[project @ 1996-04-05 08:26:04 by partain]
authorpartain <unknown>
Fri, 5 Apr 1996 08:30:45 +0000 (08:30 +0000)
committerpartain <unknown>
Fri, 5 Apr 1996 08:30:45 +0000 (08:30 +0000)
Add SLPJ/WDP 1.3 changes through 960404

174 files changed:
ghc/compiler/Jmakefile
ghc/compiler/absCSyn/AbsCLoop.lhi [new file with mode: 0644]
ghc/compiler/absCSyn/AbsCSyn.lhs
ghc/compiler/absCSyn/AbsCUtils.lhs
ghc/compiler/absCSyn/CLabel.lhs
ghc/compiler/absCSyn/Costs.lhs
ghc/compiler/absCSyn/HeapOffs.lhs
ghc/compiler/absCSyn/PprAbsC.lhs
ghc/compiler/basicTypes/FieldLabel.lhs [new file with mode: 0644]
ghc/compiler/basicTypes/Id.lhs
ghc/compiler/basicTypes/IdInfo.lhs
ghc/compiler/basicTypes/IdLoop.lhi
ghc/compiler/basicTypes/Name.lhs
ghc/compiler/basicTypes/PprEnv.lhs [new file with mode: 0644]
ghc/compiler/basicTypes/UniqSupply.lhs
ghc/compiler/codeGen/CgBindery.lhs
ghc/compiler/codeGen/CgCase.lhs
ghc/compiler/codeGen/CgClosure.lhs
ghc/compiler/codeGen/CgCompInfo.lhs
ghc/compiler/codeGen/CgCon.lhs
ghc/compiler/codeGen/CgConTbls.lhs
ghc/compiler/codeGen/CgExpr.lhs
ghc/compiler/codeGen/CgHeapery.lhs
ghc/compiler/codeGen/CgLetNoEscape.lhs
ghc/compiler/codeGen/CgLoop1.lhi [new file with mode: 0644]
ghc/compiler/codeGen/CgLoop2.lhi [new file with mode: 0644]
ghc/compiler/codeGen/CgMonad.lhs
ghc/compiler/codeGen/CgRetConv.lhs
ghc/compiler/codeGen/CgStackery.lhs
ghc/compiler/codeGen/CgTailCall.lhs
ghc/compiler/codeGen/CgUpdate.lhs
ghc/compiler/codeGen/CgUsages.lhs
ghc/compiler/codeGen/ClosureInfo.lhs
ghc/compiler/codeGen/CodeGen.lhs
ghc/compiler/codeGen/SMRep.lhs
ghc/compiler/coreSyn/CoreLift.lhs
ghc/compiler/coreSyn/CoreLint.lhs
ghc/compiler/coreSyn/CoreSyn.lhs
ghc/compiler/coreSyn/CoreUnfold.lhs
ghc/compiler/coreSyn/CoreUtils.lhs
ghc/compiler/coreSyn/FreeVars.lhs
ghc/compiler/coreSyn/PprCore.lhs
ghc/compiler/deSugar/Desugar.lhs
ghc/compiler/deSugar/DsBinds.lhs
ghc/compiler/deSugar/DsCCall.lhs
ghc/compiler/deSugar/DsExpr.lhs
ghc/compiler/deSugar/DsGRHSs.lhs
ghc/compiler/deSugar/DsMonad.lhs
ghc/compiler/deSugar/DsUtils.lhs
ghc/compiler/deSugar/Match.lhs
ghc/compiler/deSugar/MatchLit.lhs
ghc/compiler/deforest/Core2Def.lhs
ghc/compiler/deforest/Cyclic.lhs
ghc/compiler/hsSyn/HsBinds.lhs
ghc/compiler/hsSyn/HsDecls.lhs
ghc/compiler/hsSyn/HsExpr.lhs
ghc/compiler/hsSyn/HsMatches.lhs
ghc/compiler/hsSyn/HsPat.lhs
ghc/compiler/main/ErrUtils.lhs
ghc/compiler/main/Main.lhs
ghc/compiler/main/MkIface.lhs
ghc/compiler/nativeGen/AbsCStixGen.lhs
ghc/compiler/nativeGen/AlphaCode.lhs [deleted file]
ghc/compiler/nativeGen/AlphaDesc.lhs [deleted file]
ghc/compiler/nativeGen/AlphaGen.lhs [deleted file]
ghc/compiler/nativeGen/AsmCodeGen.lhs
ghc/compiler/nativeGen/AsmRegAlloc.lhs
ghc/compiler/nativeGen/I386Code.lhs [deleted file]
ghc/compiler/nativeGen/I386Desc.lhs [deleted file]
ghc/compiler/nativeGen/I386Gen.lhs [deleted file]
ghc/compiler/nativeGen/MachCode.lhs [new file with mode: 0644]
ghc/compiler/nativeGen/MachDesc.lhs [deleted file]
ghc/compiler/nativeGen/MachMisc.lhs [new file with mode: 0644]
ghc/compiler/nativeGen/MachRegs.lhs [new file with mode: 0644]
ghc/compiler/nativeGen/NCG.h [new file with mode: 0644]
ghc/compiler/nativeGen/NcgLoop.lhi [new file with mode: 0644]
ghc/compiler/nativeGen/PprMach.lhs [new file with mode: 0644]
ghc/compiler/nativeGen/RegAllocInfo.lhs [new file with mode: 0644]
ghc/compiler/nativeGen/SparcCode.lhs [deleted file]
ghc/compiler/nativeGen/SparcDesc.lhs [deleted file]
ghc/compiler/nativeGen/SparcGen.lhs [deleted file]
ghc/compiler/nativeGen/Stix.lhs
ghc/compiler/nativeGen/StixInfo.lhs
ghc/compiler/nativeGen/StixInteger.lhs
ghc/compiler/nativeGen/StixMacro.lhs
ghc/compiler/nativeGen/StixPrim.lhs
ghc/compiler/parser/UgenAll.lhs
ghc/compiler/parser/hslexer.flex
ghc/compiler/parser/hsparser.y
ghc/compiler/prelude/PrelInfo.lhs
ghc/compiler/prelude/PrelVals.lhs
ghc/compiler/prelude/PrimOp.lhs
ghc/compiler/prelude/TysPrim.lhs
ghc/compiler/prelude/TysWiredIn.lhs
ghc/compiler/profiling/SCCfinal.lhs
ghc/compiler/reader/ReadPrefix.lhs
ghc/compiler/rename/RnBinds4.lhs
ghc/compiler/rename/RnExpr4.lhs
ghc/compiler/rename/RnHsSyn.lhs
ghc/compiler/rename/RnPass1.lhs
ghc/compiler/rename/RnPass4.lhs
ghc/compiler/simplCore/AnalFBWW.lhs
ghc/compiler/simplCore/FloatIn.lhs
ghc/compiler/simplCore/FoldrBuildWW.lhs
ghc/compiler/simplCore/MagicUFs.lhs
ghc/compiler/simplCore/OccurAnal.lhs
ghc/compiler/simplCore/SimplCase.lhs
ghc/compiler/simplCore/SimplCore.lhs
ghc/compiler/simplCore/SimplEnv.lhs
ghc/compiler/simplCore/SimplMonad.lhs
ghc/compiler/simplCore/SimplPgm.lhs
ghc/compiler/simplCore/SimplUtils.lhs
ghc/compiler/simplCore/SimplVar.lhs
ghc/compiler/simplCore/Simplify.lhs
ghc/compiler/simplCore/SmplLoop.lhi
ghc/compiler/simplStg/LambdaLift.lhs
ghc/compiler/simplStg/SatStgRhs.lhs
ghc/compiler/simplStg/SimplStg.lhs
ghc/compiler/simplStg/StgSAT.lhs
ghc/compiler/simplStg/StgSATMonad.lhs
ghc/compiler/simplStg/StgStats.lhs
ghc/compiler/simplStg/StgVarInfo.lhs
ghc/compiler/simplStg/UpdAnal.lhs
ghc/compiler/specialise/SpecEnv.lhs
ghc/compiler/specialise/SpecUtils.lhs
ghc/compiler/specialise/Specialise.lhs
ghc/compiler/stgSyn/CoreToStg.lhs
ghc/compiler/stgSyn/StgLint.lhs
ghc/compiler/stgSyn/StgSyn.lhs
ghc/compiler/stgSyn/StgUtils.lhs
ghc/compiler/stranal/SaAbsInt.lhs
ghc/compiler/stranal/SaLib.lhs
ghc/compiler/stranal/StrictAnal.lhs
ghc/compiler/stranal/WorkWrap.lhs
ghc/compiler/stranal/WwLib.lhs
ghc/compiler/typecheck/GenSpecEtc.lhs
ghc/compiler/typecheck/Inst.lhs
ghc/compiler/typecheck/TcBinds.lhs
ghc/compiler/typecheck/TcClassDcl.lhs
ghc/compiler/typecheck/TcDeriv.lhs
ghc/compiler/typecheck/TcEnv.lhs
ghc/compiler/typecheck/TcExpr.lhs
ghc/compiler/typecheck/TcGenDeriv.lhs
ghc/compiler/typecheck/TcHsSyn.lhs
ghc/compiler/typecheck/TcInstDcls.lhs
ghc/compiler/typecheck/TcKind.lhs
ghc/compiler/typecheck/TcMatches.lhs
ghc/compiler/typecheck/TcModule.lhs
ghc/compiler/typecheck/TcMonad.lhs
ghc/compiler/typecheck/TcMonoType.lhs
ghc/compiler/typecheck/TcPat.lhs
ghc/compiler/typecheck/TcPragmas.lhs
ghc/compiler/typecheck/TcTyClsDecls.lhs
ghc/compiler/typecheck/TcTyDecls.lhs
ghc/compiler/typecheck/TcType.lhs
ghc/compiler/typecheck/Typecheck.lhs
ghc/compiler/typecheck/Unify.lhs
ghc/compiler/types/Kind.lhs
ghc/compiler/types/PprType.lhs
ghc/compiler/types/TyCon.lhs
ghc/compiler/types/TyLoop.lhi
ghc/compiler/types/TyVar.lhs
ghc/compiler/types/Type.lhs
ghc/compiler/utils/BitSet.lhs
ghc/compiler/utils/CharSeq.lhs
ghc/compiler/utils/FiniteMap.lhs
ghc/compiler/utils/MatchEnv.lhs
ghc/compiler/utils/PprStyle.lhs
ghc/compiler/utils/Pretty.lhs
ghc/compiler/utils/Ubiq.lhi
ghc/compiler/utils/UniqFM.lhs
ghc/compiler/utils/UniqSet.lhs
ghc/compiler/utils/Unpretty.lhs
ghc/compiler/utils/Util.lhs

index aecfcbd..55a455e 100644 (file)
@@ -95,17 +95,19 @@ hsSyn/HsTypes.lhs \
 hsSyn/HsSyn.lhs
 
 #define NOT_SO_BASICSRCS_LHS   \
 hsSyn/HsSyn.lhs
 
 #define NOT_SO_BASICSRCS_LHS   \
-basicTypes/Unique.lhs          \
-basicTypes/UniqSupply.lhs      \
-basicTypes/ProtoName.lhs       \
-basicTypes/Name.lhs            \
-basicTypes/NameTypes.lhs       \
-basicTypes/SrcLoc.lhs          \
+basicTypes/FieldLabel.lhs      \
 basicTypes/Id.lhs              \
 basicTypes/IdInfo.lhs          \
 basicTypes/IdUtils.lhs         \
 basicTypes/Id.lhs              \
 basicTypes/IdInfo.lhs          \
 basicTypes/IdUtils.lhs         \
-basicTypes/PragmaInfo.lhs      \
 basicTypes/Literal.lhs         \
 basicTypes/Literal.lhs         \
+basicTypes/Name.lhs            \
+basicTypes/NameTypes.lhs       \
+basicTypes/PprEnv.lhs          \
+basicTypes/PragmaInfo.lhs      \
+basicTypes/ProtoName.lhs       \
+basicTypes/SrcLoc.lhs          \
+basicTypes/UniqSupply.lhs      \
+basicTypes/Unique.lhs          \
 \
 types/Class.lhs                        \
 types/Kind.lhs                 \
 \
 types/Class.lhs                        \
 types/Kind.lhs                 \
@@ -181,6 +183,22 @@ deSugar/DsUtils.lhs \
 coreSyn/CoreLift.lhs \
 coreSyn/CoreLint.lhs
 
 coreSyn/CoreLift.lhs \
 coreSyn/CoreLint.lhs
 
+#if GhcWithDeforester != YES
+#define __omit_deforester_flag -DOMIT_DEFORESTER=1
+#define DEFORESTER_SRCS_LHS /*none*/
+#else
+#define __omit_deforester_flag /*nope*/
+#define DEFORESTER_SRCS_LHS \
+deforest/DefSyn.lhs \
+deforest/Core2Def.lhs \
+deforest/Def2Core.lhs \
+deforest/Deforest.lhs \
+deforest/DefUtils.lhs \
+deforest/DefExpr.lhs \
+deforest/Cyclic.lhs \
+deforest/TreelessForm.lhs
+#endif /* GhcWithDeforester */
+
 #define SIMPL_SRCS_LHS \
 coreSyn/AnnCoreSyn.lhs \
 coreSyn/FreeVars.lhs \
 #define SIMPL_SRCS_LHS \
 coreSyn/AnnCoreSyn.lhs \
 coreSyn/FreeVars.lhs \
@@ -215,30 +233,14 @@ stranal/SaAbsInt.lhs \
 stranal/WwLib.lhs \
 stranal/WorkWrap.lhs \
 \
 stranal/WwLib.lhs \
 stranal/WorkWrap.lhs \
 \
-profiling/SCCauto.lhs \
-profiling/SCCfinal.lhs
+profiling/SCCauto.lhs DEFORESTER_SRCS_LHS
 
 
-#if GhcWithDeforester != YES
-#define __omit_deforester_flag -DOMIT_DEFORESTER=1
-#define DEFORESTER_SRCS_LHS /*none*/
-#else
-#define __omit_deforester_flag /*nope*/
-#define DEFORESTER_SRCS_LHS \
-deforest/DefSyn.lhs \
-deforest/Core2Def.lhs \
-deforest/Def2Core.lhs \
-deforest/Deforest.lhs \
-deforest/DefUtils.lhs \
-deforest/DefExpr.lhs \
-deforest/Cyclic.lhs \
-deforest/TreelessForm.lhs
-#endif /* GhcWithDeforester */
-
-#define BACKSRCS_LHS \
+#define STG_SRCS_LHS \
 stgSyn/CoreToStg.lhs \
 stgSyn/StgSyn.lhs \
 stgSyn/StgUtils.lhs \
 stgSyn/StgLint.lhs \
 stgSyn/CoreToStg.lhs \
 stgSyn/StgSyn.lhs \
 stgSyn/StgUtils.lhs \
 stgSyn/StgLint.lhs \
+profiling/SCCfinal.lhs \
 \
 simplStg/SatStgRhs.lhs \
 simplStg/LambdaLift.lhs \
 \
 simplStg/SatStgRhs.lhs \
 simplStg/LambdaLift.lhs \
@@ -247,8 +249,9 @@ simplStg/UpdAnal.lhs \
 simplStg/StgStats.lhs \
 simplStg/StgSATMonad.lhs \
 simplStg/StgSAT.lhs \
 simplStg/StgStats.lhs \
 simplStg/StgSATMonad.lhs \
 simplStg/StgSAT.lhs \
-simplStg/SimplStg.lhs \
-\
+simplStg/SimplStg.lhs
+
+#define BACKSRCS_LHS \
 absCSyn/AbsCUtils.lhs \
 absCSyn/AbsCSyn.lhs \
 absCSyn/CLabel.lhs \
 absCSyn/AbsCUtils.lhs \
 absCSyn/AbsCSyn.lhs \
 absCSyn/CLabel.lhs \
@@ -283,36 +286,21 @@ codeGen/CgUpdate.lhs
 # define NATIVEGEN_SRCS_LHS /*none*/
 #else
 # define __omit_ncg_maybe /*none*/
 # define NATIVEGEN_SRCS_LHS /*none*/
 #else
 # define __omit_ncg_maybe /*none*/
-# if i386_TARGET_ARCH
-# define __machdep_nativegen_lhs \
-nativeGen/I386Desc.lhs \
-nativeGen/I386Code.lhs \
-nativeGen/I386Gen.lhs
-# endif
-# if sparc_TARGET_ARCH
-# define __machdep_nativegen_lhs \
-nativeGen/SparcDesc.lhs \
-nativeGen/SparcCode.lhs \
-nativeGen/SparcGen.lhs
-# endif
-# if alpha_TARGET_ARCH
-# define __machdep_nativegen_lhs \
-nativeGen/AlphaDesc.lhs \
-nativeGen/AlphaCode.lhs \
-nativeGen/AlphaGen.lhs
-# endif
 
 # define NATIVEGEN_SRCS_LHS \
 nativeGen/AbsCStixGen.lhs \
 nativeGen/AsmCodeGen.lhs \
 nativeGen/AsmRegAlloc.lhs \
 
 # define NATIVEGEN_SRCS_LHS \
 nativeGen/AbsCStixGen.lhs \
 nativeGen/AsmCodeGen.lhs \
 nativeGen/AsmRegAlloc.lhs \
-nativeGen/MachDesc.lhs \
+nativeGen/MachCode.lhs \
+nativeGen/MachMisc.lhs \
+nativeGen/MachRegs.lhs \
+nativeGen/PprMach.lhs \
+nativeGen/RegAllocInfo.lhs \
 nativeGen/Stix.lhs \
 nativeGen/StixInfo.lhs \
 nativeGen/StixInteger.lhs \
 nativeGen/StixPrim.lhs \
 nativeGen/Stix.lhs \
 nativeGen/StixInfo.lhs \
 nativeGen/StixInteger.lhs \
 nativeGen/StixPrim.lhs \
-nativeGen/StixMacro.lhs \
-__machdep_nativegen_lhs /*arch-specific ones */
+nativeGen/StixMacro.lhs
 #endif
 
 #define UTILSRCS_LHS \
 #endif
 
 #define UTILSRCS_LHS \
@@ -366,22 +354,20 @@ simplCore/MagicUFs.lhs
 
 ALLSRCS_HS = READERSRCS_HS
 ALLSRCS_LHS = /* all pieces of the compiler */ \
 
 ALLSRCS_HS = READERSRCS_HS
 ALLSRCS_LHS = /* all pieces of the compiler */ \
-VBASICSRCS_LHS \
-NOT_SO_BASICSRCS_LHS \
-UTILSRCS_LHS \
-MAIN_SRCS_LHS \
-READERSRCS_LHS \
-RENAMERSRCS_LHS \
-TCSRCS_LHS \
-DSSRCS_LHS
+VBASICSRCS_LHS         \
+NOT_SO_BASICSRCS_LHS   \
+UTILSRCS_LHS           \
+MAIN_SRCS_LHS          \
+READERSRCS_LHS                 \
+RENAMERSRCS_LHS        \
+TCSRCS_LHS             \
+DSSRCS_LHS             \
+SIMPL_SRCS_LHS                 \
+STG_SRCS_LHS           \
+BACKSRCS_LHS NATIVEGEN_SRCS_LHS
 
 /*
 
 /*
-SIMPL_SRCS_LHS
-BACKSRCS_LHS
 */
 */
-
-/* 
-NATIVEGEN_SRCS_LHS DEFORESTER_SRCS_LHS */
 /* NB: all the ones that may be empty (e.g., NATIVEGEN_SRCS_LHS)
        need to be on the last line.
 */
 /* NB: all the ones that may be empty (e.g., NATIVEGEN_SRCS_LHS)
        need to be on the last line.
 */
@@ -405,13 +391,6 @@ ALLINTS=$(ALLSRCS_LHS:.lhs=.hi) $(ALLSRCS_HS:.hs=.hi)
 #define __version_sensitive_flags -fomit-reexported-instances
 #endif
 
 #define __version_sensitive_flags -fomit-reexported-instances
 #endif
 
-#if GhcWithRegisterised == NO
-    /* doing a raw boot from .hc files, presumably */
-#define __unreg_opts_maybe -O -unregisterised
-#else
-#define __unreg_opts_maybe /*none*/
-#endif
-
 /* avoid use of AllProjectsHcOpts; then put in HcMaxHeapFlag "by hand" */
 #undef  AllProjectsHcOpts
 #define AllProjectsHcOpts /**/
 /* avoid use of AllProjectsHcOpts; then put in HcMaxHeapFlag "by hand" */
 #undef  AllProjectsHcOpts
 #define AllProjectsHcOpts /**/
@@ -419,10 +398,9 @@ ALLINTS=$(ALLSRCS_LHS:.lhs=.hi) $(ALLSRCS_HS:.hs=.hi)
 HC_OPTS = -cpp HcMaxHeapFlag -fhaskell-1.3 -fglasgow-exts -DCOMPILING_GHC \
        -fomit-derived-read \
        -I. -i$(SUBDIR_LIST) \
 HC_OPTS = -cpp HcMaxHeapFlag -fhaskell-1.3 -fglasgow-exts -DCOMPILING_GHC \
        -fomit-derived-read \
        -I. -i$(SUBDIR_LIST) \
-       use_DDEBUG __version_sensitive_flags __unreg_opts_maybe __omit_ncg_maybe
+       use_DDEBUG __version_sensitive_flags __omit_ncg_maybe __omit_deforester_flag
 
 #undef __version_sensitive_flags
 
 #undef __version_sensitive_flags
-#undef __unreg_opts_maybe
 #undef __omit_ncg_maybe
 #undef __omit_deforester_flag
 
 #undef __omit_ncg_maybe
 #undef __omit_deforester_flag
 
@@ -505,14 +483,22 @@ HaskellCompileWithExtraFlags_Recursive(module,isuf,o,-c,extra_flags)
 utils/Ubiq.hi : utils/Ubiq.lhi
        $(GHC_UNLIT) utils/Ubiq.lhi utils/Ubiq.hi
 
 utils/Ubiq.hi : utils/Ubiq.lhi
        $(GHC_UNLIT) utils/Ubiq.lhi utils/Ubiq.hi
 
+absCSyn/AbsCLoop.hi : absCSyn/AbsCLoop.lhi
+       $(GHC_UNLIT) absCSyn/AbsCLoop.lhi absCSyn/AbsCLoop.hi
 basicTypes/IdLoop.hi : basicTypes/IdLoop.lhi
        $(GHC_UNLIT) basicTypes/IdLoop.lhi basicTypes/IdLoop.hi
 basicTypes/NameLoop.hi : basicTypes/NameLoop.lhi
        $(GHC_UNLIT) basicTypes/NameLoop.lhi basicTypes/NameLoop.hi
 basicTypes/IdLoop.hi : basicTypes/IdLoop.lhi
        $(GHC_UNLIT) basicTypes/IdLoop.lhi basicTypes/IdLoop.hi
 basicTypes/NameLoop.hi : basicTypes/NameLoop.lhi
        $(GHC_UNLIT) basicTypes/NameLoop.lhi basicTypes/NameLoop.hi
+codeGen/CgLoop1.hi : codeGen/CgLoop1.lhi
+       $(GHC_UNLIT) codeGen/CgLoop1.lhi codeGen/CgLoop1.hi
+codeGen/CgLoop2.hi : codeGen/CgLoop2.lhi
+       $(GHC_UNLIT) codeGen/CgLoop2.lhi codeGen/CgLoop2.hi
 deSugar/DsLoop.hi : deSugar/DsLoop.lhi
        $(GHC_UNLIT) deSugar/DsLoop.lhi deSugar/DsLoop.hi
 hsSyn/HsLoop.hi : hsSyn/HsLoop.lhi
        $(GHC_UNLIT) hsSyn/HsLoop.lhi hsSyn/HsLoop.hi
 deSugar/DsLoop.hi : deSugar/DsLoop.lhi
        $(GHC_UNLIT) deSugar/DsLoop.lhi deSugar/DsLoop.hi
 hsSyn/HsLoop.hi : hsSyn/HsLoop.lhi
        $(GHC_UNLIT) hsSyn/HsLoop.lhi hsSyn/HsLoop.hi
+nativeGen/NcgLoop.hi : nativeGen/NcgLoop.lhi
+       $(GHC_UNLIT) nativeGen/NcgLoop.lhi nativeGen/NcgLoop.hi
 prelude/PrelLoop.hi : prelude/PrelLoop.lhi
        $(GHC_UNLIT) prelude/PrelLoop.lhi prelude/PrelLoop.hi
 reader/RdrLoop.hi : reader/RdrLoop.lhi
 prelude/PrelLoop.hi : prelude/PrelLoop.lhi
        $(GHC_UNLIT) prelude/PrelLoop.lhi prelude/PrelLoop.hi
 reader/RdrLoop.hi : reader/RdrLoop.lhi
@@ -548,12 +534,14 @@ compile(hsSyn/HsPragmas,lhs,)
 compile(hsSyn/HsTypes,lhs,)
 compile(hsSyn/HsSyn,lhs,if_ghc(-fno-omit-reexported-instances))
 
 compile(hsSyn/HsTypes,lhs,)
 compile(hsSyn/HsSyn,lhs,if_ghc(-fno-omit-reexported-instances))
 
+compile(basicTypes/FieldLabel,lhs,)
 compile(basicTypes/Id,lhs,)
 compile(basicTypes/IdInfo,lhs,-K2m)
 compile(basicTypes/IdUtils,lhs,)
 compile(basicTypes/Literal,lhs,)
 compile(basicTypes/Name,lhs,)
 compile(basicTypes/NameTypes,lhs,)
 compile(basicTypes/Id,lhs,)
 compile(basicTypes/IdInfo,lhs,-K2m)
 compile(basicTypes/IdUtils,lhs,)
 compile(basicTypes/Literal,lhs,)
 compile(basicTypes/Name,lhs,)
 compile(basicTypes/NameTypes,lhs,)
+compile(basicTypes/PprEnv,lhs,)
 compile(basicTypes/PragmaInfo,lhs,)
 compile(basicTypes/ProtoName,lhs,)
 compile(basicTypes/SrcLoc,lhs,)
 compile(basicTypes/PragmaInfo,lhs,)
 compile(basicTypes/ProtoName,lhs,)
 compile(basicTypes/SrcLoc,lhs,)
@@ -611,27 +599,16 @@ compile(main/MkIface,lhs,)
 compile(nativeGen/AbsCStixGen,lhs,)
 compile(nativeGen/AsmCodeGen,lhs,-I$(COMPINFO_DIR))
 compile(nativeGen/AsmRegAlloc,lhs,-I$(COMPINFO_DIR))
 compile(nativeGen/AbsCStixGen,lhs,)
 compile(nativeGen/AsmCodeGen,lhs,-I$(COMPINFO_DIR))
 compile(nativeGen/AsmRegAlloc,lhs,-I$(COMPINFO_DIR))
-compile(nativeGen/MachDesc,lhs,)
+compile(nativeGen/MachCode,lhs,)
+compile(nativeGen/MachMisc,lhs,)
+compile(nativeGen/MachRegs,lhs,)
+compile(nativeGen/PprMach,lhs,)
+compile(nativeGen/RegAllocInfo,lhs,)
 compile(nativeGen/Stix,lhs,)
 compile(nativeGen/StixInfo,lhs,-I$(NATIVEGEN_DIR))
 compile(nativeGen/StixInteger,lhs,)
 compile(nativeGen/StixMacro,lhs,-I$(NATIVEGEN_DIR))
 compile(nativeGen/StixPrim,lhs,)
 compile(nativeGen/Stix,lhs,)
 compile(nativeGen/StixInfo,lhs,-I$(NATIVEGEN_DIR))
 compile(nativeGen/StixInteger,lhs,)
 compile(nativeGen/StixMacro,lhs,-I$(NATIVEGEN_DIR))
 compile(nativeGen/StixPrim,lhs,)
-# if i386_TARGET_ARCH
-compile(nativeGen/I386Desc,lhs,)
-compile(nativeGen/I386Code,lhs,-I$(NATIVEGEN_DIR) if_ghc(-monly-4-regs))
-compile(nativeGen/I386Gen,lhs,)
-# endif
-# if sparc_TARGET_ARCH
-compile(nativeGen/SparcDesc,lhs,)
-compile(nativeGen/SparcCode,lhs,-I$(NATIVEGEN_DIR))
-compile(nativeGen/SparcGen,lhs,)
-# endif
-# if alpha_TARGET_ARCH
-compile(nativeGen/AlphaDesc,lhs,)
-compile(nativeGen/AlphaCode,lhs,-I$(NATIVEGEN_DIR))
-compile(nativeGen/AlphaGen,lhs,)
-# endif
 #endif
 
 compile(prelude/PrelInfo,lhs,)
 #endif
 
 compile(prelude/PrelInfo,lhs,)
@@ -923,7 +900,7 @@ compile(parser/U_ttype,hs,$(PARSER_HS_OPTS) '-#include"hspincl.h"')
 
 /* *** misc *************************************************** */
 
 
 /* *** misc *************************************************** */
 
-DEPSRCS = $(ALLSRCS_LHS) $(ALLSRCS_HS) SIMPL_SRCS_LHS
+DEPSRCS = $(ALLSRCS_LHS) $(ALLSRCS_HS)
 
 #if GhcWithHscBuiltViaC == NO
 MKDEPENDHS_OPTS= -I$(MAIN_INCLUDE_DIR) -I$(COMPINFO_DIR) -x HsVersions.h
 
 #if GhcWithHscBuiltViaC == NO
 MKDEPENDHS_OPTS= -I$(MAIN_INCLUDE_DIR) -I$(COMPINFO_DIR) -x HsVersions.h
diff --git a/ghc/compiler/absCSyn/AbsCLoop.lhi b/ghc/compiler/absCSyn/AbsCLoop.lhi
new file mode 100644 (file)
index 0000000..2d5f61d
--- /dev/null
@@ -0,0 +1,50 @@
+Breaks the loop caused by PprAbsC needing to
+see big swathes of ClosureInfo.
+
+Also from CLabel needing a couple of CgRetConv things.
+
+Also from HeapOffs needing some MachMisc things.
+
+\begin{code}
+interface AbsCLoop where
+import PreludeStdIO    ( Maybe )
+
+import CgRetConv       ( ctrlReturnConvAlg,
+                         CtrlReturnConvention(..)
+                       )
+import ClosureInfo     ( closureKind, closureLabelFromCI,
+                         closureNonHdrSize, closurePtrsSize,
+                         closureSMRep, closureSemiTag,
+                         closureSizeWithoutFixedHdr,
+                         closureTypeDescr, closureUpdReqd,
+                         infoTableLabelFromCI, maybeSelectorInfo,
+                         entryLabelFromCI,fastLabelFromCI,
+                         ClosureInfo
+                       )
+import CLabel          ( CLabel )
+import HeapOffs                ( HeapOffset )
+import Id              ( Id(..) )
+import MachMisc                ( fixedHdrSizeInWords, varHdrSizeInWords )
+import SMRep           ( SMRep )
+import TyCon           ( TyCon )
+
+closureKind :: ClosureInfo -> [Char]
+closureLabelFromCI :: ClosureInfo -> CLabel
+closureNonHdrSize :: ClosureInfo -> Int
+closurePtrsSize :: ClosureInfo -> Int
+closureSMRep :: ClosureInfo -> SMRep
+closureSemiTag :: ClosureInfo -> Int
+closureSizeWithoutFixedHdr :: ClosureInfo -> HeapOffset
+closureTypeDescr :: ClosureInfo -> [Char]
+closureUpdReqd :: ClosureInfo -> Bool
+entryLabelFromCI :: ClosureInfo -> CLabel
+fastLabelFromCI :: ClosureInfo -> CLabel
+infoTableLabelFromCI :: ClosureInfo -> CLabel
+maybeSelectorInfo :: ClosureInfo -> Maybe (Id, Int)
+
+ctrlReturnConvAlg :: TyCon -> CtrlReturnConvention
+data CtrlReturnConvention   = VectoredReturn Int | UnvectoredReturn Int
+
+fixedHdrSizeInWords :: Int
+varHdrSizeInWords   :: SMRep -> Int
+\end{code}
index f23614d..c36e26e 100644 (file)
@@ -14,7 +14,7 @@ raw assembler/machine code.
 \begin{code}
 #include "HsVersions.h"
 
 \begin{code}
 #include "HsVersions.h"
 
-module AbsCSyn (
+module AbsCSyn {- (
        -- export everything
        AbstractC(..),
        CStmtMacro(..),
        -- export everything
        AbstractC(..),
        CStmtMacro(..),
@@ -26,68 +26,37 @@ module AbsCSyn (
        mkAbsCStmtList,
        mkCCostCentre,
 
        mkAbsCStmtList,
        mkCCostCentre,
 
-       -- HeapOffsets, plus some convenient synonyms...
-       HeapOffset,
-       zeroOff, intOff, fixedHdrSize, totHdrSize, varHdrSize,
-       maxOff, addOff, subOff, intOffsetIntoGoods,
-       isZeroOff, possiblyEqualHeapOffset,
-       pprHeapOffset,
-       VirtualHeapOffset(..), HpRelOffset(..),
-       VirtualSpAOffset(..), VirtualSpBOffset(..),
-       SpARelOffset(..), SpBRelOffset(..),
-
        -- RegRelatives
        RegRelative(..),
 
        -- registers
        MagicId(..), node, infoptr,
        -- RegRelatives
        RegRelative(..),
 
        -- registers
        MagicId(..), node, infoptr,
-       isVolatileReg,
-
-       -- closure info
-       ClosureInfo, LambdaFormInfo, UpdateFlag, SMRep,
-
-       -- stuff from AbsCUtils and PprAbsC...
-       nonemptyAbsC, flattenAbsC, getAmodeRep,
-       mixedTypeLocn, mixedPtrLocn,
-       writeRealC,
-       dumpRealC,
-       kindFromMagicId,
-       amodeCanSurviveGC
+       isVolatileReg, noLiveRegsMask, mkLiveRegsMask
 
 #ifdef GRAN
        , CostRes(Cost)
 #endif
 
 #ifdef GRAN
        , CostRes(Cost)
 #endif
+    )-} where
 
 
-       -- and stuff to make the interface self-sufficient
-    ) where
-
-import AbsCUtils       -- used, and re-exported
-import ClosureInfo     -- ditto
-import Costs
-import PprAbsC         -- ditto
-import HeapOffs                hiding ( hpRelToInt )
+import Ubiq{-uitous-}
 
 
-import PrelInfo                ( PrimOp
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
+import CgCompInfo      ( mAX_Vanilla_REG, mAX_Float_REG,
+                         mAX_Double_REG, lIVENESS_R1, lIVENESS_R2,
+                         lIVENESS_R3, lIVENESS_R4, lIVENESS_R5,
+                         lIVENESS_R6, lIVENESS_R7, lIVENESS_R8
                        )
                        )
-import Literal         ( mkMachInt, mkMachWord, Literal(..) )
-import CLabel
-import CgCompInfo      ( mAX_Vanilla_REG, mAX_Float_REG, mAX_Double_REG )
-import CostCentre      -- for CostCentre type
-import Id              ( Id, ConTag(..), DataCon(..) )
-import Maybes          ( Maybe )
-import Outputable
-import PrimRep         ( PrimRep(..) )
-import StgSyn          ( GenStgExpr, GenStgArg, StgBinderInfo )
-import UniqSet         ( UniqSet(..), UniqFM )
-import Unpretty                -- ********** NOTE **********
-import Util
+import HeapOffs                ( VirtualSpAOffset(..), VirtualSpBOffset(..),
+                         VirtualHeapOffset(..)
+                       )
+import Literal         ( mkMachInt )
+import PrimRep         ( isFollowableRep, PrimRep(..) )
 \end{code}
 
 @AbstractC@ is a list of Abstract~C statements, but the data structure
 is tree-ish, for easier and more efficient putting-together.
 \begin{code}
 \end{code}
 
 @AbstractC@ is a list of Abstract~C statements, but the data structure
 is tree-ish, for easier and more efficient putting-together.
 \begin{code}
+absCNop = AbsCNop
+
 data AbstractC
   = AbsCNop
   | AbsCStmts          AbstractC AbstractC
 data AbstractC
   = AbsCNop
   | AbsCStmts          AbstractC AbstractC
@@ -436,7 +405,6 @@ data ReturnInfo
   = DirectReturn                       -- Jump directly, if possible
   | StaticVectoredReturn Int           -- Fixed tag, starting at zero
   | DynamicVectoredReturn CAddrMode    -- Dynamic tag given by amode, starting at zero
   = DirectReturn                       -- Jump directly, if possible
   | StaticVectoredReturn Int           -- Fixed tag, starting at zero
   | DynamicVectoredReturn CAddrMode    -- Dynamic tag given by amode, starting at zero
-
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -512,6 +480,27 @@ data MagicId
 
 node   = VanillaReg PtrRep     ILIT(1) -- A convenient alias for Node
 infoptr = VanillaReg DataPtrRep ILIT(2) -- An alias for InfoPtr
 
 node   = VanillaReg PtrRep     ILIT(1) -- A convenient alias for Node
 infoptr = VanillaReg DataPtrRep ILIT(2) -- An alias for InfoPtr
+
+--------------------
+noLiveRegsMask :: Int  -- Mask indicating nothing live
+noLiveRegsMask = 0
+
+mkLiveRegsMask
+       :: [MagicId]    -- Candidate live regs; depends what they have in them
+       -> Int
+
+mkLiveRegsMask regs
+  = foldl do_reg noLiveRegsMask regs
+  where
+    do_reg acc (VanillaReg kind reg_no)
+      | isFollowableRep kind
+      = acc + (reg_tbl !! IBOX(reg_no _SUB_ ILIT(1)))
+
+    do_reg acc anything_else = acc
+
+    reg_tbl -- ToDo: mk Array!
+      = [lIVENESS_R1, lIVENESS_R2, lIVENESS_R3, lIVENESS_R4,
+        lIVENESS_R5, lIVENESS_R6, lIVENESS_R7, lIVENESS_R8]
 \end{code}
 
 We need magical @Eq@ because @VanillaReg@s come in multiple flavors.
 \end{code}
 
 We need magical @Eq@ because @VanillaReg@s come in multiple flavors.
index a9789c8..e25ce5d 100644 (file)
@@ -10,31 +10,28 @@ module AbsCUtils (
        nonemptyAbsC,
        mkAbstractCs, mkAbsCStmts,
        mkAlgAltsCSwitch,
        nonemptyAbsC,
        mkAbstractCs, mkAbsCStmts,
        mkAlgAltsCSwitch,
-       kindFromMagicId,
+       magicIdPrimRep,
        getAmodeRep, amodeCanSurviveGC,
        mixedTypeLocn, mixedPtrLocn,
        flattenAbsC,
        mkAbsCStmtList
 
        -- printing/forcing stuff comes from PprAbsC
        getAmodeRep, amodeCanSurviveGC,
        mixedTypeLocn, mixedPtrLocn,
        flattenAbsC,
        mkAbsCStmtList
 
        -- printing/forcing stuff comes from PprAbsC
-
-       -- and for interface self-sufficiency...
     ) where
 
     ) where
 
+import Ubiq{-uitous-}
+
 import AbsCSyn
 
 import AbsCSyn
 
-import PrelInfo                ( PrimOp(..)
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                       )
-import Literal         ( literalPrimRep )
-import CLabel  ( CLabel, mkReturnPtLabel, mkVecTblLabel )
+import CLabel          ( mkReturnPtLabel )
 import Digraph         ( stronglyConnComp )
 import Digraph         ( stronglyConnComp )
-import Id              ( fIRST_TAG, ConTag(..), DataCon(..), Id )
-import Maybes          ( Maybe(..) )
-import PrimRep         ( getPrimRepSize, retPrimRepSize, PrimRep(..) )
-import UniqSupply
-import StgSyn          ( GenStgArg )
+import HeapOffs                ( possiblyEqualHeapOffset )
+import Id              ( fIRST_TAG, ConTag(..) )
+import Literal         ( literalPrimRep, Literal(..) )
+import PrimRep         ( getPrimRepSize, PrimRep(..) )
+import Unique          ( Unique{-instance Eq-} )
+import UniqSupply      ( getUnique, getUniques, splitUniqSupply )
+import Util            ( panic )
 
 infixr 9 `thenFlt`
 \end{code}
 
 infixr 9 `thenFlt`
 \end{code}
@@ -148,24 +145,24 @@ mkAlgAltsCSwitch scrutinee tagged_alts deflt_absc
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-kindFromMagicId BaseReg                    = PtrRep
-kindFromMagicId StkOReg                    = PtrRep
-kindFromMagicId (VanillaReg kind _) = kind
-kindFromMagicId (FloatReg _)       = FloatRep
-kindFromMagicId (DoubleReg _)      = DoubleRep
-kindFromMagicId TagReg             = IntRep
-kindFromMagicId RetReg             = RetRep
-kindFromMagicId SpA                = PtrRep
-kindFromMagicId SuA                = PtrRep
-kindFromMagicId SpB                = PtrRep
-kindFromMagicId SuB                = PtrRep
-kindFromMagicId Hp                 = PtrRep
-kindFromMagicId HpLim              = PtrRep
-kindFromMagicId LivenessReg        = IntRep
-kindFromMagicId StdUpdRetVecReg            = PtrRep
-kindFromMagicId StkStubReg         = PtrRep
-kindFromMagicId CurCostCentre      = CostCentreRep
-kindFromMagicId VoidReg                    = VoidRep
+magicIdPrimRep BaseReg             = PtrRep
+magicIdPrimRep StkOReg             = PtrRep
+magicIdPrimRep (VanillaReg kind _) = kind
+magicIdPrimRep (FloatReg _)        = FloatRep
+magicIdPrimRep (DoubleReg _)       = DoubleRep
+magicIdPrimRep TagReg              = IntRep
+magicIdPrimRep RetReg              = RetRep
+magicIdPrimRep SpA                 = PtrRep
+magicIdPrimRep SuA                 = PtrRep
+magicIdPrimRep SpB                 = PtrRep
+magicIdPrimRep SuB                 = PtrRep
+magicIdPrimRep Hp                  = PtrRep
+magicIdPrimRep HpLim               = PtrRep
+magicIdPrimRep LivenessReg         = IntRep
+magicIdPrimRep StdUpdRetVecReg     = PtrRep
+magicIdPrimRep StkStubReg          = PtrRep
+magicIdPrimRep CurCostCentre       = CostCentreRep
+magicIdPrimRep VoidReg             = VoidRep
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -183,7 +180,7 @@ getAmodeRep :: CAddrMode -> PrimRep
 
 getAmodeRep (CVal _ kind)                  = kind
 getAmodeRep (CAddr _)                      = PtrRep
 
 getAmodeRep (CVal _ kind)                  = kind
 getAmodeRep (CAddr _)                      = PtrRep
-getAmodeRep (CReg magic_id)                = kindFromMagicId magic_id
+getAmodeRep (CReg magic_id)                = magicIdPrimRep magic_id
 getAmodeRep (CTemp uniq kind)              = kind
 getAmodeRep (CLbl label kind)              = kind
 getAmodeRep (CUnVecLbl _ _)                = PtrRep
 getAmodeRep (CTemp uniq kind)              = kind
 getAmodeRep (CLbl label kind)              = kind
 getAmodeRep (CUnVecLbl _ _)                = PtrRep
index 2ecbd17..a6df009 100644 (file)
@@ -39,40 +39,35 @@ module CLabel (
 
        needsCDecl, isReadOnly, isAsmTemp, externallyVisibleCLabel,
 
 
        needsCDecl, isReadOnly, isAsmTemp, externallyVisibleCLabel,
 
-       pprCLabel
+       pprCLabel, pprCLabel_asm
 
 #ifdef GRAN
        , isSlowEntryCCodeBlock
 #endif
 
 #ifdef GRAN
        , isSlowEntryCCodeBlock
 #endif
-
-       -- and to make the interface self-sufficient...
     ) where
 
 import Ubiq{-uitous-}
     ) where
 
 import Ubiq{-uitous-}
+import AbsCLoop                ( CtrlReturnConvention(..),
+                         ctrlReturnConvAlg
+                       )
+import NcgLoop         ( underscorePrefix, fmtAsmLbl )
 
 
+import CStrings                ( pp_cSEP )
 import Id              ( externallyVisibleId, cmpId_withSpecDataCon,
                          isDataCon, isDictFunId,
 import Id              ( externallyVisibleId, cmpId_withSpecDataCon,
                          isDataCon, isDictFunId,
-                         isConstMethodId_maybe, isClassOpId,
+                         isConstMethodId_maybe,
                          isDefaultMethodId_maybe,
                          isSuperDictSelId_maybe, fIRST_TAG,
                          isDefaultMethodId_maybe,
                          isSuperDictSelId_maybe, fIRST_TAG,
-                         DataCon(..), ConTag(..), Id
+                         ConTag(..), GenId{-instance Outputable-}
                        )
 import Maybes          ( maybeToBool )
                        )
 import Maybes          ( maybeToBool )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( showTyCon, GenType{-instance Outputable-} )
+import Pretty          ( prettyToUn )
+import TyCon           ( TyCon{-instance Eq-} )
+import Unique          ( showUnique, pprUnique, Unique{-instance Eq-} )
 import Unpretty                -- NOTE!! ********************
 import Unpretty                -- NOTE!! ********************
-{-
-import Outputable
-import Pretty          ( ppNil, ppChar, ppStr, ppPStr, ppDouble, ppInt,
-                         ppInteger, ppBeside, ppIntersperse, prettyToUn
-                       )
-#ifdef USE_ATTACK_PRAGMAS
-import CharSeq
-#endif
-import Unique          ( pprUnique, showUnique, Unique )
-import Util
-
--- Sigh...  Shouldn't this file (CLabel) live in codeGen?
-import CgRetConv       ( CtrlReturnConvention(..), ctrlReturnConvAlg )
--}
+import Util            ( assertPanic )
 \end{code}
 
 things we want to find out:
 \end{code}
 
 things we want to find out:
@@ -290,14 +285,13 @@ externallyVisibleCLabel (IdLabel (CLabelId id) _)
   | isDataCon id         = True
   | is_ConstMethodId id   = True  -- These are here to ensure splitting works
   | isDictFunId id       = True  -- when these values have not been exported
   | isDataCon id         = True
   | is_ConstMethodId id   = True  -- These are here to ensure splitting works
   | isDictFunId id       = True  -- when these values have not been exported
-  | isClassOpId id       = True
   | is_DefaultMethodId id = True
   | is_SuperDictSelId id  = True
   | otherwise            = externallyVisibleId id
   where
   | is_DefaultMethodId id = True
   | is_SuperDictSelId id  = True
   | otherwise            = externallyVisibleId id
   where
-    is_ConstMethodId id   = maybeToBool (isConstMethodId_maybe id)
+    is_ConstMethodId   id = maybeToBool (isConstMethodId_maybe   id)
     is_DefaultMethodId id = maybeToBool (isDefaultMethodId_maybe id)
     is_DefaultMethodId id = maybeToBool (isDefaultMethodId_maybe id)
-    is_SuperDictSelId id  = maybeToBool (isSuperDictSelId_maybe id)
+    is_SuperDictSelId  id = maybeToBool (isSuperDictSelId_maybe  id)
 \end{code}
 
 These GRAN functions are needed for spitting out GRAN_FETCH() at the
 \end{code}
 
 These GRAN functions are needed for spitting out GRAN_FETCH() at the
@@ -319,17 +313,20 @@ duplicate declarations in generating C (see @labelSeenTE@ in
 @PprAbsC@).
 
 \begin{code}
 @PprAbsC@).
 
 \begin{code}
+-- specialised for PprAsm: saves lots of arg passing in NCG
+pprCLabel_asm = pprCLabel (PprForAsm underscorePrefix fmtAsmLbl)
+
 pprCLabel :: PprStyle -> CLabel -> Unpretty
 
 pprCLabel :: PprStyle -> CLabel -> Unpretty
 
-pprCLabel (PprForAsm _ _ fmtAsmLbl) (AsmTempLabel u)
+pprCLabel (PprForAsm _ fmtAsmLbl) (AsmTempLabel u)
   = uppStr (fmtAsmLbl (_UNPK_ (showUnique u)))
 
   = uppStr (fmtAsmLbl (_UNPK_ (showUnique u)))
 
-pprCLabel (PprForAsm sw_chker prepend_cSEP _) lbl
+pprCLabel (PprForAsm prepend_cSEP _) lbl
   = if prepend_cSEP
     then uppBeside pp_cSEP prLbl
     else prLbl
   where
   = if prepend_cSEP
     then uppBeside pp_cSEP prLbl
     else prLbl
   where
-    prLbl = pprCLabel (PprForC sw_chker) lbl
+    prLbl = pprCLabel PprForC lbl
 
 pprCLabel sty (TyConLabel tc UnvecConUpdCode)
   = uppBesides [uppPStr SLIT("ret"), pp_cSEP, uppStr (showTyCon sty tc),
 
 pprCLabel sty (TyConLabel tc UnvecConUpdCode)
   = uppBesides [uppPStr SLIT("ret"), pp_cSEP, uppStr (showTyCon sty tc),
@@ -399,4 +396,3 @@ ppFlavor x = uppBeside pp_cSEP
                       RednCounts       -> uppPStr SLIT("ct")
                      )
 \end{code}
                       RednCounts       -> uppPStr SLIT("ct")
                      )
 \end{code}
-
index 7a2d9dc..fd803f6 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1994-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1994-1996
 %     Hans Wolfgang Loidl
 %
 % ---------------------------------------------------------------------------
 %     Hans Wolfgang Loidl
 %
 % ---------------------------------------------------------------------------
@@ -57,12 +57,9 @@ module Costs( costs,
              addrModeCosts, CostRes(Cost), nullCosts, Side(..)
     ) where
 
              addrModeCosts, CostRes(Cost), nullCosts, Side(..)
     ) where
 
-import AbsCUtils
+import Ubiq{-uitous-}
+
 import AbsCSyn
 import AbsCSyn
-import PrelInfo
-import PrimOp
-import TyCon
-import Util
 
 -- --------------------------------------------------------------------------
 #ifndef GRAN
 
 -- --------------------------------------------------------------------------
 #ifndef GRAN
index d27645e..e37b4b2 100644 (file)
@@ -22,11 +22,9 @@ module HeapOffs (
 
        intOffsetIntoGoods,
 
 
        intOffsetIntoGoods,
 
-#if 0
 #if ! OMIT_NATIVE_CODEGEN
        hpRelToInt,
 #endif
 #if ! OMIT_NATIVE_CODEGEN
        hpRelToInt,
 #endif
-#endif
 
        VirtualHeapOffset(..), HpRelOffset(..),
        VirtualSpAOffset(..), VirtualSpBOffset(..),
 
        VirtualHeapOffset(..), HpRelOffset(..),
        VirtualSpAOffset(..), VirtualSpBOffset(..),
@@ -34,15 +32,14 @@ module HeapOffs (
     ) where
 
 import Ubiq{-uitous-}
     ) where
 
 import Ubiq{-uitous-}
+#if ! OMIT_NATIVE_CODEGEN
+import AbsCLoop                ( fixedHdrSizeInWords, varHdrSizeInWords )
+#endif
 
 
-import ClosureInfo     ( isSpecRep )
 import Maybes          ( catMaybes )
 import SMRep
 import Unpretty                -- ********** NOTE **********
 import Util            ( panic )
 import Maybes          ( catMaybes )
 import SMRep
 import Unpretty                -- ********** NOTE **********
 import Util            ( panic )
-#if ! OMIT_NATIVE_CODEGEN
---import MachDesc              ( Target )
-#endif
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -272,15 +269,15 @@ pprHeapOffset :: PprStyle -> HeapOffset -> Unpretty
 pprHeapOffset sty ZeroHeapOffset = uppChar '0'
 
 pprHeapOffset sty (MaxHeapOffset off1 off2)
 pprHeapOffset sty ZeroHeapOffset = uppChar '0'
 
 pprHeapOffset sty (MaxHeapOffset off1 off2)
-  = uppBesides [uppPStr SLIT("STG_MAX"), uppLparen,
-               pprHeapOffset sty off1, uppComma, pprHeapOffset sty off2,
-              uppRparen]
+  = uppBeside (uppPStr SLIT("STG_MAX"))
+      (uppParens (uppBesides [pprHeapOffset sty off1, uppComma, pprHeapOffset sty off2]))
+
 pprHeapOffset sty (AddHeapOffset off1 off2)
 pprHeapOffset sty (AddHeapOffset off1 off2)
-  = uppBesides [uppLparen, pprHeapOffset sty off1, uppChar '+',
-                       pprHeapOffset sty off2, uppRparen]
+  = uppParens (uppBesides [pprHeapOffset sty off1, uppChar '+',
+                       pprHeapOffset sty off2])
 pprHeapOffset sty (SubHeapOffset off1 off2)
 pprHeapOffset sty (SubHeapOffset off1 off2)
-  = uppBesides [uppLparen, pprHeapOffset sty off1, uppChar '-',
-                       pprHeapOffset sty off2, uppRparen]
+  = uppParens (uppBesides [pprHeapOffset sty off1, uppChar '-',
+                       pprHeapOffset sty off2])
 
 pprHeapOffset sty (MkHeapOffset int_offs fxdhdr_offs varhdr_offs tothdr_offs)
   = pprHeapOffsetPieces sty int_offs fxdhdr_offs varhdr_offs tothdr_offs
 
 pprHeapOffset sty (MkHeapOffset int_offs fxdhdr_offs varhdr_offs tothdr_offs)
   = pprHeapOffsetPieces sty int_offs fxdhdr_offs varhdr_offs tothdr_offs
@@ -317,14 +314,12 @@ pprHeapOffsetPieces sty int_offs fxdhdr_offs varhdr_offs tothdr_offs
     case (catMaybes [pp_tothdr_offs, pp_varhdr_offs, pp_fxdhdr_offs, pp_int_offs]) of
        []   -> uppChar '0'
        [pp] -> pp      -- Each blob is parenthesised if necessary
     case (catMaybes [pp_tothdr_offs, pp_varhdr_offs, pp_fxdhdr_offs, pp_int_offs]) of
        []   -> uppChar '0'
        [pp] -> pp      -- Each blob is parenthesised if necessary
-       pps  -> uppBesides [ uppLparen, uppIntersperse (uppChar '+') pps, uppRparen ]
+       pps  -> uppParens (uppIntersperse (uppChar '+') pps)
   where
     pp_hdrs hdr_pp [] = Nothing
     pp_hdrs hdr_pp [SMRI(rep, n)] | n _EQ_ ILIT(1) = Just (uppBeside (uppStr (show rep)) hdr_pp)
   where
     pp_hdrs hdr_pp [] = Nothing
     pp_hdrs hdr_pp [SMRI(rep, n)] | n _EQ_ ILIT(1) = Just (uppBeside (uppStr (show rep)) hdr_pp)
-    pp_hdrs hdr_pp hdrs = Just (uppBesides [ uppLparen,
-                                           uppInterleave (uppChar '+')
-                                               (map (pp_hdr hdr_pp) hdrs),
-                                           uppRparen ])
+    pp_hdrs hdr_pp hdrs = Just (uppParens (uppInterleave (uppChar '+')
+                                               (map (pp_hdr hdr_pp) hdrs)))
 
     pp_hdr :: Unpretty -> SMRep__Int -> Unpretty
     pp_hdr pp_str (SMRI(rep, n))
 
     pp_hdr :: Unpretty -> SMRep__Int -> Unpretty
     pp_hdr pp_str (SMRI(rep, n))
@@ -360,23 +355,22 @@ intOffsetIntoGoods anything_else = Nothing
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-#if 0
 #if ! OMIT_NATIVE_CODEGEN
 
 #if ! OMIT_NATIVE_CODEGEN
 
-hpRelToInt :: Target -> HeapOffset -> Int
+hpRelToInt :: HeapOffset -> Int
 
 
-hpRelToInt target (MaxHeapOffset left right)
-  = (hpRelToInt target left) `max` (hpRelToInt target right)
+hpRelToInt ZeroHeapOffset = 0
 
 
-hpRelToInt target (SubHeapOffset left right)
-  = (hpRelToInt target left) - (hpRelToInt target right)
+hpRelToInt (MaxHeapOffset left right)
+  = hpRelToInt left `max` hpRelToInt right
 
 
-hpRelToInt target (AddHeapOffset left right)
-  = (hpRelToInt target left) + (hpRelToInt target right)
+hpRelToInt (SubHeapOffset left right)
+  = hpRelToInt left - hpRelToInt right
 
 
-hpRelToInt target ZeroHeapOffset = 0
+hpRelToInt (AddHeapOffset left right)
+  = hpRelToInt left + hpRelToInt right
 
 
-hpRelToInt target (MkHeapOffset base fhs vhs ths)
+hpRelToInt (MkHeapOffset base fhs vhs ths)
   = let
        vhs_pieces, ths_pieces :: [Int]
        fhs_off, vhs_off, ths_off :: Int
   = let
        vhs_pieces, ths_pieces :: [Int]
        fhs_off, vhs_off, ths_off :: Int
@@ -390,9 +384,8 @@ hpRelToInt target (MkHeapOffset base fhs vhs ths)
     in
     IBOX(base) + fhs_off + vhs_off + ths_off
   where
     in
     IBOX(base) + fhs_off + vhs_off + ths_off
   where
-    fhs_size   = (fixedHeaderSize target) :: Int
-    vhs_size r = (varHeaderSize target r) :: Int
+    fhs_size   = fixedHdrSizeInWords
+    vhs_size r = varHdrSizeInWords r
 
 #endif
 
 #endif
-#endif {-0-}
 \end{code}
 \end{code}
index 4b5dc29..d763bc7 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 %************************************************************************
 %*                                                                     *
 %
 %************************************************************************
 %*                                                                     *
 
 module PprAbsC (
        writeRealC,
 
 module PprAbsC (
        writeRealC,
-       dumpRealC,
+       dumpRealC
 #if defined(DEBUG)
 #if defined(DEBUG)
-       pprAmode, -- otherwise, not exported
+       , pprAmode -- otherwise, not exported
 #endif
 #endif
-
-       -- and for interface self-sufficiency...
-       AbstractC, CAddrMode, MagicId,
-       PprStyle, CSeq
     ) where
 
     ) where
 
-IMPORT_Trace           -- ToDo: rm (debugging only)
+import Ubiq{-uitous-}
+import AbsCLoop                -- break its dependence on ClosureInfo
 
 import AbsCSyn
 
 
 import AbsCSyn
 
-import PrelInfo                ( pprPrimOp, primOpNeedsWrapper, PrimOp(..)
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
+import AbsCUtils       ( getAmodeRep, nonemptyAbsC,
+                         mixedPtrLocn, mixedTypeLocn
                        )
                        )
-import Literal         ( literalPrimRep, showLiteral )
-import CLabel  -- lots of things
 import CgCompInfo      ( spARelToInt, spBRelToInt, mIN_UPD_SIZE )
 import CgCompInfo      ( spARelToInt, spBRelToInt, mIN_UPD_SIZE )
-import CgRetConv       ( noLiveRegsMask )
-import ClosureInfo     -- quite a few things
-import Costs           -- for GrAnSim; cost counting function -- HWL
-import CostCentre
-import FiniteMap
-import Maybes          ( catMaybes, maybeToBool, Maybe(..) )
-import Outputable
-import Pretty          ( codeStyle, prettyToUn )
-import PrimRep         ( showPrimRep, isFloatingRep, PrimRep(..) )
-import StgSyn
-import UniqFM
+import CLabel          ( externallyVisibleCLabel, mkErrorStdEntryLabel,
+                         isReadOnly, needsCDecl, pprCLabel,
+                         CLabel{-instance Ord-}
+                       )
+import CmdLineOpts     ( opt_SccProfilingOn )
+import CostCentre      ( uppCostCentre, uppCostCentreDecl )
+import Costs           ( costs, addrModeCosts, CostRes(..), Side(..) )
+import CStrings                ( stringToC )
+import FiniteMap       ( addToFM, emptyFM, lookupFM )
+import HeapOffs                ( isZeroOff, subOff, pprHeapOffset )
+import Literal         ( showLiteral, Literal(..) )
+import Maybes          ( maybeToBool, catMaybes )
+import PprStyle                ( PprStyle(..) )
+import Pretty          ( prettyToUn )
+import PrimOp          ( primOpNeedsWrapper, pprPrimOp, PrimOp(..) )
+import PrimRep         ( isFloatingRep, showPrimRep, PrimRep(..) )
+import SMRep           ( getSMInfoStr, getSMInitHdrStr, getSMUpdInplaceHdrStr,
+                         isConstantRep, isSpecRep, isPhantomRep
+                       )
+import Unique          ( pprUnique, Unique{-instance NamedThing-} )
+import UniqSet         ( emptyUniqSet, elementOfUniqSet,
+                         addOneToUniqSet, UniqSet(..)
+                       )
 import Unpretty                -- ********** NOTE **********
 import Unpretty                -- ********** NOTE **********
-import Util
+import Util            ( nOfThem, panic, assertPanic )
 
 infixr 9 `thenTE`
 \end{code}
 
 infixr 9 `thenTE`
 \end{code}
@@ -55,18 +62,18 @@ call to a cost evaluation function @GRAN_EXEC@. For that,
 @pprAbsC@ has a new ``costs'' argument.  %% HWL
 
 \begin{code}
 @pprAbsC@ has a new ``costs'' argument.  %% HWL
 
 \begin{code}
-writeRealC :: _FILE -> AbstractC -> PrimIO ()
+writeRealC :: _FILE -> AbstractC -> IO ()
 
 
-writeRealC sw_chker file absC
+writeRealC file absC
   = uppAppendFile file 80 (
   = uppAppendFile file 80 (
-      uppAbove (pprAbsC (PprForC sw_chker) absC (costs absC)) (uppChar '\n')
+      uppAbove (pprAbsC PprForC absC (costs absC)) (uppChar '\n')
     )
 
 dumpRealC :: AbstractC -> String
 
     )
 
 dumpRealC :: AbstractC -> String
 
-dumpRealC sw_chker absC
+dumpRealC absC
   = uppShow 80 (
   = uppShow 80 (
-      uppAbove (pprAbsC (PprForC sw_chker) absC (costs absC)) (uppChar '\n')
+      uppAbove (pprAbsC PprForC absC (costs absC)) (uppChar '\n')
     )
 \end{code}
 
     )
 \end{code}
 
@@ -246,7 +253,7 @@ pprAbsC sty (CCodeBlock label abs_C) _
                          else "IFN_("),
                   pprCLabel sty label, uppStr ") {"],
        case sty of
                          else "IFN_("),
                   pprCLabel sty label, uppStr ") {"],
        case sty of
-         PprForC _ -> uppAbove pp_exts pp_temps
+         PprForC -> uppAbove pp_exts pp_temps
          _ -> uppNil,
        uppNest 8 (uppPStr SLIT("FB_")),
        uppNest 8 (pprAbsC sty abs_C (costs abs_C)),
          _ -> uppNil,
        uppNest 8 (uppPStr SLIT("FB_")),
        uppNest 8 (pprAbsC sty abs_C (costs abs_C)),
@@ -275,7 +282,7 @@ pprAbsC sty stmt@(CStaticClosure closure_lbl cl_info cost_centre amodes) _
   = BIND (pprTempAndExternDecls stmt) _TO_ (_, pp_exts) ->
     uppAboves [
        case sty of
   = BIND (pprTempAndExternDecls stmt) _TO_ (_, pp_exts) ->
     uppAboves [
        case sty of
-         PprForC _ -> pp_exts
+         PprForC -> pp_exts
          _ -> uppNil,
        uppBesides [
                uppStr "SET_STATIC_HDR(",
          _ -> uppNil,
        uppBesides [
                uppStr "SET_STATIC_HDR(",
@@ -416,7 +423,7 @@ pprAbsC sty stmt@(CFlatRetVector label amodes) _
   =    BIND (pprTempAndExternDecls stmt) _TO_ (_, pp_exts) ->
        uppAboves [
            case sty of
   =    BIND (pprTempAndExternDecls stmt) _TO_ (_, pp_exts) ->
        uppAboves [
            case sty of
-             PprForC _ -> pp_exts
+             PprForC -> pp_exts
              _ -> uppNil,
            uppBesides [ppLocalness label, uppPStr SLIT(" W_ "),
                       pprCLabel sty label, uppStr "[] = {"],
              _ -> uppNil,
            uppBesides [ppLocalness label, uppPStr SLIT(" W_ "),
                       pprCLabel sty label, uppStr "[] = {"],
@@ -504,9 +511,9 @@ pp_basic_restores
 \begin{code}
 if_profiling sty pretty
   = case sty of
 \begin{code}
 if_profiling sty pretty
   = case sty of
-      PprForC sw_chker -> if  sw_chker SccProfilingOn
-                         then pretty
-                         else uppChar '0' -- leave it out!
+      PprForC -> if  opt_SccProfilingOn
+                then pretty
+                else uppChar '0' -- leave it out!
 
       _ -> {-print it anyway-} pretty
 
 
       _ -> {-print it anyway-} pretty
 
@@ -611,7 +618,6 @@ pprCCall sty op@(CCallOp op_str is_asm may_gc _ _) args results liveness_mask vo
   = if (may_gc && liveness_mask /= noLiveRegsMask)
     then panic ("Live register in _casm_GC_ \"" ++ casm_str ++ "\" " ++ (uppShow 80 (uppCat pp_non_void_args)) ++ "\n")
     else
   = if (may_gc && liveness_mask /= noLiveRegsMask)
     then panic ("Live register in _casm_GC_ \"" ++ casm_str ++ "\" " ++ (uppShow 80 (uppCat pp_non_void_args)) ++ "\n")
     else
---    trace ("casm \"" ++ casm_str ++ "\" " ++ (uppShow 80 (uppCat localVars)) ++ (uppShow 80 (uppCat pp_non_void_args)))
     uppAboves [
       uppChar '{',
       declare_local_vars,   -- local var for *result*
     uppAboves [
       uppChar '{',
       declare_local_vars,   -- local var for *result*
@@ -795,8 +801,8 @@ process_casm results args string = process results args string
          case readDec other of
            [(num,css)] ->
                  if 0 <= num && num < length args
          case readDec other of
            [(num,css)] ->
                  if 0 <= num && num < length args
-                 then uppBesides [uppLparen, args !! num, uppRparen,
-                                   process ress args css]
+                 then uppBeside (uppParens (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")
 
                    else error ("process_casm: no such arg #:"++(show num)++" while processing \"" ++ string ++ "\".\n")
            _ -> error ("process_casm: not %<num> while processing _casm_ \"" ++ string ++ "\".\n")
 
@@ -918,8 +924,8 @@ no-cast case:
 \begin{code}
 pprAmode sty amode
   | mixedTypeLocn amode
 \begin{code}
 pprAmode sty amode
   | mixedTypeLocn amode
-  = uppBesides [ uppLparen, pprPrimKind sty (getAmodeRep amode), uppStr ")(",
-               ppr_amode sty amode, uppRparen]
+  = uppParens (uppBesides [ pprPrimKind sty (getAmodeRep amode), uppStr ")(",
+               ppr_amode sty amode ])
   | otherwise  -- No cast needed
   = ppr_amode sty amode
 \end{code}
   | otherwise  -- No cast needed
   = ppr_amode sty amode
 \end{code}
@@ -930,7 +936,7 @@ Now the rest of the cases for ``workhorse'' @ppr_amode@:
 ppr_amode sty (CVal reg_rel _)
   = case (pprRegRelative sty False{-no sign wanted-} reg_rel) of
        (pp_reg, Nothing)     -> uppBeside  (uppChar '*') pp_reg
 ppr_amode sty (CVal reg_rel _)
   = case (pprRegRelative sty False{-no sign wanted-} reg_rel) of
        (pp_reg, Nothing)     -> uppBeside  (uppChar '*') pp_reg
-       (pp_reg, Just offset) -> uppBesides [ pp_reg, uppLbrack, offset, uppRbrack ]
+       (pp_reg, Just offset) -> uppBesides [ pp_reg, uppBracket offset ]
 
 ppr_amode sty (CAddr reg_rel)
   = case (pprRegRelative sty True{-sign wanted-} reg_rel) of
 
 ppr_amode sty (CAddr reg_rel)
   = case (pprRegRelative sty True{-sign wanted-} reg_rel) of
@@ -1149,19 +1155,13 @@ x `elementOfCLabelSet` labs
   = case (lookupFM labs x) of { Just _ -> True; Nothing -> False }
 addToCLabelSet set x = addToFM set x ()
 
   = case (lookupFM labs x) of { Just _ -> True; Nothing -> False }
 addToCLabelSet set x = addToFM set x ()
 
-type UniqueSet = UniqFM ()
-emptyUniqueSet = emptyUFM
-x `elementOfUniqueSet` us
-  = case (lookupDirectlyUFM us x) of { Just _ -> True; Nothing -> False }
-addToUniqueSet set x = set `plusUFM` singletonDirectlyUFM x ()
-
-type TEenv = (UniqueSet, CLabelSet)
+type TEenv = (UniqSet Unique, CLabelSet)
 
 type TeM result =  TEenv -> (TEenv, result)
 
 initTE :: TeM a -> a
 initTE sa
 
 type TeM result =  TEenv -> (TEenv, result)
 
 initTE :: TeM a -> a
 initTE sa
-  = case sa (emptyUniqueSet, emptyCLabelSet) of { (_, result) ->
+  = case sa (emptyUniqSet, emptyCLabelSet) of { (_, result) ->
     result }
 
 {-# INLINE thenTE #-}
     result }
 
 {-# INLINE thenTE #-}
@@ -1188,9 +1188,9 @@ returnTE result env = (env, result)
 
 tempSeenTE :: Unique -> TeM Bool
 tempSeenTE uniq env@(seen_uniqs, seen_labels)
 
 tempSeenTE :: Unique -> TeM Bool
 tempSeenTE uniq env@(seen_uniqs, seen_labels)
-  = if (uniq `elementOfUniqueSet` seen_uniqs)
+  = if (uniq `elementOfUniqSet` seen_uniqs)
     then (env, True)
     then (env, True)
-    else ((addToUniqueSet seen_uniqs uniq,
+    else ((addOneToUniqSet seen_uniqs uniq,
          seen_labels),
          False)
 
          seen_labels),
          False)
 
@@ -1208,8 +1208,6 @@ pprTempDecl :: Unique -> PrimRep -> Unpretty
 pprTempDecl uniq kind
   = uppBesides [ pprPrimKind PprDebug kind, uppSP, prettyToUn (pprUnique uniq), uppSemi ]
 
 pprTempDecl uniq kind
   = uppBesides [ pprPrimKind PprDebug kind, uppSP, prettyToUn (pprUnique uniq), uppSemi ]
 
-ppr_for_C = PprForC ( \ x -> False ) -- pretend no special cmd-line flags
-
 pprExternDecl :: CLabel -> PrimRep -> Unpretty
 
 pprExternDecl clabel kind
 pprExternDecl :: CLabel -> PrimRep -> Unpretty
 
 pprExternDecl clabel kind
@@ -1222,7 +1220,7 @@ pprExternDecl clabel kind
              _           -> ppLocalnessMacro False{-data-}    clabel
        ) _TO_ pp_macro_str ->
 
              _           -> ppLocalnessMacro False{-data-}    clabel
        ) _TO_ pp_macro_str ->
 
-       uppBesides [ pp_macro_str, uppLparen, pprCLabel ppr_for_C clabel, pp_paren_semi ]
+       uppBesides [ pp_macro_str, uppLparen, pprCLabel PprForC clabel, pp_paren_semi ]
        BEND
 \end{code}
 
        BEND
 \end{code}
 
diff --git a/ghc/compiler/basicTypes/FieldLabel.lhs b/ghc/compiler/basicTypes/FieldLabel.lhs
new file mode 100644 (file)
index 0000000..d28c6c5
--- /dev/null
@@ -0,0 +1,45 @@
+%
+% (c) The AQUA Project, Glasgow University, 1996
+%
+\section[FieldLabel]{The @FieldLabel@ type}
+
+\begin{code}
+#include "HsVersions.h"
+
+module FieldLabel where
+
+import Ubiq{-uitous-}
+
+import Name            ( Name{-instance Eq/Outputable-} )
+import Type            ( Type(..) )
+\end{code}
+
+\begin{code}
+data FieldLabel
+  = FieldLabel Name
+               Type
+               FieldLabelTag
+
+type FieldLabelTag = Int
+
+mkFieldLabel = FieldLabel
+
+firstFieldLabelTag :: FieldLabelTag
+firstFieldLabelTag = 1
+
+allFieldLabelTags :: [FieldLabelTag]
+allFieldLabelTags = [1..]
+
+fieldLabelName (FieldLabel n _  _)   = n
+fieldLabelType (FieldLabel _ ty _)   = ty
+fieldLabelTag  (FieldLabel _ _  tag) = tag
+
+instance Eq FieldLabel where
+    (FieldLabel n1 _ _) == (FieldLabel n2 _ _) = n1 == n2
+
+instance Outputable FieldLabel where
+    ppr sty (FieldLabel n _ _) = ppr sty n
+
+instance NamedThing FieldLabel
+    -- ToDo: fill this in
+\end{code}
index ec6367e..6c1d19b 100644 (file)
@@ -32,12 +32,15 @@ module Id {- (
        idType,
        getIdInfo, replaceIdInfo,
        getPragmaInfo,
        idType,
        getIdInfo, replaceIdInfo,
        getPragmaInfo,
-       getIdPrimRep, getInstIdModule,
+       idPrimRep, getInstIdModule,
        getMentionedTyConsAndClassesFromId,
        getMentionedTyConsAndClassesFromId,
-       getDataConTag,
-       getDataConSig, getInstantiatedDataConSig,
 
 
-       getDataConTyCon,
+       dataConTag,
+       dataConSig, getInstantiatedDataConSig,
+       dataConTyCon, dataConArity,
+       dataConFieldLabels,
+
+       recordSelectorFieldLabel,
 
        -- PREDICATES
        isDataCon, isTupleCon,
 
        -- PREDICATES
        isDataCon, isTupleCon,
@@ -62,7 +65,7 @@ module Id {- (
 -- not exported:       apply_to_Id, -- please don't use this, generally
 
        -- UNFOLDING, ARITY, UPDATE, AND STRICTNESS STUFF (etc)
 -- not exported:       apply_to_Id, -- please don't use this, generally
 
        -- UNFOLDING, ARITY, UPDATE, AND STRICTNESS STUFF (etc)
-       getIdArity, getDataConArity, addIdArity,
+       getIdArity, addIdArity,
        getIdDemandInfo, addIdDemandInfo,
        getIdSpecialisation, addIdSpecialisation,
        getIdStrictness, addIdStrictness,
        getIdDemandInfo, addIdDemandInfo,
        getIdSpecialisation, addIdSpecialisation,
        getIdStrictness, addIdStrictness,
@@ -96,30 +99,38 @@ import NameLoop -- for paranoia checking
 
 import Bag
 import Class           ( getClassOpString, Class(..), GenClass, ClassOp(..), GenClassOp )
 
 import Bag
 import Class           ( getClassOpString, Class(..), GenClass, ClassOp(..), GenClassOp )
+import CStrings                ( identToC, cSEP )
 import IdInfo
 import Maybes          ( maybeToBool )
 import NameTypes       ( mkShortName, fromPrelude, FullName, ShortName )
 import IdInfo
 import Maybes          ( maybeToBool )
 import NameTypes       ( mkShortName, fromPrelude, FullName, ShortName )
+import FieldLabel      ( fieldLabelName, FieldLabel{-instances-} )
 import Name            ( Name(..) )
 import Outputable      ( isAvarop, isAconop, getLocalName,
                          isExported, ExportFlag(..) )
 import PragmaInfo      ( PragmaInfo(..) )
 import PrelMods                ( pRELUDE_BUILTIN )
 import Name            ( Name(..) )
 import Outputable      ( isAvarop, isAconop, getLocalName,
                          isExported, ExportFlag(..) )
 import PragmaInfo      ( PragmaInfo(..) )
 import PrelMods                ( pRELUDE_BUILTIN )
-import PprType         ( GenType, GenTyVar,
-                         getTypeString, typeMaybeString, specMaybeTysSuffix )
+import PprType         ( getTypeString, typeMaybeString, specMaybeTysSuffix,
+                         GenType, GenTyVar
+                       )
 import PprStyle
 import Pretty
 import SrcLoc          ( mkBuiltinSrcLoc )
 import PprStyle
 import Pretty
 import SrcLoc          ( mkBuiltinSrcLoc )
-import TyCon           ( TyCon, mkTupleTyCon, getTyConDataCons )
+import TyCon           ( TyCon, mkTupleTyCon, tyConDataCons )
 import Type            ( mkSigmaTy, mkTyVarTys, mkFunTys, mkDictTy,
                          applyTyCon, isPrimType, instantiateTy,
 import Type            ( mkSigmaTy, mkTyVarTys, mkFunTys, mkDictTy,
                          applyTyCon, isPrimType, instantiateTy,
-                         tyVarsOfType,
+                         tyVarsOfType, applyTypeEnvToTy, typePrimRep,
                          GenType, ThetaType(..), TauType(..), Type(..)
                        )
                          GenType, ThetaType(..), TauType(..), Type(..)
                        )
-import TyVar           ( GenTyVar, alphaTyVars, isEmptyTyVarSet )
+import TyVar           ( alphaTyVars, isEmptyTyVarSet, TyVarEnv(..) )
 import UniqFM
 import UniqSet         -- practically all of it
 import UniqFM
 import UniqSet         -- practically all of it
-import Unique          ( Unique, mkTupleDataConUnique, pprUnique, showUnique )
-import Util            ( mapAccumL, nOfThem, panic, pprPanic, assertPanic )
+import UniqSupply      ( getBuiltinUniques )
+import Unique          ( mkTupleDataConUnique, pprUnique, showUnique,
+                         Unique{-instance Ord3-}
+                       )
+import Util            ( mapAccumL, nOfThem,
+                         panic, panic#, pprPanic, assertPanic
+                       )
 \end{code}
 
 Here are the @Id@ and @IdDetails@ datatypes; also see the notes that
 \end{code}
 
 Here are the @Id@ and @IdDetails@ datatypes; also see the notes that
@@ -176,6 +187,7 @@ data IdDetails
   | DataConId  FullName
                ConTag
                [StrictnessMark] -- Strict args; length = arity
   | DataConId  FullName
                ConTag
                [StrictnessMark] -- Strict args; length = arity
+               [FieldLabel]    -- Field labels for this constructor
 
                [TyVar] [(Class,Type)] [Type] TyCon
                                -- the type is:
 
                [TyVar] [(Class,Type)] [Type] TyCon
                                -- the type is:
@@ -184,6 +196,8 @@ data IdDetails
 
   | TupleConId Int             -- Its arity
 
 
   | TupleConId Int             -- Its arity
 
+  | RecordSelectorId FieldLabel
+
   ---------------- Things to do with overloading
 
   | SuperDictSelId             -- Selector for superclass dictionary
   ---------------- Things to do with overloading
 
   | SuperDictSelId             -- Selector for superclass dictionary
@@ -229,6 +243,7 @@ data IdDetails
 
   | InstId     ShortName       -- An instance of a dictionary, class operation,
                                -- or overloaded value
 
   | InstId     ShortName       -- An instance of a dictionary, class operation,
                                -- or overloaded value
+               Bool            -- as for LocalId
 
   | SpecId                     -- A specialisation of another Id
                Id              -- Id of which this is a specialisation
 
   | SpecId                     -- A specialisation of another Id
                Id              -- Id of which this is a specialisation
@@ -437,10 +452,10 @@ unsafeGenId2Id (Id u ty d p i) = Id u (panic "unsafeGenId2Id:ty") d p i
 
 isDataCon id = is_data (unsafeGenId2Id id)
  where
 
 isDataCon id = is_data (unsafeGenId2Id id)
  where
-  is_data (Id _ _ (DataConId _ _ _ _ _ _ _) _ _) = True
-  is_data (Id _ _ (TupleConId _) _ _)           = True
-  is_data (Id _ _ (SpecId unspec _ _) _ _)      = is_data unspec
-  is_data other                                         = False
+  is_data (Id _ _ (DataConId _ _ _ _ _ _ _ _) _ _) = True
+  is_data (Id _ _ (TupleConId _) _ _)             = True
+  is_data (Id _ _ (SpecId unspec _ _) _ _)        = is_data unspec
+  is_data other                                           = False
 
 
 isTupleCon id = is_tuple (unsafeGenId2Id id)
 
 
 isTupleCon id = is_tuple (unsafeGenId2Id id)
@@ -476,29 +491,31 @@ idHasNoFreeTyVars   :: Id -> Bool
 toplevelishId (Id _ _ details _ _)
   = chk details
   where
 toplevelishId (Id _ _ details _ _)
   = chk details
   where
-    chk (DataConId _ _ _ _ _ _ _) = True
-    chk (TupleConId _)           = True
-    chk (ImportedId _)           = True
-    chk (PreludeId  _)           = True
-    chk (TopLevId   _)           = True        -- NB: see notes
-    chk (SuperDictSelId _ _)     = True
-    chk (MethodSelId _ _)        = True
-    chk (DefaultMethodId _ _ _)   = True
-    chk (DictFunId     _ _ _ _)          = True
-    chk (ConstMethodId _ _ _ _ _) = True
-    chk (SpecId unspec _ _)      = toplevelishId unspec
-                                 -- depends what the unspecialised thing is
-    chk (WorkerId unwrkr)        = toplevelishId unwrkr
-    chk (InstId _)               = False       -- these are local
-    chk (LocalId      _ _)       = False
-    chk (SysLocalId   _ _)       = False
-    chk (SpecPragmaId _ _ _)     = False
+    chk (DataConId _ _ _ _ _ _ _ _) = True
+    chk (TupleConId _)             = True
+    chk (RecordSelectorId _)               = True
+    chk (ImportedId _)             = True
+    chk (PreludeId  _)             = True
+    chk (TopLevId   _)             = True      -- NB: see notes
+    chk (SuperDictSelId _ _)       = True
+    chk (MethodSelId _ _)          = True
+    chk (DefaultMethodId _ _ _)     = True
+    chk (DictFunId     _ _ _ _)            = True
+    chk (ConstMethodId _ _ _ _ _)   = True
+    chk (SpecId unspec _ _)        = toplevelishId unspec
+                                   -- depends what the unspecialised thing is
+    chk (WorkerId unwrkr)          = toplevelishId unwrkr
+    chk (InstId _ _)               = False     -- these are local
+    chk (LocalId      _ _)         = False
+    chk (SysLocalId   _ _)         = False
+    chk (SpecPragmaId _ _ _)       = False
 
 idHasNoFreeTyVars (Id _ _ details _ info)
   = chk details
   where
 
 idHasNoFreeTyVars (Id _ _ details _ info)
   = chk details
   where
-    chk (DataConId _ _ _ _ _ _ _) = True
+    chk (DataConId _ _ _ _ _ _ _ _) = True
     chk (TupleConId _)           = True
     chk (TupleConId _)           = True
+    chk (RecordSelectorId _)             = True
     chk (ImportedId _)           = True
     chk (PreludeId  _)           = True
     chk (TopLevId   _)           = True
     chk (ImportedId _)           = True
     chk (PreludeId  _)           = True
     chk (TopLevId   _)           = True
@@ -508,7 +525,7 @@ idHasNoFreeTyVars (Id _ _ details _ info)
     chk (DictFunId     _ _ _ _)          = True
     chk (ConstMethodId _ _ _ _ _) = True
     chk (WorkerId unwrkr)        = idHasNoFreeTyVars unwrkr
     chk (DictFunId     _ _ _ _)          = True
     chk (ConstMethodId _ _ _ _ _) = True
     chk (WorkerId unwrkr)        = idHasNoFreeTyVars unwrkr
-    chk (InstId _)               = False       -- these are local
+    chk (InstId       _   no_free_tvs) = no_free_tvs
     chk (SpecId _     _   no_free_tvs) = no_free_tvs
     chk (LocalId      _   no_free_tvs) = no_free_tvs
     chk (SysLocalId   _   no_free_tvs) = no_free_tvs
     chk (SpecId _     _   no_free_tvs) = no_free_tvs
     chk (LocalId      _   no_free_tvs) = no_free_tvs
     chk (SysLocalId   _   no_free_tvs) = no_free_tvs
@@ -522,8 +539,7 @@ isTopLevId other                 = False
 isImportedId (Id _ _ (ImportedId _) _ _) = True
 isImportedId other                      = False
 
 isImportedId (Id _ _ (ImportedId _) _ _) = True
 isImportedId other                      = False
 
-isBottomingId (Id _ _ _ _ info) = panic "isBottomingId not implemented"
-                       -- LATER: bottomIsGuaranteed (getInfo info)
+isBottomingId (Id _ _ _ _ info) = bottomIsGuaranteed (getInfo info)
 
 isSysLocalId (Id _ _ (SysLocalId _ _) _ _) = True
 isSysLocalId other                        = False
 
 isSysLocalId (Id _ _ (SysLocalId _ _) _ _) = True
 isSysLocalId other                        = False
@@ -578,7 +594,7 @@ pprIdInUnfolding in_scopes v
     else if v == nilDataCon then
        ppPStr SLIT("_NIL_")
     else if isTupleCon v then
     else if v == nilDataCon then
        ppPStr SLIT("_NIL_")
     else if isTupleCon v then
-       ppBeside (ppPStr SLIT("_TUP_")) (ppInt (getDataConArity v))
+       ppBeside (ppPStr SLIT("_TUP_")) (ppInt (dataConArity v))
 
     -- ones to think about:
     else
 
     -- ones to think about:
     else
@@ -592,7 +608,9 @@ pprIdInUnfolding in_scopes v
 
            -- these ones' exportedness checked later...
          TopLevId  _ -> pp_full_name
 
            -- these ones' exportedness checked later...
          TopLevId  _ -> pp_full_name
-         DataConId _ _ _ _ _ _ _ -> pp_full_name
+         DataConId _ _ _ _ _ _ _ _ -> pp_full_name
+
+         RecordSelectorId lbl -> ppr sty lbl
 
            -- class-ish things: class already recorded as "mentioned"
          SuperDictSelId c sc
 
            -- class-ish things: class already recorded as "mentioned"
          SuperDictSelId c sc
@@ -754,14 +772,10 @@ unfoldingUnfriendlyId (Id _ _ (SpecId d@(Id _ _ _ dfun@(DictFunId _ t _ _)) _ _)
     -- TyVar(Templates) in the i/face; only a problem
     -- if -fshow-pragma-name-errs; but we can do without the pain.
     -- A HACK in any case (WDP 94/05/02)
     -- TyVar(Templates) in the i/face; only a problem
     -- if -fshow-pragma-name-errs; but we can do without the pain.
     -- A HACK in any case (WDP 94/05/02)
-  = --pprTrace "unfriendly1:" (ppCat [ppr PprDebug d, ppr PprDebug t]) (
-    naughty_DictFunId dfun
-    --)
+  = naughty_DictFunId dfun
 
 unfoldingUnfriendlyId d@(Id _ _ dfun@(DictFunId _ t _ _) _ _)
 
 unfoldingUnfriendlyId d@(Id _ _ dfun@(DictFunId _ t _ _) _ _)
-  = --pprTrace "unfriendly2:" (ppCat [ppr PprDebug d, ppr PprDebug t]) (
-    naughty_DictFunId dfun -- similar deal...
-    --)
+  = naughty_DictFunId dfun -- similar deal...
 
 unfoldingUnfriendlyId other_id   = False -- is friendly in all other cases
 
 
 unfoldingUnfriendlyId other_id   = False -- is friendly in all other cases
 
@@ -785,9 +799,6 @@ compiling the prelude, the compiler may not recognise that as true.
 \begin{code}
 externallyVisibleId :: Id -> Bool
 
 \begin{code}
 externallyVisibleId :: Id -> Bool
 
-externallyVisibleId id = panic "Id.externallyVisibleId"
-{-LATER:
-
 externallyVisibleId id@(Id _ _ details _ _)
   = if isLocallyDefined id then
        toplevelishId id && isExported id && not (weird_datacon details)
 externallyVisibleId id@(Id _ _ details _ _)
   = if isLocallyDefined id then
        toplevelishId id && isExported id && not (weird_datacon details)
@@ -805,26 +816,22 @@ externallyVisibleId id@(Id _ _ details _ _)
     -- of WeirdLocalType; but we need to know this when asked if
     -- "Mumble" is externally visible...
 
     -- of WeirdLocalType; but we need to know this when asked if
     -- "Mumble" is externally visible...
 
-    weird_datacon (DataConId _ _ _ _ _ _ tycon)
+{- LATER: if at all:
+    weird_datacon (DataConId _ _ _ _ _ _ _ tycon)
       = maybeToBool (maybePurelyLocalTyCon tycon)
       = maybeToBool (maybePurelyLocalTyCon tycon)
+-}
     weird_datacon not_a_datacon_therefore_not_weird = False
 
     weird_tuplecon (TupleConId arity)
       = arity > 32 -- sigh || isBigTupleTyCon tycon -- generated *purely* for local use
     weird_tuplecon _ = False
     weird_datacon not_a_datacon_therefore_not_weird = False
 
     weird_tuplecon (TupleConId arity)
       = arity > 32 -- sigh || isBigTupleTyCon tycon -- generated *purely* for local use
     weird_tuplecon _ = False
--}
 \end{code}
 
 \begin{code}
 idWantsToBeINLINEd :: Id -> Bool
 
 \end{code}
 
 \begin{code}
 idWantsToBeINLINEd :: Id -> Bool
 
-idWantsToBeINLINEd id
-  = panic "Id.idWantsToBeINLINEd"
-{- LATER:
-  = case (getIdUnfolding id) of
-      IWantToBeINLINEd _ -> True
-      _ -> False
--}
+idWantsToBeINLINEd (Id _ _ _ IWantToBeINLINEd _) = True
+idWantsToBeINLINEd _                            = False
 \end{code}
 
 For @unlocaliseId@: See the brief commentary in
 \end{code}
 
 For @unlocaliseId@: See the brief commentary in
@@ -861,7 +868,7 @@ unlocaliseId mod (Id u ty info (WorkerId unwrkr))
       Nothing -> Nothing
       Just xx -> Just (Id u ty info (WorkerId xx))
 
       Nothing -> Nothing
       Just xx -> Just (Id u ty info (WorkerId xx))
 
-unlocaliseId mod (Id u ty info (InstId name))
+unlocaliseId mod (Id u ty info (InstId name no_ftvs))
   = Just (Id u ty info (TopLevId full_name))
        -- type might be wrong, but it hardly matters
        -- at this stage (just before printing C)  ToDo
   = Just (Id u ty info (TopLevId full_name))
        -- type might be wrong, but it hardly matters
        -- at this stage (just before printing C)  ToDo
@@ -902,41 +909,37 @@ The special casing is in @applyTypeEnvToId@, not @apply_to_Id@, as the
 former ``should be'' the usual crunch point.
 
 \begin{code}
 former ``should be'' the usual crunch point.
 
 \begin{code}
-{-LATER:
+type TypeEnv = TyVarEnv Type
+
 applyTypeEnvToId :: TypeEnv -> Id -> Id
 
 applyTypeEnvToId :: TypeEnv -> Id -> Id
 
-applyTypeEnvToId type_env id@(Id u ty info details)
+applyTypeEnvToId type_env id@(Id _ ty _ _ _)
   | idHasNoFreeTyVars id
   = id
   | otherwise
   = apply_to_Id ( \ ty ->
        applyTypeEnvToTy type_env ty
     ) id
   | idHasNoFreeTyVars id
   = id
   | otherwise
   = apply_to_Id ( \ ty ->
        applyTypeEnvToTy type_env ty
     ) id
--}
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-{-LATER:
 apply_to_Id :: (Type -> Type)
            -> Id
            -> Id
 
 apply_to_Id :: (Type -> Type)
            -> Id
            -> Id
 
-apply_to_Id ty_fn (Id u ty info details)
-  = Id u (ty_fn ty) (apply_to_IdInfo ty_fn info) (apply_to_details details)
+apply_to_Id ty_fn (Id u ty details prag info)
+  = let
+       new_ty = ty_fn ty
+    in
+    Id u new_ty (apply_to_details details) prag (apply_to_IdInfo ty_fn info)
   where
   where
-    apply_to_details (InstId inst)
-      = let
-           new_inst = apply_to_Inst ty_fn inst
-       in
-       InstId new_inst
-
     apply_to_details (SpecId unspec ty_maybes no_ftvs)
       = let
            new_unspec = apply_to_Id ty_fn unspec
            new_maybes = map apply_to_maybe ty_maybes
        in
     apply_to_details (SpecId unspec ty_maybes no_ftvs)
       = let
            new_unspec = apply_to_Id ty_fn unspec
            new_maybes = map apply_to_maybe ty_maybes
        in
-       SpecId new_unspec new_maybes no_ftvs
-       -- ToDo: recalc no_ftvs????
+       SpecId new_unspec new_maybes (no_free_tvs ty)
+       -- ToDo: gratuitous recalc no_ftvs???? (also InstId)
       where
        apply_to_maybe Nothing   = Nothing
        apply_to_maybe (Just ty) = Just (ty_fn ty)
       where
        apply_to_maybe Nothing   = Nothing
        apply_to_maybe (Just ty) = Just (ty_fn ty)
@@ -948,7 +951,6 @@ apply_to_Id ty_fn (Id u ty info details)
        WorkerId new_unwrkr
 
     apply_to_details other = other
        WorkerId new_unwrkr
 
     apply_to_details other = other
--}
 \end{code}
 
 Sadly, I don't think the one using the magic typechecker substitution
 \end{code}
 
 Sadly, I don't think the one using the magic typechecker substitution
@@ -970,9 +972,9 @@ applySubstToId subst id@(Id u ty info details)
     case (apply_to_details   s3 new_ty details) of { (s4, new_details) ->
     (s4, Id u new_ty new_info new_details) }}}
   where
     case (apply_to_details   s3 new_ty details) of { (s4, new_details) ->
     (s4, Id u new_ty new_info new_details) }}}
   where
-    apply_to_details subst _ (InstId inst)
+    apply_to_details subst _ (InstId inst no_ftvs)
       = case (applySubstToInst subst inst) of { (s2, new_inst) ->
       = case (applySubstToInst subst inst) of { (s2, new_inst) ->
-       (s2, InstId new_inst) }
+       (s2, InstId new_inst no_ftvs{-ToDo:right???-}) }
 
     apply_to_details subst new_ty (SpecId unspec ty_maybes _)
       = case (applySubstToId subst unspec)          of { (s2, new_unspec) ->
 
     apply_to_details subst new_ty (SpecId unspec ty_maybes _)
       = case (applySubstToId subst unspec)          of { (s2, new_unspec) ->
@@ -995,18 +997,21 @@ applySubstToId subst id@(Id u ty info details)
 
 \begin{code}
 getIdNamePieces :: Bool {-show Uniques-} -> GenId ty -> [FAST_STRING]
 
 \begin{code}
 getIdNamePieces :: Bool {-show Uniques-} -> GenId ty -> [FAST_STRING]
+
 getIdNamePieces show_uniqs id
   = get (unsafeGenId2Id id)
   where
   get (Id u _ details _ _)
     = case details of
 getIdNamePieces show_uniqs id
   = get (unsafeGenId2Id id)
   where
   get (Id u _ details _ _)
     = case details of
-      DataConId n _ _ _ _ _ _ ->
+      DataConId n _ _ _ _ _ _ _ ->
        case (getOrigName n) of { (mod, name) ->
        if fromPrelude mod then [name] else [mod, name] }
 
       TupleConId 0 -> [SLIT("()")]
       TupleConId a -> [_PK_ ( "(" ++ nOfThem (a-1) ',' ++ ")" )]
 
        case (getOrigName n) of { (mod, name) ->
        if fromPrelude mod then [name] else [mod, name] }
 
       TupleConId 0 -> [SLIT("()")]
       TupleConId a -> [_PK_ ( "(" ++ nOfThem (a-1) ',' ++ ")" )]
 
+      RecordSelectorId lbl -> panic "getIdNamePieces:RecordSelectorId"
+
       ImportedId n -> get_fullname_pieces n
       PreludeId  n -> get_fullname_pieces n
       TopLevId   n -> get_fullname_pieces n
       ImportedId n -> get_fullname_pieces n
       PreludeId  n -> get_fullname_pieces n
       TopLevId   n -> get_fullname_pieces n
@@ -1075,7 +1080,7 @@ getIdNamePieces show_uniqs id
 
       LocalId      n _   -> let local = getLocalName n in
                            if show_uniqs then [local, showUnique u] else [local]
 
       LocalId      n _   -> let local = getLocalName n in
                            if show_uniqs then [local, showUnique u] else [local]
-      InstId       n     -> [getLocalName n, showUnique u]
+      InstId       n _   -> [getLocalName n, showUnique u]
       SysLocalId   n _   -> [getLocalName n, showUnique u]
       SpecPragmaId n _ _ -> [getLocalName n, showUnique u]
 
       SysLocalId   n _   -> [getLocalName n, showUnique u]
       SpecPragmaId n _ _ -> [getLocalName n, showUnique u]
 
@@ -1110,7 +1115,7 @@ getMentionedTyConsAndClassesFromId id
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
---getIdPrimRep i = primRepFromType (idType i)
+idPrimRep i = typePrimRep (idType i)
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -1140,7 +1145,7 @@ mkConstMethodId   u c op ity full_ty from_here modname info
 
 mkWorkerId u unwrkr ty info = Id u ty (WorkerId unwrkr) NoPragmaInfo info
 
 
 mkWorkerId u unwrkr ty info = Id u ty (WorkerId unwrkr) NoPragmaInfo info
 
-mkInstId uniq ty name = Id uniq ty (InstId name) NoPragmaInfo noIdInfo
+mkInstId uniq ty name = Id uniq ty (InstId name (no_free_tvs ty)) NoPragmaInfo noIdInfo
 
 {-LATER:
 getConstMethodId clas op ty
 
 {-LATER:
 getConstMethodId clas op ty
@@ -1151,14 +1156,13 @@ getConstMethodId clas op ty
     in
     case (lookupConstMethodId (getIdSpecialisation sel_id) ty) of
       Just xx -> xx
     in
     case (lookupConstMethodId (getIdSpecialisation sel_id) ty) of
       Just xx -> xx
-      Nothing -> error (ppShow 80 (ppAboves [
-       ppCat [ppStr "ERROR: getConstMethodId:", ppr PprDebug op,
-              ppr PprDebug ty, ppr PprDebug ops, ppr PprDebug op_ids,
+      Nothing -> pprError "ERROR: getConstMethodId:" (ppAboves [
+       ppCat [ppr PprDebug ty, ppr PprDebug ops, ppr PprDebug op_ids,
               ppr PprDebug sel_id],
        ppStr "(This can arise if an interface pragma refers to an instance",
        ppStr "but there is no imported interface which *defines* that instance.",
        ppStr "The info above, however ugly, should indicate what else you need to import."
               ppr PprDebug sel_id],
        ppStr "(This can arise if an interface pragma refers to an instance",
        ppStr "but there is no imported interface which *defines* that instance.",
        ppStr "The info above, however ugly, should indicate what else you need to import."
-       ]))
+       ])
 -}
 \end{code}
 
 -}
 \end{code}
 
@@ -1228,36 +1232,29 @@ mkSameSpecCon ty_maybes unspec@(Id u ty info details)
   where
     new_ty = specialiseTy ty ty_maybes 0
 
   where
     new_ty = specialiseTy ty ty_maybes 0
 
-    -- pprTrace "SameSpecCon:Unique:"
-    --         (ppSep (ppr PprDebug unspec: [pprMaybeTy PprDebug ty | ty <- ty_maybes]))
-
 localiseId :: Id -> Id
 localiseId id@(Id u ty info details)
   = Id u ty info (LocalId (mkShortName name loc) (no_free_tvs ty))
   where
     name = getOccurrenceName id
     loc  = getSrcLoc id
 localiseId :: Id -> Id
 localiseId id@(Id u ty info details)
   = Id u ty info (LocalId (mkShortName name loc) (no_free_tvs ty))
   where
     name = getOccurrenceName id
     loc  = getSrcLoc id
+-}
 
 
--- this has to be one of the "local" flavours (LocalId, SysLocalId, InstId)
--- ToDo: it does??? WDP
 mkIdWithNewUniq :: Id -> Unique -> Id
 
 mkIdWithNewUniq :: Id -> Unique -> Id
 
-mkIdWithNewUniq (Id _ ty info details) uniq
-  = Id uniq ty info new_details
--}
+mkIdWithNewUniq (Id _ ty details prag info) uniq
+  = Id uniq ty details prag info
 \end{code}
 
 Make some local @Ids@ for a template @CoreExpr@.  These have bogus
 @Uniques@, but that's OK because the templates are supposed to be
 instantiated before use.
 \begin{code}
 \end{code}
 
 Make some local @Ids@ for a template @CoreExpr@.  These have bogus
 @Uniques@, but that's OK because the templates are supposed to be
 instantiated before use.
 \begin{code}
-{-LATER:
 mkTemplateLocals :: [Type] -> [Id]
 mkTemplateLocals tys
 mkTemplateLocals :: [Type] -> [Id]
 mkTemplateLocals tys
-  = zipWith (\ u -> \ ty -> mkSysLocal SLIT("tpl") u ty mkUnknownSrcLoc)
+  = zipWith (\ u -> \ ty -> mkSysLocal SLIT("tpl") u ty mkBuiltinSrcLoc)
            (getBuiltinUniques (length tys))
            tys
            (getBuiltinUniques (length tys))
            tys
--}
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -1293,11 +1290,11 @@ besides the code-generator need arity info!)
 getIdArity :: Id -> ArityInfo
 getIdArity (Id _ _ _ _ id_info)  = getInfo id_info
 
 getIdArity :: Id -> ArityInfo
 getIdArity (Id _ _ _ _ id_info)  = getInfo id_info
 
-getDataConArity :: DataCon -> Int
-getDataConArity id@(Id _ _ _ _ id_info)
+dataConArity :: DataCon -> Int
+dataConArity id@(Id _ _ _ _ id_info)
   = ASSERT(isDataCon id)
     case (arityMaybe (getInfo id_info)) of
   = ASSERT(isDataCon id)
     case (arityMaybe (getInfo id_info)) of
-      Nothing -> pprPanic "getDataConArity:Nothing:" (ppr PprDebug id)
+      Nothing -> pprPanic "dataConArity:Nothing:" (pprId PprDebug id)
       Just  i -> i
 
 addIdArity :: Id -> Int -> Id
       Just  i -> i
 
 addIdArity :: Id -> Int -> Id
@@ -1314,13 +1311,13 @@ addIdArity (Id u ty details pinfo info) arity
 \begin{code}
 mkDataCon :: Unique{-DataConKey-}
          -> FullName
 \begin{code}
 mkDataCon :: Unique{-DataConKey-}
          -> FullName
-         -> [StrictnessMark]
+         -> [StrictnessMark] -> [FieldLabel]
          -> [TyVar] -> ThetaType -> [TauType] -> TyCon
 --ToDo:   -> SpecEnv
          -> Id
   -- can get the tag and all the pieces of the type from the Type
 
          -> [TyVar] -> ThetaType -> [TauType] -> TyCon
 --ToDo:   -> SpecEnv
          -> Id
   -- can get the tag and all the pieces of the type from the Type
 
-mkDataCon k n stricts tvs ctxt args_tys tycon
+mkDataCon k n stricts fields tvs ctxt args_tys tycon
   = ASSERT(length stricts == length args_tys)
     data_con
   where
   = ASSERT(length stricts == length args_tys)
     data_con
   where
@@ -1329,13 +1326,13 @@ mkDataCon k n stricts tvs ctxt args_tys tycon
     data_con
       = Id k
           type_of_constructor
     data_con
       = Id k
           type_of_constructor
-          (DataConId n data_con_tag stricts tvs ctxt args_tys tycon)
+          (DataConId n data_con_tag stricts fields tvs ctxt args_tys tycon)
           NoPragmaInfo
           datacon_info
 
     data_con_tag    = position_within fIRST_TAG data_con_family
 
           NoPragmaInfo
           datacon_info
 
     data_con_tag    = position_within fIRST_TAG data_con_family
 
-    data_con_family = getTyConDataCons tycon
+    data_con_family = tyConDataCons tycon
 
     position_within :: Int -> [Id] -> Int
 
 
     position_within :: Int -> [Id] -> Int
 
@@ -1450,36 +1447,53 @@ fIRST_TAG =  1  -- Tags allocated from here for real constructors
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-getDataConTag :: DataCon -> ConTag     -- will panic if not a DataCon
-getDataConTag  (Id _ _ (DataConId _ tag _ _ _ _ _) _ _) = tag
-getDataConTag  (Id _ _ (TupleConId _) _ _)              = fIRST_TAG
-getDataConTag  (Id _ _ (SpecId unspec _ _) _ _)         = getDataConTag unspec
+dataConTag :: DataCon -> ConTag        -- will panic if not a DataCon
+dataConTag     (Id _ _ (DataConId _ tag _ _ _ _ _ _) _ _) = tag
+dataConTag     (Id _ _ (TupleConId _) _ _)              = fIRST_TAG
+dataConTag     (Id _ _ (SpecId unspec _ _) _ _)         = dataConTag unspec
 
 
-getDataConTyCon :: DataCon -> TyCon    -- will panic if not a DataCon
-getDataConTyCon (Id _ _ (DataConId _ _ _ _ _ _ tycon) _ _) = tycon
-getDataConTyCon (Id _ _ (TupleConId a) _ _)               = mkTupleTyCon a
+dataConTyCon :: DataCon -> TyCon       -- will panic if not a DataCon
+dataConTyCon (Id _ _ (DataConId _ _ _ _ _ _ _ tycon) _ _) = tycon
+dataConTyCon (Id _ _ (TupleConId a) _ _)                  = mkTupleTyCon a
 
 
-getDataConSig :: DataCon -> ([TyVar], ThetaType, [TauType], TyCon)
+dataConSig :: DataCon -> ([TyVar], ThetaType, [TauType], TyCon)
                                        -- will panic if not a DataCon
 
                                        -- will panic if not a DataCon
 
-getDataConSig (Id _ _ (DataConId _ _ _ tyvars theta_ty arg_tys tycon) _ _)
+dataConSig (Id _ _ (DataConId _ _ _ _ tyvars theta_ty arg_tys tycon) _ _)
   = (tyvars, theta_ty, arg_tys, tycon)
 
   = (tyvars, theta_ty, arg_tys, tycon)
 
-getDataConSig (Id _ _ (TupleConId arity) _ _)
+dataConSig (Id _ _ (TupleConId arity) _ _)
   = (tyvars, [], tyvar_tys, mkTupleTyCon arity)
   where
     tyvars     = take arity alphaTyVars
     tyvar_tys  = mkTyVarTys tyvars
   = (tyvars, [], tyvar_tys, mkTupleTyCon arity)
   where
     tyvars     = take arity alphaTyVars
     tyvar_tys  = mkTyVarTys tyvars
+
+dataConFieldLabels :: DataCon -> [FieldLabel]
+dataConFieldLabels (Id _ _ (DataConId _ _ _ fields _ _ _ _) _ _) = fields
+\end{code}
+
+\begin{code}
+mkRecordSelectorId field_label selector_ty
+  = Id (getItsUnique name)
+       selector_ty
+       (RecordSelectorId field_label)
+       NoPragmaInfo
+       noIdInfo
+  where
+    name = fieldLabelName field_label
+
+recordSelectorFieldLabel :: Id -> FieldLabel
+recordSelectorFieldLabel (Id _ _ (RecordSelectorId lbl) _ _) = lbl
 \end{code}
 
 {- LATER
 \end{code}
 
 {- LATER
-getDataConTyCon        (Id _ _ _ (SpecId unspec tys _))
-  = mkSpecTyCon (getDataConTyCon unspec) tys
+dataConTyCon   (Id _ _ _ (SpecId unspec tys _))
+  = mkSpecTyCon (dataConTyCon unspec) tys
 
 
-getDataConSig (Id _ _ _ (SpecId unspec ty_maybes _))
+dataConSig (Id _ _ _ (SpecId unspec ty_maybes _))
   = (spec_tyvars, spec_theta_ty, spec_arg_tys, spec_tycon)
   where
   = (spec_tyvars, spec_theta_ty, spec_arg_tys, spec_tycon)
   where
-    (tyvars, theta_ty, arg_tys, tycon) = getDataConSig unspec
+    (tyvars, theta_ty, arg_tys, tycon) = dataConSig unspec
 
     ty_env = tyvars `zip` ty_maybes
 
 
     ty_env = tyvars `zip` ty_maybes
 
@@ -1493,7 +1507,7 @@ getDataConSig (Id _ _ _ (SpecId unspec ty_maybes _))
     spec_arg_tys = map (instantiateTauTy spec_env) arg_tys
 
     spec_theta_ty = if null theta_ty then []
     spec_arg_tys = map (instantiateTauTy spec_env) arg_tys
 
     spec_theta_ty = if null theta_ty then []
-                   else panic "getDataConSig:ThetaTy:SpecDataCon"
+                   else panic "dataConSig:ThetaTy:SpecDataCon"
     spec_tycon    = mkSpecTyCon tycon ty_maybes
 -}
 \end{code}
     spec_tycon    = mkSpecTyCon tycon ty_maybes
 -}
 \end{code}
@@ -1516,7 +1530,7 @@ getInstantiatedDataConSig ::
 getInstantiatedDataConSig data_con inst_tys
   = ASSERT(isDataCon data_con)
     let
 getInstantiatedDataConSig data_con inst_tys
   = ASSERT(isDataCon data_con)
     let
-       (tvs, theta, arg_tys, tycon) = getDataConSig data_con
+       (tvs, theta, arg_tys, tycon) = dataConSig data_con
 
        inst_env = ASSERT(length tvs == length inst_tys)
                   tvs `zip` inst_tys
 
        inst_env = ASSERT(length tvs == length inst_tys)
                   tvs `zip` inst_tys
@@ -1698,7 +1712,6 @@ because a specialised data constructor has the same Unique as its
 unspecialised counterpart.
 
 \begin{code}
 unspecialised counterpart.
 
 \begin{code}
-{-LATER:
 cmpId_withSpecDataCon :: Id -> Id -> TAG_
 
 cmpId_withSpecDataCon id1 id2
 cmpId_withSpecDataCon :: Id -> Id -> TAG_
 
 cmpId_withSpecDataCon id1 id2
@@ -1711,18 +1724,12 @@ cmpId_withSpecDataCon id1 id2
     cmp_ids = cmpId id1 id2
     eq_ids  = case cmp_ids of { EQ_ -> True; other -> False }
 
     cmp_ids = cmpId id1 id2
     eq_ids  = case cmp_ids of { EQ_ -> True; other -> False }
 
-cmpEqDataCon (Id _ _ _ (SpecId _ mtys1 _)) (Id _ _ _ (SpecId _ mtys2 _))
-  = cmpUniTypeMaybeList mtys1 mtys2
-
-cmpEqDataCon unspec1 (Id _ _ _ (SpecId _ _ _))
-  = LT_
-
-cmpEqDataCon (Id _ _ _ (SpecId _ _ _)) unspec2
-  = GT_
+cmpEqDataCon (Id _ _ (SpecId _ mtys1 _) _ _) (Id _ _ (SpecId _ mtys2 _) _ _)
+  = panic# "Id.cmpEqDataCon:cmpUniTypeMaybeList mtys1 mtys2"
 
 
-cmpEqDataCon unspec1 unspec2
-  = EQ_
--}
+cmpEqDataCon _ (Id _ _ (SpecId _ _ _) _ _) = LT_
+cmpEqDataCon (Id _ _ (SpecId _ _ _) _ _) _ = GT_
+cmpEqDataCon _                          _ = EQ_
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -1735,6 +1742,10 @@ cmpEqDataCon unspec1 unspec2
 instance Outputable ty => Outputable (GenId ty) where
     ppr sty id = pprId sty id
 
 instance Outputable ty => Outputable (GenId ty) where
     ppr sty id = pprId sty id
 
+-- and a SPECIALIZEd one:
+instance Outputable {-Id, i.e.:-}(GenId Type) where
+    ppr sty id = pprId sty id
+
 showId :: PprStyle -> Id -> String
 showId sty id = ppShow 80 (pprId sty id)
 
 showId :: PprStyle -> Id -> String
 showId sty id = ppShow 80 (pprId sty id)
 
@@ -1778,13 +1789,12 @@ pprId other_sty id
   = let
        pieces = getIdNamePieces (case other_sty of {PprForUser -> False; _ -> True}) id
 
   = let
        pieces = getIdNamePieces (case other_sty of {PprForUser -> False; _ -> True}) id
 
-       for_code = panic "pprId: for code"
-       {-  = let
+       for_code
+         = let
                pieces_to_print -- maybe use Unique only
                  = if isSysLocalId id then tail pieces else pieces
            in
            ppIntersperse (ppPStr cSEP) (map identToC pieces_to_print)
                pieces_to_print -- maybe use Unique only
                  = if isSysLocalId id then tail pieces else pieces
            in
            ppIntersperse (ppPStr cSEP) (map identToC pieces_to_print)
-       -}
     in
     case other_sty of
       PprForC        -> for_code
     in
     case other_sty of
       PprForC        -> for_code
@@ -1810,12 +1820,12 @@ pprId other_sty id
       = ppBeside (pp_ubxd (ppIntersperse (ppChar '.') (map ppPStr pieces))) (pp_uniq id)
 
     pp_uniq (Id _ _ (PreludeId _) _ _)                    = ppNil -- no uniq to add
       = ppBeside (pp_ubxd (ppIntersperse (ppChar '.') (map ppPStr pieces))) (pp_uniq id)
 
     pp_uniq (Id _ _ (PreludeId _) _ _)                    = ppNil -- no uniq to add
-    pp_uniq (Id _ _ (DataConId _ _ _ _ _ _ _) _ _) = ppNil
+    pp_uniq (Id _ _ (DataConId _ _ _ _ _ _ _ _) _ _) = ppNil
     pp_uniq (Id _ _ (TupleConId _) _ _)           = ppNil
     pp_uniq (Id _ _ (LocalId _ _) _ _)            = ppNil -- uniq printed elsewhere
     pp_uniq (Id _ _ (SysLocalId _ _) _ _)         = ppNil
     pp_uniq (Id _ _ (SpecPragmaId _ _ _) _ _)     = ppNil
     pp_uniq (Id _ _ (TupleConId _) _ _)           = ppNil
     pp_uniq (Id _ _ (LocalId _ _) _ _)            = ppNil -- uniq printed elsewhere
     pp_uniq (Id _ _ (SysLocalId _ _) _ _)         = ppNil
     pp_uniq (Id _ _ (SpecPragmaId _ _ _) _ _)     = ppNil
-    pp_uniq (Id _ _ (InstId _) _ _)               = ppNil
+    pp_uniq (Id _ _ (InstId _ _) _ _)                     = ppNil
     pp_uniq other_id = ppBesides [ppPStr SLIT("{-"), pprUnique (getItsUnique other_id), ppPStr SLIT("-}")]
 
     -- print PprDebug Ids with # afterwards if they are of primitive type.
     pp_uniq other_id = ppBesides [ppPStr SLIT("{-"), pprUnique (getItsUnique other_id), ppPStr SLIT("-}")]
 
     -- print PprDebug Ids with # afterwards if they are of primitive type.
@@ -1834,8 +1844,9 @@ instance NamedThing (GenId ty) where
     getExportFlag (Id _ _ details _ _)
       = get details
       where
     getExportFlag (Id _ _ details _ _)
       = get details
       where
-       get (DataConId _ _ _ _ _ _ tc)= getExportFlag tc -- NB: don't use the FullName
+       get (DataConId _ _ _ _ _ _ _ tc)= getExportFlag tc -- NB: don't use the FullName
        get (TupleConId _)          = NotExported
        get (TupleConId _)          = NotExported
+       get (RecordSelectorId l)    = getExportFlag l
        get (ImportedId  n)         = getExportFlag n
        get (PreludeId   n)         = getExportFlag n
        get (TopLevId    n)         = getExportFlag n
        get (ImportedId  n)         = getExportFlag n
        get (PreludeId   n)         = getExportFlag n
        get (TopLevId    n)         = getExportFlag n
@@ -1846,7 +1857,7 @@ instance NamedThing (GenId ty) where
        get (ConstMethodId c ty _ from_here _) = instance_export_flag c ty from_here
        get (SpecId unspec _ _)     = getExportFlag unspec
        get (WorkerId unwrkr)       = getExportFlag unwrkr
        get (ConstMethodId c ty _ from_here _) = instance_export_flag c ty from_here
        get (SpecId unspec _ _)     = getExportFlag unspec
        get (WorkerId unwrkr)       = getExportFlag unwrkr
-       get (InstId _)              = NotExported
+       get (InstId _ _)            = NotExported
        get (LocalId      _ _)      = NotExported
        get (SysLocalId   _ _)      = NotExported
        get (SpecPragmaId _ _ _)    = NotExported
        get (LocalId      _ _)      = NotExported
        get (SysLocalId   _ _)      = NotExported
        get (SpecPragmaId _ _ _)    = NotExported
@@ -1854,10 +1865,11 @@ instance NamedThing (GenId ty) where
     isLocallyDefined this_id@(Id _ _ details _ _)
       = get details
       where
     isLocallyDefined this_id@(Id _ _ details _ _)
       = get details
       where
-       get (DataConId _ _ _ _ _ _ tc)= isLocallyDefined tc -- NB: don't use the FullName
+       get (DataConId _ _ _ _ _ _ _ tc)= isLocallyDefined tc -- NB: don't use the FullName
        get (TupleConId _)          = False
        get (ImportedId _)          = False
        get (PreludeId  _)          = False
        get (TupleConId _)          = False
        get (ImportedId _)          = False
        get (PreludeId  _)          = False
+       get (RecordSelectorId l)    = isLocallyDefined l
        get (TopLevId   n)          = isLocallyDefined n
        get (SuperDictSelId c _)    = isLocallyDefined c
        get (MethodSelId c _)       = isLocallyDefined c
        get (TopLevId   n)          = isLocallyDefined n
        get (SuperDictSelId c _)    = isLocallyDefined c
        get (MethodSelId c _)       = isLocallyDefined c
@@ -1870,7 +1882,7 @@ instance NamedThing (GenId ty) where
        get (ConstMethodId c tyc _ from_here _) = from_here
        get (SpecId unspec _ _)     = isLocallyDefined unspec
        get (WorkerId unwrkr)       = isLocallyDefined unwrkr
        get (ConstMethodId c tyc _ from_here _) = from_here
        get (SpecId unspec _ _)     = isLocallyDefined unspec
        get (WorkerId unwrkr)       = isLocallyDefined unwrkr
-       get (InstId  _)             = True
+       get (InstId  _ _)           = True
        get (LocalId      _ _)      = True
        get (SysLocalId   _ _)      = True
        get (SpecPragmaId _ _ _)    = True
        get (LocalId      _ _)      = True
        get (SysLocalId   _ _)      = True
        get (SpecPragmaId _ _ _)    = True
@@ -1878,9 +1890,10 @@ instance NamedThing (GenId ty) where
     getOrigName this_id@(Id u _ details _ _)
       = get details
       where
     getOrigName this_id@(Id u _ details _ _)
       = get details
       where
-       get (DataConId n _ _ _ _ _ _) =  getOrigName n
+       get (DataConId n _ _ _ _ _ _ _) =        getOrigName n
        get (TupleConId 0)      = (pRELUDE_BUILTIN, SLIT("()"))
        get (TupleConId a)      = (pRELUDE_BUILTIN, _PK_ ( "(" ++ nOfThem (a-1) ',' ++ ")" ))
        get (TupleConId 0)      = (pRELUDE_BUILTIN, SLIT("()"))
        get (TupleConId a)      = (pRELUDE_BUILTIN, _PK_ ( "(" ++ nOfThem (a-1) ',' ++ ")" ))
+       get (RecordSelectorId l)= getOrigName l
        get (ImportedId   n)    = getOrigName n
        get (PreludeId    n)    = getOrigName n
        get (TopLevId     n)    = getOrigName n
        get (ImportedId   n)    = getOrigName n
        get (PreludeId    n)    = getOrigName n
        get (TopLevId     n)    = getOrigName n
@@ -1911,7 +1924,7 @@ instance NamedThing (GenId ty) where
            BEND
 -}
 
            BEND
 -}
 
-       get (InstId       n)    = (panic "NamedThing.Id.getOrigName (LocalId)",
+       get (InstId       n _)  = (panic "NamedThing.Id.getOrigName (LocalId)",
                                   getLocalName n)
        get (LocalId      n _)  = (panic "NamedThing.Id.getOrigName (LocalId)",
                                   getLocalName n)
                                   getLocalName n)
        get (LocalId      n _)  = (panic "NamedThing.Id.getOrigName (LocalId)",
                                   getLocalName n)
@@ -1933,9 +1946,10 @@ instance NamedThing (GenId ty) where
     getOccurrenceName this_id@(Id _ _ details _ _)
       = get details
       where
     getOccurrenceName this_id@(Id _ _ details _ _)
       = get details
       where
-       get (DataConId  n _ _ _ _ _ _) = getOccurrenceName n
+       get (DataConId  n _ _ _ _ _ _ _) = getOccurrenceName n
        get (TupleConId 0)      = SLIT("()")
        get (TupleConId a)      = _PK_ ( "(" ++ nOfThem (a-1) ',' ++ ")" )
        get (TupleConId 0)      = SLIT("()")
        get (TupleConId a)      = _PK_ ( "(" ++ nOfThem (a-1) ',' ++ ")" )
+       get (RecordSelectorId l)= getOccurrenceName l
        get (ImportedId  n)     = getOccurrenceName n
        get (PreludeId   n)     = getOccurrenceName n
        get (TopLevId    n)     = getOccurrenceName n
        get (ImportedId  n)     = getOccurrenceName n
        get (PreludeId   n)     = getOccurrenceName n
        get (TopLevId    n)     = getOccurrenceName n
@@ -1947,8 +1961,9 @@ instance NamedThing (GenId ty) where
     getSrcLoc (Id _ _ details _ id_info)
       = get details
       where
     getSrcLoc (Id _ _ details _ id_info)
       = get details
       where
-       get (DataConId  n _ _ _ _ _ _) = getSrcLoc n
+       get (DataConId  n _ _ _ _ _ _ _) = getSrcLoc n
        get (TupleConId _)      = mkBuiltinSrcLoc
        get (TupleConId _)      = mkBuiltinSrcLoc
+       get (RecordSelectorId l)= getSrcLoc l
        get (ImportedId  n)     = getSrcLoc n
        get (PreludeId   n)     = getSrcLoc n
        get (TopLevId    n)     = getSrcLoc n
        get (ImportedId  n)     = getSrcLoc n
        get (PreludeId   n)     = getSrcLoc n
        get (TopLevId    n)     = getSrcLoc n
@@ -1956,7 +1971,7 @@ instance NamedThing (GenId ty) where
        get (MethodSelId c _)   = getSrcLoc c
        get (SpecId unspec _ _) = getSrcLoc unspec
        get (WorkerId unwrkr)   = getSrcLoc unwrkr
        get (MethodSelId c _)   = getSrcLoc c
        get (SpecId unspec _ _) = getSrcLoc unspec
        get (WorkerId unwrkr)   = getSrcLoc unwrkr
-       get (InstId       n)    = getSrcLoc n
+       get (InstId       n _)  = getSrcLoc n
        get (LocalId      n _)  = getSrcLoc n
        get (SysLocalId   n _)  = getSrcLoc n
        get (SpecPragmaId n _ _)= getSrcLoc n
        get (LocalId      n _)  = getSrcLoc n
        get (SysLocalId   n _)  = getSrcLoc n
        get (SpecPragmaId n _ _)= getSrcLoc n
@@ -1968,8 +1983,9 @@ instance NamedThing (GenId ty) where
     fromPreludeCore (Id _ _ details _ _)
       = get details
       where
     fromPreludeCore (Id _ _ details _ _)
       = get details
       where
-       get (DataConId _ _ _ _ _ _ tc)= fromPreludeCore tc -- NB: not from the FullName
+       get (DataConId _ _ _ _ _ _ _ tc)= fromPreludeCore tc -- NB: not from the FullName
        get (TupleConId _)          = True
        get (TupleConId _)          = True
+       get (RecordSelectorId l)    = fromPreludeCore l
        get (ImportedId  n)         = fromPreludeCore n
        get (PreludeId   n)         = fromPreludeCore n
        get (TopLevId    n)         = fromPreludeCore n
        get (ImportedId  n)         = fromPreludeCore n
        get (PreludeId   n)         = fromPreludeCore n
        get (TopLevId    n)         = fromPreludeCore n
@@ -1980,7 +1996,7 @@ instance NamedThing (GenId ty) where
        get (ConstMethodId c t _ _ _) = fromPreludeCore c && is_prelude_core_ty t
        get (SpecId unspec _ _)     = fromPreludeCore unspec
        get (WorkerId unwrkr)       = fromPreludeCore unwrkr
        get (ConstMethodId c t _ _ _) = fromPreludeCore c && is_prelude_core_ty t
        get (SpecId unspec _ _)     = fromPreludeCore unspec
        get (WorkerId unwrkr)       = fromPreludeCore unwrkr
-       get (InstId       _)        = False
+       get (InstId       _ _)      = False
        get (LocalId      _ _)      = False
        get (SysLocalId   _ _)      = False
        get (SpecPragmaId _ _ _)    = False
        get (LocalId      _ _)      = False
        get (SysLocalId   _ _)      = False
        get (SpecPragmaId _ _ _)    = False
@@ -2030,7 +2046,7 @@ mapIdEnv   = mapUFM
 mkIdEnv                 = listToUFM
 nullIdEnv       = emptyUFM
 rngIdEnv        = eltsUFM
 mkIdEnv                 = listToUFM
 nullIdEnv       = emptyUFM
 rngIdEnv        = eltsUFM
-unitIdEnv       = singletonUFM
+unitIdEnv       = unitUFM
 
 growIdEnvList    env pairs = plusUFM env (listToUFM pairs)
 isNullIdEnv      env       = sizeUFM env == 0
 
 growIdEnvList    env pairs = plusUFM env (listToUFM pairs)
 isNullIdEnv      env       = sizeUFM env == 0
@@ -2054,14 +2070,16 @@ intersectIdSets :: GenIdSet ty -> GenIdSet ty -> GenIdSet ty
 unionIdSets    :: GenIdSet ty -> GenIdSet ty -> GenIdSet ty
 unionManyIdSets        :: [GenIdSet ty] -> GenIdSet ty
 idSetToList    :: GenIdSet ty -> [GenId ty]
 unionIdSets    :: GenIdSet ty -> GenIdSet ty -> GenIdSet ty
 unionManyIdSets        :: [GenIdSet ty] -> GenIdSet ty
 idSetToList    :: GenIdSet ty -> [GenId ty]
-singletonIdSet :: GenId ty -> GenIdSet ty
+unitIdSet      :: GenId ty -> GenIdSet ty
+addOneToIdSet  :: GenIdSet ty -> GenId ty -> GenIdSet ty
 elementOfIdSet :: GenId ty -> GenIdSet ty -> Bool
 minusIdSet     :: GenIdSet ty -> GenIdSet ty -> GenIdSet ty
 isEmptyIdSet   :: GenIdSet ty -> Bool
 mkIdSet                :: [GenId ty] -> GenIdSet ty
 
 emptyIdSet     = emptyUniqSet
 elementOfIdSet :: GenId ty -> GenIdSet ty -> Bool
 minusIdSet     :: GenIdSet ty -> GenIdSet ty -> GenIdSet ty
 isEmptyIdSet   :: GenIdSet ty -> Bool
 mkIdSet                :: [GenId ty] -> GenIdSet ty
 
 emptyIdSet     = emptyUniqSet
-singletonIdSet = singletonUniqSet
+unitIdSet      = unitUniqSet
+addOneToIdSet  = addOneToUniqSet
 intersectIdSets        = intersectUniqSets
 unionIdSets    = unionUniqSets
 unionManyIdSets        = unionManyUniqSets
 intersectIdSets        = intersectUniqSets
 unionIdSets    = unionUniqSets
 unionManyIdSets        = unionManyUniqSets
index b2594b3..8f35f6a 100644 (file)
@@ -76,7 +76,7 @@ import IdLoop         -- IdInfo is a dependency-loop ranch, and
 
 import CmdLineOpts     ( opt_OmitInterfacePragmas )
 import Maybes          ( firstJust )
 
 import CmdLineOpts     ( opt_OmitInterfacePragmas )
 import Maybes          ( firstJust )
-import MatchEnv                ( nullMEnv, mEnvToList )
+import MatchEnv                ( nullMEnv, isEmptyMEnv, mEnvToList )
 import Outputable      ( ifPprInterface, Outputable(..){-instances-} )
 import PprStyle                ( PprStyle(..) )
 import Pretty
 import Outputable      ( ifPprInterface, Outputable(..){-instances-} )
 import PprStyle                ( PprStyle(..) )
 import Pretty
@@ -85,7 +85,6 @@ import Type           ( eqSimpleTy )
 import Util            ( mapAccumL, panic, assertPanic, pprPanic )
 
 applySubstToTy = panic "IdInfo.applySubstToTy"
 import Util            ( mapAccumL, panic, assertPanic, pprPanic )
 
 applySubstToTy = panic "IdInfo.applySubstToTy"
-isUnboxedDataType = panic "IdInfo.isUnboxedDataType"
 splitTypeWithDictsAsArgs = panic "IdInfo.splitTypeWithDictsAsArgs"
 showTypeCategory = panic "IdInfo.showTypeCategory"
 mkFormSummary = panic "IdInfo.mkFormSummary"
 splitTypeWithDictsAsArgs = panic "IdInfo.splitTypeWithDictsAsArgs"
 showTypeCategory = panic "IdInfo.showTypeCategory"
 mkFormSummary = panic "IdInfo.mkFormSummary"
@@ -180,8 +179,11 @@ Simply turgid.  But BE CAREFUL: don't @apply_to_Id@ if that @Id@
 will in turn @apply_to_IdInfo@ of the self-same @IdInfo@.  (A very
 nasty loop, friends...)
 \begin{code}
 will in turn @apply_to_IdInfo@ of the self-same @IdInfo@.  (A very
 nasty loop, friends...)
 \begin{code}
-apply_to_IdInfo ty_fn (IdInfo arity demand spec strictness unfold
+apply_to_IdInfo ty_fn idinfo@(IdInfo arity demand spec strictness unfold
                              update deforest arg_usage fb_ww srcloc)
                              update deforest arg_usage fb_ww srcloc)
+  | isEmptyMEnv spec
+  = idinfo
+  | otherwise
   = panic "IdInfo:apply_to_IdInfo"
 {- LATER:
     let
   = panic "IdInfo:apply_to_IdInfo"
 {- LATER:
     let
index 7cc2c63..bdc4f12 100644 (file)
@@ -17,10 +17,10 @@ import Id           ( externallyVisibleId, isDataCon, isWorkerId, isWrapperId,
                        )
 import IdInfo          ( IdInfo )
 import Literal         ( Literal )
                        )
 import IdInfo          ( IdInfo )
 import Literal         ( Literal )
-import MagicUFs                ( MagicUnfoldingFun )
+import MagicUFs                ( mkMagicUnfoldingFun, MagicUnfoldingFun )
 import Outputable      ( Outputable(..) )
 import PprStyle                ( PprStyle )
 import Outputable      ( Outputable(..) )
 import PprStyle                ( PprStyle )
-import PprType         ( pprParendType )
+import PprType         ( pprParendGenType )
 import Pretty          ( PrettyRep )
 import Type            ( GenType )
 import TyVar           ( GenTyVar )
 import Pretty          ( PrettyRep )
 import Type            ( GenType )
 import TyVar           ( GenTyVar )
@@ -39,9 +39,11 @@ getIdInfo            :: Id       -> IdInfo
 nullIdEnv              :: UniqFM a
 lookupIdEnv            :: UniqFM b -> GenId a -> Maybe b
 mAX_WORKER_ARGS                :: Int
 nullIdEnv              :: UniqFM a
 lookupIdEnv            :: UniqFM b -> GenId a -> Maybe b
 mAX_WORKER_ARGS                :: Int
-pprParendType          :: (Eq a, Outputable a, Eq b, Outputable b) => PprStyle -> GenType a b -> Int -> Bool -> PrettyRep
+pprParendGenType               :: (Eq a, Outputable a, Eq b, Outputable b) => PprStyle -> GenType a b -> Int -> Bool -> PrettyRep
 unTagBinders :: GenCoreExpr (GenId (GenType (GenTyVar (GenUsage Unique)) Unique), a) b c d -> GenCoreExpr (GenId (GenType (GenTyVar (GenUsage Unique)) Unique)) b c d
 
 unTagBinders :: GenCoreExpr (GenId (GenType (GenTyVar (GenUsage Unique)) Unique), a) b c d -> GenCoreExpr (GenId (GenType (GenTyVar (GenUsage Unique)) Unique)) b c d
 
+mkMagicUnfoldingFun    :: Unique -> MagicUnfoldingFun
+
 type IdEnv a = UniqFM a
 type CoreExpr = GenCoreExpr (GenId (GenType (GenTyVar (GenUsage Unique)) Unique))
                            (GenId (GenType (GenTyVar (GenUsage Unique)) Unique))
 type IdEnv a = UniqFM a
 type CoreExpr = GenCoreExpr (GenId (GenType (GenTyVar (GenUsage Unique)) Unique))
                            (GenId (GenType (GenTyVar (GenUsage Unique)) Unique))
index 00fcbab..c809a49 100644 (file)
@@ -28,7 +28,7 @@ import Outputable     ( ExportFlag(..) )
 import Pretty
 import PprStyle                ( PprStyle(..) )
 import SrcLoc          ( mkBuiltinSrcLoc, mkUnknownSrcLoc )
 import Pretty
 import PprStyle                ( PprStyle(..) )
 import SrcLoc          ( mkBuiltinSrcLoc, mkUnknownSrcLoc )
-import TyCon           ( TyCon, getSynTyConArity )
+import TyCon           ( TyCon, synTyConArity )
 import TyVar           ( GenTyVar )
 import Unique          ( pprUnique, Unique )
 import Util            ( panic, panic#, pprPanic )
 import TyVar           ( GenTyVar )
 import Unique          ( pprUnique, Unique )
 import Util            ( panic, panic#, pprPanic )
@@ -129,7 +129,7 @@ getTagFromClassOpName (ClassOpName _ _ _ tag)  = tag
 
 getSynNameArity :: Name -> Maybe Arity
 getSynNameArity (TyConName _ _ arity False{-syn-} _) = Just arity
 
 getSynNameArity :: Name -> Maybe Arity
 getSynNameArity (TyConName _ _ arity False{-syn-} _) = Just arity
-getSynNameArity (WiredInTyCon tycon)                = getSynTyConArity tycon
+getSynNameArity (WiredInTyCon tycon)                = synTyConArity tycon
 getSynNameArity other_name                          = Nothing
 
 getNameShortName :: Name -> ShortName
 getSynNameArity other_name                          = Nothing
 
 getNameShortName :: Name -> ShortName
diff --git a/ghc/compiler/basicTypes/PprEnv.lhs b/ghc/compiler/basicTypes/PprEnv.lhs
new file mode 100644 (file)
index 0000000..1cd1071
--- /dev/null
@@ -0,0 +1,121 @@
+%
+% (c) The AQUA Project, Glasgow University, 1996
+%
+\section[PprEnv]{The @PprEnv@ type}
+
+\begin{code}
+#include "HsVersions.h"
+
+module PprEnv (
+       PprEnv{-abstract-},
+
+       initPprEnv,
+
+       pCon, pLit, pMajBndr, pMinBndr, pOcc, pPrim, pSCC, pStyle,
+       pTy, pTyVar, pUVar, pUse
+    ) where
+
+import Ubiq{-uitous-}
+
+import Id              ( DataCon(..) )
+import Pretty          ( Pretty(..) )
+import Util            ( panic )
+\end{code}
+
+For tyvars and uvars, we {\em do} normally use these homogenized
+names; for values, we {\em don't}.  In printing interfaces, though,
+we use homogenized value names, so that interfaces don't wobble
+uncontrollably from changing Unique-based names.
+
+\begin{code}
+data PprEnv tyvar uvar bndr occ
+  = PE PprStyle                -- stored for safe keeping
+
+       (Literal    -> Pretty)  -- Doing these this way saves
+       (DataCon    -> Pretty)  -- carrying around a PprStyle
+       (PrimOp     -> Pretty)
+       (CostCentre -> Pretty)
+
+       (tyvar -> Pretty)       -- to print tyvars
+       (uvar -> Pretty)        -- to print usage vars
+
+       (bndr -> Pretty)        -- to print "major" val_bdrs
+       (bndr -> Pretty)        -- to print "minor" val_bdrs
+       (occ  -> Pretty)        -- to print bindees
+
+       (GenType tyvar uvar -> Pretty)
+       (GenUsage uvar -> Pretty)
+\end{code}
+
+\begin{code}
+initPprEnv
+       :: PprStyle
+       -> Maybe (Literal -> Pretty)
+       -> Maybe (DataCon -> Pretty)
+       -> Maybe (PrimOp  -> Pretty)
+       -> Maybe (CostCentre -> Pretty)
+       -> Maybe (tyvar -> Pretty)
+       -> Maybe (uvar -> Pretty)
+       -> Maybe (bndr -> Pretty)
+       -> Maybe (bndr -> Pretty)
+       -> Maybe (occ -> Pretty)
+       -> Maybe (GenType tyvar uvar -> Pretty)
+       -> Maybe (GenUsage uvar -> Pretty)
+       -> PprEnv tyvar uvar bndr occ
+
+-- you can specify all the printers individually; if
+-- you don't specify one, you get bottom
+
+initPprEnv sty l d p c tv uv maj_bndr min_bndr occ ty use
+  = PE sty
+       (demaybe l)
+       (demaybe d)
+       (demaybe p)
+       (demaybe c)
+       (demaybe tv)
+       (demaybe uv)
+       (demaybe maj_bndr)
+       (demaybe min_bndr)
+       (demaybe occ)
+       (demaybe ty)
+       (demaybe use)
+  where
+    demaybe Nothing  = bottom
+    demaybe (Just x) = x
+
+    bottom = panic "PprEnv.initPprEnv: unspecified printing function"
+
+{-
+initPprEnv sty pmaj pmin pocc
+  = PE (ppr sty)   -- for a Literal
+       (ppr sty)   -- for a DataCon
+       (ppr sty)   -- for a PrimOp
+       (\ cc -> ppStr (showCostCentre sty True cc)) -- CostCentre
+
+       (ppr sty)   -- for a tyvar
+       (ppr sty)   -- for a usage var
+
+       pmaj pmin pocc -- for GenIds in various guises
+
+       (ppr sty)   -- for a Type
+       (ppr sty)   -- for a Usage
+-}
+\end{code}
+
+\begin{code}
+pStyle  (PE s  _  _  _  _  _  _  _  _  _  _  _) = s
+pLit    (PE _ pp  _  _  _  _  _  _  _  _  _  _) = pp
+pCon    (PE _  _ pp  _  _  _  _  _  _  _  _  _) = pp
+pPrim   (PE _  _  _ pp  _  _  _  _  _  _  _  _) = pp
+pSCC    (PE _  _  _  _ pp  _  _  _  _  _  _  _) = pp
+                                              
+pTyVar  (PE _  _  _  _  _ pp  _  _  _  _  _  _) = pp
+pUVar   (PE _  _  _  _  _  _ pp  _  _  _  _  _) = pp
+                                              
+pMajBndr (PE _ _  _  _  _  _  _ pp  _  _  _  _) = pp
+pMinBndr (PE _ _  _  _  _  _  _  _ pp  _  _  _) = pp
+pOcc     (PE _ _  _  _  _  _  _  _  _ pp  _  _) = pp
+                              
+pTy      (PE _ _  _  _  _  _  _  _  _  _ pp  _) = pp
+pUse    (PE _  _  _  _  _  _  _  _  _  _  _ pp) = pp
+\end{code}
index 81fec96..1915538 100644 (file)
@@ -15,6 +15,7 @@ module UniqSupply (
        UniqSM(..),             -- type: unique supply monad
        initUs, thenUs, returnUs,
        mapUs, mapAndUnzipUs, mapAndUnzip3Us,
        UniqSM(..),             -- type: unique supply monad
        initUs, thenUs, returnUs,
        mapUs, mapAndUnzipUs, mapAndUnzip3Us,
+       thenMaybeUs, mapAccumLUs,
 
        mkSplitUniqSupply,
        splitUniqSupply,
 
        mkSplitUniqSupply,
        splitUniqSupply,
@@ -169,6 +170,24 @@ mapAndUnzip3Us f (x:xs)
   = f x                        `thenUs` \ (r1,  r2,  r3)  ->
     mapAndUnzip3Us f xs        `thenUs` \ (rs1, rs2, rs3) ->
     returnUs (r1:rs1, r2:rs2, r3:rs3)
   = f x                        `thenUs` \ (r1,  r2,  r3)  ->
     mapAndUnzip3Us f xs        `thenUs` \ (rs1, rs2, rs3) ->
     returnUs (r1:rs1, r2:rs2, r3:rs3)
+
+thenMaybeUs :: UniqSM (Maybe a) -> (a -> UniqSM (Maybe b)) -> UniqSM (Maybe b)
+thenMaybeUs m k
+  = m  `thenUs` \ result ->
+    case result of
+      Nothing -> returnUs Nothing
+      Just x  -> k x
+
+mapAccumLUs :: (acc -> x -> UniqSM (acc, y))
+           -> acc
+           -> [x]
+           -> UniqSM (acc, [y])
+
+mapAccumLUs f b []     = returnUs (b, [])
+mapAccumLUs f b (x:xs)
+  = f b x                          `thenUs` \ (b__2, x__2) ->
+    mapAccumLUs f b__2 xs          `thenUs` \ (b__3, xs__2) ->
+    returnUs (b__3, x__2:xs__2)
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index 84fd884..4d17fc1 100644 (file)
@@ -8,7 +8,7 @@
 
 module CgBindery (
        CgBindings(..), CgIdInfo(..){-dubiously concrete-},
 
 module CgBindery (
        CgBindings(..), CgIdInfo(..){-dubiously concrete-},
-       StableLoc, VolatileLoc, LambdaFormInfo{-re-exported-},
+       StableLoc, VolatileLoc,
 
        maybeAStkLoc, maybeBStkLoc,
 
 
        maybeAStkLoc, maybeBStkLoc,
 
@@ -20,25 +20,35 @@ module CgBindery (
        bindNewToAStack, bindNewToBStack,
        bindNewToNode, bindNewToReg, bindArgsToRegs,
        bindNewToTemp, bindNewPrimToAmode,
        bindNewToAStack, bindNewToBStack,
        bindNewToNode, bindNewToReg, bindArgsToRegs,
        bindNewToTemp, bindNewPrimToAmode,
-       getAtomAmode, getAtomAmodes,
+       getArgAmode, getArgAmodes,
        getCAddrModeAndInfo, getCAddrMode,
        getCAddrModeIfVolatile, getVolatileRegs,
        rebindToAStack, rebindToBStack
        getCAddrModeAndInfo, getCAddrMode,
        getCAddrModeIfVolatile, getVolatileRegs,
        rebindToAStack, rebindToBStack
-
-       -- and to make a self-sufficient interface...
     ) where
 
     ) where
 
+import Ubiq{-uitous-}
+import CgLoop1         -- here for paranoia-checking
+
 import AbsCSyn
 import CgMonad
 
 import CgUsages                ( getHpRelOffset, getSpARelOffset, getSpBRelOffset )
 import AbsCSyn
 import CgMonad
 
 import CgUsages                ( getHpRelOffset, getSpARelOffset, getSpBRelOffset )
-import CLabel  ( mkClosureLabel, CLabel )
-import ClosureInfo
-import Id              ( getIdPrimRep, toplevelishId, isDataCon, Id )
-import Maybes          ( catMaybes, Maybe(..) )
-import UniqSet         -- ( setToList )
-import StgSyn
-import Util
+import CLabel          ( mkClosureLabel )
+import ClosureInfo     ( mkLFImported, mkConLFInfo, mkLFArgument )
+import HeapOffs                ( VirtualHeapOffset(..),
+                         VirtualSpAOffset(..), VirtualSpBOffset(..)
+                       )
+import Id              ( idPrimRep, toplevelishId, isDataCon,
+                         mkIdEnv, rngIdEnv, IdEnv(..),
+                         idSetToList,
+                         GenId{-instance NamedThing-}
+                       )
+import Maybes          ( catMaybes )
+import PprAbsC         ( pprAmode )
+import PprStyle                ( PprStyle(..) )
+import StgSyn          ( StgArg(..), StgLiveVars(..), GenStgArg(..) )
+import Unpretty                ( uppShow )
+import Util            ( zipWithEqual, panic )
 \end{code}
 
 
 \end{code}
 
 
@@ -113,13 +123,13 @@ newTempAmodeAndIdInfo name lf_info
   = (temp_amode, temp_idinfo)
   where
     uniq               = getItsUnique name
   = (temp_amode, temp_idinfo)
   where
     uniq               = getItsUnique name
-    temp_amode = CTemp uniq (getIdPrimRep name)
+    temp_amode = CTemp uniq (idPrimRep name)
     temp_idinfo = tempIdInfo name uniq lf_info
 
     temp_idinfo = tempIdInfo name uniq lf_info
 
-idInfoToAmode :: PrimKind -> CgIdInfo -> FCode CAddrMode
+idInfoToAmode :: PrimRep -> CgIdInfo -> FCode CAddrMode
 idInfoToAmode kind (MkCgIdInfo _ vol stab _) = idInfoPiecesToAmode kind vol stab
 
 idInfoToAmode kind (MkCgIdInfo _ vol stab _) = idInfoPiecesToAmode kind vol stab
 
-idInfoPiecesToAmode :: PrimKind -> VolatileLoc -> StableLoc -> FCode CAddrMode
+idInfoPiecesToAmode :: PrimRep -> VolatileLoc -> StableLoc -> FCode CAddrMode
 
 idInfoPiecesToAmode kind (TempVarLoc uniq) stable_loc   = returnFC (CTemp uniq kind)
 idInfoPiecesToAmode kind (RegLoc magic_id) stable_loc   = returnFC (CReg magic_id)
 
 idInfoPiecesToAmode kind (TempVarLoc uniq) stable_loc   = returnFC (CTemp uniq kind)
 idInfoPiecesToAmode kind (RegLoc magic_id) stable_loc   = returnFC (CReg magic_id)
@@ -195,7 +205,7 @@ getCAddrModeAndInfo name
     returnFC (amode, lf_info)
   where
     global_amode = CLbl (mkClosureLabel name) kind
     returnFC (amode, lf_info)
   where
     global_amode = CLbl (mkClosureLabel name) kind
-    kind = getIdPrimRep name
+    kind = idPrimRep name
 
 getCAddrMode :: Id -> FCode CAddrMode
 getCAddrMode name
 
 getCAddrMode :: Id -> FCode CAddrMode
 getCAddrMode name
@@ -211,7 +221,7 @@ getCAddrModeIfVolatile name
   = lookupBindC name `thenFC` \ ~(MkCgIdInfo _ volatile_loc stable_loc lf_info) ->
     case stable_loc of
        NoStableLoc ->  -- Aha!  So it is volatile!
   = lookupBindC name `thenFC` \ ~(MkCgIdInfo _ volatile_loc stable_loc lf_info) ->
     case stable_loc of
        NoStableLoc ->  -- Aha!  So it is volatile!
-           idInfoPiecesToAmode (getIdPrimRep name) volatile_loc NoStableLoc `thenFC` \ amode ->
+           idInfoPiecesToAmode (idPrimRep name) volatile_loc NoStableLoc `thenFC` \ amode ->
            returnFC (Just amode)
 
        a_stable_loc -> returnFC Nothing
            returnFC (Just amode)
 
        a_stable_loc -> returnFC Nothing
@@ -228,7 +238,7 @@ forget the volatile one.
 getVolatileRegs :: StgLiveVars -> FCode [MagicId]
 
 getVolatileRegs vars
 getVolatileRegs :: StgLiveVars -> FCode [MagicId]
 
 getVolatileRegs vars
-  = mapFCs snaffle_it (uniqSetToList vars) `thenFC` \ stuff ->
+  = mapFCs snaffle_it (idSetToList vars) `thenFC` \ stuff ->
     returnFC (catMaybes stuff)
   where
     snaffle_it var
     returnFC (catMaybes stuff)
   where
     snaffle_it var
@@ -262,17 +272,17 @@ getVolatileRegs vars
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-getAtomAmodes :: [StgArg] -> FCode [CAddrMode]
-getAtomAmodes [] = returnFC []
-getAtomAmodes (atom:atoms)
-  = getAtomAmode  atom  `thenFC` \ amode ->
-    getAtomAmodes atoms `thenFC` \ amodes ->
+getArgAmodes :: [StgArg] -> FCode [CAddrMode]
+getArgAmodes [] = returnFC []
+getArgAmodes (atom:atoms)
+  = getArgAmode  atom  `thenFC` \ amode ->
+    getArgAmodes atoms `thenFC` \ amodes ->
     returnFC ( amode : amodes )
 
     returnFC ( amode : amodes )
 
-getAtomAmode :: StgArg -> FCode CAddrMode
+getArgAmode :: StgArg -> FCode CAddrMode
 
 
-getAtomAmode (StgVarArg var) = getCAddrMode var
-getAtomAmode (StgLitArg lit) = returnFC (CLit lit)
+getArgAmode (StgVarArg var) = getCAddrMode var
+getArgAmode (StgLitArg lit) = returnFC (CLit lit)
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index 45b21c1..5ed617d 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 %********************************************************
 %*                                                     *
 %
 %********************************************************
 %*                                                     *
 \begin{code}
 #include "HsVersions.h"
 
 \begin{code}
 #include "HsVersions.h"
 
-module CgCase (
-       cgCase,
-       saveVolatileVarsAndRegs
+module CgCase (        cgCase, saveVolatileVarsAndRegs ) where
 
 
-       -- and to make the interface self-sufficient...
-    ) where
+import Ubiq{-uitous-}
+import CgLoop2         ( cgExpr, getPrimOpArgAmodes )
 
 
-import StgSyn
 import CgMonad
 import CgMonad
+import StgSyn
 import AbsCSyn
 
 import AbsCSyn
 
-import PrelInfo                ( PrimOp(..), primOpCanTriggerGC
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
+import AbsCUtils       ( mkAbstractCs, mkAbsCStmts, mkAlgAltsCSwitch,
+                         magicIdPrimRep, getAmodeRep
                        )
                        )
-import Type            ( primRepFromType, getTyConDataCons,
-                         getUniDataSpecTyCon, getUniDataSpecTyCon_maybe,
-                         isEnumerationTyCon,
-                         Type
+import CgBindery       ( getVolatileRegs, getArgAmode, getArgAmodes,
+                         bindNewToReg, bindNewToTemp,
+                         bindNewPrimToAmode,
+                         rebindToAStack, rebindToBStack,
+                         getCAddrModeAndInfo, getCAddrModeIfVolatile,
+                         idInfoToAmode
                        )
                        )
-import CgBindery       -- all of it
 import CgCon           ( buildDynCon, bindConArgs )
 import CgCon           ( buildDynCon, bindConArgs )
-import CgExpr          ( cgExpr, getPrimOpArgAmodes )
 import CgHeapery       ( heapCheck )
 import CgHeapery       ( heapCheck )
-import CgRetConv       -- lots of stuff
-import CgStackery      -- plenty
+import CgRetConv       ( dataReturnConvAlg, dataReturnConvPrim,
+                         ctrlReturnConvAlg,
+                         DataReturnConvention(..), CtrlReturnConvention(..),
+                         assignPrimOpResultRegs,
+                         makePrimOpArgsRobust
+                       )
+import CgStackery      ( allocAStack, allocBStack )
 import CgTailCall      ( tailCallBusiness, performReturn )
 import CgTailCall      ( tailCallBusiness, performReturn )
-import CgUsages                -- and even more
-import CLabel  -- bunches of things...
-import ClosureInfo     {-( blackHoleClosureInfo, mkConLFInfo, mkLFArgument,
-                         layOutDynCon
-                       )-}
-import CostCentre      ( useCurrentCostCentre, CostCentre )
-import Literal         ( literalPrimRep )
-import Id              ( getDataConTag, getIdPrimRep, fIRST_TAG, isDataCon,
-                         toplevelishId, getInstantiatedDataConSig,
-                         ConTag(..), DataCon(..)
+import CgUsages                ( getSpARelOffset, getSpBRelOffset, freeBStkSlot )
+import CLabel          ( mkVecTblLabel, mkReturnPtLabel, mkDefaultLabel,
+                         mkAltLabel, mkClosureLabel
+                       )
+import ClosureInfo     ( mkConLFInfo, mkLFArgument, layOutDynCon )
+import CmdLineOpts     ( opt_SccProfilingOn )
+import CostCentre      ( useCurrentCostCentre )
+import HeapOffs                ( VirtualSpBOffset(..), VirtualHeapOffset(..) )
+import Id              ( idPrimRep, toplevelishId,
+                         dataConTag, fIRST_TAG, ConTag(..),
+                         isDataCon, DataCon(..),
+                         idSetToList, GenId{-instance NamedThing,Eq-}
                        )
                        )
-import Maybes          ( catMaybes, Maybe(..) )
-import PrimRep         ( getPrimRepSize, isFollowableRep, retPrimRepSize, PrimRep(..) )
-import UniqSet         -- ( uniqSetToList, UniqSet(..) )
-import Util
+import Maybes          ( catMaybes )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-} )
+import PrimOp          ( primOpCanTriggerGC, PrimOp(..) )
+import PrimRep         ( getPrimRepSize, isFollowableRep, retPrimRepSize,
+                         PrimRep(..)
+                       )
+import TyCon           ( isEnumerationTyCon )
+import Type            ( typePrimRep,
+                         getDataSpecTyCon, getDataSpecTyCon_maybe,
+                         isEnumerationTyCon
+                       )
+import Util            ( sortLt, isIn, isn'tIn, zipEqual,
+                         pprError, panic, assertPanic
+                       )
+
+getDataSpecTyCon = panic "CgCase.getDataSpecTyCon (ToDo)"
+getDataSpecTyCon_maybe = panic "CgCase.getDataSpecTyCon_maybe (ToDo)"
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -193,18 +211,17 @@ cgCase (StgPrim op args _) live_in_whole_case live_in_alts uniq alts
 
   | otherwise  -- *Can* trigger GC
   = getPrimOpArgAmodes op args `thenFC` \ arg_amodes ->
 
   | otherwise  -- *Can* trigger GC
   = getPrimOpArgAmodes op args `thenFC` \ arg_amodes ->
---NO:  getIntSwitchChkrC       `thenFC` \ isw_chkr   ->
 
        -- Get amodes for the arguments and results, and assign to regs
        -- (Can-trigger-gc primops guarantee to have their (nonRobust)
        --  args in regs)
     let
 
        -- Get amodes for the arguments and results, and assign to regs
        -- (Can-trigger-gc primops guarantee to have their (nonRobust)
        --  args in regs)
     let
-       op_result_regs = assignPrimOpResultRegs {-NO:isw_chkr-} op
+       op_result_regs = assignPrimOpResultRegs op
 
        op_result_amodes = map CReg op_result_regs
 
        (op_arg_amodes, liveness_mask, arg_assts)
 
        op_result_amodes = map CReg op_result_regs
 
        (op_arg_amodes, liveness_mask, arg_assts)
-         = makePrimOpArgsRobust {-NO:isw_chkr-} op arg_amodes
+         = makePrimOpArgsRobust op arg_amodes
 
        liveness_arg  = mkIntCLit liveness_mask
     in
 
        liveness_arg  = mkIntCLit liveness_mask
     in
@@ -275,7 +292,7 @@ eliminate a heap check altogether.
 
 \begin{code}
 cgCase (StgApp v [] _) live_in_whole_case live_in_alts uniq (StgPrimAlts ty alts deflt)
 
 \begin{code}
 cgCase (StgApp v [] _) live_in_whole_case live_in_alts uniq (StgPrimAlts ty alts deflt)
-  = getAtomAmode v             `thenFC` \ amode ->
+  = getArgAmode v              `thenFC` \ amode ->
     cgPrimAltsGivenScrutinee NoGC amode alts deflt
 \end{code}
 
     cgPrimAltsGivenScrutinee NoGC amode alts deflt
 \end{code}
 
@@ -288,7 +305,7 @@ cgCase (StgApp (StgVarArg fun) args _ {-lvs must be same as live_in_alts-})
        live_in_whole_case live_in_alts uniq alts@(StgAlgAlts _ _ _)
   =
     getCAddrModeAndInfo fun            `thenFC` \ (fun_amode, lf_info) ->
        live_in_whole_case live_in_alts uniq alts@(StgAlgAlts _ _ _)
   =
     getCAddrModeAndInfo fun            `thenFC` \ (fun_amode, lf_info) ->
-    getAtomAmodes args                 `thenFC` \ arg_amodes ->
+    getArgAmodes args                  `thenFC` \ arg_amodes ->
 
        -- Squish the environment
     nukeDeadBindings live_in_alts      `thenC`
 
        -- Squish the environment
     nukeDeadBindings live_in_alts      `thenC`
@@ -368,7 +385,7 @@ getPrimAppResultAmodes uniq (StgAlgAlts ty alts (StgBindDefault _ True {- used -
     -- A temporary variable to hold the tag; this is unaffected by GC because
     -- the heap-checks in the branches occur after the switch
     tag_amode     = CTemp uniq IntRep
     -- A temporary variable to hold the tag; this is unaffected by GC because
     -- the heap-checks in the branches occur after the switch
     tag_amode     = CTemp uniq IntRep
-    (spec_tycon, _, _) = getUniDataSpecTyCon ty
+    (spec_tycon, _, _) = getDataSpecTyCon ty
 
 getPrimAppResultAmodes uniq (StgAlgAlts ty alts other_default)
        -- Default is either StgNoDefault or StgBindDefault with unused binder
 
 getPrimAppResultAmodes uniq (StgAlgAlts ty alts other_default)
        -- Default is either StgNoDefault or StgBindDefault with unused binder
@@ -383,14 +400,14 @@ getPrimAppResultAmodes uniq (StgAlgAlts ty alts other_default)
     -- Sort alternatives into canonical order; there must be a complete
     -- set because there's no default case.
     sorted_alts = sortLt lt alts
     -- Sort alternatives into canonical order; there must be a complete
     -- set because there's no default case.
     sorted_alts = sortLt lt alts
-    (con1,_,_,_) `lt` (con2,_,_,_) = getDataConTag con1 < getDataConTag con2
+    (con1,_,_,_) `lt` (con2,_,_,_) = dataConTag con1 < dataConTag con2
 
     arg_amodes :: [CAddrMode]
 
     -- Turn them into amodes
     arg_amodes = concat (map mk_amodes sorted_alts)
     mk_amodes (con, args, use_mask, rhs)
 
     arg_amodes :: [CAddrMode]
 
     -- Turn them into amodes
     arg_amodes = concat (map mk_amodes sorted_alts)
     mk_amodes (con, args, use_mask, rhs)
-      = [ CTemp (getItsUnique arg) (getIdPrimRep arg) | arg <- args ]
+      = [ CTemp (getItsUnique arg) (idPrimRep arg) | arg <- args ]
 \end{code}
 
 The situation is simpler for primitive
 \end{code}
 
 The situation is simpler for primitive
@@ -398,9 +415,7 @@ results, because there is only one!
 
 \begin{code}
 getPrimAppResultAmodes uniq (StgPrimAlts ty _ _)
 
 \begin{code}
 getPrimAppResultAmodes uniq (StgPrimAlts ty _ _)
-  = [CTemp uniq kind]
-  where
-    kind = primRepFromType ty
+  = [CTemp uniq (typePrimRep ty)]
 \end{code}
 
 
 \end{code}
 
 
@@ -425,7 +440,6 @@ cgEvalAlts :: Maybe VirtualSpBOffset        -- Offset of cost-centre to be restored, if
 cgEvalAlts cc_slot uniq (StgAlgAlts ty alts deflt)
   =    -- Generate the instruction to restore cost centre, if any
     restoreCurrentCostCentre cc_slot   `thenFC` \ cc_restore ->
 cgEvalAlts cc_slot uniq (StgAlgAlts ty alts deflt)
   =    -- Generate the instruction to restore cost centre, if any
     restoreCurrentCostCentre cc_slot   `thenFC` \ cc_restore ->
-    getIntSwitchChkrC                  `thenFC` \ isw_chkr ->
 
        -- Generate sequel info for use downstream
        -- At the moment, we only do it if the type is vector-returnable.
 
        -- Generate sequel info for use downstream
        -- At the moment, we only do it if the type is vector-returnable.
@@ -437,7 +451,7 @@ cgEvalAlts cc_slot uniq (StgAlgAlts ty alts deflt)
        -- which is worse than having the alt code in the switch statement
 
     let
        -- which is worse than having the alt code in the switch statement
 
     let
-       (spec_tycon, _, _) = getUniDataSpecTyCon ty
+       (spec_tycon, _, _) = getDataSpecTyCon ty
 
        use_labelled_alts
          = case ctrlReturnConvAlg spec_tycon of
 
        use_labelled_alts
          = case ctrlReturnConvAlg spec_tycon of
@@ -448,7 +462,7 @@ cgEvalAlts cc_slot uniq (StgAlgAlts ty alts deflt)
          = if not use_labelled_alts then
                Nothing -- no semi-tagging info
            else
          = if not use_labelled_alts then
                Nothing -- no semi-tagging info
            else
-               cgSemiTaggedAlts isw_chkr uniq alts deflt -- Just <something>
+               cgSemiTaggedAlts uniq alts deflt -- Just <something>
     in
     cgAlgAlts GCMayHappen uniq cc_restore use_labelled_alts ty alts deflt
                                        `thenFC` \ (tagged_alt_absCs, deflt_absC) ->
     in
     cgAlgAlts GCMayHappen uniq cc_restore use_labelled_alts ty alts deflt
                                        `thenFC` \ (tagged_alt_absCs, deflt_absC) ->
@@ -560,10 +574,9 @@ It's all pretty turgid anyway.
 \begin{code}
 cgAlgAlts gc_flag uniq restore_cc semi_tagging
        ty alts deflt@(StgBindDefault binder True{-used-} _)
 \begin{code}
 cgAlgAlts gc_flag uniq restore_cc semi_tagging
        ty alts deflt@(StgBindDefault binder True{-used-} _)
-  = getIntSwitchChkrC  `thenFC` \ isw_chkr ->
-    let
+  = let
        extra_branches :: [FCode (ConTag, AbstractC)]
        extra_branches :: [FCode (ConTag, AbstractC)]
-       extra_branches = catMaybes (map (mk_extra_branch isw_chkr) default_cons)
+       extra_branches = catMaybes (map mk_extra_branch default_cons)
 
        must_label_default = semi_tagging || not (null extra_branches)
     in
 
        must_label_default = semi_tagging || not (null extra_branches)
     in
@@ -575,14 +588,7 @@ cgAlgAlts gc_flag uniq restore_cc semi_tagging
     default_join_lbl = mkDefaultLabel uniq
     jump_instruction = CJump (CLbl default_join_lbl CodePtrRep)
 
     default_join_lbl = mkDefaultLabel uniq
     jump_instruction = CJump (CLbl default_join_lbl CodePtrRep)
 
-    (spec_tycon, _, spec_cons)
-      = -- trace ("cgCase:tycon:"++(ppShow 80 (ppAboves [
-       --      ppr PprDebug uniq,
-       --      ppr PprDebug ty,
-       --      ppr PprShowAll binder
-       --      ]))) (
-       getUniDataSpecTyCon ty
-       -- )
+    (spec_tycon, _, spec_cons) = getDataSpecTyCon ty
 
     alt_cons = [ con | (con,_,_,_) <- alts ]
 
 
     alt_cons = [ con | (con,_,_,_) <- alts ]
 
@@ -596,18 +602,18 @@ cgAlgAlts gc_flag uniq restore_cc semi_tagging
     -- nothing to do. Otherwise, we have a special case for a nullary constructor,
     -- but in the general case we do an allocation and heap-check.
 
     -- nothing to do. Otherwise, we have a special case for a nullary constructor,
     -- but in the general case we do an allocation and heap-check.
 
-    mk_extra_branch :: IntSwitchChecker -> DataCon -> (Maybe (FCode (ConTag, AbstractC)))
+    mk_extra_branch :: DataCon -> (Maybe (FCode (ConTag, AbstractC)))
 
 
-    mk_extra_branch isw_chkr con
+    mk_extra_branch con
       = ASSERT(isDataCon con)
       = ASSERT(isDataCon con)
-       case dataReturnConvAlg isw_chkr con of
+       case dataReturnConvAlg con of
          ReturnInHeap    -> Nothing
          ReturnInRegs rs -> Just (getAbsC (alloc_code rs) `thenFC` \ abs_c ->
                                   returnFC (tag, abs_c)
                                  )
       where
        lf_info         = mkConLFInfo con
          ReturnInHeap    -> Nothing
          ReturnInRegs rs -> Just (getAbsC (alloc_code rs) `thenFC` \ abs_c ->
                                   returnFC (tag, abs_c)
                                  )
       where
        lf_info         = mkConLFInfo con
-       tag             = getDataConTag con
+       tag             = dataConTag con
        closure_lbl     = mkClosureLabel con
 
        -- alloc_code generates code to allocate constructor con, whose args are
        closure_lbl     = mkClosureLabel con
 
        -- alloc_code generates code to allocate constructor con, whose args are
@@ -625,7 +631,7 @@ cgAlgAlts gc_flag uniq restore_cc semi_tagging
                absC jump_instruction
            )
          where
                absC jump_instruction
            )
          where
-           zero_size reg = getPrimRepSize (kindFromMagicId reg) == 0
+           zero_size reg = getPrimRepSize (magicIdPrimRep reg) == 0
 \end{code}
 
 Now comes the general case
 \end{code}
 
 Now comes the general case
@@ -698,16 +704,15 @@ cgAlgAlt gc_flag uniq restore_cc must_label_branch (con, args, use_mask, rhs)
     in
     returnFC (tag, final_abs_c)
   where
     in
     returnFC (tag, final_abs_c)
   where
-    tag        = getDataConTag con
+    tag        = dataConTag con
     lbl = mkAltLabel uniq tag
 
 cgAlgAltRhs :: GCFlag -> Id -> [Id] -> [Bool] -> StgExpr -> Code
 
 cgAlgAltRhs gc_flag con args use_mask rhs
     lbl = mkAltLabel uniq tag
 
 cgAlgAltRhs :: GCFlag -> Id -> [Id] -> [Bool] -> StgExpr -> Code
 
 cgAlgAltRhs gc_flag con args use_mask rhs
-  = getIntSwitchChkrC  `thenFC` \ isw_chkr ->
-    let
+  = let
       (live_regs, node_reqd)
       (live_regs, node_reqd)
-       = case (dataReturnConvAlg isw_chkr con) of
+       = case (dataReturnConvAlg con) of
            ReturnInHeap      -> ([],                                             True)
            ReturnInRegs regs -> ([reg | (reg,True) <- regs `zipEqual` use_mask], False)
                                -- Pick the live registers using the use_mask
            ReturnInHeap      -> ([],                                             True)
            ReturnInRegs regs -> ([reg | (reg,True) <- regs `zipEqual` use_mask], False)
                                -- Pick the live registers using the use_mask
@@ -735,14 +740,13 @@ Turgid-but-non-monadic code to conjure up the required info from
 algebraic case alternatives for semi-tagging.
 
 \begin{code}
 algebraic case alternatives for semi-tagging.
 
 \begin{code}
-cgSemiTaggedAlts :: IntSwitchChecker
-                -> Unique
+cgSemiTaggedAlts :: Unique
                 -> [(Id, [Id], [Bool], StgExpr)]
                 -> GenStgCaseDefault Id Id
                 -> SemiTaggingStuff
 
                 -> [(Id, [Id], [Bool], StgExpr)]
                 -> GenStgCaseDefault Id Id
                 -> SemiTaggingStuff
 
-cgSemiTaggedAlts isw_chkr uniq alts deflt
-  = Just (map (st_alt isw_chkr) alts, st_deflt deflt)
+cgSemiTaggedAlts uniq alts deflt
+  = Just (map st_alt alts, st_deflt deflt)
   where
     st_deflt StgNoDefault = Nothing
 
   where
     st_deflt StgNoDefault = Nothing
 
@@ -752,8 +756,8 @@ cgSemiTaggedAlts isw_chkr uniq alts deflt
               mkDefaultLabel uniq)
             )
 
               mkDefaultLabel uniq)
             )
 
-    st_alt isw_chkr (con, args, use_mask, _)
-      = case (dataReturnConvAlg isw_chkr con) of
+    st_alt (con, args, use_mask, _)
+      = case (dataReturnConvAlg con) of
 
          ReturnInHeap ->
            -- Ha!  Nothing to do; Node already points to the thing
 
          ReturnInHeap ->
            -- Ha!  Nothing to do; Node already points to the thing
@@ -767,7 +771,7 @@ cgSemiTaggedAlts isw_chkr uniq alts deflt
            -- We have to load the live registers from the constructor
            -- pointed to by Node.
            let
            -- We have to load the live registers from the constructor
            -- pointed to by Node.
            let
-               (_, regs_w_offsets) = layOutDynCon con kindFromMagicId regs
+               (_, regs_w_offsets) = layOutDynCon con magicIdPrimRep regs
 
                used_regs = selectByMask use_mask regs
 
 
                used_regs = selectByMask use_mask regs
 
@@ -784,12 +788,12 @@ cgSemiTaggedAlts isw_chkr uniq alts deflt
                CSimultaneous (mkAbstractCs (map move_to_reg used_regs_w_offsets))],
              join_label))
       where
                CSimultaneous (mkAbstractCs (map move_to_reg used_regs_w_offsets))],
              join_label))
       where
-       con_tag     = getDataConTag con
+       con_tag     = dataConTag con
        join_label  = mkAltLabel uniq con_tag
 
     move_to_reg :: (MagicId, VirtualHeapOffset {-from Node-}) -> AbstractC
     move_to_reg (reg, offset)
        join_label  = mkAltLabel uniq con_tag
 
     move_to_reg :: (MagicId, VirtualHeapOffset {-from Node-}) -> AbstractC
     move_to_reg (reg, offset)
-      = CAssign (CReg reg) (CVal (NodeRel offset) (kindFromMagicId reg))
+      = CAssign (CReg reg) (CVal (NodeRel offset) (magicIdPrimRep reg))
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -821,7 +825,7 @@ cgPrimAlts gc_flag uniq ty alts deflt
                     NoGC        -> CTemp uniq kind
                     GCMayHappen -> CReg (dataReturnConvPrim kind)
 
                     NoGC        -> CTemp uniq kind
                     GCMayHappen -> CReg (dataReturnConvPrim kind)
 
-    kind = primRepFromType ty
+    kind = typePrimRep ty
 
 
 cgPrimAltsGivenScrutinee gc_flag scrutinee alts deflt
 
 
 cgPrimAltsGivenScrutinee gc_flag scrutinee alts deflt
@@ -892,7 +896,7 @@ saveVolatileVars :: StgLiveVars     -- Vars which should be made safe
                 -> FCode AbstractC     -- Assignments to to the saves
 
 saveVolatileVars vars
                 -> FCode AbstractC     -- Assignments to to the saves
 
 saveVolatileVars vars
-  = save_em (uniqSetToList vars)
+  = save_em (idSetToList vars)
   where
     save_em [] = returnFC AbsCNop
 
   where
     save_em [] = returnFC AbsCNop
 
@@ -978,7 +982,9 @@ saveCurrentCostCentre ::
                                        --   AbsCNop if not lexical CCs
 
 saveCurrentCostCentre
                                        --   AbsCNop if not lexical CCs
 
 saveCurrentCostCentre
-  = isSwitchSetC SccProfilingOn                `thenFC` \ doing_profiling ->
+  = let
+       doing_profiling = opt_SccProfilingOn
+    in
     if not doing_profiling then
        returnFC (Nothing, AbsCNop)
     else
     if not doing_profiling then
        returnFC (Nothing, AbsCNop)
     else
@@ -1047,9 +1053,9 @@ mkReturnVector uniq ty tagged_alt_absCs deflt_absC
     -- )
   where
 
     -- )
   where
 
-    (spec_tycon,_,_) = case (getUniDataSpecTyCon_maybe ty) of -- *must* be a real "data" type constructor
+    (spec_tycon,_,_) = case (getDataSpecTyCon_maybe ty) of -- *must* be a real "data" type constructor
              Just xx -> xx
              Just xx -> xx
-             Nothing -> error ("ERROR: can't generate code for polymorphic case;\nprobably a mis-use of `seq' or `par';\nthe User's Guide has more details.\nOffending type: "++(ppShow 80 (ppr PprDebug ty)))
+             Nothing -> pprError "ERROR: can't generate code for polymorphic case;\nprobably a mis-use of `seq' or `par';\nthe User's Guide has more details.\nOffending type: " (ppr PprDebug ty)
 
     vtbl_label = mkVecTblLabel uniq
     ret_label = mkReturnPtLabel uniq
 
     vtbl_label = mkVecTblLabel uniq
     ret_label = mkReturnPtLabel uniq
index af31842..eeaf9da 100644 (file)
@@ -12,31 +12,29 @@ with {\em closures} on the RHSs of let(rec)s.  See also
 
 module CgClosure ( cgTopRhsClosure, cgRhsClosure ) where
 
 
 module CgClosure ( cgTopRhsClosure, cgRhsClosure ) where
 
-import StgSyn
+import Ubiq{-uitous-}
+import CgLoop2         ( cgExpr, cgSccExpr )
+
 import CgMonad
 import AbsCSyn
 import CgMonad
 import AbsCSyn
+import StgSyn
 
 
-import PrelInfo                ( PrimOp(..), Name
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                       )
-import Type            ( isPrimType, isPrimTyCon,
-                         getTauType, showTypeCategory, getTyConDataCons
-                       )
-import CgBindery       ( getCAddrMode, getAtomAmodes,
-                         getCAddrModeAndInfo,
-                         bindNewToNode, bindNewToAStack, bindNewToBStack,
-                         bindNewToReg, bindArgsToRegs
+import AbsCUtils       ( mkAbstractCs, getAmodeRep )
+import CgBindery       ( getCAddrMode, getArgAmodes,
+                         getCAddrModeAndInfo, bindNewToNode,
+                         bindNewToAStack, bindNewToBStack,
+                         bindNewToReg, bindArgsToRegs,
+                         stableAmodeIdInfo, heapIdInfo
                        )
 import CgCompInfo      ( spARelToInt, spBRelToInt )
                        )
 import CgCompInfo      ( spARelToInt, spBRelToInt )
-import CgExpr          ( cgExpr, cgSccExpr )
 import CgUpdate                ( pushUpdateFrame )
 import CgHeapery       ( allocDynClosure, heapCheck
 #ifdef GRAN
 import CgUpdate                ( pushUpdateFrame )
 import CgHeapery       ( allocDynClosure, heapCheck
 #ifdef GRAN
-                         , heapCheckOnly, fetchAndReschedule  -- HWL
-#endif  {- GRAN -}
+                         , fetchAndReschedule  -- HWL
+#endif
                        )
                        )
-import CgRetConv       ( ctrlReturnConvAlg, dataReturnConvAlg, mkLiveRegsBitMask,
+import CgRetConv       ( mkLiveRegsMask,
+                         ctrlReturnConvAlg, dataReturnConvAlg, 
                          CtrlReturnConvention(..), DataReturnConvention(..)
                        )
 import CgStackery      ( getFinalStackHW, mkVirtStkOffsets,
                          CtrlReturnConvention(..), DataReturnConvention(..)
                        )
 import CgStackery      ( getFinalStackHW, mkVirtStkOffsets,
@@ -46,20 +44,37 @@ import CgUsages             ( getVirtSps, setRealAndVirtualSps,
                          getSpARelOffset, getSpBRelOffset,
                          getHpRelOffset
                        )
                          getSpARelOffset, getSpBRelOffset,
                          getHpRelOffset
                        )
-import CLabel
+import CLabel          ( mkClosureLabel, mkConUpdCodePtrVecLabel,
+                         mkStdUpdCodePtrVecLabel, mkStdUpdVecTblLabel,
+                         mkErrorStdEntryLabel, mkRednCountsLabel
+                       )
 import ClosureInfo     -- lots and lots of stuff
 import ClosureInfo     -- lots and lots of stuff
-import CostCentre
-import Id              ( idType, getIdPrimRep, isSysLocalId, myWrapperMaybe,
-                         showId, getIdInfo, getIdStrictness,
-                         getDataConTag
+import CmdLineOpts     ( opt_EmitArityChecks, opt_ForConcurrent,
+                         opt_AsmTarget
+                       )
+import CostCentre      ( useCurrentCostCentre, currentOrSubsumedCosts,
+                         noCostCentreAttached, costsAreSubsumed,
+                         isCafCC, overheadCostCentre
+                       )
+import HeapOffs                ( VirtualHeapOffset(..) )
+import Id              ( idType, idPrimRep, 
+                         showId, getIdStrictness, dataConTag,
+                         emptyIdSet,
+                         GenId{-instance Outputable-}
                        )
                        )
-import IdInfo
 import ListSetOps      ( minusList )
 import ListSetOps      ( minusList )
-import Maybes          ( Maybe(..), maybeToBool )
-import PrimRep         ( isFollowableRep )
-import UniqSet
-import Unpretty
-import Util
+import Maybes          ( maybeToBool )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-}, TyCon{-ditto-} )
+import Pretty          ( prettyToUn, ppBesides, ppChar, ppPStr )
+import PrimRep         ( isFollowableRep, PrimRep(..) )
+import TyCon           ( isPrimTyCon, tyConDataCons )
+import Unpretty                ( uppShow )
+import Util            ( isIn, panic, pprPanic, assertPanic )
+
+myWrapperMaybe = panic "CgClosure.myWrapperMaybe (ToDo)"
+showTypeCategory = panic "CgClosure.showTypeCategory (ToDo)"
+getWrapperArgTypeCategories = panic "CgClosure.getWrapperArgTypeCategories (ToDo)"
 \end{code}
 
 %********************************************************
 \end{code}
 
 %********************************************************
@@ -171,7 +186,7 @@ cgRhsClosure binder cc binder_info fvs args body lf_info
   -- ToDo: check non-primitiveness (ASSERT)
   = (
        -- LAY OUT THE OBJECT
   -- ToDo: check non-primitiveness (ASSERT)
   = (
        -- LAY OUT THE OBJECT
-    getAtomAmodes std_thunk_payload            `thenFC` \ amodes ->
+    getArgAmodes std_thunk_payload             `thenFC` \ amodes ->
     let
        (closure_info, amodes_w_offsets)
          = layOutDynClosure binder getAmodeRep amodes lf_info
     let
        (closure_info, amodes_w_offsets)
          = layOutDynClosure binder getAmodeRep amodes lf_info
@@ -226,7 +241,7 @@ cgRhsClosure binder cc binder_info fvs args body lf_info
 
        amodes_w_offsets = [(amode,offset) | ((_, (amode,_)), offset) <- bind_details]
 
 
        amodes_w_offsets = [(amode,offset) | ((_, (amode,_)), offset) <- bind_details]
 
-       get_kind (id, amode_and_info) = getIdPrimRep id
+       get_kind (id, amode_and_info) = idPrimRep id
     in
        -- BUILD ITS INFO TABLE AND CODE
     forkClosureBody (
     in
        -- BUILD ITS INFO TABLE AND CODE
     forkClosureBody (
@@ -302,7 +317,7 @@ cgVapInfoTable perhaps_bind_the_fun upd_flag fun args fun_in_payload fun_lf_info
        -- If f is not top-level, then f is one of the free variables too,
        -- hence "payload_ids" isn't the same as "arg_ids".
        --
        -- If f is not top-level, then f is one of the free variables too,
        -- hence "payload_ids" isn't the same as "arg_ids".
        --
-       vap_entry_rhs = StgApp (StgVarArg fun) (map StgVarArg args) emptyUniqSet
+       vap_entry_rhs = StgApp (StgVarArg fun) (map StgVarArg args) emptyIdSet
                                                                        -- Empty live vars
 
        arg_ids_w_info = [(name,mkLFArgument) | name <- args]
                                                                        -- Empty live vars
 
        arg_ids_w_info = [(name,mkLFArgument) | name <- args]
@@ -320,7 +335,7 @@ cgVapInfoTable perhaps_bind_the_fun upd_flag fun args fun_in_payload fun_lf_info
                --              let x = f p q   -- x isn't top level!
                --              in ...
 
                --              let x = f p q   -- x isn't top level!
                --              in ...
 
-       get_kind (id, info) = getIdPrimRep id
+       get_kind (id, info) = idPrimRep id
 
        payload_bind_details :: [((Id, LambdaFormInfo), VirtualHeapOffset)]
        (closure_info, payload_bind_details) = layOutDynClosure
 
        payload_bind_details :: [((Id, LambdaFormInfo), VirtualHeapOffset)]
        (closure_info, payload_bind_details) = layOutDynClosure
@@ -390,11 +405,10 @@ closureCodeBody binder_info closure_info cc [] body
 #endif
     getAbsC body_code  `thenFC` \ body_absC ->
     moduleName         `thenFC` \ mod_name ->
 #endif
     getAbsC body_code  `thenFC` \ body_absC ->
     moduleName         `thenFC` \ mod_name ->
-    getIntSwitchChkrC  `thenFC` \ isw_chkr ->
 
     absC (CClosureInfoAndCode closure_info body_absC Nothing
                              stdUpd (cl_descr mod_name)
 
     absC (CClosureInfoAndCode closure_info body_absC Nothing
                              stdUpd (cl_descr mod_name)
-                             (dataConLiveness isw_chkr closure_info))
+                             (dataConLiveness closure_info))
   where
     cl_descr mod_name = closureDescription mod_name (closureId closure_info) [] body
 
   where
     cl_descr mod_name = closureDescription mod_name (closureId closure_info) [] body
 
@@ -418,22 +432,19 @@ Node points to closure is available. -- HWL
 \begin{code}
 closureCodeBody binder_info closure_info cc all_args body
   = getEntryConvention id lf_info
 \begin{code}
 closureCodeBody binder_info closure_info cc all_args body
   = getEntryConvention id lf_info
-                      (map getIdPrimRep all_args)              `thenFC` \ entry_conv ->
-
-    isSwitchSetC EmitArityChecks                       `thenFC` \ do_arity_chks ->
-
-    isSwitchSetC ForConcurrent                         `thenFC` \ is_concurrent ->
-
-    isStringSwitchSetC AsmTarget                       `thenFC` \ native_code ->
-
+                      (map idPrimRep all_args)         `thenFC` \ entry_conv ->
     let
     let
+       do_arity_chks = opt_EmitArityChecks
+       is_concurrent = opt_ForConcurrent
+       native_code   = opt_AsmTarget
+
        stg_arity = length all_args
 
        -- Arg mapping for standard (slow) entry point; all args on stack
        (spA_all_args, spB_all_args, all_bxd_w_offsets, all_ubxd_w_offsets)
           = mkVirtStkOffsets
                0 0             -- Initial virtual SpA, SpB
        stg_arity = length all_args
 
        -- Arg mapping for standard (slow) entry point; all args on stack
        (spA_all_args, spB_all_args, all_bxd_w_offsets, all_ubxd_w_offsets)
           = mkVirtStkOffsets
                0 0             -- Initial virtual SpA, SpB
-               getIdPrimRep
+               idPrimRep
                all_args
 
        -- Arg mapping for the fast entry point; as many args as poss in
                all_args
 
        -- Arg mapping for the fast entry point; as many args as poss in
@@ -450,7 +461,7 @@ closureCodeBody binder_info closure_info cc all_args body
        (spA_stk_args, spB_stk_args, stk_bxd_w_offsets, stk_ubxd_w_offsets)
          = mkVirtStkOffsets
                0 0             -- Initial virtual SpA, SpB
        (spA_stk_args, spB_stk_args, stk_bxd_w_offsets, stk_ubxd_w_offsets)
          = mkVirtStkOffsets
                0 0             -- Initial virtual SpA, SpB
-               getIdPrimRep
+               idPrimRep
                stk_args
 
        -- HWL; Note: empty list of live regs in slow entry code
                stk_args
 
        -- HWL; Note: empty list of live regs in slow entry code
@@ -531,7 +542,6 @@ closureCodeBody binder_info closure_info cc all_args body
                                `thenFC` \ slow_abs_c ->
     forkAbsC fast_entry_code   `thenFC` \ fast_abs_c ->
     moduleName                 `thenFC` \ mod_name ->
                                `thenFC` \ slow_abs_c ->
     forkAbsC fast_entry_code   `thenFC` \ fast_abs_c ->
     moduleName                 `thenFC` \ mod_name ->
-    getIntSwitchChkrC          `thenFC` \ isw_chkr ->
 
        -- Now either construct the info table, or put the fast code in alone
        -- (We never have slow code without an info table)
 
        -- Now either construct the info table, or put the fast code in alone
        -- (We never have slow code without an info table)
@@ -539,7 +549,7 @@ closureCodeBody binder_info closure_info cc all_args body
       if info_table_needed then
        CClosureInfoAndCode closure_info slow_abs_c (Just fast_abs_c)
                        stdUpd (cl_descr mod_name)
       if info_table_needed then
        CClosureInfoAndCode closure_info slow_abs_c (Just fast_abs_c)
                        stdUpd (cl_descr mod_name)
-                       (dataConLiveness isw_chkr closure_info)
+                       (dataConLiveness closure_info)
       else
        CCodeBlock fast_label fast_abs_c
     )
       else
        CCodeBlock fast_label fast_abs_c
     )
@@ -665,18 +675,22 @@ argSatisfactionCheck closure_info args
 
     if (isFollowableRep (getAmodeRep last_amode)) then
        getSpARelOffset 0       `thenFC` \ (SpARel spA off) ->
 
     if (isFollowableRep (getAmodeRep last_amode)) then
        getSpARelOffset 0       `thenFC` \ (SpARel spA off) ->
+       let
+           lit = mkIntCLit (spARelToInt spA off)
+       in
        if node_points then
        if node_points then
-           absC (CMacroStmt ARGS_CHK_A [mkIntCLit (spARelToInt spA off)])
+           absC (CMacroStmt ARGS_CHK_A [lit])
        else
        else
-           absC (CMacroStmt ARGS_CHK_A_LOAD_NODE
-                               [mkIntCLit (spARelToInt spA off), set_Node_to_this])
+           absC (CMacroStmt ARGS_CHK_A_LOAD_NODE [lit, set_Node_to_this])
     else
     else
-       getSpBRelOffset 0       `thenFC` \ b_rel_offset ->
+       getSpBRelOffset 0       `thenFC` \ (SpBRel spB off) ->
+       let
+           lit = mkIntCLit (spBRelToInt spB off)
+       in
        if node_points then
        if node_points then
-           absC (CMacroStmt ARGS_CHK_B [mkIntCLit (spBRelToInt b_rel_offset)])
+           absC (CMacroStmt ARGS_CHK_B [lit])
        else
        else
-           absC (CMacroStmt ARGS_CHK_B_LOAD_NODE
-                               [mkIntCLit (spBRelToInt b_rel_offset), set_Node_to_this])
+           absC (CMacroStmt ARGS_CHK_B_LOAD_NODE [lit, set_Node_to_this])
   where
     -- We must tell the arg-satis macro whether Node is pointing to
     -- the closure or not.  If it isn't so pointing, then we give to
   where
     -- We must tell the arg-satis macro whether Node is pointing to
     -- the closure or not.  If it isn't so pointing, then we give to
@@ -780,7 +794,7 @@ stackCheck closure_info regs node_reqd code
     )
   where
     all_regs = if node_reqd then node:regs else regs
     )
   where
     all_regs = if node_reqd then node:regs else regs
-    liveness_mask = mkLiveRegsBitMask all_regs
+    liveness_mask = mkLiveRegsMask all_regs
 
     returns_prim_type = closureReturnsUnboxedType closure_info
 \end{code}
 
     returns_prim_type = closureReturnsUnboxedType closure_info
 \end{code}
@@ -817,8 +831,7 @@ setupUpdate :: ClosureInfo -> Code -> Code  -- Only called for thunks
 setupUpdate closure_info code
  = if (closureUpdReqd closure_info) then
        link_caf_if_needed      `thenFC` \ update_closure ->
 setupUpdate closure_info code
  = if (closureUpdReqd closure_info) then
        link_caf_if_needed      `thenFC` \ update_closure ->
-       getIntSwitchChkrC       `thenFC` \ isw_chkr ->
-       pushUpdateFrame update_closure (vector isw_chkr) code
+       pushUpdateFrame update_closure vector code
    else
        profCtrC SLIT("UPDF_OMITTED") [] `thenC`
        code
    else
        profCtrC SLIT("UPDF_OMITTED") [] `thenC`
        code
@@ -849,7 +862,7 @@ setupUpdate closure_info code
 
    closure_label = mkClosureLabel (closureId closure_info)
 
 
    closure_label = mkClosureLabel (closureId closure_info)
 
-   vector isw_chkr
+   vector
      = case (closureType closure_info) of
        Nothing -> CReg StdUpdRetVecReg
        Just (spec_tycon, _, spec_datacons) ->
      = case (closureType closure_info) of
        Nothing -> CReg StdUpdRetVecReg
        Just (spec_tycon, _, spec_datacons) ->
@@ -857,9 +870,9 @@ setupUpdate closure_info code
              UnvectoredReturn 1 ->
                        let
                    spec_data_con = head spec_datacons
              UnvectoredReturn 1 ->
                        let
                    spec_data_con = head spec_datacons
-                   only_tag = getDataConTag spec_data_con
+                   only_tag = dataConTag spec_data_con
 
 
-                   direct = case (dataReturnConvAlg isw_chkr spec_data_con) of
+                   direct = case (dataReturnConvAlg spec_data_con) of
                        ReturnInRegs _ -> mkConUpdCodePtrVecLabel spec_tycon only_tag
                        ReturnInHeap   -> mkStdUpdCodePtrVecLabel spec_tycon only_tag
 
                        ReturnInRegs _ -> mkConUpdCodePtrVecLabel spec_tycon only_tag
                        ReturnInHeap   -> mkStdUpdCodePtrVecLabel spec_tycon only_tag
 
@@ -893,8 +906,8 @@ closureDescription :: FAST_STRING   -- Module
        -- Not called for StgRhsCon which have global info tables built in
        -- CgConTbls.lhs with a description generated from the data constructor
 
        -- Not called for StgRhsCon which have global info tables built in
        -- CgConTbls.lhs with a description generated from the data constructor
 
-closureDescription mod_name name args body =
-    uppShow 0 (prettyToUn (
+closureDescription mod_name name args body
+  = uppShow 0 (prettyToUn (
        ppBesides [ppChar '<',
                   ppPStr mod_name,
                   ppChar '.',
        ppBesides [ppChar '<',
                   ppPStr mod_name,
                   ppChar '.',
index 4b52bf0..9b14dcd 100644 (file)
@@ -141,6 +141,9 @@ mAX_INTLIKE = MAX_INTLIKE
 
 \begin{code}
 -- THESE ARE DIRECTION SENSITIVE!
 
 \begin{code}
 -- THESE ARE DIRECTION SENSITIVE!
+spARelToInt :: Int{-VirtualSpAOffset-} -> Int{-VirtualSpAOffset-} -> Int
+spBRelToInt :: Int{-VirtualSpBOffset-} -> Int{-VirtualSpBOffset-} -> Int
+
 spARelToInt spA off = spA - off -- equiv to: AREL(spA - off)
 spBRelToInt spB off = off - spB -- equiv to: BREL(spB - off)
 \end{code}
 spARelToInt spA off = spA - off -- equiv to: AREL(spA - off)
 spBRelToInt spB off = off - spB -- equiv to: BREL(spB - off)
 \end{code}
index 8201335..6c378a9 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP Project, Glasgow University, 1992-1995
+% (c) The GRASP Project, Glasgow University, 1992-1996
 %
 \section[CgCon]{Code generation for constructors}
 
 %
 \section[CgCon]{Code generation for constructors}
 
@@ -11,55 +11,50 @@ with {\em constructors} on the RHSs of let(rec)s.  See also
 #include "HsVersions.h"
 
 module CgCon (
 #include "HsVersions.h"
 
 module CgCon (
-       -- it's all exported, actually...
        cgTopRhsCon, buildDynCon,
        bindConArgs,
        cgReturnDataCon
        cgTopRhsCon, buildDynCon,
        bindConArgs,
        cgReturnDataCon
-
-       -- and to make the interface self-sufficient...
     ) where
 
     ) where
 
-import StgSyn
+import Ubiq{-uitous-}
+
 import CgMonad
 import AbsCSyn
 import CgMonad
 import AbsCSyn
+import StgSyn
 
 
-import Type            ( maybeCharLikeTyCon, maybeIntLikeTyCon, TyVar,
-                         TyCon, Class, Type
-                       )
-import CgBindery       ( getAtomAmode, getAtomAmodes, bindNewToNode,
-                         bindArgsToRegs, newTempAmodeAndIdInfo, idInfoToAmode
+import AbsCUtils       ( mkAbstractCs, getAmodeRep )
+import CgBindery       ( getArgAmodes, bindNewToNode,
+                         bindArgsToRegs, newTempAmodeAndIdInfo,
+                         idInfoToAmode, stableAmodeIdInfo,
+                         heapIdInfo
                        )
 import CgClosure       ( cgTopRhsClosure )
                        )
 import CgClosure       ( cgTopRhsClosure )
-import CgHeapery       ( allocDynClosure, heapCheck
-#ifdef GRAN
-                         , fetchAndReschedule  -- HWL
-#endif  {- GRAN -}
-                       )
 import CgCompInfo      ( mAX_INTLIKE, mIN_INTLIKE )
 import CgCompInfo      ( mAX_INTLIKE, mIN_INTLIKE )
-
-import CgRetConv       ( dataReturnConvAlg, mkLiveRegsBitMask,
-                         CtrlReturnConvention(..), DataReturnConvention(..)
-                       )
+import CgHeapery       ( allocDynClosure )
+import CgRetConv       ( dataReturnConvAlg, DataReturnConvention(..) )
 import CgTailCall      ( performReturn, mkStaticAlgReturnCode )
 import CgTailCall      ( performReturn, mkStaticAlgReturnCode )
-import CgUsages                ( getHpRelOffset )
-import CLabel  ( CLabel, mkClosureLabel, mkInfoTableLabel,
+import CLabel          ( mkClosureLabel, mkInfoTableLabel,
                          mkPhantomInfoTableLabel,
                          mkConEntryLabel, mkStdEntryLabel
                        )
                          mkPhantomInfoTableLabel,
                          mkConEntryLabel, mkStdEntryLabel
                        )
-import ClosureInfo     -- hiding ( auxInfoTableLabelFromCI ) -- I hate pragmas
-                       {-( mkConLFInfo, mkLFArgument, closureLFInfo,
+import ClosureInfo     ( mkClosureLFInfo, mkConLFInfo, mkLFArgument,
                          layOutDynCon, layOutDynClosure,
                          layOutDynCon, layOutDynClosure,
-                         layOutStaticClosure, UpdateFlag(..),
-                         mkClosureLFInfo, layOutStaticNoFVClosure
-                       )-}
-import Id              ( getIdPrimRep, getDataConTag, getDataConTyCon,
-                         isDataCon, fIRST_TAG, DataCon(..), ConTag(..)
+                         layOutStaticClosure
+                       )
+import CostCentre      ( currentOrSubsumedCosts, useCurrentCostCentre,
+                         dontCareCostCentre
                        )
                        )
-import Maybes          ( maybeToBool, Maybe(..) )
-import PrimRep         ( PrimRep(..), isFloatingRep, getPrimRepSize )
-import CostCentre
-import UniqSet         -- ( emptyUniqSet, UniqSet(..) )
-import Util
+import Id              ( idPrimRep, dataConTag, dataConTyCon,
+                         isDataCon, DataCon(..),
+                         emptyIdSet
+                       )
+import Literal         ( Literal(..) )
+import Maybes          ( maybeToBool )
+import PrimRep         ( isFloatingRep, PrimRep(..) )
+import Util            ( isIn, zipWithEqual, panic, assertPanic )
+
+maybeCharLikeTyCon = panic "CgCon.maybeCharLikeTyCon (ToDo)"
+maybeIntLikeTyCon  = panic "CgCon.maybeIntLikeTyCon  (ToDo)"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -71,7 +66,7 @@ import Util
 \begin{code}
 cgTopRhsCon :: Id              -- Name of thing bound to this RHS
            -> DataCon          -- Id
 \begin{code}
 cgTopRhsCon :: Id              -- Name of thing bound to this RHS
            -> DataCon          -- Id
-           -> [StgArg] -- Args
+           -> [StgArg]         -- Args
            -> Bool             -- All zero-size args (see buildDynCon)
            -> FCode (Id, CgIdInfo)
 \end{code}
            -> Bool             -- All zero-size args (see buildDynCon)
            -> FCode (Id, CgIdInfo)
 \end{code}
@@ -130,7 +125,7 @@ cgTopRhsCon name con args all_zero_size_args
   || any isLitLitArg args
   = cgTopRhsClosure name top_cc NoStgBinderInfo [] body lf_info
   where
   || any isLitLitArg args
   = cgTopRhsClosure name top_cc NoStgBinderInfo [] body lf_info
   where
-    body = StgCon con args emptyUniqSet{-emptyLiveVarSet-}
+    body = StgCon con args emptyIdSet{-emptyLiveVarSet-}
     lf_info = mkClosureLFInfo True {- Top level -} [] ReEntrant [] body
 \end{code}
 
     lf_info = mkClosureLFInfo True {- Top level -} [] ReEntrant [] body
 \end{code}
 
@@ -142,7 +137,7 @@ cgTopRhsCon name con args all_zero_size_args
     ASSERT(isDataCon con)
 
        -- LAY IT OUT
     ASSERT(isDataCon con)
 
        -- LAY IT OUT
-    getAtomAmodes args         `thenFC` \ amodes ->
+    getArgAmodes args          `thenFC` \ amodes ->
 
     let
        (closure_info, amodes_w_offsets)
 
     let
        (closure_info, amodes_w_offsets)
@@ -163,13 +158,13 @@ cgTopRhsCon name con args all_zero_size_args
        -- RETURN
     returnFC (name, stableAmodeIdInfo name (CLbl closure_label PtrRep) lf_info)
   where
        -- RETURN
     returnFC (name, stableAmodeIdInfo name (CLbl closure_label PtrRep) lf_info)
   where
-    con_tycon      = getDataConTyCon con
-    lf_info        = mkConLFInfo con
+    con_tycon      = dataConTyCon con
+    lf_info        = mkConLFInfo     con
 
 
-    closure_label   = mkClosureLabel  name
+    closure_label   = mkClosureLabel   name
     info_label      = mkInfoTableLabel con
     info_label      = mkInfoTableLabel con
-    con_entry_label = mkConEntryLabel con
-    entry_label            = mkStdEntryLabel name
+    con_entry_label = mkConEntryLabel  con
+    entry_label            = mkStdEntryLabel  name
 \end{code}
 
 The general case is:
 \end{code}
 
 The general case is:
@@ -314,10 +309,10 @@ buildDynCon binder cc con [arg_amode] all_zero_size_args@False
   = ASSERT(isDataCon con)
     returnFC (stableAmodeIdInfo binder (CIntLike arg_amode) (mkConLFInfo con))
   where
   = ASSERT(isDataCon con)
     returnFC (stableAmodeIdInfo binder (CIntLike arg_amode) (mkConLFInfo con))
   where
-    tycon = getDataConTyCon con
+    tycon = dataConTyCon con
     (temp_amode, temp_id_info) = newTempAmodeAndIdInfo binder (mkConLFInfo con)
 
     (temp_amode, temp_id_info) = newTempAmodeAndIdInfo binder (mkConLFInfo con)
 
-    in_range_int_lit (CLit (MachInt val _)) = (val <= mAX_INTLIKE) && (val >= mIN_INTLIKE)
+    in_range_int_lit (CLit (MachInt val _)) = val <= mAX_INTLIKE && val >= mIN_INTLIKE
     in_range_int_lit other_amode           = False
 \end{code}
 
     in_range_int_lit other_amode           = False
 \end{code}
 
@@ -357,13 +352,11 @@ found a $con$.
 bindConArgs :: DataCon -> [Id] -> Code
 bindConArgs con args
   = ASSERT(isDataCon con)
 bindConArgs :: DataCon -> [Id] -> Code
 bindConArgs con args
   = ASSERT(isDataCon con)
-    getIntSwitchChkrC  `thenFC` \ isw_chkr ->
-
-    case (dataReturnConvAlg isw_chkr con) of
+    case (dataReturnConvAlg con) of
       ReturnInRegs rs  -> bindArgsToRegs args rs
       ReturnInHeap     ->
          let
       ReturnInRegs rs  -> bindArgsToRegs args rs
       ReturnInHeap     ->
          let
-             (_, args_w_offsets) = layOutDynCon con getIdPrimRep args
+             (_, args_w_offsets) = layOutDynCon con idPrimRep args
          in
          mapCs bind_arg args_w_offsets
    where
          in
          mapCs bind_arg args_w_offsets
    where
@@ -385,13 +378,12 @@ cgReturnDataCon :: DataCon -> [CAddrMode] -> Bool -> StgLiveVars -> Code
 
 cgReturnDataCon con amodes all_zero_size_args live_vars
   = ASSERT(isDataCon con)
 
 cgReturnDataCon con amodes all_zero_size_args live_vars
   = ASSERT(isDataCon con)
-    getIntSwitchChkrC  `thenFC` \ isw_chkr ->
     getEndOfBlockInfo  `thenFC` \ (EndOfBlockInfo args_spa args_spb sequel) ->
 
     case sequel of
 
       CaseAlts _ (Just (alts, Just (maybe_deflt_binder, (_,deflt_lbl))))
     getEndOfBlockInfo  `thenFC` \ (EndOfBlockInfo args_spa args_spb sequel) ->
 
     case sequel of
 
       CaseAlts _ (Just (alts, Just (maybe_deflt_binder, (_,deflt_lbl))))
-       | not (getDataConTag con `is_elem` map fst alts)
+       | not (dataConTag con `is_elem` map fst alts)
        ->
                -- Special case!  We're returning a constructor to the default case
                -- of an enclosing case.  For example:
        ->
                -- Special case!  We're returning a constructor to the default case
                -- of an enclosing case.  For example:
@@ -423,7 +415,7 @@ cgReturnDataCon con amodes all_zero_size_args live_vars
                -- Ignore the sequel: we've already looked at it above
 
       other_sequel ->  -- The usual case
                -- Ignore the sequel: we've already looked at it above
 
       other_sequel ->  -- The usual case
-           case (dataReturnConvAlg isw_chkr con) of
+           case (dataReturnConvAlg con) of
 
              ReturnInHeap          ->
                        -- BUILD THE OBJECT IN THE HEAP
 
              ReturnInHeap          ->
                        -- BUILD THE OBJECT IN THE HEAP
index 79dd48e..4252890 100644 (file)
@@ -1,59 +1,52 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[CgConTbls]{Info tables and update bits for constructors}
 
 \begin{code}
 #include "HsVersions.h"
 
 %
 \section[CgConTbls]{Info tables and update bits for constructors}
 
 \begin{code}
 #include "HsVersions.h"
 
-module CgConTbls (
-       genStaticConBits,
+module CgConTbls ( genStaticConBits ) where
 
 
-       -- and to complete the interface...
-       TCE(..), UniqFM, CompilationInfo, AbstractC
-    ) where
-
-import Pretty          -- ToDo: rm (debugging)
-import Outputable
+import Ubiq{-uitous-}
 
 import AbsCSyn
 import CgMonad
 
 
 import AbsCSyn
 import CgMonad
 
-import Type            ( getTyConDataCons, primRepFromType,
-                         maybeIntLikeTyCon, mkSpecTyCon,
-                         TyVarTemplate, TyCon, Class,
-                         TauType(..), Type, ThetaType(..)
-                       )
+import AbsCUtils       ( mkAbsCStmts, mkAbstractCs, magicIdPrimRep )
+import CgCompInfo      ( uF_UPDATEE )
 import CgHeapery       ( heapCheck, allocDynClosure )
 import CgHeapery       ( heapCheck, allocDynClosure )
-import CgRetConv       ( dataReturnConvAlg, ctrlReturnConvAlg,
-                         mkLiveRegsBitMask,
+import CgRetConv       ( mkLiveRegsMask,
+                         dataReturnConvAlg, ctrlReturnConvAlg,
                          CtrlReturnConvention(..),
                          DataReturnConvention(..)
                        )
 import CgTailCall      ( performReturn, mkStaticAlgReturnCode )
 import CgUsages                ( getHpRelOffset )
                          CtrlReturnConvention(..),
                          DataReturnConvention(..)
                        )
 import CgTailCall      ( performReturn, mkStaticAlgReturnCode )
 import CgUsages                ( getHpRelOffset )
-import CLabel  ( mkConEntryLabel, mkStaticConEntryLabel,
-                         mkClosureLabel,
-                         mkConUpdCodePtrVecLabel, mkStdUpdCodePtrVecLabel,
-                         mkStdUpdVecTblLabel, CLabel
+import CLabel          ( mkConEntryLabel, mkClosureLabel,
+                         mkConUpdCodePtrVecLabel,
+                         mkStdUpdCodePtrVecLabel, mkStdUpdVecTblLabel
                        )
 import ClosureInfo     ( layOutStaticClosure, layOutDynCon,
                        )
 import ClosureInfo     ( layOutStaticClosure, layOutDynCon,
-                         closureSizeWithoutFixedHdr, closurePtrsSize,
-                         fitsMinUpdSize, mkConLFInfo, layOutPhantomClosure,
+                         layOutPhantomClosure, closurePtrsSize,
+                         fitsMinUpdSize, mkConLFInfo,
                          infoTableLabelFromCI, dataConLiveness
                        )
                          infoTableLabelFromCI, dataConLiveness
                        )
-import FiniteMap
-import Id              ( getDataConTag, getDataConSig, getDataConTyCon,
-                         mkSameSpecCon,
-                         getDataConArity, fIRST_TAG, ConTag(..),
-                         DataCon(..)
+import CostCentre      ( dontCareCostCentre )
+import FiniteMap       ( fmToList )
+import HeapOffs                ( zeroOff, VirtualHeapOffset(..) )
+import Id              ( dataConTag, dataConSig,
+                         dataConArity, fIRST_TAG,
+                         emptyIdSet,
+                         GenId{-instance NamedThing-}
                        )
                        )
-import CgCompInfo      ( uF_UPDATEE )
-import Maybes          ( maybeToBool, Maybe(..) )
-import PrimRep         ( getPrimRepSize, retPrimRepSize )
-import CostCentre
-import UniqSet         -- ( emptyUniqSet, UniqSet(..) )
-import Util
+import PrimRep         ( getPrimRepSize, PrimRep(..) )
+import TyCon           ( tyConDataCons, mkSpecTyCon )
+import Type            ( typePrimRep )
+import Util            ( panic )
+
+maybeIntLikeTyCon = panic "CgConTbls.maybeIntLikeTyCon (ToDo)"
+mkSameSpecCon = panic "CgConTbls.mkSameSpecCon (ToDo)"
 \end{code}
 
 For every constructor we generate the following info tables:
 \end{code}
 
 For every constructor we generate the following info tables:
@@ -139,7 +132,7 @@ genStaticConBits comp_info gen_tycons tycon_specs
          `mkAbsCStmts`
        maybe_tycon_vtbl
       where
          `mkAbsCStmts`
        maybe_tycon_vtbl
       where
-       data_cons       = getTyConDataCons tycon
+       data_cons       = tyConDataCons tycon
        tycon_upd_label = mkStdUpdVecTblLabel tycon
 
        maybe_tycon_vtbl =
        tycon_upd_label = mkStdUpdVecTblLabel tycon
 
        maybe_tycon_vtbl =
@@ -157,7 +150,7 @@ genStaticConBits comp_info gen_tycons tycon_specs
          `mkAbsCStmts`
        maybe_spec_tycon_vtbl
       where
          `mkAbsCStmts`
        maybe_spec_tycon_vtbl
       where
-       data_cons      = getTyConDataCons tycon
+       data_cons      = tyConDataCons tycon
 
        spec_tycon     = mkSpecTyCon tycon ty_maybes
        spec_data_cons = map (mkSameSpecCon ty_maybes) data_cons
 
        spec_tycon     = mkSpecTyCon tycon ty_maybes
        spec_data_cons = map (mkSameSpecCon ty_maybes) data_cons
@@ -174,15 +167,12 @@ genStaticConBits comp_info gen_tycons tycon_specs
     ------------------
     mk_upd_label tycon con
       = CLbl
     ------------------
     mk_upd_label tycon con
       = CLbl
-       (case (dataReturnConvAlg isw_chkr con) of
+       (case (dataReturnConvAlg con) of
          ReturnInRegs _ -> mkConUpdCodePtrVecLabel tycon tag
          ReturnInHeap   -> mkStdUpdCodePtrVecLabel tycon tag)
        CodePtrRep
       where
          ReturnInRegs _ -> mkConUpdCodePtrVecLabel tycon tag
          ReturnInHeap   -> mkStdUpdCodePtrVecLabel tycon tag)
        CodePtrRep
       where
-       tag = getDataConTag con
-
-    ------------------
-    (MkCompInfo sw_chkr isw_chkr _) = comp_info
+       tag = dataConTag con
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -197,7 +187,7 @@ static closure, for a constructor.
 \begin{code}
 genConInfo :: CompilationInfo -> TyCon -> Id -> AbstractC
 
 \begin{code}
 genConInfo :: CompilationInfo -> TyCon -> Id -> AbstractC
 
-genConInfo comp_info@(MkCompInfo _ isw_chkr _) tycon data_con
+genConInfo comp_info tycon data_con
   = mkAbstractCs [
                  CSplitMarker,
                  inregs_upd_maybe,
   = mkAbstractCs [
                  CSplitMarker,
                  inregs_upd_maybe,
@@ -206,12 +196,12 @@ genConInfo comp_info@(MkCompInfo _ isw_chkr _) tycon data_con
                  closure_maybe]
        -- Order of things is to reduce forward references
   where
                  closure_maybe]
        -- Order of things is to reduce forward references
   where
-    (closure_info, body_code) = mkConCodeAndInfo isw_chkr data_con
+    (closure_info, body_code) = mkConCodeAndInfo data_con
 
     -- To allow the debuggers, interpreters, etc to cope with static
     -- data structures (ie those built at compile time), we take care that
     -- info-table contains the information we need.
 
     -- To allow the debuggers, interpreters, etc to cope with static
     -- data structures (ie those built at compile time), we take care that
     -- info-table contains the information we need.
-    (static_ci,_) = layOutStaticClosure data_con primRepFromType arg_tys (mkConLFInfo data_con)
+    (static_ci,_) = layOutStaticClosure data_con typePrimRep arg_tys (mkConLFInfo data_con)
 
     body       = (initC comp_info (
                      profCtrC SLIT("ENT_CON") [CReg node] `thenC`
 
     body       = (initC comp_info (
                      profCtrC SLIT("ENT_CON") [CReg node] `thenC`
@@ -222,16 +212,16 @@ genConInfo comp_info@(MkCompInfo _ isw_chkr _) tycon data_con
 
     closure_code        = CClosureInfoAndCode closure_info body Nothing
                                              stdUpd con_descr
 
     closure_code        = CClosureInfoAndCode closure_info body Nothing
                                              stdUpd con_descr
-                                             (dataConLiveness isw_chkr closure_info)
+                                             (dataConLiveness closure_info)
     static_code         = CClosureInfoAndCode static_ci body Nothing
                                              stdUpd con_descr
     static_code         = CClosureInfoAndCode static_ci body Nothing
                                              stdUpd con_descr
-                                             (dataConLiveness isw_chkr static_ci)
+                                             (dataConLiveness static_ci)
 
     inregs_upd_maybe    = genPhantomUpdInfo comp_info tycon data_con
 
     stdUpd             = CLbl (mkStdUpdCodePtrVecLabel tycon tag) CodePtrRep
 
 
     inregs_upd_maybe    = genPhantomUpdInfo comp_info tycon data_con
 
     stdUpd             = CLbl (mkStdUpdCodePtrVecLabel tycon tag) CodePtrRep
 
-    tag                        = getDataConTag data_con
+    tag                        = dataConTag data_con
 
     cost_centre = mkCCostCentre dontCareCostCentre -- not worried about static data costs
 
 
     cost_centre = mkCCostCentre dontCareCostCentre -- not worried about static data costs
 
@@ -247,42 +237,41 @@ genConInfo comp_info@(MkCompInfo _ isw_chkr _) tycon data_con
                                        cost_centre
                                        [{-No args!  A slight lie for constrs with VoidRep args-}]
 
                                        cost_centre
                                        [{-No args!  A slight lie for constrs with VoidRep args-}]
 
-    zero_size arg_ty = getPrimRepSize (primRepFromType arg_ty) == 0
+    zero_size arg_ty = getPrimRepSize (typePrimRep arg_ty) == 0
 
 
-    (_,_,arg_tys,_) = getDataConSig   data_con
-    con_arity      = getDataConArity data_con
+    (_,_,arg_tys,_) = dataConSig   data_con
+    con_arity      = dataConArity data_con
     entry_label     = mkConEntryLabel data_con
     closure_label   = mkClosureLabel  data_con
 \end{code}
 
 \begin{code}
     entry_label     = mkConEntryLabel data_con
     closure_label   = mkClosureLabel  data_con
 \end{code}
 
 \begin{code}
-mkConCodeAndInfo :: IntSwitchChecker
-                -> Id                  -- Data constructor
+mkConCodeAndInfo :: Id                         -- Data constructor
                 -> (ClosureInfo, Code) -- The info table
 
                 -> (ClosureInfo, Code) -- The info table
 
-mkConCodeAndInfo isw_chkr con
-  = case (dataReturnConvAlg isw_chkr con) of
+mkConCodeAndInfo con
+  = case (dataReturnConvAlg con) of
 
     ReturnInRegs regs ->
        let
            (closure_info, regs_w_offsets)
 
     ReturnInRegs regs ->
        let
            (closure_info, regs_w_offsets)
-             = layOutDynCon con kindFromMagicId regs
+             = layOutDynCon con magicIdPrimRep regs
 
            body_code
              = profCtrC SLIT("RET_OLD_IN_REGS") [mkIntCLit (length regs_w_offsets)] `thenC`
 
                performReturn (mkAbstractCs (map move_to_reg regs_w_offsets))
                              (mkStaticAlgReturnCode con Nothing {- Info-ptr already loaded-})
 
            body_code
              = profCtrC SLIT("RET_OLD_IN_REGS") [mkIntCLit (length regs_w_offsets)] `thenC`
 
                performReturn (mkAbstractCs (map move_to_reg regs_w_offsets))
                              (mkStaticAlgReturnCode con Nothing {- Info-ptr already loaded-})
-                             emptyUniqSet{-no live vars-}
+                             emptyIdSet{-no live vars-}
        in
        (closure_info, body_code)
 
     ReturnInHeap ->
        let
        in
        (closure_info, body_code)
 
     ReturnInHeap ->
        let
-           (_, _, arg_tys, _) = getDataConSig con
+           (_, _, arg_tys, _) = dataConSig con
 
            (closure_info, arg_things)
 
            (closure_info, arg_things)
-               = layOutDynCon con primRepFromType arg_tys
+               = layOutDynCon con typePrimRep arg_tys
 
            body_code
                = -- NB: We don't set CC when entering data (WDP 94/06)
 
            body_code
                = -- NB: We don't set CC when entering data (WDP 94/06)
@@ -290,14 +279,14 @@ mkConCodeAndInfo isw_chkr con
 
                  performReturn AbsCNop -- Ptr to thing already in Node
                                (mkStaticAlgReturnCode con Nothing {- Info-ptr already loaded-})
 
                  performReturn AbsCNop -- Ptr to thing already in Node
                                (mkStaticAlgReturnCode con Nothing {- Info-ptr already loaded-})
-                               emptyUniqSet{-no live vars-}
+                               emptyIdSet{-no live vars-}
        in
        (closure_info, body_code)
 
   where
     move_to_reg :: (MagicId, VirtualHeapOffset {-from Node-}) -> AbstractC
     move_to_reg (reg, offset)
        in
        (closure_info, body_code)
 
   where
     move_to_reg :: (MagicId, VirtualHeapOffset {-from Node-}) -> AbstractC
     move_to_reg (reg, offset)
-      = CAssign (CReg reg) (CVal (NodeRel offset) (kindFromMagicId reg))
+      = CAssign (CReg reg) (CVal (NodeRel offset) (magicIdPrimRep reg))
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -312,8 +301,8 @@ Generate the "phantom" info table and update code, iff the constructor returns i
 
 genPhantomUpdInfo :: CompilationInfo -> TyCon -> Id{-data con-} -> AbstractC
 
 
 genPhantomUpdInfo :: CompilationInfo -> TyCon -> Id{-data con-} -> AbstractC
 
-genPhantomUpdInfo comp_info@(MkCompInfo _ isw_chkr _) tycon data_con
-  = case (dataReturnConvAlg isw_chkr data_con) of
+genPhantomUpdInfo comp_info tycon data_con
+  = case (dataReturnConvAlg data_con) of
 
       ReturnInHeap -> AbsCNop  -- No need for a phantom update
 
 
       ReturnInHeap -> AbsCNop  -- No need for a phantom update
 
@@ -321,19 +310,19 @@ genPhantomUpdInfo comp_info@(MkCompInfo _ isw_chkr _) tycon data_con
        let
            phantom_itbl = CClosureInfoAndCode phantom_ci AbsCNop Nothing
                                upd_code con_descr
        let
            phantom_itbl = CClosureInfoAndCode phantom_ci AbsCNop Nothing
                                upd_code con_descr
-                               (dataConLiveness isw_chkr phantom_ci)
+                               (dataConLiveness phantom_ci)
 
            phantom_ci = layOutPhantomClosure data_con (mkConLFInfo data_con)
 
            con_descr = _UNPK_ (getOccurrenceName data_con)
 
 
            phantom_ci = layOutPhantomClosure data_con (mkConLFInfo data_con)
 
            con_descr = _UNPK_ (getOccurrenceName data_con)
 
-           con_arity = getDataConArity data_con
+           con_arity = dataConArity data_con
 
            upd_code = CLabelledCode upd_label (mkAbsCStmts build_closure perform_return)
            upd_label = mkConUpdCodePtrVecLabel tycon tag
 
            upd_code = CLabelledCode upd_label (mkAbsCStmts build_closure perform_return)
            upd_label = mkConUpdCodePtrVecLabel tycon tag
-           tag = getDataConTag data_con
+           tag = dataConTag data_con
 
 
-           updatee = CVal (SpBRel 0 (-uF_UPDATEE)) PtrRep
+           updatee = CVal (SpBRel 0 (- uF_UPDATEE)) PtrRep
 
            perform_return = mkAbstractCs
              [
 
            perform_return = mkAbstractCs
              [
@@ -352,7 +341,7 @@ genPhantomUpdInfo comp_info@(MkCompInfo _ isw_chkr _) tycon data_con
            blame_cc = use_cc -- who to blame for allocation
 
            do_move (reg, virt_offset) =
            blame_cc = use_cc -- who to blame for allocation
 
            do_move (reg, virt_offset) =
-               CAssign (CVal (NodeRel virt_offset) (kindFromMagicId reg)) (CReg reg)
+               CAssign (CVal (NodeRel virt_offset) (magicIdPrimRep reg)) (CReg reg)
 
 
            -- Code for building a new constructor in place over the updatee
 
 
            -- Code for building a new constructor in place over the updatee
@@ -402,9 +391,9 @@ genPhantomUpdInfo comp_info@(MkCompInfo _ isw_chkr _) tycon data_con
                        CAssign (CReg infoptr) (CLbl info_label DataPtrRep)
                      ])
 
                        CAssign (CReg infoptr) (CLbl info_label DataPtrRep)
                      ])
 
-           (closure_info, regs_w_offsets) = layOutDynCon data_con kindFromMagicId regs
+           (closure_info, regs_w_offsets) = layOutDynCon data_con magicIdPrimRep regs
            info_label = infoTableLabelFromCI closure_info
            info_label = infoTableLabelFromCI closure_info
-           liveness_mask = mkIntCLit (mkLiveRegsBitMask (node:regs))
+           liveness_mask = mkIntCLit (mkLiveRegsMask (node:regs))
 
            build_closure =
              if fitsMinUpdSize closure_info then
 
            build_closure =
              if fitsMinUpdSize closure_info then
index 4713767..6fed112 100644 (file)
 \begin{code}
 #include "HsVersions.h"
 
 \begin{code}
 #include "HsVersions.h"
 
-module CgExpr (
-       cgExpr, cgSccExpr, getPrimOpArgAmodes
+module CgExpr ( cgExpr, cgSccExpr, getPrimOpArgAmodes ) where
 
 
-       -- and to make the interface self-sufficient...
-    ) where
+import Ubiq{-uitous-}
+import CgLoop2 -- here for paranoia-checking
 
 import StgSyn
 import CgMonad
 import AbsCSyn
 
 
 import StgSyn
 import CgMonad
 import AbsCSyn
 
-import PrelInfo                ( PrimOp(..), PrimOpResultInfo(..), HeapRequirement(..),
-                         primOpHeapReq, getPrimOpResultInfo, PrimRep,
-                         primOpCanTriggerGC
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                       )
-import Type            ( isPrimType, getTyConDataCons )
-import CLabel  ( CLabel, mkPhantomInfoTableLabel, mkInfoTableVecTblLabel )
-import ClosureInfo     ( LambdaFormInfo, mkClosureLFInfo )
-import CgBindery       ( getAtomAmodes )
+import AbsCUtils       ( mkAbsCStmts, mkAbstractCs )
+import CgBindery       ( getArgAmodes )
 import CgCase          ( cgCase, saveVolatileVarsAndRegs )
 import CgClosure       ( cgRhsClosure )
 import CgCon           ( buildDynCon, cgReturnDataCon )
 import CgHeapery       ( allocHeap )
 import CgLetNoEscape   ( cgLetNoEscapeClosure )
 import CgCase          ( cgCase, saveVolatileVarsAndRegs )
 import CgClosure       ( cgRhsClosure )
 import CgCon           ( buildDynCon, cgReturnDataCon )
 import CgHeapery       ( allocHeap )
 import CgLetNoEscape   ( cgLetNoEscapeClosure )
-import CgRetConv       -- various things...
-import CgTailCall      ( cgTailCall, performReturn, mkDynamicAlgReturnCode,
-                         mkPrimReturnCode
+import CgRetConv       ( dataReturnConvAlg, ctrlReturnConvAlg,
+                         DataReturnConvention(..), CtrlReturnConvention(..),
+                         assignPrimOpResultRegs, makePrimOpArgsRobust
+                       )
+import CgTailCall      ( cgTailCall, performReturn,
+                         mkDynamicAlgReturnCode, mkPrimReturnCode
+                       )
+import CLabel          ( mkPhantomInfoTableLabel, mkInfoTableVecTblLabel )
+import ClosureInfo     ( mkClosureLFInfo )
+import CostCentre      ( setToAbleCostCentre, isDupdCC )
+import HeapOffs                ( VirtualSpBOffset(..) )
+import Id              ( mkIdSet, unionIdSets, GenId{-instance Outputable-} )
+import PprStyle                ( PprStyle(..) )
+import PrimOp          ( primOpCanTriggerGC, primOpHeapReq, HeapRequirement(..),
+                         getPrimOpResultInfo, PrimOp(..), PrimOpResultInfo(..)
                        )
                        )
-import CostCentre      ( setToAbleCostCentre, isDupdCC, CostCentre )
-import Maybes          ( Maybe(..) )
-import PrimRep         ( getPrimRepSize )
-import UniqSet
-import Util
+import PrimRep         ( getPrimRepSize, PrimRep(..) )
+import TyCon           ( tyConDataCons )
+import Util            ( panic, pprPanic )
 \end{code}
 
 This module provides the support code for @StgToAbstractC@ to deal
 \end{code}
 
 This module provides the support code for @StgToAbstractC@ to deal
@@ -77,7 +78,7 @@ cgExpr (StgApp fun args live_vars) = cgTailCall fun args live_vars
 
 \begin{code}
 cgExpr (StgCon con args live_vars)
 
 \begin{code}
 cgExpr (StgCon con args live_vars)
-  = getAtomAmodes args `thenFC` \ amodes ->
+  = getArgAmodes args `thenFC` \ amodes ->
     cgReturnDataCon con amodes (all zero_size args) live_vars
   where
     zero_size atom = getPrimRepSize (getArgPrimRep atom) == 0
     cgReturnDataCon con amodes (all zero_size args) live_vars
   where
     zero_size atom = getPrimRepSize (getArgPrimRep atom) == 0
@@ -93,10 +94,9 @@ Here is where we insert real live machine instructions.
 
 \begin{code}
 cgExpr x@(StgPrim op args live_vars)
 
 \begin{code}
 cgExpr x@(StgPrim op args live_vars)
-  = getIntSwitchChkrC          `thenFC` \ isw_chkr ->
-    getPrimOpArgAmodes op args `thenFC` \ arg_amodes ->
+  = getPrimOpArgAmodes op args `thenFC` \ arg_amodes ->
     let
     let
-       result_regs   = assignPrimOpResultRegs {-NO:isw_chkr-} op
+       result_regs   = assignPrimOpResultRegs op
        result_amodes = map CReg result_regs
        may_gc  = primOpCanTriggerGC op
        dyn_tag = head result_amodes
        result_amodes = map CReg result_regs
        may_gc  = primOpCanTriggerGC op
        dyn_tag = head result_amodes
@@ -108,7 +108,7 @@ cgExpr x@(StgPrim op args live_vars)
        -- (Can-trigger-gc primops guarantee to have their args in regs)
        let
            (arg_robust_amodes, liveness_mask, arg_assts)
        -- (Can-trigger-gc primops guarantee to have their args in regs)
        let
            (arg_robust_amodes, liveness_mask, arg_assts)
-             = makePrimOpArgsRobust {-NO:isw_chkr-} op arg_amodes
+             = makePrimOpArgsRobust op arg_amodes
 
            liveness_arg = mkIntCLit liveness_mask
        in
 
            liveness_arg = mkIntCLit liveness_mask
        in
@@ -172,10 +172,10 @@ cgExpr x@(StgPrim op args live_vars)
                vec_lbl  = CTableEntry (CLbl (mkInfoTableVecTblLabel tycon) DataPtrRep)
                                dyn_tag DataPtrRep
 
                vec_lbl  = CTableEntry (CLbl (mkInfoTableVecTblLabel tycon) DataPtrRep)
                                dyn_tag DataPtrRep
 
-               data_con = head (getTyConDataCons tycon)
+               data_con = head (tyConDataCons tycon)
 
                (dir_lbl, num_of_fields)
 
                (dir_lbl, num_of_fields)
-                 = case (dataReturnConvAlg fake_isw_chkr data_con) of
+                 = case (dataReturnConvAlg data_con) of
                      ReturnInRegs rs
                        -> (CLbl (mkPhantomInfoTableLabel data_con) DataPtrRep,
                            mkIntCLit (length rs)) -- for ticky-ticky only
                      ReturnInRegs rs
                        -> (CLbl (mkPhantomInfoTableLabel data_con) DataPtrRep,
                            mkIntCLit (length rs)) -- for ticky-ticky only
@@ -184,8 +184,6 @@ cgExpr x@(StgPrim op args live_vars)
                        -> pprPanic "CgExpr: can't return prim in heap:" (ppr PprDebug data_con)
                          -- Never used, and no point in generating
                          -- the code for it!
                        -> pprPanic "CgExpr: can't return prim in heap:" (ppr PprDebug data_con)
                          -- Never used, and no point in generating
                          -- the code for it!
-
-               fake_isw_chkr x = Nothing
   where
     -- for all PrimOps except ccalls, we pin the liveness info
     -- on as the first "argument"
   where
     -- for all PrimOps except ccalls, we pin the liveness info
     -- on as the first "argument"
@@ -314,7 +312,7 @@ cgRhs :: Id -> StgRhs -> FCode (Id, CgIdInfo)
        -- the Id is passed along so a binding can be set up
 
 cgRhs name (StgRhsCon maybe_cc con args)
        -- the Id is passed along so a binding can be set up
 
 cgRhs name (StgRhsCon maybe_cc con args)
-  = getAtomAmodes args         `thenFC` \ amodes ->
+  = getArgAmodes args          `thenFC` \ amodes ->
     buildDynCon name maybe_cc con amodes (all zero_size args)
                                `thenFC` \ idinfo ->
     returnFC (name, idinfo)
     buildDynCon name maybe_cc con amodes (all zero_size args)
                                `thenFC` \ idinfo ->
     returnFC (name, idinfo)
@@ -344,7 +342,7 @@ cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot (StgRec pairs)
   where
     -- We add the binders to the live-in-rhss set so that we don't
     -- delete the bindings for the binder from the environment!
   where
     -- We add the binders to the live-in-rhss set so that we don't
     -- delete the bindings for the binder from the environment!
-    full_live_in_rhss = live_in_rhss `unionUniqSets` (mkUniqSet [b | (b,r) <- pairs])
+    full_live_in_rhss = live_in_rhss `unionIdSets` (mkIdSet [b | (b,r) <- pairs])
 
 cgLetNoEscapeRhs
     :: StgLiveVars     -- Live in rhss
 
 cgLetNoEscapeRhs
     :: StgLiveVars     -- Live in rhss
@@ -386,10 +384,9 @@ Main current use: allocating SynchVars.
 
 \begin{code}
 getPrimOpArgAmodes op args
 
 \begin{code}
 getPrimOpArgAmodes op args
-  = getAtomAmodes args         `thenFC` \ arg_amodes ->
+  = getArgAmodes args          `thenFC` \ arg_amodes ->
 
     case primOpHeapReq op of
 
     case primOpHeapReq op of
-
        FixedHeapRequired size -> allocHeap size `thenFC` \ amode ->
                                  returnFC (amode : arg_amodes)
 
        FixedHeapRequired size -> allocHeap size `thenFC` \ amode ->
                                  returnFC (amode : arg_amodes)
 
index 98aed04..798c6ba 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1994
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[CgHeapery]{Heap management functions}
 
 %
 \section[CgHeapery]{Heap management functions}
 
@@ -8,30 +8,31 @@
 
 module CgHeapery (
        heapCheck,
 
 module CgHeapery (
        heapCheck,
-       allocHeap, allocDynClosure,
+       allocHeap, allocDynClosure
 
 #ifdef GRAN
        -- new for GrAnSim    HWL
 
 #ifdef GRAN
        -- new for GrAnSim    HWL
-       heapCheckOnly, fetchAndReschedule,
+       , heapCheckOnly, fetchAndReschedule
 #endif  {- GRAN -}
 #endif  {- GRAN -}
-
-       -- and to make the interface self-sufficient...
-       AbstractC, CAddrMode, HeapOffset,
-       CgState, ClosureInfo, Id
     ) where
 
     ) where
 
+import Ubiq{-uitous-}
+
 import AbsCSyn
 import CgMonad
 
 import AbsCSyn
 import CgMonad
 
-import CgRetConv       ( mkLiveRegsBitMask )
+import AbsCUtils       ( mkAbstractCs, getAmodeRep )
+import CgRetConv       ( mkLiveRegsMask )
 import CgUsages                ( getVirtAndRealHp, setVirtHp, setRealHp,
                          initHeapUsage
                        )
 import CgUsages                ( getVirtAndRealHp, setVirtHp, setRealHp,
                          initHeapUsage
                        )
-import ClosureInfo     ( closureSize, closureHdrSize, closureGoodStuffSize, slopSize,
-                         layOutDynClosure,
-                         allocProfilingMsg, closureKind
+import ClosureInfo     ( closureSize, closureHdrSize, closureGoodStuffSize,
+                         slopSize, allocProfilingMsg, closureKind
+                       )
+import HeapOffs                ( isZeroOff, addOff, intOff,
+                         VirtualHeapOffset(..)
                        )
                        )
-import Util
+import PrimRep         ( PrimRep(..) )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -70,7 +71,7 @@ heapCheck regs node_reqd code
            -- at once or not.
       where
        all_regs = if node_reqd then node:regs else regs
            -- at once or not.
       where
        all_regs = if node_reqd then node:regs else regs
-       liveness_mask = mkLiveRegsBitMask all_regs
+       liveness_mask = mkLiveRegsMask all_regs
 
        checking_code = CMacroStmt HEAP_CHK [
                        mkIntCLit liveness_mask,
 
        checking_code = CMacroStmt HEAP_CHK [
                        mkIntCLit liveness_mask,
@@ -149,7 +150,7 @@ heapCheck' do_context_switch regs node_reqd code
            -- at once or not.
       where
        all_regs = if node_reqd then node:regs else regs
            -- at once or not.
       where
        all_regs = if node_reqd then node:regs else regs
-       liveness_mask = mkLiveRegsBitMask all_regs
+       liveness_mask = mkLiveRegsMask all_regs
 
        maybe_context_switch = if do_context_switch
                                then context_switch_code
 
        maybe_context_switch = if do_context_switch
                                then context_switch_code
@@ -177,7 +178,7 @@ fetchAndReschedule regs node_reqd =
        else absC AbsCNop
       where
        all_regs = if node_reqd then node:regs else regs
        else absC AbsCNop
       where
        all_regs = if node_reqd then node:regs else regs
-       liveness_mask = mkLiveRegsBitMask all_regs
+       liveness_mask = mkLiveRegsMask all_regs
 
        reschedule_code = absC  (CMacroStmt GRAN_RESCHEDULE [
                                 mkIntCLit liveness_mask,
 
        reschedule_code = absC  (CMacroStmt GRAN_RESCHEDULE [
                                 mkIntCLit liveness_mask,
index 5480e93..f59ef4e 100644 (file)
 
 module CgLetNoEscape ( cgLetNoEscapeClosure ) where
 
 
 module CgLetNoEscape ( cgLetNoEscapeClosure ) where
 
+import Ubiq{-uitious-}
+import CgLoop2         ( cgExpr )
+
 import StgSyn
 import CgMonad
 import AbsCSyn
 
 import StgSyn
 import CgMonad
 import AbsCSyn
 
-import CgBindery       -- various things
-import CgExpr          ( cgExpr )
+import CgBindery       ( letNoEscapeIdInfo, bindArgsToRegs,
+                         bindNewToAStack, bindNewToBStack
+                       )
 import CgHeapery       ( heapCheck )
 import CgRetConv       ( assignRegs )
 import CgStackery      ( mkVirtStkOffsets )
 import CgUsages                ( setRealAndVirtualSps, getVirtSps )
 import CgHeapery       ( heapCheck )
 import CgRetConv       ( assignRegs )
 import CgStackery      ( mkVirtStkOffsets )
 import CgUsages                ( setRealAndVirtualSps, getVirtSps )
-import CLabel  ( mkStdEntryLabel )
+import CLabel          ( mkStdEntryLabel )
 import ClosureInfo     ( mkLFLetNoEscape )
 import ClosureInfo     ( mkLFLetNoEscape )
-import Id              ( getIdPrimRep )
-import Util
+import HeapOffs                ( VirtualSpBOffset(..) )
+import Id              ( idPrimRep )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -164,10 +168,9 @@ cgLetNoEscapeBody :: [Id]          -- Args
 
 cgLetNoEscapeBody all_args rhs
   = getVirtSps         `thenFC` \ (vA, vB) ->
 
 cgLetNoEscapeBody all_args rhs
   = getVirtSps         `thenFC` \ (vA, vB) ->
-    getIntSwitchChkrC  `thenFC` \ isw_chkr ->
     let
     let
-       arg_kinds       = map getIdPrimRep all_args
-       (arg_regs, _)   = assignRegs isw_chkr [{-nothing live-}] arg_kinds
+       arg_kinds       = map idPrimRep all_args
+       (arg_regs, _)   = assignRegs [{-nothing live-}] arg_kinds
        stk_args        = drop (length arg_regs) all_args
 
        -- stk_args is the args which are passed on the stack at the fast-entry point
        stk_args        = drop (length arg_regs) all_args
 
        -- stk_args is the args which are passed on the stack at the fast-entry point
@@ -175,7 +178,7 @@ cgLetNoEscapeBody all_args rhs
        (spA_stk_args, spB_stk_args, stk_bxd_w_offsets, stk_ubxd_w_offsets)
          = mkVirtStkOffsets
                vA vB           -- Initial virtual SpA, SpB
        (spA_stk_args, spB_stk_args, stk_bxd_w_offsets, stk_ubxd_w_offsets)
          = mkVirtStkOffsets
                vA vB           -- Initial virtual SpA, SpB
-               getIdPrimRep
+               idPrimRep
                stk_args
     in
 
                stk_args
     in
 
diff --git a/ghc/compiler/codeGen/CgLoop1.lhi b/ghc/compiler/codeGen/CgLoop1.lhi
new file mode 100644 (file)
index 0000000..ef8dd2d
--- /dev/null
@@ -0,0 +1,35 @@
+\begin{code}
+interface CgLoop1 where
+import PreludeStdIO    ( Maybe )
+
+import CgBindery       ( CgBindings(..), CgIdInfo(..),
+                         VolatileLoc, StableLoc,
+                         nukeVolatileBinds,
+                         maybeAStkLoc, maybeBStkLoc
+                       )
+import CgUsages                ( getSpBRelOffset )
+
+import AbsCSyn         ( RegRelative )
+import CgMonad         ( FCode(..) )
+import ClosureInfo     ( LambdaFormInfo )
+import HeapOffs                ( VirtualSpAOffset(..), VirtualSpBOffset(..) )
+import Id              ( IdEnv(..), Id(..) )
+
+type CgBindings = IdEnv CgIdInfo
+
+data CgIdInfo
+  = MkCgIdInfo Id      -- Id that this is the info for
+               VolatileLoc
+               StableLoc
+               LambdaFormInfo
+
+data VolatileLoc
+data StableLoc
+data LambdaFormInfo
+
+nukeVolatileBinds :: CgBindings -> CgBindings
+maybeAStkLoc     :: StableLoc  -> Maybe VirtualSpAOffset
+maybeBStkLoc     :: StableLoc  -> Maybe VirtualSpBOffset
+
+getSpBRelOffset :: VirtualSpBOffset -> FCode RegRelative
+\end{code}
diff --git a/ghc/compiler/codeGen/CgLoop2.lhi b/ghc/compiler/codeGen/CgLoop2.lhi
new file mode 100644 (file)
index 0000000..feda847
--- /dev/null
@@ -0,0 +1,15 @@
+Break loops caused by cgExpr and getPrimOpArgAmodes.
+\begin{code}
+interface CgLoop2 where
+
+import CgExpr  ( cgExpr, cgSccExpr, getPrimOpArgAmodes )
+
+import AbsCSyn ( CAddrMode )
+import CgMonad ( Code(..), FCode(..) )
+import PrimOp  ( PrimOp )
+import StgSyn  ( StgExpr(..), StgArg(..) )
+
+cgExpr            :: StgExpr -> Code
+cgSccExpr         :: StgExpr -> Code
+getPrimOpArgAmodes :: PrimOp -> [StgArg] -> FCode [CAddrMode]
+\end{code}
index 65c4217..428d6f6 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[CgMonad]{The code generation monad}
 
 %
 \section[CgMonad]{The code generation monad}
 
@@ -34,8 +34,6 @@ module CgMonad (
 --     addFreeASlots,  -- no need to export it
        addFreeBSlots,  -- ToDo: Belong elsewhere
 
 --     addFreeASlots,  -- no need to export it
        addFreeBSlots,  -- ToDo: Belong elsewhere
 
-       isSwitchSetC, isStringSwitchSetC, getIntSwitchChkrC,
-
        noBlackHolingFlag,
        profCtrC,
 
        noBlackHolingFlag,
        profCtrC,
 
@@ -45,31 +43,35 @@ module CgMonad (
        sequelToAmode,
 
        -- out of general friendliness, we also export ...
        sequelToAmode,
 
        -- out of general friendliness, we also export ...
-       CgBindings(..),
        CgInfoDownwards(..), CgState(..),       -- non-abstract
        CgInfoDownwards(..), CgState(..),       -- non-abstract
-       CgIdInfo, -- abstract
-       CompilationInfo(..), IntSwitchChecker(..),
-
-       stableAmodeIdInfo, heapIdInfo
-
-       -- and to make the interface self-sufficient...
+       CompilationInfo(..)
     ) where
 
     ) where
 
+import Ubiq{-uitous-}
+import CgLoop1         -- stuff from CgBindery and CgUsages
+
 import AbsCSyn
 import AbsCSyn
-import Type            ( primRepFromType, Type
-                         IF_ATTACK_PRAGMAS(COMMA cmpUniType)
+import AbsCUtils       ( mkAbsCStmts )
+import CmdLineOpts     ( opt_SccProfilingOn, opt_DoTickyProfiling,
+                         opt_OmitBlackHoling
+                       )
+import HeapOffs                ( maxOff,
+                         VirtualSpAOffset(..), VirtualSpBOffset(..)
+                       )
+import Id              ( idType,
+                         nullIdEnv, mkIdEnv, addOneToIdEnv,
+                         modifyIdEnv, lookupIdEnv, rngIdEnv, IdEnv(..),
+                         ConTag(..), GenId{-instance Outputable-}
                        )
                        )
-import CgBindery
-import CgUsages         ( getSpBRelOffset )
-import CmdLineOpts     ( GlobalSwitch(..) )
-import Id              ( idType, ConTag(..), DataCon(..) )
-import Maybes          ( catMaybes, maybeToBool, Maybe(..) )
-import Pretty          -- debugging only?
-import PrimRep         ( getPrimRepSize, retPrimRepSize )
-import UniqSet         -- ( elementOfUniqSet, UniqSet(..) )
-import CostCentre      -- profiling stuff
-import StgSyn          ( StgArg(..), StgLiveVars(..) )
-import Util
+import Maybes          ( maybeToBool )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-} )
+import Pretty          ( ppAboves, ppCat, ppStr )
+import PrimRep         ( getPrimRepSize, PrimRep(..) )
+import StgSyn          ( StgLiveVars(..) )
+import Type            ( typePrimRep )
+import UniqSet         ( elementOfUniqSet )
+import Util            ( sortLt, panic, pprPanic )
 
 infixr 9 `thenC`       -- Right-associative!
 infixr 9 `thenFC`
 
 infixr 9 `thenC`       -- Right-associative!
 infixr 9 `thenFC`
@@ -108,43 +110,42 @@ data CgState
        CgStksAndHeapUsage
 \end{code}
 
        CgStksAndHeapUsage
 \end{code}
 
-@EndOfBlockInfo@ tells what to do at the end of this block of code
-or, if the expression is a @case@, what to do at the end of each alternative.
+@EndOfBlockInfo@ tells what to do at the end of this block of code or,
+if the expression is a @case@, what to do at the end of each
+alternative.
 
 \begin{code}
 data EndOfBlockInfo
   = EndOfBlockInfo
 
 \begin{code}
 data EndOfBlockInfo
   = EndOfBlockInfo
-       VirtualSpAOffset        -- Args SpA: trim the A stack to this point at a return;
-                               -- push arguments starting just above this point on
-                               -- a tail call.
-
-                               -- This is therefore the A-stk ptr as seen
-                               -- by a case alternative.
-
-                               -- Args SpA is used when we want to stub any
-                               -- currently-unstubbed dead A-stack (ptr) slots;
-                               -- we want to know what SpA in the continuation is
-                               -- so that we don't stub any slots which are off the
-                               -- top of the continuation's stack!
-
-       VirtualSpBOffset        -- Args SpB: Very similar to Args SpA.
-
-                               -- Two main differences:
-                               --  1.  If Sequel isn't OnStack, then Args SpB points
-                               --      just below the slot in which the return address
-                               --      should be put.  In effect, the Sequel is
-                               --      a pending argument.  If it is OnStack, Args SpB
-                               --      points to the top word of the return address.
-                               --
-                               --  2.  It ain't used for stubbing because there are
-                               --      no ptrs on B stk.
-
+       VirtualSpAOffset  -- Args SpA: trim the A stack to this point at a
+                         -- return; push arguments starting just
+                         -- above this point on a tail call.
+                         
+                         -- This is therefore the A-stk ptr as seen
+                         -- by a case alternative.
+                         
+                         -- Args SpA is used when we want to stub any
+                         -- currently-unstubbed dead A-stack (ptr)
+                         -- slots; we want to know what SpA in the
+                         -- continuation is so that we don't stub any
+                         -- slots which are off the top of the
+                         -- continuation's stack!
+                         
+       VirtualSpBOffset  -- Args SpB: Very similar to Args SpA.
+                         -- Two main differences:
+                         --  1. If Sequel isn't OnStack, then Args SpB points
+                         --     just below the slot in which the return address
+                         --     should be put.  In effect, the Sequel
+                         --     is a pending argument.  If it is
+                         --     OnStack, Args SpB
+                         --     points to the top word of the return
+                         --     address.
+                         --
+                         --  2. It ain't used for stubbing because there are
+                         --     no ptrs on B stk.
        Sequel
 
        Sequel
 
-
 initEobInfo = EndOfBlockInfo 0 0 InRetReg
 initEobInfo = EndOfBlockInfo 0 0 InRetReg
-
-
 \end{code}
 
 Any addressing modes inside @Sequel@ must be ``robust,'' in the sense
 \end{code}
 
 Any addressing modes inside @Sequel@ must be ``robust,'' in the sense
@@ -153,21 +154,21 @@ block.
 
 \begin{code}
 data Sequel
 
 \begin{code}
 data Sequel
-       = InRetReg              -- The continuation is in RetReg
-
-       | OnStack VirtualSpBOffset
-                               -- Continuation is on the stack, at the
-                               -- specified location
+  = InRetReg              -- The continuation is in RetReg
 
 
-       | UpdateCode CAddrMode  -- May be standard update code, or might be
-                               -- the data-type-specific one.
+  | OnStack VirtualSpBOffset
+                         -- Continuation is on the stack, at the
+                         -- specified location
 
 
-       | CaseAlts
-               CAddrMode   -- Jump to this; if the continuation is for a vectored
-                           -- case this might be the label of a return vector
-                           -- Guaranteed to be a non-volatile addressing mode (I think)
+  | UpdateCode CAddrMode  -- May be standard update code, or might be
+                         -- the data-type-specific one.
 
 
-               SemiTaggingStuff
+  | CaseAlts
+         CAddrMode   -- Jump to this; if the continuation is for a vectored
+                     -- case this might be the label of a return
+                     -- vector Guaranteed to be a non-volatile
+                     -- addressing mode (I think)
+         SemiTaggingStuff
 
 type SemiTaggingStuff
   = Maybe                          -- Maybe[1] we don't have any semi-tagging stuff...
 
 type SemiTaggingStuff
   = Maybe                          -- Maybe[1] we don't have any semi-tagging stuff...
@@ -182,17 +183,17 @@ type SemiTaggingStuff
 type JoinDetails
   = (AbstractC, CLabel)                -- Code to load regs from heap object + profiling macros,
                                -- and join point label
 type JoinDetails
   = (AbstractC, CLabel)                -- Code to load regs from heap object + profiling macros,
                                -- and join point label
--- The abstract C is executed only from a successful
--- semitagging venture, when a case has looked at a variable, found
--- that it's evaluated, and wants to load up the contents and go to the
--- join point.
 
 
+-- The abstract C is executed only from a successful semitagging
+-- venture, when a case has looked at a variable, found that it's
+-- evaluated, and wants to load up the contents and go to the join
+-- point.
 
 -- DIRE WARNING.
 
 -- DIRE WARNING.
--- The OnStack case of sequelToAmode delivers an Amode which is only valid
--- just before the final control transfer, because it assumes that
--- SpB is pointing to the top word of the return address.
--- This seems unclean but there you go.
+-- The OnStack case of sequelToAmode delivers an Amode which is only
+-- valid just before the final control transfer, because it assumes
+-- that SpB is pointing to the top word of the return address.  This
+-- seems unclean but there you go.
 
 sequelToAmode :: Sequel -> FCode CAddrMode
 
 
 sequelToAmode :: Sequel -> FCode CAddrMode
 
@@ -576,17 +577,15 @@ nothing.
 \begin{code}
 costCentresC :: FAST_STRING -> [CAddrMode] -> Code
 
 \begin{code}
 costCentresC :: FAST_STRING -> [CAddrMode] -> Code
 
-costCentresC macro args (MkCgInfoDown (MkCompInfo sw_chkr _ _) _ _)
-                       state@(MkCgState absC binds usage)
-  = if sw_chkr SccProfilingOn
+costCentresC macro args _ state@(MkCgState absC binds usage)
+  = if opt_SccProfilingOn
     then MkCgState (mkAbsCStmts absC (CCallProfCCMacro macro args)) binds usage
     else state
 
 profCtrC :: FAST_STRING -> [CAddrMode] -> Code
 
     then MkCgState (mkAbsCStmts absC (CCallProfCCMacro macro args)) binds usage
     else state
 
 profCtrC :: FAST_STRING -> [CAddrMode] -> Code
 
-profCtrC macro args (MkCgInfoDown (MkCompInfo sw_chkr _ _) _ _)
-                       state@(MkCgState absC binds usage)
-  = if not (sw_chkr DoTickyProfiling)
+profCtrC macro args _ state@(MkCgState absC binds usage)
+  = if not opt_DoTickyProfiling
     then state
     else MkCgState (mkAbsCStmts absC (CCallProfCtrMacro macro args)) binds usage
 
     then state
     else MkCgState (mkAbsCStmts absC (CCallProfCtrMacro macro args)) binds usage
 
@@ -616,17 +615,14 @@ getAbsC code info_down (MkCgState absC binds usage)
 \begin{code}
 noBlackHolingFlag, costCentresFlag :: FCode Bool
 
 \begin{code}
 noBlackHolingFlag, costCentresFlag :: FCode Bool
 
-noBlackHolingFlag (MkCgInfoDown (MkCompInfo sw_chkr _ _) _ _) state
-  = (sw_chkr OmitBlackHoling, state)
-
-costCentresFlag          (MkCgInfoDown (MkCompInfo sw_chkr _ _) _ _) state
-  = (sw_chkr SccProfilingOn, state)
+noBlackHolingFlag _ state = (opt_OmitBlackHoling, state)
+costCentresFlag          _ state = (opt_SccProfilingOn, state)
 \end{code}
 
 \begin{code}
 
 moduleName :: FCode FAST_STRING
 \end{code}
 
 \begin{code}
 
 moduleName :: FCode FAST_STRING
-moduleName (MkCgInfoDown (MkCompInfo _ _ mod_name) _ _) state
+moduleName (MkCgInfoDown (MkCompInfo mod_name) _ _) state
   = (mod_name, state)
 
 \end{code}
   = (mod_name, state)
 
 \end{code}
@@ -802,7 +798,7 @@ dead_slots live_vars fbs das dbs ((v,i):bs)
        _ -> dead_slots live_vars fbs das dbs bs
   where
     size :: Int
        _ -> dead_slots live_vars fbs das dbs bs
   where
     size :: Int
-    size = (getPrimRepSize . primRepFromType . idType) v
+    size = (getPrimRepSize . typePrimRep . idType) v
 
 -- addFreeSlots expects *both* args to be in increasing order
 addFreeASlots :: [(Int,StubFlag)] -> [(Int,StubFlag)] -> [(Int,StubFlag)]
 
 -- addFreeSlots expects *both* args to be in increasing order
 addFreeASlots :: [(Int,StubFlag)] -> [(Int,StubFlag)] -> [(Int,StubFlag)]
index 5881fb1..f1a35f6 100644 (file)
@@ -15,8 +15,6 @@ module CgRetConv (
        ctrlReturnConvAlg,
        dataReturnConvAlg,
 
        ctrlReturnConvAlg,
        dataReturnConvAlg,
 
-       mkLiveRegsBitMask, noLiveRegsMask,
-
        dataReturnConvPrim,
 
        assignPrimOpResultRegs,
        dataReturnConvPrim,
 
        assignPrimOpResultRegs,
@@ -26,27 +24,35 @@ module CgRetConv (
        -- and to make the interface self-sufficient...
     ) where
 
        -- and to make the interface self-sufficient...
     ) where
 
-import AbsCSyn
+import Ubiq{-uitous-}
+import AbsCLoop                -- paranoia checking
 
 
-import PrelInfo                ( PrimOp(..), PrimOpResultInfo(..), primOpCanTriggerGC,
-                         getPrimOpResultInfo, integerDataCon
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
+import AbsCSyn         -- quite a few things
+import AbsCUtils       ( mkAbstractCs, getAmodeRep,
+                         amodeCanSurviveGC
+                       )
+import CgCompInfo      ( mAX_FAMILY_SIZE_FOR_VEC_RETURNS,
+                         mAX_Vanilla_REG, mAX_Float_REG,
+                         mAX_Double_REG
+                       )
+import CmdLineOpts     ( opt_ReturnInRegsThreshold )
+import Id              ( isDataCon, dataConSig,
+                         DataCon(..), GenId{-instance Eq-}
                        )
                        )
-import Type            ( getTyConFamilySize, primRepFromType, getTyConDataCons,
-                         TyVarTemplate, TyCon, Class,
-                         TauType(..), ThetaType(..), Type
+import Maybes          ( catMaybes )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( TyCon{-instance Outputable-} )
+import PrelInfo                ( integerDataCon )
+import PrimOp          ( primOpCanTriggerGC,
+                         getPrimOpResultInfo, PrimOpResultInfo(..),
+                         PrimOp{-instance Outputable-}
                        )
                        )
-import CgCompInfo      -- various things
-import CgMonad         ( IntSwitchChecker(..) )
-import CmdLineOpts     ( GlobalSwitch(..) )
-import Id              ( Id, getDataConSig, fIRST_TAG, isDataCon,
-                         DataCon(..), ConTag(..)
+import PrimRep         ( isFloatingRep, PrimRep(..) )
+import TyCon           ( tyConDataCons, tyConFamilySize )
+import Type            ( typePrimRep )
+import Util            ( zipWithEqual, mapAccumL, isn'tIn,
+                         pprError, pprTrace, panic, assertPanic
                        )
                        )
-import Maybes          ( catMaybes, Maybe(..) )
-import PrimRep
-import Util
-import Pretty
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -88,11 +94,11 @@ The register assignment given by a @ReturnInRegs@ obeys three rules:
 ctrlReturnConvAlg :: TyCon -> CtrlReturnConvention
 
 ctrlReturnConvAlg tycon
 ctrlReturnConvAlg :: TyCon -> CtrlReturnConvention
 
 ctrlReturnConvAlg tycon
-  = case (getTyConFamilySize tycon) of
-      Nothing -> -- pprPanic "ctrlReturnConvAlg:" (ppr PprDebug tycon)
-                UnvectoredReturn 0 -- e.g., w/ "data Bin"
+  = case (tyConFamilySize tycon) of
+      0 -> pprTrace "ctrlReturnConvAlg:" (ppr PprDebug tycon) $
+          UnvectoredReturn 0 -- e.g., w/ "data Bin"
 
 
-      Just size -> -- we're supposed to know...
+      size -> -- we're supposed to know...
        if (size > (1::Int) && size <= mAX_FAMILY_SIZE_FOR_VEC_RETURNS) then
            VectoredReturn size
        else
        if (size > (1::Int) && size <= mAX_FAMILY_SIZE_FOR_VEC_RETURNS) then
            VectoredReturn size
        else
@@ -110,68 +116,23 @@ types.    If @assign_reg@ runs out of a particular kind of register,
 then it gives up, returning @ReturnInHeap@.
 
 \begin{code}
 then it gives up, returning @ReturnInHeap@.
 
 \begin{code}
-dataReturnConvAlg :: IntSwitchChecker -> DataCon -> DataReturnConvention
+dataReturnConvAlg :: DataCon -> DataReturnConvention
 
 
-dataReturnConvAlg isw_chkr data_con
+dataReturnConvAlg data_con
   = ASSERT(isDataCon data_con)
     case leftover_kinds of
        []    ->        ReturnInRegs reg_assignment
        other ->        ReturnInHeap    -- Didn't fit in registers
   where
   = ASSERT(isDataCon data_con)
     case leftover_kinds of
        []    ->        ReturnInRegs reg_assignment
        other ->        ReturnInHeap    -- Didn't fit in registers
   where
-    (_, _, arg_tys, _) = getDataConSig data_con
+    (_, _, arg_tys, _) = dataConSig data_con
 
     (reg_assignment, leftover_kinds)
 
     (reg_assignment, leftover_kinds)
-      = assignRegs isw_chkr_to_use
-                  [node, infoptr] -- taken...
-                  (map primRepFromType arg_tys)
-
-    isw_chkr_to_use = isw_chkr
+      = assignRegs [node, infoptr] -- taken...
+                  (map typePrimRep arg_tys)
 
     is_prim_result_ty = data_con == integerDataCon -- ***HACK***! (WDP 95/11)
 \end{code}
 
 
     is_prim_result_ty = data_con == integerDataCon -- ***HACK***! (WDP 95/11)
 \end{code}
 
-\begin{code}
-noLiveRegsMask :: Int  -- Mask indicating nothing live
-noLiveRegsMask = 0
-
-mkLiveRegsBitMask
-       :: [MagicId]    -- Candidate live regs; depends what they have in them
-       -> Int
-
-mkLiveRegsBitMask regs
-  = foldl do_reg noLiveRegsMask regs
-  where
-    do_reg acc (VanillaReg kind reg_no)
-      | isFollowableRep kind
-      = acc + (reg_tbl !! IBOX(reg_no _SUB_ ILIT(1)))
-
-    do_reg acc anything_else = acc
-
-    reg_tbl -- ToDo: mk Array!
-      = [lIVENESS_R1, lIVENESS_R2, lIVENESS_R3, lIVENESS_R4,
-        lIVENESS_R5, lIVENESS_R6, lIVENESS_R7, lIVENESS_R8]
-
-{-
--- Completely opaque code.  ADR
--- What's wrong with: (untested)
-
-mkLiveRegsBitMask regs
-  = foldl (+) noLiveRegsMask (map liveness_bit regs)
-  where
-    liveness_bit (VanillaReg kind reg_no)
-      | isFollowableRep kind
-      = reg_tbl !! (reg_no - 1)
-
-    liveness_bit anything_else
-      = noLiveRegsBitMask
-
-    reg_tbl
-      = [lIVENESS_R1, lIVENESS_R2, lIVENESS_R3, lIVENESS_R4,
-        lIVENESS_R5, lIVENESS_R6, lIVENESS_R7, lIVENESS_R8]
--}
-\end{code}
-
-
 %************************************************************************
 %*                                                                     *
 \subsection[CgRetConv-prim]{Return conventions for primitive datatypes}
 %************************************************************************
 %*                                                                     *
 \subsection[CgRetConv-prim]{Return conventions for primitive datatypes}
@@ -224,7 +185,7 @@ assignPrimOpResultRegs op
 
        ReturnsAlg tycon
          -> let
 
        ReturnsAlg tycon
          -> let
-               cons        = getTyConDataCons tycon
+               cons        = tyConDataCons tycon
                result_regs = concat (map get_return_regs cons)
             in
             -- As R1 is dead, it can hold the tag if necessary
                result_regs = concat (map get_return_regs cons)
             in
             -- As R1 is dead, it can hold the tag if necessary
@@ -233,12 +194,9 @@ assignPrimOpResultRegs op
                other -> (VanillaReg IntRep ILIT(1)) : result_regs
   where
     get_return_regs con
                other -> (VanillaReg IntRep ILIT(1)) : result_regs
   where
     get_return_regs con
-      = case (dataReturnConvAlg fake_isw_chkr con) of
+      = case (dataReturnConvAlg con) of
          ReturnInRegs regs -> regs
          ReturnInHeap      -> panic "getPrimOpAlgResultRegs"
          ReturnInRegs regs -> regs
          ReturnInHeap      -> panic "getPrimOpAlgResultRegs"
-
-    fake_isw_chkr :: IntSwitchChecker
-    fake_isw_chkr x = Nothing
 \end{code}
 
 @assignPrimOpArgsRobust@ is used only for primitive ops which may
 \end{code}
 
 @assignPrimOpArgsRobust@ is used only for primitive ops which may
@@ -269,12 +227,12 @@ makePrimOpArgsRobust op arg_amodes
        arg_kinds = map getAmodeRep non_robust_amodes
 
        (arg_regs, extra_args)
        arg_kinds = map getAmodeRep non_robust_amodes
 
        (arg_regs, extra_args)
-         = assignRegs fake_isw_chkr [{-nothing live-}] arg_kinds
+         = assignRegs [{-nothing live-}] arg_kinds
 
                -- Check that all the args fit before returning arg_regs
        final_arg_regs = case extra_args of
                           []    -> arg_regs
 
                -- Check that all the args fit before returning arg_regs
        final_arg_regs = case extra_args of
                           []    -> arg_regs
-                          other -> error ("Cannot allocate enough registers for primop (try rearranging code or reducing number of arguments?) " ++ ppShow 80 (ppr PprDebug op))
+                          other -> pprError "Cannot allocate enough registers for primop (try rearranging code or reducing number of arguments?)" (ppr PprDebug op)
 
        arg_assts
          = mkAbstractCs (zipWithEqual assign_to_reg final_arg_regs non_robust_amodes)
 
        arg_assts
          = mkAbstractCs (zipWithEqual assign_to_reg final_arg_regs non_robust_amodes)
@@ -286,12 +244,9 @@ makePrimOpArgsRobust op arg_amodes
                | otherwise             = (tail regs, CReg (head regs))
        safe_amodes = snd (mapAccumL safe_arg final_arg_regs arg_amodes)
 
                | otherwise             = (tail regs, CReg (head regs))
        safe_amodes = snd (mapAccumL safe_arg final_arg_regs arg_amodes)
 
-       liveness_mask = mkLiveRegsBitMask final_arg_regs
+       liveness_mask = mkLiveRegsMask final_arg_regs
     in
     (safe_amodes, liveness_mask, arg_assts)
     in
     (safe_amodes, liveness_mask, arg_assts)
-  where
-    fake_isw_chkr :: IntSwitchChecker
-    fake_isw_chkr x = Nothing
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -308,15 +263,14 @@ any further registers (even though we might have run out of only one kind of
 register); we just return immediately with the left-overs specified.
 
 \begin{code}
 register); we just return immediately with the left-overs specified.
 
 \begin{code}
-assignRegs  :: IntSwitchChecker
-           -> [MagicId]        -- Unavailable registers
+assignRegs  :: [MagicId]       -- Unavailable registers
            -> [PrimRep]        -- Arg or result kinds to assign
            -> ([MagicId],      -- Register assignment in same order
                                -- for *initial segment of* input list
                [PrimRep])-- leftover kinds
 
            -> [PrimRep]        -- Arg or result kinds to assign
            -> ([MagicId],      -- Register assignment in same order
                                -- for *initial segment of* input list
                [PrimRep])-- leftover kinds
 
-assignRegs isw_chkr regs_in_use kinds
- = assign_reg kinds [] (mkRegTbl isw_chkr regs_in_use)
+assignRegs regs_in_use kinds
+ = assign_reg kinds [] (mkRegTbl regs_in_use)
  where
 
     assign_reg :: [PrimRep]  -- arg kinds being scrutinized
  where
 
     assign_reg :: [PrimRep]  -- arg kinds being scrutinized
@@ -360,9 +314,9 @@ floatRegNos, doubleRegNos :: [Int]
 floatRegNos    = [1 .. mAX_Float_REG]
 doubleRegNos   = [1 .. mAX_Double_REG]
 
 floatRegNos    = [1 .. mAX_Float_REG]
 doubleRegNos   = [1 .. mAX_Double_REG]
 
-mkRegTbl :: IntSwitchChecker -> [MagicId] -> ([Int], [Int], [Int])
+mkRegTbl :: [MagicId] -> ([Int], [Int], [Int])
 
 
-mkRegTbl isw_chkr regs_in_use
+mkRegTbl regs_in_use
   = (ok_vanilla, ok_float, ok_double)
   where
     ok_vanilla = catMaybes (map (select (VanillaReg VoidRep)) (taker vanillaRegNos))
   = (ok_vanilla, ok_float, ok_double)
   where
     ok_vanilla = catMaybes (map (select (VanillaReg VoidRep)) (taker vanillaRegNos))
@@ -371,7 +325,7 @@ mkRegTbl isw_chkr regs_in_use
 
     taker :: [Int] -> [Int]
     taker rs
 
     taker :: [Int] -> [Int]
     taker rs
-      = case (isw_chkr ReturnInRegsThreshold) of
+      = case (opt_ReturnInRegsThreshold) of
          Nothing -> rs -- no flag set; use all of them
          Just  n -> take n rs
 
          Nothing -> rs -- no flag set; use all of them
          Just  n -> take n rs
 
index 3759aa4..0ad6fc5 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[CgStackery]{Stack management functions}
 
 %
 \section[CgStackery]{Stack management functions}
 
@@ -13,18 +13,19 @@ module CgStackery (
        allocAStack, allocBStack, allocUpdateFrame,
        adjustRealSps, getFinalStackHW,
        mkVirtStkOffsets, mkStkAmodes
        allocAStack, allocBStack, allocUpdateFrame,
        adjustRealSps, getFinalStackHW,
        mkVirtStkOffsets, mkStkAmodes
-
-       -- and to make the interface self-sufficient...
     ) where
 
     ) where
 
-import StgSyn
+import Ubiq{-uitous-}
+
 import CgMonad
 import AbsCSyn
 
 import CgMonad
 import AbsCSyn
 
-import CgUsages                ( getSpBRelOffset )
-import Maybes          ( Maybe(..) )
-import PrimRep         ( getPrimRepSize, retPrimRepSize, separateByPtrFollowness )
-import Util
+import AbsCUtils       ( mkAbstractCs, mkAbsCStmts, getAmodeRep )
+import HeapOffs                ( VirtualSpAOffset(..), VirtualSpBOffset(..) )
+import PrimRep         ( getPrimRepSize, separateByPtrFollowness,
+                         PrimRep(..)
+                       )
+import Util            ( mapAccumR, panic )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index a22ca46..560adde 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 %********************************************************
 %*                                                     *
 %
 %********************************************************
 %*                                                     *
@@ -17,37 +17,36 @@ module CgTailCall (
        mkPrimReturnCode,
 
        tailCallBusiness
        mkPrimReturnCode,
 
        tailCallBusiness
-
-       -- and to make the interface self-sufficient...
     ) where
 
     ) where
 
-IMPORT_Trace
-import Pretty          -- Pretty/Outputable: rm (debugging only) ToDo
-import Outputable
+import Ubiq{-uitous-}
 
 
-import StgSyn
 import CgMonad
 import AbsCSyn
 
 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 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 )
+import ClosureInfo     ( nodeMustPointToIt,
+                         getEntryConvention, EntryConvention(..)
+                       )
+import CmdLineOpts     ( opt_EmitArityChecks, opt_DoSemiTagging )
+import HeapOffs                ( zeroOff, VirtualSpAOffset(..) )
+import Id              ( idType, dataConTyCon, dataConTag,
+                         fIRST_TAG
                        )
                        )
-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            ( isPrimType )
+import Util            ( zipWithEqual, panic, assertPanic )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -191,8 +190,7 @@ mkStaticAlgReturnCode con maybe_info_lbl sequel
 
                                -- Set the info pointer, and jump
                        set_info_ptr            `thenC`
 
                                -- 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
 
        CaseAlts _ (Just (alts, _)) ->  -- Ho! We know the constructor so
                                        -- we can go right to the alternative
@@ -216,14 +214,14 @@ mkStaticAlgReturnCode con maybe_info_lbl sequel
     )
 
   where
     )
 
   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
 
     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
 
          ReturnInHeap   -> mkStdUpdCodePtrVecLabel tycon tag
          ReturnInRegs _ -> mkConUpdCodePtrVecLabel tycon tag
 
@@ -296,7 +294,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) ->
   =    -- 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
 
     tailCallBusiness
                fun fun_amode lf_info arg_amodes
@@ -316,8 +314,9 @@ tailCallBusiness :: Id -> CAddrMode -- Function and its amode
                 -> Code
 
 tailCallBusiness fun fun_amode lf_info arg_amodes live_vars pending_assts
                 -> Code
 
 tailCallBusiness fun fun_amode lf_info arg_amodes live_vars pending_assts
-  = isSwitchSetC EmitArityChecks               `thenFC` \ do_arity_chks ->
-
+  = let
+       do_arity_chks = opt_EmitArityChecks
+    in
     nodeMustPointToIt lf_info                  `thenFC` \ node_points ->
     getEntryConvention fun lf_info
        (map getAmodeRep arg_amodes)            `thenFC` \ entry_conv ->
     nodeMustPointToIt lf_info                  `thenFC` \ node_points ->
     getEntryConvention fun lf_info
        (map getAmodeRep arg_amodes)            `thenFC` \ entry_conv ->
@@ -407,7 +406,9 @@ tailCallBusiness fun fun_amode lf_info arg_amodes live_vars pending_assts
            adjustRealSps final_spa final_spb   `thenC`
 
                -- Now decide about semi-tagging
            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
 
        --
            case (semi_tagging_on, arg_amodes, node_points, sequel) of
 
        --
index 92ceaa4..ff1a554 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1994
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[CgUpdate]{Manipulating update frames}
 
 %
 \section[CgUpdate]{Manipulating update frames}
 
@@ -8,18 +8,15 @@
 
 module CgUpdate ( pushUpdateFrame ) where
 
 
 module CgUpdate ( pushUpdateFrame ) where
 
-import StgSyn
+import Ubiq{-uitous-}
+
 import CgMonad
 import AbsCSyn
 
 import CgMonad
 import AbsCSyn
 
-import CgCompInfo      ( sTD_UF_SIZE, cON_UF_SIZE,
-                         sCC_STD_UF_SIZE, sCC_CON_UF_SIZE,
-                         spARelToInt, spBRelToInt
-                       )
+import CgCompInfo      ( sTD_UF_SIZE, sCC_STD_UF_SIZE )
 import CgStackery      ( allocUpdateFrame )
 import CgStackery      ( allocUpdateFrame )
-import CgUsages
-import CmdLineOpts     ( GlobalSwitch(..) )
-import Util
+import CmdLineOpts     ( opt_SccProfilingOn )
+import Util            ( assertPanic )
 \end{code}
 
 
 \end{code}
 
 
@@ -41,8 +38,9 @@ to reflect the frame pushed.
 pushUpdateFrame :: CAddrMode -> CAddrMode -> Code -> Code
 
 pushUpdateFrame updatee vector code
 pushUpdateFrame :: CAddrMode -> CAddrMode -> Code -> Code
 
 pushUpdateFrame updatee vector code
-  = isSwitchSetC SccProfilingOn                `thenFC` \ profiling_on ->
-    let
+  = let
+       profiling_on = opt_SccProfilingOn
+
        -- frame_size *includes* the return address
        frame_size = if profiling_on
                     then sCC_STD_UF_SIZE
        -- frame_size *includes* the return address
        frame_size = if profiling_on
                     then sCC_STD_UF_SIZE
index 2e3fec3..eec6be6 100644 (file)
@@ -15,15 +15,20 @@ module CgUsages (
 
        getHpRelOffset, getSpARelOffset, getSpBRelOffset,
 
 
        getHpRelOffset, getSpARelOffset, getSpBRelOffset,
 
-       freeBStkSlot,
-
-       -- and to make the interface self-sufficient...
-       AbstractC, HeapOffset, RegRelative, CgState
+       freeBStkSlot
     ) where
 
     ) where
 
-import AbsCSyn
+import Ubiq{-uitous-}
+import CgLoop1 -- here for paranoia-checking
+
+import AbsCSyn         ( RegRelative(..), AbstractC, CAddrMode )
 import CgMonad
 import CgMonad
-import Util
+import HeapOffs                ( zeroOff,
+                         VirtualHeapOffset(..),
+                         VirtualSpAOffset(..),
+                         VirtualSpBOffset(..)
+                       )
+import Id              ( IdEnv(..) )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index dddeddf..ae3bc5c 100644 (file)
@@ -1,5 +1,5 @@
 
 
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[ClosureInfo]{Data structures which describe closures}
 
 %
 \section[ClosureInfo]{Data structures which describe closures}
 
@@ -43,35 +43,61 @@ module ClosureInfo (
 
        closureKind, closureTypeDescr,          -- profiling
 
 
        closureKind, closureTypeDescr,          -- profiling
 
-       isConstantRep, isSpecRep, isPhantomRep, -- ToDo: Should be in SMRep, perhaps?
        isStaticClosure, allocProfilingMsg,
        blackHoleClosureInfo,
        isStaticClosure, allocProfilingMsg,
        blackHoleClosureInfo,
-       getSMInfoStr, getSMInitHdrStr, getSMUpdInplaceHdrStr,
-       ltSMRepHdr,
        maybeSelectorInfo,
 
        dataConLiveness                         -- concurrency
        maybeSelectorInfo,
 
        dataConLiveness                         -- concurrency
-
-       -- and to make the interface self-sufficient...
     ) where
 
     ) where
 
+import Ubiq{-uitous-}
+import AbsCLoop                -- here for paranoia-checking
+
 import AbsCSyn
 import AbsCSyn
-import CgMonad
-import SMRep
 import StgSyn
 import StgSyn
+import CgMonad
 
 
-import Type
-import CgCompInfo      -- some magic constants
-import CgRetConv
-import CLabel  -- Lots of label-making things
-import CmdLineOpts     ( GlobalSwitch(..) )
-import Id
-import IdInfo          -- SIGH
-import Maybes          ( maybeToBool, assocMaybe, Maybe(..) )
-import Outputable      -- needed for INCLUDE_FRC_METHOD
-import Pretty          -- ( ppStr, Pretty(..) )
-import PrimRep         ( PrimRep, getPrimRepSize, separateByPtrFollowness )
-import Util
+import CgCompInfo      ( mAX_SPEC_SELECTEE_SIZE,
+                         mIN_UPD_SIZE, mIN_SIZE_NonUpdHeapObject,
+                         mAX_SPEC_ALL_PTRS, mAX_SPEC_MIXED_FIELDS,
+                         mAX_SPEC_ALL_NONPTRS,
+                         oTHER_TAG
+                       )
+import CgRetConv       ( assignRegs, dataReturnConvAlg,
+                         DataReturnConvention(..)
+                       )
+import CLabel          ( mkStdEntryLabel, mkFastEntryLabel,
+                         mkPhantomInfoTableLabel, mkInfoTableLabel,
+                         mkBlackHoleInfoTableLabel, mkVapInfoTableLabel,
+                         mkStaticInfoTableLabel, mkStaticConEntryLabel,
+                         mkConEntryLabel, mkClosureLabel, mkVapEntryLabel
+                       )
+import CmdLineOpts     ( opt_SccProfilingOn, opt_ForConcurrent )
+import HeapOffs                ( intOff, addOff, totHdrSize, varHdrSize,
+                         intOffsetIntoGoods,
+                         VirtualHeapOffset(..)
+                       )
+import Id              ( idType, idPrimRep, getIdArity,
+                         externallyVisibleId, dataConSig,
+                         dataConTag, fIRST_TAG,
+                         isDataCon, dataConArity, dataConTyCon,
+                         isTupleCon, DataCon(..),
+                         GenId{-instance Eq-}
+                       )
+import IdInfo          ( arityMaybe )
+import Maybes          ( assocMaybe, maybeToBool )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-} )
+import PrimRep         ( getPrimRepSize, separateByPtrFollowness )
+import SMRep           -- all of it
+import TyCon           ( maybeTyConSingleCon, TyCon{-instance NamedThing-} )
+import Type            ( isPrimType, splitForAllTy, splitFunTy, mkFunTys )
+import Util            ( isIn, mapAccumL, panic, pprPanic, assertPanic )
+
+maybeCharLikeTyCon = panic "ClosureInfo.maybeCharLikeTyCon (ToDo)"
+maybeIntLikeTyCon = panic "ClosureInfo.maybeIntLikeTyCon (ToDo)"
+getDataSpecTyCon_maybe = panic "ClosureInfo.getDataSpecTyCon_maybe (ToDo)"
+getTyDescription = panic "ClosureInfo.getTyDescription (ToDo)"
 \end{code}
 
 The ``wrapper'' data type for closure information:
 \end{code}
 
 The ``wrapper'' data type for closure information:
@@ -392,13 +418,13 @@ mkClosureLFInfo False         -- don't bother if at top-level
     -- ASSERT(is_single_constructor)           -- Should be true, by causes error for SpecTyCon
     LFThunk False False True (SelectorThunk scrutinee con offset_into_int)
   where
     -- ASSERT(is_single_constructor)           -- Should be true, by causes error for SpecTyCon
     LFThunk False False True (SelectorThunk scrutinee con offset_into_int)
   where
-    (_, params_w_offsets) = layOutDynCon con getIdPrimRep params
+    (_, params_w_offsets) = layOutDynCon con idPrimRep params
     maybe_offset         = assocMaybe params_w_offsets selectee
     Just the_offset      = maybe_offset
     offset_into_int_maybe = intOffsetIntoGoods the_offset
     Just offset_into_int  = offset_into_int_maybe
     maybe_offset         = assocMaybe params_w_offsets selectee
     Just the_offset      = maybe_offset
     offset_into_int_maybe = intOffsetIntoGoods the_offset
     Just offset_into_int  = offset_into_int_maybe
-    is_single_constructor = maybeToBool (maybeSingleConstructorTyCon tycon)
-    (_,_,_, tycon)       = getDataConSig con
+    is_single_constructor = maybeToBool (maybeTyConSingleCon tycon)
+    (_,_,_, tycon)       = dataConSig con
 \end{code}
 
 Same kind of thing, looking for vector-apply thunks, of the form:
 \end{code}
 
 Same kind of thing, looking for vector-apply thunks, of the form:
@@ -452,7 +478,7 @@ mkConLFInfo :: DataCon -> LambdaFormInfo
 mkConLFInfo con
   = ASSERT(isDataCon con)
     let
 mkConLFInfo con
   = ASSERT(isDataCon con)
     let
-       arity = getDataConArity con
+       arity = dataConArity con
     in
     if isTupleCon con then
        LFTuple con (arity == 0)
     in
     if isTupleCon con then
        LFTuple con (arity == 0)
@@ -691,7 +717,7 @@ chooseDynSMRep lf_info tot_wds ptr_wds
                             else if maybeToBool (maybeIntLikeTyCon tycon) then IntLikeRep
                             else SpecRep
                             where
                             else if maybeToBool (maybeIntLikeTyCon tycon) then IntLikeRep
                             else SpecRep
                             where
-                            tycon = getDataConTyCon con
+                            tycon = dataConTyCon con
 
           _              -> SpecRep
        in
 
           _              -> SpecRep
        in
@@ -712,14 +738,15 @@ smaller offsets than the unboxed things, and furthermore, the offsets in
 the result list
 
 \begin{code}
 the result list
 
 \begin{code}
-mkVirtHeapOffsets :: SMRep             -- Representation to be used by storage manager
+mkVirtHeapOffsets :: SMRep     -- Representation to be used by storage manager
          -> (a -> PrimRep)     -- To be able to grab kinds;
          -> (a -> PrimRep)     -- To be able to grab kinds;
-                                       --      w/ a kind, we can find boxedness
-         -> [a]                        -- Things to make offsets for
-         -> (Int,                      -- *Total* number of words allocated
-             Int,                      -- Number of words allocated for *pointers*
-             [(a, VirtualHeapOffset)]) -- Things with their offsets from start of object
-                                       --      in order of increasing offset
+                               --      w/ a kind, we can find boxedness
+         -> [a]                -- Things to make offsets for
+         -> (Int,              -- *Total* number of words allocated
+             Int,              -- Number of words allocated for *pointers*
+             [(a, VirtualHeapOffset)])
+                               -- Things with their offsets from start of object
+                               --      in order of increasing offset
 
 -- First in list gets lowest offset, which is initial offset + 1.
 
 
 -- First in list gets lowest offset, which is initial offset + 1.
 
@@ -748,8 +775,9 @@ Be sure to see the stg-details notes about these...
 \begin{code}
 nodeMustPointToIt :: LambdaFormInfo -> FCode Bool
 nodeMustPointToIt lf_info
 \begin{code}
 nodeMustPointToIt :: LambdaFormInfo -> FCode Bool
 nodeMustPointToIt lf_info
-  = isSwitchSetC SccProfilingOn                `thenFC` \ do_profiling  ->
-
+  = let
+       do_profiling = opt_SccProfilingOn
+    in
     case lf_info of
        LFReEntrant top arity no_fvs -> returnFC (
            not no_fvs ||   -- Certainly if it has fvs we need to point to it
     case lf_info of
        LFReEntrant top arity no_fvs -> returnFC (
            not no_fvs ||   -- Certainly if it has fvs we need to point to it
@@ -843,8 +871,9 @@ getEntryConvention :: Id                    -- Function being applied
 
 getEntryConvention id lf_info arg_kinds
  =  nodeMustPointToIt lf_info  `thenFC` \ node_points ->
 
 getEntryConvention id lf_info arg_kinds
  =  nodeMustPointToIt lf_info  `thenFC` \ node_points ->
-    isSwitchSetC ForConcurrent `thenFC` \ is_concurrent ->
-    getIntSwitchChkrC          `thenFC` \ isw_chkr ->
+    let
+       is_concurrent = opt_ForConcurrent
+    in
     returnFC (
 
     if (node_points && is_concurrent) then ViaNode else
     returnFC (
 
     if (node_points && is_concurrent) then ViaNode else
@@ -857,7 +886,7 @@ getEntryConvention id lf_info arg_kinds
            else
                DirectEntry (mkFastEntryLabel id arity) arity arg_regs
          where
            else
                DirectEntry (mkFastEntryLabel id arity) arity arg_regs
          where
-           (arg_regs, _) = assignRegs isw_chkr live_regs (take arity arg_kinds)
+           (arg_regs, _) = assignRegs live_regs (take arity arg_kinds)
            live_regs = if node_points then [node] else []
 
        LFCon con zero_arity
            live_regs = if node_points then [node] else []
 
        LFCon con zero_arity
@@ -887,7 +916,7 @@ getEntryConvention id lf_info arg_kinds
          -> ASSERT(arity == length arg_kinds)
             DirectEntry (mkStdEntryLabel id) arity arg_regs
         where
          -> ASSERT(arity == length arg_kinds)
             DirectEntry (mkStdEntryLabel id) arity arg_regs
         where
-           (arg_regs, _) = assignRegs isw_chkr live_regs arg_kinds
+           (arg_regs, _) = assignRegs live_regs arg_kinds
            live_regs     = if node_points then [node] else []
     )
 
            live_regs     = if node_points then [node] else []
     )
 
@@ -1067,21 +1096,6 @@ noUpdVapRequired binder_info
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-isConstantRep, isSpecRep, isStaticRep, isPhantomRep, isIntLikeRep :: SMRep -> Bool
-isConstantRep (SpecialisedRep ConstantRep _ _ _)   = True
-isConstantRep other                               = False
-
-isSpecRep (SpecialisedRep kind _ _ _)  = True    -- All the kinds of Spec closures
-isSpecRep other                                = False   -- True indicates that the _VHS is 0 !
-
-isStaticRep (StaticRep _ _) = True
-isStaticRep _              = False
-
-isPhantomRep PhantomRep        = True
-isPhantomRep _         = False
-
-isIntLikeRep (SpecialisedRep IntLikeRep _ _ _)   = True
-isIntLikeRep other                              = False
 
 isStaticClosure :: ClosureInfo -> Bool
 isStaticClosure  (MkClosureInfo _ _ rep) = isStaticRep  rep
 
 isStaticClosure :: ClosureInfo -> Bool
 isStaticClosure  (MkClosureInfo _ _ rep) = isStaticRep  rep
@@ -1121,11 +1135,9 @@ closureType :: ClosureInfo -> Maybe (TyCon, [Type], [Id])
 -- rather than take it from the Id. The Id is probably just "f"!
 
 closureType (MkClosureInfo id (LFThunk _ _ _ (VapThunk fun_id args _)) _)
 -- rather than take it from the Id. The Id is probably just "f"!
 
 closureType (MkClosureInfo id (LFThunk _ _ _ (VapThunk fun_id args _)) _)
-  = getUniDataSpecTyCon_maybe (funResultTy de_foralld_ty (length args))
-  where
-    (_, de_foralld_ty) = splitForalls (idType fun_id)
+  = getDataSpecTyCon_maybe (fun_result_ty (length args) fun_id)
 
 
-closureType (MkClosureInfo id lf _) = getUniDataSpecTyCon_maybe (idType id)
+closureType (MkClosureInfo id lf _) = getDataSpecTyCon_maybe (idType id)
 \end{code}
 
 @closureReturnsUnboxedType@ is used to check whether a closure, {\em
 \end{code}
 
 @closureReturnsUnboxedType@ is used to check whether a closure, {\em
@@ -1140,13 +1152,20 @@ overflow checks.
 closureReturnsUnboxedType :: ClosureInfo -> Bool
 
 closureReturnsUnboxedType (MkClosureInfo fun_id (LFReEntrant _ arity _) _)
 closureReturnsUnboxedType :: ClosureInfo -> Bool
 
 closureReturnsUnboxedType (MkClosureInfo fun_id (LFReEntrant _ arity _) _)
-  = isPrimType (funResultTy de_foralld_ty arity)
-  where
-    (_, de_foralld_ty) = splitForalls (idType fun_id)
+  = isPrimType (fun_result_ty arity fun_id)
 
 closureReturnsUnboxedType other_closure = False
        -- All non-function closures aren't functions,
        -- and hence are boxed, since they are heap alloc'd
 
 closureReturnsUnboxedType other_closure = False
        -- All non-function closures aren't functions,
        -- and hence are boxed, since they are heap alloc'd
+
+-- ToDo: need anything like this in Type.lhs?
+fun_result_ty arity id
+  = let
+       (_, de_foralld_ty) = splitForAllTy (idType id)
+       (arg_tys, res_ty)  = splitFunTy{-w/ dicts as args?-} de_foralld_ty
+    in
+    ASSERT(arity >= 0 && length arg_tys >= arity)
+    mkFunTys (drop arity arg_tys) res_ty
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -1154,7 +1173,7 @@ closureSemiTag :: ClosureInfo -> Int
 
 closureSemiTag (MkClosureInfo _ lf_info _)
   = case lf_info of
 
 closureSemiTag (MkClosureInfo _ lf_info _)
   = case lf_info of
-      LFCon data_con _ -> getDataConTag data_con - fIRST_TAG
+      LFCon data_con _ -> dataConTag data_con - fIRST_TAG
       LFTuple _ _      -> 0
       _                       -> fromInteger oTHER_TAG
 \end{code}
       LFTuple _ _      -> 0
       _                       -> fromInteger oTHER_TAG
 \end{code}
@@ -1248,26 +1267,26 @@ allocProfilingMsg (MkClosureInfo _ lf_info _)
       LFImported               -> panic "ALLOC_IMP"
 \end{code}
 
       LFImported               -> panic "ALLOC_IMP"
 \end{code}
 
-We need a black-hole closure info to pass to @allocDynClosure@
-when we want to allocate the black hole on entry to a CAF.
+We need a black-hole closure info to pass to @allocDynClosure@ when we
+want to allocate the black hole on entry to a CAF.
 
 \begin{code}
 
 \begin{code}
-blackHoleClosureInfo (MkClosureInfo id _ _) = MkClosureInfo id LFBlackHole BlackHoleRep
+blackHoleClosureInfo (MkClosureInfo id _ _)
+  = MkClosureInfo id LFBlackHole BlackHoleRep
 \end{code}
 
 \end{code}
 
-The register liveness when returning from a constructor.  For simplicity,
-we claim just [node] is live for all but PhantomRep's.  In truth, this means
-that non-constructor info tables also claim node, but since their liveness
-information is never used, we don't care.
+The register liveness when returning from a constructor.  For
+simplicity, we claim just [node] is live for all but PhantomRep's.  In
+truth, this means that non-constructor info tables also claim node,
+but since their liveness information is never used, we don't care.
 
 \begin{code}
 
 \begin{code}
-
-dataConLiveness isw_chkr (MkClosureInfo con _ PhantomRep)
-  = case (dataReturnConvAlg isw_chkr con) of
-      ReturnInRegs regs -> mkLiveRegsBitMask regs
+dataConLiveness (MkClosureInfo con _ PhantomRep)
+  = case (dataReturnConvAlg con) of
+      ReturnInRegs regs -> mkLiveRegsMask regs
       ReturnInHeap -> panic "dataConLiveness:PhantomRep in heap???"
 
       ReturnInHeap -> panic "dataConLiveness:PhantomRep in heap???"
 
-dataConLiveness _ _ = mkLiveRegsBitMask [node]
+dataConLiveness _ = mkLiveRegsMask [node]
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -1303,8 +1322,7 @@ closureKind (MkClosureInfo _ lf _)
 closureTypeDescr :: ClosureInfo -> String
 closureTypeDescr (MkClosureInfo id lf _)
   = if (isDataCon id) then                     -- DataCon has function types
 closureTypeDescr :: ClosureInfo -> String
 closureTypeDescr (MkClosureInfo id lf _)
   = if (isDataCon id) then                     -- DataCon has function types
-       _UNPK_ (getOccurrenceName (getDataConTyCon id)) -- We want the TyCon not the ->
+       _UNPK_ (getOccurrenceName (dataConTyCon id))    -- We want the TyCon not the ->
     else
     else
-       getUniTyDescription (idType id)
+       getTyDescription (idType id)
 \end{code}
 \end{code}
-
index d8112a8..2b193da 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[CodeGen]{@CodeGen@: main module of the code generator}
 
 %
 \section[CodeGen]{@CodeGen@: main module of the code generator}
 
@@ -19,28 +19,32 @@ functions drive the mangling of top-level bindings.
 
 module CodeGen ( codeGen ) where
 
 
 module CodeGen ( codeGen ) where
 
+import Ubiq{-uitous-}
+
 import StgSyn
 import CgMonad
 import AbsCSyn
 
 import StgSyn
 import CgMonad
 import AbsCSyn
 
-import CLabel  ( modnameToC )
+import AbsCUtils       ( mkAbstractCs, mkAbsCStmts )
+import Bag             ( foldBag )
 import CgClosure       ( cgTopRhsClosure )
 import CgCon           ( cgTopRhsCon )
 import CgClosure       ( cgTopRhsClosure )
 import CgCon           ( cgTopRhsCon )
-import CgConTbls       ( genStaticConBits, TCE(..), UniqFM )
-import ClosureInfo     ( LambdaFormInfo, mkClosureLFInfo )
-import CmdLineOpts
-import FiniteMap       ( FiniteMap )
-import Maybes          ( Maybe(..) )
-import Pretty          -- debugging only
-import PrimRep         ( getPrimRepSize )
-import Util
+import CgConTbls       ( genStaticConBits )
+import ClosureInfo     ( mkClosureLFInfo )
+import CmdLineOpts     ( opt_SccProfilingOn, opt_CompilingPrelude,
+                         opt_EnsureSplittableC, opt_SccGroup
+                       )
+import CStrings                ( modnameToC )
+import Maybes          ( maybeToBool )
+import PrimRep         ( getPrimRepSize, PrimRep(..) )
+import Util            ( panic, assertPanic )
 \end{code}
 
 \begin{code}
 codeGen :: FAST_STRING         -- module name
        -> ([CostCentre],       -- local cost-centres needing declaring/registering
            [CostCentre])       -- "extern" cost-centres needing declaring
 \end{code}
 
 \begin{code}
 codeGen :: FAST_STRING         -- module name
        -> ([CostCentre],       -- local cost-centres needing declaring/registering
            [CostCentre])       -- "extern" cost-centres needing declaring
-       -> [FAST_STRING]        -- import names
+       -> Bag FAST_STRING      -- import names
        -> [TyCon]              -- tycons with data constructors to convert
        -> FiniteMap TyCon [(Bool, [Maybe Type])]
                                -- tycon specialisation info
        -> [TyCon]              -- tycons with data constructors to convert
        -> FiniteMap TyCon [(Bool, [Maybe Type])]
                                -- tycon specialisation info
@@ -51,11 +55,11 @@ codeGen mod_name (local_CCs, extern_CCs) import_names gen_tycons tycon_specs stg
   = let
        doing_profiling   = opt_SccProfilingOn
        compiling_prelude = opt_CompilingPrelude
   = let
        doing_profiling   = opt_SccProfilingOn
        compiling_prelude = opt_CompilingPrelude
-       maybe_split       = if (switch_is_on (EnsureSplittableC (panic "codeGen:esc")))
+       maybe_split       = if maybeToBool (opt_EnsureSplittableC)
                            then CSplitMarker
                            else AbsCNop
 
                            then CSplitMarker
                            else AbsCNop
 
-       cinfo = MkCompInfo switch_is_on int_switch_set mod_name
+       cinfo = MkCompInfo mod_name
     in
     if not doing_profiling then
        mkAbstractCs [
     in
     if not doing_profiling then
        mkAbstractCs [
@@ -85,15 +89,16 @@ codeGen mod_name (local_CCs, extern_CCs) import_names gen_tycons tycon_specs stg
                initC cinfo (cgTopBindings maybe_split stg_pgm) ]
   where
     -----------------
                initC cinfo (cgTopBindings maybe_split stg_pgm) ]
   where
     -----------------
-    grp_name  = case (stringSwitchSet sw_lookup_fn SccGroup) of
-                 Just xx -> _PK_ xx
+    grp_name  = case opt_SccGroup of
+                 Just xx -> xx
                  Nothing -> mod_name   -- default: module name
 
     -----------------
     mkCcRegister ccs import_names
       = let
            register_ccs     = mkAbstractCs (map mk_register ccs)
                  Nothing -> mod_name   -- default: module name
 
     -----------------
     mkCcRegister ccs import_names
       = let
            register_ccs     = mkAbstractCs (map mk_register ccs)
-           register_imports = mkAbstractCs (map mk_import_register import_names)
+           register_imports
+             = foldBag mkAbsCStmts mk_import_register AbsCNop import_names
        in
        mkAbstractCs [
            CCallProfCCMacro SLIT("START_REGISTER_CCS") [CLitLit (modnameToC (SLIT("_reg") _APPEND_ mod_name)) AddrRep],
        in
        mkAbstractCs [
            CCallProfCCMacro SLIT("START_REGISTER_CCS") [CLitLit (modnameToC (SLIT("_reg") _APPEND_ mod_name)) AddrRep],
index 4adcfd7..99432c7 100644 (file)
@@ -12,7 +12,9 @@ Other modules should access this info through ClosureInfo.
 module SMRep (
        SMRep(..), SMSpecRepKind(..), SMUpdateKind(..),
        getSMInfoStr, getSMInitHdrStr, getSMUpdInplaceHdrStr,
 module SMRep (
        SMRep(..), SMSpecRepKind(..), SMUpdateKind(..),
        getSMInfoStr, getSMInitHdrStr, getSMUpdInplaceHdrStr,
-       ltSMRepHdr
+       ltSMRepHdr,
+       isConstantRep, isSpecRep, isStaticRep, isPhantomRep,
+       isIntLikeRep
     ) where
 
 import Ubiq{-uitous-}
     ) where
 
 import Ubiq{-uitous-}
@@ -129,7 +131,27 @@ MuTupleRep == MUTUPLE
 
 --jim
 -}
 
 --jim
 -}
+\end{code}
+
+\begin{code}
+isConstantRep, isSpecRep, isStaticRep, isPhantomRep, isIntLikeRep :: SMRep -> Bool
+isConstantRep (SpecialisedRep ConstantRep _ _ _)   = True
+isConstantRep other                               = False
+
+isSpecRep (SpecialisedRep kind _ _ _)  = True    -- All the kinds of Spec closures
+isSpecRep other                                = False   -- True indicates that the _VHS is 0 !
+
+isStaticRep (StaticRep _ _) = True
+isStaticRep _              = False
 
 
+isPhantomRep PhantomRep        = True
+isPhantomRep _         = False
+
+isIntLikeRep (SpecialisedRep IntLikeRep _ _ _)   = True
+isIntLikeRep other                              = False
+\end{code}
+
+\begin{code}
 instance Eq SMRep where
     (SpecialisedRep k1 a1 b1 _) == (SpecialisedRep k2 a2 b2 _) = (tagOf_SMSpecRepKind k1) _EQ_ (tagOf_SMSpecRepKind k2)
                                                               && a1 == a2 && b1 == b2
 instance Eq SMRep where
     (SpecialisedRep k1 a1 b1 _) == (SpecialisedRep k2 a2 b2 _) = (tagOf_SMSpecRepKind k1) _EQ_ (tagOf_SMSpecRepKind k2)
                                                               && a1 == a2 && b1 == b2
index 90f7656..ecae173 100644 (file)
@@ -26,7 +26,7 @@ import Id             ( idType, mkSysLocal,
                          GenId{-instances-}
                        )
 import PrelInfo                ( liftDataCon, mkLiftTy, statePrimTyCon )
                          GenId{-instances-}
                        )
 import PrelInfo                ( liftDataCon, mkLiftTy, statePrimTyCon )
-import TyCon           ( TyCon{-instance-} )
+import TyCon           ( isBoxedTyCon, TyCon{-instance-} )
 import Type            ( maybeAppDataTyCon, eqTy )
 import UniqSupply      ( getUnique, getUniques, splitUniqSupply, UniqSupply )
 import Util            ( zipEqual, zipWithEqual, assertPanic, panic )
 import Type            ( maybeAppDataTyCon, eqTy )
 import UniqSupply      ( getUnique, getUniques, splitUniqSupply, UniqSupply )
 import Util            ( zipEqual, zipWithEqual, assertPanic, panic )
@@ -34,7 +34,6 @@ import Util           ( zipEqual, zipWithEqual, assertPanic, panic )
 infixr 9 `thenL`
 
 updateIdType = panic "CoreLift.updateIdType"
 infixr 9 `thenL`
 
 updateIdType = panic "CoreLift.updateIdType"
-isBoxedTyCon = panic "CoreLift.isBoxedTyCon"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index a08c45f..e31af01 100644 (file)
@@ -21,6 +21,7 @@ import Literal                ( literalType, Literal{-instance-} )
 import Id              ( idType, isBottomingId,
                          getInstantiatedDataConSig, GenId{-instances-}
                        )
 import Id              ( idType, isBottomingId,
                          getInstantiatedDataConSig, GenId{-instances-}
                        )
+import Maybes          ( catMaybes )
 import Outputable      ( Outputable(..) )
 import PprCore
 import PprStyle                ( PprStyle(..) )
 import Outputable      ( Outputable(..) )
 import PprCore
 import PprStyle                ( PprStyle(..) )
@@ -32,11 +33,13 @@ import SrcLoc               ( SrcLoc )
 import Type            ( mkFunTy,getFunTy_maybe,mkForAllTy,getForAllTy_maybe,
                          isPrimType,getTypeKind,instantiateTy,
                          mkForAllUsageTy,getForAllUsageTy,instantiateUsage,
 import Type            ( mkFunTy,getFunTy_maybe,mkForAllTy,getForAllTy_maybe,
                          isPrimType,getTypeKind,instantiateTy,
                          mkForAllUsageTy,getForAllUsageTy,instantiateUsage,
-                         maybeAppDataTyCon, eqTy )
-import TyCon           ( isPrimTyCon,isVisibleDataTyCon )
+                         maybeAppDataTyCon, eqTy
+                       )
+import TyCon           ( isPrimTyCon, tyConFamilySize )
 import TyVar           ( getTyVarKind, GenTyVar{-instances-} )
 import UniqSet         ( emptyUniqSet, mkUniqSet, intersectUniqSets,
 import TyVar           ( getTyVarKind, GenTyVar{-instances-} )
 import UniqSet         ( emptyUniqSet, mkUniqSet, intersectUniqSets,
-                         unionUniqSets, elementOfUniqSet, UniqSet(..) )
+                         unionUniqSets, elementOfUniqSet, UniqSet(..)
+                       )
 import Unique          ( Unique )
 import Usage           ( GenUsage )
 import Util            ( zipEqual, pprTrace, pprPanic, assertPanic, panic )
 import Unique          ( Unique )
 import Usage           ( GenUsage )
 import Util            ( zipEqual, pprTrace, pprPanic, assertPanic, panic )
@@ -89,9 +92,7 @@ lintCoreBindings sty whoDunnit spec_done binds
          ppStr ("*** Core Lint Errors: in " ++ whoDunnit ++ " ***"),
          msg sty,
          ppStr "*** Offending Program ***",
          ppStr ("*** Core Lint Errors: in " ++ whoDunnit ++ " ***"),
          msg sty,
          ppStr "*** Offending Program ***",
-         ppAboves
-          (map (pprCoreBinding sty (pprBigCoreBinder sty) (pprTypedCoreBinder sty) (ppr sty))
-           binds),
+         ppAboves (map (pprCoreBinding sty) binds),
          ppStr "*** End of Offense ***"
        ])
   where
          ppStr "*** End of Offense ***"
        ])
   where
@@ -297,23 +298,28 @@ lintCoreAlts :: CoreCaseAlts
             -> TyCon                   -- TyCon pinned on the case
             -> LintM (Maybe Type)      -- Type of alternatives
 
             -> TyCon                   -- TyCon pinned on the case
             -> LintM (Maybe Type)      -- Type of alternatives
 
-lintCoreAlts (AlgAlts alts deflt) ty tycon
-  = panic "CoreLint.lintCoreAlts"
-{- LATER:
-  WDP: can't tell what type DNT wants here
+lintCoreAlts whole_alts@(AlgAlts alts deflt) ty tycon
   = -- Check tycon is not a primitive tycon
     addErrIfL (isPrimTyCon tycon) (mkCasePrimMsg tycon)
     `seqL`
   = -- Check tycon is not a primitive tycon
     addErrIfL (isPrimTyCon tycon) (mkCasePrimMsg tycon)
     `seqL`
-    -- Check we have a non-abstract data tycon
-    addErrIfL (not (isVisibleDataTyCon tycon)) (mkCaseAbstractMsg tycon)
+    -- Check we are scrutinising a proper datatype
+    -- (ToDo: robustify)
+    addErrIfL (not (tyConFamilySize tycon >= 1)) (mkCaseAbstractMsg tycon)
     `seqL`
     lintDeflt deflt ty
     `thenL` \maybe_deflt_ty ->
     mapL (lintAlgAlt ty tycon) alts
     `thenL` \maybe_alt_tys ->
     `seqL`
     lintDeflt deflt ty
     `thenL` \maybe_deflt_ty ->
     mapL (lintAlgAlt ty tycon) alts
     `thenL` \maybe_alt_tys ->
-    returnL (maybe_deflt_ty : maybe_alt_tys)
+    -- Check the result types
+    case catMaybes (maybe_deflt_ty : maybe_alt_tys) of
+      []            -> returnL Nothing
 
 
-lintCoreAlts (PrimAlts alts deflt) ty tycon
+      (first_ty:tys) -> mapL check tys `seqL`
+                       returnL (Just first_ty)
+       where
+         check ty = checkTys first_ty ty (mkCaseAltMsg whole_alts)
+
+lintCoreAlts whole_alts@(PrimAlts alts deflt) ty tycon
   = -- Check tycon is a primitive tycon
     addErrIfL (not (isPrimTyCon tycon)) (mkCaseNotPrimMsg tycon)
     `seqL`
   = -- Check tycon is a primitive tycon
     addErrIfL (not (isPrimTyCon tycon)) (mkCaseNotPrimMsg tycon)
     `seqL`
@@ -321,21 +327,16 @@ lintCoreAlts (PrimAlts alts deflt) ty tycon
     `thenL` \maybe_alt_tys ->
     lintDeflt deflt ty
     `thenL` \maybe_deflt_ty ->
     `thenL` \maybe_alt_tys ->
     lintDeflt deflt ty
     `thenL` \maybe_deflt_ty ->
-    returnL (maybe_deflt_ty : maybe_alt_tys)
     -- Check the result types
     -- Check the result types
--}
-{-
-    `thenL` \ maybe_result_tys ->
-    case catMaybes (maybe_result_tys) of
+    case catMaybes (maybe_deflt_ty : maybe_alt_tys) of
       []            -> returnL Nothing
 
       (first_ty:tys) -> mapL check tys `seqL`
                        returnL (Just first_ty)
        where
       []            -> returnL Nothing
 
       (first_ty:tys) -> mapL check tys `seqL`
                        returnL (Just first_ty)
        where
-         check ty = checkTys first_ty ty (mkCaseAltMsg alts)
--}
+         check ty = checkTys first_ty ty (mkCaseAltMsg whole_alts)
 
 
-lintAlgAlt scrut_ty (con,args,rhs)
+lintAlgAlt scrut_ty tycon{-ToDo: use it!-} (con,args,rhs)
   = (case maybeAppDataTyCon scrut_ty of
       Nothing ->
         addErrL (mkAlgAltMsg1 scrut_ty)
   = (case maybeAppDataTyCon scrut_ty of
       Nothing ->
         addErrL (mkAlgAltMsg1 scrut_ty)
@@ -551,7 +552,7 @@ mkCasePrimMsg tycon sty
 
 mkCaseAbstractMsg :: TyCon -> ErrMsg
 mkCaseAbstractMsg tycon sty
 
 mkCaseAbstractMsg :: TyCon -> ErrMsg
 mkCaseAbstractMsg tycon sty
-  = ppAbove (ppStr "An algebraic case on an abstract type:")
+  = ppAbove (ppStr "An algebraic case on some weird type:")
            (ppr sty tycon)
 
 mkDefltMsg :: CoreCaseDefault -> ErrMsg
            (ppr sty tycon)
 
 mkDefltMsg :: CoreCaseDefault -> ErrMsg
index 037afb4..2e017b8 100644 (file)
@@ -17,7 +17,7 @@ module CoreSyn (
        mkApp, mkCon, mkPrim,
        mkValLam, mkTyLam, mkUseLam,
        mkLam,
        mkApp, mkCon, mkPrim,
        mkValLam, mkTyLam, mkUseLam,
        mkLam,
-       collectBinders,
+       collectBinders, isValBinder, notValBinder,
        
        collectArgs, isValArg, notValArg, numValArgs,
 
        
        collectArgs, isValArg, notValArg, numValArgs,
 
@@ -57,13 +57,10 @@ module CoreSyn (
 import Ubiq{-uitous-}
 
 import CostCentre      ( showCostCentre, CostCentre )
 import Ubiq{-uitous-}
 
 import CostCentre      ( showCostCentre, CostCentre )
-import Id              ( idType )
+import Id              ( idType, GenId{-instance Eq-} )
+import Type            ( isUnboxedType )
 import Usage           ( UVar(..) )
 import Util            ( panic, assertPanic )
 import Usage           ( UVar(..) )
 import Util            ( panic, assertPanic )
-
-isUnboxedDataType = panic "CoreSyn.isUnboxedDataType"
---eqId :: Id -> Id -> Bool
-eqId = panic "CoreSyn.eqId"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -197,12 +194,13 @@ being bound has unboxed type. We have different variants ...
                                (unboxed bindings in a letrec are still prohibited)
 
 \begin{code}
                                (unboxed bindings in a letrec are still prohibited)
 
 \begin{code}
-mkCoLetAny :: GenCoreBinding val_bdr val_occ tyvar uvar
-          -> GenCoreExpr    val_bdr val_occ tyvar uvar
-          -> GenCoreExpr    val_bdr val_occ tyvar uvar
-mkCoLetsAny :: [GenCoreBinding val_bdr val_occ tyvar uvar] ->
-               GenCoreExpr val_bdr val_occ tyvar uvar ->
-               GenCoreExpr val_bdr val_occ tyvar uvar
+mkCoLetAny :: GenCoreBinding Id Id tyvar uvar
+          -> GenCoreExpr    Id Id tyvar uvar
+          -> GenCoreExpr    Id Id tyvar uvar
+mkCoLetsAny :: [GenCoreBinding Id Id tyvar uvar] ->
+               GenCoreExpr Id Id tyvar uvar ->
+               GenCoreExpr Id Id tyvar uvar
+
 mkCoLetrecAny :: [(val_bdr, GenCoreExpr val_bdr val_occ tyvar uvar)]
              -> GenCoreExpr val_bdr val_occ tyvar uvar
              -> GenCoreExpr val_bdr val_occ tyvar uvar
 mkCoLetrecAny :: [(val_bdr, GenCoreExpr val_bdr val_occ tyvar uvar)]
              -> GenCoreExpr val_bdr val_occ tyvar uvar
              -> GenCoreExpr val_bdr val_occ tyvar uvar
@@ -216,7 +214,7 @@ mkCoLetsAny binds expr = foldr mkCoLetAny expr binds
 mkCoLetAny bind@(Rec binds) body = mkCoLetrecAny binds body
 mkCoLetAny bind@(NonRec binder rhs) body
   = case body of
 mkCoLetAny bind@(Rec binds) body = mkCoLetrecAny binds body
 mkCoLetAny bind@(NonRec binder rhs) body
   = case body of
-      Var binder2 | binder `eqId` binder2
+      Var binder2 | binder == binder2
         -> rhs   -- hey, I have the rhs
       other
         -> Let bind body
         -> rhs   -- hey, I have the rhs
       other
         -> Let bind body
@@ -231,9 +229,9 @@ mkCoLetAny bind@(NonRec binder rhs) body
 mkCoLetNoUnboxed bind@(Rec binds) body
   = mkCoLetrecNoUnboxed binds body
 mkCoLetNoUnboxed bind@(NonRec binder rhs) body
 mkCoLetNoUnboxed bind@(Rec binds) body
   = mkCoLetrecNoUnboxed binds body
 mkCoLetNoUnboxed bind@(NonRec binder rhs) body
-  = --ASSERT (not (isUnboxedDataType (idType binder)))
+  = --ASSERT (not (isUnboxedType (idType binder)))
     case body of
     case body of
-      Var binder2 | binder `eqId` binder2
+      Var binder2 | binder == binder2
         -> rhs   -- hey, I have the rhs
       other
         -> Let bind body
         -> rhs   -- hey, I have the rhs
       other
         -> Let bind body
@@ -251,7 +249,7 @@ mkCoLetrecNoUnboxed binds body
     Let (Rec binds) body
   where
     is_boxed_bind (binder, rhs)
     Let (Rec binds) body
   where
     is_boxed_bind (binder, rhs)
-      = (not . isUnboxedDataType . idType) binder
+      = (not . isUnboxedType . idType) binder
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -264,10 +262,10 @@ mkCoLetUnboxedToCase bind@(Rec binds) body
   = mkCoLetrecNoUnboxed binds body
 mkCoLetUnboxedToCase bind@(NonRec binder rhs) body
   = case body of
   = mkCoLetrecNoUnboxed binds body
 mkCoLetUnboxedToCase bind@(NonRec binder rhs) body
   = case body of
-      Var binder2 | binder `eqId` binder2
+      Var binder2 | binder == binder2
         -> rhs   -- hey, I have the rhs
       other
         -> rhs   -- hey, I have the rhs
       other
-        -> if (not (isUnboxedDataType (idType binder))) then
+        -> if (not (isUnboxedType (idType binder))) then
                Let bind body            -- boxed...
            else
                Case rhs                  -- unboxed...
                Let bind body            -- boxed...
            else
                Case rhs                  -- unboxed...
@@ -341,6 +339,11 @@ data GenCoreBinder val_bdr tyvar uvar
   = ValBinder  val_bdr
   | TyBinder   tyvar
   | UsageBinder        uvar
   = ValBinder  val_bdr
   | TyBinder   tyvar
   | UsageBinder        uvar
+
+isValBinder (ValBinder _) = True
+isValBinder _            = False
+
+notValBinder = not . isValBinder
 \end{code}
 
 Clump Lams together if possible.
 \end{code}
 
 Clump Lams together if possible.
@@ -379,42 +382,25 @@ collectBinders ::
   GenCoreExpr val_bdr val_occ tyvar uvar ->
   ([uvar], [tyvar], [val_bdr], GenCoreExpr val_bdr val_occ tyvar uvar)
 
   GenCoreExpr val_bdr val_occ tyvar uvar ->
   ([uvar], [tyvar], [val_bdr], GenCoreExpr val_bdr val_occ tyvar uvar)
 
-collectBinders (Lam (UsageBinder u) body)
-  = let
-       (uvars, tyvars, args, final_body) = collectBinders body
-    in
-    (u:uvars, tyvars, args, final_body)
-
-collectBinders other
-  = let
-       (tyvars, args, body) = dig_for_tyvars other
-    in
-    ([], tyvars, args, body)
+collectBinders expr
+  = usages expr []
   where
   where
-    dig_for_tyvars (Lam (TyBinder tv) body)
-      = let
-           (tyvars, args, body2) = dig_for_tyvars body
-       in
-       (tv : tyvars, args, body2)
-
-    dig_for_tyvars body
-      = ASSERT(not (usage_lambda body))
-       let
-           (args, body2) = dig_for_valvars body
-       in
-       ([], args, body2)
-
-    ---------------------------------------
-    dig_for_valvars (Lam (ValBinder v) body)
-      = let
-           (args, body2) = dig_for_valvars body
-       in
-       (v : args, body2)
-
-    dig_for_valvars body
-      = ASSERT(not (usage_lambda body))
-       ASSERT(not (tyvar_lambda body))
-       ([], body)
+    usages (Lam (UsageBinder u) body) uacc = usages body (u:uacc)
+    usages other uacc
+      = case (tyvars other []) of { (tacc, vacc, expr) ->
+       (reverse uacc, tacc, vacc, expr) }
+
+    tyvars (Lam (TyBinder t)    body) tacc = tyvars body (t:tacc)
+    tyvars other tacc
+      = ASSERT(not (usage_lambda other))
+       case (valvars other []) of { (vacc, expr) ->
+       (reverse tacc, vacc, expr) }
+
+    valvars (Lam (ValBinder v)  body) vacc = valvars body (v:vacc)
+    valvars other vacc
+      = ASSERT(not (usage_lambda other))
+       ASSERT(not (tyvar_lambda other))
+       (reverse vacc, other)
 
     ---------------------------------------
     usage_lambda (Lam (UsageBinder _) _) = True
 
     ---------------------------------------
     usage_lambda (Lam (UsageBinder _) _) = True
@@ -489,13 +475,36 @@ and the arguments to which it is applied.
 \begin{code}
 collectArgs :: GenCoreExpr val_bdr val_occ tyvar uvar
            -> (GenCoreExpr val_bdr val_occ tyvar uvar,
 \begin{code}
 collectArgs :: GenCoreExpr val_bdr val_occ tyvar uvar
            -> (GenCoreExpr val_bdr val_occ tyvar uvar,
-               [GenCoreArg val_occ tyvar uvar])
+               [GenUsage uvar],
+               [GenType tyvar uvar],
+               [GenCoreArg val_occ tyvar uvar]{-ValArgs-})
 
 collectArgs expr
 
 collectArgs expr
-  = collect expr []
+  = usages expr []
   where
   where
-    collect (App fun arg) args = collect fun (arg : args)
-    collect fun                  args = (fun, args)
+    usages (App fun (UsageArg u)) uacc = usages fun (u:uacc)
+    usages fun uacc
+      = case (tyvars fun []) of { (expr, tacc, vacc) ->
+       (expr, uacc, tacc, vacc) }
+
+    tyvars (App fun (TyArg t))    tacc = tyvars fun (t:tacc)
+    tyvars fun tacc
+      = ASSERT(not (usage_app fun))
+       case (valvars fun []) of { (expr, vacc) ->
+       (expr, tacc, vacc) }
+
+    valvars (App fun v) vacc | isValArg v = valvars fun (v:vacc)
+    valvars fun vacc
+      = ASSERT(not (usage_app fun))
+       ASSERT(not (ty_app    fun))
+       (fun, vacc)
+
+    ---------------------------------------
+    usage_app (App _ (UsageArg _)) = True
+    usage_app _                           = False
+
+    ty_app    (App _ (TyArg _))    = True
+    ty_app    _                           = False
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index 7aec06e..9266898 100644 (file)
@@ -28,7 +28,8 @@ module CoreUnfold (
     ) where
 
 import Ubiq
     ) where
 
 import Ubiq
-import IdLoop   -- for paranoia checking
+import IdLoop   -- for paranoia checking;
+                -- and also to get mkMagicUnfoldingFun
 import PrelLoop  -- for paranoia checking
 
 import Bag             ( emptyBag, unitBag, unionBags, Bag )
 import PrelLoop  -- for paranoia checking
 
 import Bag             ( emptyBag, unitBag, unionBags, Bag )
@@ -38,24 +39,21 @@ import CgCompInfo   ( uNFOLDING_CHEAP_OP_COST,
                          uNFOLDING_NOREP_LIT_COST
                        )
 import CoreSyn
                          uNFOLDING_NOREP_LIT_COST
                        )
 import CoreSyn
-import CoreUtils       ( coreExprType )
+import CoreUtils       ( coreExprType, manifestlyWHNF )
 import CostCentre      ( ccMentionsId )
 import Id              ( IdSet(..), GenId{-instances-} )
 import IdInfo          ( bottomIsGuaranteed )
 import Literal         ( isNoRepLit, isLitLitLit )
 import CostCentre      ( ccMentionsId )
 import Id              ( IdSet(..), GenId{-instances-} )
 import IdInfo          ( bottomIsGuaranteed )
 import Literal         ( isNoRepLit, isLitLitLit )
-import MagicUFs                ( mkMagicUnfoldingFun, MagicUnfoldingFun )
 import Pretty
 import Pretty
-import PrimOp          ( PrimOp(..) )
+import PrimOp          ( primOpCanTriggerGC, PrimOp(..) )
+import TyCon           ( tyConFamilySize )
 import Type            ( getAppDataTyCon )
 import Type            ( getAppDataTyCon )
-import UniqSet         ( emptyUniqSet, singletonUniqSet, mkUniqSet,
-                         unionUniqSets
+import UniqSet         ( emptyUniqSet, unitUniqSet, mkUniqSet,
+                         addOneToUniqSet, unionUniqSets
                        )
 import Usage           ( UVar(..) )
 import Util            ( isIn, panic )
 
                        )
 import Usage           ( UVar(..) )
 import Util            ( isIn, panic )
 
-manifestlyWHNF = panic "manifestlyWHNF (CoreUnfold)"
-primOpCanTriggerGC = panic "primOpCanTriggerGC (CoreUnfold)"
-getTyConFamilySize = panic "getTyConFamilySize (CoreUnfold)"
 whatsMentionedInId = panic "whatsMentionedInId (CoreUnfold)"
 getMentionedTyConsAndClassesFromType = panic "getMentionedTyConsAndClassesFromType (CoreUnfold)"
 \end{code}
 whatsMentionedInId = panic "whatsMentionedInId (CoreUnfold)"
 getMentionedTyConsAndClassesFromType = panic "getMentionedTyConsAndClassesFromType (CoreUnfold)"
 \end{code}
@@ -333,8 +331,7 @@ sizeExpr scc_s_OK bOMB_OUT_SIZE args expr
     ------------
     size_up_alts scrut_ty (AlgAlts alts deflt)
       = foldr (addSize . size_alg_alt) (size_up_deflt deflt) alts
     ------------
     size_up_alts scrut_ty (AlgAlts alts deflt)
       = foldr (addSize . size_alg_alt) (size_up_deflt deflt) alts
-               `addSizeN`
-       (case (getTyConFamilySize tycon) of { Just n -> n })
+               `addSizeN` (tyConFamilySize tycon)
        -- NB: we charge N for an alg. "case", where N is
        -- the number of constructors in the thing being eval'd.
        -- (You'll eventually get a "discount" of N if you
        -- NB: we charge N for an alg. "case", where N is
        -- the number of constructors in the thing being eval'd.
        -- (You'll eventually get a "discount" of N if you
@@ -426,7 +423,7 @@ add1             :: IdSet -> Id   -> IdSet
 add_some     :: IdSet -> [Id] -> IdSet
 
 no_in_scopes           = emptyUniqSet
 add_some     :: IdSet -> [Id] -> IdSet
 
 no_in_scopes           = emptyUniqSet
-in_scopes `add1`     x  = in_scopes `unionUniqSets` singletonUniqSet x
+in_scopes `add1`     x  = addOneToUniqSet in_scopes x
 in_scopes `add_some` xs = in_scopes `unionUniqSets` mkUniqSet xs
 \end{code}
 
 in_scopes `add_some` xs = in_scopes `unionUniqSets` mkUniqSet xs
 \end{code}
 
@@ -747,7 +744,7 @@ ppr_uf_Expr in_scopes (SCC cc body)
 \begin{code}
 ppr_uf_Binder :: Id -> Pretty
 ppr_uf_Binder v
 \begin{code}
 ppr_uf_Binder :: Id -> Pretty
 ppr_uf_Binder v
-  = ppBesides [ppLparen, pprIdInUnfolding (singletonUniqSet v) v, ppPStr SLIT(" :: "),
+  = ppBesides [ppLparen, pprIdInUnfolding (unitUniqSet v) v, ppPStr SLIT(" :: "),
               ppr ppr_Unfolding (idType v), ppRparen]
 
 ppr_uf_Atom in_scopes (LitArg l) = ppr ppr_Unfolding l
               ppr ppr_Unfolding (idType v), ppRparen]
 
 ppr_uf_Atom in_scopes (LitArg l) = ppr ppr_Unfolding l
index 363cecb..ddc7658 100644 (file)
@@ -9,19 +9,19 @@
 module CoreUtils (
        coreExprType, coreAltsType,
 
 module CoreUtils (
        coreExprType, coreAltsType,
 
-       substCoreExpr
+       substCoreExpr, substCoreBindings
 
        , mkCoreIfThenElse
        , mkErrorApp, escErrorMsg
        , argToExpr
        , unTagBinders, unTagBindersAlts
        , manifestlyWHNF, manifestlyBottom
 
        , mkCoreIfThenElse
        , mkErrorApp, escErrorMsg
        , argToExpr
        , unTagBinders, unTagBindersAlts
        , manifestlyWHNF, manifestlyBottom
+       , maybeErrorApp
+       , nonErrorRHSs
+       , squashableDictishCcExpr
 {-     exprSmallEnoughToDup,
        coreExprArity,
        isWrapperFor,
 {-     exprSmallEnoughToDup,
        coreExprArity,
        isWrapperFor,
-       maybeErrorApp,
-       nonErrorRHSs,
-       squashableDictishCcExpr,
 
 -}  ) where
 
 
 -}  ) where
 
@@ -38,10 +38,10 @@ import Id           ( idType, mkSysLocal, getIdArity, isBottomingId,
                        )
 import IdInfo          ( arityMaybe )
 import Literal         ( literalType, isNoRepLit, Literal(..) )
                        )
 import IdInfo          ( arityMaybe )
 import Literal         ( literalType, isNoRepLit, Literal(..) )
-import Maybes          ( catMaybes )
+import Maybes          ( catMaybes, maybeToBool )
 import PprCore         ( GenCoreExpr{-instances-}, GenCoreArg{-instances-} )
 import PprStyle                ( PprStyle(..) )
 import PprCore         ( GenCoreExpr{-instances-}, GenCoreArg{-instances-} )
 import PprStyle                ( PprStyle(..) )
-import PprType         ( GenType{-instances-}, GenTyVar{-instance-} )
+import PprType         ( GenType{-instances-} )
 import Pretty          ( ppAboves )
 import PrelInfo                ( trueDataCon, falseDataCon,
                          augmentId, buildId,
 import Pretty          ( ppAboves )
 import PrelInfo                ( trueDataCon, falseDataCon,
                          augmentId, buildId,
@@ -49,21 +49,21 @@ import PrelInfo             ( trueDataCon, falseDataCon,
                        )
 import PrimOp          ( primOpType, PrimOp(..) )
 import SrcLoc          ( mkUnknownSrcLoc )
                        )
 import PrimOp          ( primOpType, PrimOp(..) )
 import SrcLoc          ( mkUnknownSrcLoc )
-import TyVar           ( isNullTyVarEnv, TyVarEnv(..), GenTyVar{-instances-} )
-import Type            ( mkFunTys, mkForAllTy, mkForAllUsageTy,
-                         getFunTy_maybe, applyTy, splitSigmaTy
+import TyVar           ( isNullTyVarEnv, TyVarEnv(..) )
+import Type            ( mkFunTys, mkForAllTy, mkForAllUsageTy, mkTyVarTy,
+                         getFunTy_maybe, applyTy, isPrimType,
+                         splitSigmaTy, splitFunTy, eqTy, applyTypeEnvToTy
                        )
                        )
-import Unique          ( Unique{-instances-} )
 import UniqSupply      ( initUs, returnUs, thenUs,
                          mapUs, mapAndUnzipUs,
                          UniqSM(..), UniqSupply
                        )
 import UniqSupply      ( initUs, returnUs, thenUs,
                          mapUs, mapAndUnzipUs,
                          UniqSM(..), UniqSupply
                        )
+import Usage           ( UVar(..) )
 import Util            ( zipEqual, panic, pprPanic, assertPanic )
 
 type TypeEnv = TyVarEnv Type
 applyUsage = panic "CoreUtils.applyUsage:ToDo"
 dup_binder = panic "CoreUtils.dup_binder"
 import Util            ( zipEqual, panic, pprPanic, assertPanic )
 
 type TypeEnv = TyVarEnv Type
 applyUsage = panic "CoreUtils.applyUsage:ToDo"
 dup_binder = panic "CoreUtils.dup_binder"
-applyTypeEnvToTy = panic "CoreUtils.applyTypeEnvToTy"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -253,11 +253,11 @@ exprSmallEnoughToDup (Prim op _ _) = not (fragilePrimOp op)       -- Could check # of
 exprSmallEnoughToDup (Lit lit) = not (isNoRepLit lit)
 
 exprSmallEnoughToDup expr  -- for now, just: <var> applied to <args>
 exprSmallEnoughToDup (Lit lit) = not (isNoRepLit lit)
 
 exprSmallEnoughToDup expr  -- for now, just: <var> applied to <args>
-  = case (collectArgs expr) of { (fun, args) ->
+  = case (collectArgs expr) of { (fun, _, _, vargs) ->
     case fun of
       Var v -> v /= buildId
                 && v /= augmentId
     case fun of
       Var v -> v /= buildId
                 && v /= augmentId
-                && length args <= 6 -- or 10 or 1 or 4 or anything smallish.
+                && length vargs <= 6 -- or 10 or 1 or 4 or anything smallish.
       _       -> False
     }
 -}
       _       -> False
     }
 -}
@@ -280,14 +280,13 @@ manifestlyWHNF (SCC _ e)  = manifestlyWHNF e
 manifestlyWHNF (Let _ e)  = False
 manifestlyWHNF (Case _ _) = False
 
 manifestlyWHNF (Let _ e)  = False
 manifestlyWHNF (Case _ _) = False
 
-manifestlyWHNF (Lam (ValBinder _) _) = True
-manifestlyWHNF (Lam other_binder  e) = manifestlyWHNF e
+manifestlyWHNF (Lam x e)  = if isValBinder x then True else manifestlyWHNF e
 
 manifestlyWHNF other_expr   -- look for manifest partial application
 
 manifestlyWHNF other_expr   -- look for manifest partial application
-  = case (collectArgs other_expr) of { (fun, args) ->
+  = case (collectArgs other_expr) of { (fun, _, _, vargs) ->
     case fun of
       Var f ->  let
     case fun of
       Var f ->  let
-                   num_val_args = numValArgs args
+                   num_val_args = length vargs
                in
                num_val_args == 0 -- Just a type application of
                                  -- a variable (f t1 t2 t3);
                in
                num_val_args == 0 -- Just a type application of
                                  -- a variable (f t1 t2 t3);
@@ -317,8 +316,7 @@ manifestlyBottom (SCC _ e)   = manifestlyBottom e
 manifestlyBottom (Let _ e)   = manifestlyBottom e
 
   -- We do not assume \x.bottom == bottom:
 manifestlyBottom (Let _ e)   = manifestlyBottom e
 
   -- We do not assume \x.bottom == bottom:
-manifestlyBottom (Lam (ValBinder _) _) = False
-manifestlyBottom (Lam other_binder  e) = manifestlyBottom e
+manifestlyBottom (Lam x e) = if isValBinder x then False else manifestlyBottom e
 
 manifestlyBottom (Case e a)
   = manifestlyBottom e
 
 manifestlyBottom (Case e a)
   = manifestlyBottom e
@@ -335,7 +333,7 @@ manifestlyBottom (Case e a)
     mbdef (BindDefault _ e') = manifestlyBottom e'
 
 manifestlyBottom other_expr   -- look for manifest partial application
     mbdef (BindDefault _ e') = manifestlyBottom e'
 
 manifestlyBottom other_expr   -- look for manifest partial application
-  = case (collectArgs other_expr) of { (fun, args) ->
+  = case (collectArgs other_expr) of { (fun, _, _, _) ->
     case fun of
       Var f | isBottomingId f -> True
                -- Application of a function which always gives
     case fun of
       Var f | isBottomingId f -> True
                -- Application of a function which always gives
@@ -389,11 +387,11 @@ expr `isWrapperFor` var
 
     --------------
     unravel_casing case_ables (Case scrut alts)
 
     --------------
     unravel_casing case_ables (Case scrut alts)
-      = case (collectArgs scrut) of { (fun, args) ->
+      = case (collectArgs scrut) of { (fun, _, _, vargs) ->
        case fun of
          Var scrut_var -> let
                                answer =
        case fun of
          Var scrut_var -> let
                                answer =
-                                    scrut_var /= var && all (doesn't_mention var) args
+                                    scrut_var /= var && all (doesn't_mention var) vargs
                                  && scrut_var `is_elem` case_ables
                                  && unravel_alts case_ables alts
                             in
                                  && scrut_var `is_elem` case_ables
                                  && unravel_alts case_ables alts
                             in
@@ -403,15 +401,15 @@ expr `isWrapperFor` var
        }
 
     unravel_casing case_ables other_expr
        }
 
     unravel_casing case_ables other_expr
-      = case (collectArgs other_expr) of { (fun, args) ->
+      = case (collectArgs other_expr) of { (fun, _, _, vargs) ->
        case fun of
          Var wrkr -> let
                            answer =
                                -- DOESN'T WORK: wrkr == var's_worker
                                wrkr /= var
                             && isWorkerId wrkr
        case fun of
          Var wrkr -> let
                            answer =
                                -- DOESN'T WORK: wrkr == var's_worker
                                wrkr /= var
                             && isWorkerId wrkr
-                            && all (doesn't_mention var)  args
-                            && all (only_from case_ables) args
+                            && all (doesn't_mention var)  vargs
+                            && all (only_from case_ables) vargs
                        in
                        answer
 
                        in
                        answer
 
@@ -508,23 +506,24 @@ Example:
 Notice that the \tr{<alts>} don't get duplicated.
 
 \begin{code}
 Notice that the \tr{<alts>} don't get duplicated.
 
 \begin{code}
-{- LATER:
-nonErrorRHSs :: GenCoreCaseAlts binder Id -> [GenCoreExpr binder Id]
+nonErrorRHSs :: GenCoreCaseAlts a Id TyVar UVar -> [GenCoreExpr a Id TyVar UVar]
 
 
-nonErrorRHSs alts = filter not_error_app (find_rhss alts)
+nonErrorRHSs alts
+  = filter not_error_app (find_rhss alts)
   where
   where
-    find_rhss (AlgAlts  alts deflt) = [rhs | (_,_,rhs) <- alts] ++ deflt_rhs deflt
-    find_rhss (PrimAlts alts deflt) = [rhs | (_,rhs)   <- alts] ++ deflt_rhs deflt
+    find_rhss (AlgAlts  as deflt) = [rhs | (_,_,rhs) <- as] ++ deflt_rhs deflt
+    find_rhss (PrimAlts as deflt) = [rhs | (_,rhs)   <- as] ++ deflt_rhs deflt
 
     deflt_rhs NoDefault           = []
     deflt_rhs (BindDefault _ rhs) = [rhs]
 
 
     deflt_rhs NoDefault           = []
     deflt_rhs (BindDefault _ rhs) = [rhs]
 
-    not_error_app rhs = case maybeErrorApp rhs Nothing of
-                        Just _  -> False
-                        Nothing -> True
+    not_error_app rhs
+      = case (maybeErrorApp rhs Nothing) of
+         Just _  -> False
+         Nothing -> True
 \end{code}
 
 \end{code}
 
-maybeErrorApp checkes whether an expression is of the form
+maybeErrorApp checks whether an expression is of the form
 
        error ty args
 
 
        error ty args
 
@@ -540,24 +539,24 @@ Here's where it is useful:
  ===>
                error ty' "Foo"
 
  ===>
                error ty' "Foo"
 
-where ty' is the type of any of the alternatives.
-You might think this never occurs, but see the comments on
-the definition of @singleAlt@.
+where ty' is the type of any of the alternatives.  You might think
+this never occurs, but see the comments on the definition of
+@singleAlt@.
 
 
-Note: we *avoid* the case where ty' might end up as a
-primitive type: this is very uncool (totally wrong).
+Note: we *avoid* the case where ty' might end up as a primitive type:
+this is very uncool (totally wrong).
 
 
-NOTICE: in the example above we threw away e1 and e2, but
-not the string "Foo".  How did we know to do that?
+NOTICE: in the example above we threw away e1 and e2, but not the
+string "Foo".  How did we know to do that?
 
 
-Answer: for now anyway, we only handle the case of a function
-whose type is of form
+Answer: for now anyway, we only handle the case of a function whose
+type is of form
 
        bottomingFn :: forall a. t1 -> ... -> tn -> a
                              ^---------------------^ NB!
 
 
        bottomingFn :: forall a. t1 -> ... -> tn -> a
                              ^---------------------^ NB!
 
-Furthermore, we only count a bottomingApp if the function is
-applied to more than n args.  If so, we transform:
+Furthermore, we only count a bottomingApp if the function is applied
+to more than n args.  If so, we transform:
 
        bottomingFn ty e1 ... en en+1 ... em
 to
 
        bottomingFn ty e1 ... en en+1 ... em
 to
@@ -566,47 +565,47 @@ to
 That is, we discard en+1 .. em
 
 \begin{code}
 That is, we discard en+1 .. em
 
 \begin{code}
-maybeErrorApp :: GenCoreExpr bndr Id   -- Expr to look at
-             -> Maybe Type         -- Just ty => a result type *already cloned*;
-                                   -- Nothing => don't know result ty; we
-                                   -- *pretend* that the result ty won't be
-                                   -- primitive -- somebody later must
-                                   -- ensure this.
-              -> Maybe (GenCoreExpr bndr Id)
+maybeErrorApp
+       :: GenCoreExpr a Id TyVar UVar  -- Expr to look at
+       -> Maybe Type                   -- Just ty => a result type *already cloned*;
+                                       -- Nothing => don't know result ty; we
+                                       -- *pretend* that the result ty won't be
+                                       -- primitive -- somebody later must
+                                       -- ensure this.
+       -> Maybe (GenCoreExpr a Id TyVar UVar)
 
 maybeErrorApp expr result_ty_maybe
 
 maybeErrorApp expr result_ty_maybe
-  = case collectArgs expr of
-      (Var fun, (TypeArg ty : other_args))
+  = case (collectArgs expr) of
+      (Var fun, [{-no usage???-}], [ty], other_args)
        | isBottomingId fun
        && maybeToBool result_ty_maybe -- we *know* the result type
                                       -- (otherwise: live a fairy-tale existence...)
        && not (isPrimType result_ty) ->
        | isBottomingId fun
        && maybeToBool result_ty_maybe -- we *know* the result type
                                       -- (otherwise: live a fairy-tale existence...)
        && not (isPrimType result_ty) ->
-       case splitSigmaTy (idType fun) of
-         ([tyvar_tmpl], [], tau_ty) ->
-             case (splitTyArgs tau_ty) of { (arg_tys, res_ty) ->
+
+       case (splitSigmaTy (idType fun)) of
+         ([tyvar], [], tau_ty) ->
+             case (splitFunTy tau_ty) of { (arg_tys, res_ty) ->
              let
                  n_args_to_keep = length arg_tys
                  args_to_keep   = take n_args_to_keep other_args
              in
              let
                  n_args_to_keep = length arg_tys
                  args_to_keep   = take n_args_to_keep other_args
              in
-             if  res_ty == mkTyVarTemplateTy tyvar_tmpl &&
-                 n_args_to_keep <= length other_args
+             if  (res_ty `eqTy` mkTyVarTy tyvar)
+              && n_args_to_keep <= length other_args
              then
                    -- Phew!  We're in business
              then
                    -- Phew!  We're in business
-                 Just (mkGenApp (Var fun)
-                             (TypeArg result_ty : args_to_keep))
+                 Just (mkGenApp (Var fun) (TyArg result_ty : args_to_keep))
              else
                  Nothing
              }
 
              else
                  Nothing
              }
 
-         other ->      -- Function type wrong shape
-                   Nothing
+         other -> Nothing  -- Function type wrong shape
       other -> Nothing
   where
     Just result_ty = result_ty_maybe
 \end{code}
 
 \begin{code}
       other -> Nothing
   where
     Just result_ty = result_ty_maybe
 \end{code}
 
 \begin{code}
-squashableDictishCcExpr :: CostCentre -> GenCoreExpr a b -> Bool
+squashableDictishCcExpr :: CostCentre -> GenCoreExpr a b c d -> Bool
 
 squashableDictishCcExpr cc expr
   = if not (isDictCC cc) then
 
 squashableDictishCcExpr cc expr
   = if not (isDictCC cc) then
@@ -615,11 +614,11 @@ squashableDictishCcExpr cc expr
        squashable expr -- note: quite like the "atomic_rhs" stuff in simplifier
   where
     squashable (Var _)      = True
        squashable expr -- note: quite like the "atomic_rhs" stuff in simplifier
   where
     squashable (Var _)      = True
-    squashable (CoTyApp f _)  = squashable f
-    squashable (Con _ _ _)  = True -- I think so... WDP 94/09
-    squashable (Prim _ _ _) = True -- ditto
-    squashable other         = False
--}
+    squashable (Con  _ _)   = True -- I think so... WDP 94/09
+    squashable (Prim _ _)   = True -- ditto
+    squashable (App f a)
+      | notValArg a        = squashable f
+    squashable other       = False
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -629,14 +628,25 @@ squashableDictishCcExpr cc expr
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
+substCoreBindings :: ValEnv
+               -> TypeEnv -- TyVar=>Type
+               -> [CoreBinding]
+               -> UniqSM [CoreBinding]
+
 substCoreExpr  :: ValEnv
                -> TypeEnv -- TyVar=>Type
                -> CoreExpr
                -> UniqSM CoreExpr
 
 substCoreExpr  :: ValEnv
                -> TypeEnv -- TyVar=>Type
                -> CoreExpr
                -> UniqSM CoreExpr
 
-substCoreExpr venv tenv expr
+substCoreBindings venv tenv binds
   -- if the envs are empty, then avoid doing anything
   = if (isNullIdEnv venv && isNullTyVarEnv tenv) then
   -- if the envs are empty, then avoid doing anything
   = if (isNullIdEnv venv && isNullTyVarEnv tenv) then
+       returnUs binds
+    else
+       do_CoreBindings venv tenv binds
+
+substCoreExpr venv tenv expr
+  = if (isNullIdEnv venv && isNullTyVarEnv tenv) then
        returnUs expr
     else
        do_CoreExpr venv tenv expr
        returnUs expr
     else
        do_CoreExpr venv tenv expr
index 8879ffe..8703b34 100644 (file)
@@ -26,14 +26,14 @@ import AnnCoreSyn   -- output
 
 import CoreSyn
 import Id              ( idType, getIdArity, isBottomingId,
 
 import CoreSyn
 import Id              ( idType, getIdArity, isBottomingId,
-                         emptyIdSet, singletonIdSet, mkIdSet,
+                         emptyIdSet, unitIdSet, mkIdSet,
                          elementOfIdSet, minusIdSet, unionManyIdSets,
                          IdSet(..)
                        )
 import IdInfo          ( arityMaybe )
 import PrimOp          ( PrimOp(..) )
 import Type            ( tyVarsOfType )
                          elementOfIdSet, minusIdSet, unionManyIdSets,
                          IdSet(..)
                        )
 import IdInfo          ( arityMaybe )
 import PrimOp          ( PrimOp(..) )
 import Type            ( tyVarsOfType )
-import TyVar           ( emptyTyVarSet, singletonTyVarSet, minusTyVarSet,
+import TyVar           ( emptyTyVarSet, unitTyVarSet, minusTyVarSet,
                          intersectTyVarSets,
                          TyVarSet(..)
                        )
                          intersectTyVarSets,
                          TyVarSet(..)
                        )
@@ -74,8 +74,8 @@ data FVInfo
 noFreeIds      = emptyIdSet
 noFreeTyVars   = emptyTyVarSet
 noFreeAnything = (noFreeIds, noFreeTyVars)
 noFreeIds      = emptyIdSet
 noFreeTyVars   = emptyTyVarSet
 noFreeAnything = (noFreeIds, noFreeTyVars)
-aFreeId i      = singletonIdSet i
-aFreeTyVar t   = singletonTyVarSet t
+aFreeId i      = unitIdSet i
+aFreeTyVar t   = unitTyVarSet t
 is_among       = elementOfIdSet
 munge_id_ty  i = tyVarsOfType (idType i)
 combine               = unionUniqSets -- used both for {Id,TyVar}Sets
 is_among       = elementOfIdSet
 munge_id_ty  i = tyVarsOfType (idType i)
 combine               = unionUniqSets -- used both for {Id,TyVar}Sets
@@ -171,13 +171,13 @@ fvExpr id_cands tyvar_cands (Lam (UsageBinder uvar) body)
   = panic "fvExpr:Lam UsageBinder"
 
 fvExpr id_cands tyvar_cands (Lam b@(ValBinder binder) body)
   = panic "fvExpr:Lam UsageBinder"
 
 fvExpr id_cands tyvar_cands (Lam b@(ValBinder binder) body)
-  = (FVInfo (freeVarsOf body2   `minusIdSet` singletonIdSet binder)
+  = (FVInfo (freeVarsOf body2   `minusIdSet` unitIdSet binder)
            (freeTyVarsOf body2 `combine`    munge_id_ty binder)
            leakiness,
      AnnLam b body2)
   where
        -- We need to collect free tyvars from the binders
            (freeTyVarsOf body2 `combine`    munge_id_ty binder)
            leakiness,
      AnnLam b body2)
   where
        -- We need to collect free tyvars from the binders
-    body2 = fvExpr (singletonIdSet binder `combine` id_cands) tyvar_cands body
+    body2 = fvExpr (unitIdSet binder `combine` id_cands) tyvar_cands body
 
     leakiness = case leakinessOf body2 of
                  MightLeak  -> LeakFree 1
 
     leakiness = case leakinessOf body2 of
                  MightLeak  -> LeakFree 1
@@ -412,7 +412,7 @@ addExprFVs fv_cand in_scope (Lam binder body)
          TyBinder    t -> (TyBinder t, emptyIdSet)
          UsageBinder u -> (UsageBinder u, emptyIdSet)
           ValBinder   b -> (ValBinder (b, lam_fvs),
          TyBinder    t -> (TyBinder t, emptyIdSet)
          UsageBinder u -> (UsageBinder u, emptyIdSet)
           ValBinder   b -> (ValBinder (b, lam_fvs),
-                           singletonIdSet b)
+                           unitIdSet b)
 
     new_in_scope        = in_scope `combine` binder_set
     (new_body, body_fvs) = addExprFVs fv_cand new_in_scope body
 
     new_in_scope        = in_scope `combine` binder_set
     (new_body, body_fvs) = addExprFVs fv_cand new_in_scope body
index 770e9bf..4a503e4 100644 (file)
@@ -14,8 +14,7 @@ module PprCore (
        pprCoreExpr,
        pprCoreBinding,
        pprBigCoreBinder,
        pprCoreExpr,
        pprCoreBinding,
        pprBigCoreBinder,
-       pprTypedCoreBinder,
-       pprPlainCoreBinding
+       pprTypedCoreBinder
        
        -- these are here to make the instances go in 0.26:
 #if __GLASGOW_HASKELL__ <= 26
        
        -- these are here to make the instances go in 0.26:
 #if __GLASGOW_HASKELL__ <= 26
@@ -34,9 +33,8 @@ import Id             ( idType, getIdInfo, getIdStrictness,
 import IdInfo          ( ppIdInfo, StrictnessInfo(..) )
 import Literal         ( Literal{-instances-} )
 import Outputable      -- quite a few things
 import IdInfo          ( ppIdInfo, StrictnessInfo(..) )
 import Literal         ( Literal{-instances-} )
 import Outputable      -- quite a few things
-import PprType         ( pprType_Internal,
-                         GenType{-instances-}, GenTyVar{-instance-}
-                       )
+import PprEnv
+import PprType         ( GenType{-instances-}, GenTyVar{-instance-} )
 import PprStyle                ( PprStyle(..) )
 import Pretty
 import PrimOp          ( PrimOp{-instances-} )
 import PprStyle                ( PprStyle(..) )
 import Pretty
 import PrimOp          ( PrimOp{-instances-} )
@@ -58,7 +56,7 @@ function for ``major'' val_bdrs (those next to equal signs :-),
 usually be called through some intermediary.
 
 The binder/occ printers take the default ``homogenized'' (see
 usually be called through some intermediary.
 
 The binder/occ printers take the default ``homogenized'' (see
-@PrintEnv@...) @Pretty@ and the binder/occ.  They can either use the
+@PprEnv@...) @Pretty@ and the binder/occ.  They can either use the
 homogenized one, or they can ignore it completely.  In other words,
 the things passed in act as ``hooks'', getting the last word on how to
 print something.
 homogenized one, or they can ignore it completely.  In other words,
 the things passed in act as ``hooks'', getting the last word on how to
 print something.
@@ -66,9 +64,9 @@ print something.
 @pprParendCoreExpr@ puts parens around non-atomic Core expressions.
 
 \begin{code}
 @pprParendCoreExpr@ puts parens around non-atomic Core expressions.
 
 \begin{code}
-pprPlainCoreBinding :: PprStyle -> CoreBinding -> Pretty
+pprCoreBinding :: PprStyle -> CoreBinding -> Pretty
 
 
-pprCoreBinding
+pprGenCoreBinding
        :: (Eq tyvar, Outputable tyvar,
            Eq uvar,  Outputable uvar,
            Outputable bndr,
        :: (Eq tyvar, Outputable tyvar,
            Eq uvar,  Outputable uvar,
            Outputable bndr,
@@ -80,14 +78,27 @@ pprCoreBinding
        -> GenCoreBinding bndr occ tyvar uvar
        -> Pretty
 
        -> GenCoreBinding bndr occ tyvar uvar
        -> Pretty
 
-pprCoreBinding sty pbdr1 pbdr2 pocc bind
-  = ppr_bind (initial_pe sty (Left (pbdr1, pbdr2, pocc))) bind
-
-pprPlainCoreBinding sty (NonRec binder expr)
+pprGenCoreBinding sty pbdr1 pbdr2 pocc bind
+  = ppr_bind (init_ppr_env sty pbdr1 pbdr2 pocc) bind
+
+init_ppr_env sty pbdr1 pbdr2 pocc
+  = initPprEnv sty
+       (Just (ppr sty)) -- literals
+       (Just (ppr sty)) -- data cons
+       (Just (ppr sty)) -- primops
+       (Just (\ cc -> ppStr (showCostCentre sty True cc)))
+       (Just (ppr sty)) -- tyvars
+       (Just (ppr sty)) -- usage vars
+       (Just pbdr1) (Just pbdr2) (Just pocc) -- value vars
+       (Just (ppr sty)) -- types
+       (Just (ppr sty)) -- usages
+
+--------------
+pprCoreBinding sty (NonRec binder expr)
   = ppHang (ppCat [pprBigCoreBinder sty binder, ppEquals])
         4 (pprCoreExpr sty (pprBigCoreBinder sty) (pprBabyCoreBinder sty) (ppr sty) expr)
 
   = ppHang (ppCat [pprBigCoreBinder sty binder, ppEquals])
         4 (pprCoreExpr sty (pprBigCoreBinder sty) (pprBabyCoreBinder sty) (ppr sty) expr)
 
-pprPlainCoreBinding sty (Rec binds)
+pprCoreBinding sty (Rec binds)
   = ppAboves [ifPprDebug sty (ppStr "{- plain Rec -}"),
              ppAboves (map ppr_bind binds),
              ifPprDebug sty (ppStr "{- end plain Rec -}")]
   = ppAboves [ifPprDebug sty (ppStr "{- plain Rec -}"),
              ppAboves (map ppr_bind binds),
              ifPprDebug sty (ppStr "{- end plain Rec -}")]
@@ -98,7 +109,16 @@ pprPlainCoreBinding sty (Rec binds)
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-pprCoreExpr, pprParendCoreExpr
+pprCoreExpr
+       :: PprStyle
+       -> (Id -> Pretty) -- to print "major" val_bdrs
+       -> (Id -> Pretty) -- to print "minor" val_bdrs
+       -> (Id  -> Pretty) -- to print bindees
+       -> CoreExpr
+       -> Pretty
+pprCoreExpr = pprGenCoreExpr
+
+pprGenCoreExpr, pprParendCoreExpr
        :: (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar,
            Outputable bndr,
            Outputable occ)
        :: (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar,
            Outputable bndr,
            Outputable occ)
@@ -109,8 +129,8 @@ pprCoreExpr, pprParendCoreExpr
        -> GenCoreExpr bndr occ tyvar uvar
        -> Pretty
 
        -> GenCoreExpr bndr occ tyvar uvar
        -> Pretty
 
-pprCoreExpr sty pbdr1 pbdr2 pocc expr
-  = ppr_expr (initial_pe sty (Left (pbdr1, pbdr2, pocc))) expr
+pprGenCoreExpr sty pbdr1 pbdr2 pocc expr
+  = ppr_expr (init_ppr_env sty pbdr1 pbdr2 pocc) expr
 
 pprParendCoreExpr sty pbdr1 pbdr2 pocc expr
   = let
 
 pprParendCoreExpr sty pbdr1 pbdr2 pocc expr
   = let
@@ -120,16 +140,16 @@ pprParendCoreExpr sty pbdr1 pbdr2 pocc expr
              Lit _ -> id
              _     -> ppParens -- wraps in parens
     in
              Lit _ -> id
              _     -> ppParens -- wraps in parens
     in
-    parenify (pprCoreExpr sty pbdr1 pbdr2 pocc expr)
+    parenify (pprGenCoreExpr sty pbdr1 pbdr2 pocc expr)
 
 ppr_core_arg sty pocc arg
 
 ppr_core_arg sty pocc arg
-  = ppr_arg (initial_pe sty (Left (pocc, pocc, pocc))) arg
+  = ppr_arg (init_ppr_env sty pocc pocc pocc) arg
 
 ppr_core_alts sty pbdr1 pbdr2 pocc alts
 
 ppr_core_alts sty pbdr1 pbdr2 pocc alts
-  = ppr_alts (initial_pe sty (Left (pbdr1, pbdr2, pocc))) alts
+  = ppr_alts (init_ppr_env sty pbdr1 pbdr2 pocc) alts
 
 ppr_core_default sty pbdr1 pbdr2 pocc deflt
 
 ppr_core_default sty pbdr1 pbdr2 pocc deflt
-  = ppr_default (initial_pe sty (Left (pbdr1, pbdr2, pocc))) deflt
+  = ppr_default (init_ppr_env sty pbdr1 pbdr2 pocc) deflt
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -144,14 +164,14 @@ instance
    Eq uvar, Outputable uvar)
  =>
   Outputable (GenCoreBinding bndr occ tyvar uvar) where
    Eq uvar, Outputable uvar)
  =>
   Outputable (GenCoreBinding bndr occ tyvar uvar) where
-    ppr sty bind = pprCoreBinding sty (ppr sty) (ppr sty) (ppr sty) bind
+    ppr sty bind = pprGenCoreBinding sty (ppr sty) (ppr sty) (ppr sty) bind
 
 instance
   (Outputable bndr, Outputable occ, Eq tyvar, Outputable tyvar,
    Eq uvar, Outputable uvar)
  =>
   Outputable (GenCoreExpr bndr occ tyvar uvar) where
 
 instance
   (Outputable bndr, Outputable occ, Eq tyvar, Outputable tyvar,
    Eq uvar, Outputable uvar)
  =>
   Outputable (GenCoreExpr bndr occ tyvar uvar) where
-    ppr sty expr = pprCoreExpr sty (ppr sty) (ppr sty) (ppr sty) expr
+    ppr sty expr = pprGenCoreExpr sty (ppr sty) (ppr sty) (ppr sty) expr
 
 instance
   (Outputable occ, Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar)
 
 instance
   (Outputable occ, Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar)
@@ -176,126 +196,13 @@ instance
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
-\subsection{Core printing environment (purely local)}
-%*                                                                     *
-%************************************************************************
-
-Similar to @VE@ in @PprType@.  The ``values'' we print here
-are locally-defined nested-scope names; callers to @pprCoreBinding@,
-etc., can override these.
-
-For tyvars and uvars, we {\em do} normally use these homogenized
-names; for values, we {\em don't}.  In printing interfaces, though,
-we use homogenized value names, so that interfaces don't wobble
-uncontrollably from changing Unique-based names.
-
-\begin{code}
-data PrintEnv tyvar uvar bndr occ
-  = PE (Literal -> Pretty)     -- Doing these this way saves
-       (DataCon -> Pretty)     -- carrying around a PprStyle
-       (PrimOp  -> Pretty)
-       (CostCentre -> Pretty)
-
-       [Pretty]                -- Tyvar pretty names
-       (tyvar -> Pretty)       -- Tyvar lookup function
-        [Pretty]               -- Uvar  pretty names
-       (uvar -> Pretty)        -- Uvar  lookup function
-
-       (GenType tyvar uvar -> Pretty)
-       (GenUsage uvar -> Pretty)
-
-       (ValPrinters bndr occ)
-
-data ValPrinters bndr occ
-  = BOPE -- print binders/occs differently
-        (bndr -> Pretty)       -- to print "major" val_bdrs
-        (bndr -> Pretty)       -- to print "minor" val_bdrs
-        (occ  -> Pretty)       -- to print bindees
-
-  | VPE  -- print all values the same way
-        [Pretty]               -- Value pretty names
-        (bndr -> Pretty)       -- Binder lookup function
-        (occ  -> Pretty)       -- Occurrence lookup function
-\end{code}
-
-\begin{code}
-initial_pe :: (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar,
-              Outputable bndr, Outputable occ)
-          => PprStyle
-          -> Either
-               (bndr -> Pretty, bndr -> Pretty, occ -> Pretty)
-               ()
-          -> PrintEnv tyvar uvar bndr occ
-
-initial_pe sty val_printing
-  = PE (ppr sty)   -- for a Literal
-       (ppr sty)   -- for a DataCon
-       (ppr sty)   -- for a PrimOp
-       (\ cc -> ppStr (showCostCentre sty True cc)) -- CostCentre
-
-       tv_pretties ppr_tv -- for a TyVar
-        uv_pretties ppr_uv -- for a UsageVar
-
-       (\ ty -> pprType_Internal sty tv_pretties ppr_tv uv_pretties ppr_uv ty)
-       (ppr sty) -- for a Usage
-
-       val_printing_stuff
-  where
-    ppr_tv = ppr sty -- to print a tyvar
-    ppr_uv = ppr sty -- to print a uvar
-
-    tv_pretties = map (\ c -> ppChar c ) ['a' .. 'h']
-                 ++
-                 map (\ n -> ppBeside (ppChar 'a') (ppInt n))
-                     ([0 .. ] :: [Int])        -- a0 ... aN
-    
-    uv_pretties = map (\ c -> ppChar c ) ['u' .. 'y']
-                 ++
-                 map (\ n -> ppBeside (ppChar 'u') (ppInt n))
-                     ([0 .. ] :: [Int])        -- u0 ... uN
-    
-    val_pretties = map (\ c -> ppChar c ) ['i' .. 'k']
-               ++ map (\ n -> ppBeside (ppChar 'v') (ppInt n))
-                      ([0 .. ] :: [Int])       -- v0 ... vN
-
-    ------------------------
-    val_printing_stuff
-      = case val_printing of
-         Left  (pbdr1, pbdr2, pocc) -> BOPE pbdr1 pbdr2 pocc
-         Right () -> VPE val_pretties (ppr sty) (ppr sty)
-
-\end{code}
-
-\begin{code}
-plit    (PE pp  _  _  _ _  _ _  _  _  _ _) = pp
-pcon    (PE  _ pp  _  _ _  _ _  _  _  _ _) = pp
-pprim   (PE  _  _ pp  _ _  _ _  _  _  _ _) = pp
-pscc    (PE  _  _  _ pp _  _ _  _  _  _ _) = pp
-ptyvar  (PE  _  _  _  _ _ pp _  _  _  _ _) = pp
-puvar   (PE  _  _  _  _ _  _ _ pp  _  _ _) = pp
-  
-pty     (PE  _  _  _  _ _  _ _  _ pp  _ _) = pp
-puse    (PE  _  _  _  _ _  _ _  _  _ pp _) = pp
-
-pmaj_bdr (PE  _  _  _  _ _  _ _  _  _  _ (BOPE pp _ _)) = pp
-pmaj_bdr (PE  _  _  _  _ _  _ _  _  _  _ (VPE  _ pp _)) = pp
-                                  
-pmin_bdr (PE  _  _  _  _ _  _ _  _  _  _ (BOPE _ pp _)) = pp
-pmin_bdr (PE  _  _  _  _ _  _ _  _  _  _ (VPE  _ pp _)) = pp
-                                  
-pocc    (PE  _  _  _  _ _  _ _  _  _  _ (BOPE _ _ pp)) = pp
-pocc    (PE  _  _  _  _ _  _ _  _  _  _ (VPE  _ _ pp)) = pp
-\end{code}
-
-%************************************************************************
-%*                                                                     *
 \subsection{Workhorse routines (...????...)}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
 ppr_bind pe (NonRec val_bdr expr)
 \subsection{Workhorse routines (...????...)}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
 ppr_bind pe (NonRec val_bdr expr)
-  = ppHang (ppCat [pmaj_bdr pe val_bdr, ppEquals])
+  = ppHang (ppCat [pMajBndr pe val_bdr, ppEquals])
         4 (ppr_expr pe expr)
 
 ppr_bind pe (Rec binds)
         4 (ppr_expr pe expr)
 
 ppr_bind pe (Rec binds)
@@ -304,7 +211,7 @@ ppr_bind pe (Rec binds)
               ppStr "{- end Rec -}" ]
   where
     ppr_pair (val_bdr, expr)
               ppStr "{- end Rec -}" ]
   where
     ppr_pair (val_bdr, expr)
-      = ppHang (ppCat [pmaj_bdr pe val_bdr, ppEquals])
+      = ppHang (ppCat [pMajBndr pe val_bdr, ppEquals])
             4 (ppr_expr pe expr)
 \end{code}
 
             4 (ppr_expr pe expr)
 \end{code}
 
@@ -321,25 +228,25 @@ ppr_parend_expr pe expr
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-ppr_expr pe (Var name)   = pocc pe name
-ppr_expr pe (Lit lit)    = plit pe lit
-ppr_expr pe (Con con []) = pcon pe con
+ppr_expr pe (Var name)   = pOcc pe name
+ppr_expr pe (Lit lit)    = pLit pe lit
+ppr_expr pe (Con con []) = pCon pe con
 
 ppr_expr pe (Con con args)
 
 ppr_expr pe (Con con args)
-  = ppHang (ppBesides [pcon pe con, ppChar '!'])
+  = ppHang (ppBesides [pCon pe con, ppChar '!'])
         4 (ppSep (map (ppr_arg pe) args))
 
 ppr_expr pe (Prim prim args)
         4 (ppSep (map (ppr_arg pe) args))
 
 ppr_expr pe (Prim prim args)
-  = ppHang (ppBesides [pprim pe prim, ppChar '!'])
+  = ppHang (ppBesides [pPrim pe prim, ppChar '!'])
         4 (ppSep (map (ppr_arg pe) args))
 
 ppr_expr pe expr@(Lam _ _)
   = let
        (uvars, tyvars, vars, body) = collectBinders expr
     in
         4 (ppSep (map (ppr_arg pe) args))
 
 ppr_expr pe expr@(Lam _ _)
   = let
        (uvars, tyvars, vars, body) = collectBinders expr
     in
-    ppHang (ppCat [pp_vars SLIT("_/u\\_") (puvar    pe) uvars,
-                  pp_vars SLIT("_/\\_")  (ptyvar   pe) tyvars,
-                  pp_vars SLIT("\\")     (pmin_bdr pe) vars])
+    ppHang (ppCat [pp_vars SLIT("_/u\\_") (pUVar    pe) uvars,
+                  pp_vars SLIT("_/\\_")  (pTyVar   pe) tyvars,
+                  pp_vars SLIT("\\")     (pMinBndr pe) vars])
         4 (ppr_expr pe body)
   where
     pp_vars lam pp [] = ppNil
         4 (ppr_expr pe body)
   where
     pp_vars lam pp [] = ppNil
@@ -348,10 +255,13 @@ ppr_expr pe expr@(Lam _ _)
 
 ppr_expr pe expr@(App _ _)
   = let
 
 ppr_expr pe expr@(App _ _)
   = let
-       (fun, args) = collectArgs expr
+       (fun, uargs, targs, vargs) = collectArgs expr
     in
     ppHang (ppr_parend_expr pe fun)
     in
     ppHang (ppr_parend_expr pe fun)
-        4 (ppSep (map (ppr_arg pe) args))
+        4 (ppSep [ ppInterleave ppNil (map (pUse    pe) uargs)
+                 , ppInterleave ppNil (map (pTy     pe) targs)
+                 , ppInterleave ppNil (map (ppr_arg pe) vargs)
+                 ])
 
 ppr_expr pe (Case expr alts)
   = ppSep
 
 ppr_expr pe (Case expr alts)
   = ppSep
@@ -364,7 +274,7 @@ ppr_expr pe (Case expr alts)
 
 ppr_expr pe (Let bind@(NonRec val_bdr rhs@(Let _ _)) body)
   = ppAboves [
 
 ppr_expr pe (Let bind@(NonRec val_bdr rhs@(Let _ _)) body)
   = ppAboves [
-      ppCat [ppStr "let {", pmaj_bdr pe val_bdr, ppEquals],
+      ppCat [ppStr "let {", pMajBndr pe val_bdr, ppEquals],
       ppNest 2 (ppr_expr pe rhs),
       ppStr "} in",
       ppr_expr pe body ]
       ppNest 2 (ppr_expr pe rhs),
       ppStr "} in",
       ppr_expr pe body ]
@@ -372,7 +282,7 @@ ppr_expr pe (Let bind@(NonRec val_bdr rhs@(Let _ _)) body)
 ppr_expr pe (Let bind@(NonRec val_bdr rhs) expr@(Let _ _))
   = ppAbove
       (ppHang (ppStr "let {")
 ppr_expr pe (Let bind@(NonRec val_bdr rhs) expr@(Let _ _))
   = ppAbove
       (ppHang (ppStr "let {")
-           2 (ppCat [ppHang (ppCat [pmaj_bdr pe val_bdr, ppEquals])
+           2 (ppCat [ppHang (ppCat [pMajBndr pe val_bdr, ppEquals])
                           4 (ppr_expr pe rhs),
        ppStr "} in"]))
       (ppr_expr pe expr)
                           4 (ppr_expr pe rhs),
        ppStr "} in"]))
       (ppr_expr pe expr)
@@ -383,7 +293,7 @@ ppr_expr pe (Let bind expr)
           ppHang (ppStr "} in ") 2 (ppr_expr pe expr)]
 
 ppr_expr pe (SCC cc expr)
           ppHang (ppStr "} in ") 2 (ppr_expr pe expr)]
 
 ppr_expr pe (SCC cc expr)
-  = ppSep [ppCat [ppPStr SLIT("_scc_"), pscc pe cc],
+  = ppSep [ppCat [ppPStr SLIT("_scc_"), pSCC pe cc],
           ppr_parend_expr pe expr ]
 \end{code}
 
           ppr_parend_expr pe expr ]
 \end{code}
 
@@ -392,8 +302,8 @@ ppr_alts pe (AlgAlts alts deflt)
   = ppAboves [ ppAboves (map ppr_alt alts), ppr_default pe deflt ]
   where
     ppr_alt (con, params, expr)
   = ppAboves [ ppAboves (map ppr_alt alts), ppr_default pe deflt ]
   where
     ppr_alt (con, params, expr)
-      = ppHang (ppCat [ppr_con con (pcon pe con),
-                      ppInterleave ppSP (map (pmin_bdr pe) params),
+      = ppHang (ppCat [ppr_con con (pCon pe con),
+                      ppInterleave ppSP (map (pMinBndr pe) params),
                       ppStr "->"])
             4 (ppr_expr pe expr)
       where
                       ppStr "->"])
             4 (ppr_expr pe expr)
       where
@@ -404,7 +314,7 @@ ppr_alts pe (PrimAlts alts deflt)
   = ppAboves [ ppAboves (map ppr_alt alts), ppr_default pe deflt ]
   where
     ppr_alt (lit, expr)
   = ppAboves [ ppAboves (map ppr_alt alts), ppr_default pe deflt ]
   where
     ppr_alt (lit, expr)
-      = ppHang (ppCat [plit pe lit, ppStr "->"])
+      = ppHang (ppCat [pLit pe lit, ppStr "->"])
             4 (ppr_expr pe expr)
 \end{code}
 
             4 (ppr_expr pe expr)
 \end{code}
 
@@ -412,15 +322,15 @@ ppr_alts pe (PrimAlts alts deflt)
 ppr_default pe NoDefault = ppNil
 
 ppr_default pe (BindDefault val_bdr expr)
 ppr_default pe NoDefault = ppNil
 
 ppr_default pe (BindDefault val_bdr expr)
-  = ppHang (ppCat [pmin_bdr pe val_bdr, ppStr "->"])
+  = ppHang (ppCat [pMinBndr pe val_bdr, ppStr "->"])
         4 (ppr_expr pe expr)
 \end{code}
 
 \begin{code}
         4 (ppr_expr pe expr)
 \end{code}
 
 \begin{code}
-ppr_arg pe (LitArg   lit) = plit pe lit
-ppr_arg pe (VarArg   v)          = pocc pe v
-ppr_arg pe (TyArg    ty)  = pty  pe ty
-ppr_arg pe (UsageArg use) = puse pe use
+ppr_arg pe (LitArg   lit) = pLit pe lit
+ppr_arg pe (VarArg   v)          = pOcc pe v
+ppr_arg pe (TyArg    ty)  = pTy  pe ty
+ppr_arg pe (UsageArg use) = pUse pe use
 \end{code}
 
 Other printing bits-and-bobs used with the general @pprCoreBinding@
 \end{code}
 
 Other printing bits-and-bobs used with the general @pprCoreBinding@
index 4db1bdf..1e29075 100644 (file)
@@ -34,21 +34,23 @@ start.
 deSugar :: UniqSupply          -- name supply
        -> FAST_STRING                  -- module name
 
 deSugar :: UniqSupply          -- name supply
        -> FAST_STRING                  -- module name
 
-       -> (TypecheckedHsBinds,   -- input: class, instance, and value
-           TypecheckedHsBinds, --   bindings; see "tcModule" (which produces
+       -> (TypecheckedHsBinds, -- input: recsel, class, instance, and value
+           TypecheckedHsBinds, --   bindings; see "tcModule" (which produces
            TypecheckedHsBinds, --   them)
            TypecheckedHsBinds, --   them)
+           TypecheckedHsBinds,
            [(Id, TypecheckedHsExpr)])
 -- ToDo: handling of const_inst thingies is certainly WRONG ***************************
 
        -> ([CoreBinding],      -- output
            Bag DsMatchContext) -- Shadowing complaints
 
            [(Id, TypecheckedHsExpr)])
 -- ToDo: handling of const_inst thingies is certainly WRONG ***************************
 
        -> ([CoreBinding],      -- output
            Bag DsMatchContext) -- Shadowing complaints
 
-deSugar us mod_name (clas_binds, inst_binds, val_binds, const_inst_pairs)
+deSugar us mod_name (recsel_binds, clas_binds, inst_binds, val_binds, const_inst_pairs)
   = let
        (us0, us0a) = splitUniqSupply us
        (us1, us1a) = splitUniqSupply us0a
        (us2, us2a) = splitUniqSupply us1a
   = let
        (us0, us0a) = splitUniqSupply us
        (us1, us1a) = splitUniqSupply us0a
        (us2, us2a) = splitUniqSupply us1a
-       (us3, us4)  = splitUniqSupply us2a
+       (us3, us3a) = splitUniqSupply us2a
+       (us4, us5)  = splitUniqSupply us3a
 
        ((core_const_prs, consts_pairs), shadows1)
            = initDs us0 nullIdEnv mod_name (dsInstBinds [] const_inst_pairs)
 
        ((core_const_prs, consts_pairs), shadows1)
            = initDs us0 nullIdEnv mod_name (dsInstBinds [] const_inst_pairs)
@@ -67,21 +69,28 @@ deSugar us mod_name (clas_binds, inst_binds, val_binds, const_inst_pairs)
                        = initDs us3 consts_env mod_name (dsBinds val_binds)
        core_val_pairs  = pairsFromCoreBinds core_val_binds
 
                        = initDs us3 consts_env mod_name (dsBinds val_binds)
        core_val_pairs  = pairsFromCoreBinds core_val_binds
 
+       (core_recsel_binds, shadows5)
+                       = initDs us4 consts_env mod_name (dsBinds recsel_binds)
+       core_recsel_prs = pairsFromCoreBinds core_recsel_binds
+
        final_binds
        final_binds
-         = if (null core_clas_prs && null core_inst_prs && null core_const_prs) then
+         = if (null core_clas_prs && null core_inst_prs
+            && null core_recsel_prs {-???dont know???-} && null core_const_prs) then
                -- we don't have to make the whole thing recursive
                core_clas_binds ++ core_val_binds
 
            else -- gotta make it recursive (sigh)
                -- we don't have to make the whole thing recursive
                core_clas_binds ++ core_val_binds
 
            else -- gotta make it recursive (sigh)
-              [Rec (core_clas_prs ++ core_inst_prs ++ core_const_prs ++ core_val_pairs)]
+              [Rec (core_clas_prs ++ core_inst_prs
+                 ++ core_const_prs ++ core_val_pairs ++ core_recsel_prs)]
 
 
-       lift_final_binds = liftCoreBindings us4 final_binds
+       lift_final_binds = liftCoreBindings us5 final_binds
 
        really_final_binds = if opt_DoCoreLinting
                             then lintCoreBindings PprDebug "Desugarer" False lift_final_binds
                             else lift_final_binds
 
 
        really_final_binds = if opt_DoCoreLinting
                             then lintCoreBindings PprDebug "Desugarer" False lift_final_binds
                             else lift_final_binds
 
-       shadows = shadows1 `unionBags` shadows2 `unionBags` shadows3 `unionBags` shadows4
+       shadows = shadows1 `unionBags` shadows2 `unionBags`
+                 shadows3 `unionBags` shadows4 `unionBags` shadows5
     in
     (really_final_binds, shadows)
 \end{code}
     in
     (really_final_binds, shadows)
 \end{code}
index bc26cf4..ec1bdd4 100644 (file)
@@ -31,14 +31,13 @@ import CoreUtils    ( escErrorMsg )
 import CostCentre      ( mkAllDictsCC, preludeDictsCostCentre )
 import Id              ( idType, DictVar(..), GenId )
 import ListSetOps      ( minusList, intersectLists )
 import CostCentre      ( mkAllDictsCC, preludeDictsCostCentre )
 import Id              ( idType, DictVar(..), GenId )
 import ListSetOps      ( minusList, intersectLists )
-import PprType         ( GenType, GenTyVar )
+import PprType         ( GenType )
 import PprStyle                ( PprStyle(..) )
 import Pretty          ( ppShow )
 import Type            ( mkTyVarTys, splitSigmaTy,
                          tyVarsOfType, tyVarsOfTypes
                        )
 import PprStyle                ( PprStyle(..) )
 import Pretty          ( ppShow )
 import Type            ( mkTyVarTys, splitSigmaTy,
                          tyVarsOfType, tyVarsOfTypes
                        )
-import TyVar           ( tyVarSetToList, GenTyVar )
-import Unique          ( Unique )
+import TyVar           ( tyVarSetToList, GenTyVar{-instance Eq-} )
 import Util            ( isIn, panic )
 
 isDictTy = panic "DsBinds.isDictTy"
 import Util            ( isIn, panic )
 
 isDictTy = panic "DsBinds.isDictTy"
@@ -290,35 +289,28 @@ dsInstBinds :: [TyVar]                            -- Abstract wrt these
 do_nothing    = ([], []) -- out here to avoid dsInstBinds CAF (sigh)
 prel_dicts_cc = preludeDictsCostCentre False{-not dupd-} -- ditto
 
 do_nothing    = ([], []) -- out here to avoid dsInstBinds CAF (sigh)
 prel_dicts_cc = preludeDictsCostCentre False{-not dupd-} -- ditto
 
-dsInstBinds tyvars []
-  = returnDs do_nothing
-
-dsInstBinds _ _ = panic "DsBinds.dsInstBinds:maybe we want something different?"
-
-{- LATER
+dsInstBinds tyvars [] = returnDs do_nothing
 
 dsInstBinds tyvars ((inst, expr@(HsVar _)) : bs)
 
 dsInstBinds tyvars ((inst, expr@(HsVar _)) : bs)
-  = dsExpr expr                                `thenDs` ( \ rhs ->
+  = dsExpr expr                                `thenDs` \ rhs ->
     let        -- Need to apply dsExpr to the variable in case it
        -- has a substitution in the current environment
        subst_item = (inst, rhs)
     in
     extendEnvDs [subst_item] (
        dsInstBinds tyvars bs
     let        -- Need to apply dsExpr to the variable in case it
        -- has a substitution in the current environment
        subst_item = (inst, rhs)
     in
     extendEnvDs [subst_item] (
        dsInstBinds tyvars bs
-    )                                  `thenDs` (\ (binds, subst_env) ->
+    )                                  `thenDs` \ (binds, subst_env) ->
     returnDs (binds, subst_item : subst_env)
     returnDs (binds, subst_item : subst_env)
-    ))
 
 dsInstBinds tyvars ((inst, expr@(HsLit _)) : bs)
 
 dsInstBinds tyvars ((inst, expr@(HsLit _)) : bs)
-  = dsExpr expr                                `thenDs` ( \ core_lit ->
+  = dsExpr expr                                `thenDs` \ core_lit ->
     let
        subst_item = (inst, core_lit)
     in
     extendEnvDs [subst_item]    (
        dsInstBinds tyvars bs
     let
        subst_item = (inst, core_lit)
     in
     extendEnvDs [subst_item]    (
        dsInstBinds tyvars bs
-    )                                  `thenDs` (\ (binds, subst_env) ->
+    )                                  `thenDs` \ (binds, subst_env) ->
     returnDs (binds, subst_item : subst_env)
     returnDs (binds, subst_item : subst_env)
-    ))
 
 dsInstBinds tyvars ((inst, expr) : bs)
   | null abs_tyvars
 
 dsInstBinds tyvars ((inst, expr) : bs)
   | null abs_tyvars
@@ -351,7 +343,7 @@ dsInstBinds tyvars ((inst, expr) : bs)
              subst_item : subst_env)
   where
     inst_ty    = idType inst
              subst_item : subst_env)
   where
     inst_ty    = idType inst
-    abs_tyvars = tyVarsOfType inst_ty `intersectLists` tyvars
+    abs_tyvars = tyVarSetToList{-???sigh-} (tyVarsOfType inst_ty) `intersectLists` tyvars
     abs_tys    = mkTyVarTys abs_tyvars
     (_, poly_inst_ty) = quantifyTy abs_tyvars inst_ty
 
     abs_tys    = mkTyVarTys abs_tyvars
     (_, poly_inst_ty) = quantifyTy abs_tyvars inst_ty
 
@@ -359,26 +351,23 @@ dsInstBinds tyvars ((inst, expr) : bs)
     -- Wrap a desugared expression in `_scc_ "DICT" <expr>' if
     -- appropriate.  Uses "inst"'s type.
 
     -- Wrap a desugared expression in `_scc_ "DICT" <expr>' if
     -- appropriate.  Uses "inst"'s type.
 
+       -- if profiling, wrap the dict in "_scc_ DICT <dict>":
     ds_dict_cc expr
     ds_dict_cc expr
-      = -- if profiling, wrap the dict in "_scc_ DICT <dict>":
-       let
-           doing_profiling   = opt_SccProfilingOn
-           compiling_prelude = opt_CompilingPrelude
-       in
-       if not doing_profiling
-       || not (isDictTy inst_ty) then -- that's easy: do nothing
-           returnDs expr
-       else if compiling_prelude then
-           returnDs (SCC prel_dicts_cc expr)
-       else
-           getModuleAndGroupDs         `thenDs` \ (mod_name, grp_name) ->
+      | not opt_SccProfilingOn ||
+       not (isDictTy inst_ty) 
+      = returnDs expr  -- that's easy: do nothing
+
+      | opt_CompilingPrelude
+      = returnDs (SCC prel_dicts_cc expr)
+
+      | otherwise
+      = getModuleAndGroupDs    `thenDs` \ (mod_name, grp_name) ->
            -- ToDo: do -dicts-all flag (mark dict things
            -- with individual CCs)
            -- ToDo: do -dicts-all flag (mark dict things
            -- with individual CCs)
-           let
+       let
                dict_cc = mkAllDictsCC mod_name grp_name False{-not dupd-}
                dict_cc = mkAllDictsCC mod_name grp_name False{-not dupd-}
-           in
-           returnDs (SCC dict_cc expr)
--}
+       in
+       returnDs (SCC dict_cc expr)
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index f2eb50b..b54e111 100644 (file)
@@ -19,7 +19,7 @@ import CoreUtils      ( coreExprType )
 import Id              ( getInstantiatedDataConSig, mkTupleCon )
 import Maybes          ( maybeToBool )
 import PprStyle                ( PprStyle(..) )
 import Id              ( getInstantiatedDataConSig, mkTupleCon )
 import Maybes          ( maybeToBool )
 import PprStyle                ( PprStyle(..) )
-import PprType         ( GenType{-instances-}, GenTyVar{-instance-} )
+import PprType         ( GenType{-instances-} )
 import PrelInfo                ( byteArrayPrimTy, getStatePairingConInfo,
                          packStringForCId, realWorldStatePrimTy,
                          realWorldStateTy, realWorldTy, stateDataCon,
 import PrelInfo                ( byteArrayPrimTy, getStatePairingConInfo,
                          packStringForCId, realWorldStatePrimTy,
                          realWorldStateTy, realWorldTy, stateDataCon,
@@ -27,9 +27,7 @@ import PrelInfo               ( byteArrayPrimTy, getStatePairingConInfo,
 import Pretty
 import PrimOp          ( PrimOp(..) )
 import Type            ( isPrimType, maybeAppDataTyCon, eqTy )
 import Pretty
 import PrimOp          ( PrimOp(..) )
 import Type            ( isPrimType, maybeAppDataTyCon, eqTy )
-import TyVar           ( GenTyVar{-instance-} )
-import Unique          ( Unique{-instances-} )
-import Util            ( pprPanic, panic )
+import Util            ( pprPanic, pprError, panic )
 
 maybeBoxedPrimType = panic "DsCCall.maybeBoxedPrimType"
 \end{code}
 
 maybeBoxedPrimType = panic "DsCCall.maybeBoxedPrimType"
 \end{code}
@@ -198,7 +196,8 @@ we decide what's happening with enumerations. ADR
     (data_con_arg_ty1 : data_con_arg_ty2 : _) = data_con_arg_tys
 
 can't_see_datacons_error thing ty
     (data_con_arg_ty1 : data_con_arg_ty2 : _) = data_con_arg_tys
 
 can't_see_datacons_error thing ty
-  = error (ppShow 100 (ppBesides [ppStr "ERROR: Can't see the data constructor(s) for _ccall_/_casm_ ", ppStr thing, ppStr "; type: ", ppr PprForUser ty]))
+  = pprError "ERROR: Can't see the data constructor(s) for _ccall_/_casm_ "
+            (ppBesides [ppStr thing, ppStr "; type: ", ppr PprForUser ty])
 \end{code}
 
 
 \end{code}
 
 
index 5d36347..0888099 100644 (file)
@@ -32,17 +32,15 @@ import Id           ( mkTupleCon, idType, nullIdEnv, addOneToIdEnv,
 import Literal         ( mkMachInt, Literal(..) )
 import MagicUFs                ( MagicUnfoldingFun )
 import PprStyle                ( PprStyle(..) )
 import Literal         ( mkMachInt, Literal(..) )
 import MagicUFs                ( MagicUnfoldingFun )
 import PprStyle                ( PprStyle(..) )
-import PprType         ( GenType, GenTyVar )
+import PprType         ( GenType )
 import PrelInfo                ( mkTupleTy, unitTy, nilDataCon, consDataCon,
                          charDataCon, charTy )
 import PrelInfo                ( mkTupleTy, unitTy, nilDataCon, consDataCon,
                          charDataCon, charTy )
-import Pretty          ( ppShow )
-import Type            ( splitSigmaTy )
-import TyVar           ( nullTyVarEnv, addOneToTyVarEnv, GenTyVar )
-import Unique          ( Unique )
+import Pretty          ( ppShow, ppBesides, ppPStr, ppStr )
+import Type            ( splitSigmaTy, typePrimRep )
+import TyVar           ( nullTyVarEnv, addOneToTyVarEnv )
 import Usage           ( UVar(..) )
 import Usage           ( UVar(..) )
-import Util            ( panic )
+import Util            ( pprError, panic )
 
 
-primRepFromType = panic "DsExpr.primRepFromType"
 maybeBoxedPrimType = panic "DsExpr.maybeBoxedPrimType"
 splitTyArgs = panic "DsExpr.splitTyArgs"
 
 maybeBoxedPrimType = panic "DsExpr.maybeBoxedPrimType"
 splitTyArgs = panic "DsExpr.splitTyArgs"
 
@@ -103,8 +101,8 @@ dsExpr (HsLitOut (HsString s) _)
 -- "str" ==> build (\ c n -> foldr charTy T c n "str")
 
 {- LATER:
 -- "str" ==> build (\ c n -> foldr charTy T c n "str")
 
 {- LATER:
-dsExpr (HsLitOut (HsString str) _) =
-    newTyVarsDs [alphaTyVar]           `thenDs` \ [new_tyvar] ->
+dsExpr (HsLitOut (HsString str) _)
+  = newTyVarsDs [alphaTyVar]           `thenDs` \ [new_tyvar] ->
     let
        new_ty = mkTyVarTy new_tyvar
     in
     let
        new_ty = mkTyVarTy new_tyvar
     in
@@ -132,10 +130,11 @@ dsExpr (HsLitOut (HsLitLit s) ty)
   where
     (data_con, kind)
       = case (maybeBoxedPrimType ty) of
   where
     (data_con, kind)
       = case (maybeBoxedPrimType ty) of
-         Nothing
-           -> error ("ERROR: ``literal-literal'' not a single-constructor type: "++ _UNPK_ s ++"; type: "++(ppShow 80 (ppr PprDebug ty)))
          Just (boxing_data_con, prim_ty)
          Just (boxing_data_con, prim_ty)
-           -> (boxing_data_con, primRepFromType prim_ty)
+           -> (boxing_data_con, typePrimRep prim_ty)
+         Nothing
+           -> pprError "ERROR: ``literal-literal'' not a single-constructor type: "
+                       (ppBesides [ppPStr s, ppStr "; type: ", ppr PprDebug ty])
 
 dsExpr (HsLitOut (HsInt i) _)
   = returnDs (Lit (NoRepInteger i))
 
 dsExpr (HsLitOut (HsInt i) _)
   = returnDs (Lit (NoRepInteger i))
@@ -317,6 +316,9 @@ dsExpr (ArithSeqOut expr (FromThenTo from thn two))
     mkAppDs expr2 [] [from2, thn2, two2]
 \end{code}
 
     mkAppDs expr2 [] [from2, thn2, two2]
 \end{code}
 
+
+Type lambda and application
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
 \begin{code}
 dsExpr (TyLam tyvars expr)
   = dsExpr expr `thenDs` \ core_expr ->
 \begin{code}
 dsExpr (TyLam tyvars expr)
   = dsExpr expr `thenDs` \ core_expr ->
@@ -325,6 +327,31 @@ dsExpr (TyLam tyvars expr)
 dsExpr expr@(TyApp e tys) = dsApp expr []
 \end{code}
 
 dsExpr expr@(TyApp e tys) = dsApp expr []
 \end{code}
 
+
+Record construction and update
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+\begin{code}
+{-
+dsExpr (RecordCon con_expr rbinds)
+  = dsExpr con_expr    `thenDs` \ con_expr' ->
+    let
+       con_args = map mk_arg (arg_tys `zip` fieldLabelTags)
+       (arg_tys, data_ty) = splitFunTy (coreExprType con_expr')
+
+       mk_arg (arg_ty, tag) = case [  | (sel_id,rhs) <- rbinds,
+                                        fieldLabelTag (recordSelectorFieldLabel sel_id) == tag
+                                   ] of
+                                (rhs:rhss) -> ASSERT( null rhss )
+                                              dsExpr rhs
+
+                                [] -> returnDs ......GONE HOME!>>>>>
+
+    mkAppDs con_expr [] con_args
+-}
+\end{code}
+
+Dictionary lambda and application
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 @DictLam@ and @DictApp@ turn into the regular old things.
 (OLD:) @DictFunApp@ also becomes a curried application, albeit slightly more
 complicated; reminiscent of fully-applied constructors.
 @DictLam@ and @DictApp@ turn into the regular old things.
 (OLD:) @DictFunApp@ also becomes a curried application, albeit slightly more
 complicated; reminiscent of fully-applied constructors.
index 5287b22..d90e330 100644 (file)
@@ -16,20 +16,17 @@ import HsSyn                ( GRHSsAndBinds(..), GRHS(..),
 import TcHsSyn         ( TypecheckedGRHSsAndBinds(..), TypecheckedGRHS(..),
                          TypecheckedPat(..), TypecheckedHsBinds(..),
                          TypecheckedHsExpr(..) )
 import TcHsSyn         ( TypecheckedGRHSsAndBinds(..), TypecheckedGRHS(..),
                          TypecheckedPat(..), TypecheckedHsBinds(..),
                          TypecheckedHsExpr(..) )
-import CoreSyn         ( CoreBinding(..), CoreExpr(..) )
+import CoreSyn         ( CoreBinding(..), CoreExpr(..), mkCoLetsAny )
 
 import DsMonad
 import DsUtils
 
 
 import DsMonad
 import DsUtils
 
-import CoreUtils       ( escErrorMsg, mkErrorApp )
+import CoreUtils       ( escErrorMsg, mkErrorApp, mkCoreIfThenElse )
 import PrelInfo                ( stringTy )
 import PprStyle                ( PprStyle(..) )
 import Pretty          ( ppShow )
 import SrcLoc          ( SrcLoc{-instance-} )
 import Util            ( panic )
 import PrelInfo                ( stringTy )
 import PprStyle                ( PprStyle(..) )
 import Pretty          ( ppShow )
 import SrcLoc          ( SrcLoc{-instance-} )
 import Util            ( panic )
-
-mkCoLetsAny = panic "DsGRHSs.mkCoLetsAny"
-mkCoreIfThenElse = panic "DsGRHSs.mkCoreIfThenElse"
 \end{code}
 
 @dsGuarded@ is used for both @case@ expressions and pattern bindings.
 \end{code}
 
 @dsGuarded@ is used for both @case@ expressions and pattern bindings.
index 636ebf4..6d9dc55 100644 (file)
@@ -31,24 +31,21 @@ import CmdLineOpts  ( opt_SccGroup )
 import CoreSyn         ( CoreExpr(..) )
 import CoreUtils       ( substCoreExpr )
 import HsSyn           ( OutPat )
 import CoreSyn         ( CoreExpr(..) )
 import CoreUtils       ( substCoreExpr )
 import HsSyn           ( OutPat )
-import Id              ( mkSysLocal, lookupIdEnv, growIdEnvList, GenId, IdEnv(..) )
+import Id              ( mkSysLocal, mkIdWithNewUniq,
+                         lookupIdEnv, growIdEnvList, GenId, IdEnv(..)
+                       )
 import PprType         ( GenType, GenTyVar )
 import PprStyle                ( PprStyle(..) )
 import Pretty
 import SrcLoc          ( unpackSrcLoc, mkUnknownSrcLoc, SrcLoc )
 import TcHsSyn         ( TypecheckedPat(..) )
 import PprType         ( GenType, GenTyVar )
 import PprStyle                ( PprStyle(..) )
 import Pretty
 import SrcLoc          ( unpackSrcLoc, mkUnknownSrcLoc, SrcLoc )
 import TcHsSyn         ( TypecheckedPat(..) )
-import TyVar           ( nullTyVarEnv, GenTyVar )
+import TyVar           ( nullTyVarEnv, cloneTyVar, GenTyVar{-instance Eq-} )
 import Unique          ( Unique{-instances-} )
 import UniqSupply      ( splitUniqSupply, getUnique, getUniques,
                          mapUs, thenUs, returnUs, UniqSM(..) )
 import Unique          ( Unique{-instances-} )
 import UniqSupply      ( splitUniqSupply, getUnique, getUniques,
                          mapUs, thenUs, returnUs, UniqSM(..) )
-import Unique          ( Unique )
 import Util            ( assoc, mapAccumL, zipWithEqual, panic )
 
 infixr 9 `thenDs`
 import Util            ( assoc, mapAccumL, zipWithEqual, panic )
 
 infixr 9 `thenDs`
-
-cloneTyVar = panic "DsMonad.cloneTyVar"
-cloneTyVarFromTemplate = panic "DsMonad.cloneTyVarFromTemplate"
-mkIdWithNewUniq = panic "DsMonad.mkIdWithNewUniq"
 \end{code}
 
 Now the mondo monad magic (yes, @DsM@ is a silly name)---carry around
 \end{code}
 
 Now the mondo monad magic (yes, @DsM@ is a silly name)---carry around
@@ -165,7 +162,7 @@ newTyVarsDs :: [TyVar] -> DsM [TyVar]
 
 newTyVarsDs tyvar_tmpls us loc mod_and_grp env warns
   = case (getUniques (length tyvar_tmpls) us) of { uniqs ->
 
 newTyVarsDs tyvar_tmpls us loc mod_and_grp env warns
   = case (getUniques (length tyvar_tmpls) us) of { uniqs ->
-    (zipWithEqual cloneTyVarFromTemplate tyvar_tmpls uniqs, warns) }
+    (zipWithEqual cloneTyVar tyvar_tmpls uniqs, warns) }
 \end{code}
 
 We can also reach out and either set/grab location information from
 \end{code}
 
 We can also reach out and either set/grab location information from
index 07cbe0b..700db9e 100644 (file)
@@ -42,12 +42,12 @@ import PrelInfo             ( stringTy )
 import Id              ( idType, getInstantiatedDataConSig, mkTupleCon,
                          DataCon(..), DictVar(..), Id(..), GenId )
 import TyCon           ( mkTupleTyCon )
 import Id              ( idType, getInstantiatedDataConSig, mkTupleCon,
                          DataCon(..), DictVar(..), Id(..), GenId )
 import TyCon           ( mkTupleTyCon )
-import Type            ( mkTyVarTys, mkRhoTy, mkFunTys,
-                         applyTyCon, getAppDataTyCon )
+import Type            ( mkTyVarTys, mkRhoTy, mkFunTys, isUnboxedType,
+                         applyTyCon, getAppDataTyCon
+                       )
 import UniqSet         ( mkUniqSet, minusUniqSet, uniqSetToList, UniqSet(..) )
 import Util            ( panic, assertPanic )
 
 import UniqSet         ( mkUniqSet, minusUniqSet, uniqSetToList, UniqSet(..) )
 import Util            ( panic, assertPanic )
 
-isUnboxedDataType = panic "DsUtils.isUnboxedDataType"
 quantifyTy = panic "DsUtils.quantifyTy"
 splitDictType = panic "DsUtils.splitDictType"
 mkCoTyApps = panic "DsUtils.mkCoTyApps"
 quantifyTy = panic "DsUtils.quantifyTy"
 splitDictType = panic "DsUtils.splitDictType"
 mkCoTyApps = panic "DsUtils.mkCoTyApps"
@@ -228,7 +228,7 @@ dsExprToAtom arg_expr continue_with
     newSysLocalDs ty                   `thenDs` \ arg_id ->
     continue_with (VarArg arg_id)      `thenDs` \ body   ->
     returnDs (
     newSysLocalDs ty                   `thenDs` \ arg_id ->
     continue_with (VarArg arg_id)      `thenDs` \ body   ->
     returnDs (
-       if isUnboxedDataType ty
+       if isUnboxedType ty
        then Case arg_expr (PrimAlts [] (BindDefault arg_id body))
        else Let (NonRec arg_id arg_expr) body
     )
        then Case arg_expr (PrimAlts [] (BindDefault arg_id body))
        else Let (NonRec arg_id arg_expr) body
     )
@@ -537,7 +537,7 @@ mkFailurePair :: Type               -- Result type of the whole case expression
                      CoreExpr) -- Either the fail variable, or fail variable
                                -- applied to unit tuple
 mkFailurePair ty
                      CoreExpr) -- Either the fail variable, or fail variable
                                -- applied to unit tuple
 mkFailurePair ty
-  | isUnboxedDataType ty
+  | isUnboxedType ty
   = newFailLocalDs (mkFunTys [unit_ty] ty)     `thenDs` \ fail_fun_var ->
     newSysLocalDs unit_ty                      `thenDs` \ fail_fun_arg ->
     returnDs (\ body ->
   = newFailLocalDs (mkFunTys [unit_ty] ty)     `thenDs` \ fail_fun_var ->
     newSysLocalDs unit_ty                      `thenDs` \ fail_fun_arg ->
     returnDs (\ body ->
index f657e96..c7d0b5d 100644 (file)
@@ -25,9 +25,13 @@ import MatchCon              ( matchConFamily )
 import MatchLit                ( matchLiterals )
 
 import CoreUtils       ( escErrorMsg, mkErrorApp )
 import MatchLit                ( matchLiterals )
 
 import CoreUtils       ( escErrorMsg, mkErrorApp )
-import Id              ( idType, mkTupleCon, GenId{-instance-} )
+import FieldLabel      ( allFieldLabelTags, fieldLabelTag )
+import Id              ( idType, mkTupleCon, dataConSig,
+                         recordSelectorFieldLabel,
+                         GenId{-instance-}
+                       )
 import PprStyle                ( PprStyle(..) )
 import PprStyle                ( PprStyle(..) )
-import PprType         ( GenTyVar{-instance-}, GenType{-instance-} )
+import PprType         ( GenType{-instance-}, GenTyVar{-ditto-} )
 import PrelInfo                ( nilDataCon, consDataCon, mkTupleTy, mkListTy,
                          charTy, charDataCon, intTy, intDataCon,
                          floatTy, floatDataCon, doubleTy, doubleDataCon,
 import PrelInfo                ( nilDataCon, consDataCon, mkTupleTy, mkListTy,
                          charTy, charDataCon, intTy, intDataCon,
                          floatTy, floatDataCon, doubleTy, doubleDataCon,
@@ -35,10 +39,12 @@ import PrelInfo             ( nilDataCon, consDataCon, mkTupleTy, mkListTy,
                          floatPrimTy, doublePrimTy, stringTy,
                          addrTy, addrPrimTy, addrDataCon,
                          wordTy, wordPrimTy, wordDataCon )
                          floatPrimTy, doublePrimTy, stringTy,
                          addrTy, addrPrimTy, addrDataCon,
                          wordTy, wordPrimTy, wordDataCon )
-import Type            ( isPrimType, eqTy )
-import TyVar           ( GenTyVar )
-import Unique          ( Unique )
-import Util            ( panic, pprPanic )
+import Type            ( isPrimType, eqTy, getAppDataTyCon,
+                         instantiateTauTy
+                       )
+import TyVar           ( GenTyVar{-instance Eq-} )
+import Unique          ( Unique{-instance Eq-} )
+import Util            ( panic, pprPanic, assertPanic )
 \end{code}
 
 The function @match@ is basically the same as in the Wadler chapter,
 \end{code}
 
 The function @match@ is basically the same as in the Wadler chapter,
@@ -320,6 +326,27 @@ tidy1 v (LazyPat pat) match_result
 tidy1 v (ConOpPat pat1 id pat2 ty) match_result
   = returnDs (ConPat id ty [pat1, pat2], match_result)
 
 tidy1 v (ConOpPat pat1 id pat2 ty) match_result
   = returnDs (ConPat id ty [pat1, pat2], match_result)
 
+tidy1 v (RecPat con_id pat_ty rpats) match_result
+  = returnDs (ConPat con_id pat_ty pats, match_result)
+  where
+    pats                   = map mk_pat tagged_arg_tys
+
+       -- Boring stuff to find the arg-tys of the constructor
+    (tyvars, _, arg_tys, _) = dataConSig con_id
+    (_, inst_tys, _)       = getAppDataTyCon pat_ty
+    tenv                   = tyvars `zip` inst_tys
+    con_arg_tys'           = map (instantiateTauTy tenv) arg_tys
+    tagged_arg_tys         = con_arg_tys' `zip` allFieldLabelTags
+
+       -- mk_pat picks a WildPat of the appropriate type for absent fields,
+       -- and the specified pattern for present fields
+    mk_pat (arg_ty, tag) = case [pat | (sel_id,pat,_) <- rpats,
+                                       fieldLabelTag (recordSelectorFieldLabel sel_id) == tag 
+                               ] of
+                               (pat:pats) -> ASSERT( null pats )
+                                             pat
+                               []         -> WildPat arg_ty
+
 tidy1 v (ListPat ty pats) match_result
   = returnDs (list_ConPat, match_result)
   where
 tidy1 v (ListPat ty pats) match_result
   = returnDs (list_ConPat, match_result)
   where
index 52bb3a6..1ae29da 100644 (file)
@@ -75,7 +75,7 @@ matchLiterals all_vars@(var:vars) eqns_info@(EqnInfo (LitPat literal lit_ty : ps
        mk_core_lit ty (HsFloatPrim   f) = MachFloat  f
        mk_core_lit ty (HsDoublePrim  d) = MachDouble d
        mk_core_lit ty (HsLitLit      s) = ASSERT(isPrimType ty)
        mk_core_lit ty (HsFloatPrim   f) = MachFloat  f
        mk_core_lit ty (HsDoublePrim  d) = MachDouble d
        mk_core_lit ty (HsLitLit      s) = ASSERT(isPrimType ty)
-                                          MachLitLit s (panic "MatchLit.matchLiterals:mk_core_lit:HsLitLit; primRepFromType???")
+                                          MachLitLit s (panic "MatchLit.matchLiterals:mk_core_lit:HsLitLit; typePrimRep???")
        mk_core_lit ty other             = panic "matchLiterals:mk_core_lit:unhandled"
 \end{code}
 
        mk_core_lit ty other             = panic "matchLiterals:mk_core_lit:unhandled"
 \end{code}
 
index 25c5d31..b6bfea9 100644 (file)
@@ -95,8 +95,8 @@ ToDo:
 >       Let (NonRec (v,ManyOcc _) e) e'
 >              | isTrivial e -> c2d (addOneToIdEnv p v (c2d p e)) e'
 >              | otherwise ->
 >       Let (NonRec (v,ManyOcc _) e) e'
 >              | isTrivial e -> c2d (addOneToIdEnv p v (c2d p e)) e'
 >              | otherwise ->
->              trace ("Not inlining ManyOcc " ++ ppShow 80 (ppr PprDebug v)) (
->              Let (NonRec v (c2d p e)) (c2d p e'))
+>              pprTrace "Not inlining ManyOcc " (ppr PprDebug v) $
+>              Let (NonRec v (c2d p e)) (c2d p e')
 >
 >      Let (NonRec (v,DeadCode) e) e' ->
 >              panic "Core2Def(c2d): oops, unexpected DeadCode"
 >
 >      Let (NonRec (v,DeadCode) e) e' ->
 >              panic "Core2Def(c2d): oops, unexpected DeadCode"
@@ -104,8 +104,8 @@ ToDo:
 >      Let (NonRec (v,OneOcc fun_or_arg dup_danger _ _ _) e) e'
 >         | isTrivial e -> inline_it
 >         | isDupDanger dup_danger ->
 >      Let (NonRec (v,OneOcc fun_or_arg dup_danger _ _ _) e) e'
 >         | isTrivial e -> inline_it
 >         | isDupDanger dup_danger ->
->              trace ("Not inlining DupDanger " ++ ppShow 80 (ppr PprDebug v))(
->              Let (NonRec v (c2d p e)) (c2d p e'))
+>              pprTrace "Not inlining DupDanger " (ppr PprDebug v) $
+>              Let (NonRec v (c2d p e)) (c2d p e')
 >         | isFun fun_or_arg ->
 >              panic "Core2Def(c2d): oops, unexpected Macro"
 >         | otherwise -> inline_it
 >         | isFun fun_or_arg ->
 >              panic "Core2Def(c2d): oops, unexpected Macro"
 >         | otherwise -> inline_it
index 08b65d7..48cde68 100644 (file)
@@ -165,8 +165,7 @@ Comment the next section out to disable back-loops.
 >              if not (null back_loops){- && not (f `elem` ls')-} then
 >                 --if length back_loops > 1 then panic "barf!" else
 >                      d2c (head back_loops)   `thenUs` \core_e ->
 >              if not (null back_loops){- && not (f `elem` ls')-} then
 >                 --if length back_loops > 1 then panic "barf!" else
 >                      d2c (head back_loops)   `thenUs` \core_e ->
->                      trace ("Back Loop:\n" ++
->                              ppShow 80 (ppr PprDebug core_e)) $
+>                      pprTrace "Back Loop:\n" (ppr PprDebug core_e) $
 
 If we find a back-loop that also occurs where we would normally make a
 new function...
 
 If we find a back-loop that also occurs where we would normally make a
 new function...
index a01b198..51446f2 100644 (file)
@@ -25,10 +25,9 @@ import HsTypes               ( PolyType )
 --others:
 import Id              ( DictVar(..), Id(..), GenId )
 import Outputable
 --others:
 import Id              ( DictVar(..), Id(..), GenId )
 import Outputable
-import PprType         ( pprType )
 import Pretty
 import SrcLoc          ( SrcLoc{-instances-} )
 import Pretty
 import SrcLoc          ( SrcLoc{-instances-} )
-import TyVar           ( GenTyVar{-instances-} )
+--import TyVar         ( GenTyVar{-instances-} )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index dad1f52..18f817a 100644 (file)
@@ -161,7 +161,7 @@ data ConDecl name
                SrcLoc
 
   | RecConDecl name
                SrcLoc
 
   | RecConDecl name
-               [(name, BangType name)] -- list of "fields"
+               [([name], BangType name)]       -- list of "fields"
                SrcLoc
 
   | NewConDecl  name           -- newtype con decl
                SrcLoc
 
   | NewConDecl  name           -- newtype con decl
index 2004ddf..fc9356a 100644 (file)
@@ -20,13 +20,11 @@ import HsTypes              ( PolyType )
 -- others:
 import Id              ( DictVar(..), GenId, Id(..) )
 import Outputable
 -- others:
 import Id              ( DictVar(..), GenId, Id(..) )
 import Outputable
-import PprType         ( pprType, pprParendType, GenType{-instance-}, GenTyVar{-instance-} )
+import PprType         ( pprGenType, pprParendGenType, GenType{-instance-} )
 import Pretty
 import PprStyle                ( PprStyle(..) )
 import SrcLoc          ( SrcLoc )
 import Pretty
 import PprStyle                ( PprStyle(..) )
 import SrcLoc          ( SrcLoc )
-import TyVar           ( GenTyVar{-instances-} )
 import Usage           ( GenUsage{-instance-} )
 import Usage           ( GenUsage{-instance-} )
-import Unique          ( Unique{-instances-} )
 import Util            ( panic{-ToDo:rm eventually-} )
 \end{code}
 
 import Util            ( panic{-ToDo:rm eventually-} )
 \end{code}
 
@@ -99,11 +97,14 @@ data HsExpr tyvar uvar id pat
                                -- for tuples, we can get the types
                                -- direct from the components
 
                                -- for tuples, we can get the types
                                -- direct from the components
 
-  | RecordCon  id              -- record construction
-               [(id, Maybe (HsExpr tyvar uvar id pat))]
+       -- Record construction
+  | RecordCon  (HsExpr tyvar uvar id pat)      -- Always (HsVar id) until type checker,
+                                               -- but the latter adds its type args too
+               (HsRecordBinds tyvar uvar id pat)
 
 
-  | RecordUpd  (HsExpr tyvar uvar id pat) -- record update
-               [(id, Maybe (HsExpr tyvar uvar id pat))]
+       -- Record update
+  | RecordUpd  (HsExpr tyvar uvar id pat)
+               (HsRecordBinds tyvar uvar id pat)
 
   | ExprWithTySig              -- signature binding
                (HsExpr tyvar uvar id pat)
 
   | ExprWithTySig              -- signature binding
                (HsExpr tyvar uvar id pat)
@@ -160,6 +161,11 @@ Everything from here on appears only in typechecker output.
 
   |  SingleDict                        -- a simple special case of Dictionary
                id              -- local dictionary name
 
   |  SingleDict                        -- a simple special case of Dictionary
                id              -- local dictionary name
+
+type HsRecordBinds tyvar uvar id pat
+  = [(id, HsExpr tyvar uvar id pat, Bool)]
+       -- True <=> source code used "punning",
+       -- i.e. {op1, op2} rather than {op1=e1, op2=e2}
 \end{code}
 
 A @Dictionary@, unless of length 0 or 1, becomes a tuple.  A
 \end{code}
 
 A @Dictionary@, unless of length 0 or 1, becomes a tuple.  A
@@ -272,7 +278,7 @@ pprExpr sty (ExplicitList exprs)
   = ppBracket (ppInterleave ppComma (map (pprExpr sty) exprs))
 pprExpr sty (ExplicitListOut ty exprs)
   = ppBesides [ ppBracket (ppInterleave ppComma (map (pprExpr sty) exprs)),
   = ppBracket (ppInterleave ppComma (map (pprExpr sty) exprs))
 pprExpr sty (ExplicitListOut ty exprs)
   = ppBesides [ ppBracket (ppInterleave ppComma (map (pprExpr sty) exprs)),
-               ifnotPprForUser sty (ppBeside ppSP (ppParens (pprType sty ty))) ]
+               ifnotPprForUser sty (ppBeside ppSP (ppParens (pprGenType sty ty))) ]
 
 pprExpr sty (ExplicitTuple exprs)
   = ppParens (ppInterleave ppComma (map (pprExpr sty) exprs))
 
 pprExpr sty (ExplicitTuple exprs)
   = ppParens (ppInterleave ppComma (map (pprExpr sty) exprs))
@@ -300,7 +306,7 @@ pprExpr sty (TyLam tyvars expr)
         4 (pprExpr sty expr)
 
 pprExpr sty (TyApp expr [ty])
         4 (pprExpr sty expr)
 
 pprExpr sty (TyApp expr [ty])
-  = ppHang (pprExpr sty expr) 4 (pprParendType sty ty)
+  = ppHang (pprExpr sty expr) 4 (pprParendGenType sty ty)
 
 pprExpr sty (TyApp expr tys)
   = ppHang (pprExpr sty expr)
 
 pprExpr sty (TyApp expr tys)
   = ppHang (pprExpr sty expr)
@@ -360,16 +366,17 @@ pprParendExpr sty expr
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
+pp_rbinds :: (NamedThing id, Outputable id, Outputable pat,
+                 Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar)
+             => PprStyle -> Pretty 
+             -> HsRecordBinds tyvar uvar id pat -> Pretty
+
 pp_rbinds sty thing rbinds
   = ppHang thing 4
        (ppBesides [ppChar '{', ppInterleave ppComma (map (pp_rbind sty) rbinds), ppChar '}'])
 pp_rbinds sty thing rbinds
   = ppHang thing 4
        (ppBesides [ppChar '{', ppInterleave ppComma (map (pp_rbind sty) rbinds), ppChar '}'])
-
-pp_rbind :: (NamedThing id, Outputable id, Outputable pat,
-                 Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar)
-             => PprStyle -> (id, Maybe (HsExpr tyvar uvar id pat)) -> Pretty
-
-pp_rbind sty (v, Nothing) = ppr sty v
-pp_rbind sty (v, Just e)  = ppCat [ppr sty v, ppStr "<-", ppr sty e]
+  where
+    pp_rbind sty (v, _, True{-pun-}) = ppr sty v
+    pp_rbind sty (v, e, _) = ppCat [ppr sty v, ppStr "<-", ppr sty e]
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index 4c8186f..b257cd3 100644 (file)
@@ -17,8 +17,6 @@ import Outputable     ( ifPprShowAll )
 import PprType
 import Pretty
 import SrcLoc          ( SrcLoc{-instances-} )
 import PprType
 import Pretty
 import SrcLoc          ( SrcLoc{-instances-} )
-import TyVar           ( GenTyVar{-instances-} )
-import Unique          ( Unique{-instances-} )
 import Util            ( panic )
 \end{code}
 
 import Util            ( panic )
 \end{code}
 
index 73124ac..11e4d26 100644 (file)
@@ -24,16 +24,13 @@ import HsLit                ( HsLit )
 import HsLoop          ( HsExpr )
 
 -- others:
 import HsLoop          ( HsExpr )
 
 -- others:
-import Id              ( GenId, getDataConSig )
+import Id              ( GenId, dataConSig )
 import Maybes          ( maybeToBool )
 import Outputable
 import PprStyle                ( PprStyle(..) )
 import Pretty
 import TyCon           ( maybeTyConSingleCon )
 import Maybes          ( maybeToBool )
 import Outputable
 import PprStyle                ( PprStyle(..) )
 import Pretty
 import TyCon           ( maybeTyConSingleCon )
-import TyVar           ( GenTyVar )
-import PprType         ( GenType, GenTyVar )
-import Unique          ( Unique )
-
+import PprType         ( GenType )
 \end{code}
 
 Patterns come in distinct before- and after-typechecking flavo(u)rs.
 \end{code}
 
 Patterns come in distinct before- and after-typechecking flavo(u)rs.
@@ -55,7 +52,7 @@ data InPat name
   | TuplePatIn     [InPat name]        -- tuple
 
   | RecPatIn       name                -- record
   | TuplePatIn     [InPat name]        -- tuple
 
   | RecPatIn       name                -- record
-                   [(name, Maybe (InPat name))]
+                   [(name, InPat name, Bool)]  -- True <=> source used punning
 
 data OutPat tyvar uvar id
   = WildPat        (GenType tyvar uvar)                        -- wild card
 
 data OutPat tyvar uvar id
   = WildPat        (GenType tyvar uvar)                        -- wild card
@@ -82,8 +79,9 @@ data OutPat tyvar uvar id
   | TuplePat       [(OutPat tyvar uvar id)]    -- tuple
                                                -- UnitPat is TuplePat []
 
   | TuplePat       [(OutPat tyvar uvar id)]    -- tuple
                                                -- UnitPat is TuplePat []
 
-  | RecPat         id                          -- record
-                   [(id, Maybe (OutPat tyvar uvar id))]
+  | RecPat         Id                          -- record constructor
+                   (GenType tyvar uvar)        -- the type of the pattern
+                   [(id, OutPat tyvar uvar id, Bool)]  -- True <=> source used punning
 
   | LitPat         -- Used for *non-overloaded* literal patterns:
                    -- Int#, Char#, Int, Char, String, etc.
 
   | LitPat         -- Used for *non-overloaded* literal patterns:
                    -- Int#, Char#, Int, Char, String, etc.
@@ -137,8 +135,8 @@ pprInPat sty (TuplePatIn pats)
 pprInPat sty (RecPatIn con rpats)
   = ppBesides [ppr sty con, ppSP, ppChar '{', ppInterleave ppComma (map pp_rpat rpats), ppChar '}']
   where
 pprInPat sty (RecPatIn con rpats)
   = ppBesides [ppr sty con, ppSP, ppChar '{', ppInterleave ppComma (map pp_rpat rpats), ppChar '}']
   where
-    pp_rpat (v, Nothing) = ppr sty v
-    pp_rpat (v, Just p)  = ppCat [ppr sty v, ppStr "<-", ppr sty p]
+    pp_rpat (v, _, True{-pun-}) = ppr sty v
+    pp_rpat (v, p, _) = ppCat [ppr sty v, ppStr "<-", ppr sty p]
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -172,11 +170,11 @@ pprOutPat sty (ListPat ty pats)
 pprOutPat sty (TuplePat pats)
   = ppBesides [ppLparen, interpp'SP sty pats, ppRparen]
 
 pprOutPat sty (TuplePat pats)
   = ppBesides [ppLparen, interpp'SP sty pats, ppRparen]
 
-pprOutPat sty (RecPat con rpats)
+pprOutPat sty (RecPat con ty rpats)
   = ppBesides [ppr sty con, ppChar '{', ppInterleave ppComma (map pp_rpat rpats), ppChar '}']
   where
   = ppBesides [ppr sty con, ppChar '{', ppInterleave ppComma (map pp_rpat rpats), ppChar '}']
   where
-    pp_rpat (v, Nothing) = ppr sty v
-    pp_rpat (v, Just p)  = ppBesides [ppr sty v, ppStr "<-", ppr sty p]
+--  pp_rpat (v, _, True{-pun-}) = ppr sty v
+    pp_rpat (v, p, _) = ppBesides [ppr sty v, ppStr "<-", ppr sty p]
 
 pprOutPat sty (LitPat l ty)    = ppr sty l     -- ToDo: print more
 pprOutPat sty (NPat   l ty e)  = ppr sty l     -- ToDo: print more
 
 pprOutPat sty (LitPat l ty)    = ppr sty l     -- ToDo: print more
 pprOutPat sty (NPat   l ty e)  = ppr sty l     -- ToDo: print more
@@ -266,7 +264,7 @@ irrefutablePat other_pat              = False   -- Literals, NPat
 
 only_con con = maybeToBool (maybeTyConSingleCon tycon)
               where
 
 only_con con = maybeToBool (maybeTyConSingleCon tycon)
               where
-                (_,_,_,tycon) = getDataConSig con
+                (_,_,_,tycon) = dataConSig con
 \end{code}
 
 This function @collectPatBinders@ works with the ``collectBinders''
 \end{code}
 
 This function @collectPatBinders@ works with the ``collectBinders''
index d455ff0..d588f68 100644 (file)
@@ -10,10 +10,7 @@ module ErrUtils (
 
        Error(..),
        addErrLoc, addShortErrLocLine,
 
        Error(..),
        addErrLoc, addShortErrLocLine,
-       dontAddErrLoc, pprBagOfErrors,
-
-       TcError(..), TcWarning(..), Message(..),
-       mkTcErr, arityErr
+       dontAddErrLoc, pprBagOfErrors
 
     ) where
 
 
     ) where
 
@@ -51,33 +48,3 @@ pprBagOfErrors sty bag_of_errors
     ppAboves (map (\ p -> ppAbove ppSP p) pretties)
 \end{code}
 
     ppAboves (map (\ p -> ppAbove ppSP p) pretties)
 \end{code}
 
-TypeChecking Errors
-~~~~~~~~~~~~~~~~~~~
-
-\begin{code}
-type Message   = PprStyle -> Pretty
-type TcError   = Message
-type TcWarning = Message
-
-
-mkTcErr :: SrcLoc              -- Where
-       -> [Message]            -- Context
-       -> Message              -- What went wrong
-       -> TcError              -- The complete error report
-
-mkTcErr locn ctxt msg sty
-  = ppHang (ppBesides [ppr PprForUser locn, ppStr ": ", msg sty])
-        4 (ppAboves [msg sty | msg <- ctxt])
-
-
-arityErr kind name n m sty =
-    ppBesides [ ppStr "`", ppr sty name, ppStr "' should have ",
-               n_arguments, ppStr ", but has been given ", ppInt m, ppChar '.']
-    where
-       errmsg = kind ++ " has too " ++ quantity ++ " arguments"
-       quantity | m < n     = "few"
-                | otherwise = "many"
-       n_arguments | n == 0 = ppStr "no arguments"
-                   | n == 1 = ppStr "1 argument"
-                   | True   = ppCat [ppInt n, ppStr "arguments"]
-\end{code}
index c691844..7e84618 100644 (file)
@@ -19,15 +19,27 @@ import ReadPrefix   ( rdModule )
 import Rename          ( renameModule )
 import Typecheck       ( typecheckModule, InstInfo )
 import Desugar         ( deSugar, DsMatchContext, pprDsWarnings )
 import Rename          ( renameModule )
 import Typecheck       ( typecheckModule, InstInfo )
 import Desugar         ( deSugar, DsMatchContext, pprDsWarnings )
+import SimplCore       ( core2core )
+import CoreToStg       ( topCoreBindsToStg )
+import SimplStg                ( stg2stg )
+import CodeGen         ( codeGen )
+#if ! OMIT_NATIVE_CODEGEN
+import AsmCodeGen      ( dumpRealAsm, writeRealAsm )
+#endif
 
 
+import AbsCSyn         ( absCNop, AbstractC )
+import AbsCUtils       ( flattenAbsC )
 import Bag             ( emptyBag, isEmptyBag )
 import CmdLineOpts
 import ErrUtils                ( pprBagOfErrors )
 import Bag             ( emptyBag, isEmptyBag )
 import CmdLineOpts
 import ErrUtils                ( pprBagOfErrors )
-import Maybes          ( MaybeErr(..) )
+import Maybes          ( maybeToBool, MaybeErr(..) )
 import PrelInfo                ( builtinNameInfo )
 import RdrHsSyn                ( getRawExportees )
 import PrelInfo                ( builtinNameInfo )
 import RdrHsSyn                ( getRawExportees )
+import Specialise      ( SpecialiseData(..) )
+import StgSyn          ( pprPlainStgBinding, GenStgBinding )
 
 
-import PprCore         ( pprPlainCoreBinding )
+import PprAbsC         ( dumpRealC, writeRealC )
+import PprCore         ( pprCoreBinding )
 import PprStyle                ( PprStyle(..) )
 import Pretty
 
 import PprStyle                ( PprStyle(..) )
 import Pretty
 
@@ -39,20 +51,8 @@ import TyVar         ( GenTyVar )            -- instances
 import Unique          ( Unique)               -- instances
 
 {-
 import Unique          ( Unique)               -- instances
 
 {-
---import AbsCSyn
---import CodeGen               ( codeGen )
---import CoreToStg     ( topCoreBindsToStg )
---import MkIface               ( mkInterface )
-
---import SimplCore     ( core2core )
---import SimplStg              ( stg2stg )
---import StgSyn                ( pprPlainStgBinding, GenStgBinding, GenStgRhs, CostCentre,
-                         StgBinderInfo, StgBinding(..)
-                       )
+--import MkIface       ( mkInterface )
 
 
-#if ! OMIT_NATIVE_CODEGEN
---import AsmCodeGen    ( dumpRealAsm, writeRealAsm )
-#endif
 -}
 
 \end{code}
 -}
 
 \end{code}
@@ -153,12 +153,13 @@ doIt (core_cmds, stg_cmds) input_pgm
     else ( -- No typechecking errors ...
 
     case tc_results
     else ( -- No typechecking errors ...
 
     case tc_results
-    of {  (typechecked_quad@(class_binds, inst_binds, val_binds, const_binds),
+    of {  (typechecked_quint@(recsel_binds, class_binds, inst_binds, val_binds, const_binds),
           interface_stuff@(_,_,_,_,_),  -- @-pat just for strictness...
           (local_tycons,local_classes), pragma_tycon_specs, ddump_deriv) ->
 
     doDump opt_D_dump_tc "Typechecked:"
        (pp_show (ppAboves [
           interface_stuff@(_,_,_,_,_),  -- @-pat just for strictness...
           (local_tycons,local_classes), pragma_tycon_specs, ddump_deriv) ->
 
     doDump opt_D_dump_tc "Typechecked:"
        (pp_show (ppAboves [
+           ppr pprStyle recsel_binds,
            ppr pprStyle class_binds,
            ppr pprStyle inst_binds,
            ppAboves (map (\ (i,e) -> ppr pprStyle (VarMonoBind i e)) const_binds),
            ppr pprStyle class_binds,
            ppr pprStyle inst_binds,
            ppAboves (map (\ (i,e) -> ppr pprStyle (VarMonoBind i e)) const_binds),
@@ -167,12 +168,11 @@ doIt (core_cmds, stg_cmds) input_pgm
     doDump opt_D_dump_deriv "Derived instances:"
        (pp_show (ddump_deriv pprStyle))        `thenMn_`
 
     doDump opt_D_dump_deriv "Derived instances:"
        (pp_show (ddump_deriv pprStyle))        `thenMn_`
 
-
     -- ******* DESUGARER
     show_pass "DeSugar"                        `thenMn_`
     let
        (desugared,ds_warnings)
     -- ******* DESUGARER
     show_pass "DeSugar"                        `thenMn_`
     let
        (desugared,ds_warnings)
-         = deSugar ds_uniqs ds_mod_name typechecked_quad
+         = deSugar ds_uniqs ds_mod_name typechecked_quint
     in
     (if isEmptyBag ds_warnings then
        returnMn ()
     in
     (if isEmptyBag ds_warnings then
        returnMn ()
@@ -182,13 +182,11 @@ doIt (core_cmds, stg_cmds) input_pgm
     )                                          `thenMn_`
 
     doDump opt_D_dump_ds "Desugared:" (pp_show (ppAboves
     )                                          `thenMn_`
 
     doDump opt_D_dump_ds "Desugared:" (pp_show (ppAboves
-       (map (pprPlainCoreBinding pprStyle) desugared)))
+       (map (pprCoreBinding pprStyle) desugared)))
                                                `thenMn_`
 
                                                `thenMn_`
 
-{- LATER ...
-
     -- ******* CORE-TO-CORE SIMPLIFICATION (NB: I/O op)
     -- ******* CORE-TO-CORE SIMPLIFICATION (NB: I/O op)
-    core2core core_cmds switch_lookup_fn co_mod_name pprStyle
+    core2core core_cmds co_mod_name pprStyle
              sm_uniqs local_tycons pragma_tycon_specs desugared
                                                `thenMn`
 
              sm_uniqs local_tycons pragma_tycon_specs desugared
                                                `thenMn`
 
@@ -196,7 +194,7 @@ doIt (core_cmds, stg_cmds) input_pgm
            SpecData _ _ _ gen_tycons all_tycon_specs _ _ _) ->
 
     doDump opt_D_dump_simpl "Simplified:" (pp_show (ppAboves
            SpecData _ _ _ gen_tycons all_tycon_specs _ _ _) ->
 
     doDump opt_D_dump_simpl "Simplified:" (pp_show (ppAboves
-       (map (pprPlainCoreBinding pprStyle) simplified)))
+       (map (pprCoreBinding pprStyle) simplified)))
                                                `thenMn_`
 
     -- ******* STG-TO-STG SIMPLIFICATION
                                                `thenMn_`
 
     -- ******* STG-TO-STG SIMPLIFICATION
@@ -206,7 +204,7 @@ doIt (core_cmds, stg_cmds) input_pgm
     in
 
     show_pass "Stg2Stg"                        `thenMn_`
     in
 
     show_pass "Stg2Stg"                        `thenMn_`
-    stg2stg stg_cmds switch_lookup_fn st_mod_name pprStyle st_uniqs stg_binds
+    stg2stg stg_cmds st_mod_name pprStyle st_uniqs stg_binds
                                                `thenMn`
 
        \ (stg_binds2, cost_centre_info) ->
                                                `thenMn`
 
        \ (stg_binds2, cost_centre_info) ->
@@ -215,6 +213,7 @@ doIt (core_cmds, stg_cmds) input_pgm
        (pp_show (ppAboves (map (pprPlainStgBinding pprStyle) stg_binds2)))
                                                `thenMn_`
 
        (pp_show (ppAboves (map (pprPlainStgBinding pprStyle) stg_binds2)))
                                                `thenMn_`
 
+{- LATER ...
     -- ******* INTERFACE GENERATION (needs STG output)
 {-  let
        mod_name = "_TestName_"
     -- ******* INTERFACE GENERATION (needs STG output)
 {-  let
        mod_name = "_TestName_"
@@ -227,17 +226,19 @@ doIt (core_cmds, stg_cmds) input_pgm
        if_inst_info = emptyBag
     in
 -}
        if_inst_info = emptyBag
     in
 -}
+
     show_pass "Interface"                      `thenMn_`
     let
        mod_interface
     show_pass "Interface"                      `thenMn_`
     let
        mod_interface
-         = mkInterface switch_is_on if_mod_name export_list_fns
+         = mkInterface if_mod_name export_list_fns
                        inlinings_env all_tycon_specs
                        interface_stuff
                        stg_binds2
     in
                        inlinings_env all_tycon_specs
                        interface_stuff
                        stg_binds2
     in
-    doOutput ProduceHi ( \ file ->
+    doOutput opt_ProduceHi ( \ file ->
                         ppAppendFile file 1000{-pprCols-} mod_interface )
                                                        `thenMn_`
                         ppAppendFile file 1000{-pprCols-} mod_interface )
                                                        `thenMn_`
+-}
 
     -- ******* "ABSTRACT", THEN "FLAT", THEN *REAL* C!
     show_pass "CodeGen"                        `thenMn_`
 
     -- ******* "ABSTRACT", THEN "FLAT", THEN *REAL* C!
     show_pass "CodeGen"                        `thenMn_`
@@ -245,7 +246,6 @@ doIt (core_cmds, stg_cmds) input_pgm
        abstractC      = codeGen cc_mod_name     -- module name for CC labelling
                                 cost_centre_info
                                 cc_import_names -- import names for CC registering
        abstractC      = codeGen cc_mod_name     -- module name for CC labelling
                                 cost_centre_info
                                 cc_import_names -- import names for CC registering
-                                switch_lookup_fn
                                 gen_tycons      -- type constructors generated locally
                                 all_tycon_specs -- tycon specialisations
                                 stg_binds2
                                 gen_tycons      -- type constructors generated locally
                                 all_tycon_specs -- tycon specialisations
                                 stg_binds2
@@ -253,42 +253,40 @@ doIt (core_cmds, stg_cmds) input_pgm
        flat_abstractC = flattenAbsC fl_uniqs abstractC
     in
     doDump opt_D_dump_absC  "Abstract C:"
        flat_abstractC = flattenAbsC fl_uniqs abstractC
     in
     doDump opt_D_dump_absC  "Abstract C:"
-       (dumpRealC switch_is_on abstractC)      `thenMn_`
+       (dumpRealC abstractC)                   `thenMn_`
 
     doDump opt_D_dump_flatC "Flat Abstract C:"
 
     doDump opt_D_dump_flatC "Flat Abstract C:"
-       (dumpRealC switch_is_on flat_abstractC) `thenMn_`
+       (dumpRealC flat_abstractC)              `thenMn_`
 
     -- You can have C (c_output) or assembly-language (ncg_output),
     -- but not both.  [Allowing for both gives a space leak on
     -- flat_abstractC.  WDP 94/10]
     let
        (flat_absC_c, flat_absC_ncg) =
 
     -- You can have C (c_output) or assembly-language (ncg_output),
     -- but not both.  [Allowing for both gives a space leak on
     -- flat_abstractC.  WDP 94/10]
     let
        (flat_absC_c, flat_absC_ncg) =
-          case (string_switch_is_on ProduceC || switch_is_on D_dump_realC,
-                string_switch_is_on ProduceS || switch_is_on D_dump_asm) of
-            (True,  False) -> (flat_abstractC, AbsCNop)
-            (False, True)  -> (AbsCNop, flat_abstractC)
-            (False, False) -> (AbsCNop, AbsCNop)
+          case (maybeToBool opt_ProduceC || opt_D_dump_realC,
+                maybeToBool opt_ProduceS || opt_D_dump_asm) of
+            (True,  False) -> (flat_abstractC, absCNop)
+            (False, True)  -> (absCNop, flat_abstractC)
+            (False, False) -> (absCNop, absCNop)
             (True,  True)  -> error "ERROR: Can't do both .hc and .s at the same time"
 
             (True,  True)  -> error "ERROR: Can't do both .hc and .s at the same time"
 
-       c_output_d = dumpRealC switch_is_on flat_absC_c
-       c_output_w = (\ f -> writeRealC switch_is_on f flat_absC_c)
+       c_output_d = dumpRealC flat_absC_c
+       c_output_w = (\ f -> writeRealC f flat_absC_c)
 
 #if OMIT_NATIVE_CODEGEN
        ncg_output_d = error "*** GHC not built with a native-code generator ***"
        ncg_output_w = ncg_output_d
 #else
 
 #if OMIT_NATIVE_CODEGEN
        ncg_output_d = error "*** GHC not built with a native-code generator ***"
        ncg_output_w = ncg_output_d
 #else
-       ncg_output_d = dumpRealAsm switch_lookup_fn flat_absC_ncg ncg_uniqs
-       ncg_output_w = (\ f -> writeRealAsm switch_lookup_fn f flat_absC_ncg ncg_uniqs)
+       ncg_output_d = dumpRealAsm flat_absC_ncg ncg_uniqs
+       ncg_output_w = (\ f -> writeRealAsm f flat_absC_ncg ncg_uniqs)
 #endif
     in
 
     doDump opt_D_dump_asm "" ncg_output_d      `thenMn_`
 #endif
     in
 
     doDump opt_D_dump_asm "" ncg_output_d      `thenMn_`
-    doOutput ProduceS ncg_output_w             `thenMn_`
+    doOutput opt_ProduceS ncg_output_w                 `thenMn_`
 
     doDump opt_D_dump_realC "" c_output_d      `thenMn_`
 
     doDump opt_D_dump_realC "" c_output_d      `thenMn_`
-    doOutput ProduceC c_output_w               `thenMn_`
-
-LATER -}
+    doOutput opt_ProduceC c_output_w           `thenMn_`
     exitMn 0
     } ) } } }
   where
     exitMn 0
     } ) } } }
   where
@@ -319,8 +317,8 @@ LATER -}
 
     doOutput switch io_action
       = case switch of
 
     doOutput switch io_action
       = case switch of
-         Nothing        -> returnMn ()
-         Just fname ->
+         Nothing -> returnMn ()
+         Just fn -> let fname = _UNPK_ fn in
            fopen fname "a+"    `thenPrimIO` \ file ->
            if (file == ``NULL'') then
                error ("doOutput: failed to open:"++fname)
            fopen fname "a+"    `thenPrimIO` \ file ->
            if (file == ``NULL'') then
                error ("doOutput: failed to open:"++fname)
@@ -333,8 +331,8 @@ LATER -}
 
     doDump switch hdr string
       = if switch
 
     doDump switch hdr string
       = if switch
-       then writeMn stderr hdr         `thenMn_`
-            writeMn stderr ('\n': string)      `thenMn_`
+       then writeMn stderr hdr             `thenMn_`
+            writeMn stderr ('\n': string)  `thenMn_`
             writeMn stderr "\n"
        else returnMn ()
 
             writeMn stderr "\n"
        else returnMn ()
 
index 0b8de5f..46bb220 100644 (file)
@@ -163,7 +163,6 @@ mkInterface modname export_list_fns inline_env tycon_specs
        -- mkInterface to do I/O (WDP 94/10)
        error "Can't produce interface file because of errors!\n"
     else
        -- mkInterface to do I/O (WDP 94/10)
        error "Can't produce interface file because of errors!\n"
     else
---  trace ("mkIface:Ids:"++(ppShow 80 (ppr PprDebug global_ids))) (
     ppAboves
        [ppPStr SLIT("{-# GHC_PRAGMA INTERFACE VERSION 7 #-}"),
        ppCat [ppPStr SLIT("interface"), ppPStr modname, ppPStr SLIT("where")],
     ppAboves
        [ppPStr SLIT("{-# GHC_PRAGMA INTERFACE VERSION 7 #-}"),
        ppCat [ppPStr SLIT("interface"), ppPStr modname, ppPStr SLIT("where")],
@@ -181,7 +180,6 @@ mkInterface modname export_list_fns inline_env tycon_specs
 
        ppChar '\n'
        ]
 
        ppChar '\n'
        ]
---  )
   where
     any_purely_local tycons classes vals
       =  any bad_tc tycons || any bad_cl classes || any bad_id vals
   where
     any_purely_local tycons classes vals
       =  any bad_tc tycons || any bad_cl classes || any bad_id vals
@@ -322,7 +320,7 @@ get_tycon_pair tycon
                        ExportAbs   -> orig_nm
                        NotExported -> orig_nm
 
                        ExportAbs   -> orig_nm
                        NotExported -> orig_nm
 
-       cons        = getTyConDataCons tycon
+       cons        = tyConDataCons tycon
     in
     (orig_mod, nm_to_print) }
 
     in
     (orig_mod, nm_to_print) }
 
@@ -411,7 +409,7 @@ do_value better_id_fn inline_env val
                        ppPStr SLIT("#-}")]
     in
     ppAbove (ppCat [ppr_non_op name_str,
                        ppPStr SLIT("#-}")]
     in
     ppAbove (ppCat [ppr_non_op name_str,
-                   ppPStr SLIT("::"), pprType sty val_ty])
+                   ppPStr SLIT("::"), pprGenType sty val_ty])
            pp_id_info
 
 -- sadly duplicates Outputable.pprNonOp (ToDo)
            pp_id_info
 
 -- sadly duplicates Outputable.pprNonOp (ToDo)
index 3997048..9086343 100644 (file)
@@ -1,62 +1,59 @@
 %
 %
-% (c) The AQUA Project, Glasgow University, 1993-1995
+% (c) The AQUA Project, Glasgow University, 1993-1996
 %
 
 \begin{code}
 #include "HsVersions.h"
 
 %
 
 \begin{code}
 #include "HsVersions.h"
 
-module AbsCStixGen (
-       genCodeAbstractC,
+module AbsCStixGen ( genCodeAbstractC ) where
 
 
-       -- and, of course, that's not enough...
-       AbstractC, Target, StixTree, UniqSupply, UniqSM(..)
-    ) where
+import Ubiq{-uitous-}
 
 import AbsCSyn
 
 import AbsCSyn
-import PrelInfo                ( PrimOp(..), primOpNeedsWrapper, isCompareOp
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
+import Stix
+
+import MachMisc
+import MachRegs
+
+import AbsCUtils       ( getAmodeRep, mixedTypeLocn,
+                         nonemptyAbsC, mkAbsCStmts, mkAbsCStmtList
                        )
 import CgCompInfo      ( mIN_UPD_SIZE )
                        )
 import CgCompInfo      ( mIN_UPD_SIZE )
-import ClosureInfo     ( infoTableLabelFromCI, entryLabelFromCI, fastLabelFromCI,
-                         closureUpdReqd
+import ClosureInfo     ( infoTableLabelFromCI, entryLabelFromCI,
+                         fastLabelFromCI, closureUpdReqd
                        )
                        )
-import MachDesc
-import Maybes          ( Maybe(..), maybeToBool )
-import Outputable
-import PrimRep         ( isFloatingRep )
-import SMRep           ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
-import Stix
+import HeapOffs                ( hpRelToInt )
+import Literal         ( Literal(..) )
+import Maybes          ( maybeToBool )
+import OrdList         ( OrdList )
+import PrimOp          ( primOpNeedsWrapper, PrimOp(..) )
+import PrimRep         ( isFloatingRep, PrimRep(..) )
 import StixInfo                ( genCodeInfoTable )
 import StixInfo                ( genCodeInfoTable )
-import UniqSupply
-import Util
+import StixMacro       ( macroCode )
+import StixPrim                ( primCode, amodeToStix, amodeToStix' )
+import UniqSupply      ( returnUs, thenUs, mapUs, getUnique, UniqSM(..) )
+import Util            ( naturalMergeSortLe, panic )
 \end{code}
 
 \end{code}
 
-For each independent chunk of AbstractC code, we generate a list of @StixTree@s,
-where each tree corresponds to a single Stix instruction.  We leave the chunks
-separated so that register allocation can be performed locally within the chunk.
+For each independent chunk of AbstractC code, we generate a list of
+@StixTree@s, where each tree corresponds to a single Stix instruction.
+We leave the chunks separated so that register allocation can be
+performed locally within the chunk.
 
 \begin{code}
 
 \begin{code}
--- hacking with Uncle Will:
-#define target_STRICT target@(Target _ _ _ _ _ _ _ _)
+genCodeAbstractC :: AbstractC -> UniqSM [[StixTree]]
 
 
-genCodeAbstractC
-    :: Target
-    -> AbstractC
-    -> UniqSM [[StixTree]]
-
-genCodeAbstractC target_STRICT absC =
-    mapUs gentopcode (mkAbsCStmtList absC) `thenUs` \ trees ->
+genCodeAbstractC absC
+  = mapUs gentopcode (mkAbsCStmtList absC) `thenUs` \ trees ->
     returnUs ([StComment SLIT("Native Code")] : trees)
  where
     returnUs ([StComment SLIT("Native Code")] : trees)
  where
- -- "target" munging things... ---
- a2stix  = amodeToStix  target
- a2stix' = amodeToStix' target
- volsaves    = volatileSaves target
- volrestores = volatileRestores target
- p2stix      = primToStix target
- macro_code  = macroCode target
- hp_rel             = hpRel target
+ a2stix      = amodeToStix
+ a2stix'     = amodeToStix'
+ volsaves    = volatileSaves
+ volrestores = volatileRestores
+ p2stix      = primCode
+ macro_code  = macroCode
+ hp_rel             = hpRelToInt
  -- real code follows... ---------
 \end{code}
 
  -- real code follows... ---------
 \end{code}
 
@@ -66,34 +63,33 @@ Here we handle top-level things, like @CCodeBlock@s and
 \begin{code}
  {-
  genCodeTopAbsC
 \begin{code}
  {-
  genCodeTopAbsC
-    :: Target
-    -> AbstractC
+    :: AbstractC
     -> UniqSM [StixTree]
  -}
 
     -> UniqSM [StixTree]
  -}
 
- gentopcode (CCodeBlock label absC) =
-    gencode absC                               `thenUs` \ code ->
+ gentopcode (CCodeBlock label absC)
+  = gencode absC                               `thenUs` \ code ->
     returnUs (StSegment TextSegment : StFunBegin label : code [StFunEnd label])
 
     returnUs (StSegment TextSegment : StFunBegin label : code [StFunEnd label])
 
- gentopcode stmt@(CStaticClosure label _ _ _) =
-    genCodeStaticClosure stmt                  `thenUs` \ code ->
+ gentopcode stmt@(CStaticClosure label _ _ _)
+  = genCodeStaticClosure stmt                  `thenUs` \ code ->
     returnUs (StSegment DataSegment : StLabel label : code [])
 
  gentopcode stmt@(CRetUnVector _ _) = returnUs []
 
     returnUs (StSegment DataSegment : StLabel label : code [])
 
  gentopcode stmt@(CRetUnVector _ _) = returnUs []
 
- gentopcode stmt@(CFlatRetVector label _) =
-    genCodeVecTbl stmt                         `thenUs` \ code ->
+ gentopcode stmt@(CFlatRetVector label _)
+  = genCodeVecTbl stmt                         `thenUs` \ code ->
     returnUs (StSegment TextSegment : code [StLabel label])
 
  gentopcode stmt@(CClosureInfoAndCode cl_info slow Nothing _ _ _)
 
   | slow_is_empty
     returnUs (StSegment TextSegment : code [StLabel label])
 
  gentopcode stmt@(CClosureInfoAndCode cl_info slow Nothing _ _ _)
 
   | slow_is_empty
-  = genCodeInfoTable hp_rel a2stix stmt                `thenUs` \ itbl ->
+  = genCodeInfoTable stmt              `thenUs` \ itbl ->
     returnUs (StSegment TextSegment : itbl [])
 
   | otherwise
     returnUs (StSegment TextSegment : itbl [])
 
   | otherwise
-  = genCodeInfoTable hp_rel a2stix stmt                `thenUs` \ itbl ->
-    gencode slow                               `thenUs` \ slow_code ->
+  = genCodeInfoTable stmt              `thenUs` \ itbl ->
+    gencode slow                       `thenUs` \ slow_code ->
     returnUs (StSegment TextSegment : itbl (StFunBegin slow_lbl :
              slow_code [StFunEnd slow_lbl]))
   where
     returnUs (StSegment TextSegment : itbl (StFunBegin slow_lbl :
              slow_code [StFunEnd slow_lbl]))
   where
@@ -102,9 +98,9 @@ Here we handle top-level things, like @CCodeBlock@s and
 
  gentopcode stmt@(CClosureInfoAndCode cl_info slow (Just fast) _ _ _) =
  -- ToDo: what if this is empty? ------------------------^^^^
 
  gentopcode stmt@(CClosureInfoAndCode cl_info slow (Just fast) _ _ _) =
  -- ToDo: what if this is empty? ------------------------^^^^
-    genCodeInfoTable hp_rel a2stix stmt                `thenUs` \ itbl ->
-    gencode slow                               `thenUs` \ slow_code ->
-    gencode fast                               `thenUs` \ fast_code ->
+    genCodeInfoTable stmt              `thenUs` \ itbl ->
+    gencode slow                       `thenUs` \ slow_code ->
+    gencode fast                       `thenUs` \ fast_code ->
     returnUs (StSegment TextSegment : itbl (StFunBegin slow_lbl :
              slow_code (StFunEnd slow_lbl : StFunBegin fast_lbl :
              fast_code [StFunEnd fast_lbl])))
     returnUs (StSegment TextSegment : itbl (StFunBegin slow_lbl :
              slow_code (StFunEnd slow_lbl : StFunBegin fast_lbl :
              fast_code [StFunEnd fast_lbl])))
@@ -112,8 +108,8 @@ Here we handle top-level things, like @CCodeBlock@s and
     slow_lbl = entryLabelFromCI cl_info
     fast_lbl = fastLabelFromCI cl_info
 
     slow_lbl = entryLabelFromCI cl_info
     fast_lbl = fastLabelFromCI cl_info
 
- gentopcode absC =
-    gencode absC                               `thenUs` \ code ->
+ gentopcode absC
+  = gencode absC                               `thenUs` \ code ->
     returnUs (StSegment TextSegment : code [])
 
 \end{code}
     returnUs (StSegment TextSegment : code [])
 
 \end{code}
@@ -123,12 +119,11 @@ Vector tables are trivial!
 \begin{code}
  {-
  genCodeVecTbl
 \begin{code}
  {-
  genCodeVecTbl
-    :: Target
-    -> AbstractC
+    :: AbstractC
     -> UniqSM StixTreeList
  -}
     -> UniqSM StixTreeList
  -}
- genCodeVecTbl (CFlatRetVector label amodes) =
-    returnUs (\xs -> vectbl : xs)
+ genCodeVecTbl (CFlatRetVector label amodes)
+  = returnUs (\xs -> vectbl : xs)
   where
     vectbl = StData PtrRep (reverse (map a2stix amodes))
 
   where
     vectbl = StData PtrRep (reverse (map a2stix amodes))
 
@@ -139,12 +134,11 @@ Static closures are not so hard either.
 \begin{code}
  {-
  genCodeStaticClosure
 \begin{code}
  {-
  genCodeStaticClosure
-    :: Target
-    -> AbstractC
+    :: AbstractC
     -> UniqSM StixTreeList
  -}
     -> UniqSM StixTreeList
  -}
- genCodeStaticClosure (CStaticClosure _ cl_info cost_centre amodes) =
-    returnUs (\xs -> table : xs)
+ genCodeStaticClosure (CStaticClosure _ cl_info cost_centre amodes)
+  = returnUs (\xs -> table : xs)
   where
     table = StData PtrRep (StCLbl info_lbl : body)
     info_lbl = infoTableLabelFromCI cl_info
   where
     table = StData PtrRep (StCLbl info_lbl : body)
     info_lbl = infoTableLabelFromCI cl_info
@@ -170,8 +164,7 @@ Now the individual AbstractC statements.
 \begin{code}
  {-
  gencode
 \begin{code}
  {-
  gencode
-    :: Target
-    -> AbstractC
+    :: AbstractC
     -> UniqSM StixTreeList
  -}
 \end{code}
     -> UniqSM StixTreeList
  -}
 \end{code}
@@ -197,8 +190,8 @@ resulting StixTreeLists are joined together.
 
 \begin{code}
 
 
 \begin{code}
 
- gencode (AbsCStmts c1 c2) =
-    gencode c1                         `thenUs` \ b1 ->
+ gencode (AbsCStmts c1 c2)
+  = gencode c1                         `thenUs` \ b1 ->
     gencode c2                         `thenUs` \ b2 ->
     returnUs (b1 . b2)
 
     gencode c2                         `thenUs` \ b2 ->
     returnUs (b1 . b2)
 
@@ -212,8 +205,8 @@ addresses, etc.)
 
 \begin{code}
 
 
 \begin{code}
 
- gencode (CInitHdr cl_info reg_rel _ _) =
-    let
+ gencode (CInitHdr cl_info reg_rel _ _)
+  = let
        lhs = a2stix (CVal reg_rel PtrRep)
        lbl = infoTableLabelFromCI cl_info
     in
        lhs = a2stix (CVal reg_rel PtrRep)
        lbl = infoTableLabelFromCI cl_info
     in
@@ -232,8 +225,8 @@ of the source?  Be careful about floats/doubles.
 
  gencode (CAssign lhs rhs)
   | getAmodeRep lhs == VoidRep = returnUs id
 
  gencode (CAssign lhs rhs)
   | getAmodeRep lhs == VoidRep = returnUs id
-  | otherwise =
-    let pk = getAmodeRep lhs
+  | otherwise
+  = let pk = getAmodeRep lhs
        pk' = if mixedTypeLocn lhs && not (isFloatingRep pk) then IntRep else pk
        lhs' = a2stix lhs
        rhs' = a2stix' rhs
        pk' = if mixedTypeLocn lhs && not (isFloatingRep pk) then IntRep else pk
        lhs' = a2stix lhs
        rhs' = a2stix' rhs
@@ -248,23 +241,23 @@ with the address of the info table before jumping to the entry code for Node.
 
 \begin{code}
 
 
 \begin{code}
 
- gencode (CJump dest) =
-    returnUs (\xs -> StJump (a2stix dest) : xs)
+ gencode (CJump dest)
+  = returnUs (\xs -> StJump (a2stix dest) : xs)
 
 
- gencode (CFallThrough (CLbl lbl _)) =
-    returnUs (\xs -> StFallThrough lbl : xs)
+ gencode (CFallThrough (CLbl lbl _))
+  = returnUs (\xs -> StFallThrough lbl : xs)
 
 
- gencode (CReturn dest DirectReturn) =
-    returnUs (\xs -> StJump (a2stix dest) : xs)
+ gencode (CReturn dest DirectReturn)
+  = returnUs (\xs -> StJump (a2stix dest) : xs)
 
 
- gencode (CReturn table (StaticVectoredReturn n)) =
-    returnUs (\xs -> StJump dest : xs)
+ gencode (CReturn table (StaticVectoredReturn n))
+  = returnUs (\xs -> StJump dest : xs)
   where
     dest = StInd PtrRep (StIndex PtrRep (a2stix table)
                                          (StInt (toInteger (-n-1))))
 
   where
     dest = StInd PtrRep (StIndex PtrRep (a2stix table)
                                          (StInt (toInteger (-n-1))))
 
- gencode (CReturn table (DynamicVectoredReturn am)) =
-    returnUs (\xs -> StJump dest : xs)
+ gencode (CReturn table (DynamicVectoredReturn am))
+  = returnUs (\xs -> StJump dest : xs)
   where
     dest = StInd PtrRep (StIndex PtrRep (a2stix table) dyn_off)
     dyn_off = StPrim IntSubOp [StPrim IntNegOp [a2stix am], StInt 1]
   where
     dest = StInd PtrRep (StIndex PtrRep (a2stix table) dyn_off)
     dyn_off = StPrim IntSubOp [StPrim IntNegOp [a2stix am], StInt 1]
@@ -277,8 +270,8 @@ Now the PrimOps, some of which may need caller-saves register wrappers.
 
  gencode (COpStmt results op args liveness_mask vols)
   -- ToDo (ADR?): use that liveness mask
 
  gencode (COpStmt results op args liveness_mask vols)
   -- ToDo (ADR?): use that liveness mask
-  | primOpNeedsWrapper op =
-    let
+  | primOpNeedsWrapper op
+  = let
        saves = volsaves vols
        restores = volrestores vols
     in
        saves = volsaves vols
        restores = volrestores vols
     in
@@ -356,11 +349,11 @@ Finally, all of the disgusting AbstractC macros.
 
  gencode (CMacroStmt macro args) = macro_code macro args
 
 
  gencode (CMacroStmt macro args) = macro_code macro args
 
- gencode (CCallProfCtrMacro macro _) =
-    returnUs (\xs -> StComment macro : xs)
+ gencode (CCallProfCtrMacro macro _)
+  = returnUs (\xs -> StComment macro : xs)
 
 
- gencode (CCallProfCCMacro macro _) =
-    returnUs (\xs -> StComment macro : xs)
+ gencode (CCallProfCCMacro macro _)
+  = returnUs (\xs -> StComment macro : xs)
 
 \end{code}
 
 
 \end{code}
 
@@ -383,12 +376,11 @@ comparison tree.  (Perhaps this could be tuned.)
 
  {-
  mkSimpleSwitches
 
  {-
  mkSimpleSwitches
-    :: Target
-    -> CAddrMode -> [(Literal,AbstractC)] -> AbstractC
+    :: CAddrMode -> [(Literal,AbstractC)] -> AbstractC
     -> UniqSM StixTreeList
  -}
     -> UniqSM StixTreeList
  -}
- mkSimpleSwitches am alts absC =
-    getUniqLabelNCG                                    `thenUs` \ udlbl ->
+ mkSimpleSwitches am alts absC
+  = getUniqLabelNCG                                    `thenUs` \ udlbl ->
     getUniqLabelNCG                                    `thenUs` \ ujlbl ->
     let am' = a2stix am
        joinedAlts = map (\ (tag,code) -> (tag, mkJoin code ujlbl)) alts
     getUniqLabelNCG                                    `thenUs` \ ujlbl ->
     let am' = a2stix am
        joinedAlts = map (\ (tag,code) -> (tag, mkJoin code ujlbl)) alts
@@ -401,14 +393,6 @@ comparison tree.  (Perhaps this could be tuned.)
        -- lowest and highest possible values the discriminant could take
        lowest = if floating then targetMinDouble else targetMinInt
        highest = if floating then targetMaxDouble else targetMaxInt
        -- lowest and highest possible values the discriminant could take
        lowest = if floating then targetMinDouble else targetMinInt
        highest = if floating then targetMaxDouble else targetMaxInt
-
-       -- These should come from somewhere else, depending on the target arch
-       -- (Note that the floating point values aren't terribly important.)
-       -- ToDo: Fix!(JSM)
-       targetMinDouble = MachDouble (-1.7976931348623157e+308)
-       targetMaxDouble = MachDouble (1.7976931348623157e+308)
-       targetMinInt = mkMachInt (-2147483647)
-       targetMaxInt = mkMachInt 2147483647
     in
        (
        if not floating && choices > 4 && highTag - lowTag < toInteger (2 * choices) then
     in
        (
        if not floating && choices > 4 && highTag - lowTag < toInteger (2 * choices) then
@@ -431,20 +415,20 @@ comparison tree.  (Perhaps this could be tuned.)
 
 \end{code}
 
 
 \end{code}
 
-We use jump tables when doing an integer switch on a relatively dense list of
-alternatives.  We expect to be given a list of alternatives, sorted by tag,
-and a range of values for which we are to generate a table.  Of course, the tags of
-the alternatives should lie within the indicated range.  The alternatives need
-not cover the range; a default target is provided for the missing alternatives.
+We use jump tables when doing an integer switch on a relatively dense
+list of alternatives.  We expect to be given a list of alternatives,
+sorted by tag, and a range of values for which we are to generate a
+table.  Of course, the tags of the alternatives should lie within the
+indicated range.  The alternatives need not cover the range; a default
+target is provided for the missing alternatives.
 
 
-If a join is necessary after the switch, the alternatives should already finish
-with a jump to the join point.
+If a join is necessary after the switch, the alternatives should
+already finish with a jump to the join point.
 
 \begin{code}
  {-
  mkJumpTable
 
 \begin{code}
  {-
  mkJumpTable
-    :: Target
-    -> StixTree                -- discriminant
+    :: StixTree                -- discriminant
     -> [(Literal, AbstractC)]  -- alternatives
     -> Integer                         -- low tag
     -> Integer                         -- high tag
     -> [(Literal, AbstractC)]  -- alternatives
     -> Integer                         -- low tag
     -> Integer                         -- high tag
@@ -452,8 +436,8 @@ with a jump to the join point.
     -> UniqSM StixTreeList
  -}
 
     -> UniqSM StixTreeList
  -}
 
- mkJumpTable am alts lowTag highTag dflt =
-    getUniqLabelNCG                                    `thenUs` \ utlbl ->
+ mkJumpTable am alts lowTag highTag dflt
+  = getUniqLabelNCG                                    `thenUs` \ utlbl ->
     mapUs genLabel alts                                `thenUs` \ branches ->
     let        cjmpLo = StCondJump dflt (StPrim IntLtOp [am, StInt lowTag])
        cjmpHi = StCondJump dflt (StPrim IntGtOp [am, StInt highTag])
     mapUs genLabel alts                                `thenUs` \ branches ->
     let        cjmpLo = StCondJump dflt (StPrim IntLtOp [am, StInt lowTag])
        cjmpHi = StCondJump dflt (StPrim IntGtOp [am, StInt highTag])
@@ -500,8 +484,7 @@ alternatives should already finish with a jump to the join point.
 \begin{code}
  {-
  mkBinaryTree
 \begin{code}
  {-
  mkBinaryTree
-    :: Target
-    -> StixTree                -- discriminant
+    :: StixTree                -- discriminant
     -> Bool                    -- floating point?
     -> [(Literal, AbstractC)]  -- alternatives
     -> Int                     -- number of choices
     -> Bool                    -- floating point?
     -> [(Literal, AbstractC)]  -- alternatives
     -> Int                     -- number of choices
@@ -513,8 +496,8 @@ alternatives should already finish with a jump to the join point.
 
  mkBinaryTree am floating [(tag,alt)] _ lowTag highTag udlbl
   | rangeOfOne = gencode alt
 
  mkBinaryTree am floating [(tag,alt)] _ lowTag highTag udlbl
   | rangeOfOne = gencode alt
-  | otherwise =
-    let        tag' = a2stix (CLit tag)
+  | otherwise
+  = let        tag' = a2stix (CLit tag)
        cmpOp = if floating then DoubleNeOp else IntNeOp
        test = StPrim cmpOp [am, tag']
        cjmp = StCondJump udlbl test
        cmpOp = if floating then DoubleNeOp else IntNeOp
        test = StPrim cmpOp [am, tag']
        cjmp = StCondJump udlbl test
@@ -526,8 +509,8 @@ alternatives should already finish with a jump to the join point.
        rangeOfOne = not floating && intTag lowTag + 1 >= intTag highTag
        -- When there is only one possible tag left in range, we skip the comparison
 
        rangeOfOne = not floating && intTag lowTag + 1 >= intTag highTag
        -- When there is only one possible tag left in range, we skip the comparison
 
- mkBinaryTree am floating alts choices lowTag highTag udlbl =
-    getUniqLabelNCG                                    `thenUs` \ uhlbl ->
+ mkBinaryTree am floating alts choices lowTag highTag udlbl
+  = getUniqLabelNCG                                    `thenUs` \ uhlbl ->
     let tag' = a2stix (CLit splitTag)
        cmpOp = if floating then DoubleGeOp else IntGeOp
        test = StPrim cmpOp [am, tag']
     let tag' = a2stix (CLit splitTag)
        cmpOp = if floating then DoubleGeOp else IntGeOp
        test = StPrim cmpOp [am, tag']
@@ -550,16 +533,15 @@ alternatives should already finish with a jump to the join point.
 \begin{code}
  {-
  mkIfThenElse
 \begin{code}
  {-
  mkIfThenElse
-    :: Target
-    -> CAddrMode           -- discriminant
+    :: CAddrMode           -- discriminant
     -> Literal             -- tag
     -> AbstractC           -- if-part
     -> AbstractC           -- else-part
     -> UniqSM StixTreeList
  -}
 
     -> Literal             -- tag
     -> AbstractC           -- if-part
     -> AbstractC           -- else-part
     -> UniqSM StixTreeList
  -}
 
- mkIfThenElse discrim tag alt deflt =
-    getUniqLabelNCG                                    `thenUs` \ ujlbl ->
+ mkIfThenElse discrim tag alt deflt
+  = getUniqLabelNCG                                    `thenUs` \ ujlbl ->
     getUniqLabelNCG                                    `thenUs` \ utlbl ->
     let discrim' = a2stix discrim
        tag' = a2stix (CLit tag)
     getUniqLabelNCG                                    `thenUs` \ utlbl ->
     let discrim' = a2stix discrim
        tag' = a2stix (CLit tag)
@@ -604,8 +586,8 @@ mightFallThrough absC = ft absC True
   ft _ if_empty = if_empty
 
 {- Old algorithm, which called nonemptyAbsC for every subexpression! =========
   ft _ if_empty = if_empty
 
 {- Old algorithm, which called nonemptyAbsC for every subexpression! =========
-fallThroughAbsC (AbsCStmts c1 c2) =
-    case nonemptyAbsC c2 of
+fallThroughAbsC (AbsCStmts c1 c2)
+  = case nonemptyAbsC c2 of
        Nothing -> fallThroughAbsC c1
        Just x -> fallThroughAbsC x
 fallThroughAbsC (CJump _)       = False
        Nothing -> fallThroughAbsC c1
        Just x -> fallThroughAbsC x
 fallThroughAbsC (CJump _)       = False
diff --git a/ghc/compiler/nativeGen/AlphaCode.lhs b/ghc/compiler/nativeGen/AlphaCode.lhs
deleted file mode 100644 (file)
index 5b5069a..0000000
+++ /dev/null
@@ -1,1402 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1993-1995
-%
-
-\section[AlphaCode]{The Native (Alpha) Machine Code}
-
-\begin{code}
-#include "HsVersions.h"
-
-module AlphaCode (
-       Addr(..),Cond(..),Imm(..),RI(..),Size(..),
-       AlphaCode(..),AlphaInstr(..),AlphaRegs,
-       strImmLab,
-
-       printLabeledCodes,
-
-       baseRegOffset, stgRegMap, callerSaves,
-
-       kindToSize,
-
-       v0, f0, sp, ra, pv, gp, zero, argRegs,
-
-       freeRegs, reservedRegs
-
-       -- and, for self-sufficiency ...
-    ) where
-
-IMPORT_Trace
-
-import AbsCSyn     ( MagicId(..) )
-import AsmRegAlloc  ( MachineCode(..), MachineRegisters(..), FutureLive(..),
-                     Reg(..), RegUsage(..), RegLiveness(..)
-                   )
-import BitSet
-import CLabel   ( CLabel, pprCLabel, externallyVisibleCLabel, charToC )
-import CgCompInfo   ( mAX_Double_REG, mAX_Float_REG, mAX_Vanilla_REG )
-import FiniteMap
-import Maybes      ( Maybe(..), maybeToBool )
-import OrdList     ( OrdList, mkUnitList, flattenOrdList )
-import Outputable
-import PrimRep     ( PrimRep(..) )
-import UniqSet
-import Stix
-import Unpretty
-import Util
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[AlphaReg]{The Native (Alpha) Machine Register Table}
-%*                                                                     *
-%************************************************************************
-
-The alpha has 64 registers of interest; 32 integer registers and 32 floating
-point registers.  The mapping of STG registers to alpha machine registers
-is defined in StgRegs.h.  We are, of course, prepared for any eventuality.
-
-\begin{code}
-
-fReg :: Int -> Int
-fReg x = (32 + x)
-
-v0, f0, ra, pv, gp, sp, zero :: Reg
-v0   = realReg 0
-f0   = realReg (fReg 0)
-ra   = FixedReg ILIT(26)
-pv   = t12
-gp   = FixedReg ILIT(29)
-sp   = FixedReg ILIT(30)
-zero = FixedReg ILIT(31)
-
-t9, t10, t11, t12 :: Reg
-t9  = realReg 23
-t10 = realReg 24
-t11 = realReg 25
-t12 = realReg 27
-
-argRegs :: [(Reg, Reg)]
-argRegs = [(realReg i, realReg (fReg i)) | i <- [16..21]]
-
-realReg :: Int -> Reg
-realReg n@IBOX(i) = if _IS_TRUE_(freeReg i) then MappedReg i else FixedReg i
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[TheAlphaCode]{The datatype for alpha assembly language}
-%*                                                                     *
-%************************************************************************
-
-Here is a definition of the Alpha assembly language.
-
-\begin{code}
-
-data Imm = ImmInt Int
-        | ImmInteger Integer         -- Sigh.
-        | ImmCLbl CLabel             -- AbstractC Label (with baggage)
-        | ImmLab  Unpretty           -- Simple string label
-        deriving ()
-
-strImmLab s = ImmLab (uppStr s)
-
-data Addr = AddrImm Imm
-         | AddrReg Reg
-         | AddrRegImm Reg Imm
-         deriving ()
-
-data Cond = EQ                       -- For CMP and BI
-         | LT                        -- For CMP and BI
-         | LE                        -- For CMP and BI
-         | ULT                       -- For CMP only
-         | ULE                       -- For CMP only
-         | NE                        -- For BI only
-         | GT                        -- For BI only
-         | GE                        -- For BI only
-         | ALWAYS                    -- For BI (same as BR)
-         | NEVER                     -- For BI (null instruction)
-         deriving ()
-
-data RI = RIReg Reg
-       | RIImm Imm
-       deriving ()
-
-data Size = B
-         | BU
-         | W
-         | WU
-         | L
-         | Q
-         | FF
-         | DF
-         | GF
-         | SF
-         | TF
-         deriving ()
-
-data AlphaInstr =
-
--- Loads and stores.
-
-               LD            Size Reg Addr -- size, dst, src
-             | LDA           Reg Addr      -- dst, src
-             | LDAH          Reg Addr      -- dst, src
-             | LDGP          Reg Addr      -- dst, src
-             | LDI           Size Reg Imm  -- size, dst, src
-             | ST            Size Reg Addr -- size, src, dst
-
--- Int Arithmetic.
-
-             | CLR           Reg                   -- dst
-             | ABS           Size RI Reg           -- size, src, dst
-             | NEG           Size Bool RI Reg      -- size, overflow, src, dst
-             | ADD           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
-             | SADD          Size Size Reg RI Reg  -- size, scale, src, src, dst
-             | SUB           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
-             | SSUB          Size Size Reg RI Reg  -- size, scale, src, src, dst
-             | MUL           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
-             | DIV           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
-             | REM           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
-
--- Simple bit-twiddling.
-
-             | NOT           RI Reg
-             | AND           Reg RI Reg
-             | ANDNOT        Reg RI Reg
-             | OR            Reg RI Reg
-             | ORNOT         Reg RI Reg
-             | XOR           Reg RI Reg
-             | XORNOT        Reg RI Reg
-             | SLL           Reg RI Reg
-             | SRL           Reg RI Reg
-             | SRA           Reg RI Reg
-
-             | ZAP           Reg RI Reg
-             | ZAPNOT        Reg RI Reg
-
-             | NOP
-
--- Comparison
-
-             | CMP           Cond Reg RI Reg
-
--- Float Arithmetic.
-
-             | FCLR          Reg
-             | FABS          Reg Reg
-             | FNEG          Size Reg Reg
-             | FADD          Size Reg Reg Reg
-             | FDIV          Size Reg Reg Reg
-             | FMUL          Size Reg Reg Reg
-             | FSUB          Size Reg Reg Reg
-             | CVTxy         Size Size Reg Reg
-             | FCMP          Size Cond Reg Reg Reg
-             | FMOV          Reg Reg
-
--- Jumping around.
-
-             | BI            Cond Reg Imm
-             | BF            Cond Reg Imm
-             | BR            Imm
-             | JMP           Reg Addr Int
-             | BSR           Imm Int
-             | JSR           Reg Addr Int
-
--- Pseudo-ops.
-
-             | LABEL CLabel
-             | FUNBEGIN CLabel
-             | FUNEND CLabel
-             | COMMENT FAST_STRING
-             | SEGMENT CodeSegment
-             | ASCII Bool String   -- needs backslash conversion?
-             | DATA Size [Imm]
-
-type AlphaCode = OrdList AlphaInstr
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[TheAlphaPretty]{Pretty-printing the Alpha Assembly Language}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-
-printLabeledCodes :: PprStyle -> [AlphaInstr] -> Unpretty
-printLabeledCodes sty codes = uppAboves (map (pprAlphaInstr sty) codes)
-
-\end{code}
-
-Printing the pieces...
-
-\begin{code}
-
-pprReg :: Reg -> Unpretty
-
-pprReg (FixedReg i) = pprAlphaReg i
-pprReg (MappedReg i) = pprAlphaReg i
-pprReg other = uppStr (show other)   -- should only happen when debugging
-
-pprAlphaReg :: FAST_INT -> Unpretty
-pprAlphaReg i = uppPStr
-    (case i of {
-       ILIT( 0) -> SLIT("$0");   ILIT( 1) -> SLIT("$1");
-       ILIT( 2) -> SLIT("$2");   ILIT( 3) -> SLIT("$3");
-       ILIT( 4) -> SLIT("$4");   ILIT( 5) -> SLIT("$5");
-       ILIT( 6) -> SLIT("$6");   ILIT( 7) -> SLIT("$7");
-       ILIT( 8) -> SLIT("$8");   ILIT( 9) -> SLIT("$9");
-       ILIT(10) -> SLIT("$10");  ILIT(11) -> SLIT("$11");
-       ILIT(12) -> SLIT("$12");  ILIT(13) -> SLIT("$13");
-       ILIT(14) -> SLIT("$14");  ILIT(15) -> SLIT("$15");
-       ILIT(16) -> SLIT("$16");  ILIT(17) -> SLIT("$17");
-       ILIT(18) -> SLIT("$18");  ILIT(19) -> SLIT("$19");
-       ILIT(20) -> SLIT("$20");  ILIT(21) -> SLIT("$21");
-       ILIT(22) -> SLIT("$22");  ILIT(23) -> SLIT("$23");
-       ILIT(24) -> SLIT("$24");  ILIT(25) -> SLIT("$25");
-       ILIT(26) -> SLIT("$26");  ILIT(27) -> SLIT("$27");
-       ILIT(28) -> SLIT("$28");  ILIT(29) -> SLIT("$29");
-       ILIT(30) -> SLIT("$30");  ILIT(31) -> SLIT("$31");
-       ILIT(32) -> SLIT("$f0");  ILIT(33) -> SLIT("$f1");
-       ILIT(34) -> SLIT("$f2");  ILIT(35) -> SLIT("$f3");
-       ILIT(36) -> SLIT("$f4");  ILIT(37) -> SLIT("$f5");
-       ILIT(38) -> SLIT("$f6");  ILIT(39) -> SLIT("$f7");
-       ILIT(40) -> SLIT("$f8");  ILIT(41) -> SLIT("$f9");
-       ILIT(42) -> SLIT("$f10"); ILIT(43) -> SLIT("$f11");
-       ILIT(44) -> SLIT("$f12"); ILIT(45) -> SLIT("$f13");
-       ILIT(46) -> SLIT("$f14"); ILIT(47) -> SLIT("$f15");
-       ILIT(48) -> SLIT("$f16"); ILIT(49) -> SLIT("$f17");
-       ILIT(50) -> SLIT("$f18"); ILIT(51) -> SLIT("$f19");
-       ILIT(52) -> SLIT("$f20"); ILIT(53) -> SLIT("$f21");
-       ILIT(54) -> SLIT("$f22"); ILIT(55) -> SLIT("$f23");
-       ILIT(56) -> SLIT("$f24"); ILIT(57) -> SLIT("$f25");
-       ILIT(58) -> SLIT("$f26"); ILIT(59) -> SLIT("$f27");
-       ILIT(60) -> SLIT("$f28"); ILIT(61) -> SLIT("$f29");
-       ILIT(62) -> SLIT("$f30"); ILIT(63) -> SLIT("$f31");
-       _ -> SLIT("very naughty alpha register")
-    })
-
-pprCond :: Cond -> Unpretty
-pprCond EQ  = uppPStr SLIT("eq")
-pprCond LT  = uppPStr SLIT("lt")
-pprCond LE  = uppPStr SLIT("le")
-pprCond ULT = uppPStr SLIT("ult")
-pprCond ULE = uppPStr SLIT("ule")
-pprCond NE  = uppPStr SLIT("ne")
-pprCond GT  = uppPStr SLIT("gt")
-pprCond GE  = uppPStr SLIT("ge")
-
-pprImm :: PprStyle -> Imm -> Unpretty
-
-pprImm sty (ImmInt i) = uppInt i
-pprImm sty (ImmInteger i) = uppInteger i
-
-pprImm sty (ImmCLbl l) = pprCLabel sty l
-
-pprImm sty (ImmLab s) = s
-
-pprAddr :: PprStyle -> Addr -> Unpretty
-pprAddr sty (AddrReg reg) = uppBesides [uppLparen, pprReg reg, uppRparen]
-
-pprAddr sty (AddrImm imm) = pprImm sty imm
-
-pprAddr sty (AddrRegImm r1 imm) =
-    uppBesides [
-       pprImm sty imm,
-       uppLparen,
-       pprReg r1,
-       uppRparen
-    ]
-
-pprRI :: PprStyle -> RI -> Unpretty
-pprRI sty (RIReg r) = pprReg r
-pprRI sty (RIImm r) = pprImm sty r
-
-pprRegRIReg :: PprStyle -> FAST_STRING -> Reg -> RI -> Reg -> Unpretty
-pprRegRIReg sty name reg1 ri reg2 =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Unpretty
-pprSizeRegRegReg name size reg1 reg2 reg3 =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       pprSize size,
-       uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprReg reg2,
-       uppComma,
-       pprReg reg3
-    ]
-
-pprSize :: Size -> Unpretty
-pprSize x = uppPStr
-    (case x of
-        B  -> SLIT("b")
-        BU -> SLIT("bu")
-        W  -> SLIT("w")
-        WU -> SLIT("wu")
-        L  -> SLIT("l")
-        Q  -> SLIT("q")
-        FF -> SLIT("f")
-        DF -> SLIT("d")
-        GF -> SLIT("g")
-        SF -> SLIT("s")
-        TF -> SLIT("t")
-    )
-
-pprAlphaInstr :: PprStyle -> AlphaInstr -> Unpretty
-
-pprAlphaInstr sty (LD size reg addr) =
-    uppBesides [
-       uppPStr SLIT("\tld"),
-       pprSize size,
-       uppChar '\t',
-       pprReg reg,
-       uppComma,
-       pprAddr sty addr
-    ]
-
-pprAlphaInstr sty (LDA reg addr) =
-    uppBesides [
-       uppPStr SLIT("\tlda\t"),
-       pprReg reg,
-       uppComma,
-       pprAddr sty addr
-    ]
-
-pprAlphaInstr sty (LDAH reg addr) =
-    uppBesides [
-       uppPStr SLIT("\tldah\t"),
-       pprReg reg,
-       uppComma,
-       pprAddr sty addr
-    ]
-
-pprAlphaInstr sty (LDGP reg addr) =
-    uppBesides [
-       uppPStr SLIT("\tldgp\t"),
-       pprReg reg,
-       uppComma,
-       pprAddr sty addr
-    ]
-
-pprAlphaInstr sty (LDI size reg imm) =
-    uppBesides [
-       uppPStr SLIT("\tldi"),
-       pprSize size,
-       uppChar '\t',
-       pprReg reg,
-       uppComma,
-       pprImm sty imm
-    ]
-
-pprAlphaInstr sty (ST size reg addr) =
-    uppBesides [
-       uppPStr SLIT("\tst"),
-       pprSize size,
-       uppChar '\t',
-       pprReg reg,
-       uppComma,
-       pprAddr sty addr
-    ]
-
-pprAlphaInstr sty (CLR reg) =
-    uppBesides [
-       uppPStr SLIT("\tclr\t"),
-       pprReg reg
-    ]
-
-pprAlphaInstr sty (ABS size ri reg) =
-    uppBesides [
-       uppPStr SLIT("\tabs"),
-       pprSize size,
-       uppChar '\t',
-       pprRI sty ri,
-       uppComma,
-       pprReg reg
-    ]
-
-pprAlphaInstr sty (NEG size ov ri reg) =
-    uppBesides [
-       uppPStr SLIT("\tneg"),
-       pprSize size,
-       if ov then uppPStr SLIT("v\t") else uppChar '\t',
-       pprRI sty ri,
-       uppComma,
-       pprReg reg
-    ]
-
-pprAlphaInstr sty (ADD size ov reg1 ri reg2) =
-    uppBesides [
-       uppPStr SLIT("\tadd"),
-       pprSize size,
-       if ov then uppPStr SLIT("v\t") else uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (SADD size scale reg1 ri reg2) =
-    uppBesides [
-       uppPStr (case scale of {L -> SLIT("\ts4"); Q -> SLIT("\ts8")}),
-       uppPStr SLIT("add"),
-       pprSize size,
-       uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (SUB size ov reg1 ri reg2) =
-    uppBesides [
-       uppPStr SLIT("\tsub"),
-       pprSize size,
-       if ov then uppPStr SLIT("v\t") else uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (SSUB size scale reg1 ri reg2) =
-    uppBesides [
-       uppPStr (case scale of {L -> SLIT("\ts4"); Q -> SLIT("\ts8")}),
-       uppPStr SLIT("sub"),
-       pprSize size,
-       uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (MUL size ov reg1 ri reg2) =
-    uppBesides [
-       uppPStr SLIT("\tmul"),
-       pprSize size,
-       if ov then uppPStr SLIT("v\t") else uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (DIV size uns reg1 ri reg2) =
-    uppBesides [
-       uppPStr SLIT("\tdiv"),
-       pprSize size,
-       if uns then uppPStr SLIT("u\t") else uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (REM size uns reg1 ri reg2) =
-    uppBesides [
-       uppPStr SLIT("\trem"),
-       pprSize size,
-       if uns then uppPStr SLIT("u\t") else uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (NOT ri reg) =
-    uppBesides [
-       uppPStr SLIT("\tnot"),
-       uppChar '\t',
-       pprRI sty ri,
-       uppComma,
-       pprReg reg
-    ]
-
-pprAlphaInstr sty (AND reg1 ri reg2) = pprRegRIReg sty SLIT("and") reg1 ri reg2
-pprAlphaInstr sty (ANDNOT reg1 ri reg2) = pprRegRIReg sty SLIT("andnot") reg1 ri reg2
-pprAlphaInstr sty (OR reg1 ri reg2) = pprRegRIReg sty SLIT("or") reg1 ri reg2
-pprAlphaInstr sty (ORNOT reg1 ri reg2) = pprRegRIReg sty SLIT("ornot") reg1 ri reg2
-pprAlphaInstr sty (XOR reg1 ri reg2) = pprRegRIReg sty SLIT("xor") reg1 ri reg2
-pprAlphaInstr sty (XORNOT reg1 ri reg2) = pprRegRIReg sty SLIT("xornot") reg1 ri reg2
-
-pprAlphaInstr sty (SLL reg1 ri reg2) = pprRegRIReg sty SLIT("sll") reg1 ri reg2
-pprAlphaInstr sty (SRL reg1 ri reg2) = pprRegRIReg sty SLIT("srl") reg1 ri reg2
-pprAlphaInstr sty (SRA reg1 ri reg2) = pprRegRIReg sty SLIT("sra") reg1 ri reg2
-
-pprAlphaInstr sty (ZAP reg1 ri reg2) = pprRegRIReg sty SLIT("zap") reg1 ri reg2
-pprAlphaInstr sty (ZAPNOT reg1 ri reg2) = pprRegRIReg sty SLIT("zapnot") reg1 ri reg2
-
-pprAlphaInstr sty (NOP) = uppPStr SLIT("\tnop")
-
-pprAlphaInstr sty (CMP cond reg1 ri reg2) =
-    uppBesides [
-       uppPStr SLIT("\tcmp"),
-       pprCond cond,
-       uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (FCLR reg) =
-    uppBesides [
-       uppPStr SLIT("\tfclr\t"),
-       pprReg reg
-    ]
-
-pprAlphaInstr sty (FABS reg1 reg2) =
-    uppBesides [
-       uppPStr SLIT("\tfabs\t"),
-       pprReg reg1,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (FNEG size reg1 reg2) =
-    uppBesides [
-       uppPStr SLIT("\tneg"),
-       pprSize size,
-       uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
-pprAlphaInstr sty (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
-pprAlphaInstr sty (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
-pprAlphaInstr sty (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
-
-pprAlphaInstr sty (CVTxy size1 size2 reg1 reg2) =
-    uppBesides [
-       uppPStr SLIT("\tcvt"),
-       pprSize size1,
-       case size2 of {Q -> uppPStr SLIT("qc"); _ -> pprSize size2},
-       uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (FCMP size cond reg1 reg2 reg3) =
-    uppBesides [
-       uppPStr SLIT("\tcmp"),
-       pprSize size,
-       pprCond cond,
-       uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprReg reg2,
-       uppComma,
-       pprReg reg3
-    ]
-
-pprAlphaInstr sty (FMOV reg1 reg2) =
-    uppBesides [
-       uppPStr SLIT("\tfmov\t"),
-       pprReg reg1,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprAlphaInstr sty (BI ALWAYS reg lab) = pprAlphaInstr sty (BR lab)
-
-pprAlphaInstr sty (BI NEVER reg lab) = uppNil
-
-pprAlphaInstr sty (BI cond reg lab) =
-    uppBesides [
-       uppPStr SLIT("\tb"),
-       pprCond cond,
-       uppChar '\t',
-       pprReg reg,
-       uppComma,
-       pprImm sty lab
-    ]
-
-pprAlphaInstr sty (BF cond reg lab) =
-    uppBesides [
-       uppPStr SLIT("\tfb"),
-       pprCond cond,
-       uppChar '\t',
-       pprReg reg,
-       uppComma,
-       pprImm sty lab
-    ]
-
-pprAlphaInstr sty (BR lab) =
-    uppBeside (uppPStr SLIT("\tbr\t")) (pprImm sty lab)
-
-pprAlphaInstr sty (JMP reg addr hint) =
-    uppBesides [
-       uppPStr SLIT("\tjmp\t"),
-       pprReg reg,
-       uppComma,
-       pprAddr sty addr,
-       uppComma,
-       uppInt hint
-    ]
-
-pprAlphaInstr sty (BSR imm n) =
-    uppBeside (uppPStr SLIT("\tbsr\t")) (pprImm sty imm)
-
-pprAlphaInstr sty (JSR reg addr n) =
-    uppBesides [
-       uppPStr SLIT("\tjsr\t"),
-       pprReg reg,
-       uppComma,
-       pprAddr sty addr
-    ]
-
-pprAlphaInstr sty (LABEL clab) =
-    uppBesides [
-       if (externallyVisibleCLabel clab) then
-           uppBesides [uppPStr SLIT("\t.globl\t"), pprLab, uppChar '\n']
-       else
-           uppNil,
-       pprLab,
-       uppChar ':'
-    ]
-    where pprLab = pprCLabel sty clab
-
-pprAlphaInstr sty (FUNBEGIN clab) =
-    uppBesides [
-       if (externallyVisibleCLabel clab) then
-           uppBesides [uppPStr SLIT("\t.globl\t"), pprLab, uppChar '\n']
-       else
-           uppNil,
-       uppPStr SLIT("\t.ent "),
-       pprLab,
-       uppChar '\n',
-       pprLab,
-       pp_ldgp,
-       pprLab,
-       pp_frame
-    ]
-    where
-       pprLab = pprCLabel sty clab
-#ifdef USE_FAST_STRINGS
-       pp_ldgp  = uppPStr (_packCString (A# ":\n\tldgp $29,0($27)\n"#))
-       pp_frame = uppPStr (_packCString (A# "..ng:\n\t.frame $30,4240,$26,0\n\t.prologue 1"#))
-#else
-       pp_ldgp  = uppStr ":\n\tldgp $29,0($27)\n"
-       pp_frame = uppStr "..ng:\n\t.frame $30,4240,$26,0\n\t.prologue 1"
-#endif
-
-pprAlphaInstr sty (FUNEND clab) =
-    uppBeside (uppPStr SLIT("\t.align 4\n\t.end ")) (pprCLabel sty clab)
-
-pprAlphaInstr sty (COMMENT s) = uppBeside (uppPStr SLIT("\t# ")) (uppPStr s)
-
-pprAlphaInstr sty (SEGMENT TextSegment)
-    = uppPStr SLIT("\t.text\n\t.align 3")
-
-pprAlphaInstr sty (SEGMENT DataSegment)
-    = uppPStr SLIT("\t.data\n\t.align 3")
-
-pprAlphaInstr sty (ASCII False str) =
-    uppBesides [
-       uppStr "\t.asciz \"",
-       uppStr str,
-       uppChar '"'
-    ]
-
-pprAlphaInstr sty (ASCII True str) = uppBeside (uppStr "\t.ascii \"") (asciify str 60)
-    where
-       asciify :: String -> Int -> Unpretty
-       asciify [] _ = uppStr ("\\0\"")
-       asciify s n | n <= 0 = uppBeside (uppStr "\"\n\t.ascii \"") (asciify s 60)
-       asciify ('\\':cs) n = uppBeside (uppStr "\\\\") (asciify cs (n-1))
-       asciify ('\"':cs) n = uppBeside (uppStr "\\\"") (asciify cs (n-1))
-       asciify (c:cs) n | isPrint c = uppBeside (uppChar c) (asciify cs (n-1))
-       asciify [c] _ = uppBeside (uppStr (charToC c)) (uppStr ("\\0\""))
-       asciify (c:(cs@(d:_))) n | isDigit d =
-                                       uppBeside (uppStr (charToC c)) (asciify cs 0)
-                                | otherwise =
-                                       uppBeside (uppStr (charToC c)) (asciify cs (n-1))
-
-pprAlphaInstr sty (DATA s xs) = uppInterleave (uppChar '\n') (map pp_item xs)
-    where pp_item x = case s of
-           B  -> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
-           BU -> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
-           W  -> uppBeside (uppPStr SLIT("\t.word\t")) (pprImm sty x)
-           WU -> uppBeside (uppPStr SLIT("\t.word\t")) (pprImm sty x)
-           L  -> uppBeside (uppPStr SLIT("\t.long\t")) (pprImm sty x)
-           Q  -> uppBeside (uppPStr SLIT("\t.quad\t")) (pprImm sty x)
-           FF -> uppBeside (uppPStr SLIT("\t.f_floating\t")) (pprImm sty x)
-           DF -> uppBeside (uppPStr SLIT("\t.d_floating\t")) (pprImm sty x)
-           GF -> uppBeside (uppPStr SLIT("\t.g_floating\t")) (pprImm sty x)
-           SF -> uppBeside (uppPStr SLIT("\t.s_floating\t")) (pprImm sty x)
-           TF -> uppBeside (uppPStr SLIT("\t.t_floating\t")) (pprImm sty x)
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Schedule]{Register allocation information}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-
-data AlphaRegs = SRegs BitSet BitSet
-
-instance MachineRegisters AlphaRegs where
-    mkMRegs xs = SRegs (mkBS ints) (mkBS floats')
-      where
-       (ints, floats) = partition (< 32) xs
-       floats' = map (subtract 32) floats
-
-    possibleMRegs FloatRep (SRegs _ floats) = [ x + 32 | x <- listBS floats]
-    possibleMRegs DoubleRep (SRegs _ floats) = [ x + 32 | x <- listBS floats]
-    possibleMRegs _ (SRegs ints _) = listBS ints
-
-    useMReg (SRegs ints floats) n =
-       if n _LT_ ILIT(32) then SRegs (ints `minusBS` singletonBS IBOX(n)) floats
-       else SRegs ints (floats `minusBS` singletonBS (IBOX(n _SUB_ ILIT(32))))
-
-    useMRegs (SRegs ints floats) xs =
-       SRegs (ints `minusBS` ints')
-             (floats `minusBS` floats')
-      where
-       SRegs ints' floats' = mkMRegs xs
-
-    freeMReg (SRegs ints floats) n =
-       if n _LT_ ILIT(32) then SRegs (ints `unionBS` singletonBS IBOX(n)) floats
-       else SRegs ints (floats `unionBS` singletonBS (IBOX(n _SUB_ ILIT(32))))
-
-    freeMRegs (SRegs ints floats) xs =
-       SRegs (ints `unionBS` ints')
-             (floats `unionBS` floats')
-      where
-       SRegs ints' floats' = mkMRegs xs
-
-instance MachineCode AlphaInstr where
-    regUsage = alphaRegUsage
-    regLiveness = alphaRegLiveness
-    patchRegs = alphaPatchRegs
-
-    -- We spill just below the frame pointer, leaving two words per spill location.
-    spillReg dyn (MemoryReg i pk) = mkUnitList (ST (kindToSize pk) dyn (spRel i))
-    loadReg (MemoryReg i pk) dyn = mkUnitList (LD (kindToSize pk) dyn (spRel i))
-
-spRel :: Int -> Addr
-spRel n = AddrRegImm sp (ImmInt (n * 8))
-
-kindToSize :: PrimRep -> Size
-kindToSize PtrRep          = Q
-kindToSize CodePtrRep      = Q
-kindToSize DataPtrRep      = Q
-kindToSize RetRep          = Q
-kindToSize CostCentreRep   = Q
-kindToSize CharRep         = BU
-kindToSize IntRep          = Q
-kindToSize WordRep         = Q
-kindToSize AddrRep         = Q
-kindToSize FloatRep        = TF
-kindToSize DoubleRep       = TF
-kindToSize ArrayRep        = Q
-kindToSize ByteArrayRep    = Q
-kindToSize StablePtrRep    = Q
-kindToSize MallocPtrRep    = Q
-
-\end{code}
-
-@alphaRegUsage@ returns the sets of src and destination registers used by
-a particular instruction.  Machine registers that are pre-allocated
-to stgRegs are filtered out, because they are uninteresting from a
-register allocation standpoint.         (We wouldn't want them to end up on
-the free list!)
-
-\begin{code}
-
-alphaRegUsage :: AlphaInstr -> RegUsage
-alphaRegUsage instr = case instr of
-    LD B reg addr      -> usage (regAddr addr, [reg, t9])
-    LD BU reg addr     -> usage (regAddr addr, [reg, t9])
-    LD W reg addr      -> usage (regAddr addr, [reg, t9])
-    LD WU reg addr     -> usage (regAddr addr, [reg, t9])
-    LD sz reg addr     -> usage (regAddr addr, [reg])
-    LDA reg addr       -> usage (regAddr addr, [reg])
-    LDAH reg addr      -> usage (regAddr addr, [reg])
-    LDGP reg addr      -> usage (regAddr addr, [reg])
-    LDI sz reg imm     -> usage ([], [reg])
-    ST B reg addr      -> usage (reg : regAddr addr, [t9, t10])
-    ST W reg addr      -> usage (reg : regAddr addr, [t9, t10])
-    ST sz reg addr     -> usage (reg : regAddr addr, [])
-    CLR reg            -> usage ([], [reg])
-    ABS sz ri reg      -> usage (regRI ri, [reg])
-    NEG sz ov ri reg   -> usage (regRI ri, [reg])
-    ADD sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
-    SADD sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
-    SUB sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
-    SSUB sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
-    MUL sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
-    DIV sz un r1 ar r2 -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
-    REM sz un r1 ar r2 -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
-    NOT ri reg         -> usage (regRI ri, [reg])
-    AND r1 ar r2       -> usage (r1 : regRI ar, [r2])
-    ANDNOT r1 ar r2    -> usage (r1 : regRI ar, [r2])
-    OR r1 ar r2                -> usage (r1 : regRI ar, [r2])
-    ORNOT r1 ar r2     -> usage (r1 : regRI ar, [r2])
-    XOR r1 ar r2       -> usage (r1 : regRI ar, [r2])
-    XORNOT r1 ar r2    -> usage (r1 : regRI ar, [r2])
-    SLL r1 ar r2       -> usage (r1 : regRI ar, [r2])
-    SRL r1 ar r2       -> usage (r1 : regRI ar, [r2])
-    SRA r1 ar r2       -> usage (r1 : regRI ar, [r2])
-    ZAP r1 ar r2       -> usage (r1 : regRI ar, [r2])
-    ZAPNOT r1 ar r2    -> usage (r1 : regRI ar, [r2])
-    CMP co r1 ar r2    -> usage (r1 : regRI ar, [r2])
-    FCLR reg           -> usage ([], [reg])
-    FABS r1 r2         -> usage ([r1], [r2])
-    FNEG sz r1 r2      -> usage ([r1], [r2])
-    FADD sz r1 r2 r3   -> usage ([r1, r2], [r3])
-    FDIV sz r1 r2 r3   -> usage ([r1, r2], [r3])
-    FMUL sz r1 r2 r3   -> usage ([r1, r2], [r3])
-    FSUB sz r1 r2 r3   -> usage ([r1, r2], [r3])
-    CVTxy sz1 sz2 r1 r2 -> usage ([r1], [r2])
-    FCMP sz co r1 r2 r3 -> usage ([r1, r2], [r3])
-    FMOV r1 r2         -> usage ([r1], [r2])
-
-
-    -- We assume that all local jumps will be BI/BF/BR.         JMP must be out-of-line.
-    BI cond reg lbl    -> usage ([reg], [])
-    BF cond reg lbl    -> usage ([reg], [])
-    JMP reg addr hint  -> RU (mkUniqSet (filter interesting (regAddr addr))) freeSet
-
-    BSR _ n            -> RU (argSet n) callClobberedSet
-    JSR reg addr n     -> RU (argSet n) callClobberedSet
-
-    _                  -> noUsage
-
-  where
-    usage (src, dst) = RU (mkUniqSet (filter interesting src))
-                         (mkUniqSet (filter interesting dst))
-
-    interesting (FixedReg _) = False
-    interesting _ = True
-
-    regAddr (AddrReg r1)      = [r1]
-    regAddr (AddrRegImm r1 _) = [r1]
-    regAddr (AddrImm _)              = []
-
-    regRI (RIReg r) = [r]
-    regRI  _   = []
-
-freeRegs :: [Reg]
-freeRegs = freeMappedRegs [0..63]
-
-freeMappedRegs :: [Int] -> [Reg]
-
-freeMappedRegs nums
-  = foldr free [] nums
-  where
-    free IBOX(i) acc
-      = if _IS_TRUE_(freeReg i) then (MappedReg i) : acc else acc
-
-freeSet :: UniqSet Reg
-freeSet = mkUniqSet freeRegs
-
-noUsage :: RegUsage
-noUsage = RU emptyUniqSet emptyUniqSet
-
--- Color me CAF-like
-argSet :: Int -> UniqSet Reg
-argSet 0 = emptyUniqSet
-argSet 1 = mkUniqSet (freeMappedRegs [16, fReg 16])
-argSet 2 = mkUniqSet (freeMappedRegs [16, 17, fReg 16, fReg 17])
-argSet 3 = mkUniqSet (freeMappedRegs [16, 17, 18, fReg 16, fReg 17, fReg 18])
-argSet 4 = mkUniqSet (freeMappedRegs [16, 17, 18, 19, fReg 16, fReg 17, fReg 18, fReg 19])
-argSet 5 = mkUniqSet (freeMappedRegs [16, 17, 18, 19, 20, fReg 16, fReg 17, fReg 18, fReg 19, fReg 20])
-argSet 6 = mkUniqSet (freeMappedRegs [16, 17, 18, 19, 20, 21, fReg 16, fReg 17, fReg 18, fReg 19, fReg 20, fReg 21])
-
-callClobberedSet :: UniqSet Reg
-callClobberedSet = mkUniqSet callClobberedRegs
-  where
-    callClobberedRegs
-      = freeMappedRegs
-         [0, 1, 2, 3, 4, 5, 6, 7, 8,
-          16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
-          fReg 0, fReg 1, fReg 10, fReg 11, fReg 12, fReg 13, fReg 14, fReg 15,
-          fReg 16, fReg 17, fReg 18, fReg 19, fReg 20, fReg 21, fReg 22, fReg 23,
-          fReg 24, fReg 25, fReg 26, fReg 27, fReg 28, fReg 29, fReg 30]
-
-\end{code}
-
-@alphaRegLiveness@ takes future liveness information and modifies it according to
-the semantics of branches and labels.  (An out-of-line branch clobbers the liveness
-passed back by the following instruction; a forward local branch passes back the
-liveness from the target label; a conditional branch merges the liveness from the
-target and the liveness from its successor; a label stashes away the current liveness
-in the future liveness environment).
-
-\begin{code}
-alphaRegLiveness :: AlphaInstr -> RegLiveness -> RegLiveness
-alphaRegLiveness instr info@(RL live future@(FL all env)) = case instr of
-
-    -- We assume that all local jumps will be BI/BF.  JMP must be out-of-line.
-
-    BR (ImmCLbl lbl)    -> RL (lookup lbl) future
-    BI _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionUniqSets` live) future
-    BF _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionUniqSets` live) future
-    JMP _ _ _           -> RL emptyUniqSet future
-    BSR _ _             -> RL live future
-    JSR _ _ _           -> RL live future
-    LABEL lbl           -> RL live (FL (all `unionUniqSets` live) (addToFM env lbl live))
-    _                   -> info
-
-  where
-    lookup lbl = case lookupFM env lbl of
-       Just regs -> regs
-       Nothing -> trace ("Missing " ++ (uppShow 80 (pprCLabel (PprForAsm (\_->False) False id) lbl)) ++
-                         " in future?") emptyUniqSet
-
-\end{code}
-
-@alphaPatchRegs@ takes an instruction (possibly with
-MemoryReg/UnmappedReg registers) and changes all register references
-according to the supplied environment.
-
-\begin{code}
-
-alphaPatchRegs :: AlphaInstr -> (Reg -> Reg) -> AlphaInstr
-alphaPatchRegs instr env = case instr of
-    LD sz reg addr -> LD sz (env reg) (fixAddr addr)
-    LDA reg addr -> LDA (env reg) (fixAddr addr)
-    LDAH reg addr -> LDAH (env reg) (fixAddr addr)
-    LDGP reg addr -> LDGP (env reg) (fixAddr addr)
-    LDI sz reg imm -> LDI sz (env reg) imm
-    ST sz reg addr -> ST sz (env reg) (fixAddr addr)
-    CLR reg -> CLR (env reg)
-    ABS sz ar reg -> ABS sz (fixRI ar) (env reg)
-    NEG sz ov ar reg -> NEG sz ov (fixRI ar) (env reg)
-    ADD sz ov r1 ar r2 -> ADD sz ov (env r1) (fixRI ar) (env r2)
-    SADD sz sc r1 ar r2 -> SADD sz sc (env r1) (fixRI ar) (env r2)
-    SUB sz ov r1 ar r2 -> SUB sz ov (env r1) (fixRI ar) (env r2)
-    SSUB sz sc r1 ar r2 -> SSUB sz sc (env r1) (fixRI ar) (env r2)
-    MUL sz ov r1 ar r2 -> MUL sz ov (env r1) (fixRI ar) (env r2)
-    DIV sz un r1 ar r2 -> DIV sz un (env r1) (fixRI ar) (env r2)
-    REM sz un r1 ar r2 -> REM sz un (env r1) (fixRI ar) (env r2)
-    NOT ar reg -> NOT (fixRI ar) (env reg)
-    AND r1 ar r2 -> AND (env r1) (fixRI ar) (env r2)
-    ANDNOT r1 ar r2 -> ANDNOT (env r1) (fixRI ar) (env r2)
-    OR r1 ar r2 -> OR (env r1) (fixRI ar) (env r2)
-    ORNOT r1 ar r2 -> ORNOT (env r1) (fixRI ar) (env r2)
-    XOR r1 ar r2 -> XOR (env r1) (fixRI ar) (env r2)
-    XORNOT r1 ar r2 -> XORNOT (env r1) (fixRI ar) (env r2)
-    SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
-    SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
-    SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
-    ZAP r1 ar r2 -> ZAP (env r1) (fixRI ar) (env r2)
-    ZAPNOT r1 ar r2 -> ZAPNOT (env r1) (fixRI ar) (env r2)
-    CMP co r1 ar r2 -> CMP co (env r1) (fixRI ar) (env r2)
-    FCLR reg -> FCLR (env reg)
-    FABS r1 r2 -> FABS (env r1) (env r2)
-    FNEG s r1 r2 -> FNEG s (env r1) (env r2)
-    FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
-    FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
-    FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
-    FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
-    CVTxy s1 s2 r1 r2 -> CVTxy s1 s2 (env r1) (env r2)
-    FCMP s co r1 r2 r3 -> FCMP s co (env r1) (env r2) (env r3)
-    FMOV r1 r2 -> FMOV (env r1) (env r2)
-    BI cond reg lbl -> BI cond (env reg) lbl
-    BF cond reg lbl -> BF cond (env reg) lbl
-    JMP reg addr hint -> JMP (env reg) (fixAddr addr) hint
-    JSR reg addr i -> JSR (env reg) (fixAddr addr) i
-    _ -> instr
-
-  where
-    fixAddr (AddrReg r1)       = AddrReg (env r1)
-    fixAddr (AddrRegImm r1 i)  = AddrRegImm (env r1) i
-    fixAddr other             = other
-
-    fixRI (RIReg r) = RIReg (env r)
-    fixRI other        = other
-
-\end{code}
-
-If you value your sanity, do not venture below this line.
-
-\begin{code}
-
--- platform.h is generate and tells us what the target architecture is
-#include "../../includes/platform.h"
-#include "../../includes/MachRegs.h"
-#include "../../includes/alpha-dec-osf1.h"
-
--- Redefine the literals used for Alpha floating point register names
--- in the header files.         Gag me with a spoon, eh?
-
-#define f0 32
-#define f1 33
-#define f2 34
-#define f3 35
-#define f4 36
-#define f5 37
-#define f6 38
-#define f7 39
-#define f8 40
-#define f9 41
-#define f10 42
-#define f11 43
-#define f12 44
-#define f13 45
-#define f14 46
-#define f15 47
-#define f16 48
-#define f17 49
-#define f18 50
-#define f19 51
-#define f20 52
-#define f21 53
-#define f22 54
-#define f23 55
-#define f24 56
-#define f25 57
-#define f26 58
-#define f27 59
-#define f28 60
-#define f29 61
-#define f30 62
-#define f31 63
-
-baseRegOffset :: MagicId -> Int
-baseRegOffset StkOReg               = OFFSET_StkO
-baseRegOffset (VanillaReg _ ILIT(1)) = OFFSET_R1
-baseRegOffset (VanillaReg _ ILIT(2)) = OFFSET_R2
-baseRegOffset (VanillaReg _ ILIT(3)) = OFFSET_R3
-baseRegOffset (VanillaReg _ ILIT(4)) = OFFSET_R4
-baseRegOffset (VanillaReg _ ILIT(5)) = OFFSET_R5
-baseRegOffset (VanillaReg _ ILIT(6)) = OFFSET_R6
-baseRegOffset (VanillaReg _ ILIT(7)) = OFFSET_R7
-baseRegOffset (VanillaReg _ ILIT(8)) = OFFSET_R8
-baseRegOffset (FloatReg ILIT(1))     = OFFSET_Flt1
-baseRegOffset (FloatReg ILIT(2))     = OFFSET_Flt2
-baseRegOffset (FloatReg ILIT(3))     = OFFSET_Flt3
-baseRegOffset (FloatReg ILIT(4))     = OFFSET_Flt4
-baseRegOffset (DoubleReg ILIT(1))     = OFFSET_Dbl1
-baseRegOffset (DoubleReg ILIT(2))     = OFFSET_Dbl2
-baseRegOffset TagReg                = OFFSET_Tag
-baseRegOffset RetReg                = OFFSET_Ret
-baseRegOffset SpA                   = OFFSET_SpA
-baseRegOffset SuA                   = OFFSET_SuA
-baseRegOffset SpB                   = OFFSET_SpB
-baseRegOffset SuB                   = OFFSET_SuB
-baseRegOffset Hp                    = OFFSET_Hp
-baseRegOffset HpLim                 = OFFSET_HpLim
-baseRegOffset LivenessReg           = OFFSET_Liveness
---baseRegOffset ActivityReg         = OFFSET_Activity
-#ifdef DEBUG
-baseRegOffset BaseReg               = panic "baseRegOffset:BaseReg"
-baseRegOffset StdUpdRetVecReg       = panic "baseRegOffset:StgUpdRetVecReg"
-baseRegOffset StkStubReg            = panic "baseRegOffset:StkStubReg"
-baseRegOffset CurCostCentre         = panic "baseRegOffset:CurCostCentre"
-baseRegOffset VoidReg               = panic "baseRegOffset:VoidReg"
-#endif
-
-callerSaves :: MagicId -> Bool
-#ifdef CALLER_SAVES_Base
-callerSaves BaseReg            = True
-#endif
-#ifdef CALLER_SAVES_StkO
-callerSaves StkOReg            = True
-#endif
-#ifdef CALLER_SAVES_R1
-callerSaves (VanillaReg _ ILIT(1))     = True
-#endif
-#ifdef CALLER_SAVES_R2
-callerSaves (VanillaReg _ ILIT(2))    = True
-#endif
-#ifdef CALLER_SAVES_R3
-callerSaves (VanillaReg _ ILIT(3))    = True
-#endif
-#ifdef CALLER_SAVES_R4
-callerSaves (VanillaReg _ ILIT(4))    = True
-#endif
-#ifdef CALLER_SAVES_R5
-callerSaves (VanillaReg _ ILIT(5))    = True
-#endif
-#ifdef CALLER_SAVES_R6
-callerSaves (VanillaReg _ ILIT(6))    = True
-#endif
-#ifdef CALLER_SAVES_R7
-callerSaves (VanillaReg _ ILIT(7))     = True
-#endif
-#ifdef CALLER_SAVES_R8
-callerSaves (VanillaReg _ ILIT(8))    = True
-#endif
-#ifdef CALLER_SAVES_FltReg1
-callerSaves (FloatReg ILIT(1))         = True
-#endif
-#ifdef CALLER_SAVES_FltReg2
-callerSaves (FloatReg ILIT(2))         = True
-#endif
-#ifdef CALLER_SAVES_FltReg3
-callerSaves (FloatReg ILIT(3))         = True
-#endif
-#ifdef CALLER_SAVES_FltReg4
-callerSaves (FloatReg ILIT(4))         = True
-#endif
-#ifdef CALLER_SAVES_DblReg1
-callerSaves (DoubleReg ILIT(1))                = True
-#endif
-#ifdef CALLER_SAVES_DblReg2
-callerSaves (DoubleReg ILIT(2))                = True
-#endif
-#ifdef CALLER_SAVES_Tag
-callerSaves TagReg             = True
-#endif
-#ifdef CALLER_SAVES_Ret
-callerSaves RetReg             = True
-#endif
-#ifdef CALLER_SAVES_SpA
-callerSaves SpA                        = True
-#endif
-#ifdef CALLER_SAVES_SuA
-callerSaves SuA                        = True
-#endif
-#ifdef CALLER_SAVES_SpB
-callerSaves SpB                        = True
-#endif
-#ifdef CALLER_SAVES_SuB
-callerSaves SuB                        = True
-#endif
-#ifdef CALLER_SAVES_Hp
-callerSaves Hp                 = True
-#endif
-#ifdef CALLER_SAVES_HpLim
-callerSaves HpLim              = True
-#endif
-#ifdef CALLER_SAVES_Liveness
-callerSaves LivenessReg                = True
-#endif
-#ifdef CALLER_SAVES_Activity
---callerSaves ActivityReg              = True
-#endif
-#ifdef CALLER_SAVES_StdUpdRetVec
-callerSaves StdUpdRetVecReg    = True
-#endif
-#ifdef CALLER_SAVES_StkStub
-callerSaves StkStubReg         = True
-#endif
-callerSaves _                  = False
-
-stgRegMap :: MagicId -> Maybe Reg
-#ifdef REG_Base
-stgRegMap BaseReg         = Just (FixedReg ILIT(REG_Base))
-#endif
-#ifdef REG_StkO
-stgRegMap StkOReg         = Just (FixedReg ILIT(REG_StkOReg))
-#endif
-#ifdef REG_R1
-stgRegMap (VanillaReg _ ILIT(1)) = Just (FixedReg ILIT(REG_R1))
-#endif
-#ifdef REG_R2
-stgRegMap (VanillaReg _ ILIT(2)) = Just (FixedReg ILIT(REG_R2))
-#endif
-#ifdef REG_R3
-stgRegMap (VanillaReg _ ILIT(3)) = Just (FixedReg ILIT(REG_R3))
-#endif
-#ifdef REG_R4
-stgRegMap (VanillaReg _ ILIT(4)) = Just (FixedReg ILIT(REG_R4))
-#endif
-#ifdef REG_R5
-stgRegMap (VanillaReg _ ILIT(5)) = Just (FixedReg ILIT(REG_R5))
-#endif
-#ifdef REG_R6
-stgRegMap (VanillaReg _ ILIT(6)) = Just (FixedReg ILIT(REG_R6))
-#endif
-#ifdef REG_R7
-stgRegMap (VanillaReg _ ILIT(7)) = Just (FixedReg ILIT(REG_R7))
-#endif
-#ifdef REG_R8
-stgRegMap (VanillaReg _ ILIT(8)) = Just (FixedReg ILIT(REG_R8))
-#endif
-#ifdef REG_Flt1
-stgRegMap (FloatReg ILIT(1))      = Just (FixedReg ILIT(REG_Flt1))
-#endif
-#ifdef REG_Flt2
-stgRegMap (FloatReg ILIT(2))      = Just (FixedReg ILIT(REG_Flt2))
-#endif
-#ifdef REG_Flt3
-stgRegMap (FloatReg ILIT(3))      = Just (FixedReg ILIT(REG_Flt3))
-#endif
-#ifdef REG_Flt4
-stgRegMap (FloatReg ILIT(4))      = Just (FixedReg ILIT(REG_Flt4))
-#endif
-#ifdef REG_Dbl1
-stgRegMap (DoubleReg ILIT(1))     = Just (FixedReg ILIT(REG_Dbl1))
-#endif
-#ifdef REG_Dbl2
-stgRegMap (DoubleReg ILIT(2))     = Just (FixedReg ILIT(REG_Dbl2))
-#endif
-#ifdef REG_Tag
-stgRegMap TagReg          = Just (FixedReg ILIT(REG_TagReg))
-#endif
-#ifdef REG_Ret
-stgRegMap RetReg          = Just (FixedReg ILIT(REG_Ret))
-#endif
-#ifdef REG_SpA
-stgRegMap SpA             = Just (FixedReg ILIT(REG_SpA))
-#endif
-#ifdef REG_SuA
-stgRegMap SuA             = Just (FixedReg ILIT(REG_SuA))
-#endif
-#ifdef REG_SpB
-stgRegMap SpB             = Just (FixedReg ILIT(REG_SpB))
-#endif
-#ifdef REG_SuB
-stgRegMap SuB             = Just (FixedReg ILIT(REG_SuB))
-#endif
-#ifdef REG_Hp
-stgRegMap Hp              = Just (FixedReg ILIT(REG_Hp))
-#endif
-#ifdef REG_HpLim
-stgRegMap HpLim                   = Just (FixedReg ILIT(REG_HpLim))
-#endif
-#ifdef REG_Liveness
-stgRegMap LivenessReg     = Just (FixedReg ILIT(REG_Liveness))
-#endif
-#ifdef REG_Activity
---stgRegMap ActivityReg           = Just (FixedReg ILIT(REG_Activity))
-#endif
-#ifdef REG_StdUpdRetVec
-stgRegMap StdUpdRetVecReg  = Just (FixedReg ILIT(REG_StdUpdRetVec))
-#endif
-#ifdef REG_StkStub
-stgRegMap StkStubReg      = Just (FixedReg ILIT(REG_StkStub))
-#endif
-stgRegMap _               = Nothing
-
-\end{code}
-
-Here is the list of registers we can use in register allocation.
-
-With a per-instruction clobber list, we might be able to get some of
-these back, but it's probably not worth the hassle.
-
-\begin{code}
-
-freeReg :: FAST_INT -> FAST_BOOL
-
-freeReg ILIT(26) = _FALSE_  -- return address (ra)
-freeReg ILIT(28) = _FALSE_  -- reserved for the assembler (at)
-freeReg ILIT(29) = _FALSE_  -- global pointer (gp)
-freeReg ILIT(30) = _FALSE_  -- stack pointer (sp)
-freeReg ILIT(31) = _FALSE_  -- always zero (zero)
-freeReg ILIT(63) = _FALSE_  -- always zero (f31)
-
-#ifdef REG_Base
-freeReg ILIT(REG_Base) = _FALSE_
-#endif
-#ifdef REG_StkO
-freeReg ILIT(REG_StkO) = _FALSE_
-#endif
-#ifdef REG_R1
-freeReg ILIT(REG_R1) = _FALSE_
-#endif
-#ifdef REG_R2
-freeReg ILIT(REG_R2) = _FALSE_
-#endif
-#ifdef REG_R3
-freeReg ILIT(REG_R3) = _FALSE_
-#endif
-#ifdef REG_R4
-freeReg ILIT(REG_R4) = _FALSE_
-#endif
-#ifdef REG_R5
-freeReg ILIT(REG_R5) = _FALSE_
-#endif
-#ifdef REG_R6
-freeReg ILIT(REG_R6) = _FALSE_
-#endif
-#ifdef REG_R7
-freeReg ILIT(REG_R7) = _FALSE_
-#endif
-#ifdef REG_R8
-freeReg ILIT(REG_R8) = _FALSE_
-#endif
-#ifdef REG_Flt1
-freeReg ILIT(REG_Flt1) = _FALSE_
-#endif
-#ifdef REG_Flt2
-freeReg ILIT(REG_Flt2) = _FALSE_
-#endif
-#ifdef REG_Flt3
-freeReg ILIT(REG_Flt3) = _FALSE_
-#endif
-#ifdef REG_Flt4
-freeReg ILIT(REG_Flt4) = _FALSE_
-#endif
-#ifdef REG_Dbl1
-freeReg ILIT(REG_Dbl1) = _FALSE_
-#endif
-#ifdef REG_Dbl2
-freeReg ILIT(REG_Dbl2) = _FALSE_
-#endif
-#ifdef REG_Tag
-freeReg ILIT(REG_Tag) = _FALSE_
-#endif
-#ifdef REG_Ret
-freeReg ILIT(REG_Ret) = _FALSE_
-#endif
-#ifdef REG_SpA
-freeReg ILIT(REG_SpA) = _FALSE_
-#endif
-#ifdef REG_SuA
-freeReg ILIT(REG_SuA) = _FALSE_
-#endif
-#ifdef REG_SpB
-freeReg ILIT(REG_SpB) = _FALSE_
-#endif
-#ifdef REG_SuB
-freeReg ILIT(REG_SuB) = _FALSE_
-#endif
-#ifdef REG_Hp
-freeReg ILIT(REG_Hp) = _FALSE_
-#endif
-#ifdef REG_HpLim
-freeReg ILIT(REG_HpLim) = _FALSE_
-#endif
-#ifdef REG_Liveness
-freeReg ILIT(REG_Liveness) = _FALSE_
-#endif
-#ifdef REG_Activity
---freeReg ILIT(REG_Activity) = _FALSE_
-#endif
-#ifdef REG_StdUpdRetVec
-freeReg ILIT(REG_StdUpdRetVec) = _FALSE_
-#endif
-#ifdef REG_StkStub
-freeReg ILIT(REG_StkStub) = _FALSE_
-#endif
-freeReg _ = _TRUE_
-
-reservedRegs :: [Int]
-reservedRegs = [NCG_Reserved_I1, NCG_Reserved_I2, NCG_Reserved_F1, NCG_Reserved_F2]
-
-\end{code}
diff --git a/ghc/compiler/nativeGen/AlphaDesc.lhs b/ghc/compiler/nativeGen/AlphaDesc.lhs
deleted file mode 100644 (file)
index 43852f2..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1994-1995
-%
-\section[AlphaDesc]{The Alpha Machine Description}
-
-\begin{code}
-#include "HsVersions.h"
-
-module AlphaDesc (
-       mkAlpha
-
-       -- and assorted nonsense referenced by the class methods
-    ) where
-
-import AbsCSyn
-import PrelInfo                ( PrimOp(..)
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                       )
-import AsmRegAlloc     ( Reg, MachineCode(..), MachineRegisters(..),
-                         RegUsage(..), RegLiveness(..), FutureLive(..)
-                       )
-import CLabel          ( CLabel )
-import CmdLineOpts     ( GlobalSwitch(..), stringSwitchSet,
-                         switchIsOn, SwitchResult(..)
-                       )
-import HeapOffs                ( hpRelToInt )
-import MachDesc
-import Maybes          ( Maybe(..) )
-import OrdList
-import Outputable
-import PrimRep         ( PrimRep(..) )
-import SMRep           ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
-import AlphaCode
-import AlphaGen                ( alphaCodeGen )
-import Stix
-import StixMacro
-import StixPrim
-import UniqSupply
-import Util
-
-\end{code}
-
-Header sizes depend only on command-line options, not on the target
-architecture.  (I think.)
-
-\begin{code}
-
-fhs :: (GlobalSwitch -> SwitchResult) -> Int
-
-fhs switches = 1 + profFHS + ageFHS
-  where
-    profFHS = if switchIsOn switches SccProfilingOn then 1 else 0
-    ageFHS  = if switchIsOn switches SccProfilingOn then 1 else 0
-
-vhs :: (GlobalSwitch -> SwitchResult) -> SMRep -> Int
-
-vhs switches sm = case sm of
-    StaticRep _ _         -> 0
-    SpecialisedRep _ _ _ _ -> 0
-    GenericRep _ _ _      -> 0
-    BigTupleRep _         -> 1
-    MuTupleRep _          -> 2 {- (1 + GC_MUT_RESERVED_WORDS) -}
-    DataRep _             -> 1
-    DynamicRep            -> 2
-    BlackHoleRep          -> 0
-    PhantomRep            -> panic "vhs:phantom"
-
-\end{code}
-
-Here we map STG registers onto appropriate Stix Trees.  First, we
-handle the two constants, @STK_STUB_closure@ and @vtbl_StdUpdFrame@.
-The rest are either in real machine registers or stored as offsets
-from BaseReg.
-
-\begin{code}
-
-alphaReg :: (GlobalSwitch -> SwitchResult) -> MagicId -> RegLoc
-
-alphaReg switches x =
-    case stgRegMap x of
-       Just reg -> Save nonReg
-       Nothing -> Always nonReg
-    where nonReg = case x of
-           StkStubReg -> sStLitLbl SLIT("STK_STUB_closure")
-           StdUpdRetVecReg -> sStLitLbl SLIT("vtbl_StdUpdFrame")
-           BaseReg -> sStLitLbl SLIT("MainRegTable")
-           Hp -> StInd PtrRep (sStLitLbl SLIT("StorageMgrInfo"))
-           HpLim -> StInd PtrRep (sStLitLbl SLIT("StorageMgrInfo+8"))
-           TagReg -> StInd IntRep (StPrim IntSubOp [infoptr, StInt (1*8)])
-                     where
-                         r2 = VanillaReg PtrRep ILIT(2)
-                         infoptr = case alphaReg switches r2 of
-                                       Always tree -> tree
-                                       Save _ -> StReg (StixMagicId r2)
-           _ -> StInd (kindFromMagicId x)
-                      (StPrim IntAddOp [baseLoc, StInt (toInteger (offset*8))])
-         baseLoc = case stgRegMap BaseReg of
-           Just _ -> StReg (StixMagicId BaseReg)
-           Nothing -> sStLitLbl SLIT("MainRegTable")
-         offset = baseRegOffset x
-
-\end{code}
-
-Sizes in bytes.
-
-\begin{code}
-
-size pk = case kindToSize pk of
-    {B -> 1; BU -> 1; W -> 2; WU -> 2; L -> 4; FF -> 4; SF -> 4; _ -> 8}
-
-\end{code}
-
-Now the volatile saves and restores.  We add the basic guys to the list of ``user''
-registers provided.  Note that there are more basic registers on the restore list,
-because some are reloaded from constants.
-
-\begin{code}
-
-vsaves switches vols =
-    map save ((filter callerSaves) ([BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg{-,ActivityReg-}] ++ vols))
-    where
-       save x = StAssign (kindFromMagicId x) loc reg
-                   where reg = StReg (StixMagicId x)
-                         loc = case alphaReg switches x of
-                                   Save loc -> loc
-                                   Always loc -> panic "vsaves"
-
-vrests switches vols =
-    map restore ((filter callerSaves)
-       ([BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg,{-ActivityReg,-}StkStubReg,StdUpdRetVecReg] ++ vols))
-    where
-       restore x = StAssign (kindFromMagicId x) reg loc
-                   where reg = StReg (StixMagicId x)
-                         loc = case alphaReg switches x of
-                                   Save loc -> loc
-                                   Always loc -> panic "vrests"
-
-\end{code}
-
-Static closure sizes.
-
-\begin{code}
-
-charLikeSize, intLikeSize :: Target -> Int
-
-charLikeSize target =
-    size PtrRep * (fixedHeaderSize target + varHeaderSize target charLikeRep + 1)
-    where charLikeRep = SpecialisedRep CharLikeRep 0 1 SMNormalForm
-
-intLikeSize target =
-    size PtrRep * (fixedHeaderSize target + varHeaderSize target intLikeRep + 1)
-    where intLikeRep = SpecialisedRep IntLikeRep 0 1 SMNormalForm
-
-mhs, dhs :: (GlobalSwitch -> SwitchResult) -> StixTree
-
-mhs switches = StInt (toInteger words)
-  where
-    words = fhs switches + vhs switches (MuTupleRep 0)
-
-dhs switches = StInt (toInteger words)
-  where
-    words = fhs switches + vhs switches (DataRep 0)
-
-\end{code}
-
-Setting up a alpha target.
-
-\begin{code}
-
-mkAlpha :: (GlobalSwitch -> SwitchResult)
-       -> (Target,
-           (PprStyle -> [[StixTree]] -> UniqSM Unpretty), -- codeGen
-           Bool,                                           -- underscore
-           (String -> String))                             -- fmtAsmLbl
-
-mkAlpha switches =
-    let
-       fhs' = fhs switches
-       vhs' = vhs switches
-       alphaReg' = alphaReg switches
-       vsaves' = vsaves switches
-       vrests' = vrests switches
-       hprel = hpRelToInt target
-       as = amodeCode target
-       as' = amodeCode' target
-       csz = charLikeSize target
-       isz = intLikeSize target
-       mhs' = mhs switches
-       dhs' = dhs switches
-       ps = genPrimCode target
-       mc = genMacroCode target
-       hc = doHeapCheck
-       target = mkTarget {-switches-} fhs' vhs' alphaReg' {-id-} size
-                         hprel as as'
-                         (vsaves', vrests', csz, isz, mhs', dhs', ps, mc, hc)
-                         {-alphaCodeGen False mungeLabel-}
-    in
-    (target, alphaCodeGen, False, mungeLabel)
-\end{code}
-
-The alpha assembler likes temporary labels to look like \tr{$L123}
-instead of \tr{L123}.  (Don't toss the \tr{L}, because then \tr{Lf28}
-turns into \tr{$f28}.)
-\begin{code}
-mungeLabel :: String -> String
-mungeLabel xs = '$' : xs
-\end{code}
diff --git a/ghc/compiler/nativeGen/AlphaGen.lhs b/ghc/compiler/nativeGen/AlphaGen.lhs
deleted file mode 100644 (file)
index 2d5071a..0000000
+++ /dev/null
@@ -1,1107 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1993-1995
-%
-
-\begin{code}
-#include "HsVersions.h"
-
-module AlphaGen (
-       alphaCodeGen,
-
-       -- and, for self-sufficiency
-       PprStyle, StixTree, CSeq
-    ) where
-
-IMPORT_Trace
-
-import AbsCSyn     ( AbstractC, MagicId(..), kindFromMagicId )
-import PrelInfo            ( PrimOp(..)
-                     IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                   )
-import AsmRegAlloc  ( runRegAllocate, extractMappedRegNos, mkReg,
-                     Reg(..), RegLiveness(..), RegUsage(..), FutureLive(..),
-                     MachineRegisters(..), MachineCode(..)
-                   )
-import CLabel   ( CLabel, isAsmTemp )
-import AlphaCode    {- everything -}
-import MachDesc
-import Maybes      ( maybeToBool, Maybe(..) )
-import OrdList     -- ( mkEmptyList, mkUnitList, mkSeqList, mkParList, OrdList )
-import Outputable
-import AlphaDesc
-import Stix
-import UniqSupply
-import Pretty
-import Unpretty
-import Util
-
-type CodeBlock a = (OrdList a -> OrdList a)
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[AlphaCodeGen]{Generating Alpha Code}
-%*                                                                     *
-%************************************************************************
-
-This is the top-level code-generation function for the Alpha.
-
-\begin{code}
-
-alphaCodeGen :: PprStyle -> [[StixTree]] -> UniqSM Unpretty
-alphaCodeGen sty trees =
-    mapUs genAlphaCode trees           `thenUs` \ dynamicCodes ->
-    let
-       staticCodes = scheduleAlphaCode dynamicCodes
-       pretty = printLabeledCodes sty staticCodes
-    in
-       returnUs pretty
-
-\end{code}
-
-This bit does the code scheduling.  The scheduler must also deal with
-register allocation of temporaries.  Much parallelism can be exposed via
-the OrdList, but more might occur, so further analysis might be needed.
-
-\begin{code}
-
-scheduleAlphaCode :: [AlphaCode] -> [AlphaInstr]
-scheduleAlphaCode = concat . map (runRegAllocate freeAlphaRegs reservedRegs)
-  where
-    freeAlphaRegs :: AlphaRegs
-    freeAlphaRegs = mkMRegs (extractMappedRegNos freeRegs)
-
-\end{code}
-
-Registers passed up the tree.  If the stix code forces the register
-to live in a pre-decided machine register, it comes out as @Fixed@;
-otherwise, it comes out as @Any@, and the parent can decide which
-register to put it in.
-
-\begin{code}
-
-data Register
-  = Fixed Reg PrimRep (CodeBlock AlphaInstr)
-  | Any PrimRep (Reg -> (CodeBlock AlphaInstr))
-
-registerCode :: Register -> Reg -> CodeBlock AlphaInstr
-registerCode (Fixed _ _ code) reg = code
-registerCode (Any _ code) reg = code reg
-
-registerName :: Register -> Reg -> Reg
-registerName (Fixed reg _ _) _ = reg
-registerName (Any _ _) reg = reg
-
-registerKind :: Register -> PrimRep
-registerKind (Fixed _ pk _) = pk
-registerKind (Any pk _) = pk
-
-isFixed :: Register -> Bool
-isFixed (Fixed _ _ _) = True
-isFixed (Any _ _)     = False
-
-\end{code}
-
-Memory addressing modes passed up the tree.
-
-\begin{code}
-
-data Amode = Amode Addr (CodeBlock AlphaInstr)
-
-amodeAddr (Amode addr _) = addr
-amodeCode (Amode _ code) = code
-
-\end{code}
-
-General things for putting together code sequences.
-
-\begin{code}
-
-asmVoid :: OrdList AlphaInstr
-asmVoid = mkEmptyList
-
-asmInstr :: AlphaInstr -> AlphaCode
-asmInstr i = mkUnitList i
-
-asmSeq :: [AlphaInstr] -> AlphaCode
-asmSeq is = foldr (mkSeqList . asmInstr) asmVoid is
-
-asmParThen :: [AlphaCode] -> CodeBlock AlphaInstr
-asmParThen others code = mkSeqList (foldr mkParList mkEmptyList others) code
-
-returnInstr :: AlphaInstr -> UniqSM (CodeBlock AlphaInstr)
-returnInstr instr = returnUs (\xs -> mkSeqList (asmInstr instr) xs)
-
-returnInstrs :: [AlphaInstr] -> UniqSM (CodeBlock AlphaInstr)
-returnInstrs instrs = returnUs (\xs -> mkSeqList (asmSeq instrs) xs)
-
-returnSeq :: (CodeBlock AlphaInstr) -> [AlphaInstr] -> UniqSM (CodeBlock AlphaInstr)
-returnSeq code instrs = returnUs (\xs -> code (mkSeqList (asmSeq instrs) xs))
-
-mkSeqInstr :: AlphaInstr -> (CodeBlock AlphaInstr)
-mkSeqInstr instr code = mkSeqList (asmInstr instr) code
-
-mkSeqInstrs :: [AlphaInstr] -> (CodeBlock AlphaInstr)
-mkSeqInstrs instrs code = mkSeqList (asmSeq instrs) code
-
-\end{code}
-
-Top level alpha code generator for a chunk of stix code.
-
-\begin{code}
-
-genAlphaCode :: [StixTree] -> UniqSM (AlphaCode)
-
-genAlphaCode trees =
-    mapUs getCode trees                `thenUs` \ blocks ->
-    returnUs (foldr (.) id blocks asmVoid)
-
-\end{code}
-
-Code extractor for an entire stix tree---stix statement level.
-
-\begin{code}
-
-getCode
-    :: StixTree     -- a stix statement
-    -> UniqSM (CodeBlock AlphaInstr)
-
-getCode (StSegment seg) = returnInstr (SEGMENT seg)
-
-getCode (StAssign pk dst src)
-  | isFloatingRep pk = assignFltCode pk dst src
-  | otherwise = assignIntCode pk dst src
-
-getCode (StLabel lab) = returnInstr (LABEL lab)
-
-getCode (StFunBegin lab) = returnInstr (FUNBEGIN lab)
-
-getCode (StFunEnd lab) = returnInstr (FUNEND lab)
-
-getCode (StJump arg) = genJump arg
-
--- When falling through on the alpha, we still have to load pv with the
--- address of the next routine, so that it can load gp
-getCode (StFallThrough lbl) = returnInstr (LDA pv (AddrImm (ImmCLbl lbl)))
-
-getCode (StCondJump lbl arg) = genCondJump lbl arg
-
-getCode (StData kind args) =
-    mapAndUnzipUs getData args             `thenUs` \ (codes, imms) ->
-    returnUs (\xs -> mkSeqList (asmInstr (DATA (kindToSize kind) imms))
-                               (foldr1 (.) codes xs))
-  where
-    getData :: StixTree -> UniqSM (CodeBlock AlphaInstr, Imm)
-    getData (StInt i) = returnUs (id, ImmInteger i)
-    getData (StDouble d) = returnUs (id, ImmLab (prettyToUn (ppRational d)))
-    getData (StLitLbl s) = returnUs (id, ImmLab s)
-    getData (StLitLit s) = returnUs (id, strImmLab (cvtLitLit (_UNPK_ s)))
-    getData (StString s) =
-       getUniqLabelNCG                     `thenUs` \ lbl ->
-       returnUs (mkSeqInstrs [LABEL lbl, ASCII True (_UNPK_ s)], ImmCLbl lbl)
-    getData (StCLbl l)   = returnUs (id, ImmCLbl l)
-
-getCode (StCall fn VoidRep args) = genCCall fn VoidRep args
-
-getCode (StComment s) = returnInstr (COMMENT s)
-
-\end{code}
-
-Generate code to get a subtree into a register.
-
-\begin{code}
-
-getReg :: StixTree -> UniqSM Register
-
-getReg (StReg (StixMagicId stgreg)) =
-    case stgRegMap stgreg of
-       Just reg -> returnUs (Fixed reg (kindFromMagicId stgreg) id)
-       -- cannae be Nothing
-
-getReg (StReg (StixTemp u pk)) = returnUs (Fixed (UnmappedReg u pk) pk id)
-
-getReg (StDouble d) =
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    let code dst = mkSeqInstrs [
-           SEGMENT DataSegment,
-           LABEL lbl,
-           DATA TF [ImmLab (prettyToUn (ppRational d))],
-           SEGMENT TextSegment,
-           LDA tmp (AddrImm (ImmCLbl lbl)),
-           LD TF dst (AddrReg tmp)]
-    in
-       returnUs (Any DoubleRep code)
-
-getReg (StString s) =
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    let code dst = mkSeqInstrs [
-           SEGMENT DataSegment,
-           LABEL lbl,
-           ASCII True (_UNPK_ s),
-           SEGMENT TextSegment,
-           LDA dst (AddrImm (ImmCLbl lbl))]
-    in
-       returnUs (Any PtrRep code)
-
-getReg (StLitLit s) | _HEAD_ s == '"' && last xs == '"' =
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    let code dst = mkSeqInstrs [
-           SEGMENT DataSegment,
-           LABEL lbl,
-           ASCII False (init xs),
-           SEGMENT TextSegment,
-           LDA dst (AddrImm (ImmCLbl lbl))]
-    in
-       returnUs (Any PtrRep code)
-  where
-    xs = _UNPK_ (_TAIL_ s)
-
-getReg tree@(StIndex _ _ _) = getReg (mangleIndexTree tree)
-
-getReg (StCall fn kind args) =
-    genCCall fn kind args          `thenUs` \ call ->
-    returnUs (Fixed reg kind call)
-  where
-    reg = if isFloatingRep kind then f0 else v0
-
-getReg (StPrim primop args) =
-    case primop of
-
-       CharGtOp -> case args of [x,y] -> trivialCode (CMP LT) [y,x]
-       CharGeOp -> case args of [x,y] -> trivialCode (CMP LE) [y,x]
-       CharEqOp -> trivialCode (CMP EQ) args
-       CharNeOp -> intNECode args
-       CharLtOp -> trivialCode (CMP LT) args
-       CharLeOp -> trivialCode (CMP LE) args
-
-       IntAddOp -> trivialCode (ADD Q False) args
-
-       IntSubOp -> trivialCode (SUB Q False) args
-       IntMulOp -> trivialCode (MUL Q False) args
-       IntQuotOp -> trivialCode (DIV Q False) args
-       IntRemOp -> trivialCode (REM Q False) args
-       IntNegOp -> trivialUCode (NEG Q False) args
-       IntAbsOp -> trivialUCode (ABS Q) args
-
-       AndOp -> trivialCode AND args
-       OrOp  -> trivialCode OR args
-       NotOp -> trivialUCode NOT args
-       SllOp -> trivialCode SLL args
-       SraOp -> trivialCode SRA args
-       SrlOp -> trivialCode SRL args
-       ISllOp -> panic "AlphaGen:isll"
-       ISraOp -> panic "AlphaGen:isra"
-       ISrlOp -> panic "AlphaGen:isrl"
-
-       IntGtOp -> case args of [x,y] -> trivialCode (CMP LT) [y,x]
-       IntGeOp -> case args of [x,y] -> trivialCode (CMP LE) [y,x]
-       IntEqOp -> trivialCode (CMP EQ) args
-       IntNeOp -> intNECode args
-       IntLtOp -> trivialCode (CMP LT) args
-       IntLeOp -> trivialCode (CMP LE) args
-
-       WordGtOp -> case args of [x,y] -> trivialCode (CMP ULT) [y,x]
-       WordGeOp -> case args of [x,y] -> trivialCode (CMP ULE) [y,x]
-       WordEqOp -> trivialCode (CMP EQ) args
-       WordNeOp -> intNECode args
-       WordLtOp -> trivialCode (CMP ULT) args
-       WordLeOp -> trivialCode (CMP ULE) args
-
-       AddrGtOp -> case args of [x,y] -> trivialCode (CMP ULT) [y,x]
-       AddrGeOp -> case args of [x,y] -> trivialCode (CMP ULE) [y,x]
-       AddrEqOp -> trivialCode (CMP EQ) args
-       AddrNeOp -> intNECode args
-       AddrLtOp -> trivialCode (CMP ULT) args
-       AddrLeOp -> trivialCode (CMP ULE) args
-
-       FloatAddOp -> trivialFCode (FADD TF) args
-       FloatSubOp -> trivialFCode (FSUB TF) args
-       FloatMulOp -> trivialFCode (FMUL TF) args
-       FloatDivOp -> trivialFCode (FDIV TF) args
-       FloatNegOp -> trivialUFCode (FNEG TF) args
-
-       FloatGtOp -> cmpFCode (FCMP TF LE) EQ args
-       FloatGeOp -> cmpFCode (FCMP TF LT) EQ args
-       FloatEqOp -> cmpFCode (FCMP TF EQ) NE args
-       FloatNeOp -> cmpFCode (FCMP TF EQ) EQ args
-       FloatLtOp -> cmpFCode (FCMP TF LT) NE args
-       FloatLeOp -> cmpFCode (FCMP TF LE) NE args
-
-       FloatExpOp -> call SLIT("exp") DoubleRep
-       FloatLogOp -> call SLIT("log") DoubleRep
-       FloatSqrtOp -> call SLIT("sqrt") DoubleRep
-
-       FloatSinOp -> call SLIT("sin") DoubleRep
-       FloatCosOp -> call SLIT("cos") DoubleRep
-       FloatTanOp -> call SLIT("tan") DoubleRep
-
-       FloatAsinOp -> call SLIT("asin") DoubleRep
-       FloatAcosOp -> call SLIT("acos") DoubleRep
-       FloatAtanOp -> call SLIT("atan") DoubleRep
-
-       FloatSinhOp -> call SLIT("sinh") DoubleRep
-       FloatCoshOp -> call SLIT("cosh") DoubleRep
-       FloatTanhOp -> call SLIT("tanh") DoubleRep
-
-       FloatPowerOp -> call SLIT("pow") DoubleRep
-
-       DoubleAddOp -> trivialFCode (FADD TF) args
-       DoubleSubOp -> trivialFCode (FSUB TF) args
-       DoubleMulOp -> trivialFCode (FMUL TF) args
-       DoubleDivOp -> trivialFCode (FDIV TF) args
-       DoubleNegOp -> trivialUFCode (FNEG TF) args
-
-       DoubleGtOp -> cmpFCode (FCMP TF LE) EQ args
-       DoubleGeOp -> cmpFCode (FCMP TF LT) EQ args
-       DoubleEqOp -> cmpFCode (FCMP TF EQ) NE args
-       DoubleNeOp -> cmpFCode (FCMP TF EQ) EQ args
-       DoubleLtOp -> cmpFCode (FCMP TF LT) NE args
-       DoubleLeOp -> cmpFCode (FCMP TF LE) NE args
-
-       DoubleExpOp -> call SLIT("exp") DoubleRep
-       DoubleLogOp -> call SLIT("log") DoubleRep
-       DoubleSqrtOp -> call SLIT("sqrt") DoubleRep
-
-       DoubleSinOp -> call SLIT("sin") DoubleRep
-       DoubleCosOp -> call SLIT("cos") DoubleRep
-       DoubleTanOp -> call SLIT("tan") DoubleRep
-
-       DoubleAsinOp -> call SLIT("asin") DoubleRep
-       DoubleAcosOp -> call SLIT("acos") DoubleRep
-       DoubleAtanOp -> call SLIT("atan") DoubleRep
-
-       DoubleSinhOp -> call SLIT("sinh") DoubleRep
-       DoubleCoshOp -> call SLIT("cosh") DoubleRep
-       DoubleTanhOp -> call SLIT("tanh") DoubleRep
-
-       DoublePowerOp -> call SLIT("pow") DoubleRep
-
-       OrdOp -> coerceIntCode IntRep args
-       ChrOp -> chrCode args
-
-       Float2IntOp -> coerceFP2Int args
-       Int2FloatOp -> coerceInt2FP args
-       Double2IntOp -> coerceFP2Int args
-       Int2DoubleOp -> coerceInt2FP args
-
-       Double2FloatOp -> coerceFltCode args
-       Float2DoubleOp -> coerceFltCode args
-
-  where
-    call fn pk = getReg (StCall fn pk args)
-
-getReg (StInd pk mem) =
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code = amodeCode amode
-       src   = amodeAddr amode
-       size = kindToSize pk
-       code__2 dst = code . mkSeqInstr (LD size dst src)
-    in
-       returnUs (Any pk code__2)
-
-getReg (StInt i)
-  | is8Bits i =
-    let
-       code dst = mkSeqInstr (OR zero (RIImm src) dst)
-    in
-       returnUs (Any IntRep code)
-  | otherwise =
-    let
-       code dst = mkSeqInstr (LDI Q dst src)
-    in
-       returnUs (Any IntRep code)
-  where
-    src = ImmInt (fromInteger i)
-
-getReg leaf
-  | maybeToBool imm =
-    let
-       code dst = mkSeqInstr (LDA dst (AddrImm imm__2))
-    in
-       returnUs (Any PtrRep code)
-  where
-    imm = maybeImm leaf
-    imm__2 = case imm of Just x -> x
-
-\end{code}
-
-Now, given a tree (the argument to an StInd) that references memory,
-produce a suitable addressing mode.
-
-\begin{code}
-
-getAmode :: StixTree -> UniqSM Amode
-
-getAmode tree@(StIndex _ _ _) = getAmode (mangleIndexTree tree)
-
-getAmode (StPrim IntSubOp [x, StInt i]) =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    getReg x                       `thenUs` \ register ->
-    let
-       code = registerCode register tmp
-       reg  = registerName register tmp
-       off  = ImmInt (-(fromInteger i))
-    in
-       returnUs (Amode (AddrRegImm reg off) code)
-
-
-getAmode (StPrim IntAddOp [x, StInt i]) =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    getReg x                       `thenUs` \ register ->
-    let
-       code = registerCode register tmp
-       reg  = registerName register tmp
-       off  = ImmInt (fromInteger i)
-    in
-       returnUs (Amode (AddrRegImm reg off) code)
-
-getAmode leaf
-  | maybeToBool imm =
-       returnUs (Amode (AddrImm imm__2) id)
-  where
-    imm = maybeImm leaf
-    imm__2 = case imm of Just x -> x
-
-getAmode other =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    getReg other                   `thenUs` \ register ->
-    let
-       code = registerCode register tmp
-       reg  = registerName register tmp
-    in
-       returnUs (Amode (AddrReg reg) code)
-
-\end{code}
-
-Try to get a value into a specific register (or registers) for a call.
-The first 6 arguments go into the appropriate argument register
-(separate registers for integer and floating point arguments, but used
-in lock-step), and the remaining arguments are dumped to the stack,
-beginning at 0(sp).  Our first argument is a pair of the list of
-remaining argument registers to be assigned for this call and the next
-stack offset to use for overflowing arguments.  This way, @getCallArg@
-can be applied to all of a call's arguments using @mapAccumL@.
-
-\begin{code}
-
-getCallArg
-    :: ([(Reg,Reg)],Int)    -- Argument registers and stack offset (accumulator)
-    -> StixTree            -- Current argument
-    -> UniqSM (([(Reg,Reg)],Int), CodeBlock AlphaInstr) -- Updated accumulator and code
-
--- We have to use up all of our argument registers first.
-
-getCallArg ((iDst,fDst):dsts, offset) arg =
-    getReg arg                     `thenUs` \ register ->
-    let
-       reg = if isFloatingRep pk then fDst else iDst
-       code = registerCode register reg
-       src = registerName register reg
-       pk = registerKind register
-    in
-       returnUs (
-           if isFloatingRep pk then
-               ((dsts, offset), if isFixed register then
-                   code . mkSeqInstr (FMOV src fDst)
-                   else code)
-           else
-               ((dsts, offset), if isFixed register then
-                   code . mkSeqInstr (OR src (RIReg src) iDst)
-                   else code))
-
--- Once we have run out of argument registers, we move to the stack
-
-getCallArg ([], offset) arg =
-    getReg arg                     `thenUs` \ register ->
-    getNewRegNCG (registerKind register)
-                                   `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src = registerName register tmp
-       pk = registerKind register
-       sz = kindToSize pk
-    in
-       returnUs (([], offset + 1), code . mkSeqInstr (ST sz src (spRel offset)))
-
-\end{code}
-
-Assignments are really at the heart of the whole code generation business.
-Almost all top-level nodes of any real importance are assignments, which
-correspond to loads, stores, or register transfers.  If we're really lucky,
-some of the register transfers will go away, because we can use the destination
-register to complete the code generation for the right hand side.  This only
-fails when the right hand side is forced into a fixed register (e.g. the result
-of a call).
-
-\begin{code}
-
-assignIntCode :: PrimRep -> StixTree -> StixTree -> UniqSM (CodeBlock AlphaInstr)
-
-assignIntCode pk (StInd _ dst) src =
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    getAmode dst                   `thenUs` \ amode ->
-    getReg src                     `thenUs` \ register ->
-    let
-       code1 = amodeCode amode asmVoid
-       dst__2  = amodeAddr amode
-       code2 = registerCode register tmp asmVoid
-       src__2  = registerName register tmp
-       sz    = kindToSize pk
-       code__2 = asmParThen [code1, code2] . mkSeqInstr (ST sz src__2 dst__2)
-    in
-       returnUs code__2
-
-assignIntCode pk dst src =
-    getReg dst                     `thenUs` \ register1 ->
-    getReg src                     `thenUs` \ register2 ->
-    let
-       dst__2 = registerName register1 zero
-       code = registerCode register2 dst__2
-       src__2 = registerName register2 dst__2
-       code__2 = if isFixed register2 then
-                   code . mkSeqInstr (OR src__2 (RIReg src__2) dst__2)
-               else code
-    in
-       returnUs code__2
-
-assignFltCode :: PrimRep -> StixTree -> StixTree -> UniqSM (CodeBlock AlphaInstr)
-
-assignFltCode pk (StInd _ dst) src =
-    getNewRegNCG pk                `thenUs` \ tmp ->
-    getAmode dst                   `thenUs` \ amode ->
-    getReg src                     `thenUs` \ register ->
-    let
-       code1 = amodeCode amode asmVoid
-       dst__2  = amodeAddr amode
-       code2 = registerCode register tmp asmVoid
-       src__2  = registerName register tmp
-       sz    = kindToSize pk
-       code__2 = asmParThen [code1, code2] . mkSeqInstr (ST sz src__2 dst__2)
-    in
-       returnUs code__2
-
-assignFltCode pk dst src =
-    getReg dst                     `thenUs` \ register1 ->
-    getReg src                     `thenUs` \ register2 ->
-    let
-       dst__2 = registerName register1 zero
-       code = registerCode register2 dst__2
-       src__2 = registerName register2 dst__2
-       code__2 = if isFixed register2 then
-                   code . mkSeqInstr (FMOV src__2 dst__2)
-               else code
-    in
-       returnUs code__2
-
-\end{code}
-
-Generating an unconditional branch.  We accept two types of targets:
-an immediate CLabel or a tree that gets evaluated into a register.
-Any CLabels which are AsmTemporaries are assumed to be in the local
-block of code, close enough for a branch instruction.  Other CLabels
-are assumed to be far away, so we use jmp.
-
-\begin{code}
-
-genJump
-    :: StixTree     -- the branch target
-    -> UniqSM (CodeBlock AlphaInstr)
-
-genJump (StCLbl lbl)
-  | isAsmTemp lbl = returnInstr (BR target)
-  | otherwise     = returnInstrs [LDA pv (AddrImm target), JMP zero (AddrReg pv) 0]
-  where
-    target = ImmCLbl lbl
-
-genJump tree =
-    getReg tree                            `thenUs` \ register ->
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    let
-       dst = registerName register pv
-       code = registerCode register pv
-       target = registerName register pv
-    in
-       if isFixed register then
-           returnSeq code [OR dst (RIReg dst) pv, JMP zero (AddrReg pv) 0]
-       else
-           returnUs (code . mkSeqInstr (JMP zero (AddrReg pv) 0))
-
-\end{code}
-
-Conditional jumps are always to local labels, so we can use
-branch instructions.  We peek at the arguments to decide what kind
-of comparison to do.  For comparisons with 0, we're laughing, because
-we can just do the desired conditional branch.
-
-\begin{code}
-
-genCondJump
-    :: CLabel      -- the branch target
-    -> StixTree     -- the condition on which to branch
-    -> UniqSM (CodeBlock AlphaInstr)
-
-genCondJump lbl (StPrim op [x, StInt 0]) =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG (registerKind register)
-                                   `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       value = registerName register tmp
-       pk = registerKind register
-       target = ImmCLbl lbl
-    in
-           returnSeq code [BI (cmpOp op) value target]
-  where
-    cmpOp CharGtOp = GT
-    cmpOp CharGeOp = GE
-    cmpOp CharEqOp = EQ
-    cmpOp CharNeOp = NE
-    cmpOp CharLtOp = LT
-    cmpOp CharLeOp = LE
-    cmpOp IntGtOp = GT
-    cmpOp IntGeOp = GE
-    cmpOp IntEqOp = EQ
-    cmpOp IntNeOp = NE
-    cmpOp IntLtOp = LT
-    cmpOp IntLeOp = LE
-    cmpOp WordGtOp = NE
-    cmpOp WordGeOp = ALWAYS
-    cmpOp WordEqOp = EQ
-    cmpOp WordNeOp = NE
-    cmpOp WordLtOp = NEVER
-    cmpOp WordLeOp = EQ
-    cmpOp AddrGtOp = NE
-    cmpOp AddrGeOp = ALWAYS
-    cmpOp AddrEqOp = EQ
-    cmpOp AddrNeOp = NE
-    cmpOp AddrLtOp = NEVER
-    cmpOp AddrLeOp = EQ
-
-genCondJump lbl (StPrim op [x, StDouble 0.0]) =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG (registerKind register)
-                                   `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       value = registerName register tmp
-       pk = registerKind register
-       target = ImmCLbl lbl
-    in
-           returnUs (code . mkSeqInstr (BF (cmpOp op) value target))
-  where
-    cmpOp FloatGtOp = GT
-    cmpOp FloatGeOp = GE
-    cmpOp FloatEqOp = EQ
-    cmpOp FloatNeOp = NE
-    cmpOp FloatLtOp = LT
-    cmpOp FloatLeOp = LE
-    cmpOp DoubleGtOp = GT
-    cmpOp DoubleGeOp = GE
-    cmpOp DoubleEqOp = EQ
-    cmpOp DoubleNeOp = NE
-    cmpOp DoubleLtOp = LT
-    cmpOp DoubleLeOp = LE
-
-genCondJump lbl (StPrim op args)
-  | fltCmpOp op =
-    trivialFCode instr args                `thenUs` \ register ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       result = registerName register tmp
-       target = ImmCLbl lbl
-    in
-       returnUs (code . mkSeqInstr (BF cond result target))
-  where
-    fltCmpOp op = case op of
-       FloatGtOp -> True
-       FloatGeOp -> True
-       FloatEqOp -> True
-       FloatNeOp -> True
-       FloatLtOp -> True
-       FloatLeOp -> True
-       DoubleGtOp -> True
-       DoubleGeOp -> True
-       DoubleEqOp -> True
-       DoubleNeOp -> True
-       DoubleLtOp -> True
-       DoubleLeOp -> True
-       _ -> False
-    (instr, cond) = case op of
-       FloatGtOp -> (FCMP TF LE, EQ)
-       FloatGeOp -> (FCMP TF LT, EQ)
-       FloatEqOp -> (FCMP TF EQ, NE)
-       FloatNeOp -> (FCMP TF EQ, EQ)
-       FloatLtOp -> (FCMP TF LT, NE)
-       FloatLeOp -> (FCMP TF LE, NE)
-       DoubleGtOp -> (FCMP TF LE, EQ)
-       DoubleGeOp -> (FCMP TF LT, EQ)
-       DoubleEqOp -> (FCMP TF EQ, NE)
-       DoubleNeOp -> (FCMP TF EQ, EQ)
-       DoubleLtOp -> (FCMP TF LT, NE)
-       DoubleLeOp -> (FCMP TF LE, NE)
-
-genCondJump lbl (StPrim op args) =
-    trivialCode instr args         `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       result = registerName register tmp
-       target = ImmCLbl lbl
-    in
-       returnUs (code . mkSeqInstr (BI cond result target))
-  where
-    (instr, cond) = case op of
-       CharGtOp -> (CMP LE, EQ)
-       CharGeOp -> (CMP LT, EQ)
-       CharEqOp -> (CMP EQ, NE)
-       CharNeOp -> (CMP EQ, EQ)
-       CharLtOp -> (CMP LT, NE)
-       CharLeOp -> (CMP LE, NE)
-       IntGtOp -> (CMP LE, EQ)
-       IntGeOp -> (CMP LT, EQ)
-       IntEqOp -> (CMP EQ, NE)
-       IntNeOp -> (CMP EQ, EQ)
-       IntLtOp -> (CMP LT, NE)
-       IntLeOp -> (CMP LE, NE)
-       WordGtOp -> (CMP ULE, EQ)
-       WordGeOp -> (CMP ULT, EQ)
-       WordEqOp -> (CMP EQ, NE)
-       WordNeOp -> (CMP EQ, EQ)
-       WordLtOp -> (CMP ULT, NE)
-       WordLeOp -> (CMP ULE, NE)
-       AddrGtOp -> (CMP ULE, EQ)
-       AddrGeOp -> (CMP ULT, EQ)
-       AddrEqOp -> (CMP EQ, NE)
-       AddrNeOp -> (CMP EQ, EQ)
-       AddrLtOp -> (CMP ULT, NE)
-       AddrLeOp -> (CMP ULE, NE)
-
-\end{code}
-
-Now the biggest nightmare---calls.  Most of the nastiness is buried in
-getCallArg, which moves the arguments to the correct registers/stack
-locations.  Apart from that, the code is easy.
-
-\begin{code}
-
-genCCall
-    :: FAST_STRING    -- function to call
-    -> PrimRep     -- type of the result
-    -> [StixTree]   -- arguments (of mixed type)
-    -> UniqSM (CodeBlock AlphaInstr)
-
-genCCall fn kind args =
-    mapAccumLNCG getCallArg (argRegs,stackArgLoc) args
-                                   `thenUs` \ ((unused,_), argCode) ->
-    let
-       nRegs = length argRegs - length unused
-       code = asmParThen (map ($ asmVoid) argCode)
-    in
-       returnSeq code [
-           LDA pv (AddrImm (ImmLab (uppPStr fn))),
-           JSR ra (AddrReg pv) nRegs,
-           LDGP gp (AddrReg ra)]
-  where
-    mapAccumLNCG f b []     = returnUs (b, [])
-    mapAccumLNCG f b (x:xs) =
-       f b x                               `thenUs` \ (b__2, x__2) ->
-       mapAccumLNCG f b__2 xs              `thenUs` \ (b__3, xs__2) ->
-       returnUs (b__3, x__2:xs__2)
-
-\end{code}
-
-Trivial (dyadic) instructions.  Only look for constants on the right hand
-side, because that's where the generic optimizer will have put them.
-
-\begin{code}
-
-trivialCode
-    :: (Reg -> RI -> Reg -> AlphaInstr)
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialCode instr [x, StInt y]
-  | is8Bits y =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src1 = registerName register tmp
-       src2 = ImmInt (fromInteger y)
-       code__2 dst = code . mkSeqInstr (instr src1 (RIImm src2) dst)
-    in
-       returnUs (Any IntRep code__2)
-
-trivialCode instr [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1  = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 dst = asmParThen [code1, code2] .
-                    mkSeqInstr (instr src1 (RIReg src2) dst)
-    in
-       returnUs (Any IntRep code__2)
-
-trivialFCode
-    :: (Reg -> Reg -> Reg -> AlphaInstr)
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialFCode instr [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp1 ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp2 ->
-    let
-       code1 = registerCode register1 tmp1
-       src1  = registerName register1 tmp1
-
-       code2 = registerCode register2 tmp2
-       src2  = registerName register2 tmp2
-
-       code__2 dst = asmParThen [code1 asmVoid, code2 asmVoid] .
-                     mkSeqInstr (instr src1 src2 dst)
-    in
-       returnUs (Any DoubleRep code__2)
-
-\end{code}
-
-Some bizarre special code for getting condition codes into registers.
-Integer non-equality is a test for equality followed by an XOR with 1.
-(Integer comparisons always set the result register to 0 or 1.)  Floating
-point comparisons of any kind leave the result in a floating point register,
-so we need to wrangle an integer register out of things.
-
-\begin{code}
-intNECode
-    :: [StixTree]
-    -> UniqSM Register
-
-intNECode args =
-    trivialCode (CMP EQ) args              `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src  = registerName register tmp
-       code__2 dst = code . mkSeqInstr (XOR src (RIImm (ImmInt 1)) dst)
-    in
-       returnUs (Any IntRep code__2)
-
-cmpFCode
-    :: (Reg -> Reg -> Reg -> AlphaInstr)
-    -> Cond
-    -> [StixTree]
-    -> UniqSM Register
-
-cmpFCode instr cond args =
-    trivialFCode instr args                `thenUs` \ register ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp ->
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    let
-       code = registerCode register tmp
-       result  = registerName register tmp
-
-       code__2 dst = code . mkSeqInstrs [
-           OR zero (RIImm (ImmInt 1)) dst,
-           BF cond result (ImmCLbl lbl),
-           OR zero (RIReg zero) dst,
-           LABEL lbl]
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-Trivial unary instructions.  Note that we don't have to worry about
-matching an StInt as the argument, because genericOpt will already
-have handled the constant-folding.
-
-\begin{code}
-
-trivialUCode
-    :: (RI -> Reg -> AlphaInstr)
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialUCode instr [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src  = registerName register tmp
-       code__2 dst = code . mkSeqInstr (instr (RIReg src) dst)
-    in
-       returnUs (Any IntRep code__2)
-
-trivialUFCode
-    :: (Reg -> Reg -> AlphaInstr)
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialUFCode instr [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src  = registerName register tmp
-       code__2 dst = code . mkSeqInstr (instr src dst)
-    in
-       returnUs (Any DoubleRep code__2)
-
-\end{code}
-
-Simple coercions that don't require any code to be generated.
-Here we just change the type on the register passed on up
-
-\begin{code}
-
-coerceIntCode :: PrimRep -> [StixTree] -> UniqSM Register
-coerceIntCode pk [x] =
-    getReg x                       `thenUs` \ register ->
-    case register of
-       Fixed reg _ code -> returnUs (Fixed reg pk code)
-       Any _ code       -> returnUs (Any pk code)
-
-coerceFltCode :: [StixTree] -> UniqSM Register
-coerceFltCode [x] =
-    getReg x                       `thenUs` \ register ->
-    case register of
-       Fixed reg _ code -> returnUs (Fixed reg DoubleRep code)
-       Any _ code       -> returnUs (Any DoubleRep code)
-
-\end{code}
-
-Integer to character conversion.
-
-\begin{code}
-
-chrCode [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ reg ->
-    let
-       code = registerCode register reg
-       src  = registerName register reg
-       code__2 dst = code . mkSeqInstr (ZAPNOT src (RIImm (ImmInt 1)) dst)
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-More complicated integer/float conversions.  Here we have to store
-temporaries in memory to move between the integer and the floating
-point register sets.
-
-\begin{code}
-
-coerceInt2FP :: [StixTree] -> UniqSM Register
-coerceInt2FP [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ reg ->
-    let
-       code = registerCode register reg
-       src  = registerName register reg
-
-       code__2 dst = code . mkSeqInstrs [
-           ST Q src (spRel 0),
-           LD TF dst (spRel 0),
-           CVTxy Q TF dst dst]
-    in
-       returnUs (Any DoubleRep code__2)
-
-coerceFP2Int :: [StixTree] -> UniqSM Register
-coerceFP2Int [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src  = registerName register tmp
-
-       code__2 dst = code . mkSeqInstrs [
-           CVTxy TF Q src tmp,
-           ST TF tmp (spRel 0),
-           LD Q dst (spRel 0)]
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-Some random little helpers.
-
-\begin{code}
-
-is8Bits :: Integer -> Bool
-is8Bits i = i >= -256 && i < 256
-
-maybeImm :: StixTree -> Maybe Imm
-maybeImm (StInt i)
-  | i >= toInteger minInt && i <= toInteger maxInt = Just (ImmInt (fromInteger i))
-  | otherwise = Just (ImmInteger i)
-maybeImm (StLitLbl s)  = Just (ImmLab s)
-maybeImm (StLitLit s)  = Just (strImmLab (cvtLitLit (_UNPK_ s)))
-maybeImm (StCLbl l) = Just (ImmCLbl l)
-maybeImm _          = Nothing
-
-mangleIndexTree :: StixTree -> StixTree
-
-mangleIndexTree (StIndex pk base (StInt i)) =
-    StPrim IntAddOp [base, off]
-  where
-    off = StInt (i * size pk)
-    size :: PrimRep -> Integer
-    size pk = case kindToSize pk of
-       {B -> 1; BU -> 1; W -> 2; WU -> 2; L -> 4; FF -> 4; SF -> 4; _ -> 8}
-
-mangleIndexTree (StIndex pk base off) =
-    case pk of
-       CharRep -> StPrim IntAddOp [base, off]
-       _        -> StPrim IntAddOp [base, off__2]
-  where
-    off__2 = StPrim SllOp [off, StInt 3]
-
-cvtLitLit :: String -> String
-cvtLitLit "stdin" = "_iob+0"   -- This one is probably okay...
-cvtLitLit "stdout" = "_iob+56" -- but these next two are dodgy at best
-cvtLitLit "stderr" = "_iob+112"
-cvtLitLit s
-  | isHex s = s
-  | otherwise = error ("Native code generator can't handle ``" ++ s ++ "''")
-  where
-    isHex ('0':'x':xs) = all isHexDigit xs
-    isHex _ = False
-    -- Now, where have I seen this before?
-    isHexDigit c = isDigit c || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'
-
-
-\end{code}
-
-spRel gives us a stack relative addressing mode for volatile temporaries
-and for excess call arguments.
-
-\begin{code}
-
-spRel
-    :: Int     -- desired stack offset in words, positive or negative
-    -> Addr
-spRel n = AddrRegImm sp (ImmInt (n * 8))
-
-stackArgLoc = 0 :: Int     -- where to stack extra call arguments (beyond 6)
-
-\end{code}
-
-\begin{code}
-
-getNewRegNCG :: PrimRep -> UniqSM Reg
-getNewRegNCG pk =
-      getUnique          `thenUs` \ u ->
-      returnUs (mkReg u pk)
-
-\end{code}
index da0d83b..ac259c4 100644 (file)
 %
 %
-% (c) The AQUA Project, Glasgow University, 1993-1995
+% (c) The AQUA Project, Glasgow University, 1993-1996
 %
 
 \begin{code}
 #include "HsVersions.h"
 %
 
 \begin{code}
 #include "HsVersions.h"
-#include "../../includes/platform.h"
-#include "../../includes/GhcConstants.h"
-
-module AsmCodeGen (
-       writeRealAsm,
-       dumpRealAsm,
-
-       -- And, I guess we need these...
-       AbstractC, GlobalSwitch, SwitchResult,
-       UniqSupply, UniqSM(..)
-    ) where
-
-import AbsCSyn     ( AbstractC )
-import AbsCStixGen  ( genCodeAbstractC )
-import PrelInfo            ( PrimRep, PrimOp(..)
-                     IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                   )
-import CmdLineOpts  ( GlobalSwitch(..), stringSwitchSet, switchIsOn, SwitchResult(..) )
-import MachDesc
-import Maybes      ( Maybe(..) )
-import Outputable
-#if alpha_TARGET_ARCH
-import AlphaDesc    ( mkAlpha )
-#endif
-#if i386_TARGET_ARCH
-import I386Desc            ( mkI386 )
-#endif
-#if sparc_TARGET_ARCH
-import SparcDesc    ( mkSparc )
-#endif
-import Stix
-import UniqSupply
-import Unpretty
-import Util
+
+module AsmCodeGen ( writeRealAsm, dumpRealAsm ) where
+
+import Ubiq{-uitous-}
+
+import MachMisc
+import MachRegs
+import MachCode
+import PprMach
+
+import AbsCStixGen     ( genCodeAbstractC )
+import AbsCSyn         ( AbstractC, MagicId )
+import AsmRegAlloc     ( runRegAllocate )
+import OrdList         ( OrdList )
+import PrimOp          ( commutableOp, PrimOp(..) )
+import PrimRep         ( PrimRep{-instance Eq-} )
+import RegAllocInfo    ( mkMRegsState, MRegsState )
+import Stix            ( StixTree(..), StixReg(..), CodeSegment )
+import UniqSupply      ( returnUs, thenUs, mapUs, UniqSM(..) )
+import Unpretty                ( uppAppendFile, uppShow, uppAboves, Unpretty(..) )
 \end{code}
 
 \end{code}
 
-This is a generic assembly language generator for the Glasgow Haskell
-Compiler.  It has been a long time in germinating, basically due to
-time constraints and the large spectrum of design possibilities.
-Presently it generates code for:
-\begin{itemize}
-\item Sparc
-\end{itemize}
-In the pipeline (sic) are plans and/or code for 680x0, 386/486.
-
-The code generator presumes the presence of a working C port.  This is
-because any code that cannot be compiled (e.g. @casm@s) is re-directed
-via this route. It also help incremental development.  Because this
-code generator is specially written for the Abstract C produced by the
-Glasgow Haskell Compiler, several optimisation opportunities are open
-to us that are not open to @gcc@.  In particular, we know that the A
-and B stacks and the Heap are all mutually exclusive wrt. aliasing,
-and that expressions have no side effects (all state transformations
-are top level objects).
-
-There are two main components to the code generator.
-\begin{itemize}
-\item Abstract C is considered in statements,
-       with a Twig-like system handling each statement in turn.
-\item A scheduler turns the tree of assembly language orderings
-      into a sequence suitable for input to an assembler.
-\end{itemize}
-The @codeGenerate@ function returns the final assembly language output
-(as a String). We can return a string, because there is only one way
-of printing the output suitable for assembler consumption. It also
-allows limited abstraction of different machines from the Main module.
-
-The first part is the actual assembly language generation.  First we
-split up the Abstract C into individual functions, then consider
-chunks in isolation, giving back an @OrdList@ of assembly language
-instructions.  The generic algorithm is heavily inspired by Twig
-(ref), but also draws concepts from (ref).  The basic idea is to
-(dynamically) walk the Abstract C syntax tree, annotating it with
-possible code matches. For example, on the Sparc, a possible match
-(with its translation) could be
-@
-   :=
-   / \
-  i   r2       => ST r2,[r1]
-  |
-  r1
-@
-where @r1,r2@ are registers, and @i@ is an indirection.         The Twig
-bit twiddling algorithm for tree matching has been abandoned. It is
-replaced with a more direct scheme.  This is because, after careful
-consideration it is felt that the overhead of handling many bit
-patterns would be heavier that simply looking at the syntax of the
-tree at the node being considered, and dynamically choosing and
-pruning rules.
-
-The ultimate result of the first part is a Set of ordering lists of
-ordering lists of assembly language instructions (yes, really!), where
-each element in the set is basic chunk.         Now several (generic)
-simplifications and transformations can be performed.  This includes
-ones that turn the the ordering of orderings into just a single
-ordering list. (The equivalent of applying @concat@ to a list of
-lists.) A lot of the re-ordering and optimisation is actually done
-(generically) here!  The final part, the scheduler, can now be used on
-this structure.         The code sequence is optimised (obviously) to avoid
-stalling the pipeline. This part {\em has} to be heavily machine
-dependent.
-
-[The above seems to describe mostly dreamware.  -- JSM]
-
-The flag that needs to be added is -fasm-<platform> where platform is one of
-the choices below.
+The 96/03 native-code generator has machine-independent and
+machine-dependent modules (those \tr{#include}'ing \tr{NCG.h}).
+
+This module (@AsmCodeGen@) is the top-level machine-independent
+module.  It uses @AbsCStixGen.genCodeAbstractC@ to produce @StixTree@s
+(defined in module @Stix@), using support code from @StixInfo@ (info
+tables), @StixPrim@ (primitive operations), @StixMacro@ (Abstract C
+macros), and @StixInteger@ (GMP arbitrary-precision operations).
+
+Before entering machine-dependent land, we do some machine-independent
+@genericOpt@imisations (defined below) on the @StixTree@s.
+
+We convert to the machine-specific @Instr@ datatype with
+@stmt2Instrs@, assuming an ``infinite'' supply of registers.  We then
+use a machine-independent register allocator (@runRegAllocate@) to
+rejoin reality.  Obviously, @runRegAllocate@ has machine-specific
+helper functions (see about @RegAllocInfo@ below).
+
+The machine-dependent bits break down as follows:
+\begin{description}
+\item[@MachRegs@:]  Everything about the target platform's machine
+    registers (and immediate operands, and addresses, which tend to
+    intermingle/interact with registers).
+
+\item[@MachMisc@:]  Includes the @Instr@ datatype (possibly should
+    have a module of its own), plus a miscellany of other things
+    (e.g., @targetDoubleSize@, @smStablePtrTable@, ...)
+
+\item[@MachCode@:]  @stmt2Instrs@ is where @Stix@ stuff turns into
+    machine instructions.
 
 
+\item[@PprMach@:] @pprInstr@ turns an @Instr@ into text (well, really
+    an @Unpretty@).
+
+\item[@RegAllocInfo@:] In the register allocator, we manipulate
+    @MRegsState@s, which are @BitSet@s, one bit per machine register.
+    When we want to say something about a specific machine register
+    (e.g., ``it gets clobbered by this instruction''), we set/unset
+    its bit.  Obviously, we do this @BitSet@ thing for efficiency
+    reasons.
+
+    The @RegAllocInfo@ module collects together the machine-specific
+    info needed to do register allocation.
+\end{description}
+
+So, here we go:
 \begin{code}
 \begin{code}
-writeRealAsm :: (GlobalSwitch -> SwitchResult) -> _FILE -> AbstractC -> UniqSupply -> PrimIO ()
+writeRealAsm :: _FILE -> AbstractC -> UniqSupply -> IO ()
 
 
-writeRealAsm flags file absC uniq_supply
-  = uppAppendFile file 80 (runNCG (code flags absC) uniq_supply)
+writeRealAsm file absC us
+  = uppAppendFile file 80 (runNCG absC us)
 
 
-dumpRealAsm :: (GlobalSwitch -> SwitchResult) -> AbstractC -> UniqSupply -> String
+dumpRealAsm :: AbstractC -> UniqSupply -> String
 
 
-dumpRealAsm flags absC uniq_supply = uppShow 80 (runNCG (code flags absC) uniq_supply)
+dumpRealAsm absC us = uppShow 80 (runNCG absC us)
 
 
-runNCG m uniq_supply = m uniq_supply
+runNCG absC
+  = genCodeAbstractC absC      `thenUs` \ treelists ->
+    let
+       stix = map (map genericOpt) treelists
+    in
+    codeGen stix
+\end{code}
 
 
-code flags absC =
-    genCodeAbstractC target absC                   `thenUs` \ treelists ->
+@codeGen@ is the top-level code-generation function:
+\begin{code}
+codeGen :: [[StixTree]] -> UniqSM Unpretty
+
+codeGen trees
+  = mapUs genMachCode trees    `thenUs` \ dynamic_codes ->
     let
     let
-       stix = map (map (genericOpt target)) treelists
+       static_instrs = scheduleMachCode dynamic_codes
     in
     in
-    codeGen {-target-} sty stix
-  where
-    sty = PprForAsm (switchIsOn flags) (underscore {-target-}) (fmtAsmLbl {-target-})
-
-    (target, codeGen, underscore, fmtAsmLbl)
-      = case stringSwitchSet flags AsmTarget of
-#if ! OMIT_NATIVE_CODEGEN
-# if alpha_TARGET_ARCH
-       Just _ {-???"alpha-dec-osf1"-} -> mkAlpha flags
-# endif
-# if i386_TARGET_ARCH
-       Just _ {-???"i386_unknown_linuxaout"-} -> mkI386 True flags
-# endif
-# if sparc_sun_sunos4_TARGET
-       Just _ {-???"sparc-sun-sunos4"-} -> mkSparc True flags
-# endif
-# if sparc_sun_solaris2_TARGET
-       Just _ {-???"sparc-sun-solaris2"-} -> mkSparc False flags
-# endif
-#endif
-       _ -> error
-            ("ERROR:Trying to generate assembly language for an unsupported architecture\n"++
-             "(or one for which this build is not configured).")
+    returnUs (uppAboves (map pprInstr static_instrs))
+\end{code}
 
 
+Top level code generator for a chunk of stix code:
+\begin{code}
+genMachCode :: [StixTree] -> UniqSM InstrList
+
+genMachCode stmts
+  = mapUs stmt2Instrs stmts                    `thenUs` \ blocks ->
+    returnUs (foldr (.) id blocks asmVoid)
+\end{code}
+
+The next bit does the code scheduling.  The scheduler must also deal
+with register allocation of temporaries.  Much parallelism can be
+exposed via the OrdList, but more might occur, so further analysis
+might be needed.
+
+\begin{code}
+scheduleMachCode :: [InstrList] -> [Instr]
+
+scheduleMachCode
+  = concat . map (runRegAllocate freeRegsState reservedRegs)
+  where
+    freeRegsState = mkMRegsState (extractMappedRegNos freeRegs)
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -161,128 +131,108 @@ code flags absC =
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-This is called between translating Abstract C to its Tree
-and actually using the Native Code Generator to generate
-the annotations.  It's a chance to do some strength reductions.
+This is called between translating Abstract C to its Tree and actually
+using the Native Code Generator to generate the annotations.  It's a
+chance to do some strength reductions.
 
 ** Remember these all have to be machine independent ***
 
 
 ** Remember these all have to be machine independent ***
 
-Note that constant-folding should have already happened, but we might have
-introduced some new opportunities for constant-folding wrt address manipulations.
+Note that constant-folding should have already happened, but we might
+have introduced some new opportunities for constant-folding wrt
+address manipulations.
 
 \begin{code}
 
 \begin{code}
-
-genericOpt
-    :: Target
-    -> StixTree
-    -> StixTree
-
+genericOpt :: StixTree -> StixTree
 \end{code}
 
 For most nodes, just optimize the children.
 
 \begin{code}
 \end{code}
 
 For most nodes, just optimize the children.
 
 \begin{code}
--- hacking with Uncle Will:
-#define target_STRICT target@(Target _ _ _ _ _ _ _ _)
-
-genericOpt target_STRICT (StInd pk addr) =
-    StInd pk (genericOpt target addr)
-
-genericOpt target (StAssign pk dst src) =
-    StAssign pk (genericOpt target dst) (genericOpt target src)
+genericOpt (StInd pk addr) = StInd pk (genericOpt addr)
 
 
-genericOpt target (StJump addr) =
-    StJump (genericOpt target addr)
+genericOpt (StAssign pk dst src)
+  = StAssign pk (genericOpt dst) (genericOpt src)
 
 
-genericOpt target (StCondJump addr test) =
-    StCondJump addr (genericOpt target test)
+genericOpt (StJump addr) = StJump (genericOpt addr)
 
 
-genericOpt target (StCall fn pk args) =
-    StCall fn pk (map (genericOpt target) args)
+genericOpt (StCondJump addr test)
+  = StCondJump addr (genericOpt test)
 
 
+genericOpt (StCall fn pk args)
+  = StCall fn pk (map genericOpt args)
 \end{code}
 
 \end{code}
 
-Fold indices together when the types match.
-
+Fold indices together when the types match:
 \begin{code}
 \begin{code}
+genericOpt (StIndex pk (StIndex pk' base off) off')
+  | pk == pk'
+  = StIndex pk (genericOpt base)
+              (genericOpt (StPrim IntAddOp [off, off']))
 
 
-genericOpt target (StIndex pk (StIndex pk' base off) off')
-  | pk == pk' =
-    StIndex pk (genericOpt target base)
-              (genericOpt target (StPrim IntAddOp [off, off']))
-
-genericOpt target (StIndex pk base off) =
-    StIndex pk (genericOpt target base)
-              (genericOpt target off)
-
+genericOpt (StIndex pk base off)
+  = StIndex pk (genericOpt base) (genericOpt off)
 \end{code}
 
 \end{code}
 
-For primOps, we first optimize the children, and then we try our hand
+For PrimOps, we first optimize the children, and then we try our hand
 at some constant-folding.
 
 \begin{code}
 at some constant-folding.
 
 \begin{code}
-
-genericOpt target (StPrim op args) =
-    primOpt op (map (genericOpt target) args)
-
+genericOpt (StPrim op args) = primOpt op (map genericOpt args)
 \end{code}
 
 \end{code}
 
-Replace register leaves with appropriate StixTrees for the given target.
-(Oh, so this is why we've been hauling the target around!)
+Replace register leaves with appropriate StixTrees for the given
+target.
 
 \begin{code}
 
 \begin{code}
+genericOpt leaf@(StReg (StixMagicId id))
+  = case (stgReg id) of
+       Always tree -> genericOpt tree
+       Save _      -> leaf
 
 
-genericOpt target leaf@(StReg (StixMagicId id)) =
-    case stgReg target id of
-       Always tree -> genericOpt target tree
-       Save _     -> leaf
-
-genericOpt target other = other
-
+genericOpt other = other
 \end{code}
 
 \end{code}
 
-Now, try to constant-fold the primOps.  The arguments have
-already been optimized and folded.
+Now, try to constant-fold the PrimOps.  The arguments have already
+been optimized and folded.
 
 \begin{code}
 
 \begin{code}
-
 primOpt
     :: PrimOp          -- The operation from an StPrim
     -> [StixTree]      -- The optimized arguments
     -> StixTree
 
 primOpt
     :: PrimOp          -- The operation from an StPrim
     -> [StixTree]      -- The optimized arguments
     -> StixTree
 
-primOpt op arg@[StInt x] =
-    case op of
+primOpt op arg@[StInt x]
+  = case op of
        IntNegOp -> StInt (-x)
        IntAbsOp -> StInt (abs x)
        _ -> StPrim op arg
 
        IntNegOp -> StInt (-x)
        IntAbsOp -> StInt (abs x)
        _ -> StPrim op arg
 
-primOpt op args@[StInt x, StInt y] =
-    case op of
-       CharGtOp -> StInt (if x > y then 1 else 0)
+primOpt op args@[StInt x, StInt y]
+  = case op of
+       CharGtOp -> StInt (if x > y  then 1 else 0)
        CharGeOp -> StInt (if x >= y then 1 else 0)
        CharEqOp -> StInt (if x == y then 1 else 0)
        CharNeOp -> StInt (if x /= y then 1 else 0)
        CharGeOp -> StInt (if x >= y then 1 else 0)
        CharEqOp -> StInt (if x == y then 1 else 0)
        CharNeOp -> StInt (if x /= y then 1 else 0)
-       CharLtOp -> StInt (if x < y then 1 else 0)
+       CharLtOp -> StInt (if x < y  then 1 else 0)
        CharLeOp -> StInt (if x <= y then 1 else 0)
        IntAddOp -> StInt (x + y)
        IntSubOp -> StInt (x - y)
        IntMulOp -> StInt (x * y)
        IntQuotOp -> StInt (x `quot` y)
        IntRemOp -> StInt (x `rem` y)
        CharLeOp -> StInt (if x <= y then 1 else 0)
        IntAddOp -> StInt (x + y)
        IntSubOp -> StInt (x - y)
        IntMulOp -> StInt (x * y)
        IntQuotOp -> StInt (x `quot` y)
        IntRemOp -> StInt (x `rem` y)
-       IntGtOp -> StInt (if x > y then 1 else 0)
+       IntGtOp -> StInt (if x > y  then 1 else 0)
        IntGeOp -> StInt (if x >= y then 1 else 0)
        IntEqOp -> StInt (if x == y then 1 else 0)
        IntNeOp -> StInt (if x /= y then 1 else 0)
        IntGeOp -> StInt (if x >= y then 1 else 0)
        IntEqOp -> StInt (if x == y then 1 else 0)
        IntNeOp -> StInt (if x /= y then 1 else 0)
-       IntLtOp -> StInt (if x < y then 1 else 0)
+       IntLtOp -> StInt (if x < y  then 1 else 0)
        IntLeOp -> StInt (if x <= y then 1 else 0)
        _ -> StPrim op args
        IntLeOp -> StInt (if x <= y then 1 else 0)
        _ -> StPrim op args
-
 \end{code}
 
 When possible, shift the constants to the right-hand side, so that we
 can match for strength reductions.  Note that the code generator will
 \end{code}
 
 When possible, shift the constants to the right-hand side, so that we
 can match for strength reductions.  Note that the code generator will
-also assume that constants have been shifted to the right when possible.
+also assume that constants have been shifted to the right when
+possible.
 
 \begin{code}
 primOpt op [x@(StInt _), y] | commutableOp op = primOpt op [y, x]
 
 \begin{code}
 primOpt op [x@(StInt _), y] | commutableOp op = primOpt op [y, x]
@@ -291,40 +241,40 @@ primOpt op [x@(StInt _), y] | commutableOp op = primOpt op [y, x]
 We can often do something with constants of 0 and 1 ...
 
 \begin{code}
 We can often do something with constants of 0 and 1 ...
 
 \begin{code}
-primOpt op args@[x, y@(StInt 0)] =
-    case op of
+primOpt op args@[x, y@(StInt 0)]
+  = case op of
        IntAddOp -> x
        IntSubOp -> x
        IntMulOp -> y
        IntAddOp -> x
        IntSubOp -> x
        IntMulOp -> y
-       AndOp  -> y
-       OrOp   -> x
-       SllOp  -> x
-       SraOp  -> x
-       SrlOp  -> x
-       ISllOp -> x
-       ISraOp -> x
-       ISrlOp -> x
-       _ -> StPrim op args
-
-primOpt op args@[x, y@(StInt 1)] =
-    case op of
-       IntMulOp -> x
+       AndOp    -> y
+       OrOp     -> x
+       SllOp    -> x
+       SraOp    -> x
+       SrlOp    -> x
+       ISllOp   -> x
+       ISraOp   -> x
+       ISrlOp   -> x
+       _        -> StPrim op args
+
+primOpt op args@[x, y@(StInt 1)]
+  = case op of
+       IntMulOp  -> x
        IntQuotOp -> x
        IntQuotOp -> x
-       IntRemOp -> StInt 0
-       _ -> StPrim op args
+       IntRemOp  -> StInt 0
+       _         -> StPrim op args
 \end{code}
 
 Now look for multiplication/division by powers of 2 (integers).
 
 \begin{code}
 \end{code}
 
 Now look for multiplication/division by powers of 2 (integers).
 
 \begin{code}
-primOpt op args@[x, y@(StInt n)] =
-    case op of
-       IntMulOp -> case exact_log2 n of
+primOpt op args@[x, y@(StInt n)]
+  = case op of
+       IntMulOp -> case exactLog2 n of
            Nothing -> StPrim op args
            Nothing -> StPrim op args
-           Just p -> StPrim SllOp [x, StInt p]
-       IntQuotOp -> case exact_log2 n of
+           Just p  -> StPrim SllOp [x, StInt p]
+       IntQuotOp -> case exactLog2 n of
            Nothing -> StPrim op args
            Nothing -> StPrim op args
-           Just p -> StPrim SraOp [x, StInt p]
+           Just p  -> StPrim SraOp [x, StInt p]
        _ -> StPrim op args
 \end{code}
 
        _ -> StPrim op args
 \end{code}
 
@@ -333,52 +283,3 @@ Anything else is just too hard.
 \begin{code}
 primOpt op args = StPrim op args
 \end{code}
 \begin{code}
 primOpt op args = StPrim op args
 \end{code}
-
-The commutable ops are those for which we will try to move constants
-to the right hand side for strength reduction.
-
-\begin{code}
-commutableOp :: PrimOp -> Bool
-
-commutableOp CharEqOp = True
-commutableOp CharNeOp = True
-commutableOp IntAddOp = True
-commutableOp IntMulOp = True
-commutableOp AndOp = True
-commutableOp OrOp = True
-commutableOp IntEqOp = True
-commutableOp IntNeOp = True
-commutableOp IntegerAddOp = True
-commutableOp IntegerMulOp = True
-commutableOp FloatAddOp = True
-commutableOp FloatMulOp = True
-commutableOp FloatEqOp = True
-commutableOp FloatNeOp = True
-commutableOp DoubleAddOp = True
-commutableOp DoubleMulOp = True
-commutableOp DoubleEqOp = True
-commutableOp DoubleNeOp = True
-commutableOp _ = False
-\end{code}
-
-This algorithm for determining the $\log_2$ of exact powers of 2 comes
-from gcc.  It requires bit manipulation primitives, so we have a ghc
-version and an hbc version.  Other Haskell compilers are on their own.
-
-\begin{code}
-w2i x = word2Int# x
-i2w x = int2Word# x
-i2w_s x = (x::Int#)
-
-exact_log2 :: Integer -> Maybe Integer
-exact_log2 x
-    | x <= 0 || x >= 2147483648 = Nothing
-    | otherwise = case fromInteger x of
-       I# x# -> if (w2i ((i2w x#) `and#` (i2w (0# -# x#))) /=# x#) then Nothing
-                else Just (toInteger (I# (pow2 x#)))
-
-           where pow2 x# | x# ==# 1# = 0#
-                         | otherwise = 1# +# pow2 (w2i (i2w x# `shiftr` i2w_s 1#))
-
-                 shiftr x y = shiftRA# x y
-\end{code}
index 29061de..8e574e6 100644 (file)
 %
 %
-% (c) The AQUA Project, Glasgow University, 1993-1995
+% (c) The AQUA Project, Glasgow University, 1993-1996
 %
 %
+\section[AsmRegAlloc]{Register allocator}
 
 \begin{code}
 #include "HsVersions.h"
 
 \begin{code}
 #include "HsVersions.h"
-#include "../../includes/platform.h"
-#include "../../includes/GhcConstants.h"
 
 
-module AsmRegAlloc (
-       FutureLive(..), RegLiveness(..), RegUsage(..), Reg(..),
-       MachineRegisters(..), MachineCode(..),
+module AsmRegAlloc ( runRegAllocate, runHairyRegAllocate ) where       
 
 
-       mkReg, runRegAllocate, runHairyRegAllocate,
-       extractMappedRegNos
+import Ubiq{-uitous-}
 
 
-       -- And, for self-sufficiency
-    ) where
+import MachCode                ( InstrList(..) )
+import MachMisc                ( Instr )
+import MachRegs
+import RegAllocInfo
 
 
-import CLabel  ( CLabel )
-import FiniteMap
-import MachDesc
-import Maybes          ( maybeToBool, Maybe(..) )
-import OrdList         -- ( mkUnitList, mkSeqList, mkParList, OrdList )
-import Outputable
-import Pretty
-import UniqSet
-import Unique          ( Unique )
-import Util
-
-#if ! OMIT_NATIVE_CODEGEN
-
-# if alpha_TARGET_ARCH
-import AlphaCode       -- ( AlphaInstr, AlphaRegs ) -- for specializing
-
-{-# SPECIALIZE
-    runRegAllocate :: AlphaRegs -> [Int] -> (OrdList AlphaInstr) -> [AlphaInstr]
-  #-}
-# endif
-
-# if i386_TARGET_ARCH
-import I386Code                -- ( I386Instr, I386Regs ) -- for specializing
-
-{-# SPECIALIZE
-    runRegAllocate :: I386Regs -> [Int] -> (OrdList I386Instr) -> [I386Instr]
-  #-}
-# endif
-
-# if sparc_TARGET_ARCH
-import SparcCode       -- ( SparcInstr, SparcRegs ) -- for specializing
-
-{-# SPECIALIZE
-    runRegAllocate :: SparcRegs -> [Int] -> (OrdList SparcInstr) -> [SparcInstr]
-  #-}
-# endif
-
-#endif
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Reg]{Real registers}
-%*                                                                     *
-%************************************************************************
-
-Static Registers correspond to actual machine registers.  These should
-be avoided until the last possible moment.
-
-Dynamic registers are allocated on the fly, usually to represent a single
-value in the abstract assembly code (i.e. dynamic registers are usually
-single assignment).  Ultimately, they are mapped to available machine
-registers before spitting out the code.
-
-\begin{code}
-
-data Reg = FixedReg  FAST_INT          -- A pre-allocated machine register
-
-        | MappedReg FAST_INT           -- A dynamically allocated machine register
-
-        | MemoryReg Int PrimRep        -- A machine "register" actually held in a memory
-                                       -- allocated table of registers which didn't fit
-                                       -- in real registers.
-
-        | UnmappedReg Unique PrimRep   -- One of an infinite supply of registers,
-                                       -- always mapped to one of the earlier two
-                                       -- before we're done.
-        -- No thanks: deriving (Eq)
-
-mkReg :: Unique -> PrimRep -> Reg
-mkReg = UnmappedReg
-
-instance Text Reg where
-    showsPrec _ (FixedReg i)   = showString "%"  . shows IBOX(i)
-    showsPrec _ (MappedReg i)  = showString "%"  . shows IBOX(i)
-    showsPrec _ (MemoryReg i _) = showString "%M"  . shows i
-    showsPrec _ (UnmappedReg i _) = showString "%U" . shows i
-
-#ifdef DEBUG
-instance Outputable Reg where
-    ppr sty r = ppStr (show r)
-#endif
-
-cmpReg (FixedReg i) (FixedReg i') = cmp_ihash i i'
-cmpReg (MappedReg i) (MappedReg i') = cmp_ihash i i'
-cmpReg (MemoryReg i _) (MemoryReg i' _) = cmp_i i i'
-cmpReg (UnmappedReg u _) (UnmappedReg u' _) = cmp u u'
-cmpReg r1 r2 =
-    let tag1 = tagReg r1
-       tag2 = tagReg r2
-    in
-       if tag1 _LT_ tag2 then LT_ else GT_
-    where
-       tagReg (FixedReg _)      = (ILIT(1) :: FAST_INT)
-       tagReg (MappedReg _)     = ILIT(2)
-       tagReg (MemoryReg _ _)   = ILIT(3)
-       tagReg (UnmappedReg _ _) = ILIT(4)
-
-cmp_i :: Int -> Int -> TAG_
-cmp_i a1 a2 = if a1 == a2 then EQ_ else if a1 < a2 then LT_ else GT_
-
-cmp_ihash :: FAST_INT -> FAST_INT -> TAG_
-cmp_ihash a1 a2 = if a1 _EQ_ a2 then EQ_ else if a1 _LT_ a2 then LT_ else GT_
-
-instance Eq Reg where
-    a == b = case cmpReg a b of { EQ_ -> True;  _ -> False }
-    a /= b = case cmpReg a b of { EQ_ -> False; _ -> True  }
-
-instance Ord Reg where
-    a <= b = case cmpReg a b of { LT_ -> True; EQ_ -> True;  GT__ -> False }
-    a <         b = case cmpReg a b of { LT_ -> True;  EQ_ -> False; GT__ -> False }
-    a >= b = case cmpReg a b of { LT_ -> False; EQ_ -> True;  GT__ -> True  }
-    a >         b = case cmpReg a b of { LT_ -> False; EQ_ -> False; GT__ -> True  }
-    _tagCmp a b = case cmpReg a b of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
-
-instance NamedThing Reg where
-    -- the *only* method that should be defined is "getItsUnique"!
-    -- (so we can use UniqFMs/UniqSets on Regs
-    getItsUnique (UnmappedReg u _) = u
-    getItsUnique (FixedReg i)     = mkPseudoUnique1 IBOX(i)
-    getItsUnique (MappedReg i)    = mkPseudoUnique2 IBOX(i)
-    getItsUnique (MemoryReg i _)   = mkPseudoUnique3 i
+import BitSet          ( BitSet )
+import FiniteMap       ( emptyFM, addListToFM, delListFromFM, lookupFM, keysFM )
+import Maybes          ( maybeToBool )
+import OrdList         ( mkEmptyList, mkUnitList, mkSeqList, mkParList,
+                         flattenOrdList, OrdList
+                       )
+import Stix            ( StixTree )
+import UniqSupply      ( mkBuiltinUnique )
+import Util            ( mapAccumB, panic )
 \end{code}
 
 This is the generic register allocator.
 
 \end{code}
 
 This is the generic register allocator.
 
-%************************************************************************
-%*                                                                     *
-\subsection[RegPlace]{Map Stix registers to {\em real} registers}
-%*                                                                     *
-%************************************************************************
-
-An important point:  The @regUsage@ function for a particular assembly language
-must not refer to fixed registers, such as Hp, SpA, etc.  The source and destination
-lists should only refer to dynamically allocated registers or static registers
-from the free list.  As far as we are concerned, the fixed registers simply don't
-exist (for allocation purposes, anyway).
-
-\begin{code}
-
-class MachineRegisters a where
-    mkMRegs        :: [Int] -> a
-    possibleMRegs   :: PrimRep -> a -> [Int]
-    useMReg        :: a -> FAST_INT -> a
-    useMRegs       :: a -> [Int] -> a
-    freeMReg       :: a -> FAST_INT -> a
-    freeMRegs      :: a -> [Int] -> a
-
-type RegAssignment = FiniteMap Reg Reg
-type RegConflicts = FiniteMap Int (UniqSet Reg)
-
-data FutureLive
-  = FL (UniqSet Reg)
-       (FiniteMap CLabel (UniqSet Reg))
-fstFL (FL a b) = a
-
-data RegHistory a
-  = RH a
-       Int
-       RegAssignment
-
-data RegFuture
-  = RF (UniqSet Reg)   -- in use
-       FutureLive      -- future
-       RegConflicts
-
-data RegInfo a
-  = RI (UniqSet Reg)   -- in use
-       (UniqSet Reg)   -- sources
-       (UniqSet Reg)   -- destinations
-       [Reg]           -- last used
-       RegConflicts
-
-data RegUsage
-  = RU (UniqSet Reg)
-       (UniqSet Reg)
-
-data RegLiveness
-  = RL (UniqSet Reg)
-       FutureLive
-
-class MachineCode a where
-      regUsage     :: a -> RegUsage
-      regLiveness   :: a -> RegLiveness -> RegLiveness
-      patchRegs            :: a -> (Reg -> Reg) -> a
-      spillReg     :: Reg -> Reg -> OrdList a
-      loadReg      :: Reg -> Reg -> OrdList a
-\end{code}
-
-First we try something extremely simple.
-If that fails, we have to do things the hard way.
+First we try something extremely simple.  If that fails, we have to do
+things the hard way.
 
 \begin{code}
 runRegAllocate
 
 \begin{code}
 runRegAllocate
-    :: (MachineRegisters a, MachineCode b)
-    => a
-    -> [Int]
-    -> (OrdList b)
-    -> [b]
-
-runRegAllocate regs reserve_regs instrs =
-    case simpleAlloc of
+    :: MRegsState
+    -> [RegNo]
+    -> InstrList
+    -> [Instr]
+
+runRegAllocate regs reserve_regs instrs
+  = case simpleAlloc of
        Just x  -> x
        Nothing -> hairyAlloc
   where
     flatInstrs = flattenOrdList instrs
        Just x  -> x
        Nothing -> hairyAlloc
   where
     flatInstrs = flattenOrdList instrs
-    simpleAlloc = simpleRegAlloc regs [] emptyFM flatInstrs
-    hairyAlloc = hairyRegAlloc regs reserve_regs flatInstrs
+    simpleAlloc = simpleRegAlloc regs [] emptyFM   flatInstrs
+    hairyAlloc = hairyRegAlloc  regs reserve_regs flatInstrs
 
 runHairyRegAllocate            -- use only hairy for i386!
 
 runHairyRegAllocate            -- use only hairy for i386!
-    :: (MachineRegisters a, MachineCode b)
-    => a
-    -> [Int]
-    -> (OrdList b)
-    -> [b]
+    :: MRegsState
+    -> [RegNo]
+    -> InstrList
+    -> [Instr]
 
 runHairyRegAllocate regs reserve_regs instrs
   = hairyRegAlloc regs reserve_regs flatInstrs
 
 runHairyRegAllocate regs reserve_regs instrs
   = hairyRegAlloc regs reserve_regs flatInstrs
@@ -248,25 +67,24 @@ this approach will suffice for about 96 percent of the code blocks that
 we generate.
 
 \begin{code}
 we generate.
 
 \begin{code}
-
 simpleRegAlloc
 simpleRegAlloc
-    :: (MachineRegisters a, MachineCode b)
-    => a               -- registers to select from
+    :: MRegsState      -- registers to select from
     -> [Reg]           -- live static registers
     -> RegAssignment   -- mapping of dynamics to statics
     -> [Reg]           -- live static registers
     -> RegAssignment   -- mapping of dynamics to statics
-    -> [b]             -- code
-    -> Maybe [b]
+    -> [Instr]         -- code
+    -> Maybe [Instr]
 
 simpleRegAlloc _ _ _ [] = Just []
 
 simpleRegAlloc _ _ _ [] = Just []
-simpleRegAlloc free live env (instr:instrs) =
-    if null deadSrcs && maybeToBool newAlloc && maybeToBool instrs2 then
+
+simpleRegAlloc free live env (instr:instrs)
+  = if null deadSrcs && maybeToBool newAlloc && maybeToBool instrs2 then
        Just (instr3 : instrs3)
     else
        Nothing
   where
     instr3 = patchRegs instr (lookup env2)
 
        Just (instr3 : instrs3)
     else
        Nothing
   where
     instr3 = patchRegs instr (lookup env2)
 
-    (srcs, dsts) = case regUsage instr of { RU s d -> (uniqSetToList s, uniqSetToList d) }
+    (srcs, dsts) = case regUsage instr of { RU s d -> (regSetToList s, regSetToList d) }
 
     lookup env x = case lookupFM env x of {Just y -> y; Nothing -> x}
 
 
     lookup env x = case lookupFM env x of {Just y -> y; Nothing -> x}
 
@@ -284,10 +102,9 @@ simpleRegAlloc free live env (instr:instrs) =
     instrs3 = case instrs2 of Just x -> x
 
     allocateNewReg
     instrs3 = case instrs2 of Just x -> x
 
     allocateNewReg
-       :: MachineRegisters a
-       => Reg
-       -> Maybe (a, [(Reg, Reg)])
-       -> Maybe (a, [(Reg, Reg)])
+       :: Reg
+       -> Maybe (MRegsState, [(Reg, Reg)])
+       -> Maybe (MRegsState, [(Reg, Reg)])
 
     allocateNewReg _ Nothing = Nothing
 
 
     allocateNewReg _ Nothing = Nothing
 
@@ -299,7 +116,6 @@ simpleRegAlloc free live env (instr:instrs) =
        reg = head choices
        free2 = free `useMReg` (case reg of {IBOX(reg2) -> reg2} )
        prs2 = ((d,  MappedReg (case reg of {IBOX(reg2) -> reg2})) : prs)
        reg = head choices
        free2 = free `useMReg` (case reg of {IBOX(reg2) -> reg2} )
        prs2 = ((d,  MappedReg (case reg of {IBOX(reg2) -> reg2})) : prs)
-
 \end{code}
 
 Here is the ``clever'' bit. First go backward (i.e. left), looking for
 \end{code}
 
 Here is the ``clever'' bit. First go backward (i.e. left), looking for
@@ -307,16 +123,14 @@ the last use of dynamic registers. Then go forward (i.e. right), filling
 registers with static placements.
 
 \begin{code}
 registers with static placements.
 
 \begin{code}
-
 hairyRegAlloc
 hairyRegAlloc
-    :: (MachineRegisters a, MachineCode b)
-    => a
-    -> [Int]
-    -> [b]
-    -> [b]
-
-hairyRegAlloc regs reserve_regs instrs =
-    case mapAccumB (doRegAlloc reserve_regs)
+    :: MRegsState
+    -> [RegNo]
+    -> [Instr]
+    -> [Instr]
+
+hairyRegAlloc regs reserve_regs instrs
+  = case mapAccumB (doRegAlloc reserve_regs)
            (RH regs' 1 emptyFM) noFuture instrs
     of (RH _ loc' _, _, instrs') ->
        if loc' == 1 then instrs' else
            (RH regs' 1 emptyFM) noFuture instrs
     of (RH _ loc' _, _, instrs') ->
        if loc' == 1 then instrs' else
@@ -325,19 +139,18 @@ hairyRegAlloc regs reserve_regs instrs =
        of ((RH _ loc'' _),_,instrs'') ->
            if loc'' == loc' then instrs'' else panic "runRegAllocate"
   where
        of ((RH _ loc'' _),_,instrs'') ->
            if loc'' == loc' then instrs'' else panic "runRegAllocate"
   where
-    regs' = regs `useMRegs` reserve_regs
-    regs'' = mkMRegs reserve_regs `asTypeOf` regs
+    regs'  = regs `useMRegs` reserve_regs
+    regs'' = mkMRegsState reserve_regs
 
 do_RegAlloc_Nil = doRegAlloc [] -- out here to avoid CAF (sigh)
 do_RegAlloc_Nil
 
 do_RegAlloc_Nil = doRegAlloc [] -- out here to avoid CAF (sigh)
 do_RegAlloc_Nil
-    :: (MachineRegisters a, MachineCode b)
-    => RegHistory a
+    :: RegHistory MRegsState
     -> RegFuture
     -> RegFuture
-    -> b
-    -> (RegHistory a, RegFuture, b)
+    -> Instr
+    -> (RegHistory MRegsState, RegFuture, Instr)
 
 noFuture :: RegFuture
 
 noFuture :: RegFuture
-noFuture = RF emptyUniqSet (FL emptyUniqSet emptyFM) emptyFM
+noFuture = RF emptyRegSet (FL emptyRegSet emptyFM) emptyFM
 \end{code}
 
 Here we patch instructions that reference ``registers'' which are really in
 \end{code}
 
 Here we patch instructions that reference ``registers'' which are really in
@@ -349,21 +162,14 @@ instructions are rewritten with new dynamic registers, so we have to run registe
 allocation again after all of this is said and done.
 
 \begin{code}
 allocation again after all of this is said and done.
 
 \begin{code}
-
-patchMem
-    :: MachineCode a
-    => [a]
-    -> OrdList a
+patchMem :: [Instr] -> InstrList
 
 patchMem cs = foldr (mkSeqList . patchMem') mkEmptyList cs
 
 
 patchMem cs = foldr (mkSeqList . patchMem') mkEmptyList cs
 
-patchMem'
-    :: MachineCode a
-    => a
-    -> OrdList a
+patchMem' :: Instr -> InstrList
 
 
-patchMem' instr =
-    if null memSrcs && null memDsts then mkUnitList instr
+patchMem' instr
+  = if null memSrcs && null memDsts then mkUnitList instr
     else mkSeqList
            (foldr mkParList mkEmptyList loadSrcs)
            (mkSeqList instr'
     else mkSeqList
            (foldr mkParList mkEmptyList loadSrcs)
            (mkSeqList instr'
@@ -375,8 +181,8 @@ patchMem' instr =
        memToDyn (MemoryReg i pk) = UnmappedReg (mkBuiltinUnique i) pk
        memToDyn other            = other
 
        memToDyn (MemoryReg i pk) = UnmappedReg (mkBuiltinUnique i) pk
        memToDyn other            = other
 
-       memSrcs = [ r | r@(MemoryReg _ _) <- uniqSetToList srcs]
-       memDsts = [ r | r@(MemoryReg _ _) <- uniqSetToList dsts]
+       memSrcs = [ r | r@(MemoryReg _ _) <- regSetToList srcs]
+       memDsts = [ r | r@(MemoryReg _ _) <- regSetToList dsts]
 
        loadSrcs = map load memSrcs
        spillDsts = map spill memDsts
 
        loadSrcs = map load memSrcs
        spillDsts = map spill memDsts
@@ -385,62 +191,55 @@ patchMem' instr =
        spill mem = spillReg (memToDyn mem) mem
 
        instr' = mkUnitList (patchRegs instr memToDyn)
        spill mem = spillReg (memToDyn mem) mem
 
        instr' = mkUnitList (patchRegs instr memToDyn)
-
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-
 doRegAlloc
 doRegAlloc
-    :: (MachineRegisters a, MachineCode b)
-    => [Int]
-    -> RegHistory a
+    :: [RegNo]
+    -> RegHistory MRegsState
     -> RegFuture
     -> RegFuture
-    -> b
-    -> (RegHistory a, RegFuture, b)
+    -> Instr
+    -> (RegHistory MRegsState, RegFuture, Instr)
 
 doRegAlloc reserved_regs free_env in_use instr = (free_env', in_use', instr')
   where
       (free_env', instr') = doRegAlloc' reserved_regs free_env info instr
       (in_use', info) = getUsage in_use instr
 
 doRegAlloc reserved_regs free_env in_use instr = (free_env', in_use', instr')
   where
       (free_env', instr') = doRegAlloc' reserved_regs free_env info instr
       (in_use', info) = getUsage in_use instr
-
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-
 getUsage
 getUsage
-    :: MachineCode a
-    => RegFuture
-    -> a
-    -> (RegFuture, RegInfo a)
+    :: RegFuture
+    -> Instr
+    -> (RegFuture, RegInfo Instr)
 
 
-getUsage (RF next_in_use future reg_conflicts) instr =
-    (RF in_use' future' reg_conflicts',
+getUsage (RF next_in_use future reg_conflicts) instr
+  = (RF in_use' future' reg_conflicts',
      RI in_use' srcs dsts last_used reg_conflicts')
         where (RU srcs dsts) = regUsage instr
               (RL in_use future') = regLiveness instr (RL next_in_use future)
      RI in_use' srcs dsts last_used reg_conflicts')
         where (RU srcs dsts) = regUsage instr
               (RL in_use future') = regLiveness instr (RL next_in_use future)
-              live_through = in_use `minusUniqSet` dsts
-              last_used = [ r | r <- uniqSetToList srcs,
-                            not (r `elementOfUniqSet` (fstFL future) || r `elementOfUniqSet` in_use)]
-              in_use' = srcs `unionUniqSets` live_through
+              live_through = in_use `minusRegSet` dsts
+              last_used = [ r | r <- regSetToList srcs,
+                            not (r `elementOfRegSet` (fstFL future) || r `elementOfRegSet` in_use)]
+              in_use' = srcs `unionRegSets` live_through
               reg_conflicts' = case new_conflicts of
                    [] -> reg_conflicts
                    _ -> addListToFM reg_conflicts new_conflicts
               reg_conflicts' = case new_conflicts of
                    [] -> reg_conflicts
                    _ -> addListToFM reg_conflicts new_conflicts
-              new_conflicts = if isEmptyUniqSet live_dynamics then []
+              new_conflicts = if isEmptyRegSet live_dynamics then []
                               else [ (r, merge_conflicts r)
                               else [ (r, merge_conflicts r)
-                                       | r <- extractMappedRegNos (uniqSetToList dsts) ]
+                                       | r <- extractMappedRegNos (regSetToList dsts) ]
               merge_conflicts reg = case lookupFM reg_conflicts reg of
                            Nothing -> live_dynamics
               merge_conflicts reg = case lookupFM reg_conflicts reg of
                            Nothing -> live_dynamics
-                           Just conflicts -> conflicts `unionUniqSets` live_dynamics
-              live_dynamics = mkUniqSet
-                           [ r | r@(UnmappedReg _ _) <- uniqSetToList live_through ]
+                           Just conflicts -> conflicts `unionRegSets` live_dynamics
+              live_dynamics = mkRegSet
+                           [ r | r@(UnmappedReg _ _) <- regSetToList live_through ]
 
 doRegAlloc'
 
 doRegAlloc'
-    :: (MachineRegisters a, MachineCode b)
-    => [Int]
-    -> RegHistory a
-    -> RegInfo b
-    -> b
-    -> (RegHistory a, b)
+    :: [RegNo]
+    -> RegHistory MRegsState
+    -> RegInfo Instr
+    -> Instr
+    -> (RegHistory MRegsState, Instr)
 
 doRegAlloc' reserved (RH frs loc env) (RI in_use srcs dsts lastu conflicts) instr =
 
 
 doRegAlloc' reserved (RH frs loc env) (RI in_use srcs dsts lastu conflicts) instr =
 
@@ -449,17 +248,17 @@ doRegAlloc' reserved (RH frs loc env) (RI in_use srcs dsts lastu conflicts) inst
     where
 
       -- free up new registers
     where
 
       -- free up new registers
-      free :: [Int]
+      free :: [RegNo]
       free = extractMappedRegNos (map dynToStatic lastu)
 
       -- (1) free registers that are used last as source operands in this instruction
       free = extractMappedRegNos (map dynToStatic lastu)
 
       -- (1) free registers that are used last as source operands in this instruction
-      frs_not_in_use = frs `useMRegs` (extractMappedRegNos (uniqSetToList in_use))
+      frs_not_in_use = frs `useMRegs` (extractMappedRegNos (regSetToList in_use))
       frs' = (frs_not_in_use `freeMRegs` free) `useMRegs` reserved
 
       -- (2) allocate new registers for the destination operands
       -- allocate registers for new dynamics
 
       frs' = (frs_not_in_use `freeMRegs` free) `useMRegs` reserved
 
       -- (2) allocate new registers for the destination operands
       -- allocate registers for new dynamics
 
-      new_dynamix = [ r | r@(UnmappedReg _ _) <- uniqSetToList dsts, r `not_elem` keysFM env ]
+      new_dynamix = [ r | r@(UnmappedReg _ _) <- regSetToList dsts, r `not_elem` keysFM env ]
 
       (frs'', loc', new) = foldr allocateNewRegs (frs', loc, []) new_dynamix
 
 
       (frs'', loc', new) = foldr allocateNewRegs (frs', loc, []) new_dynamix
 
@@ -475,8 +274,7 @@ doRegAlloc' reserved (RH frs loc env) (RI in_use srcs dsts lastu conflicts) inst
       dynToStatic other = other
 
       allocateNewRegs
       dynToStatic other = other
 
       allocateNewRegs
-       :: MachineRegisters a
-       => Reg -> (a, Int, [(Reg, Reg)]) -> (a, Int, [(Reg, Reg)])
+       :: Reg -> (MRegsState, Int, [(Reg, Reg)]) -> (MRegsState, Int, [(Reg, Reg)])
 
       allocateNewRegs d@(UnmappedReg _ pk) (fs, mem, lst) = (fs', mem', (d, f) : lst)
        where (fs', f, mem') = case acceptable fs of
 
       allocateNewRegs d@(UnmappedReg _ pk) (fs, mem, lst) = (fs', mem', (d, f) : lst)
        where (fs', f, mem') = case acceptable fs of
@@ -486,17 +284,7 @@ doRegAlloc' reserved (RH frs loc env) (RI in_use srcs dsts lastu conflicts) inst
              acceptable regs = filter no_conflict (possibleMRegs pk regs)
              no_conflict reg = case lookupFM conflicts reg of
                    Nothing -> True
              acceptable regs = filter no_conflict (possibleMRegs pk regs)
              no_conflict reg = case lookupFM conflicts reg of
                    Nothing -> True
-                   Just conflicts -> not (d `elementOfUniqSet` conflicts)
-\end{code}
-
-\begin{code}
-extractMappedRegNos :: [Reg] -> [Int]
-
-extractMappedRegNos regs
-  = foldr ex [] regs
-  where
-    ex (MappedReg i) acc = IBOX(i) : acc  -- we'll take it
-    ex _            acc = acc            -- leave it out
+                   Just conflicts -> not (d `elementOfRegSet` conflicts)
 \end{code}
 
 We keep a local copy of the Prelude function \tr{notElem},
 \end{code}
 
 We keep a local copy of the Prelude function \tr{notElem},
diff --git a/ghc/compiler/nativeGen/I386Code.lhs b/ghc/compiler/nativeGen/I386Code.lhs
deleted file mode 100644 (file)
index 2205224..0000000
+++ /dev/null
@@ -1,1365 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1993-1995
-%
-
-\section[I386Code]{The Native (I386) Machine Code}
-
-\begin{code}
-#define ILIT2(x) ILIT(x)
-#include "HsVersions.h"
-
-module I386Code (
-       Addr(..),
-       Cond(..), Imm(..), Operand(..), Size(..),
-       Base(..), Index(..), Displacement(..),
-       I386Code(..),I386Instr(..),I386Regs,
-       strImmLit,
-       spRel,
-
-       printLabeledCodes,
-
-       baseRegOffset, stgRegMap, callerSaves,
-
-       is13Bits, offset,
-
-       kindToSize,
-
-       st0, st1, eax, ebx, ecx, edx, esi, edi, ebp, esp,
-
-       freeRegs, reservedRegs
-
-       -- and, for self-sufficiency ...
-    ) where
-
-import AbsCSyn         ( MagicId(..) )
-import AsmRegAlloc     ( MachineCode(..), MachineRegisters(..), FutureLive(..),
-                         Reg(..), RegUsage(..), RegLiveness(..)
-                       )
-import BitSet
-import CgCompInfo      ( mAX_Double_REG, mAX_Float_REG, mAX_Vanilla_REG )
-import CLabel          ( CLabel, pprCLabel, externallyVisibleCLabel, charToC )
-import FiniteMap
-import Maybes          ( Maybe(..), maybeToBool )
-import OrdList         ( OrdList, mkUnitList, flattenOrdList )
-import Outputable
-import UniqSet
-import Stix
-import Unpretty
-import Util
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[I386Reg]{The Native (I386) Machine Register Table}
-%*                                                                     *
-%************************************************************************
-
-- All registers except 7 (esp) are available for use.
-- Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
-- Registers 0-7 have 16-bit counterparts (ax, bx etc.)
-- Registers 0-3 have 8 bit counterparts (ah, bh etc.)
-- Registers 8-15 hold extended floating point values.
-
-ToDo: Deal with stg registers that live as offsets from BaseReg!(JSM)
-
-\begin{code}
-
-gReg,fReg :: Int -> Int
-gReg x = x
-fReg x = (8 + x)
-
-st0, st1, st2, st3, st4, st5, st6, st7, eax, ebx, ecx, edx, esp :: Reg
-eax = case (gReg 0) of { IBOX(g0) -> FixedReg g0 }
-ebx = case (gReg 1) of { IBOX(g1) -> FixedReg g1 }
-ecx = case (gReg 2) of { IBOX(g2) -> FixedReg g2 }
-edx = case (gReg 3) of { IBOX(g3) -> FixedReg g3 }
-esi = case (gReg 4) of { IBOX(g4) -> FixedReg g4 }
-edi = case (gReg 5) of { IBOX(g5) -> FixedReg g5 }
-ebp = case (gReg 6) of { IBOX(g6) -> FixedReg g6 }
-esp = case (gReg 7) of { IBOX(g7) -> FixedReg g7 }
-st0 = realReg  (fReg 0)
-st1 = realReg  (fReg 1)
-st2 = realReg  (fReg 2)
-st3 = realReg  (fReg 3)
-st4 = realReg  (fReg 4)
-st5 = realReg  (fReg 5)
-st6 = realReg  (fReg 6)
-st7 = realReg  (fReg 7)
-
-realReg n@IBOX(i) = if _IS_TRUE_(freeReg i) then MappedReg i else FixedReg i
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[TheI386Code]{The datatype for i386 assembly language}
-%*                                                                     *
-%************************************************************************
-
-Here is a definition of the I386 assembly language.
-
-\begin{code}
-
-data Imm = ImmInt Int
-        | ImmInteger Integer         -- Sigh.
-        | ImmCLbl CLabel             -- AbstractC Label (with baggage)
-        | ImmLab  Unpretty           -- Simple string label (underscored)
-        | ImmLit Unpretty            -- Simple string
-        deriving ()
-
-strImmLit s = ImmLit (uppStr s)
-
-data Cond = ALWAYS
-         | GEU
-         | LU
-         | EQ
-         | GT
-         | GE
-         | GU
-         | LT
-         | LE
-         | LEU
-         | NE
-         | NEG
-         | POS
-         deriving ()
-
-
-data Size = B
-         | HB
-         | S -- unused ?
-         | L
-         | F
-         | D
-         deriving ()
-
-data Operand = OpReg  Reg      -- register
-            | OpImm  Imm       -- immediate value
-            | OpAddr Addr      -- memory reference
-            deriving ()
-
-data Addr = Addr Base Index Displacement
-         | ImmAddr Imm Int
-         -- deriving Eq
-
-type Base         = Maybe Reg
-type Index        = Maybe (Reg, Int)   -- Int is 2, 4 or 8
-type Displacement = Imm
-
-data I386Instr =
-
--- Moves.
-
-               MOV           Size Operand Operand
-             | MOVZX         Size Operand Operand -- size is the size of operand 2
-             | MOVSX         Size Operand Operand -- size is the size of operand 2
-
--- Load effective address (also a very useful three-operand add instruction :-)
-
-             | LEA           Size Operand Operand
-
--- Int Arithmetic.
-
-             | ADD           Size Operand Operand
-             | SUB           Size Operand Operand
-
--- Multiplication (signed and unsigned), Division (signed and unsigned),
--- result in %eax, %edx.
-
-             | IMUL          Size Operand Operand
-             | IDIV          Size Operand
-
--- Simple bit-twiddling.
-
-             | AND           Size Operand Operand
-             | OR            Size Operand Operand
-             | XOR           Size Operand Operand
-             | NOT           Size Operand
-             | NEGI          Size Operand -- NEG instruction (name clash with Cond)
-             | SHL           Size Operand Operand -- 1st operand must be an Imm
-             | SAR           Size Operand Operand -- 1st operand must be an Imm
-             | SHR           Size Operand Operand -- 1st operand must be an Imm
-             | NOP
-
--- Float Arithmetic. -- ToDo for 386
-
--- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
--- right up until we spit them out.
-
-             | SAHF          -- stores ah into flags
-             | FABS
-             | FADD          Size Operand -- src
-             | FADDP
-             | FIADD         Size Addr -- src
-             | FCHS
-             | FCOM          Size Operand -- src
-             | FCOS
-             | FDIV          Size Operand -- src
-             | FDIVP
-             | FIDIV         Size Addr -- src
-             | FDIVR         Size Operand -- src
-             | FDIVRP
-             | FIDIVR        Size Addr -- src
-             | FICOM         Size Addr -- src
-             | FILD          Size Addr Reg -- src, dst
-             | FIST          Size Addr -- dst
-             | FLD           Size Operand -- src
-             | FLD1
-             | FLDZ
-             | FMUL          Size Operand -- src
-             | FMULP
-             | FIMUL         Size Addr -- src
-             | FRNDINT
-             | FSIN
-             | FSQRT
-             | FST           Size Operand -- dst
-             | FSTP          Size Operand -- dst
-             | FSUB          Size Operand -- src
-             | FSUBP
-             | FISUB         Size Addr -- src
-             | FSUBR         Size Operand -- src
-             | FSUBRP
-             | FISUBR        Size Addr -- src
-             | FTST
-             | FCOMP         Size Operand -- src
-             | FUCOMPP
-             | FXCH
-             | FNSTSW
-             | FNOP
-
--- Comparison
-
-             | TEST          Size Operand Operand
-             | CMP           Size Operand Operand
-             | SETCC         Cond Operand
-
--- Stack Operations.
-
-             | PUSH          Size Operand
-             | POP           Size Operand
-
--- Jumping around.
-
-             | JMP           Operand -- target
-             | JXX           Cond CLabel -- target
-             | CALL          Imm
-
--- Other things.
-
-             | CLTD -- sign extend %eax into %edx:%eax
-
--- Pseudo-ops.
-
-             | LABEL CLabel
-             | COMMENT FAST_STRING
-             | SEGMENT CodeSegment
-             | ASCII Bool String   -- needs backslash conversion?
-             | DATA Size [Imm]
-
-type I386Code  = OrdList I386Instr
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[TheI386Pretty]{Pretty-printing the I386 Assembly Language}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-
-printLabeledCodes :: PprStyle -> [I386Instr] -> Unpretty
-printLabeledCodes sty codes = uppAboves (map (pprI386Instr sty) codes)
-
-\end{code}
-
-Printing the pieces...
-
-\begin{code}
-
-pprReg :: Size -> Reg -> Unpretty
-
-pprReg s (FixedReg i)  = pprI386Reg s i
-pprReg s (MappedReg i) = pprI386Reg s i
-pprReg s other         = uppStr (show other) -- should only happen when debugging
-
-pprI386Reg :: Size -> FAST_INT -> Unpretty
-pprI386Reg B i = uppPStr
-    (case i of {
-       ILIT( 0) -> SLIT("%al");  ILIT( 1) -> SLIT("%bl");
-       ILIT( 2) -> SLIT("%cl");  ILIT( 3) -> SLIT("%dl");
-       _ -> SLIT("very naughty I386 byte register")
-    })
-
-pprI386Reg HB i = uppPStr
-    (case i of {
-       ILIT( 0) -> SLIT("%ah");  ILIT( 1) -> SLIT("%bh");
-       ILIT( 2) -> SLIT("%ch");  ILIT( 3) -> SLIT("%dh");
-       _ -> SLIT("very naughty I386 high byte register")
-    })
-
-pprI386Reg S i = uppPStr
-    (case i of {
-       ILIT( 0) -> SLIT("%ax");  ILIT( 1) -> SLIT("%bx");
-       ILIT( 2) -> SLIT("%cx");  ILIT( 3) -> SLIT("%dx");
-       ILIT( 4) -> SLIT("%si");  ILIT( 5) -> SLIT("%di");
-       ILIT( 6) -> SLIT("%bp");  ILIT( 7) -> SLIT("%sp");
-       _ -> SLIT("very naughty I386 word register")
-    })
-
-pprI386Reg L i = uppPStr
-    (case i of {
-       ILIT( 0) -> SLIT("%eax");  ILIT( 1) -> SLIT("%ebx");
-       ILIT( 2) -> SLIT("%ecx");  ILIT( 3) -> SLIT("%edx");
-       ILIT( 4) -> SLIT("%esi");  ILIT( 5) -> SLIT("%edi");
-       ILIT( 6) -> SLIT("%ebp");  ILIT( 7) -> SLIT("%esp");
-       _ -> SLIT("very naughty I386 double word register")
-    })
-
-pprI386Reg F i = uppPStr
-    (case i of {
---ToDo: rm these
-       ILIT( 8) -> SLIT("%st(0)");  ILIT( 9) -> SLIT("%st(1)");
-       ILIT(10) -> SLIT("%st(2)");  ILIT(11) -> SLIT("%st(3)");
-       ILIT(12) -> SLIT("%st(4)");  ILIT(13) -> SLIT("%st(5)");
-       ILIT(14) -> SLIT("%st(6)");  ILIT(15) -> SLIT("%st(7)");
-       _ -> SLIT("very naughty I386 float register")
-    })
-
-pprI386Reg D i = uppPStr
-    (case i of {
---ToDo: rm these
-       ILIT( 8) -> SLIT("%st(0)");  ILIT( 9) -> SLIT("%st(1)");
-       ILIT(10) -> SLIT("%st(2)");  ILIT(11) -> SLIT("%st(3)");
-       ILIT(12) -> SLIT("%st(4)");  ILIT(13) -> SLIT("%st(5)");
-       ILIT(14) -> SLIT("%st(6)");  ILIT(15) -> SLIT("%st(7)");
-       _ -> SLIT("very naughty I386 float register")
-    })
-
-pprCond :: Cond -> Unpretty -- ToDo
-pprCond x = uppPStr
-    (case x of {
-       GEU     -> SLIT("ae");  LU    -> SLIT("b");
-       EQ      -> SLIT("e");   GT    -> SLIT("g");
-       GE      -> SLIT("ge");  GU    -> SLIT("a");
-       LT      -> SLIT("l");   LE    -> SLIT("le");
-       LEU     -> SLIT("be");  NE    -> SLIT("ne");
-       NEG     -> SLIT("s");   POS   -> SLIT("ns");
-       ALWAYS  -> SLIT("mp");  -- hack
-       _       -> error "Spix: iI386Code: unknown conditional!"
-    })
-
-pprDollImm :: PprStyle -> Imm -> Unpretty
-
-pprDollImm sty i     = uppBesides [ uppPStr SLIT("$"), pprImm sty i]
-
-pprImm :: PprStyle -> Imm -> Unpretty
-
-pprImm sty (ImmInt i)     = uppInt i
-pprImm sty (ImmInteger i) = uppInteger i
-pprImm sty (ImmCLbl l)    = pprCLabel sty l
-pprImm sty (ImmLab l)     = l
-
---pprImm (PprForAsm _ False _) (ImmLab s) = s
---pprImm _                     (ImmLab s) = uppBeside (uppChar '_') s
-
-pprImm sty (ImmLit s) = s
-
-pprAddr :: PprStyle -> Addr -> Unpretty
-pprAddr sty (ImmAddr imm off)
-  =  uppBesides [pprImm sty imm,
-                if off > 0 then uppChar '+' else uppPStr SLIT(""),
-                if off == 0 then uppPStr SLIT("") else uppInt off
-               ]
-pprAddr sty (Addr Nothing Nothing displacement)
-  =  uppBesides [pprDisp sty displacement]
-pprAddr sty (Addr base index displacement)
-  =  uppBesides [pprDisp sty displacement,
-                uppChar '(',
-                pprBase base,
-                pprIndex index,
-                uppChar ')'
-               ]
-  where
-    pprBase (Just r) = uppBesides [pprReg L r,
-                                  case index of
-                                    Nothing -> uppPStr SLIT("")
-                                    _       -> uppChar ','
-                                 ]
-    pprBase _        = uppPStr SLIT("")
-    pprIndex (Just (r,i)) = uppBesides [pprReg L r, uppChar ',', uppInt i]
-    pprIndex _       = uppPStr SLIT("")
-
-pprDisp sty (ImmInt 0) = uppPStr SLIT("")
---pprDisp sty (ImmInteger 0) = uppPStr SLIT("")
-pprDisp sty d = pprImm sty d
-
-pprOperand :: PprStyle -> Size -> Operand -> Unpretty
-pprOperand sty s (OpReg r) = pprReg s r
-pprOperand sty s (OpImm i) = pprDollImm sty i
-pprOperand sty s (OpAddr ea) = pprAddr sty ea
-
-pprSize :: Size -> Unpretty
-pprSize x = uppPStr
-    (case x of
-       B  -> SLIT("b")
-       HB -> SLIT("b")
-       S  -> SLIT("w")
-       L  -> SLIT("l")
-       F  -> SLIT("s")
-       D  -> SLIT("l")
-    )
-
-pprSizeOp :: PprStyle -> FAST_STRING -> Size -> Operand -> Unpretty
-pprSizeOp sty name size op1 =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       pprSize size,
-       uppChar ' ',
-       pprOperand sty size op1
-    ]
-
-pprSizeOpOp :: PprStyle -> FAST_STRING -> Size -> Operand -> Operand -> Unpretty
-pprSizeOpOp sty name size op1 op2 =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       pprSize size,
-       uppChar ' ',
-       pprOperand sty size op1,
-       uppComma,
-       pprOperand sty size op2
-    ]
-
-pprSizeOpReg :: PprStyle -> FAST_STRING -> Size -> Operand -> Reg -> Unpretty
-pprSizeOpReg sty name size op1 reg =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       pprSize size,
-       uppChar ' ',
-       pprOperand sty size op1,
-       uppComma,
-       pprReg size reg
-    ]
-
-pprSizeAddr :: PprStyle -> FAST_STRING -> Size -> Addr -> Unpretty
-pprSizeAddr sty name size op =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       pprSize size,
-       uppChar ' ',
-       pprAddr sty op
-    ]
-
-pprSizeAddrReg :: PprStyle -> FAST_STRING -> Size -> Addr -> Reg -> Unpretty
-pprSizeAddrReg sty name size op dst =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       pprSize size,
-       uppChar ' ',
-       pprAddr sty op,
-       uppComma,
-       pprReg size dst
-    ]
-
-pprOpOp :: PprStyle -> FAST_STRING -> Size -> Operand -> Operand -> Unpretty
-pprOpOp sty name size op1 op2 =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       uppChar ' ',
-       pprOperand sty size op1,
-       uppComma,
-       pprOperand sty size op2
-    ]
-
-pprSizeOpOpCoerce :: PprStyle -> FAST_STRING -> Size -> Size -> Operand -> Operand -> Unpretty
-pprSizeOpOpCoerce sty name size1 size2 op1 op2 =
-    uppBesides [ uppChar '\t', uppPStr name, uppChar ' ',
-       pprOperand sty size1 op1,
-       uppComma,
-       pprOperand sty size2 op2
-    ]
-
-pprCondInstr :: PprStyle -> FAST_STRING -> Cond -> Unpretty -> Unpretty
-pprCondInstr sty name cond arg =
-    uppBesides [ uppChar '\t', uppPStr name, pprCond cond, uppChar ' ', arg]
-
-pprI386Instr :: PprStyle -> I386Instr -> Unpretty
-pprI386Instr sty (MOV size (OpReg src) (OpReg dst)) -- hack
-  | src == dst
-  = uppPStr SLIT("")
-pprI386Instr sty (MOV size src dst)
-  = pprSizeOpOp sty SLIT("mov") size src dst
-pprI386Instr sty (MOVZX size src dst) = pprSizeOpOpCoerce sty SLIT("movzx") L size src dst
-pprI386Instr sty (MOVSX size src dst) = pprSizeOpOpCoerce sty SLIT("movxs") L size src dst
-
--- here we do some patching, since the physical registers are only set late
--- in the code generation.
-pprI386Instr sty (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
-  | reg1 == reg3
-  = pprSizeOpOp sty SLIT("add") size (OpReg reg2) dst
-pprI386Instr sty (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
-  | reg2 == reg3
-  = pprSizeOpOp sty SLIT("add") size (OpReg reg1) dst
-pprI386Instr sty (LEA size (OpAddr (Addr src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
-  | reg1 == reg3
-  = pprI386Instr sty (ADD size (OpImm displ) dst)
-pprI386Instr sty (LEA size src dst) = pprSizeOpOp sty SLIT("lea") size src dst
-
-pprI386Instr sty (ADD size (OpImm (ImmInt (-1))) dst)
-  = pprSizeOp sty SLIT("dec") size dst
-pprI386Instr sty (ADD size (OpImm (ImmInt 1)) dst)
-  = pprSizeOp sty SLIT("inc") size dst
-pprI386Instr sty (ADD size src dst)
-  = pprSizeOpOp sty SLIT("add") size src dst
-pprI386Instr sty (SUB size src dst) = pprSizeOpOp sty SLIT("sub") size src dst
-pprI386Instr sty (IMUL size op1 op2) = pprSizeOpOp sty SLIT("imul") size op1 op2
-pprI386Instr sty (IDIV size op) = pprSizeOp sty SLIT("idiv") size op
-
-pprI386Instr sty (AND size src dst) = pprSizeOpOp sty SLIT("and") size src dst
-pprI386Instr sty (OR  size src dst) = pprSizeOpOp sty SLIT("or")  size src dst
-pprI386Instr sty (XOR size src dst) = pprSizeOpOp sty SLIT("xor")  size src dst
-pprI386Instr sty (NOT size op) = pprSizeOp sty SLIT("not") size op
-pprI386Instr sty (NEGI size op) = pprSizeOp sty SLIT("neg") size op
-pprI386Instr sty (SHL size imm dst) = pprSizeOpOp sty SLIT("shl")  size imm dst
-pprI386Instr sty (SAR size imm dst) = pprSizeOpOp sty SLIT("sar")  size imm dst
-pprI386Instr sty (SHR size imm dst) = pprSizeOpOp sty SLIT("shr")  size imm dst
-
-pprI386Instr sty (CMP size src dst) = pprSizeOpOp sty SLIT("cmp")  size src dst
-pprI386Instr sty (TEST size src dst) = pprSizeOpOp sty SLIT("test")  size src dst
-pprI386Instr sty (PUSH size op) = pprSizeOp sty SLIT("push") size op
-pprI386Instr sty (POP size op) = pprSizeOp sty SLIT("pop") size op
-
-pprI386Instr sty (NOP) = uppPStr SLIT("\tnop")
-pprI386Instr sty (CLTD) = uppPStr SLIT("\tcltd")
-
-pprI386Instr sty (SETCC cond op) = pprCondInstr sty SLIT("set") cond (pprOperand sty B op)
-
-pprI386Instr sty (JXX cond lab) = pprCondInstr sty SLIT("j") cond (pprCLabel sty lab)
-
-pprI386Instr sty (JMP (OpImm imm)) = uppBeside (uppPStr SLIT("\tjmp ")) (pprImm sty imm)
-pprI386Instr sty (JMP op) = uppBeside (uppPStr SLIT("\tjmp *")) (pprOperand sty L op)
-
-pprI386Instr sty (CALL imm) =
-    uppBesides [ uppPStr SLIT("\tcall "), pprImm sty imm ]
-
-pprI386Instr sty SAHF = uppPStr SLIT("\tsahf")
-pprI386Instr sty FABS = uppPStr SLIT("\tfabs")
-
-pprI386Instr sty (FADD sz src@(OpAddr _))
-  = uppBesides [uppPStr SLIT("\tfadd"), pprSize sz, uppChar ' ', pprOperand sty sz src]
-pprI386Instr sty (FADD sz src)
-  = uppPStr SLIT("\tfadd")
-pprI386Instr sty FADDP
-  = uppPStr SLIT("\tfaddp")
-pprI386Instr sty (FMUL sz src)
-  = uppBesides [uppPStr SLIT("\tfmul"), pprSize sz, uppChar ' ', pprOperand sty sz src]
-pprI386Instr sty FMULP
-  = uppPStr SLIT("\tfmulp")
-pprI386Instr sty (FIADD size op) = pprSizeAddr sty SLIT("fiadd") size op
-pprI386Instr sty FCHS = uppPStr SLIT("\tfchs")
-pprI386Instr sty (FCOM size op) = pprSizeOp sty SLIT("fcom") size op
-pprI386Instr sty FCOS = uppPStr SLIT("\tfcos")
-pprI386Instr sty (FIDIV size op) = pprSizeAddr sty SLIT("fidiv") size op
-pprI386Instr sty (FDIV sz src)
-  = uppBesides [uppPStr SLIT("\tfdiv"), pprSize sz, uppChar ' ', pprOperand sty sz src]
-pprI386Instr sty FDIVP
-  = uppPStr SLIT("\tfdivp")
-pprI386Instr sty (FDIVR sz src)
-  = uppBesides [uppPStr SLIT("\tfdivr"), pprSize sz, uppChar ' ', pprOperand sty sz src]
-pprI386Instr sty FDIVRP
-  = uppPStr SLIT("\tfdivpr")
-pprI386Instr sty (FIDIVR size op) = pprSizeAddr sty SLIT("fidivr") size op
-pprI386Instr sty (FICOM size op) = pprSizeAddr sty SLIT("ficom") size op
-pprI386Instr sty (FILD sz op reg) = pprSizeAddrReg sty SLIT("fild") sz op reg
-pprI386Instr sty (FIST size op) = pprSizeAddr sty SLIT("fist") size op
-pprI386Instr sty (FLD sz (OpImm (ImmCLbl src)))
-  = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppChar ' ',pprCLabel sty src]
-pprI386Instr sty (FLD sz src)
-  = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppChar ' ',pprOperand sty sz src]
-pprI386Instr sty FLD1 = uppPStr SLIT("\tfld1")
-pprI386Instr sty FLDZ = uppPStr SLIT("\tfldz")
-pprI386Instr sty (FIMUL size op) = pprSizeAddr sty SLIT("fimul") size op
-pprI386Instr sty FRNDINT = uppPStr SLIT("\tfrndint")
-pprI386Instr sty FSIN = uppPStr SLIT("\tfsin")
-pprI386Instr sty FSQRT = uppPStr SLIT("\tfsqrt")
-pprI386Instr sty (FST sz dst)
-  = uppBesides [uppPStr SLIT("\tfst"), pprSize sz, uppChar ' ', pprOperand sty sz dst]
-pprI386Instr sty (FSTP sz dst)
-  = uppBesides [uppPStr SLIT("\tfstp"), pprSize sz, uppChar ' ', pprOperand sty sz dst]
-pprI386Instr sty (FISUB size op) = pprSizeAddr sty SLIT("fisub") size op
-pprI386Instr sty (FSUB sz src)
-  = uppBesides [uppPStr SLIT("\tfsub"), pprSize sz, uppChar ' ', pprOperand sty sz src]
-pprI386Instr sty FSUBP
-  = uppPStr SLIT("\tfsubp")
-pprI386Instr sty (FSUBR size src)
-  = pprSizeOp sty SLIT("fsubr") size src
-pprI386Instr sty FSUBRP
-  = uppPStr SLIT("\tfsubpr")
-pprI386Instr sty (FISUBR size op)
-  = pprSizeAddr sty SLIT("fisubr") size op
-pprI386Instr sty FTST = uppPStr SLIT("\tftst")
-pprI386Instr sty (FCOMP sz op)
-  = uppBesides [uppPStr SLIT("\tfcomp"), pprSize sz, uppChar ' ', pprOperand sty sz op]
-pprI386Instr sty FUCOMPP = uppPStr SLIT("\tfucompp")
-pprI386Instr sty FXCH = uppPStr SLIT("\tfxch")
-pprI386Instr sty FNSTSW = uppPStr SLIT("\tfnstsw %ax")
-pprI386Instr sty FNOP = uppPStr SLIT("")
-
-pprI386Instr sty (LABEL clab) =
-    uppBesides [
-       if (externallyVisibleCLabel clab) then
-           uppBesides [uppPStr SLIT(".globl "), pprLab, uppChar '\n']
-       else
-           uppNil,
-       pprLab,
-       uppChar ':'
-    ]
-    where pprLab = pprCLabel sty clab
-
-pprI386Instr sty (COMMENT s) = uppBeside (uppPStr SLIT("# ")) (uppPStr s)
-
-pprI386Instr sty (SEGMENT TextSegment)
-    = uppPStr SLIT(".text\n\t.align 4")
-
-pprI386Instr sty (SEGMENT DataSegment)
-    = uppPStr SLIT(".data\n\t.align 2")
-
-pprI386Instr sty (ASCII False str) =
-    uppBesides [
-       uppStr "\t.asciz \"",
-       uppStr str,
-       uppChar '"'
-    ]
-
-pprI386Instr sty (ASCII True str) = uppBeside (uppStr "\t.ascii \"") (asciify str 60)
-    where
-       asciify :: String -> Int -> Unpretty
-       asciify [] _ = uppStr ("\\0\"")
-       asciify s n | n <= 0 = uppBeside (uppStr "\"\n\t.ascii \"") (asciify s 60)
-       asciify ('\\':cs) n = uppBeside (uppStr "\\\\") (asciify cs (n-1))
-       asciify ('\"':cs) n = uppBeside (uppStr "\\\"") (asciify cs (n-1))
-       asciify (c:cs) n | isPrint c = uppBeside (uppChar c) (asciify cs (n-1))
-       asciify [c] _ = uppBeside (uppStr (charToC c)) (uppStr ("\\0\""))
-       asciify (c:(cs@(d:_))) n | isDigit d =
-                                       uppBeside (uppStr (charToC c)) (asciify cs 0)
-                                | otherwise =
-                                       uppBeside (uppStr (charToC c)) (asciify cs (n-1))
-
-pprI386Instr sty (DATA s xs) = uppInterleave (uppChar '\n') (map pp_item xs)
-    where pp_item x = case s of
-           B -> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
-           HB-> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
-           S -> uppBeside (uppPStr SLIT("\t.word\t")) (pprImm sty x)
-           L -> uppBeside (uppPStr SLIT("\t.long\t")) (pprImm sty x)
-           F -> uppBeside (uppPStr SLIT("\t.long\t")) (pprImm sty x)
-           D -> uppBeside (uppPStr SLIT("\t.double\t")) (pprImm sty x)
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Schedule]{Register allocation information}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-
-data I386Regs = SRegs BitSet BitSet
-
-instance MachineRegisters I386Regs where
-    mkMRegs xs = SRegs (mkBS ints) (mkBS floats')
-      where
-       (ints, floats) = partition (< 8) xs
-       floats' = map (subtract 8) floats
-
-    possibleMRegs FloatRep (SRegs _ floats) = [ x + 8 | x <- listBS floats]
-    possibleMRegs DoubleRep (SRegs _ floats) = [ x + 8 | x <- listBS floats]
-    possibleMRegs _ (SRegs ints _) = listBS ints
-
-    useMReg (SRegs ints floats) n =
-       if n _LT_ ILIT(8) then SRegs (ints `minusBS` singletonBS IBOX(n)) floats
-       else SRegs ints (floats `minusBS` singletonBS (IBOX(n _SUB_ ILIT(8))))
-
-    useMRegs (SRegs ints floats) xs =
-       SRegs (ints `minusBS` ints')
-             (floats `minusBS` floats')
-      where
-       SRegs ints' floats' = mkMRegs xs
-
-    freeMReg (SRegs ints floats) n =
-       if n _LT_ ILIT(8) then SRegs (ints `unionBS` singletonBS IBOX(n)) floats
-       else SRegs ints (floats `unionBS` singletonBS (IBOX(n _SUB_ ILIT(8))))
-
-    freeMRegs (SRegs ints floats) xs =
-       SRegs (ints `unionBS` ints')
-             (floats `unionBS` floats')
-      where
-       SRegs ints' floats' = mkMRegs xs
-
-instance MachineCode I386Instr where
-    regUsage = i386RegUsage
-    regLiveness = i386RegLiveness
-    patchRegs = i386PatchRegs
-
-    -- We spill just below the stack pointer, leaving two words per spill location.
-    spillReg dyn (MemoryReg i pk)
-      = trace "spillsave"
-       (mkUnitList (MOV (kindToSize pk) (OpReg dyn) (OpAddr (spRel (-2 * i)))))
-    loadReg (MemoryReg i pk) dyn
-      = trace "spillload"
-       (mkUnitList (MOV (kindToSize pk) (OpAddr (spRel (-2 * i))) (OpReg dyn)))
-
---spRel gives us a stack relative addressing mode for volatile temporaries
---and for excess call arguments.
-
-spRel
-    :: Int      -- desired stack offset in words, positive or negative
-    -> Addr
-spRel n = Addr (Just esp) Nothing (ImmInt (n * 4))
-
-kindToSize :: PrimRep -> Size
-kindToSize PtrRep          = L
-kindToSize CodePtrRep      = L
-kindToSize DataPtrRep      = L
-kindToSize RetRep          = L
-kindToSize CostCentreRep   = L
-kindToSize CharRep         = L
-kindToSize IntRep          = L
-kindToSize WordRep         = L
-kindToSize AddrRep         = L
-kindToSize FloatRep        = F
-kindToSize DoubleRep       = D
-kindToSize ArrayRep        = L
-kindToSize ByteArrayRep    = L
-kindToSize StablePtrRep    = L
-kindToSize MallocPtrRep    = L
-
-\end{code}
-
-@i386RegUsage@ returns the sets of src and destination registers used by
-a particular instruction.  Machine registers that are pre-allocated
-to stgRegs are filtered out, because they are uninteresting from a
-register allocation standpoint.  (We wouldn't want them to end up on
-the free list!)
-
-\begin{code}
-
-i386RegUsage :: I386Instr -> RegUsage
-i386RegUsage instr = case instr of
-    MOV  sz src dst    -> usage2 src dst
-    MOVZX sz src dst   -> usage2 src dst
-    MOVSX sz src dst   -> usage2 src dst
-    LEA  sz src dst    -> usage2 src dst
-    ADD  sz src dst    -> usage2 src dst
-    SUB  sz src dst    -> usage2 src dst
-    IMUL sz src dst    -> usage2 src dst
-    IDIV sz src                -> usage (eax:edx:opToReg src) [eax,edx]
-    AND  sz src dst    -> usage2 src dst
-    OR   sz src dst    -> usage2 src dst
-    XOR  sz src dst    -> usage2 src dst
-    NOT  sz op         -> usage1 op
-    NEGI sz op         -> usage1 op
-    SHL  sz imm dst    -> usage1 dst -- imm has to be an Imm
-    SAR  sz imm dst    -> usage1 dst -- imm has to be an Imm
-    SHR  sz imm dst    -> usage1 dst -- imm has to be an Imm
-    PUSH sz op         -> usage (opToReg op) []
-    POP  sz op         -> usage [] (opToReg op)
-    TEST sz src dst    -> usage (opToReg src ++ opToReg dst) []
-    CMP  sz src dst    -> usage (opToReg src ++ opToReg dst) []
-    SETCC cond op      -> usage [] (opToReg op)
-    JXX cond label     -> usage [] []
-    JMP op             -> usage (opToReg op) freeRegs
-    CALL imm           -> usage [] callClobberedRegs
-    CLTD               -> usage [eax] [edx]
-    NOP                        -> usage [] []
-    SAHF               -> usage [eax] []
-    FABS               -> usage [st0] [st0]
-    FADD sz src                -> usage (st0:opToReg src) [st0] -- allFPRegs
-    FADDP              -> usage [st0,st1] [st0] -- allFPRegs
-    FIADD sz asrc      -> usage (addrToRegs asrc) [st0]
-    FCHS               -> usage [st0] [st0]
-    FCOM sz src                -> usage (st0:opToReg src) []
-    FCOS               -> usage [st0] [st0]
-    FDIV sz src        -> usage (st0:opToReg src) [st0]
-    FDIVP              -> usage [st0,st1] [st0]
-    FDIVRP             -> usage [st0,st1] [st0]
-    FIDIV sz asrc      -> usage (addrToRegs asrc) [st0]
-    FDIVR sz src       -> usage (st0:opToReg src) [st0]
-    FIDIVR sz asrc     -> usage (addrToRegs asrc) [st0]
-    FICOM sz asrc      -> usage (addrToRegs asrc) []
-    FILD sz asrc dst   -> usage (addrToRegs asrc) [dst] -- allFPRegs
-    FIST sz adst       -> usage (st0:addrToRegs adst) []
-    FLD         sz src         -> usage (opToReg src) [st0] -- allFPRegs
-    FLD1               -> usage [] [st0] -- allFPRegs
-    FLDZ               -> usage [] [st0] -- allFPRegs
-    FMUL sz src        -> usage (st0:opToReg src) [st0]
-    FMULP              -> usage [st0,st1] [st0]
-    FIMUL sz asrc      -> usage (addrToRegs asrc) [st0]
-    FRNDINT            -> usage [st0] [st0]
-    FSIN               -> usage [st0] [st0]
-    FSQRT              -> usage [st0] [st0]
-    FST sz (OpReg r)   -> usage [st0] [r]
-    FST sz dst         -> usage (st0:opToReg dst) []
-    FSTP sz (OpReg r)  -> usage [st0] [r] -- allFPRegs
-    FSTP sz dst                -> usage (st0:opToReg dst) [] -- allFPRegs
-    FSUB sz src                -> usage (st0:opToReg src) [st0] -- allFPRegs
-    FSUBR sz src       -> usage (st0:opToReg src) [st0] -- allFPRegs
-    FISUB sz asrc      -> usage (addrToRegs asrc) [st0]
-    FSUBP              -> usage [st0,st1] [st0] -- allFPRegs
-    FSUBRP             -> usage [st0,st1] [st0] -- allFPRegs
-    FISUBR sz asrc     -> usage (addrToRegs asrc) [st0]
-    FTST               -> usage [st0] []
-    FCOMP sz op                -> usage (st0:opToReg op) [st0] -- allFPRegs
-    FUCOMPP            -> usage [st0, st1] [] --  allFPRegs
-    FXCH               -> usage [st0, st1] [st0, st1]
-    FNSTSW             -> usage [] [eax]
-    _                  -> noUsage
-
- where
-
-    usage2 :: Operand -> Operand -> RegUsage
-    usage2 op (OpReg reg) = usage (opToReg op) [reg]
-    usage2 op (OpAddr ea) = usage (opToReg op ++ addrToRegs ea) []
-    usage2 op (OpImm imm) = usage (opToReg op) []
-    usage1 :: Operand -> RegUsage
-    usage1 (OpReg reg)    = usage [reg] [reg]
-    usage1 (OpAddr ea)    = usage (addrToRegs ea) []
-    allFPRegs = [st0,st1,st2,st3,st4,st5,st6,st7]
-    --callClobberedRegs = [ eax, ecx, edx ] -- according to gcc, anyway.
-    callClobberedRegs = [eax]
-
--- General purpose register collecting functions.
-
-    opToReg (OpReg reg)   = [reg]
-    opToReg (OpImm imm)   = []
-    opToReg (OpAddr  ea)  = addrToRegs ea
-
-    addrToRegs (Addr base index _) = baseToReg base ++ indexToReg index
-      where  baseToReg Nothing       = []
-            baseToReg (Just r)      = [r]
-            indexToReg Nothing      = []
-            indexToReg (Just (r,_)) = [r]
-    addrToRegs (ImmAddr _ _) = []
-
-    usage src dst = RU (mkUniqSet (filter interesting src))
-                      (mkUniqSet (filter interesting dst))
-
-    interesting (FixedReg _) = False
-    interesting _ = True
-
-freeRegs :: [Reg]
-freeRegs = freeMappedRegs (\ x -> x) [0..15]
-
-freeMappedRegs :: (Int -> Int) -> [Int] -> [Reg]
-
-freeMappedRegs modify nums
-  = foldr free [] nums
-  where
-    free n acc
-      = let
-           modified_i = case (modify n) of { IBOX(x) -> x }
-       in
-       if _IS_TRUE_(freeReg modified_i) then (MappedReg modified_i) : acc else acc
-
-freeSet :: UniqSet Reg
-freeSet = mkUniqSet freeRegs
-
-noUsage :: RegUsage
-noUsage = RU emptyUniqSet emptyUniqSet
-
-endUsage :: RegUsage
-endUsage = RU emptyUniqSet freeSet
-
-\end{code}
-
-@i386RegLiveness@ takes future liveness information and modifies it according to
-the semantics of branches and labels.  (An out-of-line branch clobbers the liveness
-passed back by the following instruction; a forward local branch passes back the
-liveness from the target label; a conditional branch merges the liveness from the
-target and the liveness from its successor; a label stashes away the current liveness
-in the future liveness environment).
-
-\begin{code}
-i386RegLiveness :: I386Instr -> RegLiveness -> RegLiveness
-i386RegLiveness instr info@(RL live future@(FL all env)) = case instr of
-
-    JXX _ lbl  -> RL (lookup lbl `unionUniqSets` live) future
-    JMP _      -> RL emptyUniqSet future
-    CALL _      -> RL live future
-    LABEL lbl   -> RL live (FL (all `unionUniqSets` live) (addToFM env lbl live))
-    _              -> info
-
-  where
-    lookup lbl = case lookupFM env lbl of
-       Just regs -> regs
-       Nothing -> trace ("Missing " ++ (uppShow 80 (pprCLabel (PprForAsm (\_->False) False id) lbl)) ++
-                         " in future?") emptyUniqSet
-
-\end{code}
-
-@i386PatchRegs@ takes an instruction (possibly with MemoryReg/UnmappedReg registers) and
-changes all register references according to the supplied environment.
-
-\begin{code}
-
-i386PatchRegs :: I386Instr -> (Reg -> Reg) -> I386Instr
-i386PatchRegs instr env = case instr of
-    MOV  sz src dst    -> patch2 (MOV  sz) src dst
-    MOVZX sz src dst   -> patch2 (MOVZX sz) src dst
-    MOVSX sz src dst   -> patch2 (MOVSX sz) src dst
-    LEA  sz src dst    -> patch2 (LEA  sz) src dst
-    ADD  sz src dst    -> patch2 (ADD  sz) src dst
-    SUB  sz src dst    -> patch2 (SUB  sz) src dst
-    IMUL sz src dst    -> patch2 (IMUL sz) src dst
-    IDIV sz src        -> patch1 (IDIV sz) src
-    AND  sz src dst    -> patch2 (AND  sz) src dst
-    OR   sz src dst    -> patch2 (OR   sz) src dst
-    XOR  sz src dst    -> patch2 (XOR  sz) src dst
-    NOT  sz op                 -> patch1 (NOT  sz) op
-    NEGI sz op         -> patch1 (NEGI sz) op
-    SHL  sz imm dst    -> patch1 (SHL  sz imm) dst
-    SAR  sz imm dst    -> patch1 (SAR  sz imm) dst
-    SHR  sz imm dst    -> patch1 (SHR  sz imm) dst
-    TEST sz src dst    -> patch2 (TEST sz) src dst
-    CMP  sz src dst    -> patch2 (CMP  sz) src dst
-    PUSH sz op         -> patch1 (PUSH sz) op
-    POP  sz op         -> patch1 (POP  sz) op
-    SETCC cond op      -> patch1 (SETCC cond) op
-    JMP op             -> patch1 JMP op
-    FADD sz src                -> FADD sz (patchOp src)
-    FIADD sz asrc      -> FIADD sz (lookupAddr asrc)
-    FCOM sz src                -> patch1 (FCOM sz) src
-    FDIV sz src        -> FDIV sz (patchOp src)
-    --FDIVP sz src     -> FDIVP sz (patchOp src)
-    FIDIV sz asrc      -> FIDIV sz (lookupAddr asrc)
-    FDIVR sz src       -> FDIVR sz (patchOp src)
-    --FDIVRP sz src    -> FDIVRP sz (patchOp src)
-    FIDIVR sz asrc     -> FIDIVR sz (lookupAddr asrc)
-    FICOM sz asrc      -> FICOM sz (lookupAddr asrc)
-    FILD sz asrc dst   -> FILD sz (lookupAddr asrc) (env dst)
-    FIST sz adst       -> FIST sz (lookupAddr adst)
-    FLD        sz src          -> patch1 (FLD sz) (patchOp src)
-    FMUL sz src        -> FMUL sz (patchOp src)
-    --FMULP sz src     -> FMULP sz (patchOp src)
-    FIMUL sz asrc      -> FIMUL sz (lookupAddr asrc)
-    FST sz dst         -> FST sz (patchOp dst)
-    FSTP sz dst                -> FSTP sz (patchOp dst)
-    FSUB sz src                -> FSUB sz (patchOp src)
-    --FSUBP sz src     -> FSUBP sz (patchOp src)
-    FISUB sz asrc      -> FISUB sz (lookupAddr asrc)
-    FSUBR sz src       -> FSUBR sz (patchOp src)
-    --FSUBRP sz src    -> FSUBRP sz (patchOp src)
-    FISUBR sz asrc     -> FISUBR sz (lookupAddr asrc)
-    FCOMP sz src       -> FCOMP sz (patchOp src)
-    _                  -> instr
-
-  where
-               patch1 insn op = insn (patchOp op)
-               patch2 insn src dst = insn (patchOp src) (patchOp dst)
-
-               patchOp (OpReg  reg) = OpReg (env reg)
-               patchOp (OpImm  imm) = OpImm imm
-               patchOp (OpAddr ea)  = OpAddr (lookupAddr ea)
-
-               lookupAddr (Addr base index disp)
-                       = Addr (lookupBase base) (lookupIndex index) disp
-                       where lookupBase Nothing        = Nothing
-                             lookupBase (Just r)       = Just (env r)
-                             lookupIndex Nothing       = Nothing
-                             lookupIndex (Just (r,i))  = Just (env r, i)
-               lookupAddr (ImmAddr imm off)
-                       = ImmAddr imm off
-
-\end{code}
-
-Sometimes, we want to be able to modify addresses at compile time.
-(Okay, just for chrCode of a fetch.)
-
-\begin{code}
-{-# SPECIALIZE
-    is13Bits :: Int -> Bool
-  #-}
-{-# SPECIALIZE
-    is13Bits :: Integer -> Bool
-  #-}
-
-is13Bits :: Integral a => a -> Bool
-is13Bits x = x >= -4096 && x < 4096
-
-offset :: Addr -> Int -> Maybe Addr
-offset (Addr reg index (ImmInt n)) off
-  = Just (Addr reg index (ImmInt n2))
-  where n2 = n + off
-
-offset (Addr reg index (ImmInteger n)) off
-  = Just (Addr reg index (ImmInt (fromInteger n2)))
-  where n2 = n + toInteger off
-
-offset (ImmAddr imm off1) off2
-  = Just (ImmAddr imm off3)
-  where off3 = off1 + off2
-
-offset _ _ = Nothing
-\end{code}
-
-If you value your sanity, do not venture below this line.
-
-\begin{code}
-
--- platform.h is generate and tells us what the target architecture is
-#include "../../includes/platform.h"
-#define STOLEN_X86_REGS 5
-#include "../../includes/MachRegs.h"
-#include "../../includes/i386-unknown-linuxaout.h"
-
--- Redefine the literals used for I386 register names in the header
--- files.  Gag me with a spoon, eh?
-
-#define eax 0
-#define ebx 1
-#define ecx 2
-#define edx 3
-#define esi 4
-#define edi 5
-#define ebp 6
-#define esp 7
-#define st0 8
-#define st1 9
-#define st2 10
-#define st3 11
-#define st4 12
-#define st5 13
-#define st6 14
-#define st7 15
-#define CALLER_SAVES_Hp
--- ToDo: rm when we give esp back
-#define REG_Hp esp
-#define REG_R2 ecx
-
-baseRegOffset :: MagicId -> Int
-baseRegOffset StkOReg                  = OFFSET_StkO
-baseRegOffset (VanillaReg _ ILIT2(1))  = OFFSET_R1
-baseRegOffset (VanillaReg _ ILIT2(2))  = OFFSET_R2
-baseRegOffset (VanillaReg _ ILIT2(3))  = OFFSET_R3
-baseRegOffset (VanillaReg _ ILIT2(4))  = OFFSET_R4
-baseRegOffset (VanillaReg _ ILIT2(5))  = OFFSET_R5
-baseRegOffset (VanillaReg _ ILIT2(6))  = OFFSET_R6
-baseRegOffset (VanillaReg _ ILIT2(7))  = OFFSET_R7
-baseRegOffset (VanillaReg _ ILIT2(8))  = OFFSET_R8
-baseRegOffset (FloatReg ILIT2(1))      = OFFSET_Flt1
-baseRegOffset (FloatReg ILIT2(2))      = OFFSET_Flt2
-baseRegOffset (FloatReg ILIT2(3))      = OFFSET_Flt3
-baseRegOffset (FloatReg ILIT2(4))      = OFFSET_Flt4
-baseRegOffset (DoubleReg ILIT2(1))     = OFFSET_Dbl1
-baseRegOffset (DoubleReg ILIT2(2))     = OFFSET_Dbl2
-baseRegOffset TagReg                   = OFFSET_Tag
-baseRegOffset RetReg                   = OFFSET_Ret
-baseRegOffset SpA                      = OFFSET_SpA
-baseRegOffset SuA                      = OFFSET_SuA
-baseRegOffset SpB                      = OFFSET_SpB
-baseRegOffset SuB                      = OFFSET_SuB
-baseRegOffset Hp                       = OFFSET_Hp
-baseRegOffset HpLim                    = OFFSET_HpLim
-baseRegOffset LivenessReg              = OFFSET_Liveness
---baseRegOffset ActivityReg            = OFFSET_Activity
-#ifdef DEBUG
-baseRegOffset BaseReg                  = panic "baseRegOffset:BaseReg"
-baseRegOffset StdUpdRetVecReg          = panic "baseRegOffset:StgUpdRetVecReg"
-baseRegOffset StkStubReg               = panic "baseRegOffset:StkStubReg"
-baseRegOffset CurCostCentre            = panic "baseRegOffset:CurCostCentre"
-baseRegOffset VoidReg                  = panic "baseRegOffset:VoidReg"
-#endif
-
-callerSaves :: MagicId -> Bool
-#ifdef CALLER_SAVES_Base
-callerSaves BaseReg                    = True
-#endif
-#ifdef CALLER_SAVES_StkO
-callerSaves StkOReg            = True
-#endif
-#ifdef CALLER_SAVES_R1
-callerSaves (VanillaReg _ ILIT2(1))    = True
-#endif
-#ifdef CALLER_SAVES_R2
-callerSaves (VanillaReg _ ILIT2(2))    = True
-#endif
-#ifdef CALLER_SAVES_R3
-callerSaves (VanillaReg _ ILIT2(3))    = True
-#endif
-#ifdef CALLER_SAVES_R4
-callerSaves (VanillaReg _ ILIT2(4))    = True
-#endif
-#ifdef CALLER_SAVES_R5
-callerSaves (VanillaReg _ ILIT2(5))    = True
-#endif
-#ifdef CALLER_SAVES_R6
-callerSaves (VanillaReg _ ILIT2(6))    = True
-#endif
-#ifdef CALLER_SAVES_R7
-callerSaves (VanillaReg _ ILIT2(7))    = True
-#endif
-#ifdef CALLER_SAVES_R8
-callerSaves (VanillaReg _ ILIT2(8))    = True
-#endif
-#ifdef CALLER_SAVES_FltReg1
-callerSaves (FloatReg ILIT2(1))        = True
-#endif
-#ifdef CALLER_SAVES_FltReg2
-callerSaves (FloatReg ILIT2(2))        = True
-#endif
-#ifdef CALLER_SAVES_FltReg3
-callerSaves (FloatReg ILIT2(3))        = True
-#endif
-#ifdef CALLER_SAVES_FltReg4
-callerSaves (FloatReg ILIT2(4))        = True
-#endif
-#ifdef CALLER_SAVES_DblReg1
-callerSaves (DoubleReg ILIT2(1))       = True
-#endif
-#ifdef CALLER_SAVES_DblReg2
-callerSaves (DoubleReg ILIT2(2))       = True
-#endif
-#ifdef CALLER_SAVES_Tag
-callerSaves TagReg             = True
-#endif
-#ifdef CALLER_SAVES_Ret
-callerSaves RetReg             = True
-#endif
-#ifdef CALLER_SAVES_SpA
-callerSaves SpA                        = True
-#endif
-#ifdef CALLER_SAVES_SuA
-callerSaves SuA                        = True
-#endif
-#ifdef CALLER_SAVES_SpB
-callerSaves SpB                        = True
-#endif
-#ifdef CALLER_SAVES_SuB
-callerSaves SuB                        = True
-#endif
-#ifdef CALLER_SAVES_Hp
-callerSaves Hp                 = True
-#endif
-#ifdef CALLER_SAVES_HpLim
-callerSaves HpLim              = True
-#endif
-#ifdef CALLER_SAVES_Liveness
-callerSaves LivenessReg                = True
-#endif
-#ifdef CALLER_SAVES_Activity
---callerSaves ActivityReg              = True
-#endif
-#ifdef CALLER_SAVES_StdUpdRetVec
-callerSaves StdUpdRetVecReg            = True
-#endif
-#ifdef CALLER_SAVES_StkStub
-callerSaves StkStubReg                 = True
-#endif
-callerSaves _                  = False
-
-stgRegMap :: MagicId -> Maybe Reg
-
-#ifdef REG_Base
-stgRegMap BaseReg         = Just (FixedReg ILIT(REG_Base))
-#endif
-#ifdef REG_StkO
-stgRegMap StkOReg         = Just (FixedReg ILIT(REG_StkOReg))
-#endif
-#ifdef REG_R1
-stgRegMap (VanillaReg _ ILIT2(1)) = Just (FixedReg ILIT(REG_R1))
-#endif
-#ifdef REG_R2
-stgRegMap (VanillaReg _ ILIT2(2)) = Just (FixedReg ILIT(REG_R2))
-#endif
-#ifdef REG_R3
-stgRegMap (VanillaReg _ ILIT2(3)) = Just (FixedReg ILIT(REG_R3))
-#endif
-#ifdef REG_R4
-stgRegMap (VanillaReg _ ILIT2(4)) = Just (FixedReg ILIT(REG_R4))
-#endif
-#ifdef REG_R5
-stgRegMap (VanillaReg _ ILIT2(5)) = Just (FixedReg ILIT(REG_R5))
-#endif
-#ifdef REG_R6
-stgRegMap (VanillaReg _ ILIT2(6)) = Just (FixedReg ILIT(REG_R6))
-#endif
-#ifdef REG_R7
-stgRegMap (VanillaReg _ ILIT2(7)) = Just (FixedReg ILIT(REG_R7))
-#endif
-#ifdef REG_R8
-stgRegMap (VanillaReg _ ILIT2(8)) = Just (FixedReg ILIT(REG_R8))
-#endif
-#ifdef REG_Flt1
-stgRegMap (FloatReg ILIT2(1))     = Just (FixedReg ILIT(REG_Flt1))
-#endif
-#ifdef REG_Flt2
-stgRegMap (FloatReg ILIT2(2))     = Just (FixedReg ILIT(REG_Flt2))
-#endif
-#ifdef REG_Flt3
-stgRegMap (FloatReg ILIT2(3))     = Just (FixedReg ILIT(REG_Flt3))
-#endif
-#ifdef REG_Flt4
-stgRegMap (FloatReg ILIT2(4))     = Just (FixedReg ILIT(REG_Flt4))
-#endif
-#ifdef REG_Dbl1
-stgRegMap (DoubleReg ILIT2(1))    = Just (FixedReg ILIT(REG_Dbl1))
-#endif
-#ifdef REG_Dbl2
-stgRegMap (DoubleReg ILIT2(2))    = Just (FixedReg ILIT(REG_Dbl2))
-#endif
-#ifdef REG_Tag
-stgRegMap TagReg          = Just (FixedReg ILIT(REG_TagReg))
-#endif
-#ifdef REG_Ret
-stgRegMap RetReg          = Just (FixedReg ILIT(REG_Ret))
-#endif
-#ifdef REG_SpA
-stgRegMap SpA             = Just (FixedReg ILIT(REG_SpA))
-#endif
-#ifdef REG_SuA
-stgRegMap SuA             = Just (FixedReg ILIT(REG_SuA))
-#endif
-#ifdef REG_SpB
-stgRegMap SpB             = Just (FixedReg ILIT(REG_SpB))
-#endif
-#ifdef REG_SuB
-stgRegMap SuB             = Just (FixedReg ILIT(REG_SuB))
-#endif
-#ifdef REG_Hp
-stgRegMap Hp              = Just (FixedReg ILIT(REG_Hp))
-#endif
-#ifdef REG_HpLim
-stgRegMap HpLim                   = Just (FixedReg ILIT(REG_HpLim))
-#endif
-#ifdef REG_Liveness
-stgRegMap LivenessReg     = Just (FixedReg ILIT(REG_Liveness))
-#endif
-#ifdef REG_Activity
---stgRegMap ActivityReg           = Just (FixedReg ILIT(REG_Activity))
-#endif
-#ifdef REG_StdUpdRetVec
-stgRegMap StdUpdRetVecReg  = Just (FixedReg ILIT(REG_StdUpdRetVec))
-#endif
-#ifdef REG_StkStub
-stgRegMap StkStubReg      = Just (FixedReg ILIT(REG_StkStub))
-#endif
-
-stgRegMap _               = Nothing
-
-\end{code}
-
-Here is the list of registers we can use in register allocation.
-
-\begin{code}
-freeReg :: FAST_INT -> FAST_BOOL
-
---freeReg ILIT(esp) = _FALSE_  --      %esp is our stack pointer.
-
-#ifdef REG_Base
-freeReg ILIT(REG_Base) = _FALSE_
-#endif
-#ifdef REG_StkO
-freeReg ILIT(REG_StkO) = _FALSE_
-#endif
-#ifdef REG_R1
-freeReg ILIT(REG_R1) = _FALSE_
-#endif
-#ifdef REG_R2
-freeReg ILIT(REG_R2) = _FALSE_
-#endif
-#ifdef REG_R3
-freeReg ILIT(REG_R3) = _FALSE_
-#endif
-#ifdef REG_R4
-freeReg ILIT(REG_R4) = _FALSE_
-#endif
-#ifdef REG_R5
-freeReg ILIT(REG_R5) = _FALSE_
-#endif
-#ifdef REG_R6
-freeReg ILIT(REG_R6) = _FALSE_
-#endif
-#ifdef REG_R7
-freeReg ILIT(REG_R7) = _FALSE_
-#endif
-#ifdef REG_R8
-freeReg ILIT(REG_R8) = _FALSE_
-#endif
-#ifdef REG_Flt1
-freeReg ILIT(REG_Flt1) = _FALSE_
-#endif
-#ifdef REG_Flt2
-freeReg ILIT(REG_Flt2) = _FALSE_
-#endif
-#ifdef REG_Flt3
-freeReg ILIT(REG_Flt3) = _FALSE_
-#endif
-#ifdef REG_Flt4
-freeReg ILIT(REG_Flt4) = _FALSE_
-#endif
-#ifdef REG_Dbl1
-freeReg ILIT(REG_Dbl1) = _FALSE_
-#endif
-#ifdef REG_Dbl2
-freeReg ILIT(REG_Dbl2) = _FALSE_
-#endif
-#ifdef REG_Tag
-freeReg ILIT(REG_Tag) = _FALSE_
-#endif
-#ifdef REG_Ret
-freeReg ILIT(REG_Ret) = _FALSE_
-#endif
-#ifdef REG_SpA
-freeReg ILIT(REG_SpA) = _FALSE_
-#endif
-#ifdef REG_SuA
-freeReg ILIT(REG_SuA) = _FALSE_
-#endif
-#ifdef REG_SpB
-freeReg ILIT(REG_SpB) = _FALSE_
-#endif
-#ifdef REG_SuB
-freeReg ILIT(REG_SuB) = _FALSE_
-#endif
-#ifdef REG_Hp
-freeReg ILIT(REG_Hp) = _FALSE_
-#endif
-#ifdef REG_HpLim
-freeReg ILIT(REG_HpLim) = _FALSE_
-#endif
-#ifdef REG_Liveness
-freeReg ILIT(REG_Liveness) = _FALSE_
-#endif
-#ifdef REG_Activity
---freeReg ILIT(REG_Activity) = _FALSE_
-#endif
-#ifdef REG_StdUpdRetVec
-freeReg ILIT(REG_StdUpdRetVec) = _FALSE_
-#endif
-#ifdef REG_StkStub
-freeReg ILIT(REG_StkStub) = _FALSE_
-#endif
-freeReg n
-#ifdef REG_Dbl1
-  | n _EQ_ (ILIT(REG_Dbl1) _ADD_ ILIT(1)) = _FALSE_
-#endif
-#ifdef REG_Dbl2
-  | n _EQ_ (ILIT(REG_Dbl2) _ADD_ ILIT(1)) = _FALSE_
-#endif
-
-  | otherwise = _TRUE_
-
-reservedRegs :: [Int]
-reservedRegs = []
---reservedRegs = [NCG_Reserved_I1, NCG_Reserved_I2,
---             NCG_Reserved_F1, NCG_Reserved_F2,
---             NCG_Reserved_D1, NCG_Reserved_D2]
-
-\end{code}
-
diff --git a/ghc/compiler/nativeGen/I386Desc.lhs b/ghc/compiler/nativeGen/I386Desc.lhs
deleted file mode 100644 (file)
index b7b3233..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1994-1995
-%
-\section[I386Desc]{The I386 Machine Description}
-
-\begin{code}
-#include "HsVersions.h"
-
-module I386Desc (
-       mkI386
-
-       -- and assorted nonsense referenced by the class methods
-    ) where
-
-import AbsCSyn
-import PrelInfo            ( PrimOp(..)
-                     IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                   )
-import AsmRegAlloc  ( Reg, MachineCode(..), MachineRegisters(..),
-                     RegLiveness(..), RegUsage(..), FutureLive(..)
-                   )
-import CLabel   ( CLabel )
-import CmdLineOpts  ( GlobalSwitch(..), stringSwitchSet, switchIsOn, SwitchResult(..) )
-import HeapOffs            ( hpRelToInt )
-import MachDesc
-import Maybes      ( Maybe(..) )
-import OrdList
-import Outputable
-import SMRep       ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
-import I386Code
-import I386Gen     ( i386CodeGen )
-import Stix
-import StixMacro
-import StixPrim
-import UniqSupply
-import Util
-\end{code}
-
-Header sizes depend only on command-line options, not on the target
-architecture.  (I think.)
-
-\begin{code}
-
-fhs :: (GlobalSwitch -> SwitchResult) -> Int
-
-fhs switches = 1 + profFHS + ageFHS
-  where
-    profFHS = if switchIsOn switches SccProfilingOn then 1 else 0
-    ageFHS  = if switchIsOn switches SccProfilingOn then 1 else 0
-
-vhs :: (GlobalSwitch -> SwitchResult) -> SMRep -> Int
-
-vhs switches sm = case sm of
-    StaticRep _ _         -> 0
-    SpecialisedRep _ _ _ _ -> 0
-    GenericRep _ _ _      -> 0
-    BigTupleRep _         -> 1
-    MuTupleRep _          -> 2 {- (1 + GC_MUT_RESERVED_WORDS) -}
-    DataRep _             -> 1
-    DynamicRep            -> 2
-    BlackHoleRep          -> 0
-    PhantomRep            -> panic "vhs:phantom"
-
-\end{code}
-
-Here we map STG registers onto appropriate Stix Trees.  First, we
-handle the two constants, @STK_STUB_closure@ and @vtbl_StdUpdFrame@.
-The rest are either in real machine registers or stored as offsets
-from BaseReg.
-
-\begin{code}
-
-i386Reg :: (GlobalSwitch -> SwitchResult) -> MagicId -> RegLoc
-
-i386Reg switches x =
-    case stgRegMap x of
-       Just reg -> Save nonReg
-       Nothing -> Always nonReg
-    where nonReg = case x of
-           StkStubReg -> sStLitLbl SLIT("STK_STUB_closure")
-           StdUpdRetVecReg -> sStLitLbl SLIT("vtbl_StdUpdFrame")
-           BaseReg -> sStLitLbl SLIT("MainRegTable")
-           --Hp -> StInd PtrRep (sStLitLbl SLIT("StorageMgrInfo"))
-           --HpLim -> StInd PtrRep (sStLitLbl SLIT("StorageMgrInfo+4"))
-           TagReg -> StInd IntRep (StPrim IntSubOp [infoptr, StInt (1*4)])
-                     where
-                         r2 = VanillaReg PtrRep ILIT(2)
-                         infoptr = case i386Reg switches r2 of
-                                       Always tree -> tree
-                                       Save _ -> StReg (StixMagicId r2)
-           _ -> StInd (kindFromMagicId x)
-                      (StPrim IntAddOp [baseLoc, StInt (toInteger (offset*4))])
-         baseLoc = case stgRegMap BaseReg of
-           Just _ -> StReg (StixMagicId BaseReg)
-           Nothing -> sStLitLbl SLIT("MainRegTable")
-         offset = baseRegOffset x
-
-\end{code}
-
-Sizes in bytes.
-
-\begin{code}
-
-size pk = case kindToSize pk of
-    {B -> 1; S -> 2; L -> 4; F -> 4; D -> 8 }
-
-\end{code}
-
-Now the volatile saves and restores.  We add the basic guys to the list of ``user''
-registers provided.  Note that there are more basic registers on the restore list,
-because some are reloaded from constants.
-
-\begin{code}
-
-vsaves switches vols =
-    map save ((filter callerSaves) ([BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg{-,ActivityReg-}] ++ vols))
-    where
-       save x = StAssign (kindFromMagicId x) loc reg
-                   where reg = StReg (StixMagicId x)
-                         loc = case i386Reg switches x of
-                                   Save loc -> loc
-                                   Always loc -> panic "vsaves"
-
-vrests switches vols =
-    map restore ((filter callerSaves)
-       ([BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg{-,ActivityReg-},StkStubReg,StdUpdRetVecReg] ++ vols))
-    where
-       restore x = StAssign (kindFromMagicId x) reg loc
-                   where reg = StReg (StixMagicId x)
-                         loc = case i386Reg switches x of
-                                   Save loc -> loc
-                                   Always loc -> panic "vrests"
-
-\end{code}
-
-Static closure sizes.
-
-\begin{code}
-
-charLikeSize, intLikeSize :: Target -> Int
-
-charLikeSize target =
-    size PtrRep * (fixedHeaderSize target + varHeaderSize target charLikeRep + 1)
-    where charLikeRep = SpecialisedRep CharLikeRep 0 1 SMNormalForm
-
-intLikeSize target =
-    size PtrRep * (fixedHeaderSize target + varHeaderSize target intLikeRep + 1)
-    where intLikeRep = SpecialisedRep IntLikeRep 0 1 SMNormalForm
-
-mhs, dhs :: (GlobalSwitch -> SwitchResult) -> StixTree
-
-mhs switches = StInt (toInteger words)
-  where
-    words = fhs switches + vhs switches (MuTupleRep 0)
-
-dhs switches = StInt (toInteger words)
-  where
-    words = fhs switches + vhs switches (DataRep 0)
-
-\end{code}
-
-Setting up a i386 target.
-
-\begin{code}
-mkI386 :: Bool
-       -> (GlobalSwitch -> SwitchResult)
-       -> (Target,
-           (PprStyle -> [[StixTree]] -> UniqSM Unpretty), -- codeGen
-           Bool,                                           -- underscore
-           (String -> String))                             -- fmtAsmLbl
-
-mkI386 decentOS switches =
-    let fhs' = fhs switches
-       vhs' = vhs switches
-       i386Reg' = i386Reg switches
-       vsaves' = vsaves switches
-       vrests' = vrests switches
-       hprel = hpRelToInt target
-       as = amodeCode target
-       as' = amodeCode' target
-       csz = charLikeSize target
-       isz = intLikeSize target
-       mhs' = mhs switches
-       dhs' = dhs switches
-       ps = genPrimCode target
-       mc = genMacroCode target
-       hc = doHeapCheck
-       target = mkTarget {-switches-} fhs' vhs' i386Reg' {-id-} size
-                         hprel as as'
-                         (vsaves', vrests', csz, isz, mhs', dhs', ps, mc, hc)
-                         {-i386CodeGen decentOS id-}
-    in
-    (target, i386CodeGen, decentOS, id)
-\end{code}
-
-
-
diff --git a/ghc/compiler/nativeGen/I386Gen.lhs b/ghc/compiler/nativeGen/I386Gen.lhs
deleted file mode 100644 (file)
index 0edbba1..0000000
+++ /dev/null
@@ -1,1639 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1993-1995
-%
-
-\begin{code}
-#include "HsVersions.h"
-#include "../includes/i386-unknown-linuxaout.h"
-
-module I386Gen (
-       i386CodeGen,
-
-       -- and, for self-sufficiency
-       PprStyle, StixTree, CSeq
-    ) where
-
-IMPORT_Trace
-
-import AbsCSyn     ( AbstractC, MagicId(..), kindFromMagicId )
-import PrelInfo            ( PrimOp(..)
-                     IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                   )
-import AsmRegAlloc  ( runRegAllocate, mkReg, extractMappedRegNos,
-                     Reg(..), RegLiveness(..), RegUsage(..),
-                     FutureLive(..), MachineRegisters(..), MachineCode(..)
-                   )
-import CLabel   ( CLabel, isAsmTemp )
-import I386Code    {- everything -}
-import MachDesc
-import Maybes      ( maybeToBool, Maybe(..) )
-import OrdList     -- ( mkEmptyList, mkUnitList, mkSeqList, mkParList, OrdList )
-import Outputable
-import I386Desc
-import Stix
-import UniqSupply
-import Pretty
-import Unpretty
-import Util
-
-type CodeBlock a = (OrdList a -> OrdList a)
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[I386CodeGen]{Generating I386 Code}
-%*                                                                     *
-%************************************************************************
-
-This is the top-level code-generation function for the I386.
-
-\begin{code}
-
-i386CodeGen :: PprStyle -> [[StixTree]] -> UniqSM Unpretty
-i386CodeGen sty trees =
-    mapUs genI386Code trees            `thenUs` \ dynamicCodes ->
-    let
-       staticCodes = scheduleI386Code dynamicCodes
-       pretty = printLabeledCodes sty staticCodes
-    in
-       returnUs pretty
-
-\end{code}
-
-This bit does the code scheduling.  The scheduler must also deal with
-register allocation of temporaries.  Much parallelism can be exposed via
-the OrdList, but more might occur, so further analysis might be needed.
-
-\begin{code}
-
-scheduleI386Code :: [I386Code] -> [I386Instr]
-scheduleI386Code = concat . map (runRegAllocate freeI386Regs reservedRegs)
-  where
-    freeI386Regs :: I386Regs
-    freeI386Regs = mkMRegs (extractMappedRegNos freeRegs)
-
-
-\end{code}
-
-Registers passed up the tree.  If the stix code forces the register
-to live in a pre-decided machine register, it comes out as @Fixed@;
-otherwise, it comes out as @Any@, and the parent can decide which
-register to put it in.
-
-\begin{code}
-
-data Register
-  = Fixed Reg PrimRep (CodeBlock I386Instr)
-  | Any PrimRep (Reg -> (CodeBlock I386Instr))
-
-registerCode :: Register -> Reg -> CodeBlock I386Instr
-registerCode (Fixed _ _ code) reg = code
-registerCode (Any _ code) reg = code reg
-
-registerName :: Register -> Reg -> Reg
-registerName (Fixed reg _ _) _ = reg
-registerName (Any _ _) reg = reg
-
-registerKind :: Register -> PrimRep
-registerKind (Fixed _ pk _) = pk
-registerKind (Any pk _) = pk
-
-isFixed :: Register -> Bool
-isFixed (Fixed _ _ _) = True
-isFixed (Any _ _)     = False
-
-\end{code}
-
-Memory addressing modes passed up the tree.
-
-\begin{code}
-
-data Amode = Amode Addr (CodeBlock I386Instr)
-
-amodeAddr (Amode addr _) = addr
-amodeCode (Amode _ code) = code
-
-\end{code}
-
-Condition codes passed up the tree.
-
-\begin{code}
-
-data Condition = Condition Bool Cond (CodeBlock I386Instr)
-
-condName (Condition _ cond _) = cond
-condFloat (Condition float _ _) = float
-condCode (Condition _ _ code) = code
-
-\end{code}
-
-General things for putting together code sequences.
-
-\begin{code}
-
-asmVoid :: OrdList I386Instr
-asmVoid = mkEmptyList
-
-asmInstr :: I386Instr -> I386Code
-asmInstr i = mkUnitList i
-
-asmSeq :: [I386Instr] -> I386Code
-asmSeq is = foldr (mkSeqList . asmInstr) asmVoid is
-
-asmParThen :: [I386Code] -> (CodeBlock I386Instr)
-asmParThen others code = mkSeqList (foldr mkParList mkEmptyList others) code
-
-returnInstr :: I386Instr -> UniqSM (CodeBlock I386Instr)
-returnInstr instr = returnUs (\xs -> mkSeqList (asmInstr instr) xs)
-
-returnInstrs :: [I386Instr] -> UniqSM (CodeBlock I386Instr)
-returnInstrs instrs = returnUs (\xs -> mkSeqList (asmSeq instrs) xs)
-
-returnSeq :: (CodeBlock I386Instr) -> [I386Instr] -> UniqSM (CodeBlock I386Instr)
-returnSeq code instrs = returnUs (\xs -> code (mkSeqList (asmSeq instrs) xs))
-
-mkSeqInstr :: I386Instr -> (CodeBlock I386Instr)
-mkSeqInstr instr code = mkSeqList (asmInstr instr) code
-
-mkSeqInstrs :: [I386Instr] -> (CodeBlock I386Instr)
-mkSeqInstrs instrs code = mkSeqList (asmSeq instrs) code
-
-\end{code}
-
-Top level i386 code generator for a chunk of stix code.
-
-\begin{code}
-
-genI386Code :: [StixTree] -> UniqSM (I386Code)
-
-genI386Code trees =
-    mapUs getCode trees                `thenUs` \ blocks ->
-    returnUs (foldr (.) id blocks asmVoid)
-
-\end{code}
-
-Code extractor for an entire stix tree---stix statement level.
-
-\begin{code}
-
-getCode
-    :: StixTree     -- a stix statement
-    -> UniqSM (CodeBlock I386Instr)
-
-getCode (StSegment seg) = returnInstr (SEGMENT seg)
-
-getCode (StAssign pk dst src)
-  | isFloatingRep pk = assignFltCode pk dst src
-  | otherwise = assignIntCode pk dst src
-
-getCode (StLabel lab) = returnInstr (LABEL lab)
-
-getCode (StFunBegin lab) = returnInstr (LABEL lab)
-
-getCode (StFunEnd lab) = returnUs id
-
-getCode (StJump arg) = genJump arg
-
-getCode (StFallThrough lbl) = returnUs id
-
-getCode (StCondJump lbl arg) = genCondJump lbl arg
-
-getCode (StData kind args) =
-    mapAndUnzipUs getData args             `thenUs` \ (codes, imms) ->
-    returnUs (\xs -> mkSeqList (asmInstr (DATA (kindToSize kind) imms))
-                               (foldr1 (.) codes xs))
-  where
-    getData :: StixTree -> UniqSM (CodeBlock I386Instr, Imm)
-    getData (StInt i) = returnUs (id, ImmInteger i)
-    getData (StDouble d) = returnUs (id, strImmLit ('0' : 'd' : ppShow 80 (ppRational d)))
-    getData (StLitLbl s) = returnUs (id, ImmLit (uppBeside (uppChar '_') s))
-    getData (StLitLit s) = returnUs (id, strImmLit (cvtLitLit (_UNPK_ s)))
-    getData (StString s) =
-       getUniqLabelNCG                     `thenUs` \ lbl ->
-       returnUs (mkSeqInstrs [LABEL lbl, ASCII True (_UNPK_ s)], ImmCLbl lbl)
-    getData (StCLbl l)   = returnUs (id, ImmCLbl l)
-
-getCode (StCall fn VoidRep args) = genCCall fn VoidRep args
-
-getCode (StComment s) = returnInstr (COMMENT s)
-
-\end{code}
-
-Generate code to get a subtree into a register.
-
-\begin{code}
-
-getReg :: StixTree -> UniqSM Register
-
-getReg (StReg (StixMagicId stgreg)) =
-    case stgRegMap stgreg of
-       Just reg -> returnUs (Fixed reg (kindFromMagicId stgreg) id)
-       -- cannot be Nothing
-
-getReg (StReg (StixTemp u pk)) = returnUs (Fixed (UnmappedReg u pk) pk id)
-
-getReg (StDouble 0.0)
-  = let
-       code dst = mkSeqInstrs [FLDZ]
-    in
-       returnUs (Any DoubleRep code)
-
-getReg (StDouble 1.0)
-  = let
-       code dst = mkSeqInstrs [FLD1]
-    in
-       returnUs (Any DoubleRep code)
-
-getReg (StDouble d) =
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    --getNewRegNCG PtrRep          `thenUs` \ tmp ->
-    let code dst = mkSeqInstrs [
-           SEGMENT DataSegment,
-           LABEL lbl,
-           DATA D [strImmLit ('0' : 'd' :ppShow 80 (ppRational d))],
-           SEGMENT TextSegment,
-           FLD D (OpImm (ImmCLbl lbl))
-           ]
-    in
-       returnUs (Any DoubleRep code)
-
-getReg (StString s) =
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    let code dst = mkSeqInstrs [
-           SEGMENT DataSegment,
-           LABEL lbl,
-           ASCII True (_UNPK_ s),
-           SEGMENT TextSegment,
-           MOV L (OpImm (ImmCLbl lbl)) (OpReg dst)]
-    in
-       returnUs (Any PtrRep code)
-
-getReg (StLitLit s) | _HEAD_ s == '"' && last xs == '"' =
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    let code dst = mkSeqInstrs [
-           SEGMENT DataSegment,
-           LABEL lbl,
-           ASCII False (init xs),
-           SEGMENT TextSegment,
-           MOV L (OpImm (ImmCLbl lbl)) (OpReg dst)]
-    in
-       returnUs (Any PtrRep code)
-  where
-    xs = _UNPK_ (_TAIL_ s)
-
-
-getReg tree@(StIndex _ _ _) = getReg (mangleIndexTree tree)
-
-getReg (StCall fn kind args) =
-    genCCall fn kind args          `thenUs` \ call ->
-    returnUs (Fixed reg kind call)
-  where
-    reg = if isFloatingRep kind then st0 else eax
-
-getReg (StPrim primop args) =
-    case primop of
-
-       CharGtOp -> condIntReg GT args
-       CharGeOp -> condIntReg GE args
-       CharEqOp -> condIntReg EQ args
-       CharNeOp -> condIntReg NE args
-       CharLtOp -> condIntReg LT args
-       CharLeOp -> condIntReg LE args
-
-       IntAddOp -> -- this should be optimised by the generic Opts,
-                   -- I don't know why it is not (sometimes)!
-                   case args of
-                     [x, StInt 0] -> getReg x
-                     _ -> addCode L args
-
-       IntSubOp -> subCode L args
-       IntMulOp -> trivialCode (IMUL L) args True
-       IntQuotOp -> divCode L args True -- division
-       IntRemOp -> divCode L args False -- remainder
-       IntNegOp -> trivialUCode (NEGI L) args
-       IntAbsOp -> absIntCode args
-
-       AndOp -> trivialCode (AND L) args True
-       OrOp  -> trivialCode (OR L) args True
-       NotOp -> trivialUCode (NOT L) args
-       SllOp -> trivialCode (SHL L) args False
-       SraOp -> trivialCode (SAR L) args False
-       SrlOp -> trivialCode (SHR L) args False
-       ISllOp -> panic "I386Gen:isll"
-       ISraOp -> panic "I386Gen:isra"
-       ISrlOp -> panic "I386Gen:isrl"
-
-       IntGtOp -> condIntReg GT args
-       IntGeOp -> condIntReg GE args
-       IntEqOp -> condIntReg EQ args
-       IntNeOp -> condIntReg NE args
-       IntLtOp -> condIntReg LT args
-       IntLeOp -> condIntReg LE args
-
-       WordGtOp -> condIntReg GU args
-       WordGeOp -> condIntReg GEU args
-       WordEqOp -> condIntReg EQ args
-       WordNeOp -> condIntReg NE args
-       WordLtOp -> condIntReg LU args
-       WordLeOp -> condIntReg LEU args
-
-       AddrGtOp -> condIntReg GU args
-       AddrGeOp -> condIntReg GEU args
-       AddrEqOp -> condIntReg EQ args
-       AddrNeOp -> condIntReg NE args
-       AddrLtOp -> condIntReg LU args
-       AddrLeOp -> condIntReg LEU args
-
-       FloatAddOp -> trivialFCode FloatRep FADD FADD FADDP FADDP args
-       FloatSubOp -> trivialFCode FloatRep FSUB FSUBR FSUBP FSUBRP args
-       FloatMulOp -> trivialFCode FloatRep FMUL FMUL FMULP FMULP args
-       FloatDivOp -> trivialFCode FloatRep FDIV FDIVR FDIVP FDIVRP args
-       FloatNegOp -> trivialUFCode FloatRep FCHS args
-
-       FloatGtOp -> condFltReg GT args
-       FloatGeOp -> condFltReg GE args
-       FloatEqOp -> condFltReg EQ args
-       FloatNeOp -> condFltReg NE args
-       FloatLtOp -> condFltReg LT args
-       FloatLeOp -> condFltReg LE args
-
-       FloatExpOp -> promoteAndCall SLIT("exp") DoubleRep
-       FloatLogOp -> promoteAndCall SLIT("log") DoubleRep
-       FloatSqrtOp -> trivialUFCode FloatRep FSQRT args
-
-       FloatSinOp -> promoteAndCall SLIT("sin") DoubleRep
-                     --trivialUFCode FloatRep FSIN args
-       FloatCosOp -> promoteAndCall SLIT("cos") DoubleRep
-                     --trivialUFCode FloatRep FCOS args
-       FloatTanOp -> promoteAndCall SLIT("tan") DoubleRep
-
-       FloatAsinOp -> promoteAndCall SLIT("asin") DoubleRep
-       FloatAcosOp -> promoteAndCall SLIT("acos") DoubleRep
-       FloatAtanOp -> promoteAndCall SLIT("atan") DoubleRep
-
-       FloatSinhOp -> promoteAndCall SLIT("sinh") DoubleRep
-       FloatCoshOp -> promoteAndCall SLIT("cosh") DoubleRep
-       FloatTanhOp -> promoteAndCall SLIT("tanh") DoubleRep
-
-       FloatPowerOp -> promoteAndCall SLIT("pow") DoubleRep
-
-       DoubleAddOp -> trivialFCode DoubleRep FADD FADD FADDP FADDP args
-       DoubleSubOp -> trivialFCode DoubleRep FSUB FSUBR FSUBP FSUBRP args
-       DoubleMulOp -> trivialFCode DoubleRep FMUL FMUL FMULP FMULP args
-       DoubleDivOp -> trivialFCode DoubleRep FDIV FDIVR FDIVP FDIVRP args
-       DoubleNegOp -> trivialUFCode DoubleRep FCHS args
-
-       DoubleGtOp -> condFltReg GT args
-       DoubleGeOp -> condFltReg GE args
-       DoubleEqOp -> condFltReg EQ args
-       DoubleNeOp -> condFltReg NE args
-       DoubleLtOp -> condFltReg LT args
-       DoubleLeOp -> condFltReg LE args
-
-       DoubleExpOp -> call SLIT("exp") DoubleRep
-       DoubleLogOp -> call SLIT("log") DoubleRep
-       DoubleSqrtOp -> trivialUFCode DoubleRep FSQRT args
-
-       DoubleSinOp -> call SLIT("sin") DoubleRep
-                      --trivialUFCode DoubleRep FSIN args
-       DoubleCosOp -> call SLIT("cos") DoubleRep
-                      --trivialUFCode DoubleRep FCOS args
-       DoubleTanOp -> call SLIT("tan") DoubleRep
-
-       DoubleAsinOp -> call SLIT("asin") DoubleRep
-       DoubleAcosOp -> call SLIT("acos") DoubleRep
-       DoubleAtanOp -> call SLIT("atan") DoubleRep
-
-       DoubleSinhOp -> call SLIT("sinh") DoubleRep
-       DoubleCoshOp -> call SLIT("cosh") DoubleRep
-       DoubleTanhOp -> call SLIT("tanh") DoubleRep
-
-       DoublePowerOp -> call SLIT("pow") DoubleRep
-
-       OrdOp -> coerceIntCode IntRep args
-       ChrOp -> chrCode args
-
-       Float2IntOp -> coerceFP2Int args
-       Int2FloatOp -> coerceInt2FP FloatRep args
-       Double2IntOp -> coerceFP2Int args
-       Int2DoubleOp -> coerceInt2FP DoubleRep args
-
-       Double2FloatOp -> coerceFltCode args
-       Float2DoubleOp -> coerceFltCode args
-
-  where
-    call fn pk = getReg (StCall fn pk args)
-    promoteAndCall fn pk = getReg (StCall fn pk (map promote args))
-      where
-       promote x = StPrim Float2DoubleOp [x]
-
-getReg (StInd pk mem) =
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code = amodeCode amode
-       src   = amodeAddr amode
-       size = kindToSize pk
-       code__2 dst = code .
-                     if pk == DoubleRep || pk == FloatRep
-                     then mkSeqInstr (FLD {-D-} size (OpAddr src))
-                     else mkSeqInstr (MOV size (OpAddr src) (OpReg dst))
-    in
-       returnUs (Any pk code__2)
-
-
-getReg (StInt i)
-  = let
-       src = ImmInt (fromInteger i)
-       code dst = mkSeqInstr (MOV L (OpImm src) (OpReg dst))
-    in
-       returnUs (Any IntRep code)
-
-getReg leaf
-  | maybeToBool imm =
-    let
-       code dst = mkSeqInstr (MOV L (OpImm imm__2) (OpReg dst))
-    in
-       returnUs (Any PtrRep code)
-  where
-    imm = maybeImm leaf
-    imm__2 = case imm of Just x -> x
-
-\end{code}
-
-Now, given a tree (the argument to an StInd) that references memory,
-produce a suitable addressing mode.
-
-\begin{code}
-
-getAmode :: StixTree -> UniqSM Amode
-
-getAmode tree@(StIndex _ _ _) = getAmode (mangleIndexTree tree)
-
-getAmode (StPrim IntSubOp [x, StInt i])
-  =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    getReg x                       `thenUs` \ register ->
-    let
-       code = registerCode register tmp
-       reg  = registerName register tmp
-       off  = ImmInt (-(fromInteger i))
-    in
-       returnUs (Amode (Addr (Just reg) Nothing off) code)
-
-getAmode (StPrim IntAddOp [x, StInt i])
-  | maybeToBool imm
-  = let
-       code = mkSeqInstrs []
-    in
-       returnUs (Amode (ImmAddr imm__2 (fromInteger i)) code)
-  where
-    imm = maybeImm x
-    imm__2 = case imm of Just x -> x
-
-getAmode (StPrim IntAddOp [x, StInt i])
-  =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    getReg x                       `thenUs` \ register ->
-    let
-       code = registerCode register tmp
-       reg  = registerName register tmp
-       off  = ImmInt (fromInteger i)
-    in
-       returnUs (Amode (Addr (Just reg) Nothing off) code)
-
-getAmode (StPrim IntAddOp [x, y]) =
-    getNewRegNCG PtrRep            `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       reg1  = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       reg2  = registerName register2 tmp2
-       code__2 = asmParThen [code1, code2]
-    in
-       returnUs (Amode (Addr (Just reg1) (Just (reg2,4)) (ImmInt 0)) code__2)
-
-getAmode leaf
-  | maybeToBool imm =
-    let code = mkSeqInstrs []
-    in
-       returnUs (Amode (ImmAddr imm__2 0) code)
-  where
-    imm = maybeImm leaf
-    imm__2 = case imm of Just x -> x
-
-getAmode other =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    getReg other                   `thenUs` \ register ->
-    let
-       code = registerCode register tmp
-       reg  = registerName register tmp
-       off  = Nothing
-    in
-       returnUs (Amode (Addr (Just reg) Nothing (ImmInt 0)) code)
-
-\end{code}
-
-\begin{code}
-getOp
-    :: StixTree
-    -> UniqSM (CodeBlock I386Instr,Operand, Size)      -- code, operator, size
-getOp (StInt i)
-  = returnUs (asmParThen [], OpImm (ImmInt (fromInteger i)), L)
-
-getOp (StInd pk mem)
-  = getAmode mem                   `thenUs` \ amode ->
-    let
-       code = amodeCode amode --asmVoid
-       addr  = amodeAddr amode
-       sz = kindToSize pk
-    in returnUs (code, OpAddr addr, sz)
-
-getOp op
-  = getReg op                      `thenUs` \ register ->
-    getNewRegNCG (registerKind register)
-                                   `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       reg = registerName register tmp
-       pk = registerKind register
-       sz = kindToSize pk
-    in
-       returnUs (code, OpReg reg, sz)
-
-getOpRI
-    :: StixTree
-    -> UniqSM (CodeBlock I386Instr,Operand, Size)      -- code, operator, size
-getOpRI op
-  | maybeToBool imm
-  = returnUs (asmParThen [], OpImm imm_op, L)
-  where
-    imm = maybeImm op
-    imm_op = case imm of Just x -> x
-
-getOpRI op
-  = getReg op                      `thenUs` \ register ->
-    getNewRegNCG (registerKind register)
-                                   `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       reg = registerName register tmp
-       pk = registerKind register
-       sz = kindToSize pk
-    in
-       returnUs (code, OpReg reg, sz)
-
-\end{code}
-
-Set up a condition code for a conditional branch.
-
-\begin{code}
-
-getCondition :: StixTree -> UniqSM Condition
-
-getCondition (StPrim primop args) =
-    case primop of
-
-       CharGtOp -> condIntCode GT args
-       CharGeOp -> condIntCode GE args
-       CharEqOp -> condIntCode EQ args
-       CharNeOp -> condIntCode NE args
-       CharLtOp -> condIntCode LT args
-       CharLeOp -> condIntCode LE args
-
-       IntGtOp -> condIntCode GT args
-       IntGeOp -> condIntCode GE args
-       IntEqOp -> condIntCode EQ args
-       IntNeOp -> condIntCode NE args
-       IntLtOp -> condIntCode LT args
-       IntLeOp -> condIntCode LE args
-
-       WordGtOp -> condIntCode GU args
-       WordGeOp -> condIntCode GEU args
-       WordEqOp -> condIntCode EQ args
-       WordNeOp -> condIntCode NE args
-       WordLtOp -> condIntCode LU args
-       WordLeOp -> condIntCode LEU args
-
-       AddrGtOp -> condIntCode GU args
-       AddrGeOp -> condIntCode GEU args
-       AddrEqOp -> condIntCode EQ args
-       AddrNeOp -> condIntCode NE args
-       AddrLtOp -> condIntCode LU args
-       AddrLeOp -> condIntCode LEU args
-
-       FloatGtOp -> condFltCode GT args
-       FloatGeOp -> condFltCode GE args
-       FloatEqOp -> condFltCode EQ args
-       FloatNeOp -> condFltCode NE args
-       FloatLtOp -> condFltCode LT args
-       FloatLeOp -> condFltCode LE args
-
-       DoubleGtOp -> condFltCode GT args
-       DoubleGeOp -> condFltCode GE args
-       DoubleEqOp -> condFltCode EQ args
-       DoubleNeOp -> condFltCode NE args
-       DoubleLtOp -> condFltCode LT args
-       DoubleLeOp -> condFltCode LE args
-
-\end{code}
-
-Turn a boolean expression into a condition, to be passed
-back up the tree.
-
-\begin{code}
-
-condIntCode, condFltCode :: Cond -> [StixTree] -> UniqSM Condition
-condIntCode cond [StInd _ x, y]
-  | maybeToBool imm
-  = getAmode x                     `thenUs` \ amode ->
-    let
-       code1 = amodeCode amode asmVoid
-       y__2  = amodeAddr amode
-       code__2 = asmParThen [code1] .
-                 mkSeqInstr (CMP L (OpImm imm__2) (OpAddr y__2))
-    in
-       returnUs (Condition False cond code__2)
-  where
-    imm = maybeImm y
-    imm__2 = case imm of Just x -> x
-
-condIntCode cond [x, StInt 0]
-  = getReg x                       `thenUs` \ register1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1  = registerName register1 tmp1
-       code__2 = asmParThen [code1] .
-               mkSeqInstr (TEST L (OpReg src1) (OpReg src1))
-    in
-       returnUs (Condition False cond code__2)
-
-condIntCode cond [x, y]
-  | maybeToBool imm
-  = getReg x                       `thenUs` \ register1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1  = registerName register1 tmp1
-       code__2 = asmParThen [code1] .
-               mkSeqInstr (CMP L (OpImm imm__2) (OpReg src1))
-    in
-       returnUs (Condition False cond code__2)
-  where
-    imm = maybeImm y
-    imm__2 = case imm of Just x -> x
-
-condIntCode cond [StInd _ x, y]
-  = getAmode x                     `thenUs` \ amode ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    let
-       code1 = amodeCode amode asmVoid
-       src1  = amodeAddr amode
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 = asmParThen [code1, code2] .
-                 mkSeqInstr (CMP L (OpReg src2) (OpAddr src1))
-    in
-       returnUs (Condition False cond code__2)
-
-condIntCode cond [y, StInd _ x]
-  = getAmode x                     `thenUs` \ amode ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    let
-       code1 = amodeCode amode asmVoid
-       src1  = amodeAddr amode
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 = asmParThen [code1, code2] .
-                 mkSeqInstr (CMP L (OpAddr src1) (OpReg src2))
-    in
-       returnUs (Condition False cond code__2)
-
-condIntCode cond [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1  = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 = asmParThen [code1, code2] .
-               mkSeqInstr (CMP L (OpReg src2) (OpReg src1))
-    in
-       returnUs (Condition False cond code__2)
-
-condFltCode cond [x, StDouble 0.0] =
-    getReg x                       `thenUs` \ register1 ->
-    getNewRegNCG (registerKind register1)
-                                   `thenUs` \ tmp1 ->
-    let
-       pk1   = registerKind register1
-       code1 = registerCode register1 tmp1
-       src1  = registerName register1 tmp1
-
-       code__2 = asmParThen [code1 asmVoid] .
-                 mkSeqInstrs [FTST, FSTP D (OpReg st0), -- or FLDZ, FUCOMPP ?
-                              FNSTSW,
-                              --AND HB (OpImm (ImmInt 68)) (OpReg eax),
-                              --XOR HB (OpImm (ImmInt 64)) (OpReg eax)
-                              SAHF
-                             ]
-    in
-       returnUs (Condition True (fixFPCond cond) code__2)
-
-condFltCode cond [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG (registerKind register1)
-                                   `thenUs` \ tmp1 ->
-    getNewRegNCG (registerKind register2)
-                                   `thenUs` \ tmp2 ->
-    let
-       pk1   = registerKind register1
-       code1 = registerCode register1 tmp1
-       src1  = registerName register1 tmp1
-
-       code2 = registerCode register2 tmp2
-       src2  = registerName register2 tmp2
-
-       code__2 = asmParThen [code2 asmVoid, code1 asmVoid] .
-                 mkSeqInstrs [FUCOMPP,
-                              FNSTSW,
-                              --AND HB (OpImm (ImmInt 68)) (OpReg eax),
-                              --XOR HB (OpImm (ImmInt 64)) (OpReg eax)
-                              SAHF
-                             ]
-    in
-       returnUs (Condition True (fixFPCond cond) code__2)
-
-\end{code}
-
-Turn those condition codes into integers now (when they appear on
-the right hand side of an assignment).
-
-\begin{code}
-
-condIntReg :: Cond -> [StixTree] -> UniqSM Register
-condIntReg cond args =
-    condIntCode cond args          `thenUs` \ condition ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    --getReg dst                           `thenUs` \ register ->
-    let
-       --code2 = registerCode register tmp asmVoid
-       --dst__2  = registerName register tmp
-       code = condCode condition
-       cond = condName condition
--- ToDo: if dst is eax, ebx, ecx, or edx we would not need the move.
-       code__2 dst = code . mkSeqInstrs [
-           SETCC cond (OpReg tmp),
-           AND L (OpImm (ImmInt 1)) (OpReg tmp),
-           MOV L (OpReg tmp) (OpReg dst)]
-    in
-       returnUs (Any IntRep code__2)
-
-condFltReg :: Cond -> [StixTree] -> UniqSM Register
-
-condFltReg cond args =
-    getUniqLabelNCG                `thenUs` \ lbl1 ->
-    getUniqLabelNCG                `thenUs` \ lbl2 ->
-    condFltCode cond args          `thenUs` \ condition ->
-    let
-       code = condCode condition
-       cond = condName condition
-       code__2 dst = code . mkSeqInstrs [
-           JXX cond lbl1,
-           MOV L (OpImm (ImmInt 0)) (OpReg dst),
-           JXX ALWAYS lbl2,
-           LABEL lbl1,
-           MOV L (OpImm (ImmInt 1)) (OpReg dst),
-           LABEL lbl2]
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-Assignments are really at the heart of the whole code generation business.
-Almost all top-level nodes of any real importance are assignments, which
-correspond to loads, stores, or register transfers.  If we're really lucky,
-some of the register transfers will go away, because we can use the destination
-register to complete the code generation for the right hand side.  This only
-fails when the right hand side is forced into a fixed register (e.g. the result
-of a call).
-
-\begin{code}
-
-assignIntCode :: PrimRep -> StixTree -> StixTree -> UniqSM (CodeBlock I386Instr)
-assignIntCode pk (StInd _ dst) src
-  = getAmode dst                   `thenUs` \ amode ->
-    getOpRI src                     `thenUs` \ (codesrc, opsrc, sz) ->
-    let
-       code1 = amodeCode amode asmVoid
-       dst__2  = amodeAddr amode
-       code__2 = asmParThen [code1, codesrc asmVoid] .
-                 mkSeqInstr (MOV sz opsrc (OpAddr dst__2))
-    in
-       returnUs code__2
-
-assignIntCode pk dst (StInd _ src) =
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    getAmode src                   `thenUs` \ amode ->
-    getReg dst                     `thenUs` \ register ->
-    let
-       code1 = amodeCode amode asmVoid
-       src__2  = amodeAddr amode
-       code2 = registerCode register tmp asmVoid
-       dst__2  = registerName register tmp
-       sz    = kindToSize pk
-       code__2 = asmParThen [code1, code2] .
-                 mkSeqInstr (MOV sz (OpAddr src__2) (OpReg dst__2))
-    in
-       returnUs code__2
-
-assignIntCode pk dst src =
-    getReg dst                     `thenUs` \ register1 ->
-    getReg src                     `thenUs` \ register2 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       dst__2 = registerName register1 tmp
-       code = registerCode register2 dst__2
-       src__2 = registerName register2 dst__2
-       code__2 = if isFixed register2 && dst__2 /= src__2
-                 then code . mkSeqInstr (MOV L (OpReg src__2) (OpReg dst__2))
-                 else
-                      code
-    in
-       returnUs code__2
-
-assignFltCode :: PrimRep -> StixTree -> StixTree -> UniqSM (CodeBlock I386Instr)
-assignFltCode pk (StInd pk_dst dst) (StInd pk_src src)
-  = getNewRegNCG IntRep            `thenUs` \ tmp ->
-    getAmode src                   `thenUs` \ amodesrc ->
-    getAmode dst                   `thenUs` \ amodedst ->
-    --getReg src                           `thenUs` \ register ->
-    let
-       codesrc1 = amodeCode amodesrc asmVoid
-       addrsrc1 = amodeAddr amodesrc
-       codedst1 = amodeCode amodedst asmVoid
-       addrdst1 = amodeAddr amodedst
-       addrsrc2 = case (offset addrsrc1 4) of Just x -> x
-       addrdst2 = case (offset addrdst1 4) of Just x -> x
-
-       code__2 = asmParThen [codesrc1, codedst1] .
-                 mkSeqInstrs ([MOV L (OpAddr addrsrc1) (OpReg tmp),
-                               MOV L (OpReg tmp) (OpAddr addrdst1)]
-                              ++
-                              if pk == DoubleRep
-                              then [MOV L (OpAddr addrsrc2) (OpReg tmp),
-                                    MOV L (OpReg tmp) (OpAddr addrdst2)]
-                              else [])
-    in
-       returnUs code__2
-
-assignFltCode pk (StInd _ dst) src =
-    --getNewRegNCG pk              `thenUs` \ tmp ->
-    getAmode dst                   `thenUs` \ amode ->
-    getReg src                     `thenUs` \ register ->
-    let
-       sz    = kindToSize pk
-       dst__2  = amodeAddr amode
-
-       code1 = amodeCode amode asmVoid
-       code2 = registerCode register {-tmp-}st0 asmVoid
-
-       --src__2  = registerName register tmp
-       pk__2  = registerKind register
-       sz__2 = kindToSize pk__2
-
-       code__2 = asmParThen [code1, code2] .
-                 mkSeqInstr (FSTP sz (OpAddr dst__2))
-    in
-       returnUs code__2
-
-assignFltCode pk dst src =
-    getReg dst                     `thenUs` \ register1 ->
-    getReg src                     `thenUs` \ register2 ->
-    --getNewRegNCG (registerKind register2)
-    --                             `thenUs` \ tmp ->
-    let
-       sz = kindToSize pk
-       dst__2 = registerName register1 st0 --tmp
-
-       code = registerCode register2 dst__2
-       src__2 = registerName register2 dst__2
-
-       code__2 = code
-    in
-       returnUs code__2
-
-\end{code}
-
-Generating an unconditional branch.  We accept two types of targets:
-an immediate CLabel or a tree that gets evaluated into a register.
-Any CLabels which are AsmTemporaries are assumed to be in the local
-block of code, close enough for a branch instruction.  Other CLabels
-are assumed to be far away, so we use call.
-
-Do not fill the delay slots here; you will confuse the register allocator.
-
-\begin{code}
-
-genJump
-    :: StixTree     -- the branch target
-    -> UniqSM (CodeBlock I386Instr)
-
-{-
-genJump (StCLbl lbl)
-  | isAsmTemp lbl = returnInstrs [JXX ALWAYS lbl]
-  | otherwise     = returnInstrs [JMP (OpImm target)]
-  where
-    target = ImmCLbl lbl
--}
-
-genJump (StInd pk mem) =
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code = amodeCode amode
-       target  = amodeAddr amode
-    in
-       returnSeq code [JMP (OpAddr target)]
-
-genJump tree
-  | maybeToBool imm
-  = returnInstr (JMP (OpImm target))
-  where
-    imm = maybeImm tree
-    target = case imm of Just x -> x
-
-
-genJump tree =
-    getReg tree                            `thenUs` \ register ->
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       target = registerName register tmp
-    in
-       returnSeq code [JMP (OpReg target)]
-
-\end{code}
-
-Conditional jumps are always to local labels, so we can use
-branch instructions.  First, we have to ensure that the condition
-codes are set according to the supplied comparison operation.
-
-\begin{code}
-
-genCondJump
-    :: CLabel      -- the branch target
-    -> StixTree     -- the condition on which to branch
-    -> UniqSM (CodeBlock I386Instr)
-
-genCondJump lbl bool =
-    getCondition bool                      `thenUs` \ condition ->
-    let
-       code = condCode condition
-       cond = condName condition
-       target = ImmCLbl lbl
-    in
-       returnSeq code [JXX cond lbl]
-
-\end{code}
-
-\begin{code}
-
-genCCall
-    :: FAST_STRING  -- function to call
-    -> PrimRep     -- type of the result
-    -> [StixTree]   -- arguments (of mixed type)
-    -> UniqSM (CodeBlock I386Instr)
-
-genCCall fn kind [StInt i]
-  | fn == SLIT ("PerformGC_wrapper")
-  = getUniqLabelNCG                        `thenUs` \ lbl ->
-    let
-       call = [MOV L (OpImm (ImmInt (fromInteger i))) (OpReg eax),
-               MOV L (OpImm (ImmCLbl lbl))
-                     -- this is hardwired
-                     (OpAddr (Addr (Just ebx) Nothing (ImmInt 104))),
-               JMP (OpImm (ImmLit (uppPStr (SLIT ("_PerformGC_wrapper"))))),
-               LABEL lbl]
-    in
-       returnInstrs call
-
-genCCall fn kind args =
-    mapUs getCallArg args `thenUs` \ argCode ->
-    let
-       nargs = length args
-       code1 = asmParThen [asmSeq [ -- MOV L (OpReg esp) (OpAddr (Addr (Just ebx) Nothing (ImmInt 80))),
-                       MOV L (OpAddr (Addr (Just ebx) Nothing (ImmInt 100))) (OpReg esp)
-                                  ]
-                          ]
-       code2 = asmParThen (map ($ asmVoid) (reverse argCode))
-       call = [CALL (ImmLit fn__2) -- ,
-               -- ADD L (OpImm (ImmInt (nargs * 4))) (OpReg esp),
-               -- MOV L (OpAddr (Addr (Just ebx) Nothing (ImmInt 80))) (OpReg esp)
-               ]
-    in
-       returnSeq (code1 . code2) call
-  where
-    -- function names that begin with '.' are assumed to be special internally
-    -- generated names like '.mul,' which don't get an underscore prefix
-    fn__2 = case (_HEAD_ fn) of
-             '.' -> uppPStr fn
-             _   -> uppBeside (uppChar '_') (uppPStr fn)
-
-    getCallArg
-       :: StixTree                             -- Current argument
-       -> UniqSM (CodeBlock I386Instr) -- code
-    getCallArg arg =
-       getOp arg                           `thenUs` \ (code, op, sz) ->
-       returnUs (code . mkSeqInstr (PUSH sz op))
-\end{code}
-
-Trivial (dyadic) instructions.  Only look for constants on the right hand
-side, because that's where the generic optimizer will have put them.
-
-\begin{code}
-
-trivialCode
-    :: (Operand -> Operand -> I386Instr)
-    -> [StixTree]
-    -> Bool    -- is the instr commutative?
-    -> UniqSM Register
-
-trivialCode instr [x, y] _
-  | maybeToBool imm
-  = getReg x                       `thenUs` \ register1 ->
-    --getNewRegNCG IntRep          `thenUs` \ tmp1 ->
-    let
-       fixedname  = registerName register1 eax
-       code__2 dst = let code1 = registerCode register1 dst
-                         src1  = registerName register1 dst
-                     in code1 .
-                        if isFixed register1 && src1 /= dst
-                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
-                                          instr (OpImm imm__2) (OpReg dst)]
-                        else
-                               mkSeqInstrs [instr (OpImm imm__2) (OpReg src1)]
-    in
-       returnUs (Any IntRep code__2)
-  where
-    imm = maybeImm y
-    imm__2 = case imm of Just x -> x
-
-trivialCode instr [x, y] _
-  | maybeToBool imm
-  = getReg y                       `thenUs` \ register1 ->
-    --getNewRegNCG IntRep          `thenUs` \ tmp1 ->
-    let
-       fixedname  = registerName register1 eax
-       code__2 dst = let code1 = registerCode register1 dst
-                         src1  = registerName register1 dst
-                     in code1 .
-                        if isFixed register1 && src1 /= dst
-                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
-                                          instr (OpImm imm__2) (OpReg dst)]
-                        else
-                               mkSeqInstr (instr (OpImm imm__2) (OpReg src1))
-    in
-       returnUs (Any IntRep code__2)
-  where
-    imm = maybeImm x
-    imm__2 = case imm of Just x -> x
-
-trivialCode instr [x, StInd pk mem] _
-  = getReg x                       `thenUs` \ register ->
-    --getNewRegNCG IntRep          `thenUs` \ tmp ->
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       fixedname  = registerName register eax
-       code2 = amodeCode amode asmVoid
-       src2  = amodeAddr amode
-       code__2 dst = let code1 = registerCode register dst asmVoid
-                         src1  = registerName register dst
-                     in asmParThen [code1, code2] .
-                        if isFixed register && src1 /= dst
-                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
-                                          instr (OpAddr src2)  (OpReg dst)]
-                        else
-                               mkSeqInstr (instr (OpAddr src2) (OpReg src1))
-    in
-       returnUs (Any pk code__2)
-
-trivialCode instr [StInd pk mem, y] _
-  = getReg y                       `thenUs` \ register ->
-    --getNewRegNCG IntRep          `thenUs` \ tmp ->
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       fixedname  = registerName register eax
-       code2 = amodeCode amode asmVoid
-       src2  = amodeAddr amode
-       code__2 dst = let
-                         code1 = registerCode register dst asmVoid
-                         src1  = registerName register dst
-                     in asmParThen [code1, code2] .
-                        if isFixed register && src1 /= dst
-                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
-                                          instr (OpAddr src2)  (OpReg dst)]
-                        else
-                               mkSeqInstr (instr (OpAddr src2) (OpReg src1))
-    in
-       returnUs (Any pk code__2)
-
-trivialCode instr [x, y] is_comm_op
-  = getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    --getNewRegNCG IntRep          `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    let
-       fixedname  = registerName register1 eax
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 dst = let
-                         code1 = registerCode register1 dst asmVoid
-                         src1  = registerName register1 dst
-                     in asmParThen [code1, code2] .
-                        if isFixed register1 && src1 /= dst
-                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
-                                          instr (OpReg src2)  (OpReg dst)]
-                        else
-                               mkSeqInstr (instr (OpReg src2) (OpReg src1))
-    in
-       returnUs (Any IntRep code__2)
-
-addCode
-    :: Size
-    -> [StixTree]
-    -> UniqSM Register
-addCode sz [x, StInt y]
-  =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src1 = registerName register tmp
-       src2 = ImmInt (fromInteger y)
-       code__2 dst = code .
-                     mkSeqInstr (LEA sz (OpAddr (Addr (Just src1) Nothing src2)) (OpReg dst))
-    in
-       returnUs (Any IntRep code__2)
-
-addCode sz [x, StInd _ mem]
-  = getReg x                       `thenUs` \ register1 ->
-    --getNewRegNCG (registerKind register1)
-    --                                     `thenUs` \ tmp1 ->
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code2 = amodeCode amode
-       src2  = amodeAddr amode
-
-       fixedname  = registerName register1 eax
-       code__2 dst = let code1 = registerCode register1 dst
-                         src1  = registerName register1 dst
-                     in asmParThen [code2 asmVoid,code1 asmVoid] .
-                        if isFixed register1 && src1 /= dst
-                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
-                                          ADD sz (OpAddr src2)  (OpReg dst)]
-                        else
-                               mkSeqInstrs [ADD sz (OpAddr src2) (OpReg src1)]
-    in
-       returnUs (Any IntRep code__2)
-
-addCode sz [StInd _ mem, y]
-  = getReg y                       `thenUs` \ register2 ->
-    --getNewRegNCG (registerKind register2)
-    --                                     `thenUs` \ tmp2 ->
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code1 = amodeCode amode
-       src1  = amodeAddr amode
-
-       fixedname  = registerName register2 eax
-       code__2 dst = let code2 = registerCode register2 dst
-                         src2  = registerName register2 dst
-                     in asmParThen [code1 asmVoid,code2 asmVoid] .
-                        if isFixed register2 && src2 /= dst
-                        then mkSeqInstrs [MOV L (OpReg src2) (OpReg dst),
-                                          ADD sz (OpAddr src1)  (OpReg dst)]
-                        else
-                               mkSeqInstrs [ADD sz (OpAddr src1) (OpReg src2)]
-    in
-       returnUs (Any IntRep code__2)
-
-addCode sz [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1  = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 dst = asmParThen [code1, code2] .
-                     mkSeqInstr (LEA sz (OpAddr (Addr (Just src1) (Just (src2,1)) (ImmInt 0))) (OpReg dst))
-    in
-       returnUs (Any IntRep code__2)
-
-subCode
-    :: Size
-    -> [StixTree]
-    -> UniqSM Register
-subCode sz [x, StInt y]
-  = getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src1 = registerName register tmp
-       src2 = ImmInt (-(fromInteger y))
-       code__2 dst = code .
-                     mkSeqInstr (LEA sz (OpAddr (Addr (Just src1) Nothing src2)) (OpReg dst))
-    in
-       returnUs (Any IntRep code__2)
-
-subCode sz args = trivialCode (SUB sz) args False
-
-divCode
-    :: Size
-    -> [StixTree]
-    -> Bool -- True => division, False => remainder operation
-    -> UniqSM Register
-
--- x must go into eax, edx must be a sign-extension of eax,
--- and y should go in some other register (or memory),
--- so that we get edx:eax / reg -> eax (remainder in edx)
--- Currently we chose to put y in memory (if it is not there already)
-divCode sz [x, StInd pk mem] is_division
-  = getReg x                       `thenUs` \ register1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1 = registerName register1 tmp1
-       code2 = amodeCode amode asmVoid
-       src2  = amodeAddr amode
-       code__2 = asmParThen [code1, code2] .
-                 mkSeqInstrs [MOV L (OpReg src1) (OpReg eax),
-                              CLTD,
-                              IDIV sz (OpAddr src2)]
-    in
-       returnUs (Fixed (if is_division then eax else edx) IntRep code__2)
-
-divCode sz [x, StInt i] is_division
-  = getReg x                       `thenUs` \ register1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1 = registerName register1 tmp1
-       src2 = ImmInt (fromInteger i)
-       code__2 = asmParThen [code1] .
-                 mkSeqInstrs [-- we put src2 in (ebx)
-                              MOV L (OpImm src2) (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1))),
-                              MOV L (OpReg src1) (OpReg eax),
-                              CLTD,
-                              IDIV sz (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1)))]
-    in
-       returnUs (Fixed (if is_division then eax else edx) IntRep code__2)
-
-divCode sz [x, y] is_division
-  = getReg x                       `thenUs` \ register1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1 = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       src2 = registerName register2 tmp2
-       code__2 = asmParThen [code1, code2] .
-                 if src2 == ecx || src2 == esi
-                 then mkSeqInstrs [ MOV L (OpReg src1) (OpReg eax),
-                                    CLTD,
-                                    IDIV sz (OpReg src2)]
-                 else mkSeqInstrs [ -- we put src2 in (ebx)
-                                    MOV L (OpReg src2) (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1))),
-                                    MOV L (OpReg src1) (OpReg eax),
-                                    CLTD,
-                                    IDIV sz (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1)))]
-    in
-       returnUs (Fixed (if is_division then eax else edx) IntRep code__2)
-
-trivialFCode
-    :: PrimRep
-    -> (Size -> Operand -> I386Instr)
-    -> (Size -> Operand -> I386Instr) -- reversed instr
-    -> I386Instr -- pop
-    -> I386Instr -- reversed instr, pop
-    -> [StixTree]
-    -> UniqSM Register
-trivialFCode pk _ instrr _ _ [StInd pk' mem, y]
-  = getReg y                       `thenUs` \ register2 ->
-    --getNewRegNCG (registerKind register2)
-    --                                     `thenUs` \ tmp2 ->
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code1 = amodeCode amode
-       src1  = amodeAddr amode
-
-       code__2 dst = let
-                         code2 = registerCode register2 dst
-                         src2  = registerName register2 dst
-                     in asmParThen [code1 asmVoid,code2 asmVoid] .
-                        mkSeqInstrs [instrr (kindToSize pk) (OpAddr src1)]
-    in
-       returnUs (Any pk code__2)
-
-trivialFCode pk instr _ _ _ [x, StInd pk' mem]
-  = getReg x                       `thenUs` \ register1 ->
-    --getNewRegNCG (registerKind register1)
-    --                                     `thenUs` \ tmp1 ->
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code2 = amodeCode amode
-       src2  = amodeAddr amode
-
-       code__2 dst = let
-                         code1 = registerCode register1 dst
-                         src1  = registerName register1 dst
-                     in asmParThen [code2 asmVoid,code1 asmVoid] .
-                        mkSeqInstrs [instr (kindToSize pk) (OpAddr src2)]
-    in
-       returnUs (Any pk code__2)
-
-trivialFCode pk _ _ _ instrpr [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    --getNewRegNCG (registerKind register1)
-    --                                     `thenUs` \ tmp1 ->
-    --getNewRegNCG (registerKind register2)
-    --                                     `thenUs` \ tmp2 ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp ->
-    let
-       pk1   = registerKind register1
-       code1 = registerCode register1 st0 --tmp1
-       src1  = registerName register1 st0 --tmp1
-
-       pk2   = registerKind register2
-
-       code__2 dst = let
-                         code2 = registerCode register2 dst
-                         src2  = registerName register2 dst
-                     in asmParThen [code1 asmVoid, code2 asmVoid] .
-                        mkSeqInstr instrpr
-    in
-       returnUs (Any pk1 code__2)
-
-\end{code}
-
-Trivial unary instructions.  Note that we don't have to worry about
-matching an StInt as the argument, because genericOpt will already
-have handled the constant-folding.
-
-\begin{code}
-
-trivialUCode
-    :: (Operand -> I386Instr)
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialUCode instr [x] =
-    getReg x                       `thenUs` \ register ->
---    getNewRegNCG IntRep          `thenUs` \ tmp ->
-    let
---     fixedname = registerName register eax
-       code__2 dst = let
-                         code = registerCode register dst
-                         src  = registerName register dst
-                     in code . if isFixed register && dst /= src
-                               then mkSeqInstrs [MOV L (OpReg src) (OpReg dst),
-                                                 instr (OpReg dst)]
-                               else mkSeqInstr (instr (OpReg src))
-    in
-       returnUs (Any IntRep code__2)
-
-trivialUFCode
-    :: PrimRep
-    -> I386Instr
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialUFCode pk instr [StInd pk' mem] =
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code = amodeCode amode
-       src  = amodeAddr amode
-       code__2 dst = code . mkSeqInstrs [FLD (kindToSize pk) (OpAddr src),
-                                         instr]
-    in
-       returnUs (Any pk code__2)
-
-trivialUFCode pk instr [x] =
-    getReg x                       `thenUs` \ register ->
-    --getNewRegNCG pk              `thenUs` \ tmp ->
-    let
-       code__2 dst = let
-                         code = registerCode register dst
-                         src  = registerName register dst
-                     in code . mkSeqInstrs [instr]
-    in
-       returnUs (Any pk code__2)
-\end{code}
-
-Absolute value on integers, mostly for gmp size check macros.  Again,
-the argument cannot be an StInt, because genericOpt already folded
-constants.
-
-\begin{code}
-
-absIntCode :: [StixTree] -> UniqSM Register
-absIntCode [x] =
-    getReg x                       `thenUs` \ register ->
-    --getNewRegNCG IntRep          `thenUs` \ reg ->
-    getUniqLabelNCG                        `thenUs` \ lbl ->
-    let
-       code__2 dst = let code = registerCode register dst
-                         src  = registerName register dst
-                     in code . if isFixed register && dst /= src
-                               then mkSeqInstrs [MOV L (OpReg src) (OpReg dst),
-                                                 TEST L (OpReg dst) (OpReg dst),
-                                                 JXX GE lbl,
-                                                 NEGI L (OpReg dst),
-                                                 LABEL lbl]
-                               else mkSeqInstrs [TEST L (OpReg src) (OpReg src),
-                                                 JXX GE lbl,
-                                                 NEGI L (OpReg src),
-                                                 LABEL lbl]
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-Simple integer coercions that don't require any code to be generated.
-Here we just change the type on the register passed on up
-
-\begin{code}
-
-coerceIntCode :: PrimRep -> [StixTree] -> UniqSM Register
-coerceIntCode pk [x] =
-    getReg x                       `thenUs` \ register ->
-    case register of
-       Fixed reg _ code -> returnUs (Fixed reg pk code)
-       Any _ code       -> returnUs (Any pk code)
-
-coerceFltCode :: [StixTree] -> UniqSM Register
-coerceFltCode [x] =
-    getReg x                       `thenUs` \ register ->
-    case register of
-       Fixed reg _ code -> returnUs (Fixed reg DoubleRep code)
-       Any _ code       -> returnUs (Any DoubleRep code)
-
-\end{code}
-
-Integer to character conversion.  We try to do this in one step if
-the original object is in memory.
-
-\begin{code}
-chrCode :: [StixTree] -> UniqSM Register
-{-
-chrCode [StInd pk mem] =
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code = amodeCode amode
-       src  = amodeAddr amode
-       code__2 dst = code . mkSeqInstr (MOVZX L (OpAddr src) (OpReg dst))
-    in
-       returnUs (Any pk code__2)
--}
-chrCode [x] =
-    getReg x                       `thenUs` \ register ->
-    --getNewRegNCG IntRep          `thenUs` \ reg ->
-    let
-       fixedname = registerName register eax
-       code__2 dst = let
-                         code = registerCode register dst
-                         src  = registerName register dst
-                     in code .
-                        if isFixed register && src /= dst
-                        then mkSeqInstrs [MOV L (OpReg src) (OpReg dst),
-                                          AND L (OpImm (ImmInt 255)) (OpReg dst)]
-                        else mkSeqInstr (AND L (OpImm (ImmInt 255)) (OpReg src))
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-More complicated integer/float conversions.  Here we have to store
-temporaries in memory to move between the integer and the floating
-point register sets.
-
-\begin{code}
-coerceInt2FP :: PrimRep -> [StixTree] -> UniqSM Register
-coerceInt2FP pk [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ reg ->
-    let
-       code = registerCode register reg
-       src  = registerName register reg
-
-       code__2 dst = code . mkSeqInstrs [
-       -- to fix: should spill instead of using R1
-                     MOV L (OpReg src) (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1))),
-                     FILD (kindToSize pk) (Addr (Just ebx) Nothing (ImmInt OFFSET_R1)) dst]
-    in
-       returnUs (Any pk code__2)
-
-coerceFP2Int :: [StixTree] -> UniqSM Register
-coerceFP2Int [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src  = registerName register tmp
-       pk   = registerKind register
-
-       code__2 dst = let
-                     in code . mkSeqInstrs [
-                               FRNDINT,
-                               FIST L (Addr (Just ebx) Nothing (ImmInt OFFSET_R1)),
-                               MOV L (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1))) (OpReg dst)]
-    in
-       returnUs (Any IntRep code__2)
-\end{code}
-
-Some random little helpers.
-
-\begin{code}
-
-maybeImm :: StixTree -> Maybe Imm
-maybeImm (StInt i)
-  | i >= toInteger minInt && i <= toInteger maxInt = Just (ImmInt (fromInteger i))
-  | otherwise = Just (ImmInteger i)
-maybeImm (StLitLbl s)  = Just (ImmLit (uppBeside (uppChar '_') s))
-maybeImm (StLitLit s)  = Just (strImmLit (cvtLitLit (_UNPK_ s)))
-maybeImm (StCLbl l) = Just (ImmCLbl l)
-maybeImm _          = Nothing
-
-mangleIndexTree :: StixTree -> StixTree
-
-mangleIndexTree (StIndex pk base (StInt i)) =
-    StPrim IntAddOp [base, off]
-  where
-    off = StInt (i * size pk)
-    size :: PrimRep -> Integer
-    size pk = case kindToSize pk of
-       {B -> 1; S -> 2; L -> 4; F -> 4; D -> 8 }
-
-mangleIndexTree (StIndex pk base off) =
-    case pk of
-       CharRep -> StPrim IntAddOp [base, off]
-       _        -> StPrim IntAddOp [base, off__2]
-  where
-    off__2 = StPrim SllOp [off, StInt (shift pk)]
-    shift :: PrimRep -> Integer
-    shift DoubleRep    = 3
-    shift _            = 2
-
-cvtLitLit :: String -> String
-cvtLitLit "stdin"  = "_IO_stdin_"
-cvtLitLit "stdout" = "_IO_stdout_"
-cvtLitLit "stderr" = "_IO_stderr_"
-cvtLitLit s
-  | isHex s = s
-  | otherwise = error ("Native code generator can't handle ``" ++ s ++ "''")
-  where
-    isHex ('0':'x':xs) = all isHexDigit xs
-    isHex _ = False
-    -- Now, where have I seen this before?
-    isHexDigit c = isDigit c || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'
-
-
-\end{code}
-
-\begin{code}
-
-stackArgLoc = 23 :: Int        -- where to stack call arguments
-
-\end{code}
-
-\begin{code}
-
-getNewRegNCG :: PrimRep -> UniqSM Reg
-getNewRegNCG pk =
-      getUnique          `thenUs` \ u ->
-      returnUs (mkReg u pk)
-
-fixFPCond :: Cond -> Cond
--- on the 486 the flags set by FP compare are the unsigned ones!
-fixFPCond GE  = GEU
-fixFPCond GT  = GU
-fixFPCond LT  = LU
-fixFPCond LE  = LEU
-fixFPCond any = any
-\end{code}
diff --git a/ghc/compiler/nativeGen/MachCode.lhs b/ghc/compiler/nativeGen/MachCode.lhs
new file mode 100644 (file)
index 0000000..25d9be3
--- /dev/null
@@ -0,0 +1,3248 @@
+%
+% (c) The AQUA Project, Glasgow University, 1996
+%
+\section[MachCode]{Generating machine code}
+
+This is a big module, but, if you pay attention to
+(a) the sectioning, (b) the type signatures, and
+(c) the \tr{#if blah_TARGET_ARCH} things, the
+structure should not be too overwhelming.
+
+\begin{code}
+#include "HsVersions.h"
+#include "nativeGen/NCG.h"
+
+module MachCode ( stmt2Instrs, asmVoid, InstrList(..) ) where
+
+import Ubiq{-uitious-}
+
+import MachMisc                -- may differ per-platform
+import MachRegs
+
+import AbsCSyn         ( MagicId )
+import AbsCUtils       ( magicIdPrimRep )
+import CLabel          ( isAsmTemp )
+import Maybes          ( maybeToBool, expectJust )
+import OrdList         -- quite a bit of it
+import Pretty          ( prettyToUn, ppRational )
+import PrimRep         ( isFloatingRep, PrimRep(..) )
+import PrimOp          ( PrimOp(..) )
+import Stix            ( getUniqLabelNCG, StixTree(..),
+                         StixReg(..), CodeSegment(..)
+                       )
+import UniqSupply      ( returnUs, thenUs, mapUs, mapAndUnzipUs,
+                         mapAccumLUs, UniqSM(..)
+                       )
+import Unpretty                ( uppPStr )
+import Util            ( panic, assertPanic )
+\end{code}
+
+Code extractor for an entire stix tree---stix statement level.
+
+\begin{code}
+stmt2Instrs :: StixTree {- a stix statement -} -> UniqSM InstrBlock
+
+stmt2Instrs stmt = case stmt of
+    StComment s    -> returnInstr (COMMENT s)
+    StSegment seg  -> returnInstr (SEGMENT seg)
+    StFunBegin lab -> returnInstr (IF_ARCH_alpha(FUNBEGIN lab,LABEL lab))
+    StFunEnd lab   -> IF_ARCH_alpha(returnInstr (FUNEND lab),returnUs id)
+    StLabel lab           -> returnInstr (LABEL lab)
+
+    StJump arg            -> genJump arg
+    StCondJump lab arg    -> genCondJump lab arg
+    StCall fn VoidRep args -> genCCall fn VoidRep args
+
+    StAssign pk dst src
+      | isFloatingRep pk -> assignFltCode pk dst src
+      | otherwise       -> assignIntCode pk dst src
+
+    StFallThrough lbl
+       -- When falling through on the Alpha, we still have to load pv
+       -- with the address of the next routine, so that it can load gp.
+      -> IF_ARCH_alpha(returnInstr (LDA pv (AddrImm (ImmCLbl lbl)))
+       ,returnUs id)
+
+    StData kind args
+      -> mapAndUnzipUs getData args    `thenUs` \ (codes, imms) ->
+        returnUs (\xs -> mkSeqList (asmInstr (DATA (primRepToSize kind) imms))
+                                   (foldr1 (.) codes xs))
+      where
+       getData :: StixTree -> UniqSM (InstrBlock, Imm)
+
+       getData (StInt i)    = returnUs (id, ImmInteger i)
+       getData (StDouble d) = returnUs (id, dblImmLit d)
+       getData (StLitLbl s) = returnUs (id, ImmLab s)
+       getData (StLitLit s) = returnUs (id, strImmLit (cvtLitLit (_UNPK_ s)))
+       getData (StCLbl l)   = returnUs (id, ImmCLbl l)
+       getData (StString s) =
+           getUniqLabelNCG                 `thenUs` \ lbl ->
+           returnUs (mkSeqInstrs [LABEL lbl,
+                                  ASCII True (_UNPK_ s)],
+                                  ImmCLbl lbl)
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{General things for putting together code sequences}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+type InstrList  = OrdList Instr
+type InstrBlock = InstrList -> InstrList
+
+asmVoid :: InstrList
+asmVoid = mkEmptyList
+
+asmInstr :: Instr -> InstrList
+asmInstr i = mkUnitList i
+
+asmSeq :: [Instr] -> InstrList
+asmSeq is = foldr (mkSeqList . asmInstr) asmVoid is
+
+asmParThen :: [InstrList] -> InstrBlock
+asmParThen others code = mkSeqList (foldr mkParList mkEmptyList others) code
+
+returnInstr :: Instr -> UniqSM InstrBlock
+returnInstr instr = returnUs (\xs -> mkSeqList (asmInstr instr) xs)
+
+returnInstrs :: [Instr] -> UniqSM InstrBlock
+returnInstrs instrs = returnUs (\xs -> mkSeqList (asmSeq instrs) xs)
+
+returnSeq :: InstrBlock -> [Instr] -> UniqSM InstrBlock
+returnSeq code instrs = returnUs (\xs -> code (mkSeqList (asmSeq instrs) xs))
+
+mkSeqInstr :: Instr -> InstrBlock
+mkSeqInstr instr code = mkSeqList (asmInstr instr) code
+
+mkSeqInstrs :: [Instr] -> InstrBlock
+mkSeqInstrs instrs code = mkSeqList (asmSeq instrs) code
+\end{code}
+
+\begin{code}
+mangleIndexTree :: StixTree -> StixTree
+
+mangleIndexTree (StIndex pk base (StInt i))
+  = StPrim IntAddOp [base, off]
+  where
+    off = StInt (i * sizeOf pk)
+
+mangleIndexTree (StIndex pk base off)
+  = StPrim IntAddOp [base,
+      case pk of
+       CharRep -> off
+       _       -> let
+                       s = shift pk
+                  in
+                  ASSERT(toInteger s == expectJust "MachCode" (exactLog2 (sizeOf pk)))
+                  StPrim SllOp [off, StInt s]
+    ]
+  where
+    shift DoubleRep    = 3
+    shift _            = IF_ARCH_alpha(3,2)
+\end{code}
+
+\begin{code}
+maybeImm :: StixTree -> Maybe Imm
+
+maybeImm (StLitLbl s) = Just (ImmLab s)
+maybeImm (StLitLit s) = Just (strImmLit (cvtLitLit (_UNPK_ s)))
+maybeImm (StCLbl   l) = Just (ImmCLbl l)
+
+maybeImm (StInt i)
+  | i >= toInteger minInt && i <= toInteger maxInt
+  = Just (ImmInt (fromInteger i))
+  | otherwise
+  = Just (ImmInteger i)
+
+maybeImm _ = Nothing
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{The @Register@ type}
+%*                                                                     *
+%************************************************************************
+
+@Register@s passed up the tree.  If the stix code forces the register
+to live in a pre-decided machine register, it comes out as @Fixed@;
+otherwise, it comes out as @Any@, and the parent can decide which
+register to put it in.
+
+\begin{code}
+data Register
+  = Fixed   PrimRep Reg InstrBlock
+  | Any            PrimRep (Reg -> InstrBlock)
+
+registerCode :: Register -> Reg -> InstrBlock
+registerCode (Fixed _ _ code) reg = code
+registerCode (Any _ code) reg = code reg
+
+registerName :: Register -> Reg -> Reg
+registerName (Fixed _ reg _) _ = reg
+registerName (Any   _ _)   reg = reg
+
+registerRep :: Register -> PrimRep
+registerRep (Fixed pk _ _) = pk
+registerRep (Any   pk _) = pk
+
+isFixed :: Register -> Bool
+isFixed (Fixed _ _ _) = True
+isFixed (Any _ _)     = False
+\end{code}
+
+Generate code to get a subtree into a @Register@:
+\begin{code}
+getRegister :: StixTree -> UniqSM Register
+
+getRegister (StReg (StixMagicId stgreg))
+  = case (magicIdRegMaybe stgreg) of
+      Just reg -> returnUs (Fixed (magicIdPrimRep stgreg) reg id)
+      -- cannae be Nothing
+
+getRegister (StReg (StixTemp u pk))
+  = returnUs (Fixed pk (UnmappedReg u pk) id)
+
+getRegister tree@(StIndex _ _ _) = getRegister (mangleIndexTree tree)
+
+getRegister (StCall fn kind args)
+  = genCCall fn kind args          `thenUs` \ call ->
+    returnUs (Fixed kind reg call)
+  where
+    reg = if isFloatingRep kind
+         then IF_ARCH_alpha( f0, IF_ARCH_i386( st0, IF_ARCH_sparc( f0,)))
+         else IF_ARCH_alpha( v0, IF_ARCH_i386( eax, IF_ARCH_sparc( o0,)))
+
+getRegister (StString s)
+  = getUniqLabelNCG                `thenUs` \ lbl ->
+    let
+       imm_lbl = ImmCLbl lbl
+
+       code dst = mkSeqInstrs [
+           SEGMENT DataSegment,
+           LABEL lbl,
+           ASCII True (_UNPK_ s),
+           SEGMENT TextSegment,
+#if alpha_TARGET_ARCH
+           LDA dst (AddrImm imm_lbl)
+#endif
+#if i386_TARGET_ARCH
+           MOV L (OpImm imm_lbl) (OpReg dst)
+#endif
+#if sparc_TARGET_ARCH
+           SETHI (HI imm_lbl) dst,
+           OR False dst (RIImm (LO imm_lbl)) dst
+#endif
+           ]
+    in
+    returnUs (Any PtrRep code)
+
+getRegister (StLitLit s) | _HEAD_ s == '"' && last xs == '"'
+  = getUniqLabelNCG                `thenUs` \ lbl ->
+    let 
+       imm_lbl = ImmCLbl lbl
+
+       code dst = mkSeqInstrs [
+           SEGMENT DataSegment,
+           LABEL lbl,
+           ASCII False (init xs),
+           SEGMENT TextSegment,
+#if alpha_TARGET_ARCH
+           LDA dst (AddrImm imm_lbl)
+#endif
+#if i386_TARGET_ARCH
+           MOV L (OpImm imm_lbl) (OpReg dst)
+#endif
+#if sparc_TARGET_ARCH
+           SETHI (HI imm_lbl) dst,
+           OR False dst (RIImm (LO imm_lbl)) dst
+#endif
+           ]
+    in
+    returnUs (Any PtrRep code)
+  where
+    xs = _UNPK_ (_TAIL_ s)
+
+-- end of machine-"independent" bit; here we go on the rest...
+
+#if alpha_TARGET_ARCH
+
+getRegister (StDouble d)
+  = getUniqLabelNCG                `thenUs` \ lbl ->
+    getNewRegNCG PtrRep            `thenUs` \ tmp ->
+    let code dst = mkSeqInstrs [
+           SEGMENT DataSegment,
+           LABEL lbl,
+           DATA TF [ImmLab (prettyToUn (ppRational d))],
+           SEGMENT TextSegment,
+           LDA tmp (AddrImm (ImmCLbl lbl)),
+           LD TF dst (AddrReg tmp)]
+    in
+       returnUs (Any DoubleRep code)
+
+getRegister (StPrim primop [x]) -- unary PrimOps
+  = case primop of
+      IntNegOp -> trivialUCode (NEG Q False) x
+      IntAbsOp -> trivialUCode (ABS Q) x
+
+      NotOp    -> trivialUCode NOT x
+
+      FloatNegOp  -> trivialUFCode FloatRep  (FNEG TF) x
+      DoubleNegOp -> trivialUFCode DoubleRep (FNEG TF) x
+
+      OrdOp -> coerceIntCode IntRep x
+      ChrOp -> chrCode x
+
+      Float2IntOp  -> coerceFP2Int    x
+      Int2FloatOp  -> coerceInt2FP pr x
+      Double2IntOp -> coerceFP2Int    x
+      Int2DoubleOp -> coerceInt2FP pr x
+
+      Double2FloatOp -> coerceFltCode x
+      Float2DoubleOp -> coerceFltCode x
+
+      other_op -> getRegister (StCall fn DoubleRep [x])
+       where
+         fn = case other_op of
+                FloatExpOp    -> SLIT("exp")
+                FloatLogOp    -> SLIT("log")
+                FloatSqrtOp   -> SLIT("sqrt")
+                FloatSinOp    -> SLIT("sin")
+                FloatCosOp    -> SLIT("cos")
+                FloatTanOp    -> SLIT("tan")
+                FloatAsinOp   -> SLIT("asin")
+                FloatAcosOp   -> SLIT("acos")
+                FloatAtanOp   -> SLIT("atan")
+                FloatSinhOp   -> SLIT("sinh")
+                FloatCoshOp   -> SLIT("cosh")
+                FloatTanhOp   -> SLIT("tanh")
+                DoubleExpOp   -> SLIT("exp")
+                DoubleLogOp   -> SLIT("log")
+                DoubleSqrtOp  -> SLIT("sqrt")
+                DoubleSinOp   -> SLIT("sin")
+                DoubleCosOp   -> SLIT("cos")
+                DoubleTanOp   -> SLIT("tan")
+                DoubleAsinOp  -> SLIT("asin")
+                DoubleAcosOp  -> SLIT("acos")
+                DoubleAtanOp  -> SLIT("atan")
+                DoubleSinhOp  -> SLIT("sinh")
+                DoubleCoshOp  -> SLIT("cosh")
+                DoubleTanhOp  -> SLIT("tanh")
+  where
+    pr = panic "MachCode.getRegister: no primrep needed for Alpha"
+
+getRegister (StPrim primop [x, y]) -- dyadic PrimOps
+  = case primop of
+      CharGtOp -> trivialCode (CMP LT) y x
+      CharGeOp -> trivialCode (CMP LE) y x
+      CharEqOp -> trivialCode (CMP EQ) x y
+      CharNeOp -> int_NE_code x y
+      CharLtOp -> trivialCode (CMP LT) x y
+      CharLeOp -> trivialCode (CMP LE) x y
+
+      IntGtOp  -> trivialCode (CMP LT) y x
+      IntGeOp  -> trivialCode (CMP LE) y x
+      IntEqOp  -> trivialCode (CMP EQ) x y
+      IntNeOp  -> int_NE_code x y
+      IntLtOp  -> trivialCode (CMP LT) x y
+      IntLeOp  -> trivialCode (CMP LE) x y
+
+      WordGtOp -> trivialCode (CMP ULT) y x
+      WordGeOp -> trivialCode (CMP ULE) x y
+      WordEqOp -> trivialCode (CMP EQ)  x y
+      WordNeOp -> int_NE_code x y
+      WordLtOp -> trivialCode (CMP ULT) x y
+      WordLeOp -> trivialCode (CMP ULE) x y
+
+      AddrGtOp -> trivialCode (CMP ULT) y x
+      AddrGeOp -> trivialCode (CMP ULE) y x
+      AddrEqOp -> trivialCode (CMP EQ)  x y
+      AddrNeOp -> int_NE_code x y
+      AddrLtOp -> trivialCode (CMP ULT) x y
+      AddrLeOp -> trivialCode (CMP ULE) x y
+
+      FloatGtOp -> cmpF_code (FCMP TF LE) EQ x y
+      FloatGeOp -> cmpF_code (FCMP TF LT) EQ x y
+      FloatEqOp -> cmpF_code (FCMP TF EQ) NE x y
+      FloatNeOp -> cmpF_code (FCMP TF EQ) EQ x y
+      FloatLtOp -> cmpF_code (FCMP TF LT) NE x y
+      FloatLeOp -> cmpF_code (FCMP TF LE) NE x y
+
+      DoubleGtOp -> cmpF_code (FCMP TF LE) EQ x y
+      DoubleGeOp -> cmpF_code (FCMP TF LT) EQ x y
+      DoubleEqOp -> cmpF_code (FCMP TF EQ) NE x y
+      DoubleNeOp -> cmpF_code (FCMP TF EQ) EQ x y
+      DoubleLtOp -> cmpF_code (FCMP TF LT) NE x y
+      DoubleLeOp -> cmpF_code (FCMP TF LE) NE x y
+
+      IntAddOp  -> trivialCode (ADD Q False) x y
+      IntSubOp  -> trivialCode (SUB Q False) x y
+      IntMulOp  -> trivialCode (MUL Q False) x y
+      IntQuotOp -> trivialCode (DIV Q False) x y
+      IntRemOp  -> trivialCode (REM Q False) x y
+
+      FloatAddOp -> trivialFCode  FloatRep (FADD TF) x y
+      FloatSubOp -> trivialFCode  FloatRep (FSUB TF) x y
+      FloatMulOp -> trivialFCode  FloatRep (FMUL TF) x y
+      FloatDivOp -> trivialFCode  FloatRep (FDIV TF) x y
+
+      DoubleAddOp -> trivialFCode  DoubleRep (FADD TF) x y
+      DoubleSubOp -> trivialFCode  DoubleRep (FSUB TF) x y
+      DoubleMulOp -> trivialFCode  DoubleRep (FMUL TF) x y
+      DoubleDivOp -> trivialFCode  DoubleRep (FDIV TF) x y
+
+      AndOp  -> trivialCode AND x y
+      OrOp   -> trivialCode OR  x y
+      SllOp  -> trivialCode SLL x y
+      SraOp  -> trivialCode SRA x y
+      SrlOp  -> trivialCode SRL x y
+
+      ISllOp -> panic "AlphaGen:isll"
+      ISraOp -> panic "AlphaGen:isra"
+      ISrlOp -> panic "AlphaGen:isrl"
+
+      FloatPowerOp  -> getRegister (StCall SLIT("pow") DoubleRep [x,y])
+      DoublePowerOp -> getRegister (StCall SLIT("pow") DoubleRep [x,y])
+  where
+    {- ------------------------------------------------------------
+       Some bizarre special code for getting condition codes into
+       registers.  Integer non-equality is a test for equality
+       followed by an XOR with 1.  (Integer comparisons always set
+       the result register to 0 or 1.)  Floating point comparisons of
+       any kind leave the result in a floating point register, so we
+       need to wrangle an integer register out of things.
+    -}
+    int_NE_code :: StixTree -> StixTree -> UniqSM Register
+
+    int_NE_code x y
+      = trivialCode (CMP EQ) x y       `thenUs` \ register ->
+       getNewRegNCG IntRep             `thenUs` \ tmp ->
+       let
+           code = registerCode register tmp
+           src  = registerName register tmp
+           code__2 dst = code . mkSeqInstr (XOR src (RIImm (ImmInt 1)) dst)
+       in
+       returnUs (Any IntRep code__2)
+
+    {- ------------------------------------------------------------
+       Comments for int_NE_code also apply to cmpF_code
+    -}
+    cmpF_code
+       :: (Reg -> Reg -> Reg -> Instr)
+       -> Cond
+       -> StixTree -> StixTree
+       -> UniqSM Register
+
+    cmpF_code instr cond x y
+      = trivialFCode pr instr x y      `thenUs` \ register ->
+       getNewRegNCG DoubleRep          `thenUs` \ tmp ->
+       getUniqLabelNCG                 `thenUs` \ lbl ->
+       let
+           code = registerCode register tmp
+           result  = registerName register tmp
+
+           code__2 dst = code . mkSeqInstrs [
+               OR zero (RIImm (ImmInt 1)) dst,
+               BF cond result (ImmCLbl lbl),
+               OR zero (RIReg zero) dst,
+               LABEL lbl]
+       in
+       returnUs (Any IntRep code__2)
+      where
+       pr = panic "trivialU?FCode: does not use PrimRep on Alpha"
+      ------------------------------------------------------------
+
+getRegister (StInd pk mem)
+  = getAmode mem                   `thenUs` \ amode ->
+    let
+       code = amodeCode amode
+       src   = amodeAddr amode
+       size = primRepToSize pk
+       code__2 dst = code . mkSeqInstr (LD size dst src)
+    in
+    returnUs (Any pk code__2)
+
+getRegister (StInt i)
+  | fits8Bits i
+  = let
+       code dst = mkSeqInstr (OR zero (RIImm src) dst)
+    in
+    returnUs (Any IntRep code)
+  | otherwise
+  = let
+       code dst = mkSeqInstr (LDI Q dst src)
+    in
+    returnUs (Any IntRep code)
+  where
+    src = ImmInt (fromInteger i)
+
+getRegister leaf
+  | maybeToBool imm
+  = let
+       code dst = mkSeqInstr (LDA dst (AddrImm imm__2))
+    in
+    returnUs (Any PtrRep code)
+  where
+    imm = maybeImm leaf
+    imm__2 = case imm of Just x -> x
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+getRegister (StReg (StixTemp u pk)) = returnUs (Fixed pk (UnmappedReg u pk) id)
+
+getRegister (StDouble 0.0)
+  = let
+       code dst = mkSeqInstrs [FLDZ]
+    in
+    returnUs (Any DoubleRep code)
+
+getRegister (StDouble 1.0)
+  = let
+       code dst = mkSeqInstrs [FLD1]
+    in
+    returnUs (Any DoubleRep code)
+
+getRegister (StDouble d)
+  = getUniqLabelNCG                `thenUs` \ lbl ->
+    --getNewRegNCG PtrRep          `thenUs` \ tmp ->
+    let code dst = mkSeqInstrs [
+           SEGMENT DataSegment,
+           LABEL lbl,
+           DATA DF [dblImmLit d],
+           SEGMENT TextSegment,
+           FLD DF (OpImm (ImmCLbl lbl))
+           ]
+    in
+    returnUs (Any DoubleRep code)
+
+getRegister (StPrim primop [x]) -- unary PrimOps
+  = case primop of
+      IntNegOp  -> trivialUCode (NEGI L) x
+      IntAbsOp  -> absIntCode x
+
+      NotOp    -> trivialUCode (NOT L) x
+
+      FloatNegOp  -> trivialUFCode FloatRep FCHS x
+      FloatSqrtOp -> trivialUFCode FloatRep FSQRT x
+      DoubleNegOp -> trivialUFCode DoubleRep FCHS x
+
+      DoubleSqrtOp -> trivialUFCode DoubleRep FSQRT x
+
+      OrdOp -> coerceIntCode IntRep x
+      ChrOp -> chrCode x
+
+      Float2IntOp  -> coerceFP2Int x
+      Int2FloatOp  -> coerceInt2FP FloatRep x
+      Double2IntOp -> coerceFP2Int x
+      Int2DoubleOp -> coerceInt2FP DoubleRep x
+
+      Double2FloatOp -> coerceFltCode x
+      Float2DoubleOp -> coerceFltCode x
+
+      other_op ->
+        let
+           fixed_x = if is_float_op  -- promote to double
+                         then StPrim Float2DoubleOp [x]
+                         else x
+       in
+       getRegister (StCall fn DoubleRep [x])
+       where
+       (is_float_op, fn)
+         = case primop of
+             FloatExpOp    -> (True,  SLIT("exp"))
+             FloatLogOp    -> (True,  SLIT("log"))
+
+             FloatSinOp    -> (True,  SLIT("sin"))
+             FloatCosOp    -> (True,  SLIT("cos"))
+             FloatTanOp    -> (True,  SLIT("tan"))
+
+             FloatAsinOp   -> (True,  SLIT("asin"))
+             FloatAcosOp   -> (True,  SLIT("acos"))
+             FloatAtanOp   -> (True,  SLIT("atan"))
+
+             FloatSinhOp   -> (True,  SLIT("sinh"))
+             FloatCoshOp   -> (True,  SLIT("cosh"))
+             FloatTanhOp   -> (True,  SLIT("tanh"))
+
+             DoubleExpOp   -> (False, SLIT("exp"))
+             DoubleLogOp   -> (False, SLIT("log"))
+
+             DoubleSinOp   -> (False, SLIT("sin"))
+             DoubleCosOp   -> (False, SLIT("cos"))
+             DoubleTanOp   -> (False, SLIT("tan"))
+
+             DoubleAsinOp  -> (False, SLIT("asin"))
+             DoubleAcosOp  -> (False, SLIT("acos"))
+             DoubleAtanOp  -> (False, SLIT("atan"))
+
+             DoubleSinhOp  -> (False, SLIT("sinh"))
+             DoubleCoshOp  -> (False, SLIT("cosh"))
+             DoubleTanhOp  -> (False, SLIT("tanh"))
+
+getRegister (StPrim primop [x, y]) -- dyadic PrimOps
+  = case primop of
+      CharGtOp -> condIntReg GT x y
+      CharGeOp -> condIntReg GE x y
+      CharEqOp -> condIntReg EQ x y
+      CharNeOp -> condIntReg NE x y
+      CharLtOp -> condIntReg LT x y
+      CharLeOp -> condIntReg LE x y
+
+      IntGtOp  -> condIntReg GT x y
+      IntGeOp  -> condIntReg GE x y
+      IntEqOp  -> condIntReg EQ x y
+      IntNeOp  -> condIntReg NE x y
+      IntLtOp  -> condIntReg LT x y
+      IntLeOp  -> condIntReg LE x y
+
+      WordGtOp -> condIntReg GU  x y
+      WordGeOp -> condIntReg GEU x y
+      WordEqOp -> condIntReg EQ  x y
+      WordNeOp -> condIntReg NE  x y
+      WordLtOp -> condIntReg LU  x y
+      WordLeOp -> condIntReg LEU x y
+
+      AddrGtOp -> condIntReg GU  x y
+      AddrGeOp -> condIntReg GEU x y
+      AddrEqOp -> condIntReg EQ  x y
+      AddrNeOp -> condIntReg NE  x y
+      AddrLtOp -> condIntReg LU  x y
+      AddrLeOp -> condIntReg LEU x y
+
+      FloatGtOp -> condFltReg GT x y
+      FloatGeOp -> condFltReg GE x y
+      FloatEqOp -> condFltReg EQ x y
+      FloatNeOp -> condFltReg NE x y
+      FloatLtOp -> condFltReg LT x y
+      FloatLeOp -> condFltReg LE x y
+
+      DoubleGtOp -> condFltReg GT x y
+      DoubleGeOp -> condFltReg GE x y
+      DoubleEqOp -> condFltReg EQ x y
+      DoubleNeOp -> condFltReg NE x y
+      DoubleLtOp -> condFltReg LT x y
+      DoubleLeOp -> condFltReg LE x y
+
+      IntAddOp  -> {- ToDo: fix this, whatever it is (WDP 96/04)...
+                  -- this should be optimised by the generic Opts,
+                  -- I don't know why it is not (sometimes)!
+                  case args of
+                   [x, StInt 0] -> getRegister x
+                   _ -> add_code L x y
+                  -}
+                  add_code  L x y
+
+      IntSubOp  -> sub_code  L x y
+      IntQuotOp -> quot_code L x y True{-division-}
+      IntRemOp  -> quot_code L x y False{-remainder-}
+      IntMulOp  -> trivialCode (IMUL L) x y {-True-}
+
+      FloatAddOp -> trivialFCode  FloatRep  FADD FADD  FADDP FADDP  x y
+      FloatSubOp -> trivialFCode  FloatRep  FSUB FSUBR FSUBP FSUBRP x y
+      FloatMulOp -> trivialFCode  FloatRep  FMUL FMUL  FMULP FMULP  x y
+      FloatDivOp -> trivialFCode  FloatRep  FDIV FDIVR FDIVP FDIVRP x y
+
+      DoubleAddOp -> trivialFCode DoubleRep FADD FADD  FADDP FADDP  x y
+      DoubleSubOp -> trivialFCode DoubleRep FSUB FSUBR FSUBP FSUBRP x y
+      DoubleMulOp -> trivialFCode DoubleRep FMUL FMUL  FMULP FMULP  x y
+      DoubleDivOp -> trivialFCode DoubleRep FDIV FDIVR FDIVP FDIVRP x y
+
+      AndOp -> trivialCode (AND L) x y {-True-}
+      OrOp  -> trivialCode (OR L)  x y {-True-}
+      SllOp -> trivialCode (SHL L) x y {-False-}
+      SraOp -> trivialCode (SAR L) x y {-False-}
+      SrlOp -> trivialCode (SHR L) x y {-False-}
+
+      ISllOp -> panic "I386Gen:isll"
+      ISraOp -> panic "I386Gen:isra"
+      ISrlOp -> panic "I386Gen:isrl"
+
+      FloatPowerOp  -> getRegister (StCall SLIT("pow") DoubleRep [promote x, promote y])
+                      where promote x = StPrim Float2DoubleOp [x]
+      DoublePowerOp -> getRegister (StCall SLIT("pow") DoubleRep [x, y])
+  where
+    add_code :: Size -> StixTree -> StixTree -> UniqSM Register
+
+    add_code sz x (StInt y)
+      = getRegister x          `thenUs` \ register ->
+       getNewRegNCG IntRep     `thenUs` \ tmp ->
+       let
+           code = registerCode register tmp
+           src1 = registerName register tmp
+           src2 = ImmInt (fromInteger y)
+           code__2 dst = code .
+                         mkSeqInstr (LEA sz (OpAddr (Addr (Just src1) Nothing src2)) (OpReg dst))
+       in
+       returnUs (Any IntRep code__2)
+
+    add_code sz x (StInd _ mem)
+      = getRegister x          `thenUs` \ register1 ->
+       --getNewRegNCG (registerRep register1)
+       --                      `thenUs` \ tmp1 ->
+       getAmode mem            `thenUs` \ amode ->
+       let
+           code2 = amodeCode amode
+           src2  = amodeAddr amode
+
+           fixedname  = registerName register1 eax
+           code__2 dst = let code1 = registerCode register1 dst
+                             src1  = registerName register1 dst
+                         in asmParThen [code2 asmVoid,code1 asmVoid] .
+                            if isFixed register1 && src1 /= dst
+                            then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
+                                              ADD sz (OpAddr src2)  (OpReg dst)]
+                            else
+                                   mkSeqInstrs [ADD sz (OpAddr src2) (OpReg src1)]
+       in
+       returnUs (Any IntRep code__2)
+
+    add_code sz (StInd _ mem) y
+      = getRegister y          `thenUs` \ register2 ->
+       --getNewRegNCG (registerRep register2)
+       --                      `thenUs` \ tmp2 ->
+       getAmode mem            `thenUs` \ amode ->
+       let
+           code1 = amodeCode amode
+           src1  = amodeAddr amode
+
+           fixedname  = registerName register2 eax
+           code__2 dst = let code2 = registerCode register2 dst
+                             src2  = registerName register2 dst
+                         in asmParThen [code1 asmVoid,code2 asmVoid] .
+                            if isFixed register2 && src2 /= dst
+                            then mkSeqInstrs [MOV L (OpReg src2) (OpReg dst),
+                                              ADD sz (OpAddr src1)  (OpReg dst)]
+                            else
+                                   mkSeqInstrs [ADD sz (OpAddr src1) (OpReg src2)]
+       in
+       returnUs (Any IntRep code__2)
+
+    add_code sz x y
+      = getRegister x          `thenUs` \ register1 ->
+       getRegister y           `thenUs` \ register2 ->
+       getNewRegNCG IntRep     `thenUs` \ tmp1 ->
+       getNewRegNCG IntRep     `thenUs` \ tmp2 ->
+       let
+           code1 = registerCode register1 tmp1 asmVoid
+           src1  = registerName register1 tmp1
+           code2 = registerCode register2 tmp2 asmVoid
+           src2  = registerName register2 tmp2
+           code__2 dst = asmParThen [code1, code2] .
+                         mkSeqInstr (LEA sz (OpAddr (Addr (Just src1) (Just (src2,1)) (ImmInt 0))) (OpReg dst))
+       in
+       returnUs (Any IntRep code__2)
+
+    --------------------
+    sub_code :: Size -> StixTree -> StixTree -> UniqSM Register
+
+    sub_code sz x (StInt y)
+      = getRegister x          `thenUs` \ register ->
+       getNewRegNCG IntRep     `thenUs` \ tmp ->
+       let
+           code = registerCode register tmp
+           src1 = registerName register tmp
+           src2 = ImmInt (-(fromInteger y))
+           code__2 dst = code .
+                         mkSeqInstr (LEA sz (OpAddr (Addr (Just src1) Nothing src2)) (OpReg dst))
+       in
+       returnUs (Any IntRep code__2)
+
+    sub_code sz x y = trivialCode (SUB sz) x y {-False-}
+
+    --------------------
+    quot_code
+       :: Size
+       -> StixTree -> StixTree
+       -> Bool -- True => division, False => remainder operation
+       -> UniqSM Register
+
+    -- x must go into eax, edx must be a sign-extension of eax, and y
+    -- should go in some other register (or memory), so that we get
+    -- edx:eax / reg -> eax (remainder in edx) Currently we chose to
+    -- put y in memory (if it is not there already)
+
+    quot_code sz x (StInd pk mem) is_division
+      = getRegister x          `thenUs` \ register1 ->
+       getNewRegNCG IntRep     `thenUs` \ tmp1 ->
+       getAmode mem            `thenUs` \ amode ->
+       let
+           code1   = registerCode register1 tmp1 asmVoid
+           src1    = registerName register1 tmp1
+           code2   = amodeCode amode asmVoid
+           src2    = amodeAddr amode
+           code__2 = asmParThen [code1, code2] .
+                     mkSeqInstrs [MOV L (OpReg src1) (OpReg eax),
+                                  CLTD,
+                                  IDIV sz (OpAddr src2)]
+       in
+       returnUs (Fixed IntRep (if is_division then eax else edx) code__2)
+
+    quot_code sz x (StInt i) is_division
+      = getRegister x          `thenUs` \ register1 ->
+       getNewRegNCG IntRep     `thenUs` \ tmp1 ->
+       let
+           code1   = registerCode register1 tmp1 asmVoid
+           src1    = registerName register1 tmp1
+           src2    = ImmInt (fromInteger i)
+           code__2 = asmParThen [code1] .
+                     mkSeqInstrs [-- we put src2 in (ebx)
+                                  MOV L (OpImm src2) (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1))),
+                                  MOV L (OpReg src1) (OpReg eax),
+                                  CLTD,
+                                  IDIV sz (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1)))]
+       in
+       returnUs (Fixed IntRep (if is_division then eax else edx) code__2)
+
+    quot_code sz x y is_division
+      = getRegister x          `thenUs` \ register1 ->
+       getNewRegNCG IntRep     `thenUs` \ tmp1 ->
+       getRegister y           `thenUs` \ register2 ->
+       getNewRegNCG IntRep     `thenUs` \ tmp2 ->
+       let
+           code1   = registerCode register1 tmp1 asmVoid
+           src1    = registerName register1 tmp1
+           code2   = registerCode register2 tmp2 asmVoid
+           src2    = registerName register2 tmp2
+           code__2 = asmParThen [code1, code2] .
+                     if src2 == ecx || src2 == esi
+                     then mkSeqInstrs [ MOV L (OpReg src1) (OpReg eax),
+                                        CLTD,
+                                        IDIV sz (OpReg src2)]
+                     else mkSeqInstrs [ -- we put src2 in (ebx)
+                                        MOV L (OpReg src2) (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1))),
+                                        MOV L (OpReg src1) (OpReg eax),
+                                        CLTD,
+                                        IDIV sz (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1)))]
+       in
+       returnUs (Fixed IntRep (if is_division then eax else edx) code__2)
+       -----------------------
+
+getRegister (StInd pk mem)
+  = getAmode mem                   `thenUs` \ amode ->
+    let
+       code = amodeCode amode
+       src   = amodeAddr amode
+       size = primRepToSize pk
+       code__2 dst = code .
+                     if pk == DoubleRep || pk == FloatRep
+                     then mkSeqInstr (FLD {-DF-} size (OpAddr src))
+                     else mkSeqInstr (MOV size (OpAddr src) (OpReg dst))
+    in
+       returnUs (Any pk code__2)
+
+
+getRegister (StInt i)
+  = let
+       src = ImmInt (fromInteger i)
+       code dst = mkSeqInstr (MOV L (OpImm src) (OpReg dst))
+    in
+       returnUs (Any IntRep code)
+
+getRegister leaf
+  | maybeToBool imm
+  = let
+       code dst = mkSeqInstr (MOV L (OpImm imm__2) (OpReg dst))
+    in
+       returnUs (Any PtrRep code)
+  where
+    imm = maybeImm leaf
+    imm__2 = case imm of Just x -> x
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+getRegister (StDouble d)
+  = getUniqLabelNCG                `thenUs` \ lbl ->
+    getNewRegNCG PtrRep            `thenUs` \ tmp ->
+    let code dst = mkSeqInstrs [
+           SEGMENT DataSegment,
+           LABEL lbl,
+           DATA DF [dblImmLit d],
+           SEGMENT TextSegment,
+           SETHI (HI (ImmCLbl lbl)) tmp,
+           LD DF (AddrRegImm tmp (LO (ImmCLbl lbl))) dst]
+    in
+       returnUs (Any DoubleRep code)
+
+getRegister (StPrim primop [x]) -- unary PrimOps
+  = case primop of
+      IntNegOp -> trivialUCode (SUB False False g0) x
+      IntAbsOp -> absIntCode x
+
+      NotOp    -> trivialUCode (XNOR False g0) x
+
+      FloatNegOp  -> trivialUFCode FloatRep (FNEG F) x
+      DoubleNegOp -> trivialUFCode DoubleRep (FNEG DF) x
+
+      Double2FloatOp -> trivialUFCode FloatRep  (FxTOy DF F) x
+      Float2DoubleOp -> trivialUFCode DoubleRep (FxTOy F DF) x
+
+      OrdOp -> coerceIntCode IntRep x
+      ChrOp -> chrCode x
+
+      Float2IntOp  -> coerceFP2Int x
+      Int2FloatOp  -> coerceInt2FP FloatRep x
+      Double2IntOp -> coerceFP2Int x
+      Int2DoubleOp -> coerceInt2FP DoubleRep x
+
+      other_op ->
+        let
+           fixed_x = if is_float_op  -- promote to double
+                         then StPrim Float2DoubleOp [x]
+                         else x
+       in
+       getRegister (StCall fn DoubleRep [x])
+       where
+       (is_float_op, fn)
+         = case primop of
+             FloatExpOp    -> (True,  SLIT("exp"))
+             FloatLogOp    -> (True,  SLIT("log"))
+
+             FloatSinOp    -> (True,  SLIT("sin"))
+             FloatCosOp    -> (True,  SLIT("cos"))
+             FloatTanOp    -> (True,  SLIT("tan"))
+
+             FloatAsinOp   -> (True,  SLIT("asin"))
+             FloatAcosOp   -> (True,  SLIT("acos"))
+             FloatAtanOp   -> (True,  SLIT("atan"))
+
+             FloatSinhOp   -> (True,  SLIT("sinh"))
+             FloatCoshOp   -> (True,  SLIT("cosh"))
+             FloatTanhOp   -> (True,  SLIT("tanh"))
+
+             DoubleExpOp   -> (False, SLIT("exp"))
+             DoubleLogOp   -> (False, SLIT("log"))
+
+             DoubleSinOp   -> (False, SLIT("sin"))
+             DoubleCosOp   -> (False, SLIT("cos"))
+             DoubleTanOp   -> (False, SLIT("tan"))
+
+             DoubleAsinOp  -> (False, SLIT("asin"))
+             DoubleAcosOp  -> (False, SLIT("acos"))
+             DoubleAtanOp  -> (False, SLIT("atan"))
+
+             DoubleSinhOp  -> (False, SLIT("sinh"))
+             DoubleCoshOp  -> (False, SLIT("cosh"))
+             DoubleTanhOp  -> (False, SLIT("tanh"))
+
+getRegister (StPrim primop [x, y]) -- dyadic PrimOps
+  = case primop of
+      CharGtOp -> condIntReg GT x y
+      CharGeOp -> condIntReg GE x y
+      CharEqOp -> condIntReg EQ x y
+      CharNeOp -> condIntReg NE x y
+      CharLtOp -> condIntReg LT x y
+      CharLeOp -> condIntReg LE x y
+
+      IntGtOp  -> condIntReg GT x y
+      IntGeOp  -> condIntReg GE x y
+      IntEqOp  -> condIntReg EQ x y
+      IntNeOp  -> condIntReg NE x y
+      IntLtOp  -> condIntReg LT x y
+      IntLeOp  -> condIntReg LE x y
+
+      WordGtOp -> condIntReg GU  x y
+      WordGeOp -> condIntReg GEU x y
+      WordEqOp -> condIntReg EQ  x y
+      WordNeOp -> condIntReg NE  x y
+      WordLtOp -> condIntReg LU  x y
+      WordLeOp -> condIntReg LEU x y
+
+      AddrGtOp -> condIntReg GU  x y
+      AddrGeOp -> condIntReg GEU x y
+      AddrEqOp -> condIntReg EQ  x y
+      AddrNeOp -> condIntReg NE  x y
+      AddrLtOp -> condIntReg LU  x y
+      AddrLeOp -> condIntReg LEU x y
+
+      FloatGtOp -> condFltReg GT x y
+      FloatGeOp -> condFltReg GE x y
+      FloatEqOp -> condFltReg EQ x y
+      FloatNeOp -> condFltReg NE x y
+      FloatLtOp -> condFltReg LT x y
+      FloatLeOp -> condFltReg LE x y
+
+      DoubleGtOp -> condFltReg GT x y
+      DoubleGeOp -> condFltReg GE x y
+      DoubleEqOp -> condFltReg EQ x y
+      DoubleNeOp -> condFltReg NE x y
+      DoubleLtOp -> condFltReg LT x y
+      DoubleLeOp -> condFltReg LE x y
+
+      IntAddOp -> trivialCode (ADD False False) x y
+      IntSubOp -> trivialCode (SUB False False) x y
+
+       -- ToDo: teach about V8+ SPARC mul/div instructions
+      IntMulOp    -> imul_div SLIT(".umul") x y
+      IntQuotOp   -> imul_div SLIT(".div")  x y
+      IntRemOp    -> imul_div SLIT(".rem")  x y
+
+      FloatAddOp  -> trivialFCode FloatRep  FADD x y
+      FloatSubOp  -> trivialFCode FloatRep  FSUB x y
+      FloatMulOp  -> trivialFCode FloatRep  FMUL x y
+      FloatDivOp  -> trivialFCode FloatRep  FDIV x y
+
+      DoubleAddOp -> trivialFCode DoubleRep FADD x y
+      DoubleSubOp -> trivialFCode DoubleRep FSUB x y
+      DoubleMulOp -> trivialFCode DoubleRep FMUL x y
+      DoubleDivOp -> trivialFCode DoubleRep FDIV x y
+
+      AndOp -> trivialCode (AND False) x y
+      OrOp  -> trivialCode (OR False) x y
+      SllOp -> trivialCode SLL x y
+      SraOp -> trivialCode SRA x y
+      SrlOp -> trivialCode SRL x y
+
+      ISllOp -> panic "SparcGen:isll"
+      ISraOp -> panic "SparcGen:isra"
+      ISrlOp -> panic "SparcGen:isrl"
+
+      FloatPowerOp  -> getRegister (StCall SLIT("pow") DoubleRep [promote x, promote y])
+                      where promote x = StPrim Float2DoubleOp [x]
+      DoublePowerOp -> getRegister (StCall SLIT("pow") DoubleRep [x, y])
+  where
+    imul_div fn x y = getRegister (StCall fn IntRep [x, y])
+
+getRegister (StInd pk mem)
+  = getAmode mem                   `thenUs` \ amode ->
+    let
+       code = amodeCode amode
+       src   = amodeAddr amode
+       size = primRepToSize pk
+       code__2 dst = code . mkSeqInstr (LD size src dst)
+    in
+       returnUs (Any pk code__2)
+
+getRegister (StInt i)
+  | fits13Bits i
+  = let
+       src = ImmInt (fromInteger i)
+       code dst = mkSeqInstr (OR False g0 (RIImm src) dst)
+    in
+       returnUs (Any IntRep code)
+
+getRegister leaf
+  | maybeToBool imm
+  = let
+       code dst = mkSeqInstrs [
+           SETHI (HI imm__2) dst,
+           OR False dst (RIImm (LO imm__2)) dst]
+    in
+       returnUs (Any PtrRep code)
+  where
+    imm = maybeImm leaf
+    imm__2 = case imm of Just x -> x
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{The @Amode@ type}
+%*                                                                     *
+%************************************************************************
+
+@Amode@s: Memory addressing modes passed up the tree.
+\begin{code}
+data Amode = Amode Addr InstrBlock
+
+amodeAddr (Amode addr _) = addr
+amodeCode (Amode _ code) = code
+\end{code}
+
+Now, given a tree (the argument to an StInd) that references memory,
+produce a suitable addressing mode.
+
+\begin{code}
+getAmode :: StixTree -> UniqSM Amode
+
+getAmode tree@(StIndex _ _ _) = getAmode (mangleIndexTree tree)
+
+#if alpha_TARGET_ARCH
+
+getAmode (StPrim IntSubOp [x, StInt i])
+  = getNewRegNCG PtrRep                `thenUs` \ tmp ->
+    getRegister x              `thenUs` \ register ->
+    let
+       code = registerCode register tmp
+       reg  = registerName register tmp
+       off  = ImmInt (-(fromInteger i))
+    in
+    returnUs (Amode (AddrRegImm reg off) code)
+
+getAmode (StPrim IntAddOp [x, StInt i])
+  = getNewRegNCG PtrRep                `thenUs` \ tmp ->
+    getRegister x              `thenUs` \ register ->
+    let
+       code = registerCode register tmp
+       reg  = registerName register tmp
+       off  = ImmInt (fromInteger i)
+    in
+    returnUs (Amode (AddrRegImm reg off) code)
+
+getAmode leaf
+  | maybeToBool imm
+  = returnUs (Amode (AddrImm imm__2) id)
+  where
+    imm = maybeImm leaf
+    imm__2 = case imm of Just x -> x
+
+getAmode other
+  = getNewRegNCG PtrRep                `thenUs` \ tmp ->
+    getRegister other          `thenUs` \ register ->
+    let
+       code = registerCode register tmp
+       reg  = registerName register tmp
+    in
+    returnUs (Amode (AddrReg reg) code)
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+getAmode (StPrim IntSubOp [x, StInt i])
+  = getNewRegNCG PtrRep                `thenUs` \ tmp ->
+    getRegister x              `thenUs` \ register ->
+    let
+       code = registerCode register tmp
+       reg  = registerName register tmp
+       off  = ImmInt (-(fromInteger i))
+    in
+    returnUs (Amode (Addr (Just reg) Nothing off) code)
+
+getAmode (StPrim IntAddOp [x, StInt i])
+  | maybeToBool imm
+  = let
+       code = mkSeqInstrs []
+    in
+    returnUs (Amode (ImmAddr imm__2 (fromInteger i)) code)
+  where
+    imm    = maybeImm x
+    imm__2 = case imm of Just x -> x
+
+getAmode (StPrim IntAddOp [x, StInt i])
+  = getNewRegNCG PtrRep                `thenUs` \ tmp ->
+    getRegister x              `thenUs` \ register ->
+    let
+       code = registerCode register tmp
+       reg  = registerName register tmp
+       off  = ImmInt (fromInteger i)
+    in
+    returnUs (Amode (Addr (Just reg) Nothing off) code)
+
+getAmode (StPrim IntAddOp [x, y])
+  = getNewRegNCG PtrRep                `thenUs` \ tmp1 ->
+    getNewRegNCG IntRep        `thenUs` \ tmp2 ->
+    getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       reg1  = registerName register1 tmp1
+       code2 = registerCode register2 tmp2 asmVoid
+       reg2  = registerName register2 tmp2
+       code__2 = asmParThen [code1, code2]
+    in
+    returnUs (Amode (Addr (Just reg1) (Just (reg2,4)) (ImmInt 0)) code__2)
+
+getAmode leaf
+  | maybeToBool imm
+  = let
+       code = mkSeqInstrs []
+    in
+    returnUs (Amode (ImmAddr imm__2 0) code)
+  where
+    imm    = maybeImm leaf
+    imm__2 = case imm of Just x -> x
+
+getAmode other
+  = getNewRegNCG PtrRep                `thenUs` \ tmp ->
+    getRegister other          `thenUs` \ register ->
+    let
+       code = registerCode register tmp
+       reg  = registerName register tmp
+       off  = Nothing
+    in
+    returnUs (Amode (Addr (Just reg) Nothing (ImmInt 0)) code)
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+getAmode (StPrim IntSubOp [x, StInt i])
+  | fits13Bits (-i)
+  = getNewRegNCG PtrRep                `thenUs` \ tmp ->
+    getRegister x              `thenUs` \ register ->
+    let
+       code = registerCode register tmp
+       reg  = registerName register tmp
+       off  = ImmInt (-(fromInteger i))
+    in
+    returnUs (Amode (AddrRegImm reg off) code)
+
+
+getAmode (StPrim IntAddOp [x, StInt i])
+  | fits13Bits i
+  = getNewRegNCG PtrRep                `thenUs` \ tmp ->
+    getRegister x              `thenUs` \ register ->
+    let
+       code = registerCode register tmp
+       reg  = registerName register tmp
+       off  = ImmInt (fromInteger i)
+    in
+    returnUs (Amode (AddrRegImm reg off) code)
+
+getAmode (StPrim IntAddOp [x, y])
+  = getNewRegNCG PtrRep        `thenUs` \ tmp1 ->
+    getNewRegNCG IntRep        `thenUs` \ tmp2 ->
+    getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       reg1  = registerName register1 tmp1
+       code2 = registerCode register2 tmp2 asmVoid
+       reg2  = registerName register2 tmp2
+       code__2 = asmParThen [code1, code2]
+    in
+    returnUs (Amode (AddrRegReg reg1 reg2) code__2)
+
+getAmode leaf
+  | maybeToBool imm
+  = getNewRegNCG PtrRep            `thenUs` \ tmp ->
+    let
+       code = mkSeqInstr (SETHI (HI imm__2) tmp)
+    in
+    returnUs (Amode (AddrRegImm tmp (LO imm__2)) code)
+  where
+    imm    = maybeImm leaf
+    imm__2 = case imm of Just x -> x
+
+getAmode other
+  = getNewRegNCG PtrRep                `thenUs` \ tmp ->
+    getRegister other          `thenUs` \ register ->
+    let
+       code = registerCode register tmp
+       reg  = registerName register tmp
+       off  = ImmInt 0
+    in
+    returnUs (Amode (AddrRegImm reg off) code)
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{The @CondCode@ type}
+%*                                                                     *
+%************************************************************************
+
+Condition codes passed up the tree.
+\begin{code}
+data CondCode = CondCode Bool Cond InstrBlock
+
+condName  (CondCode _ cond _)     = cond
+condFloat (CondCode is_float _ _) = is_float
+condCode  (CondCode _ _ code)     = code
+\end{code}
+
+Set up a condition code for a conditional branch.
+
+\begin{code}
+getCondCode :: StixTree -> UniqSM CondCode
+
+#if alpha_TARGET_ARCH
+getCondCode = panic "MachCode.getCondCode: not on Alphas"
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#if i386_TARGET_ARCH || sparc_TARGET_ARCH
+-- yes, they really do seem to want exactly the same!
+
+getCondCode (StPrim primop [x, y])
+  = case primop of
+      CharGtOp -> condIntCode GT  x y
+      CharGeOp -> condIntCode GE  x y
+      CharEqOp -> condIntCode EQ  x y
+      CharNeOp -> condIntCode NE  x y
+      CharLtOp -> condIntCode LT  x y
+      CharLeOp -> condIntCode LE  x y
+      IntGtOp  -> condIntCode GT  x y
+      IntGeOp  -> condIntCode GE  x y
+      IntEqOp  -> condIntCode EQ  x y
+      IntNeOp  -> condIntCode NE  x y
+      IntLtOp  -> condIntCode LT  x y
+      IntLeOp  -> condIntCode LE  x y
+
+      WordGtOp -> condIntCode GU  x y
+      WordGeOp -> condIntCode GEU x y
+      WordEqOp -> condIntCode EQ  x y
+      WordNeOp -> condIntCode NE  x y
+      WordLtOp -> condIntCode LU  x y
+      WordLeOp -> condIntCode LEU x y
+
+      AddrGtOp -> condIntCode GU  x y
+      AddrGeOp -> condIntCode GEU x y
+      AddrEqOp -> condIntCode EQ  x y
+      AddrNeOp -> condIntCode NE  x y
+      AddrLtOp -> condIntCode LU  x y
+      AddrLeOp -> condIntCode LEU x y
+
+      FloatGtOp -> condFltCode GT x y
+      FloatGeOp -> condFltCode GE x y
+      FloatEqOp -> condFltCode EQ x y
+      FloatNeOp -> condFltCode NE x y
+      FloatLtOp -> condFltCode LT x y
+      FloatLeOp -> condFltCode LE x y
+
+      DoubleGtOp -> condFltCode GT x y
+      DoubleGeOp -> condFltCode GE x y
+      DoubleEqOp -> condFltCode EQ x y
+      DoubleNeOp -> condFltCode NE x y
+      DoubleLtOp -> condFltCode LT x y
+      DoubleLeOp -> condFltCode LE x y
+
+#endif {- i386_TARGET_ARCH || sparc_TARGET_ARCH -}
+\end{code}
+
+% -----------------
+
+@cond(Int|Flt)Code@: Turn a boolean expression into a condition, to be
+passed back up the tree.
+
+\begin{code}
+condIntCode, condFltCode :: Cond -> StixTree -> StixTree -> UniqSM CondCode
+
+#if alpha_TARGET_ARCH
+condIntCode = panic "MachCode.condIntCode: not on Alphas"
+condFltCode = panic "MachCode.condFltCode: not on Alphas"
+#endif {- alpha_TARGET_ARCH -}
+
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+condIntCode cond (StInd _ x) y
+  | maybeToBool imm
+  = getAmode x                 `thenUs` \ amode ->
+    let
+       code1 = amodeCode amode asmVoid
+       y__2  = amodeAddr amode
+       code__2 = asmParThen [code1] .
+                 mkSeqInstr (CMP L (OpImm imm__2) (OpAddr y__2))
+    in
+    returnUs (CondCode False cond code__2)
+  where
+    imm    = maybeImm y
+    imm__2 = case imm of Just x -> x
+
+condIntCode cond x (StInt 0)
+  = getRegister x              `thenUs` \ register1 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp1 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       src1  = registerName register1 tmp1
+       code__2 = asmParThen [code1] .
+               mkSeqInstr (TEST L (OpReg src1) (OpReg src1))
+    in
+    returnUs (CondCode False cond code__2)
+
+condIntCode cond x y
+  | maybeToBool imm
+  = getRegister x              `thenUs` \ register1 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp1 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       src1  = registerName register1 tmp1
+       code__2 = asmParThen [code1] .
+               mkSeqInstr (CMP L (OpImm imm__2) (OpReg src1))
+    in
+    returnUs (CondCode False cond code__2)
+  where
+    imm    = maybeImm y
+    imm__2 = case imm of Just x -> x
+
+condIntCode cond (StInd _ x) y
+  = getAmode x                 `thenUs` \ amode ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp2 ->
+    let
+       code1 = amodeCode amode asmVoid
+       src1  = amodeAddr amode
+       code2 = registerCode register2 tmp2 asmVoid
+       src2  = registerName register2 tmp2
+       code__2 = asmParThen [code1, code2] .
+                 mkSeqInstr (CMP L (OpReg src2) (OpAddr src1))
+    in
+    returnUs (CondCode False cond code__2)
+
+condIntCode cond y (StInd _ x)
+  = getAmode x                 `thenUs` \ amode ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp2 ->
+    let
+       code1 = amodeCode amode asmVoid
+       src1  = amodeAddr amode
+       code2 = registerCode register2 tmp2 asmVoid
+       src2  = registerName register2 tmp2
+       code__2 = asmParThen [code1, code2] .
+                 mkSeqInstr (CMP L (OpAddr src1) (OpReg src2))
+    in
+    returnUs (CondCode False cond code__2)
+
+condIntCode cond x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp1 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp2 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       src1  = registerName register1 tmp1
+       code2 = registerCode register2 tmp2 asmVoid
+       src2  = registerName register2 tmp2
+       code__2 = asmParThen [code1, code2] .
+               mkSeqInstr (CMP L (OpReg src2) (OpReg src1))
+    in
+    returnUs (CondCode False cond code__2)
+
+-----------
+
+condFltCode cond x (StDouble 0.0)
+  = getRegister x              `thenUs` \ register1 ->
+    getNewRegNCG (registerRep register1)
+                               `thenUs` \ tmp1 ->
+    let
+       pk1   = registerRep register1
+       code1 = registerCode register1 tmp1
+       src1  = registerName register1 tmp1
+
+       code__2 = asmParThen [code1 asmVoid] .
+                 mkSeqInstrs [FTST, FSTP DF (OpReg st0), -- or FLDZ, FUCOMPP ?
+                              FNSTSW,
+                              --AND HB (OpImm (ImmInt 68)) (OpReg eax),
+                              --XOR HB (OpImm (ImmInt 64)) (OpReg eax)
+                              SAHF
+                             ]
+    in
+    returnUs (CondCode True (fix_FP_cond cond) code__2)
+
+condFltCode cond x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG (registerRep register1)
+                               `thenUs` \ tmp1 ->
+    getNewRegNCG (registerRep register2)
+                               `thenUs` \ tmp2 ->
+    let
+       pk1   = registerRep register1
+       code1 = registerCode register1 tmp1
+       src1  = registerName register1 tmp1
+
+       code2 = registerCode register2 tmp2
+       src2  = registerName register2 tmp2
+
+       code__2 = asmParThen [code2 asmVoid, code1 asmVoid] .
+                 mkSeqInstrs [FUCOMPP,
+                              FNSTSW,
+                              --AND HB (OpImm (ImmInt 68)) (OpReg eax),
+                              --XOR HB (OpImm (ImmInt 64)) (OpReg eax)
+                              SAHF
+                             ]
+    in
+    returnUs (CondCode True (fix_FP_cond cond) code__2)
+
+{- On the 486, the flags set by FP compare are the unsigned ones!
+   (This looks like a HACK to me.  WDP 96/03)
+-}
+
+fix_FP_cond :: Cond -> Cond
+
+fix_FP_cond GE  = GEU
+fix_FP_cond GT  = GU
+fix_FP_cond LT  = LU
+fix_FP_cond LE  = LEU
+fix_FP_cond any = any
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+condIntCode cond x (StInt y)
+  | fits13Bits y
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src1 = registerName register tmp
+       src2 = ImmInt (fromInteger y)
+       code__2 = code . mkSeqInstr (SUB False True src1 (RIImm src2) g0)
+    in
+    returnUs (CondCode False cond code__2)
+
+condIntCode cond x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp1 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp2 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       src1  = registerName register1 tmp1
+       code2 = registerCode register2 tmp2 asmVoid
+       src2  = registerName register2 tmp2
+       code__2 = asmParThen [code1, code2] .
+               mkSeqInstr (SUB False True src1 (RIReg src2) g0)
+    in
+    returnUs (CondCode False cond code__2)
+
+-----------
+condFltCode cond x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG (registerRep register1)
+                               `thenUs` \ tmp1 ->
+    getNewRegNCG (registerRep register2)
+                               `thenUs` \ tmp2 ->
+    getNewRegNCG DoubleRep     `thenUs` \ tmp ->
+    let
+       promote x = asmInstr (FxTOy F DF x tmp)
+
+       pk1   = registerRep register1
+       code1 = registerCode register1 tmp1
+       src1  = registerName register1 tmp1
+
+       pk2   = registerRep register2
+       code2 = registerCode register2 tmp2
+       src2  = registerName register2 tmp2
+
+       code__2 =
+               if pk1 == pk2 then
+                   asmParThen [code1 asmVoid, code2 asmVoid] .
+                   mkSeqInstr (FCMP True (primRepToSize pk1) src1 src2)
+               else if pk1 == FloatRep then
+                   asmParThen [code1 (promote src1), code2 asmVoid] .
+                   mkSeqInstr (FCMP True DF tmp src2)
+               else
+                   asmParThen [code1 asmVoid, code2 (promote src2)] .
+                   mkSeqInstr (FCMP True DF src1 tmp)
+    in
+    returnUs (CondCode True cond code__2)
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Generating assignments}
+%*                                                                     *
+%************************************************************************
+
+Assignments are really at the heart of the whole code generation
+business.  Almost all top-level nodes of any real importance are
+assignments, which correspond to loads, stores, or register transfers.
+If we're really lucky, some of the register transfers will go away,
+because we can use the destination register to complete the code
+generation for the right hand side.  This only fails when the right
+hand side is forced into a fixed register (e.g. the result of a call).
+
+\begin{code}
+assignIntCode, assignFltCode
+       :: PrimRep -> StixTree -> StixTree -> UniqSM InstrBlock
+
+#if alpha_TARGET_ARCH
+
+assignIntCode pk (StInd _ dst) src
+  = getNewRegNCG IntRep            `thenUs` \ tmp ->
+    getAmode dst                   `thenUs` \ amode ->
+    getRegister src                        `thenUs` \ register ->
+    let
+       code1   = amodeCode amode asmVoid
+       dst__2  = amodeAddr amode
+       code2   = registerCode register tmp asmVoid
+       src__2  = registerName register tmp
+       sz      = primRepToSize pk
+       code__2 = asmParThen [code1, code2] . mkSeqInstr (ST sz src__2 dst__2)
+    in
+    returnUs code__2
+
+assignIntCode pk dst src
+  = getRegister dst                        `thenUs` \ register1 ->
+    getRegister src                        `thenUs` \ register2 ->
+    let
+       dst__2  = registerName register1 zero
+       code    = registerCode register2 dst__2
+       src__2  = registerName register2 dst__2
+       code__2 = if isFixed register2
+                 then code . mkSeqInstr (OR src__2 (RIReg src__2) dst__2)
+                 else code
+    in
+    returnUs code__2
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+assignIntCode pk (StInd _ dst) src
+  = getAmode dst               `thenUs` \ amode ->
+    get_op_RI src              `thenUs` \ (codesrc, opsrc, sz) ->
+    let
+       code1   = amodeCode amode asmVoid
+       dst__2  = amodeAddr amode
+       code__2 = asmParThen [code1, codesrc asmVoid] .
+                 mkSeqInstr (MOV sz opsrc (OpAddr dst__2))
+    in
+    returnUs code__2
+  where
+    get_op_RI
+       :: StixTree
+       -> UniqSM (InstrBlock,Operand, Size)    -- code, operator, size
+
+    get_op_RI op
+      | maybeToBool imm
+      = returnUs (asmParThen [], OpImm imm_op, L)
+      where
+       imm    = maybeImm op
+       imm_op = case imm of Just x -> x
+
+    get_op_RI op
+      = getRegister op                 `thenUs` \ register ->
+       getNewRegNCG (registerRep register)
+                                       `thenUs` \ tmp ->
+       let
+           code = registerCode register tmp
+           reg  = registerName register tmp
+           pk   = registerRep  register
+           sz   = primRepToSize pk
+       in
+       returnUs (code, OpReg reg, sz)
+
+assignIntCode pk dst (StInd _ src)
+  = getNewRegNCG IntRep            `thenUs` \ tmp ->
+    getAmode src                   `thenUs` \ amode ->
+    getRegister dst                        `thenUs` \ register ->
+    let
+       code1   = amodeCode amode asmVoid
+       src__2  = amodeAddr amode
+       code2   = registerCode register tmp asmVoid
+       dst__2  = registerName register tmp
+       sz      = primRepToSize pk
+       code__2 = asmParThen [code1, code2] .
+                 mkSeqInstr (MOV sz (OpAddr src__2) (OpReg dst__2))
+    in
+    returnUs code__2
+
+assignIntCode pk dst src
+  = getRegister dst                        `thenUs` \ register1 ->
+    getRegister src                        `thenUs` \ register2 ->
+    getNewRegNCG IntRep            `thenUs` \ tmp ->
+    let
+       dst__2  = registerName register1 tmp
+       code    = registerCode register2 dst__2
+       src__2  = registerName register2 dst__2
+       code__2 = if isFixed register2 && dst__2 /= src__2
+                 then code . mkSeqInstr (MOV L (OpReg src__2) (OpReg dst__2))
+                 else code
+    in
+    returnUs code__2
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+assignIntCode pk (StInd _ dst) src
+  = getNewRegNCG IntRep            `thenUs` \ tmp ->
+    getAmode dst                   `thenUs` \ amode ->
+    getRegister src                        `thenUs` \ register ->
+    let
+       code1   = amodeCode amode asmVoid
+       dst__2  = amodeAddr amode
+       code2   = registerCode register tmp asmVoid
+       src__2  = registerName register tmp
+       sz      = primRepToSize pk
+       code__2 = asmParThen [code1, code2] . mkSeqInstr (ST sz src__2 dst__2)
+    in
+    returnUs code__2
+
+assignIntCode pk dst src
+  = getRegister dst                        `thenUs` \ register1 ->
+    getRegister src                        `thenUs` \ register2 ->
+    let
+       dst__2  = registerName register1 g0
+       code    = registerCode register2 dst__2
+       src__2  = registerName register2 dst__2
+       code__2 = if isFixed register2
+                 then code . mkSeqInstr (OR False g0 (RIReg src__2) dst__2)
+                 else code
+    in
+    returnUs code__2
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+% --------------------------------
+Floating-point assignments:
+% --------------------------------
+\begin{code}
+#if alpha_TARGET_ARCH
+
+assignFltCode pk (StInd _ dst) src
+  = getNewRegNCG pk                `thenUs` \ tmp ->
+    getAmode dst                   `thenUs` \ amode ->
+    getRegister src                        `thenUs` \ register ->
+    let
+       code1   = amodeCode amode asmVoid
+       dst__2  = amodeAddr amode
+       code2   = registerCode register tmp asmVoid
+       src__2  = registerName register tmp
+       sz      = primRepToSize pk
+       code__2 = asmParThen [code1, code2] . mkSeqInstr (ST sz src__2 dst__2)
+    in
+    returnUs code__2
+
+assignFltCode pk dst src
+  = getRegister dst                        `thenUs` \ register1 ->
+    getRegister src                        `thenUs` \ register2 ->
+    let
+       dst__2  = registerName register1 zero
+       code    = registerCode register2 dst__2
+       src__2  = registerName register2 dst__2
+       code__2 = if isFixed register2
+                 then code . mkSeqInstr (FMOV src__2 dst__2)
+                 else code
+    in
+    returnUs code__2
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+assignFltCode pk (StInd pk_dst dst) (StInd pk_src src)
+  = getNewRegNCG IntRep            `thenUs` \ tmp ->
+    getAmode src                   `thenUs` \ amodesrc ->
+    getAmode dst                   `thenUs` \ amodedst ->
+    --getRegister src                      `thenUs` \ register ->
+    let
+       codesrc1 = amodeCode amodesrc asmVoid
+       addrsrc1 = amodeAddr amodesrc
+       codedst1 = amodeCode amodedst asmVoid
+       addrdst1 = amodeAddr amodedst
+       addrsrc2 = case (addrOffset addrsrc1 4) of Just x -> x
+       addrdst2 = case (addrOffset addrdst1 4) of Just x -> x
+
+       code__2 = asmParThen [codesrc1, codedst1] .
+                 mkSeqInstrs ([MOV L (OpAddr addrsrc1) (OpReg tmp),
+                               MOV L (OpReg tmp) (OpAddr addrdst1)]
+                              ++
+                              if pk == DoubleRep
+                              then [MOV L (OpAddr addrsrc2) (OpReg tmp),
+                                    MOV L (OpReg tmp) (OpAddr addrdst2)]
+                              else [])
+    in
+    returnUs code__2
+
+assignFltCode pk (StInd _ dst) src
+  = --getNewRegNCG pk              `thenUs` \ tmp ->
+    getAmode dst                   `thenUs` \ amode ->
+    getRegister src                        `thenUs` \ register ->
+    let
+       sz      = primRepToSize pk
+       dst__2  = amodeAddr amode
+
+       code1   = amodeCode amode asmVoid
+       code2   = registerCode register {-tmp-}st0 asmVoid
+
+       --src__2= registerName register tmp
+       pk__2   = registerRep register
+       sz__2   = primRepToSize pk__2
+
+       code__2 = asmParThen [code1, code2] .
+                 mkSeqInstr (FSTP sz (OpAddr dst__2))
+    in
+    returnUs code__2
+
+assignFltCode pk dst src
+  = getRegister dst                        `thenUs` \ register1 ->
+    getRegister src                        `thenUs` \ register2 ->
+    --getNewRegNCG (registerRep register2)
+    --                             `thenUs` \ tmp ->
+    let
+       sz      = primRepToSize pk
+       dst__2  = registerName register1 st0 --tmp
+
+       code    = registerCode register2 dst__2
+       src__2  = registerName register2 dst__2
+
+       code__2 = code
+    in
+    returnUs code__2
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+assignFltCode pk (StInd _ dst) src
+  = getNewRegNCG pk                `thenUs` \ tmp ->
+    getAmode dst                   `thenUs` \ amode ->
+    getRegister src                        `thenUs` \ register ->
+    let
+       sz      = primRepToSize pk
+       dst__2  = amodeAddr amode
+
+       code1   = amodeCode amode asmVoid
+       code2   = registerCode register tmp asmVoid
+
+       src__2  = registerName register tmp
+       pk__2   = registerRep register
+       sz__2   = primRepToSize pk__2
+
+       code__2 = asmParThen [code1, code2] .
+           if pk == pk__2 then
+               mkSeqInstr (ST sz src__2 dst__2)
+           else
+               mkSeqInstrs [FxTOy sz__2 sz src__2 tmp, ST sz tmp dst__2]
+    in
+    returnUs code__2
+
+assignFltCode pk dst src
+  = getRegister dst                        `thenUs` \ register1 ->
+    getRegister src                        `thenUs` \ register2 ->
+    getNewRegNCG (registerRep register2)
+                                   `thenUs` \ tmp ->
+    let
+       sz      = primRepToSize pk
+       dst__2  = registerName register1 g0    -- must be Fixed
+       reg__2  = if pk /= pk__2 then tmp else dst__2
+       code    = registerCode register2 reg__2
+       src__2  = registerName register2 reg__2
+       pk__2   = registerRep register2
+       sz__2   = primRepToSize pk__2
+
+       code__2 = if pk /= pk__2 then
+                    code . mkSeqInstr (FxTOy sz__2 sz src__2 dst__2)
+               else if isFixed register2 then
+                    code . mkSeqInstr (FMOV sz src__2 dst__2)
+               else
+                    code
+    in
+    returnUs code__2
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Generating an unconditional branch}
+%*                                                                     *
+%************************************************************************
+
+We accept two types of targets: an immediate CLabel or a tree that
+gets evaluated into a register.  Any CLabels which are AsmTemporaries
+are assumed to be in the local block of code, close enough for a
+branch instruction.  Other CLabels are assumed to be far away.
+
+(If applicable) Do not fill the delay slots here; you will confuse the
+register allocator.
+
+\begin{code}
+genJump :: StixTree{-the branch target-} -> UniqSM InstrBlock
+
+#if alpha_TARGET_ARCH
+
+genJump (StCLbl lbl)
+  | isAsmTemp lbl = returnInstr (BR target)
+  | otherwise     = returnInstrs [LDA pv (AddrImm target), JMP zero (AddrReg pv) 0]
+  where
+    target = ImmCLbl lbl
+
+genJump tree
+  = getRegister tree                       `thenUs` \ register ->
+    getNewRegNCG PtrRep            `thenUs` \ tmp ->
+    let
+       dst    = registerName register pv
+       code   = registerCode register pv
+       target = registerName register pv
+    in
+    if isFixed register then
+       returnSeq code [OR dst (RIReg dst) pv, JMP zero (AddrReg pv) 0]
+    else
+    returnUs (code . mkSeqInstr (JMP zero (AddrReg pv) 0))
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+{-
+genJump (StCLbl lbl)
+  | isAsmTemp lbl = returnInstrs [JXX ALWAYS lbl]
+  | otherwise     = returnInstrs [JMP (OpImm target)]
+  where
+    target = ImmCLbl lbl
+-}
+
+genJump (StInd pk mem)
+  = getAmode mem                   `thenUs` \ amode ->
+    let
+       code   = amodeCode amode
+       target = amodeAddr amode
+    in
+    returnSeq code [JMP (OpAddr target)]
+
+genJump tree
+  | maybeToBool imm
+  = returnInstr (JMP (OpImm target))
+
+  | otherwise
+  = getRegister tree                       `thenUs` \ register ->
+    getNewRegNCG PtrRep            `thenUs` \ tmp ->
+    let
+       code   = registerCode register tmp
+       target = registerName register tmp
+    in
+    returnSeq code [JMP (OpReg target)]
+  where
+    imm    = maybeImm tree
+    target = case imm of Just x -> x
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+genJump (StCLbl lbl)
+  | isAsmTemp lbl = returnInstrs [BI ALWAYS False target, NOP]
+  | otherwise     = returnInstrs [CALL target 0 True, NOP]
+  where
+    target = ImmCLbl lbl
+
+genJump tree
+  = getRegister tree                       `thenUs` \ register ->
+    getNewRegNCG PtrRep            `thenUs` \ tmp ->
+    let
+       code   = registerCode register tmp
+       target = registerName register tmp
+    in
+    returnSeq code [JMP (AddrRegReg target g0), NOP]
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Conditional jumps}
+%*                                                                     *
+%************************************************************************
+
+Conditional jumps are always to local labels, so we can use branch
+instructions.  We peek at the arguments to decide what kind of
+comparison to do.
+
+ALPHA: For comparisons with 0, we're laughing, because we can just do
+the desired conditional branch.
+
+I386: First, we have to ensure that the condition
+codes are set according to the supplied comparison operation.
+
+SPARC: First, we have to ensure that the condition codes are set
+according to the supplied comparison operation.  We generate slightly
+different code for floating point comparisons, because a floating
+point operation cannot directly precede a @BF@.  We assume the worst
+and fill that slot with a @NOP@.
+
+SPARC: Do not fill the delay slots here; you will confuse the register
+allocator.
+
+\begin{code}
+genCondJump
+    :: CLabel      -- the branch target
+    -> StixTree     -- the condition on which to branch
+    -> UniqSM InstrBlock
+
+#if alpha_TARGET_ARCH
+
+genCondJump lbl (StPrim op [x, StInt 0])
+  = getRegister x                          `thenUs` \ register ->
+    getNewRegNCG (registerRep register)
+                                   `thenUs` \ tmp ->
+    let
+       code   = registerCode register tmp
+       value  = registerName register tmp
+       pk     = registerRep register
+       target = ImmCLbl lbl
+    in
+    returnSeq code [BI (cmpOp op) value target]
+  where
+    cmpOp CharGtOp = GT
+    cmpOp CharGeOp = GE
+    cmpOp CharEqOp = EQ
+    cmpOp CharNeOp = NE
+    cmpOp CharLtOp = LT
+    cmpOp CharLeOp = LE
+    cmpOp IntGtOp = GT
+    cmpOp IntGeOp = GE
+    cmpOp IntEqOp = EQ
+    cmpOp IntNeOp = NE
+    cmpOp IntLtOp = LT
+    cmpOp IntLeOp = LE
+    cmpOp WordGtOp = NE
+    cmpOp WordGeOp = ALWAYS
+    cmpOp WordEqOp = EQ
+    cmpOp WordNeOp = NE
+    cmpOp WordLtOp = NEVER
+    cmpOp WordLeOp = EQ
+    cmpOp AddrGtOp = NE
+    cmpOp AddrGeOp = ALWAYS
+    cmpOp AddrEqOp = EQ
+    cmpOp AddrNeOp = NE
+    cmpOp AddrLtOp = NEVER
+    cmpOp AddrLeOp = EQ
+
+genCondJump lbl (StPrim op [x, StDouble 0.0])
+  = getRegister x                          `thenUs` \ register ->
+    getNewRegNCG (registerRep register)
+                                   `thenUs` \ tmp ->
+    let
+       code   = registerCode register tmp
+       value  = registerName register tmp
+       pk     = registerRep register
+       target = ImmCLbl lbl
+    in
+    returnUs (code . mkSeqInstr (BF (cmpOp op) value target))
+  where
+    cmpOp FloatGtOp = GT
+    cmpOp FloatGeOp = GE
+    cmpOp FloatEqOp = EQ
+    cmpOp FloatNeOp = NE
+    cmpOp FloatLtOp = LT
+    cmpOp FloatLeOp = LE
+    cmpOp DoubleGtOp = GT
+    cmpOp DoubleGeOp = GE
+    cmpOp DoubleEqOp = EQ
+    cmpOp DoubleNeOp = NE
+    cmpOp DoubleLtOp = LT
+    cmpOp DoubleLeOp = LE
+
+genCondJump lbl (StPrim op [x, y])
+  | fltCmpOp op
+  = trivialFCode pr instr x y      `thenUs` \ register ->
+    getNewRegNCG DoubleRep         `thenUs` \ tmp ->
+    let
+       code   = registerCode register tmp
+       result = registerName register tmp
+       target = ImmCLbl lbl
+    in
+    returnUs (code . mkSeqInstr (BF cond result target))
+  where
+    pr = panic "trivialU?FCode: does not use PrimRep on Alpha"
+
+    fltCmpOp op = case op of
+       FloatGtOp -> True
+       FloatGeOp -> True
+       FloatEqOp -> True
+       FloatNeOp -> True
+       FloatLtOp -> True
+       FloatLeOp -> True
+       DoubleGtOp -> True
+       DoubleGeOp -> True
+       DoubleEqOp -> True
+       DoubleNeOp -> True
+       DoubleLtOp -> True
+       DoubleLeOp -> True
+       _ -> False
+    (instr, cond) = case op of
+       FloatGtOp -> (FCMP TF LE, EQ)
+       FloatGeOp -> (FCMP TF LT, EQ)
+       FloatEqOp -> (FCMP TF EQ, NE)
+       FloatNeOp -> (FCMP TF EQ, EQ)
+       FloatLtOp -> (FCMP TF LT, NE)
+       FloatLeOp -> (FCMP TF LE, NE)
+       DoubleGtOp -> (FCMP TF LE, EQ)
+       DoubleGeOp -> (FCMP TF LT, EQ)
+       DoubleEqOp -> (FCMP TF EQ, NE)
+       DoubleNeOp -> (FCMP TF EQ, EQ)
+       DoubleLtOp -> (FCMP TF LT, NE)
+       DoubleLeOp -> (FCMP TF LE, NE)
+
+genCondJump lbl (StPrim op [x, y])
+  = trivialCode instr x y          `thenUs` \ register ->
+    getNewRegNCG IntRep            `thenUs` \ tmp ->
+    let
+       code   = registerCode register tmp
+       result = registerName register tmp
+       target = ImmCLbl lbl
+    in
+    returnUs (code . mkSeqInstr (BI cond result target))
+  where
+    (instr, cond) = case op of
+       CharGtOp -> (CMP LE, EQ)
+       CharGeOp -> (CMP LT, EQ)
+       CharEqOp -> (CMP EQ, NE)
+       CharNeOp -> (CMP EQ, EQ)
+       CharLtOp -> (CMP LT, NE)
+       CharLeOp -> (CMP LE, NE)
+       IntGtOp -> (CMP LE, EQ)
+       IntGeOp -> (CMP LT, EQ)
+       IntEqOp -> (CMP EQ, NE)
+       IntNeOp -> (CMP EQ, EQ)
+       IntLtOp -> (CMP LT, NE)
+       IntLeOp -> (CMP LE, NE)
+       WordGtOp -> (CMP ULE, EQ)
+       WordGeOp -> (CMP ULT, EQ)
+       WordEqOp -> (CMP EQ, NE)
+       WordNeOp -> (CMP EQ, EQ)
+       WordLtOp -> (CMP ULT, NE)
+       WordLeOp -> (CMP ULE, NE)
+       AddrGtOp -> (CMP ULE, EQ)
+       AddrGeOp -> (CMP ULT, EQ)
+       AddrEqOp -> (CMP EQ, NE)
+       AddrNeOp -> (CMP EQ, EQ)
+       AddrLtOp -> (CMP ULT, NE)
+       AddrLeOp -> (CMP ULE, NE)
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+genCondJump lbl bool
+  = getCondCode bool               `thenUs` \ condition ->
+    let
+       code   = condCode condition
+       cond   = condName condition
+       target = ImmCLbl lbl
+    in
+    returnSeq code [JXX cond lbl]
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+genCondJump lbl bool
+  = getCondCode bool               `thenUs` \ condition ->
+    let
+       code   = condCode condition
+       cond   = condName condition
+       target = ImmCLbl lbl
+    in
+    returnSeq code (
+    if condFloat condition then
+       [NOP, BF cond False target, NOP]
+    else
+       [BI cond False target, NOP]
+    )
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Generating C calls}
+%*                                                                     *
+%************************************************************************
+
+Now the biggest nightmare---calls.  Most of the nastiness is buried in
+@get_arg@, which moves the arguments to the correct registers/stack
+locations.  Apart from that, the code is easy.
+
+(If applicable) Do not fill the delay slots here; you will confuse the
+register allocator.
+
+\begin{code}
+genCCall
+    :: FAST_STRING     -- function to call
+    -> PrimRep         -- type of the result
+    -> [StixTree]      -- arguments (of mixed type)
+    -> UniqSM InstrBlock
+
+#if alpha_TARGET_ARCH
+
+genCCall fn kind args
+  = mapAccumLUs get_arg (allArgRegs, eXTRA_STK_ARGS_HERE) args
+                                   `thenUs` \ ((unused,_), argCode) ->
+    let
+       nRegs = length allArgRegs - length unused
+       code = asmParThen (map ($ asmVoid) argCode)
+    in
+       returnSeq code [
+           LDA pv (AddrImm (ImmLab (uppPStr fn))),
+           JSR ra (AddrReg pv) nRegs,
+           LDGP gp (AddrReg ra)]
+  where
+    ------------------------
+    {- Try to get a value into a specific register (or registers) for
+       a call.  The first 6 arguments go into the appropriate
+       argument register (separate registers for integer and floating
+       point arguments, but used in lock-step), and the remaining
+       arguments are dumped to the stack, beginning at 0(sp).  Our
+       first argument is a pair of the list of remaining argument
+       registers to be assigned for this call and the next stack
+       offset to use for overflowing arguments.  This way,
+       @get_Arg@ can be applied to all of a call's arguments using
+       @mapAccumLUs@.
+    -}
+    get_arg
+       :: ([(Reg,Reg)], Int)   -- Argument registers and stack offset (accumulator)
+       -> StixTree             -- Current argument
+       -> UniqSM (([(Reg,Reg)],Int), InstrBlock) -- Updated accumulator and code
+
+    -- We have to use up all of our argument registers first...
+
+    get_arg ((iDst,fDst):dsts, offset) arg
+      = getRegister arg                            `thenUs` \ register ->
+       let
+           reg  = if isFloatingRep pk then fDst else iDst
+           code = registerCode register reg
+           src  = registerName register reg
+           pk   = registerRep register
+       in
+       returnUs (
+           if isFloatingRep pk then
+               ((dsts, offset), if isFixed register then
+                   code . mkSeqInstr (FMOV src fDst)
+                   else code)
+           else
+               ((dsts, offset), if isFixed register then
+                   code . mkSeqInstr (OR src (RIReg src) iDst)
+                   else code))
+
+    -- Once we have run out of argument registers, we move to the
+    -- stack...
+
+    get_arg ([], offset) arg
+      = getRegister arg                        `thenUs` \ register ->
+       getNewRegNCG (registerRep register)
+                                       `thenUs` \ tmp ->
+       let
+           code = registerCode register tmp
+           src  = registerName register tmp
+           pk   = registerRep register
+           sz   = primRepToSize pk
+       in
+       returnUs (([], offset + 1), code . mkSeqInstr (ST sz src (spRel offset)))
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+genCCall fn kind [StInt i]
+  | fn == SLIT ("PerformGC_wrapper")
+  = getUniqLabelNCG                        `thenUs` \ lbl ->
+    let
+       call = [MOV L (OpImm (ImmInt (fromInteger i))) (OpReg eax),
+               MOV L (OpImm (ImmCLbl lbl))
+                     -- this is hardwired
+                     (OpAddr (Addr (Just ebx) Nothing (ImmInt 104))),
+               JMP (OpImm (ImmLit (uppPStr (SLIT ("_PerformGC_wrapper"))))),
+               LABEL lbl]
+    in
+    returnInstrs call
+
+genCCall fn kind args
+  = mapUs get_call_arg args `thenUs` \ argCode ->
+    let
+       nargs = length args
+       code1 = asmParThen [asmSeq [ -- MOV L (OpReg esp) (OpAddr (Addr (Just ebx) Nothing (ImmInt 80))),
+                       MOV L (OpAddr (Addr (Just ebx) Nothing (ImmInt 100))) (OpReg esp)
+                                  ]
+                          ]
+       code2 = asmParThen (map ($ asmVoid) (reverse argCode))
+       call = [CALL fn__2 -- ,
+               -- ADD L (OpImm (ImmInt (nargs * 4))) (OpReg esp),
+               -- MOV L (OpAddr (Addr (Just ebx) Nothing (ImmInt 80))) (OpReg esp)
+               ]
+    in
+    returnSeq (code1 . code2) call
+  where
+    -- function names that begin with '.' are assumed to be special
+    -- internally generated names like '.mul,' which don't get an
+    -- underscore prefix
+    -- ToDo:needed (WDP 96/03) ???
+    fn__2 = case (_HEAD_ fn) of
+             '.' -> ImmLit (uppPStr fn)
+             _   -> ImmLab (uppPStr fn)
+
+    ------------
+    get_call_arg :: StixTree{-current argument-} -> UniqSM InstrBlock  -- code
+
+    get_call_arg arg
+      = get_op arg             `thenUs` \ (code, op, sz) ->
+       returnUs (code . mkSeqInstr (PUSH sz op))
+
+    ------------
+    get_op
+       :: StixTree
+       -> UniqSM (InstrBlock,Operand, Size)    -- code, operator, size
+
+    get_op (StInt i)
+      = returnUs (asmParThen [], OpImm (ImmInt (fromInteger i)), L)
+
+    get_op (StInd pk mem)
+      = getAmode mem           `thenUs` \ amode ->
+       let
+           code = amodeCode amode --asmVoid
+           addr = amodeAddr amode
+           sz   = primRepToSize pk
+       in
+       returnUs (code, OpAddr addr, sz)
+
+    get_op op
+      = getRegister op         `thenUs` \ register ->
+       getNewRegNCG (registerRep register)
+                               `thenUs` \ tmp ->
+       let
+           code = registerCode register tmp
+           reg  = registerName register tmp
+           pk   = registerRep  register
+           sz   = primRepToSize pk
+       in
+       returnUs (code, OpReg reg, sz)
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+genCCall fn kind args
+  = mapAccumLUs get_arg (allArgRegs, eXTRA_STK_ARGS_HERE) args
+                                   `thenUs` \ ((unused,_), argCode) ->
+    let
+       nRegs = length allArgRegs - length unused
+       call = CALL fn__2 nRegs False
+       code = asmParThen (map ($ asmVoid) argCode)
+    in
+       returnSeq code [call, NOP]
+  where
+    -- function names that begin with '.' are assumed to be special
+    -- internally generated names like '.mul,' which don't get an
+    -- underscore prefix
+    -- ToDo:needed (WDP 96/03) ???
+    fn__2 = case (_HEAD_ fn) of
+             '.' -> ImmLit (uppPStr fn)
+             _   -> ImmLab (uppPStr fn)
+
+    ------------------------------------
+    {-  Try to get a value into a specific register (or registers) for
+       a call.  The SPARC calling convention is an absolute
+       nightmare.  The first 6x32 bits of arguments are mapped into
+       %o0 through %o5, and the remaining arguments are dumped to the
+       stack, beginning at [%sp+92].  (Note that %o6 == %sp.)  Our
+       first argument is a pair of the list of remaining argument
+       registers to be assigned for this call and the next stack
+       offset to use for overflowing arguments.  This way,
+       @get_arg@ can be applied to all of a call's arguments using
+       @mapAccumL@.
+    -}
+    get_arg
+       :: ([Reg],Int)  -- Argument registers and stack offset (accumulator)
+       -> StixTree     -- Current argument
+       -> UniqSM (([Reg],Int), InstrBlock) -- Updated accumulator and code
+
+    -- We have to use up all of our argument registers first...
+
+    get_arg (dst:dsts, offset) arg
+      = getRegister arg                        `thenUs` \ register ->
+       getNewRegNCG (registerRep register)
+                                       `thenUs` \ tmp ->
+       let
+           reg  = if isFloatingRep pk then tmp else dst
+           code = registerCode register reg
+           src  = registerName register reg
+           pk   = registerRep register
+       in
+       returnUs (case pk of
+           DoubleRep ->
+               case dsts of
+                   [] -> (([], offset + 1), code . mkSeqInstrs [
+                           -- conveniently put the second part in the right stack
+                           -- location, and load the first part into %o5
+                           ST DF src (spRel (offset - 1)),
+                           LD W (spRel (offset - 1)) dst])
+                   (dst__2:dsts__2) -> ((dsts__2, offset), code . mkSeqInstrs [
+                           ST DF src (spRel (-2)),
+                           LD W (spRel (-2)) dst,
+                           LD W (spRel (-1)) dst__2])
+           FloatRep -> ((dsts, offset), code . mkSeqInstrs [
+                           ST F src (spRel (-2)),
+                           LD W (spRel (-2)) dst])
+           _ -> ((dsts, offset), if isFixed register then
+                                 code . mkSeqInstr (OR False g0 (RIReg src) dst)
+                                 else code))
+
+    -- Once we have run out of argument registers, we move to the
+    -- stack...
+
+    get_arg ([], offset) arg
+      = getRegister arg                        `thenUs` \ register ->
+       getNewRegNCG (registerRep register)
+                                       `thenUs` \ tmp ->
+       let
+           code  = registerCode register tmp
+           src   = registerName register tmp
+           pk    = registerRep register
+           sz    = primRepToSize pk
+           words = if pk == DoubleRep then 2 else 1
+       in
+       returnUs (([], offset + words), code . mkSeqInstr (ST sz src (spRel offset)))
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Support bits}
+%*                                                                     *
+%************************************************************************
+
+%************************************************************************
+%*                                                                     *
+\subsubsection{@condIntReg@ and @condFltReg@: condition codes into registers}
+%*                                                                     *
+%************************************************************************
+
+Turn those condition codes into integers now (when they appear on
+the right hand side of an assignment).
+
+(If applicable) Do not fill the delay slots here; you will confuse the
+register allocator.
+
+\begin{code}
+condIntReg, condFltReg :: Cond -> StixTree -> StixTree -> UniqSM Register
+
+#if alpha_TARGET_ARCH
+condIntReg = panic "MachCode.condIntReg (not on Alpha)"
+condFltReg = panic "MachCode.condFltReg (not on Alpha)"
+#endif {- alpha_TARGET_ARCH -}
+
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+condIntReg cond x y
+  = condIntCode cond x y       `thenUs` \ condition ->
+    getNewRegNCG IntRep                `thenUs` \ tmp ->
+    --getRegister dst          `thenUs` \ register ->
+    let
+       --code2 = registerCode register tmp asmVoid
+       --dst__2  = registerName register tmp
+       code = condCode condition
+       cond = condName condition
+       -- ToDo: if dst is eax, ebx, ecx, or edx we would not need the move.
+       code__2 dst = code . mkSeqInstrs [
+           SETCC cond (OpReg tmp),
+           AND L (OpImm (ImmInt 1)) (OpReg tmp),
+           MOV L (OpReg tmp) (OpReg dst)]
+    in
+    returnUs (Any IntRep code__2)
+
+condFltReg cond x y
+  = getUniqLabelNCG            `thenUs` \ lbl1 ->
+    getUniqLabelNCG            `thenUs` \ lbl2 ->
+    condFltCode cond x y       `thenUs` \ condition ->
+    let
+       code = condCode condition
+       cond = condName condition
+       code__2 dst = code . mkSeqInstrs [
+           JXX cond lbl1,
+           MOV L (OpImm (ImmInt 0)) (OpReg dst),
+           JXX ALWAYS lbl2,
+           LABEL lbl1,
+           MOV L (OpImm (ImmInt 1)) (OpReg dst),
+           LABEL lbl2]
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+condIntReg EQ x (StInt 0)
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src  = registerName register tmp
+       code__2 dst = code . mkSeqInstrs [
+           SUB False True g0 (RIReg src) g0,
+           SUB True False g0 (RIImm (ImmInt (-1))) dst]
+    in
+    returnUs (Any IntRep code__2)
+
+condIntReg EQ x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp1 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp2 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       src1  = registerName register1 tmp1
+       code2 = registerCode register2 tmp2 asmVoid
+       src2  = registerName register2 tmp2
+       code__2 dst = asmParThen [code1, code2] . mkSeqInstrs [
+           XOR False src1 (RIReg src2) dst,
+           SUB False True g0 (RIReg dst) g0,
+           SUB True False g0 (RIImm (ImmInt (-1))) dst]
+    in
+    returnUs (Any IntRep code__2)
+
+condIntReg NE x (StInt 0)
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep        `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src  = registerName register tmp
+       code__2 dst = code . mkSeqInstrs [
+           SUB False True g0 (RIReg src) g0,
+           ADD True False g0 (RIImm (ImmInt 0)) dst]
+    in
+    returnUs (Any IntRep code__2)
+
+condIntReg NE x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp1 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp2 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       src1  = registerName register1 tmp1
+       code2 = registerCode register2 tmp2 asmVoid
+       src2  = registerName register2 tmp2
+       code__2 dst = asmParThen [code1, code2] . mkSeqInstrs [
+           XOR False src1 (RIReg src2) dst,
+           SUB False True g0 (RIReg dst) g0,
+           ADD True False g0 (RIImm (ImmInt 0)) dst]
+    in
+    returnUs (Any IntRep code__2)
+
+condIntReg cond x y
+  = getUniqLabelNCG            `thenUs` \ lbl1 ->
+    getUniqLabelNCG            `thenUs` \ lbl2 ->
+    condIntCode cond x y       `thenUs` \ condition ->
+    let
+       code = condCode condition
+       cond = condName condition
+       code__2 dst = code . mkSeqInstrs [
+           BI cond False (ImmCLbl lbl1), NOP,
+           OR False g0 (RIImm (ImmInt 0)) dst,
+           BI ALWAYS False (ImmCLbl lbl2), NOP,
+           LABEL lbl1,
+           OR False g0 (RIImm (ImmInt 1)) dst,
+           LABEL lbl2]
+    in
+    returnUs (Any IntRep code__2)
+
+condFltReg cond x y
+  = getUniqLabelNCG            `thenUs` \ lbl1 ->
+    getUniqLabelNCG            `thenUs` \ lbl2 ->
+    condFltCode cond x y       `thenUs` \ condition ->
+    let
+       code = condCode condition
+       cond = condName condition
+       code__2 dst = code . mkSeqInstrs [
+           NOP,
+           BF cond False (ImmCLbl lbl1), NOP,
+           OR False g0 (RIImm (ImmInt 0)) dst,
+           BI ALWAYS False (ImmCLbl lbl2), NOP,
+           LABEL lbl1,
+           OR False g0 (RIImm (ImmInt 1)) dst,
+           LABEL lbl2]
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsubsection{@trivial*Code@: deal with trivial instructions}
+%*                                                                     *
+%************************************************************************
+
+Trivial (dyadic: @trivialCode@, floating-point: @trivialFCode@, unary:
+@trivialUCode@, unary fl-pt:@trivialUFCode@) instructions.  Only look
+for constants on the right hand side, because that's where the generic
+optimizer will have put them.
+
+Similarly, for unary instructions, we don't have to worry about
+matching an StInt as the argument, because genericOpt will already
+have handled the constant-folding.
+
+\begin{code}
+trivialCode
+    :: IF_ARCH_alpha((Reg -> RI -> Reg -> Instr)
+      ,IF_ARCH_i386 ((Operand -> Operand -> Instr)
+      ,IF_ARCH_sparc((Reg -> RI -> Reg -> Instr)
+      ,)))
+    -> StixTree -> StixTree -- the two arguments
+    -> UniqSM Register
+
+trivialFCode
+    :: PrimRep
+    -> IF_ARCH_alpha((Reg -> Reg -> Reg -> Instr)
+      ,IF_ARCH_sparc((Size -> Reg -> Reg -> Reg -> Instr)
+      ,IF_ARCH_i386 (
+             {-this bizarre type for i386 seems a little too weird (WDP 96/03)-}
+              (Size -> Operand -> Instr)
+           -> (Size -> Operand -> Instr) {-reversed instr-}
+           -> Instr {-pop-}
+           -> Instr {-reversed instr: pop-}
+      ,)))
+    -> StixTree -> StixTree -- the two arguments
+    -> UniqSM Register
+
+trivialUCode
+    :: IF_ARCH_alpha((RI -> Reg -> Instr)
+      ,IF_ARCH_i386 ((Operand -> Instr)
+      ,IF_ARCH_sparc((RI -> Reg -> Instr)
+      ,)))
+    -> StixTree        -- the one argument
+    -> UniqSM Register
+
+trivialUFCode
+    :: PrimRep
+    -> IF_ARCH_alpha((Reg -> Reg -> Instr)
+      ,IF_ARCH_i386 (Instr
+      ,IF_ARCH_sparc((Reg -> Reg -> Instr)
+      ,)))
+    -> StixTree -- the one argument
+    -> UniqSM Register
+
+#if alpha_TARGET_ARCH
+
+trivialCode instr x (StInt y)
+  | fits8Bits y
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src1 = registerName register tmp
+       src2 = ImmInt (fromInteger y)
+       code__2 dst = code . mkSeqInstr (instr src1 (RIImm src2) dst)
+    in
+    returnUs (Any IntRep code__2)
+
+trivialCode instr x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp1 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp2 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       src1  = registerName register1 tmp1
+       code2 = registerCode register2 tmp2 asmVoid
+       src2  = registerName register2 tmp2
+       code__2 dst = asmParThen [code1, code2] .
+                    mkSeqInstr (instr src1 (RIReg src2) dst)
+    in
+    returnUs (Any IntRep code__2)
+
+------------
+trivialUCode instr x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src  = registerName register tmp
+       code__2 dst = code . mkSeqInstr (instr (RIReg src) dst)
+    in
+    returnUs (Any IntRep code__2)
+
+------------
+trivialFCode _ instr x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG DoubleRep     `thenUs` \ tmp1 ->
+    getNewRegNCG DoubleRep     `thenUs` \ tmp2 ->
+    let
+       code1 = registerCode register1 tmp1
+       src1  = registerName register1 tmp1
+
+       code2 = registerCode register2 tmp2
+       src2  = registerName register2 tmp2
+
+       code__2 dst = asmParThen [code1 asmVoid, code2 asmVoid] .
+                     mkSeqInstr (instr src1 src2 dst)
+    in
+    returnUs (Any DoubleRep code__2)
+
+trivialUFCode _ instr x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG DoubleRep     `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src  = registerName register tmp
+       code__2 dst = code . mkSeqInstr (instr src dst)
+    in
+    returnUs (Any DoubleRep code__2)
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+trivialCode instr x y
+  | maybeToBool imm
+  = getRegister x              `thenUs` \ register1 ->
+    --getNewRegNCG IntRep      `thenUs` \ tmp1 ->
+    let
+       fixedname  = registerName register1 eax
+       code__2 dst = let code1 = registerCode register1 dst
+                         src1  = registerName register1 dst
+                     in code1 .
+                        if isFixed register1 && src1 /= dst
+                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
+                                          instr (OpImm imm__2) (OpReg dst)]
+                        else
+                               mkSeqInstrs [instr (OpImm imm__2) (OpReg src1)]
+    in
+    returnUs (Any IntRep code__2)
+  where
+    imm = maybeImm y
+    imm__2 = case imm of Just x -> x
+
+trivialCode instr x y
+  | maybeToBool imm
+  = getRegister y              `thenUs` \ register1 ->
+    --getNewRegNCG IntRep      `thenUs` \ tmp1 ->
+    let
+       fixedname  = registerName register1 eax
+       code__2 dst = let code1 = registerCode register1 dst
+                         src1  = registerName register1 dst
+                     in code1 .
+                        if isFixed register1 && src1 /= dst
+                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
+                                          instr (OpImm imm__2) (OpReg dst)]
+                        else
+                               mkSeqInstr (instr (OpImm imm__2) (OpReg src1))
+    in
+    returnUs (Any IntRep code__2)
+  where
+    imm = maybeImm x
+    imm__2 = case imm of Just x -> x
+
+trivialCode instr x (StInd pk mem)
+  = getRegister x              `thenUs` \ register ->
+    --getNewRegNCG IntRep      `thenUs` \ tmp ->
+    getAmode mem               `thenUs` \ amode ->
+    let
+       fixedname  = registerName register eax
+       code2 = amodeCode amode asmVoid
+       src2  = amodeAddr amode
+       code__2 dst = let code1 = registerCode register dst asmVoid
+                         src1  = registerName register dst
+                     in asmParThen [code1, code2] .
+                        if isFixed register && src1 /= dst
+                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
+                                          instr (OpAddr src2)  (OpReg dst)]
+                        else
+                               mkSeqInstr (instr (OpAddr src2) (OpReg src1))
+    in
+    returnUs (Any pk code__2)
+
+trivialCode instr (StInd pk mem) y
+  = getRegister y              `thenUs` \ register ->
+    --getNewRegNCG IntRep      `thenUs` \ tmp ->
+    getAmode mem               `thenUs` \ amode ->
+    let
+       fixedname  = registerName register eax
+       code2 = amodeCode amode asmVoid
+       src2  = amodeAddr amode
+       code__2 dst = let
+                         code1 = registerCode register dst asmVoid
+                         src1  = registerName register dst
+                     in asmParThen [code1, code2] .
+                        if isFixed register && src1 /= dst
+                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
+                                          instr (OpAddr src2)  (OpReg dst)]
+                        else
+                               mkSeqInstr (instr (OpAddr src2) (OpReg src1))
+    in
+    returnUs (Any pk code__2)
+
+trivialCode instr x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    --getNewRegNCG IntRep      `thenUs` \ tmp1 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp2 ->
+    let
+       fixedname  = registerName register1 eax
+       code2 = registerCode register2 tmp2 asmVoid
+       src2  = registerName register2 tmp2
+       code__2 dst = let
+                         code1 = registerCode register1 dst asmVoid
+                         src1  = registerName register1 dst
+                     in asmParThen [code1, code2] .
+                        if isFixed register1 && src1 /= dst
+                        then mkSeqInstrs [MOV L (OpReg src1) (OpReg dst),
+                                          instr (OpReg src2)  (OpReg dst)]
+                        else
+                               mkSeqInstr (instr (OpReg src2) (OpReg src1))
+    in
+    returnUs (Any IntRep code__2)
+
+-----------
+trivialUCode instr x
+  = getRegister x              `thenUs` \ register ->
+--    getNewRegNCG IntRep      `thenUs` \ tmp ->
+    let
+--     fixedname = registerName register eax
+       code__2 dst = let
+                         code = registerCode register dst
+                         src  = registerName register dst
+                     in code . if isFixed register && dst /= src
+                               then mkSeqInstrs [MOV L (OpReg src) (OpReg dst),
+                                                 instr (OpReg dst)]
+                               else mkSeqInstr (instr (OpReg src))
+    in
+    returnUs (Any IntRep code__2)
+
+-----------
+trivialFCode pk _ instrr _ _ (StInd pk' mem) y
+  = getRegister y              `thenUs` \ register2 ->
+    --getNewRegNCG (registerRep register2)
+    --                         `thenUs` \ tmp2 ->
+    getAmode mem               `thenUs` \ amode ->
+    let
+       code1 = amodeCode amode
+       src1  = amodeAddr amode
+
+       code__2 dst = let
+                         code2 = registerCode register2 dst
+                         src2  = registerName register2 dst
+                     in asmParThen [code1 asmVoid,code2 asmVoid] .
+                        mkSeqInstrs [instrr (primRepToSize pk) (OpAddr src1)]
+    in
+    returnUs (Any pk code__2)
+
+trivialFCode pk instr _ _ _ x (StInd pk' mem)
+  = getRegister x              `thenUs` \ register1 ->
+    --getNewRegNCG (registerRep register1)
+    --                         `thenUs` \ tmp1 ->
+    getAmode mem               `thenUs` \ amode ->
+    let
+       code2 = amodeCode amode
+       src2  = amodeAddr amode
+
+       code__2 dst = let
+                         code1 = registerCode register1 dst
+                         src1  = registerName register1 dst
+                     in asmParThen [code2 asmVoid,code1 asmVoid] .
+                        mkSeqInstrs [instr (primRepToSize pk) (OpAddr src2)]
+    in
+    returnUs (Any pk code__2)
+
+trivialFCode pk _ _ _ instrpr x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    --getNewRegNCG (registerRep register1)
+    --                         `thenUs` \ tmp1 ->
+    --getNewRegNCG (registerRep register2)
+    --                         `thenUs` \ tmp2 ->
+    getNewRegNCG DoubleRep     `thenUs` \ tmp ->
+    let
+       pk1   = registerRep register1
+       code1 = registerCode register1 st0 --tmp1
+       src1  = registerName register1 st0 --tmp1
+
+       pk2   = registerRep register2
+
+       code__2 dst = let
+                         code2 = registerCode register2 dst
+                         src2  = registerName register2 dst
+                     in asmParThen [code1 asmVoid, code2 asmVoid] .
+                        mkSeqInstr instrpr
+    in
+    returnUs (Any pk1 code__2)
+
+-------------
+trivialUFCode pk instr (StInd pk' mem)
+  = getAmode mem               `thenUs` \ amode ->
+    let
+       code = amodeCode amode
+       src  = amodeAddr amode
+       code__2 dst = code . mkSeqInstrs [FLD (primRepToSize pk) (OpAddr src),
+                                         instr]
+    in
+    returnUs (Any pk code__2)
+
+trivialUFCode pk instr x
+  = getRegister x              `thenUs` \ register ->
+    --getNewRegNCG pk          `thenUs` \ tmp ->
+    let
+       code__2 dst = let
+                         code = registerCode register dst
+                         src  = registerName register dst
+                     in code . mkSeqInstrs [instr]
+    in
+    returnUs (Any pk code__2)
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+trivialCode instr x (StInt y)
+  | fits13Bits y
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src1 = registerName register tmp
+       src2 = ImmInt (fromInteger y)
+       code__2 dst = code . mkSeqInstr (instr src1 (RIImm src2) dst)
+    in
+    returnUs (Any IntRep code__2)
+
+trivialCode instr x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp1 ->
+    getNewRegNCG IntRep                `thenUs` \ tmp2 ->
+    let
+       code1 = registerCode register1 tmp1 asmVoid
+       src1  = registerName register1 tmp1
+       code2 = registerCode register2 tmp2 asmVoid
+       src2  = registerName register2 tmp2
+       code__2 dst = asmParThen [code1, code2] .
+                    mkSeqInstr (instr src1 (RIReg src2) dst)
+    in
+    returnUs (Any IntRep code__2)
+
+------------
+trivialFCode pk instr x y
+  = getRegister x              `thenUs` \ register1 ->
+    getRegister y              `thenUs` \ register2 ->
+    getNewRegNCG (registerRep register1)
+                               `thenUs` \ tmp1 ->
+    getNewRegNCG (registerRep register2)
+                               `thenUs` \ tmp2 ->
+    getNewRegNCG DoubleRep     `thenUs` \ tmp ->
+    let
+       promote x = asmInstr (FxTOy F DF x tmp)
+
+       pk1   = registerRep register1
+       code1 = registerCode register1 tmp1
+       src1  = registerName register1 tmp1
+
+       pk2   = registerRep register2
+       code2 = registerCode register2 tmp2
+       src2  = registerName register2 tmp2
+
+       code__2 dst =
+               if pk1 == pk2 then
+                   asmParThen [code1 asmVoid, code2 asmVoid] .
+                   mkSeqInstr (instr (primRepToSize pk) src1 src2 dst)
+               else if pk1 == FloatRep then
+                   asmParThen [code1 (promote src1), code2 asmVoid] .
+                   mkSeqInstr (instr DF tmp src2 dst)
+               else
+                   asmParThen [code1 asmVoid, code2 (promote src2)] .
+                   mkSeqInstr (instr DF src1 tmp dst)
+    in
+    returnUs (Any (if pk1 == pk2 then pk1 else DoubleRep) code__2)
+
+------------
+trivialUCode instr x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src  = registerName register tmp
+       code__2 dst = code . mkSeqInstr (instr (RIReg src) dst)
+    in
+    returnUs (Any IntRep code__2)
+
+-------------
+trivialUFCode pk instr x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG pk            `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src  = registerName register tmp
+       code__2 dst = code . mkSeqInstr (instr src dst)
+    in
+    returnUs (Any pk code__2)
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsubsection{Coercing to/from integer/floating-point...}
+%*                                                                     *
+%************************************************************************
+
+@coerce(Int|Flt)Code@ are simple coercions that don't require any code
+to be generated.  Here we just change the type on the Register passed
+on up.  The code is machine-independent.
+
+@coerce(Int2FP|FP2Int)@ are more complicated integer/float
+conversions.  We have to store temporaries in memory to move
+between the integer and the floating point register sets.
+
+\begin{code}
+coerceIntCode :: PrimRep -> StixTree -> UniqSM Register
+coerceFltCode ::           StixTree -> UniqSM Register
+
+coerceInt2FP :: PrimRep -> StixTree -> UniqSM Register
+coerceFP2Int ::           StixTree -> UniqSM Register
+
+coerceIntCode pk x
+  = getRegister x              `thenUs` \ register ->
+    returnUs (
+    case register of
+       Fixed _ reg code -> Fixed pk reg code
+       Any   _ code     -> Any   pk code
+    )
+
+-------------
+coerceFltCode x
+  = getRegister x              `thenUs` \ register ->
+    returnUs (
+    case register of
+       Fixed _ reg code -> Fixed DoubleRep reg code
+       Any   _ code     -> Any   DoubleRep code
+    )
+\end{code}
+
+\begin{code}
+#if alpha_TARGET_ARCH
+
+coerceInt2FP _ x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ reg ->
+    let
+       code = registerCode register reg
+       src  = registerName register reg
+
+       code__2 dst = code . mkSeqInstrs [
+           ST Q src (spRel 0),
+           LD TF dst (spRel 0),
+           CVTxy Q TF dst dst]
+    in
+    returnUs (Any DoubleRep code__2)
+
+-------------
+coerceFP2Int x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG DoubleRep     `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src  = registerName register tmp
+
+       code__2 dst = code . mkSeqInstrs [
+           CVTxy TF Q src tmp,
+           ST TF tmp (spRel 0),
+           LD Q dst (spRel 0)]
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+coerceInt2FP pk x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ reg ->
+    let
+       code = registerCode register reg
+       src  = registerName register reg
+
+       code__2 dst = code . mkSeqInstrs [
+       -- to fix: should spill instead of using R1
+                     MOV L (OpReg src) (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1))),
+                     FILD (primRepToSize pk) (Addr (Just ebx) Nothing (ImmInt OFFSET_R1)) dst]
+    in
+    returnUs (Any pk code__2)
+
+------------
+coerceFP2Int x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG DoubleRep     `thenUs` \ tmp ->
+    let
+       code = registerCode register tmp
+       src  = registerName register tmp
+       pk   = registerRep register
+
+       code__2 dst = let
+                     in code . mkSeqInstrs [
+                               FRNDINT,
+                               FIST L (Addr (Just ebx) Nothing (ImmInt OFFSET_R1)),
+                               MOV L (OpAddr (Addr (Just ebx) Nothing (ImmInt OFFSET_R1))) (OpReg dst)]
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+coerceInt2FP pk x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ reg ->
+    let
+       code = registerCode register reg
+       src  = registerName register reg
+
+       code__2 dst = code . mkSeqInstrs [
+           ST W src (spRel (-2)),
+           LD W (spRel (-2)) dst,
+           FxTOy W (primRepToSize pk) dst dst]
+    in
+    returnUs (Any pk code__2)
+
+------------
+coerceFP2Int x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ reg ->
+    getNewRegNCG FloatRep      `thenUs` \ tmp ->
+    let
+       code = registerCode register reg
+       src  = registerName register reg
+       pk   = registerRep  register
+
+       code__2 dst = code . mkSeqInstrs [
+           FxTOy (primRepToSize pk) W src tmp,
+           ST W tmp (spRel (-2)),
+           LD W (spRel (-2)) dst]
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsubsection{Coercing integer to @Char@...}
+%*                                                                     *
+%************************************************************************
+
+Integer to character conversion.  Where applicable, we try to do this
+in one step if the original object is in memory.
+
+\begin{code}
+chrCode :: StixTree -> UniqSM Register
+
+#if alpha_TARGET_ARCH
+
+chrCode x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ reg ->
+    let
+       code = registerCode register reg
+       src  = registerName register reg
+       code__2 dst = code . mkSeqInstr (ZAPNOT src (RIImm (ImmInt 1)) dst)
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+chrCode x
+  = getRegister x              `thenUs` \ register ->
+    --getNewRegNCG IntRep      `thenUs` \ reg ->
+    let
+       fixedname = registerName register eax
+       code__2 dst = let
+                         code = registerCode register dst
+                         src  = registerName register dst
+                     in code .
+                        if isFixed register && src /= dst
+                        then mkSeqInstrs [MOV L (OpReg src) (OpReg dst),
+                                          AND L (OpImm (ImmInt 255)) (OpReg dst)]
+                        else mkSeqInstr (AND L (OpImm (ImmInt 255)) (OpReg src))
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+chrCode (StInd pk mem)
+  = getAmode mem               `thenUs` \ amode ->
+    let
+       code    = amodeCode amode
+       src     = amodeAddr amode
+       src_off = addrOffset src 3
+       src__2  = case src_off of Just x -> x
+       code__2 dst = if maybeToBool src_off then
+                       code . mkSeqInstr (LD BU src__2 dst)
+                   else
+                       code . mkSeqInstrs [
+                           LD (primRepToSize pk) src dst,
+                           AND False dst (RIImm (ImmInt 255)) dst]
+    in
+    returnUs (Any pk code__2)
+
+chrCode x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ reg ->
+    let
+       code = registerCode register reg
+       src  = registerName register reg
+       code__2 dst = code . mkSeqInstr (AND False src (RIImm (ImmInt 255)) dst)
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsubsection{Absolute value on integers}
+%*                                                                     *
+%************************************************************************
+
+Absolute value on integers, mostly for gmp size check macros.  Again,
+the argument cannot be an StInt, because genericOpt already folded
+constants.
+
+If applicable, do not fill the delay slots here; you will confuse the
+register allocator.
+
+\begin{code}
+absIntCode :: StixTree -> UniqSM Register
+
+#if alpha_TARGET_ARCH
+absIntCode = panic "MachCode.absIntCode: not on Alphas"
+#endif {- alpha_TARGET_ARCH -}
+
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+absIntCode x
+  = getRegister x              `thenUs` \ register ->
+    --getNewRegNCG IntRep      `thenUs` \ reg ->
+    getUniqLabelNCG            `thenUs` \ lbl ->
+    let
+       code__2 dst = let code = registerCode register dst
+                         src  = registerName register dst
+                     in code . if isFixed register && dst /= src
+                               then mkSeqInstrs [MOV L (OpReg src) (OpReg dst),
+                                                 TEST L (OpReg dst) (OpReg dst),
+                                                 JXX GE lbl,
+                                                 NEGI L (OpReg dst),
+                                                 LABEL lbl]
+                               else mkSeqInstrs [TEST L (OpReg src) (OpReg src),
+                                                 JXX GE lbl,
+                                                 NEGI L (OpReg src),
+                                                 LABEL lbl]
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+absIntCode x
+  = getRegister x              `thenUs` \ register ->
+    getNewRegNCG IntRep                `thenUs` \ reg ->
+    getUniqLabelNCG            `thenUs` \ lbl ->
+    let
+       code = registerCode register reg
+       src  = registerName register reg
+       code__2 dst = code . mkSeqInstrs [
+           SUB False True g0 (RIReg src) dst,
+           BI GE False (ImmCLbl lbl), NOP,
+           OR False g0 (RIReg src) dst,
+           LABEL lbl]
+    in
+    returnUs (Any IntRep code__2)
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
diff --git a/ghc/compiler/nativeGen/MachDesc.lhs b/ghc/compiler/nativeGen/MachDesc.lhs
deleted file mode 100644 (file)
index c89d228..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1993-1995
-%
-
-Machine- and flag- specific bits that the abstract code generator has
-to know about.
-
-No doubt there will be more...
-
-\begin{code}
-#include "HsVersions.h"
-
-module MachDesc (
-       Target(..){-(..) for target_STRICT only-}, mkTarget, RegLoc(..),
-
-       saveLoc,
-
-       fixedHeaderSize, varHeaderSize, stgReg,
-       sizeof, volatileSaves, volatileRestores, hpRel,
-       amodeToStix, amodeToStix', charLikeClosureSize,
-       intLikeClosureSize, mutHS, dataHS, primToStix, macroCode,
-       heapCheck
-
-       -- and, for self-sufficiency...
-    ) where
-
-import AbsCSyn
-import CmdLineOpts  ( GlobalSwitch(..), stringSwitchSet, switchIsOn, SwitchResult(..) )
-import Outputable
-import OrdList     ( OrdList )
-import SMRep       ( SMRep )
-import Stix
-import UniqSupply
-import Unique
-import Unpretty            ( PprStyle, CSeq )
-import Util
-
-data RegLoc = Save StixTree | Always StixTree
-\end{code}
-
-Think of this as a big runtime class dictionary:
-\begin{code}
-data Target = Target
-    Int                                -- fixedHeaderSize
-    (SMRep -> Int)                             -- varHeaderSize
-    (MagicId -> RegLoc)                -- stgReg
-    (PrimRep -> Int)                   -- sizeof
-    (HeapOffset -> Int)                        -- hpRel
-    (CAddrMode -> StixTree)            -- amodeToStix
-    (CAddrMode -> StixTree)            -- amodeToStix'
-    (
-    ([MagicId] -> [StixTree]),         -- volatileSaves
-    ([MagicId] -> [StixTree]),         -- volatileRestores
-    Int,                               -- charLikeClosureSize
-    Int,                               -- intLikeClosureSize
-    StixTree,                          -- mutHS
-    StixTree,                          -- dataHS
-    ([CAddrMode] -> PrimOp -> [CAddrMode] -> UniqSM StixTreeList),
-                                       -- primToStix
-    (CStmtMacro -> [CAddrMode] -> UniqSM StixTreeList),
-                                       -- macroCode
-    (StixTree -> StixTree -> StixTree -> UniqSM StixTreeList)
-                                       -- heapCheck
-    )
-
-mkTarget = Target
-
-fixedHeaderSize (Target fhs vhs reg size hprel am am' ~(vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) = fhs
-varHeaderSize (Target fhs vhs reg size hprel am am' ~(vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x = vhs x
-stgReg (Target fhs vhs reg size hprel am am' ~(vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x = reg x
-sizeof (Target fhs vhs reg size hprel am am' ~(vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x = size x
--- used only for wrapper-hungry PrimOps:
-hpRel (Target fhs vhs reg size hprel am am' ~(vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x = hprel x
-amodeToStix (Target fhs vhs reg size hprel am am' ~(vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x = am x
-amodeToStix' (Target fhs vhs reg size hprel am am' ~(vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x = am' x
-
-volatileSaves (Target fhs vhs reg size hprel am am' (vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x = vsave x
--- used only for wrapper-hungry PrimOps:
-volatileRestores (Target fhs vhs reg size hprel am am' (vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x = vrest x
-charLikeClosureSize (Target fhs vhs reg size hprel am am' (vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) = csz
-intLikeClosureSize (Target fhs vhs reg size hprel am am' (vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) = isz
-mutHS (Target fhs vhs reg size hprel am am' (vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) = mhs
-dataHS (Target fhs vhs reg size hprel am am' (vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) = dhs
-primToStix (Target fhs vhs reg size hprel am am' (vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x y z = ps x y z
-macroCode (Target fhs vhs reg size hprel am am' (vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x y = mc x y
-heapCheck (Target fhs vhs reg size hprel am am' (vsave, vrest, csz, isz, mhs, dhs, ps, mc, hc) ) x y z = hc x y z
-\end{code}
-
-Trees for register save locations
-\begin{code}
-saveLoc :: Target -> MagicId -> StixTree
-
-saveLoc target reg = case stgReg target reg of {Always loc -> loc; Save loc -> loc}
-\end{code}
-
diff --git a/ghc/compiler/nativeGen/MachMisc.lhs b/ghc/compiler/nativeGen/MachMisc.lhs
new file mode 100644 (file)
index 0000000..add0ada
--- /dev/null
@@ -0,0 +1,676 @@
+%
+% (c) The AQUA Project, Glasgow University, 1993-1996
+%
+\section[MachMisc]{Description of various machine-specific things}
+
+\begin{code}
+#include "HsVersions.h"
+#include "nativeGen/NCG.h"
+
+module MachMisc (
+
+       fixedHdrSizeInWords, varHdrSizeInWords,
+       charLikeSize, intLikeSize, mutHS, dataHS,
+       sizeOf, primRepToSize,
+
+       eXTRA_STK_ARGS_HERE,
+
+       volatileSaves, volatileRestores,
+
+       storageMgrInfo, smCAFlist, smOldLim, smOldMutables,
+       smStablePtrTable,
+
+       targetMaxDouble, targetMaxInt, targetMinDouble, targetMinInt,
+
+       underscorePrefix,
+       fmtAsmLbl,
+       cvtLitLit,
+       exactLog2,
+
+       Instr(..),  IF_ARCH_i386(Operand(..) COMMA,)
+       Cond(..),
+       Size(..)
+       
+#if alpha_TARGET_ARCH
+       , RI(..)
+#endif
+#if i386_TARGET_ARCH
+#endif
+#if sparc_TARGET_ARCH
+       , RI(..), riZero
+#endif
+    ) where
+
+import Ubiq{-uitous-}
+import AbsCLoop                ( fixedHdrSizeInWords, varHdrSizeInWords ) -- paranoia
+import NcgLoop         ( underscorePrefix, fmtAsmLbl ) -- paranoia
+
+import AbsCSyn         ( MagicId(..) ) 
+import AbsCUtils       ( magicIdPrimRep )
+import CmdLineOpts     ( opt_SccProfilingOn )
+import Literal         ( mkMachInt, Literal(..) )
+import MachRegs                ( stgReg, callerSaves, RegLoc(..),
+                         Imm(..), Reg(..), Addr
+                       )
+import OrdList         ( OrdList )
+import PrimRep         ( PrimRep(..) )
+import SMRep           ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
+import Stix            ( StixTree(..), StixReg(..), sStLitLbl,
+                         CodeSegment
+                       )
+import Util            ( panic )
+\end{code}
+
+\begin{code}
+underscorePrefix :: Bool   -- leading underscore on labels?
+
+underscorePrefix
+  = IF_ARCH_alpha(False
+    ,{-else-} IF_ARCH_i386(
+       IF_OS_linuxaout(True
+       , IF_OS_freebsd(True
+       , IF_OS_bsdi(True
+       , {-otherwise-} False)))
+     ,{-else-}IF_ARCH_sparc(
+       IF_OS_sunos4(True, {-otherwise-} False)
+     ,)))
+
+---------------------------
+fmtAsmLbl :: String -> String  -- for formatting labels
+
+fmtAsmLbl s
+  =  IF_ARCH_alpha(
+     {- The alpha assembler likes temporary labels to look like $L123
+       instead of L123.  (Don't toss the L, because then Lf28
+       turns into $f28.)
+     -}
+     '$' : s
+     ,{-otherwise-}
+     s
+     )
+
+---------------------------
+cvtLitLit :: String -> String
+
+-- ToDo: some kind of *careful* attention needed...
+
+cvtLitLit "stdin"  = IF_ARCH_alpha("_iob+0" {-probably OK...-}
+                   ,IF_ARCH_i386("_IO_stdin_"
+                   ,IF_ARCH_sparc("__iob+0x0"{-probably OK...-}
+                   ,)))
+cvtLitLit "stdout" = IF_ARCH_alpha("_iob+56"{-dodgy *at best*...-}
+                   ,IF_ARCH_i386("_IO_stdout_"
+                   ,IF_ARCH_sparc("__iob+0x14"{-dodgy *at best*...-}
+                   ,)))
+cvtLitLit "stderr" = IF_ARCH_alpha("_iob+112"{-dodgy *at best*...-}
+                   ,IF_ARCH_i386("_IO_stderr_"
+                   ,IF_ARCH_sparc("__iob+0x28"{-dodgy *at best*...-}
+                   ,)))
+cvtLitLit s
+  | isHex s   = s
+  | otherwise = error ("Native code generator can't handle ``" ++ s ++ "''")
+  where
+    isHex ('0':'x':xs) = all isHexDigit xs
+    isHex _ = False
+    -- Now, where have I seen this before?
+    isHexDigit c = isDigit c || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'
+\end{code}
+
+% ----------------------------------------------------------------
+
+We (allegedly) put the first six C-call arguments in registers;
+where do we start putting the rest of them?
+\begin{code}
+eXTRA_STK_ARGS_HERE :: Int
+eXTRA_STK_ARGS_HERE
+  = IF_ARCH_alpha(0, IF_ARCH_i386(23{-6x4bytes-}, IF_ARCH_sparc(23,???)))
+\end{code}
+
+% ----------------------------------------------------------------
+
+@fixedHdrSizeInWords@ and @varHdrSizeInWords@: these are not dependent
+on target architecture.
+\begin{code}
+fixedHdrSizeInWords :: Int
+
+fixedHdrSizeInWords
+  = 1{-info ptr-} + profFHS + parFHS + tickyFHS
+    -- obviously, we aren't taking non-sequential too seriously yet
+  where
+    profFHS  = if opt_SccProfilingOn then 1 else 0
+    parFHS   = {-if PAR or GRAN then 1 else-} 0
+    tickyFHS = {-if ticky ... then 1 else-} 0
+
+varHdrSizeInWords :: SMRep -> Int{-in words-}
+
+varHdrSizeInWords sm
+  = case sm of
+    StaticRep _ _         -> 0
+    SpecialisedRep _ _ _ _ -> 0
+    GenericRep _ _ _      -> 0
+    BigTupleRep _         -> 1
+    MuTupleRep _          -> 2 {- (1 + GC_MUT_RESERVED_WORDS) -}
+    DataRep _             -> 1
+    DynamicRep            -> 2
+    BlackHoleRep          -> 0
+    PhantomRep            -> panic "MachMisc.varHdrSizeInWords:phantom"
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+Static closure sizes:
+\begin{code}
+charLikeSize, intLikeSize :: Int
+
+charLikeSize = blahLikeSize CharLikeRep
+intLikeSize  = blahLikeSize IntLikeRep
+
+blahLikeSize blah
+  = fromInteger (sizeOf PtrRep)
+  * (fixedHdrSizeInWords + varHdrSizeInWords blahLikeRep + 1)
+  where
+    blahLikeRep = SpecialisedRep blah 0 1 SMNormalForm
+
+--------
+mutHS, dataHS :: StixTree
+
+mutHS  = blah_hs (MuTupleRep 0)
+dataHS = blah_hs (DataRep 0)
+
+blah_hs blah
+  = StInt (toInteger words)
+  where
+    words = fixedHdrSizeInWords + varHdrSizeInWords blah
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+Size of a @PrimRep@, in bytes.
+
+\begin{code}
+sizeOf :: PrimRep -> Integer{-in bytes-}
+    -- the result is an Integer only because it's more convenient
+
+sizeOf pr = case (primRepToSize pr) of
+  IF_ARCH_alpha({B -> 1; BU -> 1; {-W -> 2; WU -> 2; L -> 4; SF -> 4;-} _ -> 8},)
+  IF_ARCH_sparc({B -> 1; BU -> 1; {-HW -> 2; HWU -> 2;-} W -> 4; {-D -> 8;-} F -> 4; DF -> 8},)
+  IF_ARCH_i386( {B -> 1; {-S -> 2;-} L -> 4; F -> 4; DF -> 8 },)
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+Now the volatile saves and restores.  We add the basic guys to the
+list of ``user'' registers provided.  Note that there are more basic
+registers on the restore list, because some are reloaded from
+constants.
+
+(@volatileRestores@ used only for wrapper-hungry PrimOps.)
+
+\begin{code}
+volatileSaves, volatileRestores :: [MagicId] -> [StixTree]
+
+save_cands    = [BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg]
+restore_cands = save_cands ++ [StkStubReg,StdUpdRetVecReg]
+
+volatileSaves vols
+  = map save ((filter callerSaves) (save_cands ++ vols))
+  where
+    save x = StAssign (magicIdPrimRep x) loc reg
+      where
+       reg = StReg (StixMagicId x)
+       loc = case stgReg x of
+               Save loc -> loc
+               Always _ -> panic "volatileSaves"
+
+volatileRestores vols
+  = map restore ((filter callerSaves) (restore_cands ++ vols))
+  where
+    restore x = StAssign (magicIdPrimRep x) reg loc
+      where
+       reg = StReg (StixMagicId x)
+       loc = case stgReg x of
+               Save loc -> loc
+               Always _ -> panic "volatileRestores"
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+Obviously slightly weedy
+(Note that the floating point values aren't terribly important.)
+ToDo: Fix!(JSM)
+\begin{code}
+targetMinDouble = MachDouble (-1.7976931348623157e+308)
+targetMaxDouble = MachDouble (1.7976931348623157e+308)
+targetMinInt = mkMachInt (-2147483647)
+targetMaxInt = mkMachInt 2147483647
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+Storage manager nonsense.  Note that the indices are dependent on
+the definition of the smInfo structure in SMinterface.lh
+
+\begin{code}
+storageMgrInfo, smCAFlist, smOldMutables, smOldLim :: StixTree
+
+storageMgrInfo   = sStLitLbl SLIT("StorageMgrInfo")
+smCAFlist        = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_CAFLIST))
+smOldMutables    = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_OLDMUTABLES))
+smOldLim         = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_OLDLIM))
+smStablePtrTable = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_STABLEPOINTERTABLE))
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+This algorithm for determining the $\log_2$ of exact powers of 2 comes
+from GCC.  It requires bit manipulation primitives, and we use GHC
+extensions.  Tough.
+
+\begin{code}
+w2i x = word2Int# x
+i2w x = int2Word# x
+i2w_s x = (x::Int#)
+
+exactLog2 :: Integer -> Maybe Integer
+exactLog2 x
+  = if (x <= 0 || x >= 2147483648) then
+       Nothing
+    else
+       case (fromInteger x) of { I# x# ->
+       if (w2i ((i2w x#) `and#` (i2w (0# -# x#))) /=# x#) then
+         Nothing
+       else
+         Just (toInteger (I# (pow2 x#)))
+       }
+  where
+    shiftr x y = shiftRA# x y
+
+    pow2 x# | x# ==# 1# = 0#
+            | otherwise = 1# +# pow2 (w2i (i2w x# `shiftr` i2w_s 1#))
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+\begin{code}
+data Cond
+#if alpha_TARGET_ARCH
+  = ALWAYS     -- For BI (same as BR)
+  | EQ         -- For CMP and BI
+  | GE         -- For BI only
+  | GT         -- For BI only
+  | LE         -- For CMP and BI
+  | LT         -- For CMP and BI
+  | NE         -- For BI only
+  | NEVER      -- For BI (null instruction)
+  | ULE                -- For CMP only
+  | ULT                -- For CMP only
+#endif
+#if i386_TARGET_ARCH
+  = ALWAYS     -- What's really used? ToDo
+  | EQ
+  | GE
+  | GEU
+  | GT
+  | GU
+  | LE
+  | LEU
+  | LT
+  | LU
+  | NE
+  | NEG
+  | POS
+#endif
+#if sparc_TARGET_ARCH
+  = ALWAYS     -- What's really used? ToDo
+  | EQ
+  | GE
+  | GEU
+  | GT
+  | GU
+  | LE
+  | LEU
+  | LT
+  | LU
+  | NE
+  | NEG
+  | NEVER
+  | POS
+  | VC
+  | VS
+#endif
+\end{code}
+
+\begin{code}
+data Size
+#if alpha_TARGET_ARCH
+    = B            -- byte
+    | BU
+--  | W            -- word (2 bytes): UNUSED
+--  | WU    -- : UNUSED
+--  | L            -- longword (4 bytes): UNUSED
+    | Q            -- quadword (8 bytes)
+--  | FF    -- VAX F-style floating pt: UNUSED
+--  | GF    -- VAX G-style floating pt: UNUSED
+--  | DF    -- VAX D-style floating pt: UNUSED
+--  | SF    -- IEEE single-precision floating pt: UNUSED
+    | TF    -- IEEE double-precision floating pt
+#endif
+#if i386_TARGET_ARCH
+    = B            -- byte (lower)
+--  | HB    -- higher byte **UNUSED**
+--  | S            -- : UNUSED
+    | L
+    | F            -- IEEE single-precision floating pt
+    | DF    -- IEEE single-precision floating pt
+#endif
+#if sparc_TARGET_ARCH
+    = B     -- byte (signed)
+    | BU    -- byte (unsigned)
+--  | HW    -- halfword, 2 bytes (signed): UNUSED
+--  | HWU   -- halfword, 2 bytes (unsigned): UNUSED
+    | W            -- word, 4 bytes
+--  | D            -- doubleword, 8 bytes: UNUSED
+    | F            -- IEEE single-precision floating pt
+    | DF    -- IEEE single-precision floating pt
+#endif
+
+primRepToSize :: PrimRep -> Size
+
+primRepToSize PtrRep       = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize CodePtrRep    = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize DataPtrRep    = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize RetRep       = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize CostCentreRep = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize CharRep      = IF_ARCH_alpha( BU, IF_ARCH_i386( L, IF_ARCH_sparc( BU,)))
+primRepToSize IntRep       = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize WordRep      = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize AddrRep      = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize FloatRep     = IF_ARCH_alpha( TF, IF_ARCH_i386( F, IF_ARCH_sparc( F ,)))
+primRepToSize DoubleRep            = IF_ARCH_alpha( TF, IF_ARCH_i386( DF,IF_ARCH_sparc( DF,)))
+primRepToSize ArrayRep     = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize ByteArrayRep  = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize StablePtrRep  = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize MallocPtrRep  = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Machine's assembly language}
+%*                                                                     *
+%************************************************************************
+
+We have a few common ``instructions'' (nearly all the pseudo-ops) but
+mostly all of @Instr@ is machine-specific.
+
+\begin{code}
+data Instr
+  = COMMENT FAST_STRING                -- comment pseudo-op
+  | SEGMENT CodeSegment                -- {data,text} segment pseudo-op
+  | LABEL   CLabel             -- global label pseudo-op
+  | ASCII   Bool               -- True <=> needs backslash conversion
+           String              -- the literal string
+  | DATA    Size
+           [Imm]
+\end{code}
+
+\begin{code}
+#if alpha_TARGET_ARCH
+
+-- data Instr continues...
+
+-- Loads and stores.
+
+             | LD            Size Reg Addr -- size, dst, src
+             | LDA           Reg Addr      -- dst, src
+             | LDAH          Reg Addr      -- dst, src
+             | LDGP          Reg Addr      -- dst, src
+             | LDI           Size Reg Imm  -- size, dst, src
+             | ST            Size Reg Addr -- size, src, dst
+
+-- Int Arithmetic.
+
+             | CLR           Reg                   -- dst
+             | ABS           Size RI Reg           -- size, src, dst
+             | NEG           Size Bool RI Reg      -- size, overflow, src, dst
+             | ADD           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
+             | SADD          Size Size Reg RI Reg  -- size, scale, src, src, dst
+             | SUB           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
+             | SSUB          Size Size Reg RI Reg  -- size, scale, src, src, dst
+             | MUL           Size Bool Reg RI Reg  -- size, overflow, src, src, dst
+             | DIV           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
+             | REM           Size Bool Reg RI Reg  -- size, unsigned, src, src, dst
+
+-- Simple bit-twiddling.
+
+             | NOT           RI Reg
+             | AND           Reg RI Reg
+             | ANDNOT        Reg RI Reg
+             | OR            Reg RI Reg
+             | ORNOT         Reg RI Reg
+             | XOR           Reg RI Reg
+             | XORNOT        Reg RI Reg
+             | SLL           Reg RI Reg
+             | SRL           Reg RI Reg
+             | SRA           Reg RI Reg
+
+             | ZAP           Reg RI Reg
+             | ZAPNOT        Reg RI Reg
+
+             | NOP
+
+-- Comparison
+
+             | CMP           Cond Reg RI Reg
+
+-- Float Arithmetic.
+
+             | FCLR          Reg
+             | FABS          Reg Reg
+             | FNEG          Size Reg Reg
+             | FADD          Size Reg Reg Reg
+             | FDIV          Size Reg Reg Reg
+             | FMUL          Size Reg Reg Reg
+             | FSUB          Size Reg Reg Reg
+             | CVTxy         Size Size Reg Reg
+             | FCMP          Size Cond Reg Reg Reg
+             | FMOV          Reg Reg
+
+-- Jumping around.
+
+             | BI            Cond Reg Imm
+             | BF            Cond Reg Imm
+             | BR            Imm
+             | JMP           Reg Addr Int
+             | BSR           Imm Int
+             | JSR           Reg Addr Int
+
+-- Alpha-specific pseudo-ops.
+
+             | FUNBEGIN CLabel
+             | FUNEND CLabel
+
+data RI
+  = RIReg Reg
+  | RIImm Imm
+
+#endif {- alpha_TARGET_ARCH -}
+\end{code}
+
+\begin{code}
+#if i386_TARGET_ARCH
+
+-- data Instr continues...
+
+-- Moves.
+
+             | MOV           Size Operand Operand
+             | MOVZX         Size Operand Operand -- size is the size of operand 2
+             | MOVSX         Size Operand Operand -- size is the size of operand 2
+
+-- Load effective address (also a very useful three-operand add instruction :-)
+
+             | LEA           Size Operand Operand
+
+-- Int Arithmetic.
+
+             | ADD           Size Operand Operand
+             | SUB           Size Operand Operand
+
+-- Multiplication (signed and unsigned), Division (signed and unsigned),
+-- result in %eax, %edx.
+
+             | IMUL          Size Operand Operand
+             | IDIV          Size Operand
+
+-- Simple bit-twiddling.
+
+             | AND           Size Operand Operand
+             | OR            Size Operand Operand
+             | XOR           Size Operand Operand
+             | NOT           Size Operand
+             | NEGI          Size Operand -- NEG instruction (name clash with Cond)
+             | SHL           Size Operand Operand -- 1st operand must be an Imm
+             | SAR           Size Operand Operand -- 1st operand must be an Imm
+             | SHR           Size Operand Operand -- 1st operand must be an Imm
+             | NOP
+
+-- Float Arithmetic. -- ToDo for 386
+
+-- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
+-- right up until we spit them out.
+
+             | SAHF          -- stores ah into flags
+             | FABS
+             | FADD          Size Operand -- src
+             | FADDP
+             | FIADD         Size Addr -- src
+             | FCHS
+             | FCOM          Size Operand -- src
+             | FCOS
+             | FDIV          Size Operand -- src
+             | FDIVP
+             | FIDIV         Size Addr -- src
+             | FDIVR         Size Operand -- src
+             | FDIVRP
+             | FIDIVR        Size Addr -- src
+             | FICOM         Size Addr -- src
+             | FILD          Size Addr Reg -- src, dst
+             | FIST          Size Addr -- dst
+             | FLD           Size Operand -- src
+             | FLD1
+             | FLDZ
+             | FMUL          Size Operand -- src
+             | FMULP
+             | FIMUL         Size Addr -- src
+             | FRNDINT
+             | FSIN
+             | FSQRT
+             | FST           Size Operand -- dst
+             | FSTP          Size Operand -- dst
+             | FSUB          Size Operand -- src
+             | FSUBP
+             | FISUB         Size Addr -- src
+             | FSUBR         Size Operand -- src
+             | FSUBRP
+             | FISUBR        Size Addr -- src
+             | FTST
+             | FCOMP         Size Operand -- src
+             | FUCOMPP
+             | FXCH
+             | FNSTSW
+             | FNOP
+
+-- Comparison
+
+             | TEST          Size Operand Operand
+             | CMP           Size Operand Operand
+             | SETCC         Cond Operand
+
+-- Stack Operations.
+
+             | PUSH          Size Operand
+             | POP           Size Operand
+
+-- Jumping around.
+
+             | JMP           Operand -- target
+             | JXX           Cond CLabel -- target
+             | CALL          Imm
+
+-- Other things.
+
+             | CLTD -- sign extend %eax into %edx:%eax
+
+data Operand
+  = OpReg  Reg -- register
+  | OpImm  Imm -- immediate value
+  | OpAddr Addr        -- memory reference
+
+#endif {- i386_TARGET_ARCH -}
+\end{code}
+
+\begin{code}
+#if sparc_TARGET_ARCH
+
+-- data Instr continues...
+
+-- Loads and stores.
+
+             | LD            Size Addr Reg -- size, src, dst
+             | ST            Size Reg Addr -- size, src, dst
+
+-- Int Arithmetic.
+
+             | ADD           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
+             | SUB           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
+
+-- Simple bit-twiddling.
+
+             | AND           Bool Reg RI Reg -- cc?, src1, src2, dst
+             | ANDN          Bool Reg RI Reg -- cc?, src1, src2, dst
+             | OR            Bool Reg RI Reg -- cc?, src1, src2, dst
+             | ORN           Bool Reg RI Reg -- cc?, src1, src2, dst
+             | XOR           Bool Reg RI Reg -- cc?, src1, src2, dst
+             | XNOR          Bool Reg RI Reg -- cc?, src1, src2, dst
+             | SLL           Reg RI Reg -- src1, src2, dst
+             | SRL           Reg RI Reg -- src1, src2, dst
+             | SRA           Reg RI Reg -- src1, src2, dst
+             | SETHI         Imm Reg -- src, dst
+             | NOP           -- Really SETHI 0, %g0, but worth an alias
+
+-- Float Arithmetic.
+
+-- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
+-- right up until we spit them out.
+
+             | FABS          Size Reg Reg -- src dst
+             | FADD          Size Reg Reg Reg -- src1, src2, dst
+             | FCMP          Bool Size Reg Reg -- exception?, src1, src2, dst
+             | FDIV          Size Reg Reg Reg -- src1, src2, dst
+             | FMOV          Size Reg Reg -- src, dst
+             | FMUL          Size Reg Reg Reg -- src1, src2, dst
+             | FNEG          Size Reg Reg -- src, dst
+             | FSQRT         Size Reg Reg -- src, dst
+             | FSUB          Size Reg Reg Reg -- src1, src2, dst
+             | FxTOy         Size Size Reg Reg -- src, dst
+
+-- Jumping around.
+
+             | BI            Cond Bool Imm -- cond, annul?, target
+             | BF            Cond Bool Imm -- cond, annul?, target
+
+             | JMP           Addr -- target
+             | CALL          Imm Int Bool -- target, args, terminal
+
+data RI = RIReg Reg
+       | RIImm Imm
+
+riZero :: RI -> Bool
+
+riZero (RIImm (ImmInt 0))          = True
+riZero (RIImm (ImmInteger 0))      = True
+riZero (RIReg (FixedReg ILIT(0)))   = True
+riZero _                           = False
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
diff --git a/ghc/compiler/nativeGen/MachRegs.lhs b/ghc/compiler/nativeGen/MachRegs.lhs
new file mode 100644 (file)
index 0000000..b122217
--- /dev/null
@@ -0,0 +1,1022 @@
+%
+% (c) The AQUA Project, Glasgow University, 1996
+%
+\section[MachRegs]{Machine-specific info about registers}
+
+Also includes stuff about immediate operands, which are
+often/usually quite entangled with registers.
+
+(Immediates could be untangled from registers at some cost in tangled
+modules --- the pleasure has been foregone.)
+
+\begin{code}
+#include "HsVersions.h"
+#include "nativeGen/NCG.h"
+
+module MachRegs (
+
+       Reg(..),
+       Imm(..),
+       Addr(..),
+       RegLoc(..),
+       RegNo(..),
+
+       addrOffset,
+       argRegs,
+       baseRegOffset,
+       callClobberedRegs,
+       callerSaves,
+       dblImmLit,
+       extractMappedRegNos,
+       freeMappedRegs,
+       freeReg, freeRegs,
+       getNewRegNCG,
+       magicIdRegMaybe,
+       mkReg,
+       realReg,
+       reservedRegs,
+       saveLoc,
+       spRel,
+       stgReg,
+       strImmLit
+
+#if alpha_TARGET_ARCH
+       , allArgRegs
+       , fits8Bits
+       , fReg
+       , gp, pv, ra, sp, t9, t10, t11, t12, v0, f0, zero
+#endif
+#if i386_TARGET_ARCH
+       , eax, ebx, ecx, edx, esi, esp
+       , st0, st1, st2, st3, st4, st5, st6, st7
+#endif
+#if sparc_TARGET_ARCH
+       , allArgRegs
+       , fits13Bits
+       , fPair, fpRel, gReg, iReg, lReg, oReg, largeOffsetError
+       , fp, g0, o0, f0
+       
+#endif
+    ) where
+
+import Ubiq{-uitous-}
+
+import AbsCSyn         ( MagicId(..) )
+import AbsCUtils       ( magicIdPrimRep )
+import Pretty          ( ppStr, ppRational, ppShow )
+import PrimOp          ( PrimOp(..) )
+import PrimRep         ( PrimRep(..) )
+import Stix            ( sStLitLbl, StixTree(..), StixReg(..),
+                         CodeSegment
+                       )
+import Unique          ( Unique{-instance Ord3-} )
+import UniqSupply      ( mkPseudoUnique1, mkPseudoUnique2, mkPseudoUnique3,
+                         getUnique, returnUs, thenUs, UniqSM(..)
+                       )
+import Unpretty                ( uppStr, Unpretty(..) )
+import Util            ( panic )
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+\begin{code}
+data Imm
+  = ImmInt     Int
+  | ImmInteger Integer     -- Sigh.
+  | ImmCLbl    CLabel      -- AbstractC Label (with baggage)
+  | ImmLab     Unpretty    -- Simple string label (underscore-able)
+  | ImmLit     Unpretty    -- Simple string
+  IF_ARCH_sparc(
+  | LO Imm                 -- Possible restrictions...
+  | HI Imm
+  ,)
+
+strImmLit s = ImmLit (uppStr s)
+dblImmLit r
+  = strImmLit (
+        IF_ARCH_alpha({-prepend nothing-}
+       ,IF_ARCH_i386( '0' : 'd' :
+       ,IF_ARCH_sparc('0' : 'r' :,)))
+       ppShow 80 (ppRational r))
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+\begin{code}
+data Addr
+#if alpha_TARGET_ARCH
+  = AddrImm    Imm
+  | AddrReg    Reg
+  | AddrRegImm Reg Imm
+#endif
+
+#if i386_TARGET_ARCH
+  = Addr       Base Index Displacement
+  | ImmAddr    Imm Int
+
+type Base         = Maybe Reg
+type Index        = Maybe (Reg, Int)   -- Int is 2, 4 or 8
+type Displacement = Imm
+#endif
+
+#if sparc_TARGET_ARCH
+  = AddrRegReg Reg Reg
+  | AddrRegImm Reg Imm
+#endif
+
+addrOffset :: Addr -> Int -> Maybe Addr
+
+addrOffset addr off
+  = case addr of
+#if alpha_TARGET_ARCH
+      _ -> panic "MachMisc.addrOffset not defined for Alpha"
+#endif
+#if i386_TARGET_ARCH
+      ImmAddr i off0     -> Just (ImmAddr i (off0 + off))
+      Addr r i (ImmInt n) -> Just (Addr r i (ImmInt (n + off)))
+      Addr r i (ImmInteger n)
+       -> Just (Addr r i (ImmInt (fromInteger (n + toInteger off))))
+      _ -> Nothing
+#endif
+#if sparc_TARGET_ARCH
+      AddrRegImm r (ImmInt n)
+       | fits13Bits n2 -> Just (AddrRegImm r (ImmInt n2))
+       | otherwise     -> Nothing
+       where n2 = n + off
+
+      AddrRegImm r (ImmInteger n)
+       | fits13Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
+       | otherwise     -> Nothing
+       where n2 = n + toInteger off
+
+      AddrRegReg r (FixedReg ILIT(0))
+       | fits13Bits off -> Just (AddrRegImm r (ImmInt off))
+       | otherwise     -> Nothing
+       
+      _ -> Nothing
+
+#endif {-sparc-}
+
+-----------------
+#if alpha_TARGET_ARCH
+
+fits8Bits :: Integer -> Bool
+fits8Bits i = i >= -256 && i < 256
+
+#endif
+
+#if sparc_TARGET_ARCH
+{-# SPECIALIZE
+    fits13Bits :: Int -> Bool
+  #-}
+{-# SPECIALIZE
+    fits13Bits :: Integer -> Bool
+  #-}
+
+fits13Bits :: Integral a => a -> Bool
+fits13Bits x = x >= -4096 && x < 4096
+
+-----------------
+largeOffsetError i
+  = error ("ERROR: SPARC native-code generator cannot handle large offset ("++show i++");\nprobably because of large constant data structures;\nworkaround: use -fvia-C on this module.\n")
+
+#endif {-sparc-}
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+@stgReg@: we map STG registers onto appropriate Stix Trees.  First, we
+handle the two constants, @STK_STUB_closure@ and @vtbl_StdUpdFrame@.
+The rest are either in real machine registers or stored as offsets
+from BaseReg.
+
+\begin{code}
+data RegLoc = Save StixTree | Always StixTree
+\end{code}
+
+Trees for register save locations:
+\begin{code}
+saveLoc :: MagicId -> StixTree
+
+saveLoc reg = case (stgReg reg) of {Always loc -> loc; Save loc -> loc}
+\end{code}
+
+\begin{code}
+stgReg :: MagicId -> RegLoc
+
+stgReg x
+  = case (magicIdRegMaybe x) of
+       Just _  -> Save   nonReg
+       Nothing -> Always nonReg
+  where
+    offset = baseRegOffset x
+
+    baseLoc = case (magicIdRegMaybe BaseReg) of
+      Just _  -> StReg (StixMagicId BaseReg)
+      Nothing -> sStLitLbl SLIT("MainRegTable")
+
+    nonReg = case x of
+      StkStubReg       -> sStLitLbl SLIT("STK_STUB_closure")
+      StdUpdRetVecReg  -> sStLitLbl SLIT("vtbl_StdUpdFrame")
+      BaseReg          -> sStLitLbl SLIT("MainRegTable")
+       -- these Hp&HpLim cases perhaps should
+       -- not be here for i386 (???) WDP 96/03
+      Hp               -> StInd PtrRep (sStLitLbl SLIT("StorageMgrInfo"))
+      HpLim            -> StInd PtrRep (sStLitLbl
+                               (_PK_ ("StorageMgrInfo+" ++ BYTES_PER_WORD_STR)))
+      TagReg           -> StInd IntRep (StPrim IntSubOp [infoptr,
+                               StInt (1*BYTES_PER_WORD)])
+                       where
+                           r2      = VanillaReg PtrRep ILIT(2)
+                           infoptr = case (stgReg r2) of
+                                         Always t -> t
+                                         Save   _ -> StReg (StixMagicId r2)
+      _ -> StInd (magicIdPrimRep x)
+                (StPrim IntAddOp [baseLoc,
+                       StInt (toInteger (offset*BYTES_PER_WORD))])
+\end{code}
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+@spRel@ gives us a stack relative addressing mode for volatile
+temporaries and for excess call arguments.  @fpRel@, where
+applicable, is the same but for the frame pointer.
+
+\begin{code}
+spRel :: Int   -- desired stack offset in words, positive or negative
+      -> Addr
+
+spRel n
+#if i386_TARGET_ARCH
+  = Addr (Just esp) Nothing (ImmInt (n * BYTES_PER_WORD))
+#else
+  = AddrRegImm sp (ImmInt (n * BYTES_PER_WORD))
+#endif
+
+#if sparc_TARGET_ARCH
+fpRel :: Int -> Addr
+    -- Duznae work for offsets greater than 13 bits; we just hope for
+    -- the best
+fpRel n
+  = AddrRegImm fp (ImmInt (n * BYTES_PER_WORD))
+#endif
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection[Reg]{Real registers}
+%*                                                                     *
+%************************************************************************
+
+Static Registers correspond to actual machine registers.  These should
+be avoided until the last possible moment.
+
+Dynamic registers are allocated on the fly, usually to represent a single
+value in the abstract assembly code (i.e. dynamic registers are usually
+single assignment).  Ultimately, they are mapped to available machine
+registers before spitting out the code.
+
+\begin{code}
+data Reg
+  = FixedReg  FAST_INT         -- A pre-allocated machine register
+
+  | MappedReg FAST_INT         -- A dynamically allocated machine register
+
+  | MemoryReg Int PrimRep      -- A machine "register" actually held in
+                               -- a memory allocated table of
+                               -- registers which didn't fit in real
+                               -- registers.
+
+  | UnmappedReg Unique PrimRep -- One of an infinite supply of registers,
+                               -- always mapped to one of the earlier
+                               -- two (?)  before we're done.
+
+mkReg :: Unique -> PrimRep -> Reg
+mkReg = UnmappedReg
+
+getNewRegNCG :: PrimRep -> UniqSM Reg
+getNewRegNCG pk
+  = getUnique  `thenUs` \ u ->
+    returnUs (UnmappedReg u pk)
+
+instance Text Reg where
+    showsPrec _ (FixedReg i)   = showString "%"  . shows IBOX(i)
+    showsPrec _ (MappedReg i)  = showString "%"  . shows IBOX(i)
+    showsPrec _ (MemoryReg i _) = showString "%M"  . shows i
+    showsPrec _ (UnmappedReg i _) = showString "%U" . shows i
+
+#ifdef DEBUG
+instance Outputable Reg where
+    ppr sty r = ppStr (show r)
+#endif
+
+cmpReg (FixedReg i) (FixedReg i') = cmp_ihash i i'
+cmpReg (MappedReg i) (MappedReg i') = cmp_ihash i i'
+cmpReg (MemoryReg i _) (MemoryReg i' _) = cmp_i i i'
+cmpReg (UnmappedReg u _) (UnmappedReg u' _) = cmp u u'
+cmpReg r1 r2
+  = let tag1 = tagReg r1
+       tag2 = tagReg r2
+    in
+       if tag1 _LT_ tag2 then LT_ else GT_
+    where
+       tagReg (FixedReg _)      = (ILIT(1) :: FAST_INT)
+       tagReg (MappedReg _)     = ILIT(2)
+       tagReg (MemoryReg _ _)   = ILIT(3)
+       tagReg (UnmappedReg _ _) = ILIT(4)
+
+cmp_i :: Int -> Int -> TAG_
+cmp_i a1 a2 = if a1 == a2 then EQ_ else if a1 < a2 then LT_ else GT_
+
+cmp_ihash :: FAST_INT -> FAST_INT -> TAG_
+cmp_ihash a1 a2 = if a1 _EQ_ a2 then EQ_ else if a1 _LT_ a2 then LT_ else GT_
+
+instance Eq Reg where
+    a == b = case cmpReg a b of { EQ_ -> True;  _ -> False }
+    a /= b = case cmpReg a b of { EQ_ -> False; _ -> True  }
+
+instance Ord Reg where
+    a <= b = case cmpReg a b of { LT_ -> True; EQ_ -> True;  GT__ -> False }
+    a <         b = case cmpReg a b of { LT_ -> True;  EQ_ -> False; GT__ -> False }
+    a >= b = case cmpReg a b of { LT_ -> False; EQ_ -> True;  GT__ -> True  }
+    a >         b = case cmpReg a b of { LT_ -> False; EQ_ -> False; GT__ -> True  }
+    _tagCmp a b = case cmpReg a b of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
+
+instance NamedThing Reg where
+    -- the *only* method that should be defined is "getItsUnique"!
+    -- (so we can use UniqFMs/UniqSets on Regs
+    getItsUnique (UnmappedReg u _) = u
+    getItsUnique (FixedReg i)     = mkPseudoUnique1 IBOX(i)
+    getItsUnique (MappedReg i)    = mkPseudoUnique2 IBOX(i)
+    getItsUnique (MemoryReg i _)   = mkPseudoUnique3 i
+\end{code}
+
+\begin{code}
+type RegNo = Int
+
+realReg :: RegNo -> Reg
+realReg n@IBOX(i)
+  = if _IS_TRUE_(freeReg i) then MappedReg i else FixedReg i
+
+extractMappedRegNos :: [Reg] -> [RegNo]
+
+extractMappedRegNos regs
+  = foldr ex [] regs
+  where
+    ex (MappedReg i) acc = IBOX(i) : acc  -- we'll take it
+    ex _            acc = acc            -- leave it out
+\end{code}
+
+** Machine-specific Reg stuff: **
+
+The Alpha has 64 registers of interest; 32 integer registers and 32 floating
+point registers.  The mapping of STG registers to alpha machine registers
+is defined in StgRegs.h.  We are, of course, prepared for any eventuality.
+\begin{code}
+#if alpha_TARGET_ARCH
+fReg :: Int -> Int
+fReg x = (32 + x)
+
+v0, f0, ra, pv, gp, sp, zero :: Reg
+v0   = realReg 0
+f0   = realReg (fReg 0)
+ra   = FixedReg ILIT(26)
+pv   = t12
+gp   = FixedReg ILIT(29)
+sp   = FixedReg ILIT(30)
+zero = FixedReg ILIT(31)
+
+t9, t10, t11, t12 :: Reg
+t9  = realReg 23
+t10 = realReg 24
+t11 = realReg 25
+t12 = realReg 27
+#endif
+\end{code}
+
+Intel x86 architecture:
+- All registers except 7 (esp) are available for use.
+- Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
+- Registers 0-7 have 16-bit counterparts (ax, bx etc.)
+- Registers 0-3 have 8 bit counterparts (ah, bh etc.)
+- Registers 8-15 hold extended floating point values.
+\begin{code}
+#if i386_TARGET_ARCH
+
+gReg,fReg :: Int -> Int
+gReg x = x
+fReg x = (8 + x)
+
+st0, st1, st2, st3, st4, st5, st6, st7, eax, ebx, ecx, edx, esp :: Reg
+eax = case (gReg 0) of { IBOX(g0) -> FixedReg g0 }
+ebx = case (gReg 1) of { IBOX(g1) -> FixedReg g1 }
+ecx = case (gReg 2) of { IBOX(g2) -> FixedReg g2 }
+edx = case (gReg 3) of { IBOX(g3) -> FixedReg g3 }
+esi = case (gReg 4) of { IBOX(g4) -> FixedReg g4 }
+edi = case (gReg 5) of { IBOX(g5) -> FixedReg g5 }
+ebp = case (gReg 6) of { IBOX(g6) -> FixedReg g6 }
+esp = case (gReg 7) of { IBOX(g7) -> FixedReg g7 }
+st0 = realReg  (fReg 0)
+st1 = realReg  (fReg 1)
+st2 = realReg  (fReg 2)
+st3 = realReg  (fReg 3)
+st4 = realReg  (fReg 4)
+st5 = realReg  (fReg 5)
+st6 = realReg  (fReg 6)
+st7 = realReg  (fReg 7)
+
+#endif
+\end{code}
+
+The SPARC has 64 registers of interest; 32 integer registers and 32
+floating point registers.  The mapping of STG registers to SPARC
+machine registers is defined in StgRegs.h.  We are, of course,
+prepared for any eventuality.
+
+\begin{code}
+#if sparc_TARGET_ARCH
+
+gReg,lReg,iReg,oReg,fReg :: Int -> Int
+gReg x = x
+oReg x = (8 + x)
+lReg x = (16 + x)
+iReg x = (24 + x)
+fReg x = (32 + x)
+
+fPair :: Reg -> Reg
+fPair (FixedReg i) = FixedReg (i _ADD_ ILIT(1))
+fPair (MappedReg i) = MappedReg (i _ADD_ ILIT(1))
+
+g0, fp, sp, o0, f0 :: Reg
+g0 = case (gReg 0) of { IBOX(g0) -> FixedReg g0 }
+fp = case (iReg 6) of { IBOX(i6) -> FixedReg i6 }
+sp = case (oReg 6) of { IBOX(o6) -> FixedReg o6 }
+o0 = realReg  (oReg 0)
+f0 = realReg  (fReg 0)
+
+#endif
+\end{code}
+
+Redefine the literals used for machine-registers with non-numeric
+names in the header files.  Gag me with a spoon, eh?
+\begin{code}
+#if alpha_TARGET_ARCH
+#define f0 32
+#define f1 33
+#define f2 34
+#define f3 35
+#define f4 36
+#define f5 37
+#define f6 38
+#define f7 39
+#define f8 40
+#define f9 41
+#define f10 42
+#define f11 43
+#define f12 44
+#define f13 45
+#define f14 46
+#define f15 47
+#define f16 48
+#define f17 49
+#define f18 50
+#define f19 51
+#define f20 52
+#define f21 53
+#define f22 54
+#define f23 55
+#define f24 56
+#define f25 57
+#define f26 58
+#define f27 59
+#define f28 60
+#define f29 61
+#define f30 62
+#define f31 63
+#endif
+#if i386_TARGET_ARCH
+#define eax 0
+#define ebx 1
+#define ecx 2
+#define edx 3
+#define esi 4
+#define edi 5
+#define ebp 6
+#define esp 7
+#define st0 8
+#define st1 9
+#define st2 10
+#define st3 11
+#define st4 12
+#define st5 13
+#define st6 14
+#define st7 15
+#endif
+#if sparc_TARGET_ARCH
+#define g0 0
+#define g1 1
+#define g2 2
+#define g3 3
+#define g4 4
+#define g5 5
+#define g6 6
+#define g7 7
+#define o0 8
+#define o1 9
+#define o2 10
+#define o3 11
+#define o4 12
+#define o5 13
+#define o6 14
+#define o7 15
+#define l0 16
+#define l1 17
+#define l2 18
+#define l3 19
+#define l4 20
+#define l5 21
+#define l6 22
+#define l7 23
+#define i0 24
+#define i1 25
+#define i2 26
+#define i3 27
+#define i4 28
+#define i5 29
+#define i6 30
+#define i7 31
+#define f0 32
+#define f1 33
+#define f2 34
+#define f3 35
+#define f4 36
+#define f5 37
+#define f6 38
+#define f7 39
+#define f8 40
+#define f9 41
+#define f10 42
+#define f11 43
+#define f12 44
+#define f13 45
+#define f14 46
+#define f15 47
+#define f16 48
+#define f17 49
+#define f18 50
+#define f19 51
+#define f20 52
+#define f21 53
+#define f22 54
+#define f23 55
+#define f24 56
+#define f25 57
+#define f26 58
+#define f27 59
+#define f28 60
+#define f29 61
+#define f30 62
+#define f31 63
+#endif
+\end{code}
+
+\begin{code}
+baseRegOffset :: MagicId -> Int
+
+baseRegOffset StkOReg               = OFFSET_StkO
+baseRegOffset (VanillaReg _ ILIT(1)) = OFFSET_R1
+baseRegOffset (VanillaReg _ ILIT(2)) = OFFSET_R2
+baseRegOffset (VanillaReg _ ILIT(3)) = OFFSET_R3
+baseRegOffset (VanillaReg _ ILIT(4)) = OFFSET_R4
+baseRegOffset (VanillaReg _ ILIT(5)) = OFFSET_R5
+baseRegOffset (VanillaReg _ ILIT(6)) = OFFSET_R6
+baseRegOffset (VanillaReg _ ILIT(7)) = OFFSET_R7
+baseRegOffset (VanillaReg _ ILIT(8)) = OFFSET_R8
+baseRegOffset (FloatReg  ILIT(1))    = OFFSET_Flt1
+baseRegOffset (FloatReg  ILIT(2))    = OFFSET_Flt2
+baseRegOffset (FloatReg  ILIT(3))    = OFFSET_Flt3
+baseRegOffset (FloatReg  ILIT(4))    = OFFSET_Flt4
+baseRegOffset (DoubleReg ILIT(1))    = OFFSET_Dbl1
+baseRegOffset (DoubleReg ILIT(2))    = OFFSET_Dbl2
+baseRegOffset TagReg                = OFFSET_Tag
+baseRegOffset RetReg                = OFFSET_Ret
+baseRegOffset SpA                   = OFFSET_SpA
+baseRegOffset SuA                   = OFFSET_SuA
+baseRegOffset SpB                   = OFFSET_SpB
+baseRegOffset SuB                   = OFFSET_SuB
+baseRegOffset Hp                    = OFFSET_Hp
+baseRegOffset HpLim                 = OFFSET_HpLim
+baseRegOffset LivenessReg           = OFFSET_Liveness
+#ifdef DEBUG
+baseRegOffset BaseReg               = panic "baseRegOffset:BaseReg"
+baseRegOffset StdUpdRetVecReg       = panic "baseRegOffset:StgUpdRetVecReg"
+baseRegOffset StkStubReg            = panic "baseRegOffset:StkStubReg"
+baseRegOffset CurCostCentre         = panic "baseRegOffset:CurCostCentre"
+baseRegOffset VoidReg               = panic "baseRegOffset:VoidReg"
+#endif
+\end{code}
+
+\begin{code}
+callerSaves :: MagicId -> Bool
+
+#ifdef CALLER_SAVES_Base
+callerSaves BaseReg                    = True
+#endif
+#ifdef CALLER_SAVES_StkO
+callerSaves StkOReg                    = True
+#endif
+#ifdef CALLER_SAVES_R1
+callerSaves (VanillaReg _ ILIT(1))     = True
+#endif
+#ifdef CALLER_SAVES_R2
+callerSaves (VanillaReg _ ILIT(2))     = True
+#endif
+#ifdef CALLER_SAVES_R3
+callerSaves (VanillaReg _ ILIT(3))     = True
+#endif
+#ifdef CALLER_SAVES_R4
+callerSaves (VanillaReg _ ILIT(4))     = True
+#endif
+#ifdef CALLER_SAVES_R5
+callerSaves (VanillaReg _ ILIT(5))     = True
+#endif
+#ifdef CALLER_SAVES_R6
+callerSaves (VanillaReg _ ILIT(6))     = True
+#endif
+#ifdef CALLER_SAVES_R7
+callerSaves (VanillaReg _ ILIT(7))     = True
+#endif
+#ifdef CALLER_SAVES_R8
+callerSaves (VanillaReg _ ILIT(8))     = True
+#endif
+#ifdef CALLER_SAVES_FltReg1
+callerSaves (FloatReg ILIT(1))         = True
+#endif
+#ifdef CALLER_SAVES_FltReg2
+callerSaves (FloatReg ILIT(2))         = True
+#endif
+#ifdef CALLER_SAVES_FltReg3
+callerSaves (FloatReg ILIT(3))         = True
+#endif
+#ifdef CALLER_SAVES_FltReg4
+callerSaves (FloatReg ILIT(4))         = True
+#endif
+#ifdef CALLER_SAVES_DblReg1
+callerSaves (DoubleReg ILIT(1))                = True
+#endif
+#ifdef CALLER_SAVES_DblReg2
+callerSaves (DoubleReg ILIT(2))                = True
+#endif
+#ifdef CALLER_SAVES_Tag
+callerSaves TagReg                     = True
+#endif
+#ifdef CALLER_SAVES_Ret
+callerSaves RetReg                     = True
+#endif
+#ifdef CALLER_SAVES_SpA
+callerSaves SpA                                = True
+#endif
+#ifdef CALLER_SAVES_SuA
+callerSaves SuA                                = True
+#endif
+#ifdef CALLER_SAVES_SpB
+callerSaves SpB                                = True
+#endif
+#ifdef CALLER_SAVES_SuB
+callerSaves SuB                                = True
+#endif
+#ifdef CALLER_SAVES_Hp
+callerSaves Hp                         = True
+#endif
+#ifdef CALLER_SAVES_HpLim
+callerSaves HpLim                      = True
+#endif
+#ifdef CALLER_SAVES_Liveness
+callerSaves LivenessReg                        = True
+#endif
+#ifdef CALLER_SAVES_StdUpdRetVec
+callerSaves StdUpdRetVecReg            = True
+#endif
+#ifdef CALLER_SAVES_StkStub
+callerSaves StkStubReg                 = True
+#endif
+callerSaves _                          = False
+\end{code}
+
+\begin{code}
+magicIdRegMaybe :: MagicId -> Maybe Reg
+
+#ifdef REG_Base
+magicIdRegMaybe BaseReg                        = Just (FixedReg ILIT(REG_Base))
+#endif
+#ifdef REG_StkO
+magicIdRegMaybe StkOReg                        = Just (FixedReg ILIT(REG_StkOReg))
+#endif
+#ifdef REG_R1
+magicIdRegMaybe (VanillaReg _ ILIT(1))         = Just (FixedReg ILIT(REG_R1))
+#endif 
+#ifdef REG_R2 
+magicIdRegMaybe (VanillaReg _ ILIT(2))         = Just (FixedReg ILIT(REG_R2))
+#endif 
+#ifdef REG_R3 
+magicIdRegMaybe (VanillaReg _ ILIT(3))         = Just (FixedReg ILIT(REG_R3))
+#endif 
+#ifdef REG_R4 
+magicIdRegMaybe (VanillaReg _ ILIT(4))         = Just (FixedReg ILIT(REG_R4))
+#endif 
+#ifdef REG_R5 
+magicIdRegMaybe (VanillaReg _ ILIT(5))         = Just (FixedReg ILIT(REG_R5))
+#endif 
+#ifdef REG_R6 
+magicIdRegMaybe (VanillaReg _ ILIT(6))         = Just (FixedReg ILIT(REG_R6))
+#endif 
+#ifdef REG_R7 
+magicIdRegMaybe (VanillaReg _ ILIT(7))         = Just (FixedReg ILIT(REG_R7))
+#endif 
+#ifdef REG_R8 
+magicIdRegMaybe (VanillaReg _ ILIT(8))         = Just (FixedReg ILIT(REG_R8))
+#endif
+#ifdef REG_Flt1
+magicIdRegMaybe (FloatReg ILIT(1))     = Just (FixedReg ILIT(REG_Flt1))
+#endif                                 
+#ifdef REG_Flt2                                
+magicIdRegMaybe (FloatReg ILIT(2))     = Just (FixedReg ILIT(REG_Flt2))
+#endif                                 
+#ifdef REG_Flt3                                
+magicIdRegMaybe (FloatReg ILIT(3))     = Just (FixedReg ILIT(REG_Flt3))
+#endif                                 
+#ifdef REG_Flt4                                
+magicIdRegMaybe (FloatReg ILIT(4))     = Just (FixedReg ILIT(REG_Flt4))
+#endif                                 
+#ifdef REG_Dbl1                                
+magicIdRegMaybe (DoubleReg ILIT(1))    = Just (FixedReg ILIT(REG_Dbl1))
+#endif                                 
+#ifdef REG_Dbl2                                
+magicIdRegMaybe (DoubleReg ILIT(2))    = Just (FixedReg ILIT(REG_Dbl2))
+#endif
+#ifdef REG_Tag
+magicIdRegMaybe TagReg                 = Just (FixedReg ILIT(REG_TagReg))
+#endif     
+#ifdef REG_Ret     
+magicIdRegMaybe RetReg                 = Just (FixedReg ILIT(REG_Ret))
+#endif     
+#ifdef REG_SpA     
+magicIdRegMaybe SpA                    = Just (FixedReg ILIT(REG_SpA))
+#endif                                 
+#ifdef REG_SuA                         
+magicIdRegMaybe SuA                    = Just (FixedReg ILIT(REG_SuA))
+#endif                                 
+#ifdef REG_SpB                         
+magicIdRegMaybe SpB                    = Just (FixedReg ILIT(REG_SpB))
+#endif                                 
+#ifdef REG_SuB                         
+magicIdRegMaybe SuB                    = Just (FixedReg ILIT(REG_SuB))
+#endif                                 
+#ifdef REG_Hp                          
+magicIdRegMaybe Hp                     = Just (FixedReg ILIT(REG_Hp))
+#endif                                 
+#ifdef REG_HpLim                       
+magicIdRegMaybe HpLim                  = Just (FixedReg ILIT(REG_HpLim))
+#endif                                 
+#ifdef REG_Liveness                    
+magicIdRegMaybe LivenessReg            = Just (FixedReg ILIT(REG_Liveness))
+#endif                                 
+#ifdef REG_StdUpdRetVec                        
+magicIdRegMaybe StdUpdRetVecReg        = Just (FixedReg ILIT(REG_StdUpdRetVec))
+#endif                                 
+#ifdef REG_StkStub                     
+magicIdRegMaybe StkStubReg             = Just (FixedReg ILIT(REG_StkStub))
+#endif                                 
+magicIdRegMaybe _                      = Nothing
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Free, reserved, call-clobbered, and argument registers}
+%*                                                                     *
+%************************************************************************
+
+@freeRegs@ is the list of registers we can use in register allocation.
+@freeReg@ (below) says if a particular register is free.
+
+With a per-instruction clobber list, we might be able to get some of
+these back, but it's probably not worth the hassle.
+
+@callClobberedRegs@ ... the obvious.
+
+@argRegs@: assuming a call with N arguments, what registers will be
+used to hold arguments?  (NB: it doesn't know whether the arguments
+are integer or floating-point...)
+
+\begin{code}
+reservedRegs :: [RegNo]
+reservedRegs
+#if alpha_TARGET_ARCH
+  = [NCG_Reserved_I1, NCG_Reserved_I2,
+     NCG_Reserved_F1, NCG_Reserved_F2]
+#endif
+#if i386_TARGET_ARCH
+  = [{-certainly cannot afford any!-}]
+#endif
+#if sparc_TARGET_ARCH
+  = [NCG_Reserved_I1, NCG_Reserved_I2,
+     NCG_Reserved_F1, NCG_Reserved_F2,
+     NCG_Reserved_D1, NCG_Reserved_D2]
+#endif
+
+-------------------------------
+freeRegs :: [Reg]
+freeRegs
+  = freeMappedRegs IF_ARCH_alpha( [0..63],
+                  IF_ARCH_i386(  [0..15],
+                  IF_ARCH_sparc( [0..63],)))
+
+-------------------------------
+callClobberedRegs :: [Reg]
+callClobberedRegs
+  = freeMappedRegs
+#if alpha_TARGET_ARCH
+    [0, 1, 2, 3, 4, 5, 6, 7, 8,
+     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+     fReg 0, fReg 1, fReg 10, fReg 11, fReg 12, fReg 13, fReg 14, fReg 15,
+     fReg 16, fReg 17, fReg 18, fReg 19, fReg 20, fReg 21, fReg 22, fReg 23,
+     fReg 24, fReg 25, fReg 26, fReg 27, fReg 28, fReg 29, fReg 30]
+#endif {- alpha_TARGET_ARCH -}
+#if i386_TARGET_ARCH
+    [{-none-}]
+#endif {- i386_TARGET_ARCH -}
+#if sparc_TARGET_ARCH
+    ( oReg 7 :
+      [oReg i | i <- [0..5]] ++
+      [gReg i | i <- [1..7]] ++
+      [fReg i | i <- [0..31]] )
+#endif {- sparc_TARGET_ARCH -}
+
+-------------------------------
+argRegs :: Int -> [Reg]
+
+argRegs 0 = []
+#if alpha_TARGET_ARCH
+argRegs 1 = freeMappedRegs [16, fReg 16]
+argRegs 2 = freeMappedRegs [16, 17, fReg 16, fReg 17]
+argRegs 3 = freeMappedRegs [16, 17, 18, fReg 16, fReg 17, fReg 18]
+argRegs 4 = freeMappedRegs [16, 17, 18, 19, fReg 16, fReg 17, fReg 18, fReg 19]
+argRegs 5 = freeMappedRegs [16, 17, 18, 19, 20, fReg 16, fReg 17, fReg 18, fReg 19, fReg 20]
+argRegs 6 = freeMappedRegs [16, 17, 18, 19, 20, 21, fReg 16, fReg 17, fReg 18, fReg 19, fReg 20, fReg 21]
+#endif {- alpha_TARGET_ARCH -}
+#if i386_TARGET_ARCH
+argRegs _ = panic "MachRegs.argRegs: doesn't work on I386"
+#endif {- i386_TARGET_ARCH -}
+#if sparc_TARGET_ARCH
+argRegs 1 = freeMappedRegs (map oReg [0])
+argRegs 2 = freeMappedRegs (map oReg [0,1])
+argRegs 3 = freeMappedRegs (map oReg [0,1,2])
+argRegs 4 = freeMappedRegs (map oReg [0,1,2,3])
+argRegs 5 = freeMappedRegs (map oReg [0,1,2,3,4])
+argRegs 6 = freeMappedRegs (map oReg [0,1,2,3,4,5])
+#endif {- sparc_TARGET_ARCH -}
+argRegs _ = panic "MachRegs.argRegs: don't know about >6 arguments!"
+
+-------------------------------
+
+#if alpha_TARGET_ARCH
+allArgRegs :: [(Reg, Reg)]
+
+allArgRegs = [(realReg i, realReg (fReg i)) | i <- [16..21]]
+#endif {- alpha_TARGET_ARCH -}
+
+#if sparc_TARGET_ARCH
+allArgRegs :: [Reg]
+
+allArgRegs = map realReg [oReg i | i <- [0..5]]
+#endif {- sparc_TARGET_ARCH -}
+
+-------------------------------
+freeMappedRegs :: [Int] -> [Reg]
+
+freeMappedRegs nums
+  = foldr free [] nums
+  where
+    free IBOX(i) acc
+      = if _IS_TRUE_(freeReg i) then (MappedReg i) : acc else acc
+\end{code}
+
+\begin{code}
+freeReg :: FAST_INT -> FAST_BOOL
+
+#if alpha_TARGET_ARCH
+freeReg ILIT(26) = _FALSE_  -- return address (ra)
+freeReg ILIT(28) = _FALSE_  -- reserved for the assembler (at)
+freeReg ILIT(29) = _FALSE_  -- global pointer (gp)
+freeReg ILIT(30) = _FALSE_  -- stack pointer (sp)
+freeReg ILIT(31) = _FALSE_  -- always zero (zero)
+freeReg ILIT(63) = _FALSE_  -- always zero (f31)
+#endif
+
+#if i386_TARGET_ARCH
+freeReg ILIT(esp) = _FALSE_  --        %esp is the C stack pointer
+#endif
+
+#if sparc_TARGET_ARCH
+freeReg ILIT(g0) = _FALSE_  -- %g0 is always 0.
+freeReg ILIT(g5) = _FALSE_  -- %g5 is reserved (ABI).
+freeReg ILIT(g6) = _FALSE_  -- %g6 is reserved (ABI).
+freeReg ILIT(g7) = _FALSE_  -- %g7 is reserved (ABI).
+freeReg ILIT(i6) = _FALSE_  -- %i6 is our frame pointer.
+freeReg ILIT(o6) = _FALSE_  -- %o6 is our stack pointer.
+#endif
+
+#ifdef REG_Base
+freeReg ILIT(REG_Base) = _FALSE_
+#endif
+#ifdef REG_StkO
+freeReg ILIT(REG_StkO) = _FALSE_
+#endif
+#ifdef REG_R1
+freeReg ILIT(REG_R1)   = _FALSE_
+#endif 
+#ifdef REG_R2  
+freeReg ILIT(REG_R2)   = _FALSE_
+#endif 
+#ifdef REG_R3  
+freeReg ILIT(REG_R3)   = _FALSE_
+#endif 
+#ifdef REG_R4  
+freeReg ILIT(REG_R4)   = _FALSE_
+#endif 
+#ifdef REG_R5  
+freeReg ILIT(REG_R5)   = _FALSE_
+#endif 
+#ifdef REG_R6  
+freeReg ILIT(REG_R6)   = _FALSE_
+#endif 
+#ifdef REG_R7  
+freeReg ILIT(REG_R7)   = _FALSE_
+#endif 
+#ifdef REG_R8  
+freeReg ILIT(REG_R8)   = _FALSE_
+#endif
+#ifdef REG_Flt1
+freeReg ILIT(REG_Flt1) = _FALSE_
+#endif
+#ifdef REG_Flt2
+freeReg ILIT(REG_Flt2) = _FALSE_
+#endif
+#ifdef REG_Flt3
+freeReg ILIT(REG_Flt3) = _FALSE_
+#endif
+#ifdef REG_Flt4
+freeReg ILIT(REG_Flt4) = _FALSE_
+#endif
+#ifdef REG_Dbl1
+freeReg ILIT(REG_Dbl1) = _FALSE_
+#endif
+#ifdef REG_Dbl2
+freeReg ILIT(REG_Dbl2) = _FALSE_
+#endif
+#ifdef REG_Tag
+freeReg ILIT(REG_Tag)  = _FALSE_
+#endif 
+#ifdef REG_Ret 
+freeReg ILIT(REG_Ret)  = _FALSE_
+#endif 
+#ifdef REG_SpA 
+freeReg ILIT(REG_SpA)  = _FALSE_
+#endif 
+#ifdef REG_SuA 
+freeReg ILIT(REG_SuA)  = _FALSE_
+#endif 
+#ifdef REG_SpB 
+freeReg ILIT(REG_SpB)  = _FALSE_
+#endif 
+#ifdef REG_SuB 
+freeReg ILIT(REG_SuB)  = _FALSE_
+#endif 
+#ifdef REG_Hp 
+freeReg ILIT(REG_Hp)   = _FALSE_
+#endif
+#ifdef REG_HpLim
+freeReg ILIT(REG_HpLim) = _FALSE_
+#endif
+#ifdef REG_Liveness
+freeReg ILIT(REG_Liveness) = _FALSE_
+#endif
+#ifdef REG_StdUpdRetVec
+freeReg ILIT(REG_StdUpdRetVec) = _FALSE_
+#endif
+#ifdef REG_StkStub
+freeReg ILIT(REG_StkStub) = _FALSE_
+#endif
+freeReg _ = _TRUE_
+freeReg n
+  -- we hang onto two double regs for dedicated
+  -- use; this is not necessary on Alphas and
+  -- may not be on other non-SPARCs.
+#ifdef REG_Dbl1
+  | n _EQ_ (ILIT(REG_Dbl1) _ADD_ ILIT(1)) = _FALSE_
+#endif
+#ifdef REG_Dbl2
+  | n _EQ_ (ILIT(REG_Dbl2) _ADD_ ILIT(1)) = _FALSE_
+#endif
+  | otherwise = _TRUE_
+\end{code}
diff --git a/ghc/compiler/nativeGen/NCG.h b/ghc/compiler/nativeGen/NCG.h
new file mode 100644 (file)
index 0000000..4b3049b
--- /dev/null
@@ -0,0 +1,150 @@
+#ifndef NCG_H
+#define NCG_H
+
+#if 0
+
+IMPORTANT!  If you put extra tabs/spaces in these macro definitions,
+you will screw up the layout where they are used in case expressions!
+
+(This is cpp-dependent, of course)
+
+** Convenience macros for writing the native-code generator **
+
+#endif
+
+#define FAST_REG_NO FAST_INT
+
+#include "../../includes/platform.h"
+
+#if 0
+{-testing only-}
+#undef sparc_TARGET_ARCH
+#undef sunos4_TARGET_OS
+#undef i386_TARGET_ARCH
+#define i386_TARGET_ARCH 1
+#undef linuxaout_TARGET_OS
+#define linuxaout_TARGET_OS 1
+#endif
+#if 0
+{-testing only-}
+#undef sparc_TARGET_ARCH
+#undef sunos4_TARGET_OS
+#undef alpha_TARGET_ARCH
+#define alpha_TARGET_ARCH 1
+#endif
+
+#if i386_TARGET_ARCH
+# define STOLEN_X86_REGS 4
+-- HACK: go for the max
+#endif
+#include "../../includes/MachRegs.h"
+
+#if alpha_TARGET_ARCH
+# define BYTES_PER_WORD 8
+# define BYTES_PER_WORD_STR "8"
+
+# include "../../includes/alpha-dec-osf1.h"
+#endif
+
+#if i386_TARGET_ARCH
+# define BYTES_PER_WORD 4
+# define BYTES_PER_WORD_STR "4"
+
+# if linuxaout_TARGET_OS
+#  include "../../includes/i386-unknown-linuxaout.h"
+# endif
+# if linux_TARGET_OS
+#  include "../../includes/i386-unknown-linux.h"
+# endif
+# if freebsd_TARGET_OS
+#  include "../../includes/i386-unknown-freebsd.h"
+# endif
+# if netbsd_TARGET_OS
+#  include "../../includes/i386-unknown-netbsd.h"
+# endif
+# if bsdi_TARGET_OS
+#  include "../../includes/i386-unknown-bsdi.h"
+# endif
+# if solaris2_TARGET_OS
+#  include "../../includes/i386-unknown-solaris2.h"
+# endif
+#endif
+
+#if sparc_TARGET_ARCH
+# define BYTES_PER_WORD 4
+# define BYTES_PER_WORD_STR "4"
+
+# if sunos4_TARGET_OS
+#  include "../../includes/sparc-sun-sunos4.h"
+# endif
+# if solaris2_TARGET_OS
+#  include "../../includes/sparc-sun-solaris2.h"
+# endif
+#endif
+
+---------------------------------------------
+
+#if alpha_TARGET_ARCH
+# define IF_ARCH_alpha(x,y) x
+#else
+# define IF_ARCH_alpha(x,y) y
+#endif
+
+---------------------------------------------
+
+#if i386_TARGET_ARCH
+# define IF_ARCH_i386(x,y) x
+#else
+# define IF_ARCH_i386(x,y) y
+#endif
+-- - - - - - - - - - - - - - - - - - - - - - 
+#if freebsd_TARGET_OS
+# define IF_OS_freebsd(x,y) x
+#else
+# define IF_OS_freebsd(x,y) y
+#endif
+-- - - - - - - - - - - - - - - - - - - - - - 
+#if netbsd_TARGET_OS
+# define IF_OS_netbsd(x,y) x
+#else
+# define IF_OS_netbsd(x,y) y
+#endif
+-- - - - - - - - - - - - - - - - - - - - - - 
+#if linux_TARGET_OS
+# define IF_OS_linux(x,y) x
+#else
+# define IF_OS_linux(x,y) y
+#endif
+-- - - - - - - - - - - - - - - - - - - - - - 
+#if linuxaout_TARGET_OS
+# define IF_OS_linuxaout(x,y) x
+#else
+# define IF_OS_linuxaout(x,y) y
+#endif
+-- - - - - - - - - - - - - - - - - - - - - - 
+#if bsdi_TARGET_OS
+# define IF_OS_bsdi(x,y) x
+#else
+# define IF_OS_bsdi(x,y) y
+#endif
+---------------------------------------------
+#if sparc_TARGET_ARCH
+# define IF_ARCH_sparc(x,y) x
+#else
+# define IF_ARCH_sparc(x,y) y
+#endif
+-- - - - - - - - - - - - - - - - - - - - - - 
+#if sunos4_TARGET_OS
+# define IF_OS_sunos4(x,y) x
+#else
+# define IF_OS_sunos4(x,y) y
+#endif
+-- - - - - - - - - - - - - - - - - - - - - - 
+-- NB: this will catch i386-*-solaris2, too
+#if solaris2_TARGET_OS
+# define IF_OS_solaris2(x,y) x
+#else
+# define IF_OS_solaris2(x,y) y
+#endif
+---------------------------------------------
+#endif
diff --git a/ghc/compiler/nativeGen/NcgLoop.lhi b/ghc/compiler/nativeGen/NcgLoop.lhi
new file mode 100644 (file)
index 0000000..9086b31
--- /dev/null
@@ -0,0 +1,16 @@
+Breaks loops between Stix{Macro,Prim,Integer}.lhs.
+
+Also some CLabel dependencies on MachMisc.
+
+\begin{code}
+interface NcgLoop where
+
+import AbsCSyn         ( CAddrMode )
+import Stix            ( StixTree )
+import MachMisc                ( underscorePrefix, fmtAsmLbl )
+import StixPrim                ( amodeToStix )
+
+amodeToStix :: CAddrMode -> StixTree
+underscorePrefix :: Bool
+fmtAsmLbl :: [Char] -> [Char]
+\end{code}
diff --git a/ghc/compiler/nativeGen/PprMach.lhs b/ghc/compiler/nativeGen/PprMach.lhs
new file mode 100644 (file)
index 0000000..f1835a3
--- /dev/null
@@ -0,0 +1,1323 @@
+%
+% (c) The AQUA Project, Glasgow University, 1996
+%
+\section[PprMach]{Pretty-printing assembly language}
+
+We start with the @pprXXX@s with some cross-platform commonality
+(e.g., @pprReg@); we conclude with the no-commonality monster,
+@pprInstr@.
+
+\begin{code}
+#include "HsVersions.h"
+#include "nativeGen/NCG.h"
+
+module PprMach ( pprInstr ) where
+
+import Ubiq{-uitious-}
+
+import MachRegs                -- may differ per-platform
+import MachMisc
+
+import CLabel          ( pprCLabel_asm, externallyVisibleCLabel )
+import CStrings                ( charToC )
+import Maybes          ( maybeToBool )
+import OrdList         ( OrdList )
+import Stix            ( CodeSegment(..), StixTree )
+import Unpretty                -- all of it
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@pprReg@: print a @Reg@}
+%*                                                                     *
+%************************************************************************
+
+For x86, the way we print a register name depends
+on which bit of it we care about.  Yurgh.
+\begin{code}
+pprReg :: IF_ARCH_i386(Size ->,) Reg -> Unpretty
+
+pprReg IF_ARCH_i386(s,) r
+  = case r of
+      FixedReg  i -> ppr_reg_no IF_ARCH_i386(s,) i
+      MappedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
+      other      -> uppStr (show other)   -- should only happen when debugging
+  where
+#if alpha_TARGET_ARCH
+    ppr_reg_no :: FAST_REG_NO -> Unpretty
+    ppr_reg_no i = uppPStr
+      (case i of {
+       ILIT( 0) -> SLIT("$0");   ILIT( 1) -> SLIT("$1");
+       ILIT( 2) -> SLIT("$2");   ILIT( 3) -> SLIT("$3");
+       ILIT( 4) -> SLIT("$4");   ILIT( 5) -> SLIT("$5");
+       ILIT( 6) -> SLIT("$6");   ILIT( 7) -> SLIT("$7");
+       ILIT( 8) -> SLIT("$8");   ILIT( 9) -> SLIT("$9");
+       ILIT(10) -> SLIT("$10");  ILIT(11) -> SLIT("$11");
+       ILIT(12) -> SLIT("$12");  ILIT(13) -> SLIT("$13");
+       ILIT(14) -> SLIT("$14");  ILIT(15) -> SLIT("$15");
+       ILIT(16) -> SLIT("$16");  ILIT(17) -> SLIT("$17");
+       ILIT(18) -> SLIT("$18");  ILIT(19) -> SLIT("$19");
+       ILIT(20) -> SLIT("$20");  ILIT(21) -> SLIT("$21");
+       ILIT(22) -> SLIT("$22");  ILIT(23) -> SLIT("$23");
+       ILIT(24) -> SLIT("$24");  ILIT(25) -> SLIT("$25");
+       ILIT(26) -> SLIT("$26");  ILIT(27) -> SLIT("$27");
+       ILIT(28) -> SLIT("$28");  ILIT(29) -> SLIT("$29");
+       ILIT(30) -> SLIT("$30");  ILIT(31) -> SLIT("$31");
+       ILIT(32) -> SLIT("$f0");  ILIT(33) -> SLIT("$f1");
+       ILIT(34) -> SLIT("$f2");  ILIT(35) -> SLIT("$f3");
+       ILIT(36) -> SLIT("$f4");  ILIT(37) -> SLIT("$f5");
+       ILIT(38) -> SLIT("$f6");  ILIT(39) -> SLIT("$f7");
+       ILIT(40) -> SLIT("$f8");  ILIT(41) -> SLIT("$f9");
+       ILIT(42) -> SLIT("$f10"); ILIT(43) -> SLIT("$f11");
+       ILIT(44) -> SLIT("$f12"); ILIT(45) -> SLIT("$f13");
+       ILIT(46) -> SLIT("$f14"); ILIT(47) -> SLIT("$f15");
+       ILIT(48) -> SLIT("$f16"); ILIT(49) -> SLIT("$f17");
+       ILIT(50) -> SLIT("$f18"); ILIT(51) -> SLIT("$f19");
+       ILIT(52) -> SLIT("$f20"); ILIT(53) -> SLIT("$f21");
+       ILIT(54) -> SLIT("$f22"); ILIT(55) -> SLIT("$f23");
+       ILIT(56) -> SLIT("$f24"); ILIT(57) -> SLIT("$f25");
+       ILIT(58) -> SLIT("$f26"); ILIT(59) -> SLIT("$f27");
+       ILIT(60) -> SLIT("$f28"); ILIT(61) -> SLIT("$f29");
+       ILIT(62) -> SLIT("$f30"); ILIT(63) -> SLIT("$f31");
+       _ -> SLIT("very naughty alpha register")
+      })
+#endif
+#if i386_TARGET_ARCH
+    ppr_reg_no :: Size -> FAST_REG_NO -> Unpretty
+    ppr_reg_no B i = uppPStr
+      (case i of {
+       ILIT( 0) -> SLIT("%al");  ILIT( 1) -> SLIT("%bl");
+       ILIT( 2) -> SLIT("%cl");  ILIT( 3) -> SLIT("%dl");
+       _ -> SLIT("very naughty I386 byte register")
+      })
+
+    {- UNUSED:
+    ppr_reg_no HB i = uppPStr
+      (case i of {
+       ILIT( 0) -> SLIT("%ah");  ILIT( 1) -> SLIT("%bh");
+       ILIT( 2) -> SLIT("%ch");  ILIT( 3) -> SLIT("%dh");
+       _ -> SLIT("very naughty I386 high byte register")
+      })
+    -}
+
+{- UNUSED:
+    ppr_reg_no S i = uppPStr
+      (case i of {
+       ILIT( 0) -> SLIT("%ax");  ILIT( 1) -> SLIT("%bx");
+       ILIT( 2) -> SLIT("%cx");  ILIT( 3) -> SLIT("%dx");
+       ILIT( 4) -> SLIT("%si");  ILIT( 5) -> SLIT("%di");
+       ILIT( 6) -> SLIT("%bp");  ILIT( 7) -> SLIT("%sp");
+       _ -> SLIT("very naughty I386 word register")
+      })
+-}
+
+    ppr_reg_no L i = uppPStr
+      (case i of {
+       ILIT( 0) -> SLIT("%eax");  ILIT( 1) -> SLIT("%ebx");
+       ILIT( 2) -> SLIT("%ecx");  ILIT( 3) -> SLIT("%edx");
+       ILIT( 4) -> SLIT("%esi");  ILIT( 5) -> SLIT("%edi");
+       ILIT( 6) -> SLIT("%ebp");  ILIT( 7) -> SLIT("%esp");
+       _ -> SLIT("very naughty I386 double word register")
+      })
+
+    ppr_reg_no F i = uppPStr
+      (case i of {
+       --ToDo: rm these (???)
+       ILIT( 8) -> SLIT("%st(0)");  ILIT( 9) -> SLIT("%st(1)");
+       ILIT(10) -> SLIT("%st(2)");  ILIT(11) -> SLIT("%st(3)");
+       ILIT(12) -> SLIT("%st(4)");  ILIT(13) -> SLIT("%st(5)");
+       ILIT(14) -> SLIT("%st(6)");  ILIT(15) -> SLIT("%st(7)");
+       _ -> SLIT("very naughty I386 float register")
+      })
+
+    ppr_reg_no DF i = uppPStr
+      (case i of {
+       --ToDo: rm these (???)
+       ILIT( 8) -> SLIT("%st(0)");  ILIT( 9) -> SLIT("%st(1)");
+       ILIT(10) -> SLIT("%st(2)");  ILIT(11) -> SLIT("%st(3)");
+       ILIT(12) -> SLIT("%st(4)");  ILIT(13) -> SLIT("%st(5)");
+       ILIT(14) -> SLIT("%st(6)");  ILIT(15) -> SLIT("%st(7)");
+       _ -> SLIT("very naughty I386 float register")
+      })
+#endif
+#if sparc_TARGET_ARCH
+    ppr_reg_no :: FAST_REG_NO -> Unpretty
+    ppr_reg_no i = uppPStr
+      (case i of {
+       ILIT( 0) -> SLIT("%g0");  ILIT( 1) -> SLIT("%g1");
+       ILIT( 2) -> SLIT("%g2");  ILIT( 3) -> SLIT("%g3");
+       ILIT( 4) -> SLIT("%g4");  ILIT( 5) -> SLIT("%g5");
+       ILIT( 6) -> SLIT("%g6");  ILIT( 7) -> SLIT("%g7");
+       ILIT( 8) -> SLIT("%o0");  ILIT( 9) -> SLIT("%o1");
+       ILIT(10) -> SLIT("%o2");  ILIT(11) -> SLIT("%o3");
+       ILIT(12) -> SLIT("%o4");  ILIT(13) -> SLIT("%o5");
+       ILIT(14) -> SLIT("%o6");  ILIT(15) -> SLIT("%o7");
+       ILIT(16) -> SLIT("%l0");  ILIT(17) -> SLIT("%l1");
+       ILIT(18) -> SLIT("%l2");  ILIT(19) -> SLIT("%l3");
+       ILIT(20) -> SLIT("%l4");  ILIT(21) -> SLIT("%l5");
+       ILIT(22) -> SLIT("%l6");  ILIT(23) -> SLIT("%l7");
+       ILIT(24) -> SLIT("%i0");  ILIT(25) -> SLIT("%i1");
+       ILIT(26) -> SLIT("%i2");  ILIT(27) -> SLIT("%i3");
+       ILIT(28) -> SLIT("%i4");  ILIT(29) -> SLIT("%i5");
+       ILIT(30) -> SLIT("%i6");  ILIT(31) -> SLIT("%i7");
+       ILIT(32) -> SLIT("%f0");  ILIT(33) -> SLIT("%f1");
+       ILIT(34) -> SLIT("%f2");  ILIT(35) -> SLIT("%f3");
+       ILIT(36) -> SLIT("%f4");  ILIT(37) -> SLIT("%f5");
+       ILIT(38) -> SLIT("%f6");  ILIT(39) -> SLIT("%f7");
+       ILIT(40) -> SLIT("%f8");  ILIT(41) -> SLIT("%f9");
+       ILIT(42) -> SLIT("%f10"); ILIT(43) -> SLIT("%f11");
+       ILIT(44) -> SLIT("%f12"); ILIT(45) -> SLIT("%f13");
+       ILIT(46) -> SLIT("%f14"); ILIT(47) -> SLIT("%f15");
+       ILIT(48) -> SLIT("%f16"); ILIT(49) -> SLIT("%f17");
+       ILIT(50) -> SLIT("%f18"); ILIT(51) -> SLIT("%f19");
+       ILIT(52) -> SLIT("%f20"); ILIT(53) -> SLIT("%f21");
+       ILIT(54) -> SLIT("%f22"); ILIT(55) -> SLIT("%f23");
+       ILIT(56) -> SLIT("%f24"); ILIT(57) -> SLIT("%f25");
+       ILIT(58) -> SLIT("%f26"); ILIT(59) -> SLIT("%f27");
+       ILIT(60) -> SLIT("%f28"); ILIT(61) -> SLIT("%f29");
+       ILIT(62) -> SLIT("%f30"); ILIT(63) -> SLIT("%f31");
+       _ -> SLIT("very naughty sparc register")
+      })
+#endif
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@pprSize@: print a @Size@}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+pprSize :: Size -> Unpretty
+
+pprSize x = uppPStr (case x of
+#if alpha_TARGET_ARCH
+        B  -> SLIT("b")
+        BU -> SLIT("bu")
+--      W  -> SLIT("w") UNUSED
+--      WU -> SLIT("wu") UNUSED
+--      L  -> SLIT("l") UNUSED
+        Q  -> SLIT("q")
+--      FF -> SLIT("f") UNUSED
+--      DF -> SLIT("d") UNUSED
+--      GF -> SLIT("g") UNUSED
+--      SF -> SLIT("s") UNUSED
+        TF -> SLIT("t")
+#endif
+#if i386_TARGET_ARCH
+       B  -> SLIT("b")
+--     HB -> SLIT("b") UNUSED
+--     S  -> SLIT("w") UNUSED
+       L  -> SLIT("l")
+       F  -> SLIT("s")
+       DF -> SLIT("l")
+#endif
+#if sparc_TARGET_ARCH
+       B   -> SLIT("sb")
+--     HW  -> SLIT("hw") UNUSED
+--     BU  -> SLIT("ub") UNUSED
+--     HWU -> SLIT("uhw") UNUSED
+       W   -> SLIT("")
+       F   -> SLIT("")
+--     D   -> SLIT("d") UNUSED
+       DF  -> SLIT("d")
+#endif
+    )
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@pprCond@: print a @Cond@}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+pprCond :: Cond -> Unpretty
+
+pprCond c = uppPStr (case c of {
+#if alpha_TARGET_ARCH
+       EQ  -> SLIT("eq");
+       LT  -> SLIT("lt");
+       LE  -> SLIT("le");
+       ULT -> SLIT("ult");
+       ULE -> SLIT("ule");
+       NE  -> SLIT("ne");
+       GT  -> SLIT("gt");
+       GE  -> SLIT("ge")
+#endif
+#if i386_TARGET_ARCH
+       GEU     -> SLIT("ae");  LU    -> SLIT("b");
+       EQ      -> SLIT("e");   GT    -> SLIT("g");
+       GE      -> SLIT("ge");  GU    -> SLIT("a");
+       LT      -> SLIT("l");   LE    -> SLIT("le");
+       LEU     -> SLIT("be");  NE    -> SLIT("ne");
+       NEG     -> SLIT("s");   POS   -> SLIT("ns");
+       ALWAYS  -> SLIT("mp")   -- hack
+#endif
+#if sparc_TARGET_ARCH
+       ALWAYS  -> SLIT("");    NEVER -> SLIT("n");
+       GEU     -> SLIT("geu"); LU    -> SLIT("lu");
+       EQ      -> SLIT("e");   GT    -> SLIT("g");
+       GE      -> SLIT("ge");  GU    -> SLIT("gu");
+       LT      -> SLIT("l");   LE    -> SLIT("le");
+       LEU     -> SLIT("leu"); NE    -> SLIT("ne");
+       NEG     -> SLIT("neg"); POS   -> SLIT("pos");
+       VC      -> SLIT("vc");  VS    -> SLIT("vs")
+#endif
+    })
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@pprImm@: print an @Imm@}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+pprImm :: Imm -> Unpretty
+
+pprImm (ImmInt i)     = uppInt i
+pprImm (ImmInteger i) = uppInteger i
+pprImm (ImmCLbl l)    = pprCLabel_asm l
+pprImm (ImmLit s)     = s
+
+pprImm (ImmLab s) | underscorePrefix = uppBeside (uppChar '_') s
+                 | otherwise        = s
+
+#if sparc_TARGET_ARCH
+pprImm (LO i)
+  = uppBesides [ pp_lo, pprImm i, uppRparen ]
+  where
+    pp_lo = uppPStr (_packCString (A# "%lo("#))
+
+pprImm (HI i)
+  = uppBesides [ pp_hi, pprImm i, uppRparen ]
+  where
+    pp_hi = uppPStr (_packCString (A# "%hi("#))
+#endif
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@pprAddr@: print an @Addr@}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+pprAddr :: Addr -> Unpretty
+
+#if alpha_TARGET_ARCH
+pprAddr (AddrReg r) = uppParens (pprReg r)
+pprAddr (AddrImm i) = pprImm i
+pprAddr (AddrRegImm r1 i)
+  = uppBeside (pprImm i) (uppParens (pprReg r1))
+#endif
+
+-------------------
+
+#if i386_TARGET_ARCH
+pprAddr (ImmAddr imm off)
+  = let
+       pp_imm = pprImm imm
+    in
+    if (off == 0) then
+       pp_imm
+    else if (off < 0) then
+       uppBeside pp_imm (uppInt off)
+    else
+       uppBesides [pp_imm, uppChar '+', uppInt off]
+
+pprAddr (Addr base index displacement)
+  = let
+       pp_disp  = ppr_disp displacement
+       pp_off p = uppBeside pp_disp (uppParens p)
+       pp_reg r = pprReg L r
+    in
+    case (base,index) of
+      (Nothing, Nothing)    -> pp_disp
+      (Just b,  Nothing)    -> pp_off (pp_reg b)
+      (Nothing, Just (r,i)) -> pp_off (uppBesides [pp_reg r, uppComma, uppInt i])
+      (Just b,  Just (r,i)) -> pp_off (uppBesides [pp_reg b, uppComma, pp_reg r, uppComma, uppInt i])
+  where
+    ppr_disp (ImmInt 0) = uppNil
+    ppr_disp imm        = pprImm imm
+#endif
+
+-------------------
+
+#if sparc_TARGET_ARCH
+pprAddr (AddrRegReg r1 (FixedReg ILIT(0))) = pprReg r1
+
+pprAddr (AddrRegReg r1 r2)
+  = uppBesides [ pprReg r1, uppChar '+', pprReg r2 ]
+
+pprAddr (AddrRegImm r1 (ImmInt i))
+  | i == 0 = pprReg r1
+  | not (fits13Bits i) = largeOffsetError i
+  | otherwise = uppBesides [ pprReg r1, pp_sign, uppInt i ]
+  where
+    pp_sign = if i > 0 then uppChar '+' else uppNil
+
+pprAddr (AddrRegImm r1 (ImmInteger i))
+  | i == 0 = pprReg r1
+  | not (fits13Bits i) = largeOffsetError i
+  | otherwise  = uppBesides [ pprReg r1, pp_sign, uppInteger i ]
+  where
+    pp_sign = if i > 0 then uppChar '+' else uppNil
+
+pprAddr (AddrRegImm r1 imm)
+  = uppBesides [ pprReg r1, uppChar '+', pprImm imm ]
+#endif
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@pprInstr@: print an @Instr@}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+pprInstr :: Instr -> Unpretty
+
+pprInstr (COMMENT s) = uppBeside (uppPStr SLIT("\t# ")) (uppPStr s)
+
+pprInstr (SEGMENT TextSegment)
+    = uppPStr
+        IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
+       ,IF_ARCH_sparc(SLIT("\t.text\n\t.align 4") {-word boundary-}
+       ,IF_ARCH_i386(SLIT(".text\n\t.align 2,0x90") {-needs per-OS variation!-}
+       ,)))
+
+pprInstr (SEGMENT DataSegment)
+    = uppPStr
+        IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
+       ,IF_ARCH_sparc(SLIT("\t.data\n\t.align 8") {-<8 will break double constants -}
+       ,IF_ARCH_i386(SLIT(".data\n\t.align 2")
+       ,)))
+
+pprInstr (LABEL clab)
+  = let
+       pp_lab = pprCLabel_asm clab
+    in
+    uppBesides [
+       if not (externallyVisibleCLabel clab) then
+           uppNil
+       else
+           uppBesides [uppPStr
+                        IF_ARCH_alpha(SLIT("\t.globl\t")
+                       ,IF_ARCH_i386(SLIT(".globl ")
+                       ,IF_ARCH_sparc(SLIT("\t.global\t")
+                       ,)))
+                       , pp_lab, uppChar '\n'],
+       pp_lab,
+       uppChar ':'
+    ]
+
+pprInstr (ASCII False{-no backslash conversion-} str)
+  = uppBesides [ uppStr "\t.asciz \"", uppStr str, uppChar '"' ]
+
+pprInstr (ASCII True str)
+  = uppBeside (uppStr "\t.ascii \"") (asciify str 60)
+  where
+    asciify :: String -> Int -> Unpretty
+
+    asciify [] _ = uppStr ("\\0\"")
+    asciify s     n | n <= 0 = uppBeside (uppStr "\"\n\t.ascii \"") (asciify s 60)
+    asciify ('\\':cs)      n = uppBeside (uppStr "\\\\") (asciify cs (n-1))
+    asciify ('\"':cs)      n = uppBeside (uppStr "\\\"") (asciify cs (n-1))
+    asciify (c:cs) n | isPrint c = uppBeside (uppChar c) (asciify cs (n-1))
+    asciify [c]            _ = uppBeside (uppStr (charToC c)) (uppStr ("\\0\""))
+    asciify (c:(cs@(d:_))) n
+      | isDigit d = uppBeside (uppStr (charToC c)) (asciify cs 0)
+      | otherwise = uppBeside (uppStr (charToC c)) (asciify cs (n-1))
+
+pprInstr (DATA s xs)
+  = uppInterleave (uppChar '\n')
+                 [uppBeside (uppPStr pp_size) (pprImm x) | x <- xs]
+  where
+    pp_size = case s of
+#if alpha_TARGET_ARCH
+           B  -> SLIT("\t.byte\t")
+           BU -> SLIT("\t.byte\t")
+--UNUSED:   W  -> SLIT("\t.word\t")
+--UNUSED:   WU -> SLIT("\t.word\t")
+--UNUSED:   L  -> SLIT("\t.long\t")
+           Q  -> SLIT("\t.quad\t")
+--UNUSED:   FF -> SLIT("\t.f_floating\t")
+--UNUSED:   DF -> SLIT("\t.d_floating\t")
+--UNUSED:   GF -> SLIT("\t.g_floating\t")
+--UNUSED:   SF -> SLIT("\t.s_floating\t")
+           TF -> SLIT("\t.t_floating\t")
+#endif
+#if i386_TARGET_ARCH
+           B  -> SLIT("\t.byte\t")
+--UNUSED:   HB -> SLIT("\t.byte\t")
+--UNUSED:   S  -> SLIT("\t.word\t")
+           L  -> SLIT("\t.long\t")
+           F  -> SLIT("\t.long\t")
+           DF -> SLIT("\t.double\t")
+#endif
+#if sparc_TARGET_ARCH
+           B  -> SLIT("\t.byte\t")
+           BU -> SLIT("\t.byte\t")
+           W  -> SLIT("\t.word\t")
+           DF -> SLIT("\t.double\t")
+#endif
+
+-- fall through to rest of (machine-specific) pprInstr...
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsubsection{@pprInstr@ for an Alpha}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+#if alpha_TARGET_ARCH
+
+pprInstr (LD size reg addr)
+  = uppBesides [
+       uppPStr SLIT("\tld"),
+       pprSize size,
+       uppChar '\t',
+       pprReg reg,
+       uppComma,
+       pprAddr addr
+    ]
+
+pprInstr (LDA reg addr)
+  = uppBesides [
+       uppPStr SLIT("\tlda\t"),
+       pprReg reg,
+       uppComma,
+       pprAddr addr
+    ]
+
+pprInstr (LDAH reg addr)
+  = uppBesides [
+       uppPStr SLIT("\tldah\t"),
+       pprReg reg,
+       uppComma,
+       pprAddr addr
+    ]
+
+pprInstr (LDGP reg addr)
+  = uppBesides [
+       uppPStr SLIT("\tldgp\t"),
+       pprReg reg,
+       uppComma,
+       pprAddr addr
+    ]
+
+pprInstr (LDI size reg imm)
+  = uppBesides [
+       uppPStr SLIT("\tldi"),
+       pprSize size,
+       uppChar '\t',
+       pprReg reg,
+       uppComma,
+       pprImm imm
+    ]
+
+pprInstr (ST size reg addr)
+  = uppBesides [
+       uppPStr SLIT("\tst"),
+       pprSize size,
+       uppChar '\t',
+       pprReg reg,
+       uppComma,
+       pprAddr addr
+    ]
+
+pprInstr (CLR reg)
+  = uppBesides [
+       uppPStr SLIT("\tclr\t"),
+       pprReg reg
+    ]
+
+pprInstr (ABS size ri reg)
+  = uppBesides [
+       uppPStr SLIT("\tabs"),
+       pprSize size,
+       uppChar '\t',
+       pprRI ri,
+       uppComma,
+       pprReg reg
+    ]
+
+pprInstr (NEG size ov ri reg)
+  = uppBesides [
+       uppPStr SLIT("\tneg"),
+       pprSize size,
+       if ov then uppPStr SLIT("v\t") else uppChar '\t',
+       pprRI ri,
+       uppComma,
+       pprReg reg
+    ]
+
+pprInstr (ADD size ov reg1 ri reg2)
+  = uppBesides [
+       uppPStr SLIT("\tadd"),
+       pprSize size,
+       if ov then uppPStr SLIT("v\t") else uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (SADD size scale reg1 ri reg2)
+  = uppBesides [
+       uppPStr (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
+       uppPStr SLIT("add"),
+       pprSize size,
+       uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (SUB size ov reg1 ri reg2)
+  = uppBesides [
+       uppPStr SLIT("\tsub"),
+       pprSize size,
+       if ov then uppPStr SLIT("v\t") else uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (SSUB size scale reg1 ri reg2)
+  = uppBesides [
+       uppPStr (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
+       uppPStr SLIT("sub"),
+       pprSize size,
+       uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (MUL size ov reg1 ri reg2)
+  = uppBesides [
+       uppPStr SLIT("\tmul"),
+       pprSize size,
+       if ov then uppPStr SLIT("v\t") else uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (DIV size uns reg1 ri reg2)
+  = uppBesides [
+       uppPStr SLIT("\tdiv"),
+       pprSize size,
+       if uns then uppPStr SLIT("u\t") else uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (REM size uns reg1 ri reg2)
+  = uppBesides [
+       uppPStr SLIT("\trem"),
+       pprSize size,
+       if uns then uppPStr SLIT("u\t") else uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (NOT ri reg)
+  = uppBesides [
+       uppPStr SLIT("\tnot"),
+       uppChar '\t',
+       pprRI ri,
+       uppComma,
+       pprReg reg
+    ]
+
+pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
+pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
+pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
+pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
+pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
+pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
+
+pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
+pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
+pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
+
+pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
+pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
+
+pprInstr (NOP) = uppPStr SLIT("\tnop")
+
+pprInstr (CMP cond reg1 ri reg2)
+  = uppBesides [
+       uppPStr SLIT("\tcmp"),
+       pprCond cond,
+       uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (FCLR reg)
+  = uppBesides [
+       uppPStr SLIT("\tfclr\t"),
+       pprReg reg
+    ]
+
+pprInstr (FABS reg1 reg2)
+  = uppBesides [
+       uppPStr SLIT("\tfabs\t"),
+       pprReg reg1,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (FNEG size reg1 reg2)
+  = uppBesides [
+       uppPStr SLIT("\tneg"),
+       pprSize size,
+       uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
+pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
+pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
+pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
+
+pprInstr (CVTxy size1 size2 reg1 reg2)
+  = uppBesides [
+       uppPStr SLIT("\tcvt"),
+       pprSize size1,
+       case size2 of {Q -> uppPStr SLIT("qc"); _ -> pprSize size2},
+       uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (FCMP size cond reg1 reg2 reg3)
+  = uppBesides [
+       uppPStr SLIT("\tcmp"),
+       pprSize size,
+       pprCond cond,
+       uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprReg reg2,
+       uppComma,
+       pprReg reg3
+    ]
+
+pprInstr (FMOV reg1 reg2)
+  = uppBesides [
+       uppPStr SLIT("\tfmov\t"),
+       pprReg reg1,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
+
+pprInstr (BI NEVER reg lab) = uppNil
+
+pprInstr (BI cond reg lab)
+  = uppBesides [
+       uppPStr SLIT("\tb"),
+       pprCond cond,
+       uppChar '\t',
+       pprReg reg,
+       uppComma,
+       pprImm lab
+    ]
+
+pprInstr (BF cond reg lab)
+  = uppBesides [
+       uppPStr SLIT("\tfb"),
+       pprCond cond,
+       uppChar '\t',
+       pprReg reg,
+       uppComma,
+       pprImm lab
+    ]
+
+pprInstr (BR lab)
+  = uppBeside (uppPStr SLIT("\tbr\t")) (pprImm lab)
+
+pprInstr (JMP reg addr hint)
+  = uppBesides [
+       uppPStr SLIT("\tjmp\t"),
+       pprReg reg,
+       uppComma,
+       pprAddr addr,
+       uppComma,
+       uppInt hint
+    ]
+
+pprInstr (BSR imm n)
+  = uppBeside (uppPStr SLIT("\tbsr\t")) (pprImm imm)
+
+pprInstr (JSR reg addr n)
+  = uppBesides [
+       uppPStr SLIT("\tjsr\t"),
+       pprReg reg,
+       uppComma,
+       pprAddr addr
+    ]
+
+pprInstr (FUNBEGIN clab)
+  = uppBesides [
+       if (externallyVisibleCLabel clab) then
+           uppBesides [uppPStr SLIT("\t.globl\t"), pp_lab, uppChar '\n']
+       else
+           uppNil,
+       uppPStr SLIT("\t.ent "),
+       pp_lab,
+       uppChar '\n',
+       pp_lab,
+       pp_ldgp,
+       pp_lab,
+       pp_frame
+    ]
+    where
+       pp_lab = pprCLabel_asm clab
+       pp_ldgp  = uppPStr (_packCString (A# ":\n\tldgp $29,0($27)\n"#))
+       pp_frame = uppPStr (_packCString (A# "..ng:\n\t.frame $30,4240,$26,0\n\t.prologue 1"#))
+
+pprInstr (FUNEND clab)
+  = uppBeside (uppPStr SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
+\end{code}
+
+Continue with Alpha-only printing bits and bobs:
+\begin{code}
+pprRI :: RI -> Unpretty
+
+pprRI (RIReg r) = pprReg r
+pprRI (RIImm r) = pprImm r
+
+pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> Unpretty
+
+pprRegRIReg name reg1 ri reg2
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Unpretty
+
+pprSizeRegRegReg name size reg1 reg2 reg3
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       pprSize size,
+       uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprReg reg2,
+       uppComma,
+       pprReg reg3
+    ]
+
+#endif {-alpha_TARGET_ARCH-}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsubsection{@pprInstr@ for an I386}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+#if i386_TARGET_ARCH
+
+pprInstr (MOV size (OpReg src) (OpReg dst)) -- hack
+  | src == dst
+  = uppPStr SLIT("")
+pprInstr (MOV size src dst)
+  = pprSizeOpOp SLIT("mov") size src dst
+pprInstr (MOVZX size src dst) = pprSizeOpOpCoerce SLIT("movzx") L size src dst
+pprInstr (MOVSX size src dst) = pprSizeOpOpCoerce SLIT("movxs") L size src dst
+
+-- here we do some patching, since the physical registers are only set late
+-- in the code generation.
+pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
+  | reg1 == reg3
+  = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
+pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
+  | reg2 == reg3
+  = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
+pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
+  | reg1 == reg3
+  = pprInstr (ADD size (OpImm displ) dst)
+pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
+
+pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
+  = pprSizeOp SLIT("dec") size dst
+pprInstr (ADD size (OpImm (ImmInt 1)) dst)
+  = pprSizeOp SLIT("inc") size dst
+pprInstr (ADD size src dst)
+  = pprSizeOpOp SLIT("add") size src dst
+pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
+pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
+pprInstr (IDIV size op) = pprSizeOp SLIT("idiv") size op
+
+pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
+pprInstr (OR  size src dst) = pprSizeOpOp SLIT("or")  size src dst
+pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor")  size src dst
+pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
+pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
+pprInstr (SHL size imm dst) = pprSizeOpOp SLIT("shl")  size imm dst
+pprInstr (SAR size imm dst) = pprSizeOpOp SLIT("sar")  size imm dst
+pprInstr (SHR size imm dst) = pprSizeOpOp SLIT("shr")  size imm dst
+
+pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp")  size src dst
+pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test")  size src dst
+pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
+pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
+
+pprInstr (NOP) = uppPStr SLIT("\tnop")
+pprInstr (CLTD) = uppPStr SLIT("\tcltd")
+
+pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
+
+pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
+
+pprInstr (JMP (OpImm imm)) = uppBeside (uppPStr SLIT("\tjmp ")) (pprImm imm)
+pprInstr (JMP op) = uppBeside (uppPStr SLIT("\tjmp *")) (pprOperand L op)
+
+pprInstr (CALL imm)
+  = uppBesides [ uppPStr SLIT("\tcall "), pprImm imm ]
+
+pprInstr SAHF = uppPStr SLIT("\tsahf")
+pprInstr FABS = uppPStr SLIT("\tfabs")
+
+pprInstr (FADD sz src@(OpAddr _))
+  = uppBesides [uppPStr SLIT("\tfadd"), pprSize sz, uppSP, pprOperand sz src]
+pprInstr (FADD sz src)
+  = uppPStr SLIT("\tfadd")
+pprInstr FADDP
+  = uppPStr SLIT("\tfaddp")
+pprInstr (FMUL sz src)
+  = uppBesides [uppPStr SLIT("\tfmul"), pprSize sz, uppSP, pprOperand sz src]
+pprInstr FMULP
+  = uppPStr SLIT("\tfmulp")
+pprInstr (FIADD size op) = pprSizeAddr SLIT("fiadd") size op
+pprInstr FCHS = uppPStr SLIT("\tfchs")
+pprInstr (FCOM size op) = pprSizeOp SLIT("fcom") size op
+pprInstr FCOS = uppPStr SLIT("\tfcos")
+pprInstr (FIDIV size op) = pprSizeAddr SLIT("fidiv") size op
+pprInstr (FDIV sz src)
+  = uppBesides [uppPStr SLIT("\tfdiv"), pprSize sz, uppSP, pprOperand sz src]
+pprInstr FDIVP
+  = uppPStr SLIT("\tfdivp")
+pprInstr (FDIVR sz src)
+  = uppBesides [uppPStr SLIT("\tfdivr"), pprSize sz, uppSP, pprOperand sz src]
+pprInstr FDIVRP
+  = uppPStr SLIT("\tfdivpr")
+pprInstr (FIDIVR size op) = pprSizeAddr SLIT("fidivr") size op
+pprInstr (FICOM size op) = pprSizeAddr SLIT("ficom") size op
+pprInstr (FILD sz op reg) = pprSizeAddrReg SLIT("fild") sz op reg
+pprInstr (FIST size op) = pprSizeAddr SLIT("fist") size op
+pprInstr (FLD sz (OpImm (ImmCLbl src)))
+  = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppSP,pprCLabel_asm src]
+pprInstr (FLD sz src)
+  = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppSP,pprOperand sz src]
+pprInstr FLD1 = uppPStr SLIT("\tfld1")
+pprInstr FLDZ = uppPStr SLIT("\tfldz")
+pprInstr (FIMUL size op) = pprSizeAddr SLIT("fimul") size op
+pprInstr FRNDINT = uppPStr SLIT("\tfrndint")
+pprInstr FSIN = uppPStr SLIT("\tfsin")
+pprInstr FSQRT = uppPStr SLIT("\tfsqrt")
+pprInstr (FST sz dst)
+  = uppBesides [uppPStr SLIT("\tfst"), pprSize sz, uppSP, pprOperand sz dst]
+pprInstr (FSTP sz dst)
+  = uppBesides [uppPStr SLIT("\tfstp"), pprSize sz, uppSP, pprOperand sz dst]
+pprInstr (FISUB size op) = pprSizeAddr SLIT("fisub") size op
+pprInstr (FSUB sz src)
+  = uppBesides [uppPStr SLIT("\tfsub"), pprSize sz, uppSP, pprOperand sz src]
+pprInstr FSUBP
+  = uppPStr SLIT("\tfsubp")
+pprInstr (FSUBR size src)
+  = pprSizeOp SLIT("fsubr") size src
+pprInstr FSUBRP
+  = uppPStr SLIT("\tfsubpr")
+pprInstr (FISUBR size op)
+  = pprSizeAddr SLIT("fisubr") size op
+pprInstr FTST = uppPStr SLIT("\tftst")
+pprInstr (FCOMP sz op)
+  = uppBesides [uppPStr SLIT("\tfcomp"), pprSize sz, uppSP, pprOperand sz op]
+pprInstr FUCOMPP = uppPStr SLIT("\tfucompp")
+pprInstr FXCH = uppPStr SLIT("\tfxch")
+pprInstr FNSTSW = uppPStr SLIT("\tfnstsw %ax")
+pprInstr FNOP = uppPStr SLIT("")
+\end{code}
+
+Continue with I386-only printing bits and bobs:
+\begin{code}
+pprDollImm :: Imm -> Unpretty
+
+pprDollImm i     = uppBesides [ uppPStr SLIT("$"), pprImm i]
+
+pprOperand :: Size -> Operand -> Unpretty
+pprOperand s (OpReg r) = pprReg s r
+pprOperand s (OpImm i) = pprDollImm i
+pprOperand s (OpAddr ea) = pprAddr ea
+
+pprSizeOp :: FAST_STRING -> Size -> Operand -> Unpretty
+pprSizeOp name size op1
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       pprSize size,
+       uppSP,
+       pprOperand size op1
+    ]
+
+pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Unpretty
+pprSizeOpOp name size op1 op2
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       pprSize size,
+       uppSP,
+       pprOperand size op1,
+       uppComma,
+       pprOperand size op2
+    ]
+
+pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> Unpretty
+pprSizeOpReg name size op1 reg
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       pprSize size,
+       uppSP,
+       pprOperand size op1,
+       uppComma,
+       pprReg size reg
+    ]
+
+pprSizeAddr :: FAST_STRING -> Size -> Addr -> Unpretty
+pprSizeAddr name size op
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       pprSize size,
+       uppSP,
+       pprAddr op
+    ]
+
+pprSizeAddrReg :: FAST_STRING -> Size -> Addr -> Reg -> Unpretty
+pprSizeAddrReg name size op dst
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       pprSize size,
+       uppSP,
+       pprAddr op,
+       uppComma,
+       pprReg size dst
+    ]
+
+pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Unpretty
+pprOpOp name size op1 op2
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name, uppSP,
+       pprOperand size op1,
+       uppComma,
+       pprOperand size op2
+    ]
+
+pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> Unpretty
+pprSizeOpOpCoerce name size1 size2 op1 op2
+  = uppBesides [ uppChar '\t', uppPStr name, uppSP,
+       pprOperand size1 op1,
+       uppComma,
+       pprOperand size2 op2
+    ]
+
+pprCondInstr :: FAST_STRING -> Cond -> Unpretty -> Unpretty
+pprCondInstr name cond arg
+  = uppBesides [ uppChar '\t', uppPStr name, pprCond cond, uppSP, arg]
+
+#endif {-i386_TARGET_ARCH-}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsubsection{@pprInstr@ for a SPARC}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+#if sparc_TARGET_ARCH
+
+-- a clumsy hack for now, to handle possible double alignment problems
+
+pprInstr (LD DF addr reg) | maybeToBool off_addr
+  = uppBesides [
+       pp_ld_lbracket,
+       pprAddr addr,
+       pp_rbracket_comma,
+       pprReg reg,
+
+       uppChar '\n',
+       pp_ld_lbracket,
+       pprAddr addr2,
+       pp_rbracket_comma,
+       pprReg (fPair reg)
+    ]
+  where
+    off_addr = addrOffset addr 4
+    addr2 = case off_addr of Just x -> x
+
+pprInstr (LD size addr reg)
+  = uppBesides [
+       uppPStr SLIT("\tld"),
+       pprSize size,
+       uppChar '\t',
+       uppLbrack,
+       pprAddr addr,
+       pp_rbracket_comma,
+       pprReg reg
+    ]
+
+-- The same clumsy hack as above
+
+pprInstr (ST DF reg addr) | maybeToBool off_addr
+  = uppBesides [
+       uppPStr SLIT("\tst\t"),
+       pprReg reg,
+       pp_comma_lbracket,
+       pprAddr addr,
+
+       uppPStr SLIT("]\n\tst\t"),
+       pprReg (fPair reg),
+       pp_comma_lbracket,
+       pprAddr addr2,
+       uppRbrack
+    ]
+  where
+    off_addr = addrOffset addr 4
+    addr2 = case off_addr of Just x -> x
+
+pprInstr (ST size reg addr)
+  = uppBesides [
+       uppPStr SLIT("\tst"),
+       pprSize size,
+       uppChar '\t',
+       pprReg reg,
+       pp_comma_lbracket,
+       pprAddr addr,
+       uppRbrack
+    ]
+
+pprInstr (ADD x cc reg1 ri reg2)
+  | not x && not cc && riZero ri
+  = uppBesides [ uppPStr SLIT("\tmov\t"), pprReg reg1, uppComma, pprReg reg2 ]
+  | otherwise
+  = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
+
+pprInstr (SUB x cc reg1 ri reg2)
+  | not x && cc && reg2 == g0
+  = uppBesides [ uppPStr SLIT("\tcmp\t"), pprReg reg1, uppComma, pprRI ri ]
+  | not x && not cc && riZero ri
+  = uppBesides [ uppPStr SLIT("\tmov\t"), pprReg reg1, uppComma, pprReg reg2 ]
+  | otherwise
+  = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
+
+pprInstr (AND  b reg1 ri reg2) = pprRegRIReg SLIT("and")  b reg1 ri reg2
+pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
+
+pprInstr (OR b reg1 ri reg2)
+  | not b && reg1 == g0
+  = uppBesides [ uppPStr SLIT("\tmov\t"), pprRI ri, uppComma, pprReg reg2 ]
+  | otherwise
+  = pprRegRIReg SLIT("or") b reg1 ri reg2
+
+pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
+
+pprInstr (XOR  b reg1 ri reg2) = pprRegRIReg SLIT("xor")  b reg1 ri reg2
+pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
+
+pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
+pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
+pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
+
+pprInstr (SETHI imm reg)
+  = uppBesides [
+       uppPStr SLIT("\tsethi\t"),
+       pprImm imm,
+       uppComma,
+       pprReg reg
+    ]
+
+pprInstr NOP = uppPStr SLIT("\tnop")
+
+pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
+pprInstr (FABS DF reg1 reg2)
+  = uppBeside (pprSizeRegReg SLIT("fabs") F reg1 reg2)
+    (if (reg1 == reg2) then uppNil
+     else uppBeside (uppChar '\n')
+         (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
+
+pprInstr (FADD size reg1 reg2 reg3)
+  = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
+pprInstr (FCMP e size reg1 reg2)
+  = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
+pprInstr (FDIV size reg1 reg2 reg3)
+  = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
+
+pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
+pprInstr (FMOV DF reg1 reg2)
+  = uppBeside (pprSizeRegReg SLIT("fmov") F reg1 reg2)
+    (if (reg1 == reg2) then uppNil
+     else uppBeside (uppChar '\n')
+         (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
+
+pprInstr (FMUL size reg1 reg2 reg3)
+  = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
+
+pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
+pprInstr (FNEG DF reg1 reg2)
+  = uppBeside (pprSizeRegReg SLIT("fneg") F reg1 reg2)
+    (if (reg1 == reg2) then uppNil
+     else uppBeside (uppChar '\n')
+         (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
+
+pprInstr (FSQRT size reg1 reg2)     = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
+pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
+pprInstr (FxTOy size1 size2 reg1 reg2)
+  = uppBesides [
+       uppPStr SLIT("\tf"),
+       uppPStr
+       (case size1 of
+           W  -> SLIT("ito")
+           F  -> SLIT("sto")
+           DF -> SLIT("dto")),
+       uppPStr
+       (case size2 of
+           W  -> SLIT("i\t")
+           F  -> SLIT("s\t")
+           DF -> SLIT("d\t")),
+       pprReg reg1, uppComma, pprReg reg2
+    ]
+
+
+pprInstr (BI cond b lab)
+  = uppBesides [
+       uppPStr SLIT("\tb"), pprCond cond,
+       if b then pp_comma_a else uppNil,
+       uppChar '\t',
+       pprImm lab
+    ]
+
+pprInstr (BF cond b lab)
+  = uppBesides [
+       uppPStr SLIT("\tfb"), pprCond cond,
+       if b then pp_comma_a else uppNil,
+       uppChar '\t',
+       pprImm lab
+    ]
+
+pprInstr (JMP addr) = uppBeside (uppPStr SLIT("\tjmp\t")) (pprAddr addr)
+
+pprInstr (CALL imm n _)
+  = uppBesides [ uppPStr SLIT("\tcall\t"), pprImm imm, uppComma, uppInt n ]
+\end{code}
+
+Continue with SPARC-only printing bits and bobs:
+\begin{code}
+pprRI :: RI -> Unpretty
+pprRI (RIReg r) = pprReg r
+pprRI (RIImm r) = pprImm r
+
+pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Unpretty
+pprSizeRegReg name size reg1 reg2
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       (case size of
+           F  -> uppPStr SLIT("s\t")
+           DF -> uppPStr SLIT("d\t")),
+       pprReg reg1,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Unpretty
+pprSizeRegRegReg name size reg1 reg2 reg3
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       (case size of
+           F  -> uppPStr SLIT("s\t")
+           DF -> uppPStr SLIT("d\t")),
+       pprReg reg1,
+       uppComma,
+       pprReg reg2,
+       uppComma,
+       pprReg reg3
+    ]
+
+pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> Unpretty
+pprRegRIReg name b reg1 ri reg2
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       if b then uppPStr SLIT("cc\t") else uppChar '\t',
+       pprReg reg1,
+       uppComma,
+       pprRI ri,
+       uppComma,
+       pprReg reg2
+    ]
+
+pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> Unpretty
+pprRIReg name b ri reg1
+  = uppBesides [
+       uppChar '\t',
+       uppPStr name,
+       if b then uppPStr SLIT("cc\t") else uppChar '\t',
+       pprRI ri,
+       uppComma,
+       pprReg reg1
+    ]
+
+pp_ld_lbracket    = uppPStr (_packCString (A# "\tld\t["#))
+pp_rbracket_comma = uppPStr (_packCString (A# "],"#))
+pp_comma_lbracket = uppPStr (_packCString (A# ",["#))
+pp_comma_a       = uppPStr (_packCString (A# ",a"#))
+
+#endif {-sparc_TARGET_ARCH-}
+\end{code}
diff --git a/ghc/compiler/nativeGen/RegAllocInfo.lhs b/ghc/compiler/nativeGen/RegAllocInfo.lhs
new file mode 100644 (file)
index 0000000..93cda5c
--- /dev/null
@@ -0,0 +1,799 @@
+%
+% (c) The AQUA Project, Glasgow University, 1996
+%
+\section[RegAllocInfo]{Machine-specific info used for register allocation}
+
+The (machine-independent) allocator itself is in @AsmRegAlloc@.
+
+\begin{code}
+#include "HsVersions.h"
+#include "nativeGen/NCG.h"
+
+module RegAllocInfo (
+       MRegsState(..),
+       mkMRegsState,
+       freeMReg,
+       freeMRegs,
+       possibleMRegs,
+       useMReg,
+       useMRegs,
+
+       RegUsage(..),
+       noUsage,
+       endUsage,
+       regUsage,
+
+       FutureLive(..),
+       RegAssignment(..),
+       RegConflicts(..),
+       RegFuture(..),
+       RegHistory(..),
+       RegInfo(..),
+       RegLiveness(..),
+
+       fstFL,
+       loadReg,
+       patchRegs,
+       regLiveness,
+       spillReg,
+
+       RegSet(..),
+       elementOfRegSet,
+       emptyRegSet,
+       isEmptyRegSet,
+       minusRegSet,
+       mkRegSet,
+       regSetToList,
+       unionRegSets,
+
+       argRegSet,
+       callClobberedRegSet,
+       freeRegSet
+    ) where
+
+import Ubiq{-uitous-}
+
+import MachMisc
+import MachRegs
+import MachCode                ( InstrList(..) )
+
+import BitSet          ( unitBS, mkBS, minusBS, unionBS, listBS, BitSet )
+import CLabel          ( pprCLabel_asm, CLabel{-instance Ord-} )
+import FiniteMap       ( addToFM, lookupFM )
+import OrdList         ( mkUnitList, OrdList )
+import PrimRep         ( PrimRep(..) )
+import Stix            ( StixTree, CodeSegment )
+import UniqSet         -- quite a bit of it
+import Unpretty                ( uppShow )
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Register allocation information}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+type RegSet = UniqSet Reg
+
+mkRegSet :: [Reg] -> RegSet
+emptyRegSet :: RegSet
+unionRegSets, minusRegSet :: RegSet -> RegSet -> RegSet
+elementOfRegSet :: Reg -> RegSet -> Bool
+isEmptyRegSet :: RegSet -> Bool
+regSetToList :: RegSet -> [Reg]
+
+mkRegSet       = mkUniqSet
+emptyRegSet    = emptyUniqSet
+unionRegSets   = unionUniqSets
+minusRegSet    = minusUniqSet
+elementOfRegSet        = elementOfUniqSet
+isEmptyRegSet  = isEmptyUniqSet
+regSetToList   = uniqSetToList
+
+freeRegSet, callClobberedRegSet :: RegSet
+argRegSet :: Int -> RegSet
+
+freeRegSet         = mkRegSet freeRegs
+callClobberedRegSet = mkRegSet callClobberedRegs
+argRegSet n        = mkRegSet (argRegs n)
+
+type RegAssignment = FiniteMap Reg Reg
+type RegConflicts  = FiniteMap Int RegSet
+
+data FutureLive = FL RegSet (FiniteMap CLabel RegSet)
+
+fstFL (FL a b)  = a
+
+data RegHistory a
+  = RH a
+       Int
+       RegAssignment
+
+data RegFuture
+  = RF RegSet          -- in use
+       FutureLive      -- future
+       RegConflicts
+
+data RegInfo a
+  = RI RegSet          -- in use
+       RegSet          -- sources
+       RegSet          -- destinations
+       [Reg]           -- last used
+       RegConflicts
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{Register allocation information}
+%*                                                                     *
+%************************************************************************
+
+COMMENT ON THE EXTRA BitSet FOR SPARC MRegsState: Getting the conflicts
+right is a bit tedious for doubles.  We'd have to add a conflict
+function to the MachineRegisters class, and we'd have to put a PrimRep
+in the MappedReg datatype, or use some kludge (e.g. register 64 + n is
+really the same as 32 + n, except that it's used for a double, so it
+also conflicts with 33 + n) to deal with it.  It's just not worth the
+bother, so we just partition the free floating point registers into
+two sets: one for single precision and one for double precision.  We
+never seem to run out of floating point registers anyway.
+
+\begin{code}
+data MRegsState
+  = MRs        BitSet  -- integer registers
+       BitSet  -- floating-point registers
+       IF_ARCH_sparc(BitSet,) -- double registers handled separately
+\end{code}
+
+\begin{code}
+#if alpha_TARGET_ARCH
+# define INT_FLPT_CUTOFF 32
+#endif
+#if i386_TARGET_ARCH
+# define INT_FLPT_CUTOFF 8
+#endif
+#if sparc_TARGET_ARCH
+# define INT_FLPT_CUTOFF 32
+# define SNGL_DBL_CUTOFF 48
+#endif
+
+mkMRegsState   :: [RegNo] -> MRegsState
+possibleMRegs   :: PrimRep -> MRegsState -> [RegNo]
+useMReg                :: MRegsState -> FAST_REG_NO -> MRegsState
+useMRegs       :: MRegsState -> [RegNo]     -> MRegsState
+freeMReg       :: MRegsState -> FAST_REG_NO -> MRegsState
+freeMRegs      :: MRegsState -> [RegNo]     -> MRegsState
+
+mkMRegsState xs
+  = MRs (mkBS is) (mkBS fs2) IF_ARCH_sparc((mkBS ds2),)
+  where
+    (is, fs) = partition (< INT_FLPT_CUTOFF) xs
+#if sparc_TARGET_ARCH
+    (ss, ds) = partition (< SNGL_DBL_CUTOFF) fs
+    fs2         = map (subtract INT_FLPT_CUTOFF) ss
+    ds2         = map (subtract INT_FLPT_CUTOFF) (filter even ds)
+#else
+    fs2      = map (subtract INT_FLPT_CUTOFF) fs
+#endif
+
+------------------------------------------------
+#if sparc_TARGET_ARCH
+possibleMRegs FloatRep  (MRs _ ss _) = [ x + INT_FLPT_CUTOFF | x <- listBS ss]
+possibleMRegs DoubleRep (MRs _ _ ds) = [ x + INT_FLPT_CUTOFF | x <- listBS ds]
+possibleMRegs _         (MRs is _ _) = listBS is
+#else
+possibleMRegs FloatRep  (MRs _ fs) = [ x + INT_FLPT_CUTOFF | x <- listBS fs]
+possibleMRegs DoubleRep (MRs _ fs) = [ x + INT_FLPT_CUTOFF | x <- listBS fs]
+possibleMRegs _            (MRs is _) = listBS is
+#endif
+
+------------------------------------------------
+#if sparc_TARGET_ARCH
+useMReg (MRs is ss ds) n
+  = if (n _LT_ ILIT(INT_FLPT_CUTOFF)) then
+       MRs (is `minusBS` unitBS IBOX(n)) ss ds
+    else if (n _LT_ ILIT(SNGL_DBL_CUTOFF)) then
+       MRs is (ss `minusBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF)))) ds
+    else
+       MRs is ss (ds `minusBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
+#else
+useMReg (MRs is fs) n
+  = if (n _LT_ ILIT(INT_FLPT_CUTOFF))
+    then MRs (is `minusBS` unitBS IBOX(n)) fs
+    else MRs is (fs `minusBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
+#endif
+
+------------------------------------------------
+#if sparc_TARGET_ARCH
+useMRegs (MRs is ss ds) xs
+  = MRs (is `minusBS` is2) (ss `minusBS` ss2) (ds `minusBS` ds2)
+  where
+    MRs is2 ss2 ds2 = mkMRegsState xs
+#else
+useMRegs (MRs is fs) xs
+  = MRs (is `minusBS` is2) (fs `minusBS` fs2)
+  where
+    MRs is2 fs2 = mkMRegsState xs
+#endif
+
+------------------------------------------------
+#if sparc_TARGET_ARCH
+freeMReg (MRs is ss ds) n
+  = if (n _LT_ ILIT(INT_FLPT_CUTOFF)) then
+       MRs (is `unionBS` unitBS IBOX(n)) ss ds
+    else if (n _LT_ ILIT(SNGL_DBL_CUTOFF)) then
+       MRs is (ss `unionBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF)))) ds
+    else
+       MRs is ss (ds `unionBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
+#else
+freeMReg (MRs is fs) n
+  = if (n _LT_ ILIT(INT_FLPT_CUTOFF))
+    then MRs (is `unionBS` unitBS IBOX(n)) fs
+    else MRs is (fs `unionBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
+#endif
+
+------------------------------------------------
+#if sparc_TARGET_ARCH
+freeMRegs (MRs is ss ds) xs
+  = MRs (is `unionBS` is2) (ss `unionBS` ss2) (ds `unionBS` ds2)
+  where
+    MRs is2 ss2 ds2 = mkMRegsState xs
+#else
+freeMRegs (MRs is fs) xs
+  = MRs (is `unionBS` is2) (fs `unionBS` fs2)
+  where
+    MRs is2 fs2 = mkMRegsState xs
+#endif
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@RegUsage@ type; @noUsage@, @endUsage@, @regUsage@ functions}
+%*                                                                     *
+%************************************************************************
+
+@regUsage@ returns the sets of src and destination registers used by a
+particular instruction.  Machine registers that are pre-allocated to
+stgRegs are filtered out, because they are uninteresting from a
+register allocation standpoint.  (We wouldn't want them to end up on
+the free list!)
+
+An important point: The @regUsage@ function for a particular
+assembly language must not refer to fixed registers, such as Hp, SpA,
+etc.  The source and destination MRegsStates should only refer to
+dynamically allocated registers or static registers from the free
+list.  As far as we are concerned, the fixed registers simply don't
+exist (for allocation purposes, anyway).
+
+\begin{code}
+data RegUsage = RU RegSet RegSet
+
+noUsage, endUsage :: RegUsage
+noUsage  = RU emptyRegSet emptyRegSet
+endUsage = RU emptyRegSet freeRegSet
+
+regUsage :: Instr -> RegUsage
+
+#if alpha_TARGET_ARCH
+
+regUsage instr = case instr of
+    LD B reg addr      -> usage (regAddr addr, [reg, t9])
+    LD BU reg addr     -> usage (regAddr addr, [reg, t9])
+--  LD W reg addr      -> usage (regAddr addr, [reg, t9]) : UNUSED
+--  LD WU reg addr     -> usage (regAddr addr, [reg, t9]) : UNUSED
+    LD sz reg addr     -> usage (regAddr addr, [reg])
+    LDA reg addr       -> usage (regAddr addr, [reg])
+    LDAH reg addr      -> usage (regAddr addr, [reg])
+    LDGP reg addr      -> usage (regAddr addr, [reg])
+    LDI sz reg imm     -> usage ([], [reg])
+    ST B reg addr      -> usage (reg : regAddr addr, [t9, t10])
+--  ST W reg addr      -> usage (reg : regAddr addr, [t9, t10]) : UNUSED
+    ST sz reg addr     -> usage (reg : regAddr addr, [])
+    CLR reg            -> usage ([], [reg])
+    ABS sz ri reg      -> usage (regRI ri, [reg])
+    NEG sz ov ri reg   -> usage (regRI ri, [reg])
+    ADD sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
+    SADD sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
+    SUB sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
+    SSUB sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
+    MUL sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
+    DIV sz un r1 ar r2 -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
+    REM sz un r1 ar r2 -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
+    NOT ri reg         -> usage (regRI ri, [reg])
+    AND r1 ar r2       -> usage (r1 : regRI ar, [r2])
+    ANDNOT r1 ar r2    -> usage (r1 : regRI ar, [r2])
+    OR r1 ar r2                -> usage (r1 : regRI ar, [r2])
+    ORNOT r1 ar r2     -> usage (r1 : regRI ar, [r2])
+    XOR r1 ar r2       -> usage (r1 : regRI ar, [r2])
+    XORNOT r1 ar r2    -> usage (r1 : regRI ar, [r2])
+    SLL r1 ar r2       -> usage (r1 : regRI ar, [r2])
+    SRL r1 ar r2       -> usage (r1 : regRI ar, [r2])
+    SRA r1 ar r2       -> usage (r1 : regRI ar, [r2])
+    ZAP r1 ar r2       -> usage (r1 : regRI ar, [r2])
+    ZAPNOT r1 ar r2    -> usage (r1 : regRI ar, [r2])
+    CMP co r1 ar r2    -> usage (r1 : regRI ar, [r2])
+    FCLR reg           -> usage ([], [reg])
+    FABS r1 r2         -> usage ([r1], [r2])
+    FNEG sz r1 r2      -> usage ([r1], [r2])
+    FADD sz r1 r2 r3   -> usage ([r1, r2], [r3])
+    FDIV sz r1 r2 r3   -> usage ([r1, r2], [r3])
+    FMUL sz r1 r2 r3   -> usage ([r1, r2], [r3])
+    FSUB sz r1 r2 r3   -> usage ([r1, r2], [r3])
+    CVTxy sz1 sz2 r1 r2 -> usage ([r1], [r2])
+    FCMP sz co r1 r2 r3 -> usage ([r1, r2], [r3])
+    FMOV r1 r2         -> usage ([r1], [r2])
+
+
+    -- We assume that all local jumps will be BI/BF/BR.         JMP must be out-of-line.
+    BI cond reg lbl    -> usage ([reg], [])
+    BF cond reg lbl    -> usage ([reg], [])
+    JMP reg addr hint  -> RU (mkRegSet (filter interesting (regAddr addr))) freeRegSet
+
+    BSR _ n            -> RU (argRegSet n) callClobberedRegSet
+    JSR reg addr n     -> RU (argRegSet n) callClobberedRegSet
+
+    _                  -> noUsage
+
+  where
+    usage (src, dst) = RU (mkRegSet (filter interesting src))
+                         (mkRegSet (filter interesting dst))
+
+    interesting (FixedReg _) = False
+    interesting _ = True
+
+    regAddr (AddrReg r1)      = [r1]
+    regAddr (AddrRegImm r1 _) = [r1]
+    regAddr (AddrImm _)              = []
+
+    regRI (RIReg r) = [r]
+    regRI  _   = []
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+regUsage instr = case instr of
+    MOV  sz src dst    -> usage2 src dst
+    MOVZX sz src dst   -> usage2 src dst
+    MOVSX sz src dst   -> usage2 src dst
+    LEA  sz src dst    -> usage2 src dst
+    ADD  sz src dst    -> usage2 src dst
+    SUB  sz src dst    -> usage2 src dst
+    IMUL sz src dst    -> usage2 src dst
+    IDIV sz src                -> usage (eax:edx:opToReg src) [eax,edx]
+    AND  sz src dst    -> usage2 src dst
+    OR   sz src dst    -> usage2 src dst
+    XOR  sz src dst    -> usage2 src dst
+    NOT  sz op         -> usage1 op
+    NEGI sz op         -> usage1 op
+    SHL  sz imm dst    -> usage1 dst -- imm has to be an Imm
+    SAR  sz imm dst    -> usage1 dst -- imm has to be an Imm
+    SHR  sz imm dst    -> usage1 dst -- imm has to be an Imm
+    PUSH sz op         -> usage (opToReg op) []
+    POP  sz op         -> usage [] (opToReg op)
+    TEST sz src dst    -> usage (opToReg src ++ opToReg dst) []
+    CMP  sz src dst    -> usage (opToReg src ++ opToReg dst) []
+    SETCC cond op      -> usage [] (opToReg op)
+    JXX cond label     -> usage [] []
+    JMP op             -> usage (opToReg op) freeRegs
+    CALL imm           -> usage [] callClobberedRegs
+    CLTD               -> usage [eax] [edx]
+    NOP                        -> usage [] []
+    SAHF               -> usage [eax] []
+    FABS               -> usage [st0] [st0]
+    FADD sz src                -> usage (st0:opToReg src) [st0] -- allFPRegs
+    FADDP              -> usage [st0,st1] [st0] -- allFPRegs
+    FIADD sz asrc      -> usage (addrToRegs asrc) [st0]
+    FCHS               -> usage [st0] [st0]
+    FCOM sz src                -> usage (st0:opToReg src) []
+    FCOS               -> usage [st0] [st0]
+    FDIV sz src        -> usage (st0:opToReg src) [st0]
+    FDIVP              -> usage [st0,st1] [st0]
+    FDIVRP             -> usage [st0,st1] [st0]
+    FIDIV sz asrc      -> usage (addrToRegs asrc) [st0]
+    FDIVR sz src       -> usage (st0:opToReg src) [st0]
+    FIDIVR sz asrc     -> usage (addrToRegs asrc) [st0]
+    FICOM sz asrc      -> usage (addrToRegs asrc) []
+    FILD sz asrc dst   -> usage (addrToRegs asrc) [dst] -- allFPRegs
+    FIST sz adst       -> usage (st0:addrToRegs adst) []
+    FLD         sz src         -> usage (opToReg src) [st0] -- allFPRegs
+    FLD1               -> usage [] [st0] -- allFPRegs
+    FLDZ               -> usage [] [st0] -- allFPRegs
+    FMUL sz src        -> usage (st0:opToReg src) [st0]
+    FMULP              -> usage [st0,st1] [st0]
+    FIMUL sz asrc      -> usage (addrToRegs asrc) [st0]
+    FRNDINT            -> usage [st0] [st0]
+    FSIN               -> usage [st0] [st0]
+    FSQRT              -> usage [st0] [st0]
+    FST sz (OpReg r)   -> usage [st0] [r]
+    FST sz dst         -> usage (st0:opToReg dst) []
+    FSTP sz (OpReg r)  -> usage [st0] [r] -- allFPRegs
+    FSTP sz dst                -> usage (st0:opToReg dst) [] -- allFPRegs
+    FSUB sz src                -> usage (st0:opToReg src) [st0] -- allFPRegs
+    FSUBR sz src       -> usage (st0:opToReg src) [st0] -- allFPRegs
+    FISUB sz asrc      -> usage (addrToRegs asrc) [st0]
+    FSUBP              -> usage [st0,st1] [st0] -- allFPRegs
+    FSUBRP             -> usage [st0,st1] [st0] -- allFPRegs
+    FISUBR sz asrc     -> usage (addrToRegs asrc) [st0]
+    FTST               -> usage [st0] []
+    FCOMP sz op                -> usage (st0:opToReg op) [st0] -- allFPRegs
+    FUCOMPP            -> usage [st0, st1] [] --  allFPRegs
+    FXCH               -> usage [st0, st1] [st0, st1]
+    FNSTSW             -> usage [] [eax]
+    _                  -> noUsage
+ where
+    usage2 :: Operand -> Operand -> RegUsage
+    usage2 op (OpReg reg) = usage (opToReg op) [reg]
+    usage2 op (OpAddr ea) = usage (opToReg op ++ addrToRegs ea) []
+    usage2 op (OpImm imm) = usage (opToReg op) []
+    usage1 :: Operand -> RegUsage
+    usage1 (OpReg reg)    = usage [reg] [reg]
+    usage1 (OpAddr ea)    = usage (addrToRegs ea) []
+    allFPRegs = [st0,st1,st2,st3,st4,st5,st6,st7]
+
+    --callClobberedRegs = [ eax, ecx, edx ] -- according to gcc, anyway.
+    callClobberedRegs = [eax]
+
+-- General purpose register collecting functions.
+
+    opToReg (OpReg reg)   = [reg]
+    opToReg (OpImm imm)   = []
+    opToReg (OpAddr  ea)  = addrToRegs ea
+
+    addrToRegs (Addr base index _) = baseToReg base ++ indexToReg index
+      where  baseToReg Nothing       = []
+            baseToReg (Just r)      = [r]
+            indexToReg Nothing      = []
+            indexToReg (Just (r,_)) = [r]
+    addrToRegs (ImmAddr _ _) = []
+
+    usage src dst = RU (mkRegSet (filter interesting src))
+                      (mkRegSet (filter interesting dst))
+
+    interesting (FixedReg _) = False
+    interesting _ = True
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+regUsage instr = case instr of
+    LD sz addr reg     -> usage (regAddr addr, [reg])
+    ST sz reg addr     -> usage (reg : regAddr addr, [])
+    ADD x cc r1 ar r2  -> usage (r1 : regRI ar, [r2])
+    SUB x cc r1 ar r2  -> usage (r1 : regRI ar, [r2])
+    AND b r1 ar r2     -> usage (r1 : regRI ar, [r2])
+    ANDN b r1 ar r2    -> usage (r1 : regRI ar, [r2])
+    OR b r1 ar r2      -> usage (r1 : regRI ar, [r2])
+    ORN b r1 ar r2     -> usage (r1 : regRI ar, [r2])
+    XOR b r1 ar r2     -> usage (r1 : regRI ar, [r2])
+    XNOR b r1 ar r2    -> usage (r1 : regRI ar, [r2])
+    SLL r1 ar r2       -> usage (r1 : regRI ar, [r2])
+    SRL r1 ar r2       -> usage (r1 : regRI ar, [r2])
+    SRA r1 ar r2       -> usage (r1 : regRI ar, [r2])
+    SETHI imm reg      -> usage ([], [reg])
+    FABS s r1 r2       -> usage ([r1], [r2])
+    FADD s r1 r2 r3    -> usage ([r1, r2], [r3])
+    FCMP e s r1 r2     -> usage ([r1, r2], [])
+    FDIV s r1 r2 r3    -> usage ([r1, r2], [r3])
+    FMOV s r1 r2       -> usage ([r1], [r2])
+    FMUL s r1 r2 r3    -> usage ([r1, r2], [r3])
+    FNEG s r1 r2       -> usage ([r1], [r2])
+    FSQRT s r1 r2      -> usage ([r1], [r2])
+    FSUB s r1 r2 r3    -> usage ([r1, r2], [r3])
+    FxTOy s1 s2 r1 r2  -> usage ([r1], [r2])
+
+    -- We assume that all local jumps will be BI/BF.  JMP must be out-of-line.
+    JMP addr           -> RU (mkRegSet (filter interesting (regAddr addr))) freeRegSet
+
+    CALL _ n True      -> endUsage
+    CALL _ n False     -> RU (argRegSet n) callClobberedRegSet
+
+    _                  -> noUsage
+  where
+    usage (src, dst) = RU (mkRegSet (filter interesting src))
+                         (mkRegSet (filter interesting dst))
+
+    interesting (FixedReg _) = False
+    interesting _ = True
+
+    regAddr (AddrRegReg r1 r2) = [r1, r2]
+    regAddr (AddrRegImm r1 _)  = [r1]
+
+    regRI (RIReg r) = [r]
+    regRI  _   = []
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@RegLiveness@ type; @regLiveness@ function}
+%*                                                                     *
+%************************************************************************
+
+@regLiveness@ takes future liveness information and modifies it
+according to the semantics of branches and labels.  (An out-of-line
+branch clobbers the liveness passed back by the following instruction;
+a forward local branch passes back the liveness from the target label;
+a conditional branch merges the liveness from the target and the
+liveness from its successor; a label stashes away the current liveness
+in the future liveness environment).
+
+\begin{code}
+data RegLiveness = RL RegSet FutureLive
+
+regLiveness :: Instr -> RegLiveness -> RegLiveness
+
+regLiveness instr info@(RL live future@(FL all env))
+  = let
+       lookup lbl
+         = case (lookupFM env lbl) of
+           Just rs -> rs
+           Nothing -> trace ("Missing " ++ (uppShow 80 (pprCLabel_asm lbl)) ++
+                             " in future?") emptyRegSet
+    in
+    case instr of -- the rest is machine-specific...
+
+#if alpha_TARGET_ARCH
+
+    -- We assume that all local jumps will be BI/BF.  JMP must be out-of-line.
+
+    BR (ImmCLbl lbl)    -> RL (lookup lbl) future
+    BI _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
+    BF _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
+    JMP _ _ _           -> RL emptyRegSet future
+    BSR _ _             -> RL live future
+    JSR _ _ _           -> RL live future
+    LABEL lbl           -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
+    _                   -> info
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+    JXX _ lbl  -> RL (lookup lbl `unionRegSets` live) future
+    JMP _      -> RL emptyRegSet future
+    CALL _      -> RL live future
+    LABEL lbl   -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
+    _              -> info
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+    -- We assume that all local jumps will be BI/BF.  JMP must be out-of-line.
+
+    BI ALWAYS _ (ImmCLbl lbl)  -> RL (lookup lbl) future
+    BI _ _ (ImmCLbl lbl)       -> RL (lookup lbl `unionRegSets` live) future
+    BF ALWAYS _ (ImmCLbl lbl)  -> RL (lookup lbl) future
+    BF _ _ (ImmCLbl lbl)       -> RL (lookup lbl `unionRegSets` live) future
+    JMP _                      -> RL emptyRegSet future
+    CALL _ i True   -> RL emptyRegSet future
+    CALL _ i False  -> RL live future
+    LABEL lbl      -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
+    _              -> info
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@patchRegs@ function}
+%*                                                                     *
+%************************************************************************
+
+@patchRegs@ takes an instruction (possibly with
+MemoryReg/UnmappedReg registers) and changes all register references
+according to the supplied environment.
+
+\begin{code}
+patchRegs :: Instr -> (Reg -> Reg) -> Instr
+
+#if alpha_TARGET_ARCH
+
+patchRegs instr env = case instr of
+    LD sz reg addr -> LD sz (env reg) (fixAddr addr)
+    LDA reg addr -> LDA (env reg) (fixAddr addr)
+    LDAH reg addr -> LDAH (env reg) (fixAddr addr)
+    LDGP reg addr -> LDGP (env reg) (fixAddr addr)
+    LDI sz reg imm -> LDI sz (env reg) imm
+    ST sz reg addr -> ST sz (env reg) (fixAddr addr)
+    CLR reg -> CLR (env reg)
+    ABS sz ar reg -> ABS sz (fixRI ar) (env reg)
+    NEG sz ov ar reg -> NEG sz ov (fixRI ar) (env reg)
+    ADD sz ov r1 ar r2 -> ADD sz ov (env r1) (fixRI ar) (env r2)
+    SADD sz sc r1 ar r2 -> SADD sz sc (env r1) (fixRI ar) (env r2)
+    SUB sz ov r1 ar r2 -> SUB sz ov (env r1) (fixRI ar) (env r2)
+    SSUB sz sc r1 ar r2 -> SSUB sz sc (env r1) (fixRI ar) (env r2)
+    MUL sz ov r1 ar r2 -> MUL sz ov (env r1) (fixRI ar) (env r2)
+    DIV sz un r1 ar r2 -> DIV sz un (env r1) (fixRI ar) (env r2)
+    REM sz un r1 ar r2 -> REM sz un (env r1) (fixRI ar) (env r2)
+    NOT ar reg -> NOT (fixRI ar) (env reg)
+    AND r1 ar r2 -> AND (env r1) (fixRI ar) (env r2)
+    ANDNOT r1 ar r2 -> ANDNOT (env r1) (fixRI ar) (env r2)
+    OR r1 ar r2 -> OR (env r1) (fixRI ar) (env r2)
+    ORNOT r1 ar r2 -> ORNOT (env r1) (fixRI ar) (env r2)
+    XOR r1 ar r2 -> XOR (env r1) (fixRI ar) (env r2)
+    XORNOT r1 ar r2 -> XORNOT (env r1) (fixRI ar) (env r2)
+    SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
+    SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
+    SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
+    ZAP r1 ar r2 -> ZAP (env r1) (fixRI ar) (env r2)
+    ZAPNOT r1 ar r2 -> ZAPNOT (env r1) (fixRI ar) (env r2)
+    CMP co r1 ar r2 -> CMP co (env r1) (fixRI ar) (env r2)
+    FCLR reg -> FCLR (env reg)
+    FABS r1 r2 -> FABS (env r1) (env r2)
+    FNEG s r1 r2 -> FNEG s (env r1) (env r2)
+    FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
+    FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
+    FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
+    FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
+    CVTxy s1 s2 r1 r2 -> CVTxy s1 s2 (env r1) (env r2)
+    FCMP s co r1 r2 r3 -> FCMP s co (env r1) (env r2) (env r3)
+    FMOV r1 r2 -> FMOV (env r1) (env r2)
+    BI cond reg lbl -> BI cond (env reg) lbl
+    BF cond reg lbl -> BF cond (env reg) lbl
+    JMP reg addr hint -> JMP (env reg) (fixAddr addr) hint
+    JSR reg addr i -> JSR (env reg) (fixAddr addr) i
+    _ -> instr
+  where
+    fixAddr (AddrReg r1)       = AddrReg (env r1)
+    fixAddr (AddrRegImm r1 i)  = AddrRegImm (env r1) i
+    fixAddr other             = other
+
+    fixRI (RIReg r) = RIReg (env r)
+    fixRI other        = other
+
+#endif {- alpha_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if i386_TARGET_ARCH
+
+patchRegs instr env = case instr of
+    MOV  sz src dst    -> patch2 (MOV  sz) src dst
+    MOVZX sz src dst   -> patch2 (MOVZX sz) src dst
+    MOVSX sz src dst   -> patch2 (MOVSX sz) src dst
+    LEA  sz src dst    -> patch2 (LEA  sz) src dst
+    ADD  sz src dst    -> patch2 (ADD  sz) src dst
+    SUB  sz src dst    -> patch2 (SUB  sz) src dst
+    IMUL sz src dst    -> patch2 (IMUL sz) src dst
+    IDIV sz src        -> patch1 (IDIV sz) src
+    AND  sz src dst    -> patch2 (AND  sz) src dst
+    OR   sz src dst    -> patch2 (OR   sz) src dst
+    XOR  sz src dst    -> patch2 (XOR  sz) src dst
+    NOT  sz op                 -> patch1 (NOT  sz) op
+    NEGI sz op         -> patch1 (NEGI sz) op
+    SHL  sz imm dst    -> patch1 (SHL  sz imm) dst
+    SAR  sz imm dst    -> patch1 (SAR  sz imm) dst
+    SHR  sz imm dst    -> patch1 (SHR  sz imm) dst
+    TEST sz src dst    -> patch2 (TEST sz) src dst
+    CMP  sz src dst    -> patch2 (CMP  sz) src dst
+    PUSH sz op         -> patch1 (PUSH sz) op
+    POP  sz op         -> patch1 (POP  sz) op
+    SETCC cond op      -> patch1 (SETCC cond) op
+    JMP op             -> patch1 JMP op
+    FADD sz src                -> FADD sz (patchOp src)
+    FIADD sz asrc      -> FIADD sz (lookupAddr asrc)
+    FCOM sz src                -> patch1 (FCOM sz) src
+    FDIV sz src        -> FDIV sz (patchOp src)
+    --FDIVP sz src     -> FDIVP sz (patchOp src)
+    FIDIV sz asrc      -> FIDIV sz (lookupAddr asrc)
+    FDIVR sz src       -> FDIVR sz (patchOp src)
+    --FDIVRP sz src    -> FDIVRP sz (patchOp src)
+    FIDIVR sz asrc     -> FIDIVR sz (lookupAddr asrc)
+    FICOM sz asrc      -> FICOM sz (lookupAddr asrc)
+    FILD sz asrc dst   -> FILD sz (lookupAddr asrc) (env dst)
+    FIST sz adst       -> FIST sz (lookupAddr adst)
+    FLD        sz src          -> patch1 (FLD sz) (patchOp src)
+    FMUL sz src        -> FMUL sz (patchOp src)
+    --FMULP sz src     -> FMULP sz (patchOp src)
+    FIMUL sz asrc      -> FIMUL sz (lookupAddr asrc)
+    FST sz dst         -> FST sz (patchOp dst)
+    FSTP sz dst                -> FSTP sz (patchOp dst)
+    FSUB sz src                -> FSUB sz (patchOp src)
+    --FSUBP sz src     -> FSUBP sz (patchOp src)
+    FISUB sz asrc      -> FISUB sz (lookupAddr asrc)
+    FSUBR sz src       -> FSUBR sz (patchOp src)
+    --FSUBRP sz src    -> FSUBRP sz (patchOp src)
+    FISUBR sz asrc     -> FISUBR sz (lookupAddr asrc)
+    FCOMP sz src       -> FCOMP sz (patchOp src)
+    _                  -> instr
+  where
+    patch1 insn op      = insn (patchOp op)
+    patch2 insn src dst = insn (patchOp src) (patchOp dst)
+
+    patchOp (OpReg  reg) = OpReg (env reg)
+    patchOp (OpImm  imm) = OpImm imm
+    patchOp (OpAddr ea)  = OpAddr (lookupAddr ea)
+
+    lookupAddr (ImmAddr imm off) = ImmAddr imm off
+    lookupAddr (Addr base index disp)
+      = Addr (lookupBase base) (lookupIndex index) disp
+      where
+       lookupBase Nothing       = Nothing
+       lookupBase (Just r)      = Just (env r)
+                                
+       lookupIndex Nothing      = Nothing
+       lookupIndex (Just (r,i)) = Just (env r, i)
+
+#endif {- i386_TARGET_ARCH -}
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if sparc_TARGET_ARCH
+
+patchRegs instr env = case instr of
+    LD sz addr reg -> LD sz (fixAddr addr) (env reg)
+    ST sz reg addr -> ST sz (env reg) (fixAddr addr)
+    ADD x cc r1 ar r2 -> ADD x cc (env r1) (fixRI ar) (env r2)
+    SUB x cc r1 ar r2 -> SUB x cc (env r1) (fixRI ar) (env r2)
+    AND b r1 ar r2 -> AND b (env r1) (fixRI ar) (env r2)
+    ANDN b r1 ar r2 -> ANDN b (env r1) (fixRI ar) (env r2)
+    OR b r1 ar r2 -> OR b (env r1) (fixRI ar) (env r2)
+    ORN b r1 ar r2 -> ORN b (env r1) (fixRI ar) (env r2)
+    XOR b r1 ar r2 -> XOR b (env r1) (fixRI ar) (env r2)
+    XNOR b r1 ar r2 -> XNOR b (env r1) (fixRI ar) (env r2)
+    SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
+    SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
+    SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
+    SETHI imm reg -> SETHI imm (env reg)
+    FABS s r1 r2 -> FABS s (env r1) (env r2)
+    FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
+    FCMP e s r1 r2 -> FCMP e s (env r1) (env r2)
+    FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
+    FMOV s r1 r2 -> FMOV s (env r1) (env r2)
+    FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
+    FNEG s r1 r2 -> FNEG s (env r1) (env r2)
+    FSQRT s r1 r2 -> FSQRT s (env r1) (env r2)
+    FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
+    FxTOy s1 s2 r1 r2 -> FxTOy s1 s2 (env r1) (env r2)
+    JMP addr -> JMP (fixAddr addr)
+    _ -> instr
+  where
+    fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
+    fixAddr (AddrRegImm r1 i)  = AddrRegImm (env r1) i
+
+    fixRI (RIReg r) = RIReg (env r)
+    fixRI other        = other
+
+#endif {- sparc_TARGET_ARCH -}
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\subsection{@spillReg@ and @loadReg@ functions}
+%*                                                                     *
+%************************************************************************
+
+Spill to memory, and load it back...
+
+\begin{code}
+spillReg, loadReg :: Reg -> Reg -> InstrList
+
+spillReg dyn (MemoryReg i pk)
+  = let
+       sz = primRepToSize pk
+    in
+    mkUnitList (
+       {-Alpha: spill below the stack pointer (?)-}
+        IF_ARCH_alpha( ST sz dyn (spRel i)
+
+       {-I386: spill below stack pointer leaving 2 words/spill-}
+       ,IF_ARCH_i386 ( MOV sz (OpReg dyn) (OpAddr (spRel (-2 * i)))
+
+       {-SPARC: spill below frame pointer leaving 2 words/spill-}
+       ,IF_ARCH_sparc( ST sz dyn (fpRel (-2 * i))
+        ,)))
+    )
+
+----------------------------
+loadReg (MemoryReg i pk) dyn
+  = let
+       sz = primRepToSize pk
+    in
+    mkUnitList (
+        IF_ARCH_alpha( LD  sz dyn (spRel i)
+       ,IF_ARCH_i386 ( MOV sz (OpAddr (spRel (-2 * i))) (OpReg dyn)
+       ,IF_ARCH_sparc( LD  sz (fpRel (-2 * i)) dyn
+       ,)))
+    )
+\end{code}
diff --git a/ghc/compiler/nativeGen/SparcCode.lhs b/ghc/compiler/nativeGen/SparcCode.lhs
deleted file mode 100644 (file)
index 203807e..0000000
+++ /dev/null
@@ -1,1389 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1993-1995
-%
-
-\section[SparcCode]{The Native (Sparc) Machine Code}
-
-\begin{code}
-#define ILIT2(x) ILIT(x)
-#include "HsVersions.h"
-
-module SparcCode (
-       Addr(..),Cond(..),Imm(..),RI(..),Size(..),
-       SparcCode(..),SparcInstr(..),SparcRegs,
-       strImmLit,
-
-       printLabeledCodes,
-
-       baseRegOffset, stgRegMap, callerSaves,
-
-       is13Bits, offset,
-
-       kindToSize,
-
-       g0, o0, f0, fp, sp, argRegs,
-
-       freeRegs, reservedRegs
-
-       -- and, for self-sufficiency ...
-    ) where
-
-IMPORT_Trace
-
-import AbsCSyn         ( MagicId(..) )
-import AsmRegAlloc     ( MachineCode(..), MachineRegisters(..), FutureLive(..),
-                         Reg(..), RegUsage(..), RegLiveness(..)
-                       )
-import BitSet
-import CgCompInfo      ( mAX_Double_REG, mAX_Float_REG, mAX_Vanilla_REG )
-import CLabel          ( CLabel, pprCLabel, externallyVisibleCLabel, charToC )
-import FiniteMap
-import Maybes          ( Maybe(..), maybeToBool )
-import OrdList         ( OrdList, mkUnitList, flattenOrdList )
-import Outputable
-import UniqSet
-import Stix
-import Unpretty
-import Util
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[SparcReg]{The Native (Sparc) Machine Register Table}
-%*                                                                     *
-%************************************************************************
-
-The sparc has 64 registers of interest; 32 integer registers and 32 floating
-point registers.  The mapping of STG registers to sparc machine registers
-is defined in StgRegs.h.  We are, of course, prepared for any eventuality.
-
-ToDo: Deal with stg registers that live as offsets from BaseReg!(JSM)
-
-\begin{code}
-
-gReg,lReg,iReg,oReg,fReg :: Int -> Int
-gReg x = x
-oReg x = (8 + x)
-lReg x = (16 + x)
-iReg x = (24 + x)
-fReg x = (32 + x)
-
-fPair :: Reg -> Reg
-fPair (FixedReg i) = FixedReg (i _ADD_ ILIT(1))
-fPair (MappedReg i) = MappedReg (i _ADD_ ILIT(1))
-
-g0, fp, sp, o0, f0 :: Reg
-g0 = case (gReg 0) of { IBOX(g0) -> FixedReg g0 }
-fp = case (iReg 6) of { IBOX(i6) -> FixedReg i6 }
-sp = case (oReg 6) of { IBOX(o6) -> FixedReg o6 }
-o0 = realReg  (oReg 0)
-f0 = realReg  (fReg 0)
-
-argRegs :: [Reg]
-argRegs = map realReg [oReg i | i <- [0..5]]
-
-realReg n@IBOX(i) = if _IS_TRUE_(freeReg i) then MappedReg i else FixedReg i
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[TheSparcCode]{The datatype for sparc assembly language}
-%*                                                                     *
-%************************************************************************
-
-Here is a definition of the Sparc assembly language.
-
-\begin{code}
-
-data Imm = ImmInt Int
-        | ImmInteger Integer         -- Sigh.
-        | ImmCLbl CLabel             -- AbstractC Label (with baggage)
-        | ImmLab  Unpretty           -- Simple string label (underscored)
-        | ImmLit Unpretty            -- Simple string
-        | LO Imm                     -- Possible restrictions
-        | HI Imm
-        deriving ()
-
-strImmLit s = ImmLit (uppStr s)
-
-data Addr = AddrRegReg Reg Reg
-         | AddrRegImm Reg Imm
-         deriving ()
-
-data Cond = ALWAYS
-         | NEVER
-         | GEU
-         | LU
-         | EQ
-         | GT
-         | GE
-         | GU
-         | LT
-         | LE
-         | LEU
-         | NE
-         | NEG
-         | POS
-         | VC
-         | VS
-         deriving ()
-
-data RI = RIReg Reg
-       | RIImm Imm
-       deriving ()
-
-riZero :: RI -> Bool
-riZero (RIImm (ImmInt 0))          = True
-riZero (RIImm (ImmInteger 0))      = True
-riZero (RIReg (FixedReg ILIT(0)))   = True
-riZero _                           = False
-
-data Size = SB
-         | HW
-         | UB
-         | UHW
-         | W
-         | D
-         | F
-         | DF
-         deriving ()
-
-data SparcInstr =
-
--- Loads and stores.
-
-               LD            Size Addr Reg -- size, src, dst
-             | ST            Size Reg Addr -- size, src, dst
-
--- Int Arithmetic.
-
-             | ADD           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
-             | SUB           Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
-
--- Simple bit-twiddling.
-
-             | AND           Bool Reg RI Reg -- cc?, src1, src2, dst
-             | ANDN          Bool Reg RI Reg -- cc?, src1, src2, dst
-             | OR            Bool Reg RI Reg -- cc?, src1, src2, dst
-             | ORN           Bool Reg RI Reg -- cc?, src1, src2, dst
-             | XOR           Bool Reg RI Reg -- cc?, src1, src2, dst
-             | XNOR          Bool Reg RI Reg -- cc?, src1, src2, dst
-             | SLL           Reg RI Reg -- src1, src2, dst
-             | SRL           Reg RI Reg -- src1, src2, dst
-             | SRA           Reg RI Reg -- src1, src2, dst
-             | SETHI         Imm Reg -- src, dst
-             | NOP           -- Really SETHI 0, %g0, but worth an alias
-
--- Float Arithmetic.
-
--- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single instructions
--- right up until we spit them out.
-
-             | FABS          Size Reg Reg -- src dst
-             | FADD          Size Reg Reg Reg -- src1, src2, dst
-             | FCMP          Bool Size Reg Reg -- exception?, src1, src2, dst
-             | FDIV          Size Reg Reg Reg -- src1, src2, dst
-             | FMOV          Size Reg Reg -- src, dst
-             | FMUL          Size Reg Reg Reg -- src1, src2, dst
-             | FNEG          Size Reg Reg -- src, dst
-             | FSQRT         Size Reg Reg -- src, dst
-             | FSUB          Size Reg Reg Reg -- src1, src2, dst
-             | FxTOy         Size Size Reg Reg -- src, dst
-
--- Jumping around.
-
-             | BI            Cond Bool Imm -- cond, annul?, target
-             | BF            Cond Bool Imm -- cond, annul?, target
-
-             | JMP           Addr -- target
-             | CALL          Imm Int Bool -- target, args, terminal
-
--- Pseudo-ops.
-
-             | LABEL CLabel
-             | COMMENT FAST_STRING
-             | SEGMENT CodeSegment
-             | ASCII Bool String   -- needs backslash conversion?
-             | DATA Size [Imm]
-
-type SparcCode = OrdList SparcInstr
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[TheSparcPretty]{Pretty-printing the Sparc Assembly Language}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-
-printLabeledCodes :: PprStyle -> [SparcInstr] -> Unpretty
-printLabeledCodes sty codes = uppAboves (map (pprSparcInstr sty) codes)
-
-\end{code}
-
-Printing the pieces...
-
-\begin{code}
-
-pprReg :: Reg -> Unpretty
-
-pprReg (FixedReg i) = pprSparcReg i
-pprReg (MappedReg i) = pprSparcReg i
-pprReg other = uppStr (show other)   -- should only happen when debugging
-
-pprSparcReg :: FAST_INT -> Unpretty
-pprSparcReg i = uppPStr
-    (case i of {
-       ILIT( 0) -> SLIT("%g0");  ILIT( 1) -> SLIT("%g1");
-       ILIT( 2) -> SLIT("%g2");  ILIT( 3) -> SLIT("%g3");
-       ILIT( 4) -> SLIT("%g4");  ILIT( 5) -> SLIT("%g5");
-       ILIT( 6) -> SLIT("%g6");  ILIT( 7) -> SLIT("%g7");
-       ILIT( 8) -> SLIT("%o0");  ILIT( 9) -> SLIT("%o1");
-       ILIT(10) -> SLIT("%o2");  ILIT(11) -> SLIT("%o3");
-       ILIT(12) -> SLIT("%o4");  ILIT(13) -> SLIT("%o5");
-       ILIT(14) -> SLIT("%o6");  ILIT(15) -> SLIT("%o7");
-       ILIT(16) -> SLIT("%l0");  ILIT(17) -> SLIT("%l1");
-       ILIT(18) -> SLIT("%l2");  ILIT(19) -> SLIT("%l3");
-       ILIT(20) -> SLIT("%l4");  ILIT(21) -> SLIT("%l5");
-       ILIT(22) -> SLIT("%l6");  ILIT(23) -> SLIT("%l7");
-       ILIT(24) -> SLIT("%i0");  ILIT(25) -> SLIT("%i1");
-       ILIT(26) -> SLIT("%i2");  ILIT(27) -> SLIT("%i3");
-       ILIT(28) -> SLIT("%i4");  ILIT(29) -> SLIT("%i5");
-       ILIT(30) -> SLIT("%i6");  ILIT(31) -> SLIT("%i7");
-       ILIT(32) -> SLIT("%f0");  ILIT(33) -> SLIT("%f1");
-       ILIT(34) -> SLIT("%f2");  ILIT(35) -> SLIT("%f3");
-       ILIT(36) -> SLIT("%f4");  ILIT(37) -> SLIT("%f5");
-       ILIT(38) -> SLIT("%f6");  ILIT(39) -> SLIT("%f7");
-       ILIT(40) -> SLIT("%f8");  ILIT(41) -> SLIT("%f9");
-       ILIT(42) -> SLIT("%f10"); ILIT(43) -> SLIT("%f11");
-       ILIT(44) -> SLIT("%f12"); ILIT(45) -> SLIT("%f13");
-       ILIT(46) -> SLIT("%f14"); ILIT(47) -> SLIT("%f15");
-       ILIT(48) -> SLIT("%f16"); ILIT(49) -> SLIT("%f17");
-       ILIT(50) -> SLIT("%f18"); ILIT(51) -> SLIT("%f19");
-       ILIT(52) -> SLIT("%f20"); ILIT(53) -> SLIT("%f21");
-       ILIT(54) -> SLIT("%f22"); ILIT(55) -> SLIT("%f23");
-       ILIT(56) -> SLIT("%f24"); ILIT(57) -> SLIT("%f25");
-       ILIT(58) -> SLIT("%f26"); ILIT(59) -> SLIT("%f27");
-       ILIT(60) -> SLIT("%f28"); ILIT(61) -> SLIT("%f29");
-       ILIT(62) -> SLIT("%f30"); ILIT(63) -> SLIT("%f31");
-       _ -> SLIT("very naughty sparc register")
-    })
-
-pprCond :: Cond -> Unpretty
-pprCond x = uppPStr
-    (case x of {
-       ALWAYS  -> SLIT("");    NEVER -> SLIT("n");
-       GEU     -> SLIT("geu"); LU    -> SLIT("lu");
-       EQ      -> SLIT("e");   GT    -> SLIT("g");
-       GE      -> SLIT("ge");  GU    -> SLIT("gu");
-       LT      -> SLIT("l");   LE    -> SLIT("le");
-       LEU     -> SLIT("leu"); NE    -> SLIT("ne");
-       NEG     -> SLIT("neg"); POS   -> SLIT("pos");
-       VC      -> SLIT("vc");  VS    -> SLIT("vs")
-    })
-
-pprImm :: PprStyle -> Imm -> Unpretty
-
-pprImm sty (ImmInt i) = uppInt i
-pprImm sty (ImmInteger i) = uppInteger i
-
-pprImm sty (LO i) =
-    uppBesides [
-         pp_lo,
-         pprImm sty i,
-         uppRparen
-    ]
-  where
-#ifdef USE_FAST_STRINGS
-    pp_lo = uppPStr (_packCString (A# "%lo("#))
-#else
-    pp_lo = uppStr "%lo("
-#endif
-
-pprImm sty (HI i) =
-    uppBesides [
-         pp_hi,
-         pprImm sty i,
-         uppRparen
-    ]
-  where
-#ifdef USE_FAST_STRINGS
-    pp_hi = uppPStr (_packCString (A# "%hi("#))
-#else
-    pp_hi = uppStr "%hi("
-#endif
-
-pprImm sty (ImmCLbl l) = pprCLabel sty l
-
-pprImm (PprForAsm _ False _) (ImmLab s) = s
-pprImm _                     (ImmLab s) = uppBeside (uppChar '_') s
-
-pprImm sty (ImmLit s) = s
-
-pprAddr :: PprStyle -> Addr -> Unpretty
-pprAddr sty (AddrRegReg r1 (FixedReg ILIT(0))) = pprReg r1
-
-pprAddr sty (AddrRegReg r1 r2) =
-    uppBesides [
-       pprReg r1,
-       uppChar '+',
-       pprReg r2
-    ]
-
-pprAddr sty (AddrRegImm r1 (ImmInt i))
-    | i == 0 = pprReg r1
-    | i < -4096 || i > 4095 = large_offset_error i
-    | i < 0  =
-       uppBesides [
-           pprReg r1,
-           uppChar '-',
-           uppInt (-i)
-       ]
-
-pprAddr sty (AddrRegImm r1 (ImmInteger i))
-    | i == 0 = pprReg r1
-    | i < -4096 || i > 4095 = large_offset_error i
-    | i < 0  =
-       uppBesides [
-           pprReg r1,
-           uppChar '-',
-           uppInteger (-i)
-       ]
-
-pprAddr sty (AddrRegImm r1 imm) =
-    uppBesides [
-       pprReg r1,
-       uppChar '+',
-       pprImm sty imm
-    ]
-
-large_offset_error i
-  = error ("ERROR: SPARC native-code generator cannot handle large offset ("++show i++");\nprobably because of large constant data structures;\nworkaround: use -fvia-C on this module.\n")
-
-pprRI :: PprStyle -> RI -> Unpretty
-pprRI sty (RIReg r) = pprReg r
-pprRI sty (RIImm r) = pprImm sty r
-
-pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Unpretty
-pprSizeRegReg name size reg1 reg2 =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       (case size of
-           F  -> uppPStr SLIT("s\t")
-           DF -> uppPStr SLIT("d\t")),
-       pprReg reg1,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Unpretty
-pprSizeRegRegReg name size reg1 reg2 reg3 =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       (case size of
-           F  -> uppPStr SLIT("s\t")
-           DF -> uppPStr SLIT("d\t")),
-       pprReg reg1,
-       uppComma,
-       pprReg reg2,
-       uppComma,
-       pprReg reg3
-    ]
-
-pprRegRIReg :: PprStyle -> FAST_STRING -> Bool -> Reg -> RI -> Reg -> Unpretty
-pprRegRIReg sty name b reg1 ri reg2 =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       if b then uppPStr SLIT("cc\t") else uppChar '\t',
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
-
-pprRIReg :: PprStyle -> FAST_STRING -> Bool -> RI -> Reg -> Unpretty
-pprRIReg sty name b ri reg1 =
-    uppBesides [
-       uppChar '\t',
-       uppPStr name,
-       if b then uppPStr SLIT("cc\t") else uppChar '\t',
-       pprRI sty ri,
-       uppComma,
-       pprReg reg1
-    ]
-
-pprSize :: Size -> Unpretty
-pprSize x = uppPStr
-    (case x of
-       SB  -> SLIT("sb")
-       HW  -> SLIT("hw")
-       UB  -> SLIT("ub")
-       UHW -> SLIT("uhw")
-       W   -> SLIT("")
-       F   -> SLIT("")
-       D   -> SLIT("d")
-       DF  -> SLIT("d")
-    )
-
-#ifdef USE_FAST_STRINGS
-pp_ld_lbracket    = uppPStr (_packCString (A# "\tld\t["#))
-pp_rbracket_comma = uppPStr (_packCString (A# "],"#))
-pp_comma_lbracket = uppPStr (_packCString (A# ",["#))
-pp_comma_a       = uppPStr (_packCString (A# ",a"#))
-#else
-pp_ld_lbracket    = uppStr "\tld\t["
-pp_rbracket_comma = uppStr "],"
-pp_comma_lbracket = uppStr ",["
-pp_comma_a       = uppStr ",a"
-#endif
-
-pprSparcInstr :: PprStyle -> SparcInstr -> Unpretty
-
--- a clumsy hack for now, to handle possible alignment problems
-
-pprSparcInstr sty (LD DF addr reg) | maybeToBool addrOff =
-    uppBesides [
-       pp_ld_lbracket,
-       pprAddr sty addr,
-       pp_rbracket_comma,
-       pprReg reg,
-
-       uppChar '\n',
-       pp_ld_lbracket,
-       pprAddr sty addr2,
-       pp_rbracket_comma,
-       pprReg (fPair reg)
-    ]
-  where
-    addrOff = offset addr 4
-    addr2 = case addrOff of Just x -> x
-
-pprSparcInstr sty (LD size addr reg) =
-    uppBesides [
-       uppPStr SLIT("\tld"),
-       pprSize size,
-       uppChar '\t',
-       uppLbrack,
-       pprAddr sty addr,
-       pp_rbracket_comma,
-       pprReg reg
-    ]
-
--- The same clumsy hack as above
-
-pprSparcInstr sty (ST DF reg addr) | maybeToBool addrOff =
-    uppBesides [
-       uppPStr SLIT("\tst\t"),
-       pprReg reg,
-       pp_comma_lbracket,
-       pprAddr sty addr,
-
-       uppPStr SLIT("]\n\tst\t"),
-       pprReg (fPair reg),
-       pp_comma_lbracket,
-       pprAddr sty addr2,
-       uppRbrack
-    ]
-  where
-    addrOff = offset addr 4
-    addr2 = case addrOff of Just x -> x
-
-pprSparcInstr sty (ST size reg addr) =
-    uppBesides [
-       uppPStr SLIT("\tst"),
-       pprSize size,
-       uppChar '\t',
-       pprReg reg,
-       pp_comma_lbracket,
-       pprAddr sty addr,
-       uppRbrack
-    ]
-
-pprSparcInstr sty (ADD x cc reg1 ri reg2)
- | not x && not cc && riZero ri =
-    uppBesides [
-       uppPStr SLIT("\tmov\t"),
-       pprReg reg1,
-       uppComma,
-       pprReg reg2
-    ]
- | otherwise = pprRegRIReg sty (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
-
-pprSparcInstr sty (SUB x cc reg1 ri reg2)
- | not x && cc && reg2 == g0 =
-    uppBesides [
-       uppPStr SLIT("\tcmp\t"),
-       pprReg reg1,
-       uppComma,
-       pprRI sty ri
-    ]
- | not x && not cc && riZero ri =
-    uppBesides [
-       uppPStr SLIT("\tmov\t"),
-       pprReg reg1,
-       uppComma,
-       pprReg reg2
-    ]
- | otherwise = pprRegRIReg sty (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
-
-pprSparcInstr sty (AND b reg1 ri reg2) = pprRegRIReg sty SLIT("and") b reg1 ri reg2
-pprSparcInstr sty (ANDN b reg1 ri reg2) = pprRegRIReg sty SLIT("andn") b reg1 ri reg2
-
-pprSparcInstr sty (OR b reg1 ri reg2)
- | not b && reg1 == g0 =
-    uppBesides [
-       uppPStr SLIT("\tmov\t"),
-       pprRI sty ri,
-       uppComma,
-       pprReg reg2
-    ]
- | otherwise = pprRegRIReg sty SLIT("or") b reg1 ri reg2
-
-pprSparcInstr sty (ORN b reg1 ri reg2) = pprRegRIReg sty SLIT("orn") b reg1 ri reg2
-
-pprSparcInstr sty (XOR b reg1 ri reg2) = pprRegRIReg sty SLIT("xor") b reg1 ri reg2
-pprSparcInstr sty (XNOR b reg1 ri reg2) = pprRegRIReg sty SLIT("xnor") b reg1 ri reg2
-
-pprSparcInstr sty (SLL reg1 ri reg2) = pprRegRIReg sty SLIT("sll") False reg1 ri reg2
-pprSparcInstr sty (SRL reg1 ri reg2) = pprRegRIReg sty SLIT("srl") False reg1 ri reg2
-pprSparcInstr sty (SRA reg1 ri reg2) = pprRegRIReg sty SLIT("sra") False reg1 ri reg2
-
-pprSparcInstr sty (SETHI imm reg) =
-    uppBesides [
-       uppPStr SLIT("\tsethi\t"),
-       pprImm sty imm,
-       uppComma,
-       pprReg reg
-    ]
-
-pprSparcInstr sty (NOP) = uppPStr SLIT("\tnop")
-
-pprSparcInstr sty (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
-pprSparcInstr sty (FABS DF reg1 reg2) =
-    uppBeside (pprSizeRegReg SLIT("fabs") F reg1 reg2)
-    (if (reg1 == reg2) then uppNil
-     else uppBeside (uppChar '\n')
-         (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
-
-pprSparcInstr sty (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
-pprSparcInstr sty (FCMP e size reg1 reg2) =
-    pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
-pprSparcInstr sty (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
-
-pprSparcInstr sty (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
-pprSparcInstr sty (FMOV DF reg1 reg2) =
-    uppBeside (pprSizeRegReg SLIT("fmov") F reg1 reg2)
-    (if (reg1 == reg2) then uppNil
-     else uppBeside (uppChar '\n')
-         (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
-
-pprSparcInstr sty (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
-
-pprSparcInstr sty (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
-pprSparcInstr sty (FNEG DF reg1 reg2) =
-    uppBeside (pprSizeRegReg SLIT("fneg") F reg1 reg2)
-    (if (reg1 == reg2) then uppNil
-     else uppBeside (uppChar '\n')
-         (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
-
-pprSparcInstr sty (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
-pprSparcInstr sty (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
-pprSparcInstr sty (FxTOy size1 size2 reg1 reg2) =
-    uppBesides [
-       uppPStr SLIT("\tf"),
-       uppPStr
-       (case size1 of
-           W  -> SLIT("ito")
-           F  -> SLIT("sto")
-           DF -> SLIT("dto")),
-       uppPStr
-       (case size2 of
-           W  -> SLIT("i\t")
-           F  -> SLIT("s\t")
-           DF -> SLIT("d\t")),
-       pprReg reg1,
-       uppComma,
-       pprReg reg2
-    ]
-
-
-pprSparcInstr sty (BI cond b lab) =
-    uppBesides [
-       uppPStr SLIT("\tb"), pprCond cond,
-       if b then pp_comma_a else uppNil,
-       uppChar '\t',
-       pprImm sty lab
-    ]
-
-pprSparcInstr sty (BF cond b lab) =
-    uppBesides [
-       uppPStr SLIT("\tfb"), pprCond cond,
-       if b then pp_comma_a else uppNil,
-       uppChar '\t',
-       pprImm sty lab
-    ]
-
-pprSparcInstr sty (JMP addr) = uppBeside (uppPStr SLIT("\tjmp\t")) (pprAddr sty addr)
-
-pprSparcInstr sty (CALL imm n _) =
-    uppBesides [
-       uppPStr SLIT("\tcall\t"),
-       pprImm sty imm,
-       uppComma,
-       uppInt n
-    ]
-
-pprSparcInstr sty (LABEL clab) =
-    uppBesides [
-       if (externallyVisibleCLabel clab) then
-           uppBesides [uppPStr SLIT("\t.global\t"), pprLab, uppChar '\n']
-       else
-           uppNil,
-       pprLab,
-       uppChar ':'
-    ]
-    where pprLab = pprCLabel sty clab
-
-pprSparcInstr sty (COMMENT s) = uppBeside (uppPStr SLIT("! ")) (uppPStr s)
-
-pprSparcInstr sty (SEGMENT TextSegment)
-    = uppPStr SLIT("\t.text\n\t.align 4")
-
-pprSparcInstr sty (SEGMENT DataSegment)
-    = uppPStr SLIT("\t.data\n\t.align 8")   -- Less than 8 will break double constants
-
-pprSparcInstr sty (ASCII False str) =
-    uppBesides [
-       uppStr "\t.asciz \"",
-       uppStr str,
-       uppChar '"'
-    ]
-
-pprSparcInstr sty (ASCII True str) = uppBeside (uppStr "\t.ascii \"") (asciify str 60)
-    where
-       asciify :: String -> Int -> Unpretty
-       asciify [] _ = uppStr ("\\0\"")
-       asciify s n | n <= 0 = uppBeside (uppStr "\"\n\t.ascii \"") (asciify s 60)
-       asciify ('\\':cs) n = uppBeside (uppStr "\\\\") (asciify cs (n-1))
-       asciify ('\"':cs) n = uppBeside (uppStr "\\\"") (asciify cs (n-1))
-       asciify (c:cs) n | isPrint c = uppBeside (uppChar c) (asciify cs (n-1))
-       asciify [c] _ = uppBeside (uppStr (charToC c)) (uppStr ("\\0\""))
-       asciify (c:(cs@(d:_))) n | isDigit d =
-                                       uppBeside (uppStr (charToC c)) (asciify cs 0)
-                                | otherwise =
-                                       uppBeside (uppStr (charToC c)) (asciify cs (n-1))
-
-pprSparcInstr sty (DATA s xs) = uppInterleave (uppChar '\n') (map pp_item xs)
-    where pp_item x = case s of
-           SB -> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
-           UB -> uppBeside (uppPStr SLIT("\t.byte\t")) (pprImm sty x)
-           W  -> uppBeside (uppPStr SLIT("\t.word\t")) (pprImm sty x)
-           DF -> uppBeside (uppPStr SLIT("\t.double\t")) (pprImm sty x)
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Schedule]{Register allocation information}
-%*                                                                     *
-%************************************************************************
-
-Getting the conflicts right is a bit tedious for doubles.  We'd have to
-add a conflict function to the MachineRegisters class, and we'd have to
-put a PrimRep in the MappedReg datatype, or use some kludge (e.g. register
-64 + n is really the same as 32 + n, except that it's used for a double,
-so it also conflicts with 33 + n) to deal with it.  It's just not worth the
-bother, so we just partition the free floating point registers into two
-sets: one for single precision and one for double precision.  We never seem
-to run out of floating point registers anyway.
-
-\begin{code}
-
-data SparcRegs = SRegs BitSet BitSet BitSet
-
-instance MachineRegisters SparcRegs where
-    mkMRegs xs = SRegs (mkBS ints) (mkBS singles') (mkBS doubles')
-      where
-       (ints, floats) = partition (< 32) xs
-       (singles, doubles) = partition (< 48) floats
-       singles' = map (subtract 32) singles
-       doubles' = map (subtract 32) (filter even doubles)
-
-    possibleMRegs FloatRep (SRegs _ singles _) = [ x + 32 | x <- listBS singles]
-    possibleMRegs DoubleRep (SRegs _ _ doubles) = [ x + 32 | x <- listBS doubles]
-    possibleMRegs _ (SRegs ints _ _) = listBS ints
-
-    useMReg (SRegs ints singles doubles) n =
-       if n _LT_ ILIT(32) then SRegs (ints `minusBS` singletonBS IBOX(n)) singles doubles
-       else if n _LT_ ILIT(48) then SRegs ints (singles `minusBS` singletonBS (IBOX(n _SUB_ ILIT(32)))) doubles
-       else SRegs ints singles (doubles `minusBS` singletonBS (IBOX(n _SUB_ ILIT(32))))
-
-    useMRegs (SRegs ints singles doubles) xs =
-       SRegs (ints `minusBS` ints')
-             (singles `minusBS` singles')
-             (doubles `minusBS` doubles')
-      where
-       SRegs ints' singles' doubles' = mkMRegs xs
-
-    freeMReg (SRegs ints singles doubles) n =
-       if n _LT_ ILIT(32) then SRegs (ints `unionBS` singletonBS IBOX(n)) singles doubles
-       else if n _LT_ ILIT(48) then SRegs ints (singles `unionBS` singletonBS (IBOX(n _SUB_ ILIT(32)))) doubles
-       else SRegs ints singles (doubles `unionBS` singletonBS (IBOX(n _SUB_ ILIT(32))))
-
-    freeMRegs (SRegs ints singles doubles) xs =
-       SRegs (ints `unionBS` ints')
-             (singles `unionBS` singles')
-             (doubles `unionBS` doubles')
-      where
-       SRegs ints' singles' doubles' = mkMRegs xs
-
-instance MachineCode SparcInstr where
-    regUsage = sparcRegUsage
-    regLiveness = sparcRegLiveness
-    patchRegs = sparcPatchRegs
-
-    -- We spill just below the frame pointer, leaving two words per spill location.
-    spillReg dyn (MemoryReg i pk) = mkUnitList (ST (kindToSize pk) dyn (fpRel (-2 * i)))
-    loadReg (MemoryReg i pk) dyn = mkUnitList (LD (kindToSize pk) (fpRel (-2 * i)) dyn)
-
--- Duznae work for offsets greater than 13 bits; we just hope for the best
-fpRel :: Int -> Addr
-fpRel n = AddrRegImm fp (ImmInt (n * 4))
-
-kindToSize :: PrimRep -> Size
-kindToSize PtrRep          = W
-kindToSize CodePtrRep      = W
-kindToSize DataPtrRep      = W
-kindToSize RetRep          = W
-kindToSize CostCentreRep   = W
-kindToSize CharRep         = UB
-kindToSize IntRep          = W
-kindToSize WordRep         = W
-kindToSize AddrRep         = W
-kindToSize FloatRep        = F
-kindToSize DoubleRep       = DF
-kindToSize ArrayRep        = W
-kindToSize ByteArrayRep    = W
-kindToSize StablePtrRep    = W
-kindToSize MallocPtrRep    = W
-
-\end{code}
-
-@sparcRegUsage@ returns the sets of src and destination registers used by
-a particular instruction.  Machine registers that are pre-allocated
-to stgRegs are filtered out, because they are uninteresting from a
-register allocation standpoint.  (We wouldn't want them to end up on
-the free list!)
-
-\begin{code}
-
-sparcRegUsage :: SparcInstr -> RegUsage
-sparcRegUsage instr = case instr of
-    LD sz addr reg     -> usage (regAddr addr, [reg])
-    ST sz reg addr     -> usage (reg : regAddr addr, [])
-    ADD x cc r1 ar r2  -> usage (r1 : regRI ar, [r2])
-    SUB x cc r1 ar r2  -> usage (r1 : regRI ar, [r2])
-    AND b r1 ar r2     -> usage (r1 : regRI ar, [r2])
-    ANDN b r1 ar r2    -> usage (r1 : regRI ar, [r2])
-    OR b r1 ar r2      -> usage (r1 : regRI ar, [r2])
-    ORN b r1 ar r2     -> usage (r1 : regRI ar, [r2])
-    XOR b r1 ar r2     -> usage (r1 : regRI ar, [r2])
-    XNOR b r1 ar r2    -> usage (r1 : regRI ar, [r2])
-    SLL r1 ar r2       -> usage (r1 : regRI ar, [r2])
-    SRL r1 ar r2       -> usage (r1 : regRI ar, [r2])
-    SRA r1 ar r2       -> usage (r1 : regRI ar, [r2])
-    SETHI imm reg      -> usage ([], [reg])
-    FABS s r1 r2       -> usage ([r1], [r2])
-    FADD s r1 r2 r3    -> usage ([r1, r2], [r3])
-    FCMP e s r1 r2     -> usage ([r1, r2], [])
-    FDIV s r1 r2 r3    -> usage ([r1, r2], [r3])
-    FMOV s r1 r2       -> usage ([r1], [r2])
-    FMUL s r1 r2 r3    -> usage ([r1, r2], [r3])
-    FNEG s r1 r2       -> usage ([r1], [r2])
-    FSQRT s r1 r2      -> usage ([r1], [r2])
-    FSUB s r1 r2 r3    -> usage ([r1, r2], [r3])
-    FxTOy s1 s2 r1 r2  -> usage ([r1], [r2])
-
-    -- We assume that all local jumps will be BI/BF.  JMP must be out-of-line.
-    JMP addr           -> RU (mkUniqSet (filter interesting (regAddr addr))) freeSet
-
-    CALL _ n True      -> endUsage
-    CALL _ n False     -> RU (argSet n) callClobberedSet
-
-    _                  -> noUsage
-
-  where
-    usage (src, dst) = RU (mkUniqSet (filter interesting src))
-                         (mkUniqSet (filter interesting dst))
-
-    interesting (FixedReg _) = False
-    interesting _ = True
-
-    regAddr (AddrRegReg r1 r2) = [r1, r2]
-    regAddr (AddrRegImm r1 _)  = [r1]
-
-    regRI (RIReg r) = [r]
-    regRI  _   = []
-
-freeRegs :: [Reg]
-freeRegs = freeMappedRegs (\ x -> x) [0..63]
-
-freeMappedRegs :: (Int -> Int) -> [Int] -> [Reg]
-
-freeMappedRegs modify nums
-  = foldr free [] nums
-  where
-    free n acc
-      = let
-           modified_i = case (modify n) of { IBOX(x) -> x }
-       in
-       if _IS_TRUE_(freeReg modified_i) then (MappedReg modified_i) : acc else acc
-
-freeSet :: UniqSet Reg
-freeSet = mkUniqSet freeRegs
-
-noUsage :: RegUsage
-noUsage = RU emptyUniqSet emptyUniqSet
-
-endUsage :: RegUsage
-endUsage = RU emptyUniqSet freeSet
-
--- Color me CAF-like
-argSet :: Int -> UniqSet Reg
-argSet 0 = emptyUniqSet
-argSet 1 = mkUniqSet (freeMappedRegs oReg [0])
-argSet 2 = mkUniqSet (freeMappedRegs oReg [0,1])
-argSet 3 = mkUniqSet (freeMappedRegs oReg [0,1,2])
-argSet 4 = mkUniqSet (freeMappedRegs oReg [0,1,2,3])
-argSet 5 = mkUniqSet (freeMappedRegs oReg [0,1,2,3,4])
-argSet 6 = mkUniqSet (freeMappedRegs oReg [0,1,2,3,4,5])
-
-callClobberedSet :: UniqSet Reg
-callClobberedSet = mkUniqSet callClobberedRegs
-  where
-    callClobberedRegs = freeMappedRegs (\x -> x)
-      ( oReg 7 :
-       [oReg i | i <- [0..5]] ++
-       [gReg i | i <- [1..7]] ++
-       [fReg i | i <- [0..31]] )
-
-\end{code}
-
-@sparcRegLiveness@ takes future liveness information and modifies it according to
-the semantics of branches and labels.  (An out-of-line branch clobbers the liveness
-passed back by the following instruction; a forward local branch passes back the
-liveness from the target label; a conditional branch merges the liveness from the
-target and the liveness from its successor; a label stashes away the current liveness
-in the future liveness environment).
-
-\begin{code}
-sparcRegLiveness :: SparcInstr -> RegLiveness -> RegLiveness
-sparcRegLiveness instr info@(RL live future@(FL all env)) = case instr of
-
-    -- We assume that all local jumps will be BI/BF.  JMP must be out-of-line.
-
-    BI ALWAYS _ (ImmCLbl lbl)  -> RL (lookup lbl) future
-    BI _ _ (ImmCLbl lbl)       -> RL (lookup lbl `unionUniqSets` live) future
-    BF ALWAYS _ (ImmCLbl lbl)  -> RL (lookup lbl) future
-    BF _ _ (ImmCLbl lbl)       -> RL (lookup lbl `unionUniqSets` live) future
-    JMP _                      -> RL emptyUniqSet future
-    CALL _ i True   -> RL emptyUniqSet future
-    CALL _ i False  -> RL live future
-    LABEL lbl      -> RL live (FL (all `unionUniqSets` live) (addToFM env lbl live))
-    _              -> info
-
-  where
-    lookup lbl = case lookupFM env lbl of
-       Just regs -> regs
-       Nothing -> trace ("Missing " ++ (uppShow 80 (pprCLabel (PprForAsm (\_->False) False id) lbl)) ++
-                         " in future?") emptyUniqSet
-
-\end{code}
-
-@sparcPatchRegs@ takes an instruction (possibly with MemoryReg/UnmappedReg registers) and
-changes all register references according to the supplied environment.
-
-\begin{code}
-
-sparcPatchRegs :: SparcInstr -> (Reg -> Reg) -> SparcInstr
-sparcPatchRegs instr env = case instr of
-    LD sz addr reg -> LD sz (fixAddr addr) (env reg)
-    ST sz reg addr -> ST sz (env reg) (fixAddr addr)
-    ADD x cc r1 ar r2 -> ADD x cc (env r1) (fixRI ar) (env r2)
-    SUB x cc r1 ar r2 -> SUB x cc (env r1) (fixRI ar) (env r2)
-    AND b r1 ar r2 -> AND b (env r1) (fixRI ar) (env r2)
-    ANDN b r1 ar r2 -> ANDN b (env r1) (fixRI ar) (env r2)
-    OR b r1 ar r2 -> OR b (env r1) (fixRI ar) (env r2)
-    ORN b r1 ar r2 -> ORN b (env r1) (fixRI ar) (env r2)
-    XOR b r1 ar r2 -> XOR b (env r1) (fixRI ar) (env r2)
-    XNOR b r1 ar r2 -> XNOR b (env r1) (fixRI ar) (env r2)
-    SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
-    SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
-    SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
-    SETHI imm reg -> SETHI imm (env reg)
-    FABS s r1 r2 -> FABS s (env r1) (env r2)
-    FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
-    FCMP e s r1 r2 -> FCMP e s (env r1) (env r2)
-    FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
-    FMOV s r1 r2 -> FMOV s (env r1) (env r2)
-    FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
-    FNEG s r1 r2 -> FNEG s (env r1) (env r2)
-    FSQRT s r1 r2 -> FSQRT s (env r1) (env r2)
-    FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
-    FxTOy s1 s2 r1 r2 -> FxTOy s1 s2 (env r1) (env r2)
-    JMP addr -> JMP (fixAddr addr)
-    _ -> instr
-
-  where
-    fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
-    fixAddr (AddrRegImm r1 i)  = AddrRegImm (env r1) i
-
-    fixRI (RIReg r) = RIReg (env r)
-    fixRI other        = other
-\end{code}
-
-Sometimes, we want to be able to modify addresses at compile time.
-(Okay, just for chrCode of a fetch.)
-
-\begin{code}
-{-# SPECIALIZE
-    is13Bits :: Int -> Bool
-  #-}
-{-# SPECIALIZE
-    is13Bits :: Integer -> Bool
-  #-}
-
-is13Bits :: Integral a => a -> Bool
-is13Bits x = x >= -4096 && x < 4096
-
-offset :: Addr -> Int -> Maybe Addr
-
-offset (AddrRegImm reg (ImmInt n)) off
-  | is13Bits n2 = Just (AddrRegImm reg (ImmInt n2))
-  | otherwise = Nothing
-  where n2 = n + off
-
-offset (AddrRegImm reg (ImmInteger n)) off
-  | is13Bits n2 = Just (AddrRegImm reg (ImmInt (fromInteger n2)))
-  | otherwise = Nothing
-  where n2 = n + toInteger off
-
-offset (AddrRegReg reg (FixedReg ILIT(0))) off
-  | is13Bits off = Just (AddrRegImm reg (ImmInt off))
-  | otherwise = Nothing
-
-offset _ _ = Nothing
-
-\end{code}
-
-If you value your sanity, do not venture below this line.
-
-\begin{code}
-
--- platform.h is generate and tells us what the target architecture is
-#include "../../includes/platform.h"
-#include "../../includes/MachRegs.h"
-#if sunos4_TARGET_OS
-#include "../../includes/sparc-sun-sunos4.h"
-#else
-#include "../../includes/sparc-sun-solaris2.h"
-#endif
-
--- Redefine the literals used for Sparc register names in the header
--- files.  Gag me with a spoon, eh?
-
-#define g0 0
-#define g1 1
-#define g2 2
-#define g3 3
-#define g4 4
-#define g5 5
-#define g6 6
-#define g7 7
-#define o0 8
-#define o1 9
-#define o2 10
-#define o3 11
-#define o4 12
-#define o5 13
-#define o6 14
-#define o7 15
-#define l0 16
-#define l1 17
-#define l2 18
-#define l3 19
-#define l4 20
-#define l5 21
-#define l6 22
-#define l7 23
-#define i0 24
-#define i1 25
-#define i2 26
-#define i3 27
-#define i4 28
-#define i5 29
-#define i6 30
-#define i7 31
-#define f0 32
-#define f1 33
-#define f2 34
-#define f3 35
-#define f4 36
-#define f5 37
-#define f6 38
-#define f7 39
-#define f8 40
-#define f9 41
-#define f10 42
-#define f11 43
-#define f12 44
-#define f13 45
-#define f14 46
-#define f15 47
-#define f16 48
-#define f17 49
-#define f18 50
-#define f19 51
-#define f20 52
-#define f21 53
-#define f22 54
-#define f23 55
-#define f24 56
-#define f25 57
-#define f26 58
-#define f27 59
-#define f28 60
-#define f29 61
-#define f30 62
-#define f31 63
-
-baseRegOffset :: MagicId -> Int
-baseRegOffset StkOReg                  = OFFSET_StkO
-baseRegOffset (VanillaReg _ ILIT2(1))  = OFFSET_R1
-baseRegOffset (VanillaReg _ ILIT2(2))  = OFFSET_R2
-baseRegOffset (VanillaReg _ ILIT2(3))  = OFFSET_R3
-baseRegOffset (VanillaReg _ ILIT2(4))  = OFFSET_R4
-baseRegOffset (VanillaReg _ ILIT2(5))  = OFFSET_R5
-baseRegOffset (VanillaReg _ ILIT2(6))  = OFFSET_R6
-baseRegOffset (VanillaReg _ ILIT2(7))  = OFFSET_R7
-baseRegOffset (VanillaReg _ ILIT2(8))  = OFFSET_R8
-baseRegOffset (FloatReg ILIT2(1))      = OFFSET_Flt1
-baseRegOffset (FloatReg ILIT2(2))      = OFFSET_Flt2
-baseRegOffset (FloatReg ILIT2(3))      = OFFSET_Flt3
-baseRegOffset (FloatReg ILIT2(4))      = OFFSET_Flt4
-baseRegOffset (DoubleReg ILIT2(1))     = OFFSET_Dbl1
-baseRegOffset (DoubleReg ILIT2(2))     = OFFSET_Dbl2
-baseRegOffset TagReg                   = OFFSET_Tag
-baseRegOffset RetReg                   = OFFSET_Ret
-baseRegOffset SpA                      = OFFSET_SpA
-baseRegOffset SuA                      = OFFSET_SuA
-baseRegOffset SpB                      = OFFSET_SpB
-baseRegOffset SuB                      = OFFSET_SuB
-baseRegOffset Hp                       = OFFSET_Hp
-baseRegOffset HpLim                    = OFFSET_HpLim
-baseRegOffset LivenessReg              = OFFSET_Liveness
---baseRegOffset ActivityReg            = OFFSET_Activity
-#ifdef DEBUG
-baseRegOffset BaseReg                  = panic "baseRegOffset:BaseReg"
-baseRegOffset StdUpdRetVecReg          = panic "baseRegOffset:StgUpdRetVecReg"
-baseRegOffset StkStubReg               = panic "baseRegOffset:StkStubReg"
-baseRegOffset CurCostCentre            = panic "baseRegOffset:CurCostCentre"
-baseRegOffset VoidReg                  = panic "baseRegOffset:VoidReg"
-#endif
-
-callerSaves :: MagicId -> Bool
-#ifdef CALLER_SAVES_Base
-callerSaves BaseReg                    = True
-#endif
-#ifdef CALLER_SAVES_StkO
-callerSaves StkOReg            = True
-#endif
-#ifdef CALLER_SAVES_R1
-callerSaves (VanillaReg _ ILIT2(1))    = True
-#endif
-#ifdef CALLER_SAVES_R2
-callerSaves (VanillaReg _ ILIT2(2))    = True
-#endif
-#ifdef CALLER_SAVES_R3
-callerSaves (VanillaReg _ ILIT2(3))    = True
-#endif
-#ifdef CALLER_SAVES_R4
-callerSaves (VanillaReg _ ILIT2(4))    = True
-#endif
-#ifdef CALLER_SAVES_R5
-callerSaves (VanillaReg _ ILIT2(5))    = True
-#endif
-#ifdef CALLER_SAVES_R6
-callerSaves (VanillaReg _ ILIT2(6))    = True
-#endif
-#ifdef CALLER_SAVES_R7
-callerSaves (VanillaReg _ ILIT2(7))    = True
-#endif
-#ifdef CALLER_SAVES_R8
-callerSaves (VanillaReg _ ILIT2(8))    = True
-#endif
-#ifdef CALLER_SAVES_FltReg1
-callerSaves (FloatReg ILIT2(1))        = True
-#endif
-#ifdef CALLER_SAVES_FltReg2
-callerSaves (FloatReg ILIT2(2))        = True
-#endif
-#ifdef CALLER_SAVES_FltReg3
-callerSaves (FloatReg ILIT2(3))        = True
-#endif
-#ifdef CALLER_SAVES_FltReg4
-callerSaves (FloatReg ILIT2(4))        = True
-#endif
-#ifdef CALLER_SAVES_DblReg1
-callerSaves (DoubleReg ILIT2(1))       = True
-#endif
-#ifdef CALLER_SAVES_DblReg2
-callerSaves (DoubleReg ILIT2(2))       = True
-#endif
-#ifdef CALLER_SAVES_Tag
-callerSaves TagReg             = True
-#endif
-#ifdef CALLER_SAVES_Ret
-callerSaves RetReg             = True
-#endif
-#ifdef CALLER_SAVES_SpA
-callerSaves SpA                        = True
-#endif
-#ifdef CALLER_SAVES_SuA
-callerSaves SuA                        = True
-#endif
-#ifdef CALLER_SAVES_SpB
-callerSaves SpB                        = True
-#endif
-#ifdef CALLER_SAVES_SuB
-callerSaves SuB                        = True
-#endif
-#ifdef CALLER_SAVES_Hp
-callerSaves Hp                 = True
-#endif
-#ifdef CALLER_SAVES_HpLim
-callerSaves HpLim              = True
-#endif
-#ifdef CALLER_SAVES_Liveness
-callerSaves LivenessReg                = True
-#endif
-#ifdef CALLER_SAVES_Activity
---callerSaves ActivityReg              = True
-#endif
-#ifdef CALLER_SAVES_StdUpdRetVec
-callerSaves StdUpdRetVecReg            = True
-#endif
-#ifdef CALLER_SAVES_StkStub
-callerSaves StkStubReg                 = True
-#endif
-callerSaves _                  = False
-
-stgRegMap :: MagicId -> Maybe Reg
-#ifdef REG_Base
-stgRegMap BaseReg         = Just (FixedReg ILIT(REG_Base))
-#endif
-#ifdef REG_StkO
-stgRegMap StkOReg         = Just (FixedReg ILIT(REG_StkOReg))
-#endif
-#ifdef REG_R1
-stgRegMap (VanillaReg _ ILIT2(1)) = Just (FixedReg ILIT(REG_R1))
-#endif
-#ifdef REG_R2
-stgRegMap (VanillaReg _ ILIT2(2)) = Just (FixedReg ILIT(REG_R2))
-#endif
-#ifdef REG_R3
-stgRegMap (VanillaReg _ ILIT2(3)) = Just (FixedReg ILIT(REG_R3))
-#endif
-#ifdef REG_R4
-stgRegMap (VanillaReg _ ILIT2(4)) = Just (FixedReg ILIT(REG_R4))
-#endif
-#ifdef REG_R5
-stgRegMap (VanillaReg _ ILIT2(5)) = Just (FixedReg ILIT(REG_R5))
-#endif
-#ifdef REG_R6
-stgRegMap (VanillaReg _ ILIT2(6)) = Just (FixedReg ILIT(REG_R6))
-#endif
-#ifdef REG_R7
-stgRegMap (VanillaReg _ ILIT2(7)) = Just (FixedReg ILIT(REG_R7))
-#endif
-#ifdef REG_R8
-stgRegMap (VanillaReg _ ILIT2(8)) = Just (FixedReg ILIT(REG_R8))
-#endif
-#ifdef REG_Flt1
-stgRegMap (FloatReg ILIT2(1))     = Just (FixedReg ILIT(REG_Flt1))
-#endif
-#ifdef REG_Flt2
-stgRegMap (FloatReg ILIT2(2))     = Just (FixedReg ILIT(REG_Flt2))
-#endif
-#ifdef REG_Flt3
-stgRegMap (FloatReg ILIT2(3))     = Just (FixedReg ILIT(REG_Flt3))
-#endif
-#ifdef REG_Flt4
-stgRegMap (FloatReg ILIT2(4))     = Just (FixedReg ILIT(REG_Flt4))
-#endif
-#ifdef REG_Dbl1
-stgRegMap (DoubleReg ILIT2(1))    = Just (FixedReg ILIT(REG_Dbl1))
-#endif
-#ifdef REG_Dbl2
-stgRegMap (DoubleReg ILIT2(2))    = Just (FixedReg ILIT(REG_Dbl2))
-#endif
-#ifdef REG_Tag
-stgRegMap TagReg          = Just (FixedReg ILIT(REG_TagReg))
-#endif
-#ifdef REG_Ret
-stgRegMap RetReg          = Just (FixedReg ILIT(REG_Ret))
-#endif
-#ifdef REG_SpA
-stgRegMap SpA             = Just (FixedReg ILIT(REG_SpA))
-#endif
-#ifdef REG_SuA
-stgRegMap SuA             = Just (FixedReg ILIT(REG_SuA))
-#endif
-#ifdef REG_SpB
-stgRegMap SpB             = Just (FixedReg ILIT(REG_SpB))
-#endif
-#ifdef REG_SuB
-stgRegMap SuB             = Just (FixedReg ILIT(REG_SuB))
-#endif
-#ifdef REG_Hp
-stgRegMap Hp              = Just (FixedReg ILIT(REG_Hp))
-#endif
-#ifdef REG_HpLim
-stgRegMap HpLim                   = Just (FixedReg ILIT(REG_HpLim))
-#endif
-#ifdef REG_Liveness
-stgRegMap LivenessReg     = Just (FixedReg ILIT(REG_Liveness))
-#endif
-#ifdef REG_Activity
---stgRegMap ActivityReg           = Just (FixedReg ILIT(REG_Activity))
-#endif
-#ifdef REG_StdUpdRetVec
-stgRegMap StdUpdRetVecReg  = Just (FixedReg ILIT(REG_StdUpdRetVec))
-#endif
-#ifdef REG_StkStub
-stgRegMap StkStubReg      = Just (FixedReg ILIT(REG_StkStub))
-#endif
-stgRegMap _               = Nothing
-
-\end{code}
-
-Here is the list of registers we can use in register allocation.
-
-\begin{code}
-
-freeReg :: FAST_INT -> FAST_BOOL
-
-freeReg ILIT(g0) = _FALSE_  -- %g0 is always 0.
-freeReg ILIT(g5) = _FALSE_  -- %g5 is reserved (ABI).
-freeReg ILIT(g6) = _FALSE_  -- %g6 is reserved (ABI).
-freeReg ILIT(g7) = _FALSE_  -- %g7 is reserved (ABI).
-freeReg ILIT(i6) = _FALSE_  -- %i6 is our frame pointer.
-freeReg ILIT(o6) = _FALSE_  -- %o6 is our stack pointer.
-
-#ifdef REG_Base
-freeReg ILIT(REG_Base) = _FALSE_
-#endif
-#ifdef REG_StkO
-freeReg ILIT(REG_StkO) = _FALSE_
-#endif
-#ifdef REG_R1
-freeReg ILIT(REG_R1) = _FALSE_
-#endif
-#ifdef REG_R2
-freeReg ILIT(REG_R2) = _FALSE_
-#endif
-#ifdef REG_R3
-freeReg ILIT(REG_R3) = _FALSE_
-#endif
-#ifdef REG_R4
-freeReg ILIT(REG_R4) = _FALSE_
-#endif
-#ifdef REG_R5
-freeReg ILIT(REG_R5) = _FALSE_
-#endif
-#ifdef REG_R6
-freeReg ILIT(REG_R6) = _FALSE_
-#endif
-#ifdef REG_R7
-freeReg ILIT(REG_R7) = _FALSE_
-#endif
-#ifdef REG_R8
-freeReg ILIT(REG_R8) = _FALSE_
-#endif
-#ifdef REG_Flt1
-freeReg ILIT(REG_Flt1) = _FALSE_
-#endif
-#ifdef REG_Flt2
-freeReg ILIT(REG_Flt2) = _FALSE_
-#endif
-#ifdef REG_Flt3
-freeReg ILIT(REG_Flt3) = _FALSE_
-#endif
-#ifdef REG_Flt4
-freeReg ILIT(REG_Flt4) = _FALSE_
-#endif
-#ifdef REG_Dbl1
-freeReg ILIT(REG_Dbl1) = _FALSE_
-#endif
-#ifdef REG_Dbl2
-freeReg ILIT(REG_Dbl2) = _FALSE_
-#endif
-#ifdef REG_Tag
-freeReg ILIT(REG_Tag) = _FALSE_
-#endif
-#ifdef REG_Ret
-freeReg ILIT(REG_Ret) = _FALSE_
-#endif
-#ifdef REG_SpA
-freeReg ILIT(REG_SpA) = _FALSE_
-#endif
-#ifdef REG_SuA
-freeReg ILIT(REG_SuA) = _FALSE_
-#endif
-#ifdef REG_SpB
-freeReg ILIT(REG_SpB) = _FALSE_
-#endif
-#ifdef REG_SuB
-freeReg ILIT(REG_SuB) = _FALSE_
-#endif
-#ifdef REG_Hp
-freeReg ILIT(REG_Hp) = _FALSE_
-#endif
-#ifdef REG_HpLim
-freeReg ILIT(REG_HpLim) = _FALSE_
-#endif
-#ifdef REG_Liveness
-freeReg ILIT(REG_Liveness) = _FALSE_
-#endif
-#ifdef REG_Activity
---freeReg ILIT(REG_Activity) = _FALSE_
-#endif
-#ifdef REG_StdUpdRetVec
-freeReg ILIT(REG_StdUpdRetVec) = _FALSE_
-#endif
-#ifdef REG_StkStub
-freeReg ILIT(REG_StkStub) = _FALSE_
-#endif
-freeReg n
-#ifdef REG_Dbl1
-  | n _EQ_ (ILIT(REG_Dbl1) _ADD_ ILIT(1)) = _FALSE_
-#endif
-#ifdef REG_Dbl2
-  | n _EQ_ (ILIT(REG_Dbl2) _ADD_ ILIT(1)) = _FALSE_
-#endif
-  | otherwise = _TRUE_
-
-reservedRegs :: [Int]
-reservedRegs = [NCG_Reserved_I1, NCG_Reserved_I2,
-               NCG_Reserved_F1, NCG_Reserved_F2,
-               NCG_Reserved_D1, NCG_Reserved_D2]
-
-\end{code}
-
diff --git a/ghc/compiler/nativeGen/SparcDesc.lhs b/ghc/compiler/nativeGen/SparcDesc.lhs
deleted file mode 100644 (file)
index 8445399..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1994-1995
-%
-\section[SparcDesc]{The Sparc Machine Description}
-
-\begin{code}
-#include "HsVersions.h"
-
-module SparcDesc (
-       mkSparc
-
-       -- and assorted nonsense referenced by the class methods
-    ) where
-
-import AbsCSyn
-import PrelInfo            ( PrimOp(..)
-                     IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                   )
-import AsmRegAlloc  ( Reg, MachineCode(..), MachineRegisters(..),
-                     RegLiveness(..), RegUsage(..), FutureLive(..)
-                   )
-import CLabel   ( CLabel )
-import CmdLineOpts  ( GlobalSwitch(..), stringSwitchSet, switchIsOn, SwitchResult(..) )
-import HeapOffs            ( hpRelToInt )
-import MachDesc
-import Maybes      ( Maybe(..) )
-import OrdList
-import Outputable
-import SMRep       ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
-import SparcCode
-import SparcGen            ( sparcCodeGen )
-import Stix
-import StixMacro
-import StixPrim
-import UniqSupply
-import Util
-\end{code}
-
-Header sizes depend only on command-line options, not on the target
-architecture.  (I think.)
-
-\begin{code}
-
-fhs :: (GlobalSwitch -> SwitchResult) -> Int
-
-fhs switches = 1 + profFHS + ageFHS
-  where
-    profFHS = if switchIsOn switches SccProfilingOn then 1 else 0
-    ageFHS  = if switchIsOn switches SccProfilingOn then 1 else 0
-
-vhs :: (GlobalSwitch -> SwitchResult) -> SMRep -> Int
-
-vhs switches sm = case sm of
-    StaticRep _ _         -> 0
-    SpecialisedRep _ _ _ _ -> 0
-    GenericRep _ _ _      -> 0
-    BigTupleRep _         -> 1
-    MuTupleRep _          -> 2 {- (1 + GC_MUT_RESERVED_WORDS) -}
-    DataRep _             -> 1
-    DynamicRep            -> 2
-    BlackHoleRep          -> 0
-    PhantomRep            -> panic "vhs:phantom"
-
-\end{code}
-
-Here we map STG registers onto appropriate Stix Trees.  First, we
-handle the two constants, @STK_STUB_closure@ and @vtbl_StdUpdFrame@.
-The rest are either in real machine registers or stored as offsets
-from BaseReg.
-
-\begin{code}
-
-sparcReg :: (GlobalSwitch -> SwitchResult) -> MagicId -> RegLoc
-
-sparcReg switches x =
-    case stgRegMap x of
-       Just reg -> Save nonReg
-       Nothing -> Always nonReg
-    where nonReg = case x of
-           StkStubReg -> sStLitLbl SLIT("STK_STUB_closure")
-           StdUpdRetVecReg -> sStLitLbl SLIT("vtbl_StdUpdFrame")
-           BaseReg -> sStLitLbl SLIT("MainRegTable")
-           Hp -> StInd PtrRep (sStLitLbl SLIT("StorageMgrInfo"))
-           HpLim -> StInd PtrRep (sStLitLbl SLIT("StorageMgrInfo+4"))
-           TagReg -> StInd IntRep (StPrim IntSubOp [infoptr, StInt (1*4)])
-                     where
-                         r2 = VanillaReg PtrRep ILIT(2)
-                         infoptr = case sparcReg switches r2 of
-                                       Always tree -> tree
-                                       Save _ -> StReg (StixMagicId r2)
-           _ -> StInd (kindFromMagicId x)
-                      (StPrim IntAddOp [baseLoc, StInt (toInteger (offset*4))])
-         baseLoc = case stgRegMap BaseReg of
-           Just _ -> StReg (StixMagicId BaseReg)
-           Nothing -> sStLitLbl SLIT("MainRegTable")
-         offset = baseRegOffset x
-
-\end{code}
-
-Sizes in bytes.
-
-\begin{code}
-
-size pk = case kindToSize pk of
-    {SB -> 1; UB -> 1; HW -> 2; UHW -> 2; W -> 4; D -> 8; F -> 4; DF -> 8}
-
-\end{code}
-
-Now the volatile saves and restores.  We add the basic guys to the list of ``user''
-registers provided.  Note that there are more basic registers on the restore list,
-because some are reloaded from constants.
-
-\begin{code}
-
-vsaves switches vols =
-    map save ((filter callerSaves) ([BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg{-,ActivityReg-}] ++ vols))
-    where
-       save x = StAssign (kindFromMagicId x) loc reg
-                   where reg = StReg (StixMagicId x)
-                         loc = case sparcReg switches x of
-                                   Save loc -> loc
-                                   Always loc -> panic "vsaves"
-
-vrests switches vols =
-    map restore ((filter callerSaves)
-       ([BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg{-,ActivityReg-},StkStubReg,StdUpdRetVecReg] ++ vols))
-    where
-       restore x = StAssign (kindFromMagicId x) reg loc
-                   where reg = StReg (StixMagicId x)
-                         loc = case sparcReg switches x of
-                                   Save loc -> loc
-                                   Always loc -> panic "vrests"
-
-\end{code}
-
-Static closure sizes.
-
-\begin{code}
-
-charLikeSize, intLikeSize :: Target -> Int
-
-charLikeSize target =
-    size PtrRep * (fixedHeaderSize target + varHeaderSize target charLikeRep + 1)
-    where charLikeRep = SpecialisedRep CharLikeRep 0 1 SMNormalForm
-
-intLikeSize target =
-    size PtrRep * (fixedHeaderSize target + varHeaderSize target intLikeRep + 1)
-    where intLikeRep = SpecialisedRep IntLikeRep 0 1 SMNormalForm
-
-mhs, dhs :: (GlobalSwitch -> SwitchResult) -> StixTree
-
-mhs switches = StInt (toInteger words)
-  where
-    words = fhs switches + vhs switches (MuTupleRep 0)
-
-dhs switches = StInt (toInteger words)
-  where
-    words = fhs switches + vhs switches (DataRep 0)
-
-\end{code}
-
-Setting up a sparc target.
-
-\begin{code}
-
-mkSparc :: Bool
-       -> (GlobalSwitch -> SwitchResult)
-       -> (Target,
-           (PprStyle -> [[StixTree]] -> UniqSM Unpretty), -- codeGen
-           Bool,                                           -- underscore
-           (String -> String))                             -- fmtAsmLbl
-
-mkSparc decentOS switches =
-    let
-       fhs' = fhs switches
-       vhs' = vhs switches
-       sparcReg' = sparcReg switches
-       vsaves' = vsaves switches
-       vrests' = vrests switches
-       hprel = hpRelToInt target
-       as = amodeCode target
-       as' = amodeCode' target
-       csz = charLikeSize target
-       isz = intLikeSize target
-       mhs' = mhs switches
-       dhs' = dhs switches
-       ps = genPrimCode target
-       mc = genMacroCode target
-       hc = doHeapCheck
-       target = mkTarget {-switches-} fhs' vhs' sparcReg' {-id-} size
-                         hprel as as'
-                         (vsaves', vrests', csz, isz, mhs', dhs', ps, mc, hc)
-                         {-sparcCodeGen decentOS id-}
-    in
-    (target, sparcCodeGen, decentOS, id)
-\end{code}
diff --git a/ghc/compiler/nativeGen/SparcGen.lhs b/ghc/compiler/nativeGen/SparcGen.lhs
deleted file mode 100644 (file)
index f5046d7..0000000
+++ /dev/null
@@ -1,1289 +0,0 @@
-%
-% (c) The AQUA Project, Glasgow University, 1993-1995
-%
-
-\begin{code}
-#include "HsVersions.h"
-
-module SparcGen (
-       sparcCodeGen,
-
-       -- and, for self-sufficiency
-       PprStyle, StixTree, CSeq
-    ) where
-
-IMPORT_Trace
-
-import AbsCSyn     ( AbstractC, MagicId(..), kindFromMagicId )
-import PrelInfo            ( PrimOp(..)
-                     IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                   )
-import AsmRegAlloc  ( runRegAllocate, mkReg, extractMappedRegNos,
-                     Reg(..), RegLiveness(..), RegUsage(..),
-                     FutureLive(..), MachineRegisters(..), MachineCode(..)
-                   )
-import CLabel   ( CLabel, isAsmTemp )
-import SparcCode    {- everything -}
-import MachDesc
-import Maybes      ( maybeToBool, Maybe(..) )
-import OrdList     -- ( mkEmptyList, mkUnitList, mkSeqList, mkParList, OrdList )
-import Outputable
-import SparcDesc
-import Stix
-import UniqSupply
-import Pretty
-import Unpretty
-import Util
-
-type CodeBlock a = (OrdList a -> OrdList a)
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[SparcCodeGen]{Generating Sparc Code}
-%*                                                                     *
-%************************************************************************
-
-This is the top-level code-generation function for the Sparc.
-
-\begin{code}
-
-sparcCodeGen :: PprStyle -> [[StixTree]] -> UniqSM Unpretty
-sparcCodeGen sty trees =
-    mapUs genSparcCode trees           `thenUs` \ dynamicCodes ->
-    let
-       staticCodes = scheduleSparcCode dynamicCodes
-       pretty = printLabeledCodes sty staticCodes
-    in
-       returnUs pretty
-
-\end{code}
-
-This bit does the code scheduling.  The scheduler must also deal with
-register allocation of temporaries.  Much parallelism can be exposed via
-the OrdList, but more might occur, so further analysis might be needed.
-
-\begin{code}
-
-scheduleSparcCode :: [SparcCode] -> [SparcInstr]
-scheduleSparcCode = concat . map (runRegAllocate freeSparcRegs reservedRegs)
-  where
-    freeSparcRegs :: SparcRegs
-    freeSparcRegs = mkMRegs (extractMappedRegNos freeRegs)
-
-
-\end{code}
-
-Registers passed up the tree.  If the stix code forces the register
-to live in a pre-decided machine register, it comes out as @Fixed@;
-otherwise, it comes out as @Any@, and the parent can decide which
-register to put it in.
-
-\begin{code}
-
-data Register
-  = Fixed Reg PrimRep (CodeBlock SparcInstr)
-  | Any PrimRep (Reg -> (CodeBlock SparcInstr))
-
-registerCode :: Register -> Reg -> CodeBlock SparcInstr
-registerCode (Fixed _ _ code) reg = code
-registerCode (Any _ code) reg = code reg
-
-registerName :: Register -> Reg -> Reg
-registerName (Fixed reg _ _) _ = reg
-registerName (Any _ _) reg = reg
-
-registerKind :: Register -> PrimRep
-registerKind (Fixed _ pk _) = pk
-registerKind (Any pk _) = pk
-
-isFixed :: Register -> Bool
-isFixed (Fixed _ _ _) = True
-isFixed (Any _ _)     = False
-
-\end{code}
-
-Memory addressing modes passed up the tree.
-
-\begin{code}
-
-data Amode = Amode Addr (CodeBlock SparcInstr)
-
-amodeAddr (Amode addr _) = addr
-amodeCode (Amode _ code) = code
-
-\end{code}
-
-Condition codes passed up the tree.
-
-\begin{code}
-
-data Condition = Condition Bool Cond (CodeBlock SparcInstr)
-
-condName (Condition _ cond _) = cond
-condFloat (Condition float _ _) = float
-condCode (Condition _ _ code) = code
-
-\end{code}
-
-General things for putting together code sequences.
-
-\begin{code}
-
-asmVoid :: OrdList SparcInstr
-asmVoid = mkEmptyList
-
-asmInstr :: SparcInstr -> SparcCode
-asmInstr i = mkUnitList i
-
-asmSeq :: [SparcInstr] -> SparcCode
-asmSeq is = foldr (mkSeqList . asmInstr) asmVoid is
-
-asmParThen :: [SparcCode] -> (CodeBlock SparcInstr)
-asmParThen others code = mkSeqList (foldr mkParList mkEmptyList others) code
-
-returnInstr :: SparcInstr -> UniqSM (CodeBlock SparcInstr)
-returnInstr instr = returnUs (\xs -> mkSeqList (asmInstr instr) xs)
-
-returnInstrs :: [SparcInstr] -> UniqSM (CodeBlock SparcInstr)
-returnInstrs instrs = returnUs (\xs -> mkSeqList (asmSeq instrs) xs)
-
-returnSeq :: (CodeBlock SparcInstr) -> [SparcInstr] -> UniqSM (CodeBlock SparcInstr)
-returnSeq code instrs = returnUs (\xs -> code (mkSeqList (asmSeq instrs) xs))
-
-mkSeqInstr :: SparcInstr -> (CodeBlock SparcInstr)
-mkSeqInstr instr code = mkSeqList (asmInstr instr) code
-
-mkSeqInstrs :: [SparcInstr] -> (CodeBlock SparcInstr)
-mkSeqInstrs instrs code = mkSeqList (asmSeq instrs) code
-
-\end{code}
-
-Top level sparc code generator for a chunk of stix code.
-
-\begin{code}
-
-genSparcCode :: [StixTree] -> UniqSM (SparcCode)
-
-genSparcCode trees =
-    mapUs getCode trees                `thenUs` \ blocks ->
-    returnUs (foldr (.) id blocks asmVoid)
-
-\end{code}
-
-Code extractor for an entire stix tree---stix statement level.
-
-\begin{code}
-
-getCode
-    :: StixTree     -- a stix statement
-    -> UniqSM (CodeBlock SparcInstr)
-
-getCode (StSegment seg) = returnInstr (SEGMENT seg)
-
-getCode (StAssign pk dst src)
-  | isFloatingRep pk = assignFltCode pk dst src
-  | otherwise = assignIntCode pk dst src
-
-getCode (StLabel lab) = returnInstr (LABEL lab)
-
-getCode (StFunBegin lab) = returnInstr (LABEL lab)
-
-getCode (StFunEnd lab) = returnUs id
-
-getCode (StJump arg) = genJump arg
-
-getCode (StFallThrough lbl) = returnUs id
-
-getCode (StCondJump lbl arg) = genCondJump lbl arg
-
-getCode (StData kind args) =
-    mapAndUnzipUs getData args             `thenUs` \ (codes, imms) ->
-    returnUs (\xs -> mkSeqList (asmInstr (DATA (kindToSize kind) imms))
-                               (foldr1 (.) codes xs))
-  where
-    getData :: StixTree -> UniqSM (CodeBlock SparcInstr, Imm)
-    getData (StInt i) = returnUs (id, ImmInteger i)
-    getData (StDouble d) = returnUs (id, strImmLit ('0' : 'r' : ppShow 80 (ppRational d)))
-    getData (StLitLbl s) = returnUs (id, ImmLab s)
-    getData (StLitLit s) = returnUs (id, strImmLit (cvtLitLit (_UNPK_ s)))
-    getData (StString s) =
-       getUniqLabelNCG                     `thenUs` \ lbl ->
-       returnUs (mkSeqInstrs [LABEL lbl, ASCII True (_UNPK_ s)], ImmCLbl lbl)
-    getData (StCLbl l)   = returnUs (id, ImmCLbl l)
-
-getCode (StCall fn VoidRep args) = genCCall fn VoidRep args
-
-getCode (StComment s) = returnInstr (COMMENT s)
-
-\end{code}
-
-Generate code to get a subtree into a register.
-
-\begin{code}
-
-getReg :: StixTree -> UniqSM Register
-
-getReg (StReg (StixMagicId stgreg)) =
-    case stgRegMap stgreg of
-       Just reg -> returnUs (Fixed reg (kindFromMagicId stgreg) id)
-       -- cannae be Nothing
-
-getReg (StReg (StixTemp u pk)) = returnUs (Fixed (UnmappedReg u pk) pk id)
-
-getReg (StDouble d) =
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    let code dst = mkSeqInstrs [
-           SEGMENT DataSegment,
-           LABEL lbl,
-           DATA DF [strImmLit ('0' : 'r' : ppShow  80 (ppRational d))],
-           SEGMENT TextSegment,
-           SETHI (HI (ImmCLbl lbl)) tmp,
-           LD DF (AddrRegImm tmp (LO (ImmCLbl lbl))) dst]
-    in
-       returnUs (Any DoubleRep code)
-
-getReg (StString s) =
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    let code dst = mkSeqInstrs [
-           SEGMENT DataSegment,
-           LABEL lbl,
-           ASCII True (_UNPK_ s),
-           SEGMENT TextSegment,
-           SETHI (HI (ImmCLbl lbl)) dst,
-           OR False dst (RIImm (LO (ImmCLbl lbl))) dst]
-    in
-       returnUs (Any PtrRep code)
-
-getReg (StLitLit s) | _HEAD_ s == '"' && last xs == '"' =
-    getUniqLabelNCG                `thenUs` \ lbl ->
-    let code dst = mkSeqInstrs [
-           SEGMENT DataSegment,
-           LABEL lbl,
-           ASCII False (init xs),
-           SEGMENT TextSegment,
-           SETHI (HI (ImmCLbl lbl)) dst,
-           OR False dst (RIImm (LO (ImmCLbl lbl))) dst]
-    in
-       returnUs (Any PtrRep code)
-  where
-    xs = _UNPK_ (_TAIL_ s)
-
-getReg tree@(StIndex _ _ _) = getReg (mangleIndexTree tree)
-
-getReg (StCall fn kind args) =
-    genCCall fn kind args          `thenUs` \ call ->
-    returnUs (Fixed reg kind call)
-  where
-    reg = if isFloatingRep kind then f0 else o0
-
-getReg (StPrim primop args) =
-    case primop of
-
-       CharGtOp -> condIntReg GT args
-       CharGeOp -> condIntReg GE args
-       CharEqOp -> condIntReg EQ args
-       CharNeOp -> condIntReg NE args
-       CharLtOp -> condIntReg LT args
-       CharLeOp -> condIntReg LE args
-
-       IntAddOp -> trivialCode (ADD False False) args
-
-       IntSubOp -> trivialCode (SUB False False) args
-       IntMulOp -> call SLIT(".umul") IntRep
-       IntQuotOp -> call SLIT(".div") IntRep
-       IntRemOp -> call SLIT(".rem") IntRep
-       IntNegOp -> trivialUCode (SUB False False g0) args
-       IntAbsOp -> absIntCode args
-
-       AndOp -> trivialCode (AND False) args
-       OrOp  -> trivialCode (OR False) args
-       NotOp -> trivialUCode (XNOR False g0) args
-       SllOp -> trivialCode SLL args
-       SraOp -> trivialCode SRA args
-       SrlOp -> trivialCode SRL args
-       ISllOp -> panic "SparcGen:isll"
-       ISraOp -> panic "SparcGen:isra"
-       ISrlOp -> panic "SparcGen:isrl"
-
-       IntGtOp -> condIntReg GT args
-       IntGeOp -> condIntReg GE args
-       IntEqOp -> condIntReg EQ args
-       IntNeOp -> condIntReg NE args
-       IntLtOp -> condIntReg LT args
-       IntLeOp -> condIntReg LE args
-
-       WordGtOp -> condIntReg GU args
-       WordGeOp -> condIntReg GEU args
-       WordEqOp -> condIntReg EQ args
-       WordNeOp -> condIntReg NE args
-       WordLtOp -> condIntReg LU args
-       WordLeOp -> condIntReg LEU args
-
-       AddrGtOp -> condIntReg GU args
-       AddrGeOp -> condIntReg GEU args
-       AddrEqOp -> condIntReg EQ args
-       AddrNeOp -> condIntReg NE args
-       AddrLtOp -> condIntReg LU args
-       AddrLeOp -> condIntReg LEU args
-
-       FloatAddOp -> trivialFCode FloatRep FADD args
-       FloatSubOp -> trivialFCode FloatRep FSUB args
-       FloatMulOp -> trivialFCode FloatRep FMUL args
-       FloatDivOp -> trivialFCode FloatRep FDIV args
-       FloatNegOp -> trivialUFCode FloatRep (FNEG F) args
-
-       FloatGtOp -> condFltReg GT args
-       FloatGeOp -> condFltReg GE args
-       FloatEqOp -> condFltReg EQ args
-       FloatNeOp -> condFltReg NE args
-       FloatLtOp -> condFltReg LT args
-       FloatLeOp -> condFltReg LE args
-
-       FloatExpOp -> promoteAndCall SLIT("exp") DoubleRep
-       FloatLogOp -> promoteAndCall SLIT("log") DoubleRep
-       FloatSqrtOp -> promoteAndCall SLIT("sqrt") DoubleRep
-
-       FloatSinOp -> promoteAndCall SLIT("sin") DoubleRep
-       FloatCosOp -> promoteAndCall SLIT("cos") DoubleRep
-       FloatTanOp -> promoteAndCall SLIT("tan") DoubleRep
-
-       FloatAsinOp -> promoteAndCall SLIT("asin") DoubleRep
-       FloatAcosOp -> promoteAndCall SLIT("acos") DoubleRep
-       FloatAtanOp -> promoteAndCall SLIT("atan") DoubleRep
-
-       FloatSinhOp -> promoteAndCall SLIT("sinh") DoubleRep
-       FloatCoshOp -> promoteAndCall SLIT("cosh") DoubleRep
-       FloatTanhOp -> promoteAndCall SLIT("tanh") DoubleRep
-
-       FloatPowerOp -> promoteAndCall SLIT("pow") DoubleRep
-
-       DoubleAddOp -> trivialFCode DoubleRep FADD args
-       DoubleSubOp -> trivialFCode DoubleRep FSUB args
-       DoubleMulOp -> trivialFCode DoubleRep FMUL args
-       DoubleDivOp -> trivialFCode DoubleRep FDIV args
-       DoubleNegOp -> trivialUFCode DoubleRep (FNEG DF) args
-
-       DoubleGtOp -> condFltReg GT args
-       DoubleGeOp -> condFltReg GE args
-       DoubleEqOp -> condFltReg EQ args
-       DoubleNeOp -> condFltReg NE args
-       DoubleLtOp -> condFltReg LT args
-       DoubleLeOp -> condFltReg LE args
-
-       DoubleExpOp -> call SLIT("exp") DoubleRep
-       DoubleLogOp -> call SLIT("log") DoubleRep
-       DoubleSqrtOp -> call SLIT("sqrt") DoubleRep
-
-       DoubleSinOp -> call SLIT("sin") DoubleRep
-       DoubleCosOp -> call SLIT("cos") DoubleRep
-       DoubleTanOp -> call SLIT("tan") DoubleRep
-
-       DoubleAsinOp -> call SLIT("asin") DoubleRep
-       DoubleAcosOp -> call SLIT("acos") DoubleRep
-       DoubleAtanOp -> call SLIT("atan") DoubleRep
-
-       DoubleSinhOp -> call SLIT("sinh") DoubleRep
-       DoubleCoshOp -> call SLIT("cosh") DoubleRep
-       DoubleTanhOp -> call SLIT("tanh") DoubleRep
-
-       DoublePowerOp -> call SLIT("pow") DoubleRep
-
-       OrdOp -> coerceIntCode IntRep args
-       ChrOp -> chrCode args
-
-       Float2IntOp -> coerceFP2Int args
-       Int2FloatOp -> coerceInt2FP FloatRep args
-       Double2IntOp -> coerceFP2Int args
-       Int2DoubleOp -> coerceInt2FP DoubleRep args
-
-       Double2FloatOp -> trivialUFCode FloatRep (FxTOy DF F) args
-       Float2DoubleOp -> trivialUFCode DoubleRep (FxTOy F DF) args
-
-  where
-    call fn pk = getReg (StCall fn pk args)
-    promoteAndCall fn pk = getReg (StCall fn pk (map promote args))
-      where
-       promote x = StPrim Float2DoubleOp [x]
-
-getReg (StInd pk mem) =
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code = amodeCode amode
-       src   = amodeAddr amode
-       size = kindToSize pk
-       code__2 dst = code . mkSeqInstr (LD size src dst)
-    in
-       returnUs (Any pk code__2)
-
-getReg (StInt i)
-  | is13Bits i =
-    let
-       src = ImmInt (fromInteger i)
-       code dst = mkSeqInstr (OR False g0 (RIImm src) dst)
-    in
-       returnUs (Any IntRep code)
-
-getReg leaf
-  | maybeToBool imm =
-    let
-       code dst = mkSeqInstrs [
-           SETHI (HI imm__2) dst,
-           OR False dst (RIImm (LO imm__2)) dst]
-    in
-       returnUs (Any PtrRep code)
-  where
-    imm = maybeImm leaf
-    imm__2 = case imm of Just x -> x
-
-\end{code}
-
-Now, given a tree (the argument to an StInd) that references memory,
-produce a suitable addressing mode.
-
-\begin{code}
-
-getAmode :: StixTree -> UniqSM Amode
-
-getAmode tree@(StIndex _ _ _) = getAmode (mangleIndexTree tree)
-
-getAmode (StPrim IntSubOp [x, StInt i])
-  | is13Bits (-i) =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    getReg x                       `thenUs` \ register ->
-    let
-       code = registerCode register tmp
-       reg  = registerName register tmp
-       off  = ImmInt (-(fromInteger i))
-    in
-       returnUs (Amode (AddrRegImm reg off) code)
-
-
-getAmode (StPrim IntAddOp [x, StInt i])
-  | is13Bits i =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    getReg x                       `thenUs` \ register ->
-    let
-       code = registerCode register tmp
-       reg  = registerName register tmp
-       off  = ImmInt (fromInteger i)
-    in
-       returnUs (Amode (AddrRegImm reg off) code)
-
-getAmode (StPrim IntAddOp [x, y]) =
-    getNewRegNCG PtrRep            `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       reg1  = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       reg2  = registerName register2 tmp2
-       code__2 = asmParThen [code1, code2]
-    in
-       returnUs (Amode (AddrRegReg reg1 reg2) code__2)
-
-getAmode leaf
-  | maybeToBool imm =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    let
-       code = mkSeqInstr (SETHI (HI imm__2) tmp)
-    in
-       returnUs (Amode (AddrRegImm tmp (LO imm__2)) code)
-  where
-    imm = maybeImm leaf
-    imm__2 = case imm of Just x -> x
-
-getAmode other =
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    getReg other                   `thenUs` \ register ->
-    let
-       code = registerCode register tmp
-       reg  = registerName register tmp
-       off  = ImmInt 0
-    in
-       returnUs (Amode (AddrRegImm reg off) code)
-
-\end{code}
-
-Try to get a value into a specific register (or registers) for a call.  The Sparc
-calling convention is an absolute nightmare.  The first 6x32 bits of arguments are
-mapped into %o0 through %o5, and the remaining arguments are dumped to the stack,
-beginning at [%sp+92].  (Note that %o6 == %sp.)  Our first argument is a pair of
-the list of remaining argument registers to be assigned for this call and the next
-stack offset to use for overflowing arguments.  This way, @getCallArg@ can be applied
-to all of a call's arguments using @mapAccumL@.
-
-\begin{code}
-
-getCallArg
-    :: ([Reg],Int)         -- Argument registers and stack offset (accumulator)
-    -> StixTree            -- Current argument
-    -> UniqSM (([Reg],Int), CodeBlock SparcInstr)    -- Updated accumulator and code
-
--- We have to use up all of our argument registers first.
-
-getCallArg (dst:dsts, offset) arg =
-    getReg arg                     `thenUs` \ register ->
-    getNewRegNCG (registerKind register)
-                                   `thenUs` \ tmp ->
-    let
-       reg = if isFloatingRep pk then tmp else dst
-       code = registerCode register reg
-       src = registerName register reg
-       pk = registerKind register
-    in
-       returnUs (case pk of
-           DoubleRep ->
-               case dsts of
-                   [] -> (([], offset + 1), code . mkSeqInstrs [
-                           -- conveniently put the second part in the right stack
-                           -- location, and load the first part into %o5
-                           ST DF src (spRel (offset - 1)),
-                           LD W (spRel (offset - 1)) dst])
-                   (dst__2:dsts__2) -> ((dsts__2, offset), code . mkSeqInstrs [
-                           ST DF src (spRel (-2)),
-                           LD W (spRel (-2)) dst,
-                           LD W (spRel (-1)) dst__2])
-           FloatRep -> ((dsts, offset), code . mkSeqInstrs [
-                           ST F src (spRel (-2)),
-                           LD W (spRel (-2)) dst])
-           _ -> ((dsts, offset), if isFixed register then
-                                 code . mkSeqInstr (OR False g0 (RIReg src) dst)
-                                 else code))
-
--- Once we have run out of argument registers, we move to the stack
-
-getCallArg ([], offset) arg =
-    getReg arg                     `thenUs` \ register ->
-    getNewRegNCG (registerKind register)
-                                   `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src = registerName register tmp
-       pk = registerKind register
-       sz = kindToSize pk
-       words = if pk == DoubleRep then 2 else 1
-    in
-       returnUs (([], offset + words), code . mkSeqInstr (ST sz src (spRel offset)))
-
-\end{code}
-
-Set up a condition code for a conditional branch.
-
-\begin{code}
-
-getCondition :: StixTree -> UniqSM Condition
-
-getCondition (StPrim primop args) =
-    case primop of
-
-       CharGtOp -> condIntCode GT args
-       CharGeOp -> condIntCode GE args
-       CharEqOp -> condIntCode EQ args
-       CharNeOp -> condIntCode NE args
-       CharLtOp -> condIntCode LT args
-       CharLeOp -> condIntCode LE args
-
-       IntGtOp -> condIntCode GT args
-       IntGeOp -> condIntCode GE args
-       IntEqOp -> condIntCode EQ args
-       IntNeOp -> condIntCode NE args
-       IntLtOp -> condIntCode LT args
-       IntLeOp -> condIntCode LE args
-
-       WordGtOp -> condIntCode GU args
-       WordGeOp -> condIntCode GEU args
-       WordEqOp -> condIntCode EQ args
-       WordNeOp -> condIntCode NE args
-       WordLtOp -> condIntCode LU args
-       WordLeOp -> condIntCode LEU args
-
-       AddrGtOp -> condIntCode GU args
-       AddrGeOp -> condIntCode GEU args
-       AddrEqOp -> condIntCode EQ args
-       AddrNeOp -> condIntCode NE args
-       AddrLtOp -> condIntCode LU args
-       AddrLeOp -> condIntCode LEU args
-
-       FloatGtOp -> condFltCode GT args
-       FloatGeOp -> condFltCode GE args
-       FloatEqOp -> condFltCode EQ args
-       FloatNeOp -> condFltCode NE args
-       FloatLtOp -> condFltCode LT args
-       FloatLeOp -> condFltCode LE args
-
-       DoubleGtOp -> condFltCode GT args
-       DoubleGeOp -> condFltCode GE args
-       DoubleEqOp -> condFltCode EQ args
-       DoubleNeOp -> condFltCode NE args
-       DoubleLtOp -> condFltCode LT args
-       DoubleLeOp -> condFltCode LE args
-
-\end{code}
-
-Turn a boolean expression into a condition, to be passed
-back up the tree.
-
-\begin{code}
-
-condIntCode, condFltCode :: Cond -> [StixTree] -> UniqSM Condition
-
-condIntCode cond [x, StInt y]
-  | is13Bits y =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src1 = registerName register tmp
-       src2 = ImmInt (fromInteger y)
-       code__2 = code . mkSeqInstr (SUB False True src1 (RIImm src2) g0)
-    in
-       returnUs (Condition False cond code__2)
-
-condIntCode cond [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1  = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 = asmParThen [code1, code2] .
-               mkSeqInstr (SUB False True src1 (RIReg src2) g0)
-    in
-       returnUs (Condition False cond code__2)
-
-condFltCode cond [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG (registerKind register1)
-                                   `thenUs` \ tmp1 ->
-    getNewRegNCG (registerKind register2)
-                                   `thenUs` \ tmp2 ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp ->
-    let
-       promote x = asmInstr (FxTOy F DF x tmp)
-
-       pk1   = registerKind register1
-       code1 = registerCode register1 tmp1
-       src1  = registerName register1 tmp1
-
-       pk2   = registerKind register2
-       code2 = registerCode register2 tmp2
-       src2  = registerName register2 tmp2
-
-       code__2 =
-               if pk1 == pk2 then
-                   asmParThen [code1 asmVoid, code2 asmVoid] .
-                   mkSeqInstr (FCMP True (kindToSize pk1) src1 src2)
-               else if pk1 == FloatRep then
-                   asmParThen [code1 (promote src1), code2 asmVoid] .
-                   mkSeqInstr (FCMP True DF tmp src2)
-               else
-                   asmParThen [code1 asmVoid, code2 (promote src2)] .
-                   mkSeqInstr (FCMP True DF src1 tmp)
-    in
-       returnUs (Condition True cond code__2)
-
-\end{code}
-
-Turn those condition codes into integers now (when they appear on
-the right hand side of an assignment).
-
-Do not fill the delay slots here; you will confuse the register allocator.
-
-\begin{code}
-
-condIntReg :: Cond -> [StixTree] -> UniqSM Register
-
-condIntReg EQ [x, StInt 0] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src  = registerName register tmp
-       code__2 dst = code . mkSeqInstrs [
-           SUB False True g0 (RIReg src) g0,
-           SUB True False g0 (RIImm (ImmInt (-1))) dst]
-    in
-       returnUs (Any IntRep code__2)
-
-condIntReg EQ [x, y] =
-    getReg x               `thenUs` \ register1 ->
-    getReg y               `thenUs` \ register2 ->
-    getNewRegNCG IntRep        `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep        `thenUs` \ tmp2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1  = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 dst = asmParThen [code1, code2] . mkSeqInstrs [
-           XOR False src1 (RIReg src2) dst,
-           SUB False True g0 (RIReg dst) g0,
-           SUB True False g0 (RIImm (ImmInt (-1))) dst]
-    in
-       returnUs (Any IntRep code__2)
-
-condIntReg NE [x, StInt 0] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src  = registerName register tmp
-       code__2 dst = code . mkSeqInstrs [
-           SUB False True g0 (RIReg src) g0,
-           ADD True False g0 (RIImm (ImmInt 0)) dst]
-    in
-       returnUs (Any IntRep code__2)
-
-condIntReg NE [x, y] =
-    getReg x               `thenUs` \ register1 ->
-    getReg y               `thenUs` \ register2 ->
-    getNewRegNCG IntRep        `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep        `thenUs` \ tmp2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1  = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 dst = asmParThen [code1, code2] . mkSeqInstrs [
-           XOR False src1 (RIReg src2) dst,
-           SUB False True g0 (RIReg dst) g0,
-           ADD True False g0 (RIImm (ImmInt 0)) dst]
-    in
-       returnUs (Any IntRep code__2)
-
-condIntReg cond args =
-    getUniqLabelNCG                `thenUs` \ lbl1 ->
-    getUniqLabelNCG                `thenUs` \ lbl2 ->
-    condIntCode cond args          `thenUs` \ condition ->
-    let
-       code = condCode condition
-       cond = condName condition
-       code__2 dst = code . mkSeqInstrs [
-           BI cond False (ImmCLbl lbl1), NOP,
-           OR False g0 (RIImm (ImmInt 0)) dst,
-           BI ALWAYS False (ImmCLbl lbl2), NOP,
-           LABEL lbl1,
-           OR False g0 (RIImm (ImmInt 1)) dst,
-           LABEL lbl2]
-    in
-       returnUs (Any IntRep code__2)
-
-condFltReg :: Cond -> [StixTree] -> UniqSM Register
-
-condFltReg cond args =
-    getUniqLabelNCG                `thenUs` \ lbl1 ->
-    getUniqLabelNCG                `thenUs` \ lbl2 ->
-    condFltCode cond args          `thenUs` \ condition ->
-    let
-       code = condCode condition
-       cond = condName condition
-       code__2 dst = code . mkSeqInstrs [
-           NOP,
-           BF cond False (ImmCLbl lbl1), NOP,
-           OR False g0 (RIImm (ImmInt 0)) dst,
-           BI ALWAYS False (ImmCLbl lbl2), NOP,
-           LABEL lbl1,
-           OR False g0 (RIImm (ImmInt 1)) dst,
-           LABEL lbl2]
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-Assignments are really at the heart of the whole code generation business.
-Almost all top-level nodes of any real importance are assignments, which
-correspond to loads, stores, or register transfers.  If we're really lucky,
-some of the register transfers will go away, because we can use the destination
-register to complete the code generation for the right hand side.  This only
-fails when the right hand side is forced into a fixed register (e.g. the result
-of a call).
-
-\begin{code}
-
-assignIntCode :: PrimRep -> StixTree -> StixTree -> UniqSM (CodeBlock SparcInstr)
-
-assignIntCode pk (StInd _ dst) src =
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    getAmode dst                   `thenUs` \ amode ->
-    getReg src                     `thenUs` \ register ->
-    let
-       code1 = amodeCode amode asmVoid
-       dst__2  = amodeAddr amode
-       code2 = registerCode register tmp asmVoid
-       src__2  = registerName register tmp
-       sz    = kindToSize pk
-       code__2 = asmParThen [code1, code2] . mkSeqInstr (ST sz src__2 dst__2)
-    in
-       returnUs code__2
-
-assignIntCode pk dst src =
-    getReg dst                     `thenUs` \ register1 ->
-    getReg src                     `thenUs` \ register2 ->
-    let
-       dst__2 = registerName register1 g0
-       code = registerCode register2 dst__2
-       src__2 = registerName register2 dst__2
-       code__2 = if isFixed register2 then
-                   code . mkSeqInstr (OR False g0 (RIReg src__2) dst__2)
-               else code
-    in
-       returnUs code__2
-
-assignFltCode :: PrimRep -> StixTree -> StixTree -> UniqSM (CodeBlock SparcInstr)
-
-assignFltCode pk (StInd _ dst) src =
-    getNewRegNCG pk                `thenUs` \ tmp ->
-    getAmode dst                   `thenUs` \ amode ->
-    getReg src                     `thenUs` \ register ->
-    let
-       sz    = kindToSize pk
-       dst__2  = amodeAddr amode
-
-       code1 = amodeCode amode asmVoid
-       code2 = registerCode register tmp asmVoid
-
-       src__2  = registerName register tmp
-       pk__2  = registerKind register
-       sz__2 = kindToSize pk__2
-
-       code__2 = asmParThen [code1, code2] .
-           if pk == pk__2 then
-               mkSeqInstr (ST sz src__2 dst__2)
-           else
-               mkSeqInstrs [FxTOy sz__2 sz src__2 tmp, ST sz tmp dst__2]
-    in
-       returnUs code__2
-
-assignFltCode pk dst src =
-    getReg dst                     `thenUs` \ register1 ->
-    getReg src                     `thenUs` \ register2 ->
-    getNewRegNCG (registerKind register2)
-                                   `thenUs` \ tmp ->
-    let
-       sz = kindToSize pk
-       dst__2 = registerName register1 g0    -- must be Fixed
-
-       reg__2 = if pk /= pk__2 then tmp else dst__2
-
-       code = registerCode register2 reg__2
-       src__2 = registerName register2 reg__2
-       pk__2  = registerKind register2
-       sz__2 = kindToSize pk__2
-
-       code__2 = if pk /= pk__2 then code . mkSeqInstr (FxTOy sz__2 sz src__2 dst__2)
-               else if isFixed register2 then code . mkSeqInstr (FMOV sz src__2 dst__2)
-               else code
-    in
-       returnUs code__2
-
-\end{code}
-
-Generating an unconditional branch.  We accept two types of targets:
-an immediate CLabel or a tree that gets evaluated into a register.
-Any CLabels which are AsmTemporaries are assumed to be in the local
-block of code, close enough for a branch instruction.  Other CLabels
-are assumed to be far away, so we use call.
-
-Do not fill the delay slots here; you will confuse the register allocator.
-
-\begin{code}
-
-genJump
-    :: StixTree     -- the branch target
-    -> UniqSM (CodeBlock SparcInstr)
-
-genJump (StCLbl lbl)
-  | isAsmTemp lbl = returnInstrs [BI ALWAYS False target, NOP]
-  | otherwise     = returnInstrs [CALL target 0 True, NOP]
-  where
-    target = ImmCLbl lbl
-
-genJump tree =
-    getReg tree                            `thenUs` \ register ->
-    getNewRegNCG PtrRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       target = registerName register tmp
-    in
-       returnSeq code [JMP (AddrRegReg target g0), NOP]
-
-\end{code}
-
-Conditional jumps are always to local labels, so we can use
-branch instructions.  First, we have to ensure that the condition
-codes are set according to the supplied comparison operation.
-We generate slightly different code for floating point comparisons,
-because a floating point operation cannot directly precede a @BF@.
-We assume the worst and fill that slot with a @NOP@.
-
-Do not fill the delay slots here; you will confuse the register allocator.
-
-\begin{code}
-
-genCondJump
-    :: CLabel      -- the branch target
-    -> StixTree     -- the condition on which to branch
-    -> UniqSM (CodeBlock SparcInstr)
-
-genCondJump lbl bool =
-    getCondition bool                      `thenUs` \ condition ->
-    let
-       code = condCode condition
-       cond = condName condition
-       target = ImmCLbl lbl
-    in
-       if condFloat condition then
-           returnSeq code [NOP, BF cond False target, NOP]
-       else
-           returnSeq code [BI cond False target, NOP]
-
-\end{code}
-
-Now the biggest nightmare---calls.  Most of the nastiness is buried in
-getCallArg, which moves the arguments to the correct registers/stack
-locations.  Apart from that, the code is easy.
-
-Do not fill the delay slots here; you will confuse the register allocator.
-
-\begin{code}
-
-genCCall
-    :: FAST_STRING  -- function to call
-    -> PrimRep     -- type of the result
-    -> [StixTree]   -- arguments (of mixed type)
-    -> UniqSM (CodeBlock SparcInstr)
-
-genCCall fn kind args =
-    mapAccumLNCG getCallArg (argRegs,stackArgLoc) args
-                                   `thenUs` \ ((unused,_), argCode) ->
-    let
-       nRegs = length argRegs - length unused
-       call = CALL fn__2 nRegs False
-       code = asmParThen (map ($ asmVoid) argCode)
-    in
-       returnSeq code [call, NOP]
-  where
-    -- function names that begin with '.' are assumed to be special internally
-    -- generated names like '.mul,' which don't get an underscore prefix
-    fn__2 = case (_HEAD_ fn) of
-             '.' -> ImmLit (uppPStr fn)
-             _   -> ImmLab (uppPStr fn)
-
-    mapAccumLNCG f b []     = returnUs (b, [])
-    mapAccumLNCG f b (x:xs) =
-       f b x                               `thenUs` \ (b__2, x__2) ->
-       mapAccumLNCG f b__2 xs              `thenUs` \ (b__3, xs__2) ->
-       returnUs (b__3, x__2:xs__2)
-
-\end{code}
-
-Trivial (dyadic) instructions.  Only look for constants on the right hand
-side, because that's where the generic optimizer will have put them.
-
-\begin{code}
-
-trivialCode
-    :: (Reg -> RI -> Reg -> SparcInstr)
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialCode instr [x, StInt y]
-  | is13Bits y =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src1 = registerName register tmp
-       src2 = ImmInt (fromInteger y)
-       code__2 dst = code . mkSeqInstr (instr src1 (RIImm src2) dst)
-    in
-       returnUs (Any IntRep code__2)
-
-trivialCode instr [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp1 ->
-    getNewRegNCG IntRep            `thenUs` \ tmp2 ->
-    let
-       code1 = registerCode register1 tmp1 asmVoid
-       src1  = registerName register1 tmp1
-       code2 = registerCode register2 tmp2 asmVoid
-       src2  = registerName register2 tmp2
-       code__2 dst = asmParThen [code1, code2] .
-                    mkSeqInstr (instr src1 (RIReg src2) dst)
-    in
-       returnUs (Any IntRep code__2)
-
-trivialFCode
-    :: PrimRep
-    -> (Size -> Reg -> Reg -> Reg -> SparcInstr)
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialFCode pk instr [x, y] =
-    getReg x                       `thenUs` \ register1 ->
-    getReg y                       `thenUs` \ register2 ->
-    getNewRegNCG (registerKind register1)
-                                   `thenUs` \ tmp1 ->
-    getNewRegNCG (registerKind register2)
-                                   `thenUs` \ tmp2 ->
-    getNewRegNCG DoubleRep         `thenUs` \ tmp ->
-    let
-       promote x = asmInstr (FxTOy F DF x tmp)
-
-       pk1   = registerKind register1
-       code1 = registerCode register1 tmp1
-       src1  = registerName register1 tmp1
-
-       pk2   = registerKind register2
-       code2 = registerCode register2 tmp2
-       src2  = registerName register2 tmp2
-
-       code__2 dst =
-               if pk1 == pk2 then
-                   asmParThen [code1 asmVoid, code2 asmVoid] .
-                   mkSeqInstr (instr (kindToSize pk) src1 src2 dst)
-               else if pk1 == FloatRep then
-                   asmParThen [code1 (promote src1), code2 asmVoid] .
-                   mkSeqInstr (instr DF tmp src2 dst)
-               else
-                   asmParThen [code1 asmVoid, code2 (promote src2)] .
-                   mkSeqInstr (instr DF src1 tmp dst)
-    in
-       returnUs (Any (if pk1 == pk2 then pk1 else DoubleRep) code__2)
-
-\end{code}
-
-Trivial unary instructions.  Note that we don't have to worry about
-matching an StInt as the argument, because genericOpt will already
-have handled the constant-folding.
-
-\begin{code}
-
-trivialUCode
-    :: (RI -> Reg -> SparcInstr)
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialUCode instr [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src  = registerName register tmp
-       code__2 dst = code . mkSeqInstr (instr (RIReg src) dst)
-    in
-       returnUs (Any IntRep code__2)
-
-trivialUFCode
-    :: PrimRep
-    -> (Reg -> Reg -> SparcInstr)
-    -> [StixTree]
-    -> UniqSM Register
-
-trivialUFCode pk instr [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG pk                `thenUs` \ tmp ->
-    let
-       code = registerCode register tmp
-       src  = registerName register tmp
-       code__2 dst = code . mkSeqInstr (instr src dst)
-    in
-       returnUs (Any pk code__2)
-
-\end{code}
-
-Absolute value on integers, mostly for gmp size check macros.  Again,
-the argument cannot be an StInt, because genericOpt already folded
-constants.
-
-Do not fill the delay slots here; you will confuse the register allocator.
-
-\begin{code}
-
-absIntCode :: [StixTree] -> UniqSM Register
-absIntCode [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ reg ->
-    getUniqLabelNCG                        `thenUs` \ lbl ->
-    let
-       code = registerCode register reg
-       src  = registerName register reg
-       code__2 dst = code . mkSeqInstrs [
-           SUB False True g0 (RIReg src) dst,
-           BI GE False (ImmCLbl lbl), NOP,
-           OR False g0 (RIReg src) dst,
-           LABEL lbl]
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-Simple integer coercions that don't require any code to be generated.
-Here we just change the type on the register passed on up
-
-\begin{code}
-
-coerceIntCode :: PrimRep -> [StixTree] -> UniqSM Register
-coerceIntCode pk [x] =
-    getReg x                       `thenUs` \ register ->
-    case register of
-       Fixed reg _ code -> returnUs (Fixed reg pk code)
-       Any _ code       -> returnUs (Any pk code)
-
-\end{code}
-
-Integer to character conversion.  We try to do this in one step if
-the original object is in memory.
-
-\begin{code}
-
-chrCode :: [StixTree] -> UniqSM Register
-chrCode [StInd pk mem] =
-    getAmode mem                   `thenUs` \ amode ->
-    let
-       code = amodeCode amode
-       src  = amodeAddr amode
-       srcOff = offset src 3
-       src__2 = case srcOff of Just x -> x
-       code__2 dst = if maybeToBool srcOff then
-                       code . mkSeqInstr (LD UB src__2 dst)
-                   else
-                       code . mkSeqInstrs [
-                           LD (kindToSize pk) src dst,
-                           AND False dst (RIImm (ImmInt 255)) dst]
-    in
-       returnUs (Any pk code__2)
-
-chrCode [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ reg ->
-    let
-       code = registerCode register reg
-       src  = registerName register reg
-       code__2 dst = code . mkSeqInstr (AND False src (RIImm (ImmInt 255)) dst)
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-More complicated integer/float conversions.  Here we have to store
-temporaries in memory to move between the integer and the floating
-point register sets.
-
-\begin{code}
-
-coerceInt2FP :: PrimRep -> [StixTree] -> UniqSM Register
-coerceInt2FP pk [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ reg ->
-    let
-       code = registerCode register reg
-       src  = registerName register reg
-
-       code__2 dst = code . mkSeqInstrs [
-           ST W src (spRel (-2)),
-           LD W (spRel (-2)) dst,
-           FxTOy W (kindToSize pk) dst dst]
-    in
-       returnUs (Any pk code__2)
-
-coerceFP2Int :: [StixTree] -> UniqSM Register
-coerceFP2Int [x] =
-    getReg x                       `thenUs` \ register ->
-    getNewRegNCG IntRep            `thenUs` \ reg ->
-    getNewRegNCG FloatRep          `thenUs` \ tmp ->
-    let
-       code = registerCode register reg
-       src  = registerName register reg
-       pk   = registerKind register
-
-       code__2 dst = code . mkSeqInstrs [
-           FxTOy (kindToSize pk) W src tmp,
-           ST W tmp (spRel (-2)),
-           LD W (spRel (-2)) dst]
-    in
-       returnUs (Any IntRep code__2)
-
-\end{code}
-
-Some random little helpers.
-
-\begin{code}
-
-maybeImm :: StixTree -> Maybe Imm
-maybeImm (StInt i)
-  | i >= toInteger minInt && i <= toInteger maxInt = Just (ImmInt (fromInteger i))
-  | otherwise = Just (ImmInteger i)
-maybeImm (StLitLbl s)  = Just (ImmLab s)
-maybeImm (StLitLit s)  = Just (strImmLit (cvtLitLit (_UNPK_ s)))
-maybeImm (StCLbl l) = Just (ImmCLbl l)
-maybeImm _          = Nothing
-
-mangleIndexTree :: StixTree -> StixTree
-
-mangleIndexTree (StIndex pk base (StInt i)) =
-    StPrim IntAddOp [base, off]
-  where
-    off = StInt (i * size pk)
-    size :: PrimRep -> Integer
-    size pk = case kindToSize pk of
-       {SB -> 1; UB -> 1; HW -> 2; UHW -> 2; W -> 4; D -> 8; F -> 4; DF -> 8}
-
-mangleIndexTree (StIndex pk base off) =
-    case pk of
-       CharRep -> StPrim IntAddOp [base, off]
-       _        -> StPrim IntAddOp [base, off__2]
-  where
-    off__2 = StPrim SllOp [off, StInt (shift pk)]
-    shift :: PrimRep -> Integer
-    shift DoubleRep    = 3
-    shift _            = 2
-
-cvtLitLit :: String -> String
-cvtLitLit "stdin" = "__iob+0x0"   -- This one is probably okay...
-cvtLitLit "stdout" = "__iob+0x14" -- but these next two are dodgy at best
-cvtLitLit "stderr" = "__iob+0x28"
-cvtLitLit s
-  | isHex s = s
-  | otherwise = error ("Native code generator can't handle ``" ++ s ++ "''")
-  where
-    isHex ('0':'x':xs) = all isHexDigit xs
-    isHex _ = False
-    -- Now, where have I seen this before?
-    isHexDigit c = isDigit c || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'
-
-
-\end{code}
-
-spRel gives us a stack relative addressing mode for volatile temporaries
-and for excess call arguments.
-
-\begin{code}
-
-spRel
-    :: Int     -- desired stack offset in words, positive or negative
-    -> Addr
-spRel n = AddrRegImm sp (ImmInt (n * 4))
-
-stackArgLoc = 23 :: Int            -- where to stack extra call arguments (beyond 6x32 bits)
-
-\end{code}
-
-\begin{code}
-
-getNewRegNCG :: PrimRep -> UniqSM Reg
-getNewRegNCG pk =
-      getUnique          `thenUs` \ u ->
-      returnUs (mkReg u pk)
-
-\end{code}
index 8269dbd..f187e9f 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The AQUA Project, Glasgow University, 1993-1995
+% (c) The AQUA Project, Glasgow University, 1993-1996
 %
 
 \begin{code}
 %
 
 \begin{code}
@@ -11,158 +11,142 @@ module Stix (
 
        stgBaseReg, stgStkOReg, stgNode, stgTagReg, stgRetReg,
        stgSpA, stgSuA, stgSpB, stgSuB, stgHp, stgHpLim, stgLivenessReg,
 
        stgBaseReg, stgStkOReg, stgNode, stgTagReg, stgRetReg,
        stgSpA, stgSuA, stgSpB, stgSuB, stgHp, stgHpLim, stgLivenessReg,
---     stgActivityReg,
        stgStdUpdRetVecReg, stgStkStubReg,
        getUniqLabelNCG
        stgStdUpdRetVecReg, stgStkStubReg,
        getUniqLabelNCG
-
-       -- And for self-sufficiency, by golly...
     ) where
 
     ) where
 
-import AbsCSyn     ( MagicId(..), kindFromMagicId, node, infoptr )
-import PrelInfo            ( showPrimOp, PrimOp
-                     IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                   )
-import CLabel   ( CLabel, mkAsmTempLabel )
-import Outputable
-import UniqSupply
-import Unpretty
-import Util
+import Ubiq{-uitous-}
+
+import AbsCSyn         ( node, infoptr, MagicId(..) )
+import AbsCUtils       ( magicIdPrimRep )
+import CLabel          ( mkAsmTempLabel )
+import UniqSupply      ( returnUs, thenUs, getUnique, UniqSM(..) )
+import Unpretty                ( uppPStr, Unpretty(..) )
 \end{code}
 
 Here is the tag at the nodes of our @StixTree@.         Notice its
 relationship with @PrimOp@ in prelude/PrimOp.
 
 \begin{code}
 \end{code}
 
 Here is the tag at the nodes of our @StixTree@.         Notice its
 relationship with @PrimOp@ in prelude/PrimOp.
 
 \begin{code}
+data StixTree
+  = -- Segment (text or data)
 
 
-data StixTree =
-
-       -- Segment (text or data)
+    StSegment CodeSegment
 
 
-       StSegment CodeSegment
+    -- We can tag the leaves with constants/immediates.
 
 
-       -- We can tag the leaves with constants/immediates.
+  | StInt      Integer     -- ** add Kind at some point
+  | StDouble   Rational
+  | StString   FAST_STRING
+  | StLitLbl   Unpretty    -- literal labels
+                           -- (will be _-prefixed on some machines)
+  | StLitLit   FAST_STRING -- innards from CLitLit
+  | StCLbl     CLabel      -- labels that we might index into
 
 
-      | StInt    Integer      -- ** add Kind at some point
-      | StDouble  Rational
-      | StString  FAST_STRING
-      | StLitLbl  Unpretty     -- literal labels (will be _-prefixed on some machines)
-      | StLitLit  FAST_STRING  -- innards from CLitLit
-      | StCLbl   CLabel        -- labels that we might index into
+    -- Abstract registers of various kinds
 
 
-       -- Abstract registers of various kinds
+  | StReg StixReg
 
 
-      | StReg StixReg
+    -- A typed offset from a base location
 
 
-       -- A typed offset from a base location
+  | StIndex PrimRep StixTree StixTree -- kind, base, offset
 
 
-      | StIndex PrimRep StixTree StixTree -- kind, base, offset
+    -- An indirection from an address to its contents.
 
 
-       -- An indirection from an address to its contents.
+  | StInd PrimRep StixTree
 
 
-      | StInd PrimRep StixTree
+    -- Assignment is typed to determine size and register placement
 
 
-       -- Assignment is typed to determine size and register placement
+  | StAssign PrimRep StixTree StixTree -- dst, src
 
 
-      | StAssign PrimRep StixTree StixTree -- dst, src
+    -- A simple assembly label that we might jump to.
 
 
-       -- A simple assembly label that we might jump to.
+  | StLabel CLabel
 
 
-      | StLabel CLabel
+    -- A function header and footer
 
 
-       -- A function header and footer
+  | StFunBegin CLabel
+  | StFunEnd CLabel
 
 
-      | StFunBegin CLabel
-      | StFunEnd CLabel
+    -- An unconditional jump. This instruction is terminal.
+    -- Dynamic targets are allowed
 
 
-       -- An unconditional jump. This instruction is terminal.
-       -- Dynamic targets are allowed
+  | StJump StixTree
 
 
-      | StJump StixTree
+    -- A fall-through, from slow to fast
 
 
-       -- A fall-through, from slow to fast
+  | StFallThrough CLabel
 
 
-      | StFallThrough CLabel
+    -- A conditional jump. This instruction can be non-terminal :-)
+    -- Only static, local, forward labels are allowed
 
 
-       -- A conditional jump.  This instruction can be non-terminal :-)
-       -- Only static, local, forward labels are allowed
+  | StCondJump CLabel StixTree
 
 
-      | StCondJump CLabel StixTree
+    -- Raw data (as in an info table).
 
 
-       -- Raw data (as in an info table).
+  | StData PrimRep [StixTree]
 
 
-      | StData PrimRep [StixTree]
+    -- Primitive Operations
 
 
-       -- Primitive Operations
+  | StPrim PrimOp [StixTree]
 
 
-      | StPrim PrimOp [StixTree]
+    -- Calls to C functions
 
 
-       -- Calls to C functions
+  | StCall FAST_STRING PrimRep [StixTree]
 
 
-      | StCall FAST_STRING PrimRep [StixTree]
+    -- Assembly-language comments
 
 
-       -- Comments, of course
-
-      | StComment FAST_STRING  -- For assembly comments
-
-      deriving ()
+  | StComment FAST_STRING
 
 sStLitLbl :: FAST_STRING -> StixTree
 sStLitLbl s = StLitLbl (uppPStr s)
 \end{code}
 
 Stix registers can have two forms.  They {\em may} or {\em may not}
 
 sStLitLbl :: FAST_STRING -> StixTree
 sStLitLbl s = StLitLbl (uppPStr s)
 \end{code}
 
 Stix registers can have two forms.  They {\em may} or {\em may not}
-map to real, machine level registers.
+map to real, machine-level registers.
 
 \begin{code}
 
 \begin{code}
+data StixReg
+  = StixMagicId MagicId        -- Regs which are part of the abstract machine model
 
 
-data StixReg = StixMagicId MagicId     -- Regs which are part of the abstract machine model
-
-            | StixTemp Unique PrimRep -- "Regs" which model local variables (CTemps) in
+  | StixTemp Unique PrimRep -- "Regs" which model local variables (CTemps) in
                                        -- the abstract C.
                                        -- the abstract C.
-            deriving ()
-
 \end{code}
 
 We hope that every machine supports the idea of data segment and text
 \end{code}
 
 We hope that every machine supports the idea of data segment and text
-segment (or that it has no segments at all, and we can lump these together).
+segment (or that it has no segments at all, and we can lump these
+together).
 
 \begin{code}
 
 \begin{code}
-
-data CodeSegment = DataSegment | TextSegment deriving (Eq)
+data CodeSegment = DataSegment | TextSegment deriving Eq
 
 type StixTreeList = [StixTree] -> [StixTree]
 
 type StixTreeList = [StixTree] -> [StixTree]
-
 \end{code}
 
 \end{code}
 
--- Stix Trees for STG registers
-
+Stix Trees for STG registers:
 \begin{code}
 \begin{code}
-
-stgBaseReg, stgStkOReg, stgNode, stgTagReg, stgRetReg, stgSpA, stgSuA,
-    stgSpB, stgSuB, stgHp, stgHpLim, stgLivenessReg{-, stgActivityReg-}, stgStdUpdRetVecReg,
-    stgStkStubReg :: StixTree
-
-stgBaseReg = StReg (StixMagicId BaseReg)
-stgStkOReg = StReg (StixMagicId StkOReg)
-stgNode = StReg (StixMagicId node)
-stgInfoPtr = StReg (StixMagicId infoptr)
-stgTagReg = StReg (StixMagicId TagReg)
-stgRetReg = StReg (StixMagicId RetReg)
-stgSpA = StReg (StixMagicId SpA)
-stgSuA = StReg (StixMagicId SuA)
-stgSpB = StReg (StixMagicId SpB)
-stgSuB = StReg (StixMagicId SuB)
-stgHp = StReg (StixMagicId Hp)
-stgHpLim = StReg (StixMagicId HpLim)
-stgLivenessReg = StReg (StixMagicId LivenessReg)
---stgActivityReg = StReg (StixMagicId ActivityReg)
-stgStdUpdRetVecReg = StReg (StixMagicId StdUpdRetVecReg)
-stgStkStubReg = StReg (StixMagicId StkStubReg)
+stgBaseReg, stgStkOReg, stgNode, stgTagReg, stgRetReg, stgSpA,
+    stgSuA, stgSpB, stgSuB, stgHp, stgHpLim, stgLivenessReg,
+    stgStdUpdRetVecReg, stgStkStubReg :: StixTree
+
+stgBaseReg         = StReg (StixMagicId BaseReg)
+stgStkOReg         = StReg (StixMagicId StkOReg)
+stgNode            = StReg (StixMagicId node)
+stgInfoPtr         = StReg (StixMagicId infoptr)
+stgTagReg          = StReg (StixMagicId TagReg)
+stgRetReg          = StReg (StixMagicId RetReg)
+stgSpA                     = StReg (StixMagicId SpA)
+stgSuA                     = StReg (StixMagicId SuA)
+stgSpB                     = StReg (StixMagicId SpB)
+stgSuB                     = StReg (StixMagicId SuB)
+stgHp              = StReg (StixMagicId Hp)
+stgHpLim           = StReg (StixMagicId HpLim)
+stgLivenessReg     = StReg (StixMagicId LivenessReg)
+stgStdUpdRetVecReg  = StReg (StixMagicId StdUpdRetVecReg)
+stgStkStubReg      = StReg (StixMagicId StkStubReg)
 
 getUniqLabelNCG :: UniqSM CLabel
 
 getUniqLabelNCG :: UniqSM CLabel
-getUniqLabelNCG =
-      getUnique              `thenUs` \ u ->
-      returnUs (mkAsmTempLabel u)
-
+getUniqLabelNCG
+  = getUnique        `thenUs` \ u ->
+    returnUs (mkAsmTempLabel u)
 \end{code}
 \end{code}
index e827167..82b88c6 100644 (file)
@@ -1,24 +1,32 @@
 %
 %
-% (c) The AQUA Project, Glasgow University, 1993-1995
+% (c) The AQUA Project, Glasgow University, 1993-1996
 %
 
 \begin{code}
 #include "HsVersions.h"
 
 %
 
 \begin{code}
 #include "HsVersions.h"
 
-module StixInfo (
-       genCodeInfoTable
-    ) where
-
-import AbsCSyn
-import ClosureInfo
-import MachDesc
-import Maybes          ( maybeToBool, Maybe(..) )
-import SMRep           ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
-import Stix
-import UniqSupply
-import Unpretty
-import Util
-
+module StixInfo ( genCodeInfoTable ) where
+
+import Ubiq{-uitious-}
+
+import AbsCSyn         ( AbstractC(..), CAddrMode, ReturnInfo,
+                         RegRelative, MagicId, CStmtMacro
+                       )
+import ClosureInfo     ( closurePtrsSize, closureSizeWithoutFixedHdr,
+                         closureNonHdrSize, closureSemiTag, maybeSelectorInfo,
+                         closureSMRep, closureLabelFromCI,
+                         infoTableLabelFromCI
+                       )
+import HeapOffs                ( hpRelToInt )
+import Maybes          ( maybeToBool )
+import PrimRep         ( PrimRep(..) )
+import SMRep           ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..),
+                         isSpecRep
+                       )
+import Stix            -- all of it
+import StixPrim                ( amodeToStix )
+import UniqSupply      ( returnUs, UniqSM(..) )
+import Unpretty                ( uppBesides, uppPStr, uppInt, uppChar )
 \end{code}
 
 Generating code for info tables (arrays of data).
 \end{code}
 
 Generating code for info tables (arrays of data).
@@ -36,14 +44,11 @@ data___rtbl = sStLitLbl SLIT("Data___rtbl")
 dyn___rtbl     = sStLitLbl SLIT("Dyn___rtbl")
 
 genCodeInfoTable
 dyn___rtbl     = sStLitLbl SLIT("Dyn___rtbl")
 
 genCodeInfoTable
-    :: {-Target-}
-       (HeapOffset -> Int)     -- needed bit of Target
-    -> (CAddrMode -> StixTree) -- ditto
-    -> AbstractC
+    :: AbstractC
     -> UniqSM StixTreeList
 
     -> UniqSM StixTreeList
 
-genCodeInfoTable hp_rel amode2stix (CClosureInfoAndCode cl_info _ _ upd cl_descr _) =
-    returnUs (\xs -> info : lbl : xs)
+genCodeInfoTable (CClosureInfoAndCode cl_info _ _ upd cl_descr _)
+  = returnUs (\xs -> info : lbl : xs)
 
     where
        info = StData PtrRep table
 
     where
        info = StData PtrRep table
@@ -133,11 +138,10 @@ genCodeInfoTable hp_rel amode2stix (CClosureInfoAndCode cl_info _ _ upd cl_descr
 
        size    = if isSpecRep sm_rep
                  then closureNonHdrSize cl_info
 
        size    = if isSpecRep sm_rep
                  then closureNonHdrSize cl_info
-                 else hp_rel (closureSizeWithoutFixedHdr cl_info)
+                 else hpRelToInt (closureSizeWithoutFixedHdr cl_info)
        ptrs    = closurePtrsSize cl_info
 
        ptrs    = closurePtrsSize cl_info
 
-       upd_code = amode2stix upd
+       upd_code = amodeToStix upd
 
        info_unused = StInt (-1)
 
        info_unused = StInt (-1)
-
 \end{code}
 \end{code}
index 91d68d0..fe9ec74 100644 (file)
@@ -1,38 +1,41 @@
 %
 %
-% (c) The AQUA Project, Glasgow University, 1993-1995
+% (c) The AQUA Project, Glasgow University, 1993-1996
 %
 
 \begin{code}
 #include "HsVersions.h"
 
 module StixInteger (
 %
 
 \begin{code}
 #include "HsVersions.h"
 
 module StixInteger (
-       gmpTake1Return1, gmpTake2Return1, gmpTake2Return2,
-       gmpCompare, gmpInteger2Int, gmpInt2Integer, gmpString2Integer,
+       gmpTake1Return1, gmpTake2Return1, gmpTake2Return2, gmpCompare,
+       gmpInteger2Int, gmpInt2Integer, gmpString2Integer,
        encodeFloatingKind, decodeFloatingKind
     ) where
 
        encodeFloatingKind, decodeFloatingKind
     ) where
 
-IMPORT_Trace   -- ToDo: rm debugging
-
-import AbsCSyn
-import CgCompInfo   ( mIN_MP_INT_SIZE )
-import MachDesc
-import Pretty
-import PrelInfo            ( PrimOp(..)
-                     IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                   )
-import SMRep       ( SMRep(..), SMSpecRepKind, SMUpdateKind(..) )
-import Stix
-import UniqSupply
-import Util
-
+import Ubiq{-uitous-}
+import NcgLoop         ( amodeToStix )
+
+import MachMisc
+import MachRegs
+
+import AbsCSyn         -- bits and bobs...
+import CgCompInfo      ( mIN_MP_INT_SIZE )
+import Literal         ( Literal(..) )
+import OrdList         ( OrdList )
+import PrimOp          ( PrimOp(..) )
+import PrimRep         ( PrimRep(..) )
+import SMRep           ( SMRep(..), SMSpecRepKind, SMUpdateKind )
+import Stix            ( getUniqLabelNCG, sStLitLbl, stgHp, stgHpLim,
+                         StixTree(..), StixTreeList(..),
+                         CodeSegment, StixReg
+                       )
+import StixMacro       ( macroCode, heapCheck )
+import UniqSupply      ( returnUs, thenUs, UniqSM(..) )
+import Util            ( panic )
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-
 gmpTake1Return1
 gmpTake1Return1
-    :: Target
-    -> (CAddrMode,CAddrMode,CAddrMode)  -- result (3 parts)
+    :: (CAddrMode,CAddrMode,CAddrMode)  -- result (3 parts)
     -> FAST_STRING                     -- function name
     -> (CAddrMode, CAddrMode,CAddrMode,CAddrMode)
                                        -- argument (4 parts)
     -> FAST_STRING                     -- function name
     -> (CAddrMode, CAddrMode,CAddrMode,CAddrMode)
                                        -- argument (4 parts)
@@ -47,124 +50,109 @@ init2 = StCall SLIT("mpz_init") VoidRep [result2]
 init3 = StCall SLIT("mpz_init") VoidRep [result3]
 init4 = StCall SLIT("mpz_init") VoidRep [result4]
 
 init3 = StCall SLIT("mpz_init") VoidRep [result3]
 init4 = StCall SLIT("mpz_init") VoidRep [result4]
 
--- hacking with Uncle Will:
-#define target_STRICT target@(Target _ _ _ _ _ _ _ _)
-
-gmpTake1Return1 target_STRICT res@(car,csr,cdr) rtn arg@(clive,caa,csa,cda) =
-    let
-       a2stix  = amodeToStix target
-       data_hs = dataHS target
-
-       ar      = a2stix car
-       sr      = a2stix csr
-       dr      = a2stix cdr
-       liveness= a2stix clive
-       aa      = a2stix caa
-       sa      = a2stix csa
-       da      = a2stix cda
-
-       space = mpSpace data_hs 2 1 [sa]
+gmpTake1Return1 res@(car,csr,cdr) rtn arg@(clive,caa,csa,cda)
+  = let
+       ar      = amodeToStix car
+       sr      = amodeToStix csr
+       dr      = amodeToStix cdr
+       liveness= amodeToStix clive
+       aa      = amodeToStix caa
+       sa      = amodeToStix csa
+       da      = amodeToStix cda
+
+       space = mpSpace 2 1 [sa]
        oldHp = StIndex PtrRep stgHp (StPrim IntNegOp [space])
        oldHp = StIndex PtrRep stgHp (StPrim IntNegOp [space])
-       safeHp = saveLoc target Hp
+       safeHp = saveLoc Hp
        save = StAssign PtrRep safeHp oldHp
        save = StAssign PtrRep safeHp oldHp
-       (a1,a2,a3) = toStruct data_hs argument1 (aa,sa,da)
+       (a1,a2,a3) = toStruct argument1 (aa,sa,da)
        mpz_op = StCall rtn VoidRep [result2, argument1]
        restore = StAssign PtrRep stgHp safeHp
        mpz_op = StCall rtn VoidRep [result2, argument1]
        restore = StAssign PtrRep stgHp safeHp
-       (r1,r2,r3) = fromStruct data_hs result2 (ar,sr,dr)
+       (r1,r2,r3) = fromStruct result2 (ar,sr,dr)
     in
     in
-       heapCheck target liveness space (StInt 0) `thenUs` \ heap_chk ->
+    heapCheck liveness space (StInt 0) `thenUs` \ heap_chk ->
 
 
-       returnUs (heap_chk .
-           (\xs -> a1 : a2 : a3 : save : init2 : mpz_op : r1 : r2 : r3 : restore : xs))
+    returnUs (heap_chk .
+       (\xs -> a1 : a2 : a3 : save : init2 : mpz_op : r1 : r2 : r3 : restore : xs))
 
 gmpTake2Return1
 
 gmpTake2Return1
-    :: Target
-    -> (CAddrMode,CAddrMode,CAddrMode) -- result (3 parts)
+    :: (CAddrMode,CAddrMode,CAddrMode) -- result (3 parts)
     -> FAST_STRING                     -- function name
     -> (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
                                        -- liveness + 2 arguments (3 parts each)
     -> UniqSM StixTreeList
 
     -> FAST_STRING                     -- function name
     -> (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
                                        -- liveness + 2 arguments (3 parts each)
     -> UniqSM StixTreeList
 
-gmpTake2Return1 target_STRICT res@(car,csr,cdr) rtn args@(clive, caa1,csa1,cda1, caa2,csa2,cda2) =
-    let
-       a2stix  = amodeToStix target
-       data_hs = dataHS target
-
-       ar      = a2stix car
-       sr      = a2stix csr
-       dr      = a2stix cdr
-       liveness= a2stix clive
-       aa1     = a2stix caa1
-       sa1     = a2stix csa1
-       da1     = a2stix cda1
-       aa2     = a2stix caa2
-       sa2     = a2stix csa2
-       da2     = a2stix cda2
-
-       space = mpSpace data_hs 3 1 [sa1, sa2]
+gmpTake2Return1 res@(car,csr,cdr) rtn args@(clive, caa1,csa1,cda1, caa2,csa2,cda2)
+  = let
+       ar      = amodeToStix car
+       sr      = amodeToStix csr
+       dr      = amodeToStix cdr
+       liveness= amodeToStix clive
+       aa1     = amodeToStix caa1
+       sa1     = amodeToStix csa1
+       da1     = amodeToStix cda1
+       aa2     = amodeToStix caa2
+       sa2     = amodeToStix csa2
+       da2     = amodeToStix cda2
+
+       space = mpSpace 3 1 [sa1, sa2]
        oldHp = StIndex PtrRep stgHp (StPrim IntNegOp [space])
        oldHp = StIndex PtrRep stgHp (StPrim IntNegOp [space])
-       safeHp = saveLoc target Hp
+       safeHp = saveLoc Hp
        save = StAssign PtrRep safeHp oldHp
        save = StAssign PtrRep safeHp oldHp
-       (a1,a2,a3) = toStruct data_hs argument1 (aa1,sa1,da1)
-       (a4,a5,a6) = toStruct data_hs argument2 (aa2,sa2,da2)
+       (a1,a2,a3) = toStruct argument1 (aa1,sa1,da1)
+       (a4,a5,a6) = toStruct argument2 (aa2,sa2,da2)
        mpz_op = StCall rtn VoidRep [result3, argument1, argument2]
        restore = StAssign PtrRep stgHp safeHp
        mpz_op = StCall rtn VoidRep [result3, argument1, argument2]
        restore = StAssign PtrRep stgHp safeHp
-       (r1,r2,r3) = fromStruct data_hs result3 (ar,sr,dr)
+       (r1,r2,r3) = fromStruct result3 (ar,sr,dr)
     in
     in
-       heapCheck target liveness space (StInt 0) `thenUs` \ heap_chk ->
+    heapCheck liveness space (StInt 0) `thenUs` \ heap_chk ->
 
 
-       returnUs (heap_chk .
-           (\xs -> a1 : a2 : a3 : a4 : a5 : a6
-                       : save : init3 : mpz_op : r1 : r2 : r3 : restore : xs))
+    returnUs (heap_chk .
+       (\xs -> a1 : a2 : a3 : a4 : a5 : a6
+                   : save : init3 : mpz_op : r1 : r2 : r3 : restore : xs))
 
 gmpTake2Return2
 
 gmpTake2Return2
-    :: Target
-    -> (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
+    :: (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
                            -- 2 results (3 parts each)
     -> FAST_STRING         -- function name
     -> (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
                            -- liveness + 2 arguments (3 parts each)
     -> UniqSM StixTreeList
 
                            -- 2 results (3 parts each)
     -> FAST_STRING         -- function name
     -> (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
                            -- liveness + 2 arguments (3 parts each)
     -> UniqSM StixTreeList
 
-gmpTake2Return2 target_STRICT res@(car1,csr1,cdr1, car2,csr2,cdr2)
-               rtn args@(clive, caa1,csa1,cda1, caa2,csa2,cda2) =
-    let
-       a2stix  = amodeToStix target
-       data_hs = dataHS target
-
-       ar1     = a2stix car1
-       sr1     = a2stix csr1
-       dr1     = a2stix cdr1
-       ar2     = a2stix car2
-       sr2     = a2stix csr2
-       dr2     = a2stix cdr2
-       liveness= a2stix clive
-       aa1     = a2stix caa1
-       sa1     = a2stix csa1
-       da1     = a2stix cda1
-       aa2     = a2stix caa2
-       sa2     = a2stix csa2
-       da2     = a2stix cda2
-
-       space = StPrim IntMulOp [mpSpace data_hs 2 1 [sa1, sa2], StInt 2]
+gmpTake2Return2 res@(car1,csr1,cdr1, car2,csr2,cdr2)
+               rtn args@(clive, caa1,csa1,cda1, caa2,csa2,cda2)
+  = let
+       ar1     = amodeToStix car1
+       sr1     = amodeToStix csr1
+       dr1     = amodeToStix cdr1
+       ar2     = amodeToStix car2
+       sr2     = amodeToStix csr2
+       dr2     = amodeToStix cdr2
+       liveness= amodeToStix clive
+       aa1     = amodeToStix caa1
+       sa1     = amodeToStix csa1
+       da1     = amodeToStix cda1
+       aa2     = amodeToStix caa2
+       sa2     = amodeToStix csa2
+       da2     = amodeToStix cda2
+
+       space = StPrim IntMulOp [mpSpace 2 1 [sa1, sa2], StInt 2]
        oldHp = StIndex PtrRep stgHp (StPrim IntNegOp [space])
        oldHp = StIndex PtrRep stgHp (StPrim IntNegOp [space])
-       safeHp = saveLoc target Hp
+       safeHp = saveLoc Hp
        save = StAssign PtrRep safeHp oldHp
        save = StAssign PtrRep safeHp oldHp
-       (a1,a2,a3) = toStruct data_hs argument1 (aa1,sa1,da1)
-       (a4,a5,a6) = toStruct data_hs argument2 (aa2,sa2,da2)
+       (a1,a2,a3) = toStruct argument1 (aa1,sa1,da1)
+       (a4,a5,a6) = toStruct argument2 (aa2,sa2,da2)
        mpz_op = StCall rtn VoidRep [result3, result4, argument1, argument2]
        restore = StAssign PtrRep stgHp safeHp
        mpz_op = StCall rtn VoidRep [result3, result4, argument1, argument2]
        restore = StAssign PtrRep stgHp safeHp
-       (r1,r2,r3) = fromStruct data_hs result3 (ar1,sr1,dr1)
-       (r4,r5,r6) = fromStruct data_hs result4 (ar2,sr2,dr2)
+       (r1,r2,r3) = fromStruct result3 (ar1,sr1,dr1)
+       (r4,r5,r6) = fromStruct result4 (ar2,sr2,dr2)
 
     in
 
     in
-       heapCheck target liveness space (StInt 0) `thenUs` \ heap_chk ->
-
-       returnUs (heap_chk .
-           (\xs -> a1 : a2 : a3 : a4 : a5 : a6
-                       : save : init3 : init4 : mpz_op
-                       : r1 : r2 : r3 : r4 : r5 : r6 : restore : xs))
+    heapCheck liveness space (StInt 0) `thenUs` \ heap_chk ->
 
 
+    returnUs (heap_chk .
+       (\xs -> a1 : a2 : a3 : a4 : a5 : a6
+                   : save : init3 : init4 : mpz_op
+                   : r1 : r2 : r3 : r4 : r5 : r6 : restore : xs))
 \end{code}
 
 Although gmpCompare doesn't allocate space, it does temporarily use
 \end{code}
 
 Although gmpCompare doesn't allocate space, it does temporarily use
@@ -173,92 +161,79 @@ enclosing routine has already guaranteed that this space will be
 available.  (See ``primOpHeapRequired.'')
 
 \begin{code}
 available.  (See ``primOpHeapRequired.'')
 
 \begin{code}
-
 gmpCompare
 gmpCompare
-    :: Target
-    -> CAddrMode           -- result (boolean)
+    :: CAddrMode           -- result (boolean)
     -> (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
                            -- alloc hp + 2 arguments (3 parts each)
     -> UniqSM StixTreeList
 
     -> (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
                            -- alloc hp + 2 arguments (3 parts each)
     -> UniqSM StixTreeList
 
-gmpCompare target_STRICT res args@(chp, caa1,csa1,cda1, caa2,csa2,cda2) =
-    let
-       a2stix  = amodeToStix target
-       data_hs = dataHS target
-
-       result  = a2stix res
-       hp      = a2stix chp
-       aa1     = a2stix caa1
-       sa1     = a2stix csa1
-       da1     = a2stix cda1
-       aa2     = a2stix caa2
-       sa2     = a2stix csa2
-       da2     = a2stix cda2
+gmpCompare res args@(chp, caa1,csa1,cda1, caa2,csa2,cda2)
+  = let
+       result  = amodeToStix res
+       hp      = amodeToStix chp
+       aa1     = amodeToStix caa1
+       sa1     = amodeToStix csa1
+       da1     = amodeToStix cda1
+       aa2     = amodeToStix caa2
+       sa2     = amodeToStix csa2
+       da2     = amodeToStix cda2
 
        argument1 = hp
        argument2 = StIndex IntRep hp (StInt (toInteger mpIntSize))
 
        argument1 = hp
        argument2 = StIndex IntRep hp (StInt (toInteger mpIntSize))
-       (a1,a2,a3) = toStruct data_hs argument1 (aa1,sa1,da1)
-       (a4,a5,a6) = toStruct data_hs argument2 (aa2,sa2,da2)
+       (a1,a2,a3) = toStruct argument1 (aa1,sa1,da1)
+       (a4,a5,a6) = toStruct argument2 (aa2,sa2,da2)
        mpz_cmp = StCall SLIT("mpz_cmp") IntRep [argument1, argument2]
        r1 = StAssign IntRep result mpz_cmp
     in
        mpz_cmp = StCall SLIT("mpz_cmp") IntRep [argument1, argument2]
        r1 = StAssign IntRep result mpz_cmp
     in
-       returnUs (\xs -> a1 : a2 : a3 : a4 : a5 : a6 : r1 : xs)
-
+    returnUs (\xs -> a1 : a2 : a3 : a4 : a5 : a6 : r1 : xs)
 \end{code}
 
 See the comment above regarding the heap check (or lack thereof).
 
 \begin{code}
 \end{code}
 
 See the comment above regarding the heap check (or lack thereof).
 
 \begin{code}
-
 gmpInteger2Int
 gmpInteger2Int
-    :: Target
-    -> CAddrMode           -- result
+    :: CAddrMode           -- result
     -> (CAddrMode, CAddrMode,CAddrMode,CAddrMode) -- alloc hp + argument (3 parts)
     -> UniqSM StixTreeList
 
     -> (CAddrMode, CAddrMode,CAddrMode,CAddrMode) -- alloc hp + argument (3 parts)
     -> UniqSM StixTreeList
 
-gmpInteger2Int target_STRICT res args@(chp, caa,csa,cda) =
-    let
-       a2stix  = amodeToStix target
-       data_hs = dataHS target
+gmpInteger2Int res args@(chp, caa,csa,cda)
+  = let
+       result  = amodeToStix res
+       hp      = amodeToStix chp
+       aa      = amodeToStix caa
+       sa      = amodeToStix csa
+       da      = amodeToStix cda
 
 
-       result  = a2stix res
-       hp      = a2stix chp
-       aa      = a2stix caa
-       sa      = a2stix csa
-       da      = a2stix cda
-
-       (a1,a2,a3) = toStruct data_hs hp (aa,sa,da)
+       (a1,a2,a3) = toStruct hp (aa,sa,da)
        mpz_get_si = StCall SLIT("mpz_get_si") IntRep [hp]
        r1 = StAssign IntRep result mpz_get_si
     in
        mpz_get_si = StCall SLIT("mpz_get_si") IntRep [hp]
        r1 = StAssign IntRep result mpz_get_si
     in
-       returnUs (\xs -> a1 : a2 : a3 : r1 : xs)
+    returnUs (\xs -> a1 : a2 : a3 : r1 : xs)
 
 arrayOfData_info = sStLitLbl SLIT("ArrayOfData_info")
 
 
 arrayOfData_info = sStLitLbl SLIT("ArrayOfData_info")
 
+--------------
 gmpInt2Integer
 gmpInt2Integer
-    :: Target
-    -> (CAddrMode, CAddrMode, CAddrMode) -- result (3 parts)
+    :: (CAddrMode, CAddrMode, CAddrMode) -- result (3 parts)
     -> (CAddrMode, CAddrMode)  -- allocated heap, Int to convert
     -> UniqSM StixTreeList
 
     -> (CAddrMode, CAddrMode)  -- allocated heap, Int to convert
     -> UniqSM StixTreeList
 
-gmpInt2Integer target_STRICT res@(car,csr,cdr) args@(chp, n) =
-    getUniqLabelNCG                    `thenUs` \ zlbl ->
+gmpInt2Integer res@(car,csr,cdr) args@(chp, n)
+  = getUniqLabelNCG                    `thenUs` \ zlbl ->
     getUniqLabelNCG                    `thenUs` \ nlbl ->
     getUniqLabelNCG                    `thenUs` \ jlbl ->
     let
     getUniqLabelNCG                    `thenUs` \ nlbl ->
     getUniqLabelNCG                    `thenUs` \ jlbl ->
     let
-       a2stix = amodeToStix target
-
-       ar  = a2stix car
-       sr  = a2stix csr
-       dr  = a2stix cdr
-       hp  = a2stix chp
-       i   = a2stix n
+       ar  = amodeToStix car
+       sr  = amodeToStix csr
+       dr  = amodeToStix cdr
+       hp  = amodeToStix chp
+       i   = amodeToStix n
 
        h1 = StAssign PtrRep (StInd PtrRep hp) arrayOfData_info
 
        h1 = StAssign PtrRep (StInd PtrRep hp) arrayOfData_info
-       size = varHeaderSize target (DataRep 0) + mIN_MP_INT_SIZE
+       size = varHdrSizeInWords (DataRep 0) + mIN_MP_INT_SIZE
        h2 = StAssign IntRep (StInd IntRep (StIndex IntRep hp (StInt 1)))
                              (StInt (toInteger size))
        h2 = StAssign IntRep (StInd IntRep (StIndex IntRep hp (StInt 1)))
                              (StInt (toInteger size))
-       cts = StInd IntRep (StIndex IntRep hp (dataHS target))
+       cts = StInd IntRep (StIndex IntRep hp dataHS)
        test1 = StPrim IntEqOp [i, StInt 0]
        test2 = StPrim IntLtOp [i, StInt 0]
        cjmp1 = StCondJump zlbl test1
        test1 = StPrim IntEqOp [i, StInt 0]
        test2 = StPrim IntLtOp [i, StInt 0]
        cjmp1 = StCondJump zlbl test1
@@ -280,84 +255,75 @@ gmpInt2Integer target_STRICT res@(car,csr,cdr) args@(chp, n) =
        a1 = StAssign IntRep ar (StInt 1)
        a2 = StAssign PtrRep dr hp
     in
        a1 = StAssign IntRep ar (StInt 1)
        a2 = StAssign PtrRep dr hp
     in
-       returnUs (\xs ->
-           case n of
-               CLit (MachInt c _) ->
-                   if c == 0 then     h1 : h2 : z1 : a1 : a2 : xs
-                   else if c > 0 then h1 : h2 : p1 : p2 : a1 : a2 : xs
-                   else               h1 : h2 : n1 : n2 : a1 : a2 : xs
-               _                ->    h1 : h2 : cjmp1 : cjmp2 : p1 : p2 : p3
-                                       : n0 : n1 : n2 : n3 : z0 : z1
-                                       : a0 : a1 : a2 : xs)
+    returnUs (\xs ->
+       case n of
+           CLit (MachInt c _) ->
+               if c == 0 then     h1 : h2 : z1 : a1 : a2 : xs
+               else if c > 0 then h1 : h2 : p1 : p2 : a1 : a2 : xs
+               else               h1 : h2 : n1 : n2 : a1 : a2 : xs
+           _                ->    h1 : h2 : cjmp1 : cjmp2 : p1 : p2 : p3
+                                     : n0 : n1 : n2 : n3 : z0 : z1
+                                     : a0 : a1 : a2 : xs)
 
 gmpString2Integer
 
 gmpString2Integer
-    :: Target
-    -> (CAddrMode, CAddrMode, CAddrMode)    -- result (3 parts)
+    :: (CAddrMode, CAddrMode, CAddrMode)    -- result (3 parts)
     -> (CAddrMode, CAddrMode)              -- liveness, string
     -> UniqSM StixTreeList
 
     -> (CAddrMode, CAddrMode)              -- liveness, string
     -> UniqSM StixTreeList
 
-gmpString2Integer target_STRICT res@(car,csr,cdr) (liveness, str) =
-    getUniqLabelNCG                                    `thenUs` \ ulbl ->
+gmpString2Integer res@(car,csr,cdr) (liveness, str)
+  = getUniqLabelNCG                                    `thenUs` \ ulbl ->
     let
     let
-       a2stix  = amodeToStix target
-       data_hs = dataHS target
-
-       ar = a2stix car
-       sr = a2stix csr
-       dr = a2stix cdr
+       ar = amodeToStix car
+       sr = amodeToStix csr
+       dr = amodeToStix cdr
 
        len = case str of
            (CString s) -> _LENGTH_ s
            (CLit (MachStr s)) -> _LENGTH_ s
            _ -> panic "String2Integer"
        space = len `quot` 8 + 17 + mpIntSize +
 
        len = case str of
            (CString s) -> _LENGTH_ s
            (CLit (MachStr s)) -> _LENGTH_ s
            _ -> panic "String2Integer"
        space = len `quot` 8 + 17 + mpIntSize +
-           varHeaderSize target (DataRep 0) + fixedHeaderSize target
+           varHdrSizeInWords (DataRep 0) + fixedHdrSizeInWords
        oldHp = StIndex PtrRep stgHp (StInt (toInteger (-space)))
        oldHp = StIndex PtrRep stgHp (StInt (toInteger (-space)))
-       safeHp = saveLoc target Hp
+       safeHp = saveLoc Hp
        save = StAssign PtrRep safeHp oldHp
        result = StIndex IntRep stgHpLim (StInt (toInteger (-mpIntSize)))
        set_str = StCall SLIT("mpz_init_set_str") IntRep
        save = StAssign PtrRep safeHp oldHp
        result = StIndex IntRep stgHpLim (StInt (toInteger (-mpIntSize)))
        set_str = StCall SLIT("mpz_init_set_str") IntRep
-           [result, a2stix str, StInt 10]
+           [result, amodeToStix str, StInt 10]
        test = StPrim IntEqOp [set_str, StInt 0]
        cjmp = StCondJump ulbl test
        abort = StCall SLIT("abort") VoidRep []
        join = StLabel ulbl
        restore = StAssign PtrRep stgHp safeHp
        test = StPrim IntEqOp [set_str, StInt 0]
        cjmp = StCondJump ulbl test
        abort = StCall SLIT("abort") VoidRep []
        join = StLabel ulbl
        restore = StAssign PtrRep stgHp safeHp
-       (a1,a2,a3) = fromStruct data_hs result (ar,sr,dr)
+       (a1,a2,a3) = fromStruct result (ar,sr,dr)
     in
     in
-       macroCode target HEAP_CHK [liveness, mkIntCLit space, mkIntCLit_0]
-                                                       `thenUs` \ heap_chk ->
+    macroCode HEAP_CHK [liveness, mkIntCLit space, mkIntCLit_0]
+                                                   `thenUs` \ heap_chk ->
 
 
-       returnUs (heap_chk .
-           (\xs -> save : cjmp : abort : join : a1 : a2 : a3 : restore : xs))
+    returnUs (heap_chk .
+       (\xs -> save : cjmp : abort : join : a1 : a2 : a3 : restore : xs))
 
 mkIntCLit_0 = mkIntCLit 0 -- out here to avoid CAF (sigh)
 
 encodeFloatingKind
     :: PrimRep
 
 mkIntCLit_0 = mkIntCLit 0 -- out here to avoid CAF (sigh)
 
 encodeFloatingKind
     :: PrimRep
-    -> Target
     -> CAddrMode       -- result
     -> (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
                -- heap pointer for result, integer argument (3 parts), exponent
     -> UniqSM StixTreeList
 
     -> CAddrMode       -- result
     -> (CAddrMode,CAddrMode,CAddrMode,CAddrMode,CAddrMode)
                -- heap pointer for result, integer argument (3 parts), exponent
     -> UniqSM StixTreeList
 
-encodeFloatingKind pk target_STRICT res args@(chp, caa,csa,cda, cexpon) =
-    let
-       a2stix  = amodeToStix target
-       size_of = sizeof target
-       data_hs = dataHS target
-
-       result  = a2stix res
-       hp      = a2stix chp
-       aa      = a2stix caa
-       sa      = a2stix csa
-       da      = a2stix cda
-       expon   = a2stix cexpon
-
-       pk' = if size_of FloatRep == size_of DoubleRep
+encodeFloatingKind pk res args@(chp, caa,csa,cda, cexpon)
+  = let
+       result  = amodeToStix res
+       hp      = amodeToStix chp
+       aa      = amodeToStix caa
+       sa      = amodeToStix csa
+       da      = amodeToStix cda
+       expon   = amodeToStix cexpon
+
+       pk' = if sizeOf FloatRep == sizeOf DoubleRep
              then DoubleRep
              else pk
              then DoubleRep
              else pk
-       (a1,a2,a3) = toStruct data_hs hp (aa,sa,da)
+       (a1,a2,a3) = toStruct hp (aa,sa,da)
        fn = case pk' of
            FloatRep -> SLIT("__encodeFloat")
            DoubleRep -> SLIT("__encodeDouble")
        fn = case pk' of
            FloatRep -> SLIT("__encodeFloat")
            DoubleRep -> SLIT("__encodeDouble")
@@ -365,31 +331,26 @@ encodeFloatingKind pk target_STRICT res args@(chp, caa,csa,cda, cexpon) =
        encode = StCall fn pk' [hp, expon]
        r1 = StAssign pk' result encode
     in
        encode = StCall fn pk' [hp, expon]
        r1 = StAssign pk' result encode
     in
-       returnUs (\xs -> a1 : a2 : a3 : r1 : xs)
+    returnUs (\xs -> a1 : a2 : a3 : r1 : xs)
 
 decodeFloatingKind
     :: PrimRep
 
 decodeFloatingKind
     :: PrimRep
-    -> Target
     -> (CAddrMode, CAddrMode, CAddrMode, CAddrMode)
                        -- exponent result, integer result (3 parts)
     -> (CAddrMode, CAddrMode)
                        -- heap pointer for exponent, floating argument
     -> UniqSM StixTreeList
 
     -> (CAddrMode, CAddrMode, CAddrMode, CAddrMode)
                        -- exponent result, integer result (3 parts)
     -> (CAddrMode, CAddrMode)
                        -- heap pointer for exponent, floating argument
     -> UniqSM StixTreeList
 
-decodeFloatingKind pk target_STRICT res@(cexponr,car,csr,cdr) args@(chp, carg) =
-    let
-       a2stix  = amodeToStix target
-       size_of = sizeof target
-       data_hs = dataHS target
-
-       exponr  = a2stix cexponr
-       ar      = a2stix car
-       sr      = a2stix csr
-       dr      = a2stix cdr
-       hp      = a2stix chp
-       arg     = a2stix carg
-
-       pk' = if size_of FloatRep == size_of DoubleRep
+decodeFloatingKind pk res@(cexponr,car,csr,cdr) args@(chp, carg)
+  = let
+       exponr  = amodeToStix cexponr
+       ar      = amodeToStix car
+       sr      = amodeToStix csr
+       dr      = amodeToStix cdr
+       hp      = amodeToStix chp
+       arg     = amodeToStix carg
+
+       pk' = if sizeOf FloatRep == sizeOf DoubleRep
              then DoubleRep
              else pk
        setup = StAssign PtrRep mpData_mantissa (StIndex IntRep hp (StInt 1))
              then DoubleRep
              else pk
        setup = StAssign PtrRep mpData_mantissa (StIndex IntRep hp (StInt 1))
@@ -398,10 +359,10 @@ decodeFloatingKind pk target_STRICT res@(cexponr,car,csr,cdr) args@(chp, carg) =
            DoubleRep -> SLIT("__decodeDouble")
            _ -> panic "decodeFloatingKind"
        decode = StCall fn VoidRep [mantissa, hp, arg]
            DoubleRep -> SLIT("__decodeDouble")
            _ -> panic "decodeFloatingKind"
        decode = StCall fn VoidRep [mantissa, hp, arg]
-       (a1,a2,a3) = fromStruct data_hs mantissa (ar,sr,dr)
+       (a1,a2,a3) = fromStruct mantissa (ar,sr,dr)
        a4 = StAssign IntRep exponr (StInd IntRep hp)
     in
        a4 = StAssign IntRep exponr (StInd IntRep hp)
     in
-       returnUs (\xs -> setup : decode : a1 : a2 : a3 : a4 : xs)
+    returnUs (\xs -> setup : decode : a1 : a2 : a3 : a4 : xs)
 
 mantissa = mpStruct 1 -- out here to avoid CAF (sigh)
 mpData_mantissa = mpData mantissa
 
 mantissa = mpStruct 1 -- out here to avoid CAF (sigh)
 mpData_mantissa = mpData mantissa
@@ -410,7 +371,6 @@ mpData_mantissa = mpData mantissa
 Support for the Gnu GMP multi-precision package.
 
 \begin{code}
 Support for the Gnu GMP multi-precision package.
 
 \begin{code}
-
 mpIntSize = 3 :: Int
 
 mpAlloc, mpSize, mpData :: StixTree -> StixTree
 mpIntSize = 3 :: Int
 
 mpAlloc, mpSize, mpData :: StixTree -> StixTree
@@ -419,57 +379,54 @@ mpSize base = StInd IntRep (StIndex IntRep base (StInt 1))
 mpData base = StInd PtrRep (StIndex IntRep base (StInt 2))
 
 mpSpace
 mpData base = StInd PtrRep (StIndex IntRep base (StInt 2))
 
 mpSpace
-    :: StixTree                -- dataHs from Target
-    -> Int             -- gmp structures needed
+    :: Int             -- gmp structures needed
     -> Int             -- number of results
     -> [StixTree]      -- sizes to add for estimating result size
     -> StixTree        -- total space
 
     -> Int             -- number of results
     -> [StixTree]      -- sizes to add for estimating result size
     -> StixTree        -- total space
 
-mpSpace data_hs gmp res sizes =
-    foldr sum (StPrim IntAddOp [fixed, hdrs]) sizes
+mpSpace gmp res sizes
+  = foldr sum (StPrim IntAddOp [fixed, hdrs]) sizes
   where
     sum x y = StPrim IntAddOp [StPrim IntAbsOp [x], y]
     fixed = StInt (toInteger (17 * res + gmp * mpIntSize))
   where
     sum x y = StPrim IntAddOp [StPrim IntAbsOp [x], y]
     fixed = StInt (toInteger (17 * res + gmp * mpIntSize))
-    hdrs = StPrim IntMulOp [data_hs, StInt (toInteger res)]
-
+    hdrs = StPrim IntMulOp [dataHS, StInt (toInteger res)]
 \end{code}
 
 \end{code}
 
-We don't have a truly portable way of allocating local temporaries, so we
-cheat and use space at the end of the heap.  (Thus, negative offsets from
-HpLim are our temporaries.)  Note that you must have performed a heap check
-which includes the space needed for these temporaries before you use them.
+We don't have a truly portable way of allocating local temporaries, so
+we cheat and use space at the end of the heap.  (Thus, negative
+offsets from HpLim are our temporaries.)  Note that you must have
+performed a heap check which includes the space needed for these
+temporaries before you use them.
 
 \begin{code}
 mpStruct :: Int -> StixTree
 mpStruct n = StIndex IntRep stgHpLim (StInt (toInteger (-(n * mpIntSize))))
 
 toStruct
 
 \begin{code}
 mpStruct :: Int -> StixTree
 mpStruct n = StIndex IntRep stgHpLim (StInt (toInteger (-(n * mpIntSize))))
 
 toStruct
-    :: StixTree                -- dataHS, from Target
-    -> StixTree
+    :: StixTree
     -> (StixTree, StixTree, StixTree)
     -> (StixTree, StixTree, StixTree)
 
     -> (StixTree, StixTree, StixTree)
     -> (StixTree, StixTree, StixTree)
 
-toStruct data_hs str (alloc,size,arr) =
-    let
+toStruct str (alloc,size,arr)
+  = let
        f1 = StAssign IntRep (mpAlloc str) alloc
        f2 = StAssign IntRep (mpSize str) size
        f1 = StAssign IntRep (mpAlloc str) alloc
        f2 = StAssign IntRep (mpSize str) size
-       f3 = StAssign PtrRep (mpData str) (StIndex PtrRep arr data_hs)
+       f3 = StAssign PtrRep (mpData str) (StIndex PtrRep arr dataHS)
     in
     in
-       (f1, f2, f3)
+    (f1, f2, f3)
 
 fromStruct
 
 fromStruct
-    :: StixTree                -- dataHS, from Target
-    -> StixTree
+    :: StixTree
     -> (StixTree, StixTree, StixTree)
     -> (StixTree, StixTree, StixTree)
 
     -> (StixTree, StixTree, StixTree)
     -> (StixTree, StixTree, StixTree)
 
-fromStruct data_hs str (alloc,size,arr) =
-    let
+fromStruct str (alloc,size,arr)
+  = let
        e1 = StAssign IntRep alloc (mpAlloc str)
        e2 = StAssign IntRep size (mpSize str)
        e3 = StAssign PtrRep arr (StIndex PtrRep (mpData str)
        e1 = StAssign IntRep alloc (mpAlloc str)
        e2 = StAssign IntRep size (mpSize str)
        e3 = StAssign PtrRep arr (StIndex PtrRep (mpData str)
-                                                  (StPrim IntNegOp [data_hs]))
+                                                (StPrim IntNegOp [dataHS]))
     in
     in
-       (e1, e2, e3)
+    (e1, e2, e3)
 \end{code}
 
 \end{code}
 
index b244110..4e7b47f 100644 (file)
@@ -1,27 +1,27 @@
 %
 %
-% (c) The AQUA Project, Glasgow University, 1993-1995
+% (c) The AQUA Project, Glasgow University, 1993-1996
 %
 
 \begin{code}
 #include "HsVersions.h"
 
 %
 
 \begin{code}
 #include "HsVersions.h"
 
-module StixMacro (
-       genMacroCode, doHeapCheck, smStablePtrTable,
+module StixMacro ( macroCode, heapCheck ) where
 
 
-       Target, StixTree, UniqSupply, CAddrMode, CExprMacro,
-       CStmtMacro
-    ) where
+import Ubiq{-uitious-}
+import NcgLoop         ( amodeToStix )
 
 
-import AbsCSyn
-import PrelInfo      ( PrimOp(..)
-                     IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                   )
-import MachDesc            {- lots -}
-import CgCompInfo   ( sTD_UF_SIZE, uF_RET, uF_SUA, uF_SUB, uF_UPDATEE )
+import MachMisc
+import MachRegs
+
+import AbsCSyn         ( CStmtMacro(..), MagicId(..), mkIntCLit, CAddrMode )
+import CgCompInfo      ( uF_RET, uF_SUA, uF_SUB, uF_UPDATEE,
+                         sTD_UF_SIZE
+                       )
+import OrdList         ( OrdList )
+import PrimOp          ( PrimOp(..) )
+import PrimRep         ( PrimRep(..) )
 import Stix
 import Stix
-import UniqSupply
-import Util
+import UniqSupply      ( returnUs, thenUs, UniqSM(..) )
 \end{code}
 
 The @ARGS_CHK_A{_LOAD_NODE}@ macros check for sufficient arguments on
 \end{code}
 
 The @ARGS_CHK_A{_LOAD_NODE}@ macros check for sufficient arguments on
@@ -33,43 +33,31 @@ closure address.
 mkIntCLit_0 = mkIntCLit 0 -- out here to avoid CAF (sigh)
 mkIntCLit_3 = mkIntCLit 3
 
 mkIntCLit_0 = mkIntCLit 0 -- out here to avoid CAF (sigh)
 mkIntCLit_3 = mkIntCLit 3
 
--- hacking with Uncle Will:
-#define target_STRICT target@(Target _ _ _ _ _ _ _ _)
-
-genMacroCode
-    :: Target
-    -> CStmtMacro          -- statement macro
+macroCode
+    :: CStmtMacro          -- statement macro
     -> [CAddrMode]         -- args
     -> UniqSM StixTreeList
 
     -> [CAddrMode]         -- args
     -> UniqSM StixTreeList
 
-genMacroCode target_STRICT macro args
- = genmacro macro args
- where
-  a2stix  = amodeToStix target
-  stg_reg = stgReg target
-
-  -- real thing: here we go -----------------------
-
-  genmacro ARGS_CHK_A_LOAD_NODE args =
-    getUniqLabelNCG                                    `thenUs` \ ulbl ->
-    let [words, lbl] = map a2stix args
-       temp = StIndex PtrRep stgSpA words
-       test = StPrim AddrGeOp [stgSuA, temp]
-       cjmp = StCondJump ulbl test
-       assign = StAssign PtrRep stgNode lbl
-       join = StLabel ulbl
+macroCode ARGS_CHK_A_LOAD_NODE args
+  = getUniqLabelNCG                                    `thenUs` \ ulbl ->
+    let
+         [words, lbl] = map amodeToStix args
+         temp = StIndex PtrRep stgSpA words
+         test = StPrim AddrGeOp [stgSuA, temp]
+         cjmp = StCondJump ulbl test
+         assign = StAssign PtrRep stgNode lbl
+         join = StLabel ulbl
     in
     in
-       returnUs (\xs -> cjmp : assign : updatePAP : join : xs)
+    returnUs (\xs -> cjmp : assign : updatePAP : join : xs)
 
 
-  genmacro ARGS_CHK_A [words] =
-    getUniqLabelNCG                                    `thenUs` \ ulbl ->
-    let temp = StIndex PtrRep stgSpA (a2stix words)
+macroCode ARGS_CHK_A [words]
+  = getUniqLabelNCG                                    `thenUs` \ ulbl ->
+    let temp = StIndex PtrRep stgSpA (amodeToStix words)
        test = StPrim AddrGeOp [stgSuA, temp]
        cjmp = StCondJump ulbl test
        join = StLabel ulbl
     in
        test = StPrim AddrGeOp [stgSuA, temp]
        cjmp = StCondJump ulbl test
        join = StLabel ulbl
     in
-       returnUs (\xs -> cjmp : updatePAP : join : xs)
-
+    returnUs (\xs -> cjmp : updatePAP : join : xs)
 \end{code}
 
 Like the macros above, the @ARGS_CHK_B{_LOAD_NODE}@ macros check for
 \end{code}
 
 Like the macros above, the @ARGS_CHK_B{_LOAD_NODE}@ macros check for
@@ -79,43 +67,43 @@ also loads R1 with an appropriate closure address.  Note that the
 directions are swapped relative to the A stack.
 
 \begin{code}
 directions are swapped relative to the A stack.
 
 \begin{code}
-
-  genmacro ARGS_CHK_B_LOAD_NODE args =
-    getUniqLabelNCG                                    `thenUs` \ ulbl ->
-    let [words, lbl] = map a2stix args
+macroCode ARGS_CHK_B_LOAD_NODE args
+  = getUniqLabelNCG                                    `thenUs` \ ulbl ->
+    let
+       [words, lbl] = map amodeToStix args
        temp = StIndex PtrRep stgSuB (StPrim IntNegOp [words])
        test = StPrim AddrGeOp [stgSpB, temp]
        cjmp = StCondJump ulbl test
        assign = StAssign PtrRep stgNode lbl
        join = StLabel ulbl
     in
        temp = StIndex PtrRep stgSuB (StPrim IntNegOp [words])
        test = StPrim AddrGeOp [stgSpB, temp]
        cjmp = StCondJump ulbl test
        assign = StAssign PtrRep stgNode lbl
        join = StLabel ulbl
     in
-       returnUs (\xs -> cjmp : assign : updatePAP : join : xs)
+    returnUs (\xs -> cjmp : assign : updatePAP : join : xs)
 
 
-  genmacro ARGS_CHK_B [words] =
-    getUniqLabelNCG                                    `thenUs` \ ulbl ->
-    let        temp = StIndex PtrRep stgSuB (StPrim IntNegOp [a2stix words])
+macroCode ARGS_CHK_B [words]
+  = getUniqLabelNCG                                    `thenUs` \ ulbl ->
+    let
+       temp = StIndex PtrRep stgSuB (StPrim IntNegOp [amodeToStix words])
        test = StPrim AddrGeOp [stgSpB, temp]
        cjmp = StCondJump ulbl test
        join = StLabel ulbl
     in
        test = StPrim AddrGeOp [stgSpB, temp]
        cjmp = StCondJump ulbl test
        join = StLabel ulbl
     in
-       returnUs (\xs -> cjmp : updatePAP : join : xs)
-
+    returnUs (\xs -> cjmp : updatePAP : join : xs)
 \end{code}
 
 The @HEAP_CHK@ macro checks to see that there are enough words
 available in the heap (before reaching @HpLim@).  When a heap check
 fails, it has to call @PerformGC@ via the @PerformGC_wrapper@.  The
 \end{code}
 
 The @HEAP_CHK@ macro checks to see that there are enough words
 available in the heap (before reaching @HpLim@).  When a heap check
 fails, it has to call @PerformGC@ via the @PerformGC_wrapper@.  The
-call wrapper saves all of our volatile registers so that we don't have to.
+call wrapper saves all of our volatile registers so that we don't have
+to.
 
 
-Since there are @HEAP_CHK@s buried at unfortunate places in the integer
-primOps, this is just a wrapper.
+Since there are @HEAP_CHK@s buried at unfortunate places in the
+integer primOps, this is just a wrapper.
 
 \begin{code}
 
 \begin{code}
-
-  genmacro HEAP_CHK args =
-    let [liveness,words,reenter] = map a2stix args
+macroCode HEAP_CHK args
+  = let [liveness,words,reenter] = map amodeToStix args
     in
     in
-       doHeapCheck liveness words reenter
+    heapCheck liveness words reenter
 \end{code}
 
 The @STK_CHK@ macro checks for enough space on the stack between @SpA@
 \end{code}
 
 The @STK_CHK@ macro checks for enough space on the stack between @SpA@
@@ -125,12 +113,12 @@ enough space to continue.  Not that @_StackOverflow@ doesn't return,
 so we don't have to @callWrapper@ it.
 
 \begin{code}
 so we don't have to @callWrapper@ it.
 
 \begin{code}
-
-  genmacro STK_CHK [liveness, aWords, bWords, spa, spb, prim, reenter] =
+macroCode STK_CHK [liveness, aWords, bWords, spa, spb, prim, reenter]
+  =
 {- Need to check to see if we are compiling with stack checks
 {- Need to check to see if we are compiling with stack checks
-    getUniqLabelNCG                                    `thenUs` \ ulbl ->
+   getUniqLabelNCG                                     `thenUs` \ ulbl ->
     let words = StPrim IntNegOp
     let words = StPrim IntNegOp
-           [StPrim IntAddOp [a2stix aWords, a2stix bWords]]
+           [StPrim IntAddOp [amodeToStix aWords, amodeToStix bWords]]
        temp = StIndex PtrRep stgSpA words
        test = StPrim AddrGtOp [temp, stgSpB]
        cjmp = StCondJump ulbl test
        temp = StIndex PtrRep stgSpA words
        test = StPrim AddrGtOp [temp, stgSpB]
        cjmp = StCondJump ulbl test
@@ -139,16 +127,16 @@ so we don't have to @callWrapper@ it.
        returnUs (\xs -> cjmp : stackOverflow : join : xs)
 -}
     returnUs id
        returnUs (\xs -> cjmp : stackOverflow : join : xs)
 -}
     returnUs id
-
 \end{code}
 
 \end{code}
 
-@UPD_CAF@ involves changing the info pointer of the closure, adding an indirection,
-and putting the new CAF on a linked list for the storage manager.
+@UPD_CAF@ involves changing the info pointer of the closure, adding an
+indirection, and putting the new CAF on a linked list for the storage
+manager.
 
 \begin{code}
 
 \begin{code}
-
-  genmacro UPD_CAF args =
-    let [cafptr,bhptr] = map a2stix args
+macroCode UPD_CAF args
+  = let
+       [cafptr,bhptr] = map amodeToStix args
        w0 = StInd PtrRep cafptr
        w1 = StInd PtrRep (StIndex PtrRep cafptr (StInt 1))
        w2 = StInd PtrRep (StIndex PtrRep cafptr (StInt 2))
        w0 = StInd PtrRep cafptr
        w1 = StInd PtrRep (StIndex PtrRep cafptr (StInt 1))
        w2 = StInd PtrRep (StIndex PtrRep cafptr (StInt 2))
@@ -157,8 +145,7 @@ and putting the new CAF on a linked list for the storage manager.
        a3 = StAssign PtrRep w2 bhptr
        a4 = StAssign PtrRep smCAFlist cafptr
     in
        a3 = StAssign PtrRep w2 bhptr
        a4 = StAssign PtrRep smCAFlist cafptr
     in
-       returnUs (\xs -> a1 : a2 : a3 : a4 : xs)
-
+    returnUs (\xs -> a1 : a2 : a3 : a4 : xs)
 \end{code}
 
 @UPD_IND@ is complicated by the fact that we are supporting the
 \end{code}
 
 @UPD_IND@ is complicated by the fact that we are supporting the
@@ -166,10 +153,10 @@ Appel-style garbage collector by default.  This means some extra work
 if we update an old generation object.
 
 \begin{code}
 if we update an old generation object.
 
 \begin{code}
-
-  genmacro UPD_IND args =
-    getUniqLabelNCG                                    `thenUs` \ ulbl ->
-    let [updptr, heapptr] = map a2stix args
+macroCode UPD_IND args
+  = getUniqLabelNCG                                    `thenUs` \ ulbl ->
+    let
+       [updptr, heapptr] = map amodeToStix args
        test = StPrim AddrGtOp [updptr, smOldLim]
        cjmp = StCondJump ulbl test
        updRoots = StAssign PtrRep smOldMutables updptr
        test = StPrim AddrGtOp [updptr, smOldLim]
        cjmp = StCondJump ulbl test
        updRoots = StAssign PtrRep smOldMutables updptr
@@ -180,26 +167,22 @@ if we update an old generation object.
        upd2 = StAssign PtrRep (StInd PtrRep
                (StIndex PtrRep updptr (StInt 2))) heapptr
     in
        upd2 = StAssign PtrRep (StInd PtrRep
                (StIndex PtrRep updptr (StInt 2))) heapptr
     in
-       returnUs (\xs -> cjmp : upd1 : updRoots : join : upd0 : upd2 : xs)
-
+    returnUs (\xs -> cjmp : upd1 : updRoots : join : upd0 : upd2 : xs)
 \end{code}
 
 @UPD_INPLACE_NOPTRS@ is only needed for ticky-ticky profiling.
 
 \begin{code}
 \end{code}
 
 @UPD_INPLACE_NOPTRS@ is only needed for ticky-ticky profiling.
 
 \begin{code}
-
-  genmacro UPD_INPLACE_NOPTRS args = returnUs id
-
+macroCode UPD_INPLACE_NOPTRS args = returnUs id
 \end{code}
 
 @UPD_INPLACE_PTRS@ is complicated by the fact that we are supporting
 \end{code}
 
 @UPD_INPLACE_PTRS@ is complicated by the fact that we are supporting
-the Appel-style garbage collector by default.  This means some extra work
-if we update an old generation object.
+the Appel-style garbage collector by default.  This means some extra
+work if we update an old generation object.
 
 \begin{code}
 
 \begin{code}
-
-  genmacro UPD_INPLACE_PTRS [liveness] =
-    getUniqLabelNCG                                    `thenUs` \ ulbl ->
+macroCode UPD_INPLACE_PTRS [liveness]
+  = getUniqLabelNCG                                    `thenUs` \ ulbl ->
     let cjmp = StCondJump ulbl testOldLim
        testOldLim = StPrim AddrGtOp [stgNode, smOldLim]
        join = StLabel ulbl
     let cjmp = StCondJump ulbl testOldLim
        testOldLim = StPrim AddrGtOp [stgNode, smOldLim]
        join = StLabel ulbl
@@ -212,12 +195,11 @@ if we update an old generation object.
        updOldMutables = StAssign PtrRep smOldMutables stgNode
        updUpdReg = StAssign PtrRep stgNode hpBack2
     in
        updOldMutables = StAssign PtrRep smOldMutables stgNode
        updUpdReg = StAssign PtrRep stgNode hpBack2
     in
-       genmacro HEAP_CHK [liveness, mkIntCLit_3, mkIntCLit_0]
-                                                       `thenUs` \ heap_chk ->
-       returnUs (\xs -> (cjmp :
-                           heap_chk (updUpd0 : updUpd1 : updUpd2 :
-                                       updOldMutables : updUpdReg : join : xs)))
-
+    macroCode HEAP_CHK [liveness, mkIntCLit_3, mkIntCLit_0]
+                                                   `thenUs` \ heap_chk ->
+    returnUs (\xs -> (cjmp :
+                       heap_chk (updUpd0 : updUpd1 : updUpd2 :
+                                   updOldMutables : updUpdReg : join : xs)))
 \end{code}
 
 @UPD_BH_UPDATABLE@ is only used when running concurrent threads (in
 \end{code}
 
 @UPD_BH_UPDATABLE@ is only used when running concurrent threads (in
@@ -225,24 +207,22 @@ the sequential case, the GC takes care of this).  However, we do need
 to handle @UPD_BH_SINGLE_ENTRY@ in all cases.
 
 \begin{code}
 to handle @UPD_BH_SINGLE_ENTRY@ in all cases.
 
 \begin{code}
+macroCode UPD_BH_UPDATABLE args = returnUs id
 
 
-  genmacro UPD_BH_UPDATABLE args = returnUs id
-
-  genmacro UPD_BH_SINGLE_ENTRY [arg] =
-    let
-       update = StAssign PtrRep (StInd PtrRep (a2stix arg)) bh_info
+macroCode UPD_BH_SINGLE_ENTRY [arg]
+  = let
+       update = StAssign PtrRep (StInd PtrRep (amodeToStix arg)) bh_info
     in
     in
-       returnUs (\xs -> update : xs)
-
+    returnUs (\xs -> update : xs)
 \end{code}
 
 Push a four word update frame on the stack and slide the Su[AB]
 registers to the current Sp[AB] locations.
 
 \begin{code}
 \end{code}
 
 Push a four word update frame on the stack and slide the Su[AB]
 registers to the current Sp[AB] locations.
 
 \begin{code}
-
-  genmacro PUSH_STD_UPD_FRAME args =
-    let [bhptr, aWords, bWords] = map a2stix args
+macroCode PUSH_STD_UPD_FRAME args
+  = let
+       [bhptr, aWords, bWords] = map amodeToStix args
        frame n = StInd PtrRep
            (StIndex PtrRep stgSpB (StPrim IntAddOp
                [bWords, StInt (toInteger (sTD_UF_SIZE - n))]))
        frame n = StInd PtrRep
            (StIndex PtrRep stgSpB (StPrim IntAddOp
                [bWords, StInt (toInteger (sTD_UF_SIZE - n))]))
@@ -258,16 +238,15 @@ registers to the current Sp[AB] locations.
        updSuA = StAssign PtrRep
            stgSuA (StIndex PtrRep stgSpA (StPrim IntNegOp [aWords]))
     in
        updSuA = StAssign PtrRep
            stgSuA (StIndex PtrRep stgSpA (StPrim IntNegOp [aWords]))
     in
-       returnUs (\xs -> a1 : a2 : a3 : a4 : updSuB : updSuA : xs)
-
+    returnUs (\xs -> a1 : a2 : a3 : a4 : updSuB : updSuA : xs)
 \end{code}
 
 Pop a standard update frame.
 
 \begin{code}
 \end{code}
 
 Pop a standard update frame.
 
 \begin{code}
-
-  genmacro POP_STD_UPD_FRAME args =
-    let frame n = StInd PtrRep (StIndex PtrRep stgSpB (StInt (toInteger (-n))))
+macroCode POP_STD_UPD_FRAME args
+  = let
+       frame n = StInd PtrRep (StIndex PtrRep stgSpB (StInt (toInteger (-n))))
 
        grabRet = StAssign PtrRep stgRetReg (frame uF_RET)
        grabSuB = StAssign PtrRep stgSuB    (frame uF_SUB)
 
        grabRet = StAssign PtrRep stgRetReg (frame uF_RET)
        grabSuB = StAssign PtrRep stgSuB    (frame uF_SUB)
@@ -276,41 +255,38 @@ Pop a standard update frame.
        updSpB = StAssign PtrRep
            stgSpB (StIndex PtrRep stgSpB (StInt (toInteger (-sTD_UF_SIZE))))
     in
        updSpB = StAssign PtrRep
            stgSpB (StIndex PtrRep stgSpB (StInt (toInteger (-sTD_UF_SIZE))))
     in
-       returnUs (\xs -> grabRet : grabSuB : grabSuA : updSpB : xs)
-
+    returnUs (\xs -> grabRet : grabSuB : grabSuA : updSpB : xs)
 \end{code}
 
 The @SET_ARITY@ and @CHK_ARITY@ macros are disabled for ``normal''
 compilation.
 \begin{code}
 \end{code}
 
 The @SET_ARITY@ and @CHK_ARITY@ macros are disabled for ``normal''
 compilation.
 \begin{code}
-  genmacro SET_ARITY args = returnUs id
-  genmacro CHK_ARITY args = returnUs id
+macroCode SET_ARITY args = returnUs id
+macroCode CHK_ARITY args = returnUs id
 \end{code}
 
 This one only applies if we have a machine register devoted to TagReg.
 \begin{code}
 \end{code}
 
 This one only applies if we have a machine register devoted to TagReg.
 \begin{code}
-  genmacro SET_TAG [tag] =
-    let set_tag = StAssign IntRep stgTagReg (a2stix tag)
+macroCode SET_TAG [tag]
+  = let set_tag = StAssign IntRep stgTagReg (amodeToStix tag)
     in
     in
-       case stg_reg TagReg of
-           Always _ -> returnUs id
-           Save   _ -> returnUs (\ xs -> set_tag : xs)
+    case stgReg TagReg of
+      Always _ -> returnUs id
+      Save   _ -> returnUs (\ xs -> set_tag : xs)
 \end{code}
 
 Do the business for a @HEAP_CHK@, having converted the args to Trees
 of StixOp.
 
 \begin{code}
 \end{code}
 
 Do the business for a @HEAP_CHK@, having converted the args to Trees
 of StixOp.
 
 \begin{code}
-
-doHeapCheck
-    :: {- unused now: Target
-    -> -}StixTree      -- liveness
+heapCheck
+    :: StixTree        -- liveness
     -> StixTree        -- words needed
     -> StixTree        -- always reenter node? (boolean)
     -> UniqSM StixTreeList
 
     -> StixTree        -- words needed
     -> StixTree        -- always reenter node? (boolean)
     -> UniqSM StixTreeList
 
-doHeapCheck {-target:unused now-} liveness words reenter =
-    getUniqLabelNCG                                    `thenUs` \ ulbl ->
+heapCheck liveness words reenter
+  = getUniqLabelNCG                                    `thenUs` \ ulbl ->
     let newHp = StIndex PtrRep stgHp words
        assign = StAssign PtrRep stgHp newHp
        test = StPrim AddrLeOp [stgHp, stgHpLim]
     let newHp = StIndex PtrRep stgHp words
        assign = StAssign PtrRep stgHp newHp
        test = StPrim AddrLeOp [stgHp, stgHpLim]
@@ -320,14 +296,12 @@ doHeapCheck {-target:unused now-} liveness words reenter =
        gc = StCall SLIT("PerformGC_wrapper") VoidRep [arg]
        join = StLabel ulbl
     in
        gc = StCall SLIT("PerformGC_wrapper") VoidRep [arg]
        join = StLabel ulbl
     in
-       returnUs (\xs -> assign : cjmp : gc : join : xs)
-
+    returnUs (\xs -> assign : cjmp : gc : join : xs)
 \end{code}
 
 Let's make sure that these CAFs are lifted out, shall we?
 
 \begin{code}
 \end{code}
 
 Let's make sure that these CAFs are lifted out, shall we?
 
 \begin{code}
-
 -- Some common labels
 
 bh_info, caf_info, ind_info :: StixTree
 -- Some common labels
 
 bh_info, caf_info, ind_info :: StixTree
@@ -342,34 +316,4 @@ updatePAP, stackOverflow :: StixTree
 
 updatePAP     = StJump (sStLitLbl SLIT("UpdatePAP"))
 stackOverflow = StCall SLIT("StackOverflow") VoidRep []
 
 updatePAP     = StJump (sStLitLbl SLIT("UpdatePAP"))
 stackOverflow = StCall SLIT("StackOverflow") VoidRep []
-
-\end{code}
-
-Storage manager nonsense.  Note that the indices are dependent on
-the definition of the smInfo structure in SMinterface.lh
-
-\begin{code}
-
-#include "../../includes/platform.h"
-
-#if alpha_TARGET_ARCH
-#include "../../includes/alpha-dec-osf1.h"
-#else
-#if sunos4_TARGET_OS
-#include "../../includes/sparc-sun-sunos4.h"
-#else
-#include "../../includes/sparc-sun-solaris2.h"
-#endif
-#endif
-
-storageMgrInfo, smCAFlist, smOldMutables, smOldLim :: StixTree
-
-storageMgrInfo = sStLitLbl SLIT("StorageMgrInfo")
-smCAFlist  = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_CAFLIST))
-smOldMutables = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_OLDMUTABLES))
-smOldLim   = StInd PtrRep (StIndex PtrRep storageMgrInfo (StInt SM_OLDLIM))
-
-smStablePtrTable = StInd PtrRep
-                        (StIndex PtrRep storageMgrInfo (StInt SM_STABLEPOINTERTABLE))
-
 \end{code}
 \end{code}
index e566c7b..d8e1bf6 100644 (file)
 %
 %
-% (c) The AQUA Project, Glasgow University, 1993-1995
+% (c) The AQUA Project, Glasgow University, 1993-1996
 %
 
 \begin{code}
 #include "HsVersions.h"
 
 %
 
 \begin{code}
 #include "HsVersions.h"
 
-module StixPrim (
-       genPrimCode, amodeCode, amodeCode',
+module StixPrim ( primCode, amodeToStix, amodeToStix' ) where
 
 
-       Target, CAddrMode, StixTree, PrimOp, UniqSupply
-    ) where
+import Ubiq{-uitous-}
+import NcgLoop         -- paranoia checking only
 
 
-IMPORT_Trace   -- ToDo: rm debugging
+import MachMisc
+import MachRegs
 
 import AbsCSyn
 
 import AbsCSyn
-import PrelInfo                ( PrimOp(..), PrimOpResultInfo(..), TyCon,
-                         getPrimOpResultInfo, isCompareOp, showPrimOp
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                       )
+import AbsCUtils       ( getAmodeRep, mixedTypeLocn )
 import CgCompInfo      ( spARelToInt, spBRelToInt )
 import CgCompInfo      ( spARelToInt, spBRelToInt )
-import MachDesc
-import Pretty
-import PrimRep         ( isFloatingRep )
-import CostCentre
-import SMRep           ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
+import CostCentre      ( noCostCentreAttached )
+import HeapOffs                ( hpRelToInt, subOff )
+import Literal         ( Literal(..) )
+import PrimOp          ( PrimOp(..), isCompareOp, showPrimOp,
+                         getPrimOpResultInfo, PrimOpResultInfo(..)
+                       )
+import PrimRep         ( PrimRep(..), isFloatingRep )
+import OrdList         ( OrdList )
+import PprStyle                ( PprStyle(..) )
+import SMRep           ( SMRep(..), SMSpecRepKind, SMUpdateKind )
 import Stix
 import Stix
-import StixMacro       ( smStablePtrTable )
+import StixMacro       ( heapCheck, smStablePtrTable )
 import StixInteger     {- everything -}
 import StixInteger     {- everything -}
-import UniqSupply
-import Unpretty
-import Util
-
+import UniqSupply      ( returnUs, thenUs, UniqSM(..) )
+import Unpretty                ( uppBeside, uppPStr, uppInt )
+import Util            ( panic )
 \end{code}
 
 \end{code}
 
-The main honcho here is genPrimCode, which handles the guts of COpStmts.
+The main honcho here is primCode, which handles the guts of COpStmts.
 
 \begin{code}
 arrayOfData_info      = sStLitLbl SLIT("ArrayOfData_info") -- out here to avoid CAF (sigh)
 imMutArrayOfPtrs_info = sStLitLbl SLIT("ImMutArrayOfPtrs_info")
 
 
 \begin{code}
 arrayOfData_info      = sStLitLbl SLIT("ArrayOfData_info") -- out here to avoid CAF (sigh)
 imMutArrayOfPtrs_info = sStLitLbl SLIT("ImMutArrayOfPtrs_info")
 
-genPrimCode
-    :: Target
-    -> [CAddrMode]     -- results
+primCode
+    :: [CAddrMode]     -- results
     -> PrimOp          -- op
     -> [CAddrMode]     -- args
     -> UniqSM StixTreeList
     -> PrimOp          -- op
     -> [CAddrMode]     -- args
     -> UniqSM StixTreeList
-
 \end{code}
 
 First, the dreaded @ccall@.  We can't handle @casm@s.
 
 \end{code}
 
 First, the dreaded @ccall@.  We can't handle @casm@s.
 
-Usually, this compiles to an assignment, but when the left-hand side is
-empty, we just perform the call and ignore the result.
+Usually, this compiles to an assignment, but when the left-hand side
+is empty, we just perform the call and ignore the result.
 
 ToDo ADR: modify this to handle Malloc Ptrs.
 
 btw Why not let programmer use casm to provide assembly code instead
 of C code?  ADR
 
 
 ToDo ADR: modify this to handle Malloc Ptrs.
 
 btw Why not let programmer use casm to provide assembly code instead
 of C code?  ADR
 
-\begin{code}
--- hacking with Uncle Will:
-#define target_STRICT target@(Target _ _ _ _ _ _ _ _)
-
-genPrimCode target_STRICT res op args
- = genprim res op args
- where
-  a2stix    = amodeToStix target
-  a2stix'   = amodeToStix' target
-  mut_hs    = mutHS target
-  data_hs   = dataHS target
-  heap_chkr = heapCheck target
-  size_of   = sizeof target
-  fixed_hs  = fixedHeaderSize target
-  var_hs    = varHeaderSize target
-
-  --- real code will follow... -------------
-\end{code}
-
-The (MP) integer operations are a true nightmare.  Since we don't have a
-convenient abstract way of allocating temporary variables on the (C) stack,
-we use the space just below HpLim for the @MP_INT@ structures, and modify our
-heap check accordingly.
+The (MP) integer operations are a true nightmare.  Since we don't have
+a convenient abstract way of allocating temporary variables on the (C)
+stack, we use the space just below HpLim for the @MP_INT@ structures,
+and modify our heap check accordingly.
 
 \begin{code}
 
 \begin{code}
-  -- NB: ordering of clauses somewhere driven by
-  -- the desire to getting sane patt-matching behavior
-
-  genprim res@[ar1,sr1,dr1, ar2,sr2,dr2]
-         IntegerQuotRemOp
-         args@[liveness, aa1,sa1,da1, aa2,sa2,da2] =
-    gmpTake2Return2 target (ar1,sr1,dr1, ar2,sr2,dr2) SLIT("mpz_divmod") (liveness, aa1,sa1,da1, aa2,sa2,da2)
-
-  genprim res@[ar1,sr1,dr1, ar2,sr2,dr2]
-         IntegerDivModOp
-         args@[liveness, aa1,sa1,da1, aa2,sa2,da2] =
-    gmpTake2Return2 target (ar1,sr1,dr1, ar2,sr2,dr2) SLIT("mpz_targetivmod") (liveness, aa1,sa1,da1, aa2,sa2,da2)
-
-  genprim res@[ar,sr,dr] IntegerAddOp args@[liveness, aa1,sa1,da1, aa2,sa2,da2] =
-    gmpTake2Return1 target (ar,sr,dr) SLIT("mpz_add") (liveness, aa1,sa1,da1, aa2,sa2,da2)
-  genprim res@[ar,sr,dr] IntegerSubOp args@[liveness, aa1,sa1,da1, aa2,sa2,da2] =
-    gmpTake2Return1 target (ar,sr,dr) SLIT("mpz_sub") (liveness, aa1,sa1,da1, aa2,sa2,da2)
-  genprim res@[ar,sr,dr] IntegerMulOp args@[liveness, aa1,sa1,da1, aa2,sa2,da2] =
-    gmpTake2Return1 target (ar,sr,dr) SLIT("mpz_mul") (liveness, aa1,sa1,da1, aa2,sa2,da2)
-
-  genprim res@[ar,sr,dr] IntegerNegOp arg@[liveness,aa,sa,da] =
-    gmpTake1Return1 target (ar,sr,dr) SLIT("mpz_neg") (liveness,aa,sa,da)
+-- NB: ordering of clauses somewhere driven by
+-- the desire to getting sane patt-matching behavior
+
+primCode res@[ar1,sr1,dr1, ar2,sr2,dr2]
+        IntegerQuotRemOp
+        args@[liveness, aa1,sa1,da1, aa2,sa2,da2]
+  = gmpTake2Return2 (ar1,sr1,dr1, ar2,sr2,dr2) SLIT("mpz_divmod") (liveness, aa1,sa1,da1, aa2,sa2,da2)
+
+primCode res@[ar1,sr1,dr1, ar2,sr2,dr2]
+        IntegerDivModOp
+        args@[liveness, aa1,sa1,da1, aa2,sa2,da2]
+  = gmpTake2Return2 (ar1,sr1,dr1, ar2,sr2,dr2) SLIT("mpz_targetivmod") (liveness, aa1,sa1,da1, aa2,sa2,da2)
+
+primCode res@[ar,sr,dr] IntegerAddOp args@[liveness, aa1,sa1,da1, aa2,sa2,da2]
+  = gmpTake2Return1 (ar,sr,dr) SLIT("mpz_add") (liveness, aa1,sa1,da1, aa2,sa2,da2)
+primCode res@[ar,sr,dr] IntegerSubOp args@[liveness, aa1,sa1,da1, aa2,sa2,da2]
+  = gmpTake2Return1 (ar,sr,dr) SLIT("mpz_sub") (liveness, aa1,sa1,da1, aa2,sa2,da2)
+primCode res@[ar,sr,dr] IntegerMulOp args@[liveness, aa1,sa1,da1, aa2,sa2,da2]
+  = gmpTake2Return1 (ar,sr,dr) SLIT("mpz_mul") (liveness, aa1,sa1,da1, aa2,sa2,da2)
+
+primCode res@[ar,sr,dr] IntegerNegOp arg@[liveness,aa,sa,da]
+  = gmpTake1Return1 (ar,sr,dr) SLIT("mpz_neg") (liveness,aa,sa,da)
 \end{code}
 
 \end{code}
 
-Since we are using the heap for intermediate @MP_INT@ structs, integer comparison
-{\em does} require a heap check in the native code implementation.
+Since we are using the heap for intermediate @MP_INT@ structs, integer
+comparison {\em does} require a heap check in the native code
+implementation.
 
 \begin{code}
 
 \begin{code}
-  genprim res@[exponr,ar,sr,dr] FloatDecodeOp args@[hp, arg] =
-    decodeFloatingKind FloatRep target (exponr,ar,sr,dr) (hp, arg)
-
-  genprim res@[exponr,ar,sr,dr] DoubleDecodeOp args@[hp, arg] =
-    decodeFloatingKind DoubleRep target (exponr,ar,sr,dr) (hp, arg)
+primCode res@[exponr,ar,sr,dr] FloatDecodeOp args@[hp, arg]
+  = decodeFloatingKind FloatRep (exponr,ar,sr,dr) (hp, arg)
 
 
-  genprim res@[ar,sr,dr] Int2IntegerOp args@[hp, n]
-    = gmpInt2Integer target (ar,sr,dr) (hp, n)
+primCode res@[exponr,ar,sr,dr] DoubleDecodeOp args@[hp, arg]
+  = decodeFloatingKind DoubleRep (exponr,ar,sr,dr) (hp, arg)
 
 
-  genprim res@[ar,sr,dr] Addr2IntegerOp args@[liveness,str]
-    = gmpString2Integer target (ar,sr,dr) (liveness,str)
+primCode res@[ar,sr,dr] Int2IntegerOp args@[hp, n]
+  = gmpInt2Integer (ar,sr,dr) (hp, n)
 
 
-  genprim [res] IntegerCmpOp args@[hp, aa1,sa1,da1, aa2,sa2,da2]
-    = gmpCompare target res (hp, aa1,sa1,da1, aa2,sa2,da2)
+primCode res@[ar,sr,dr] Addr2IntegerOp args@[liveness,str]
+  = gmpString2Integer (ar,sr,dr) (liveness,str)
 
 
-  genprim [res] Integer2IntOp arg@[hp, aa,sa,da]
-    = gmpInteger2Int target res (hp, aa,sa,da)
+primCode [res] IntegerCmpOp args@[hp, aa1,sa1,da1, aa2,sa2,da2]
+  = gmpCompare res (hp, aa1,sa1,da1, aa2,sa2,da2)
 
 
-  genprim [res] FloatEncodeOp args@[hp, aa,sa,da, expon] =
-    encodeFloatingKind FloatRep target res (hp, aa,sa,da, expon)
+primCode [res] Integer2IntOp arg@[hp, aa,sa,da]
+  = gmpInteger2Int res (hp, aa,sa,da)
 
 
-  genprim [res] DoubleEncodeOp args@[hp, aa,sa,da, expon] =
-    encodeFloatingKind DoubleRep target res (hp, aa,sa,da, expon)
+primCode [res] FloatEncodeOp args@[hp, aa,sa,da, expon]
+  = encodeFloatingKind FloatRep res (hp, aa,sa,da, expon)
 
 
-  genprim [res] Int2AddrOp [arg] =
-    simpleCoercion AddrRep res arg
+primCode [res] DoubleEncodeOp args@[hp, aa,sa,da, expon]
+  = encodeFloatingKind DoubleRep res (hp, aa,sa,da, expon)
 
 
-  genprim [res] Addr2IntOp [arg] =
-    simpleCoercion IntRep res arg
+primCode [res] Int2AddrOp [arg]
+  = simpleCoercion AddrRep res arg
 
 
-  genprim [res] Int2WordOp [arg] =
-    simpleCoercion IntRep{-WordRep?-} res arg
+primCode [res] Addr2IntOp [arg]
+  = simpleCoercion IntRep res arg
 
 
-  genprim [res] Word2IntOp [arg] =
-    simpleCoercion IntRep res arg
+primCode [res] Int2WordOp [arg]
+  = simpleCoercion IntRep{-WordRep?-} res arg
 
 
+primCode [res] Word2IntOp [arg]
+  = simpleCoercion IntRep res arg
 \end{code}
 
 \end{code}
 
-The @ErrorIO@ primitive is actually a bit weird...assign a new value to the root
-closure, flush stdout and stderr, and jump to the @ErrorIO_innards@.
+The @ErrorIO@ primitive is actually a bit weird...assign a new value
+to the root closure, flush stdout and stderr, and jump to the
+@ErrorIO_innards@.
 
 \begin{code}
 
 \begin{code}
-
-  genprim [] ErrorIOPrimOp [rhs] =
-    let changeTop = StAssign PtrRep topClosure (a2stix rhs)
+primCode [] ErrorIOPrimOp [rhs]
+  = let
+       changeTop = StAssign PtrRep topClosure (amodeToStix rhs)
     in
     in
-       returnUs (\xs -> changeTop : flushStdout : flushStderr : errorIO : xs)
-
+    returnUs (\xs -> changeTop : flushStdout : flushStderr : errorIO : xs)
 \end{code}
 
 @newArray#@ ops allocate heap space.
 
 \begin{code}
 \end{code}
 
 @newArray#@ ops allocate heap space.
 
 \begin{code}
-  genprim [res] NewArrayOp args =
-    let        [liveness, n, initial] = map a2stix args
-       result = a2stix res
-       space = StPrim IntAddOp [n, mut_hs]
+primCode [res] NewArrayOp args
+  = let
+       [liveness, n, initial] = map amodeToStix args
+       result = amodeToStix res
+       space = StPrim IntAddOp [n, mutHS]
        loc = StIndex PtrRep stgHp
              (StPrim IntNegOp [StPrim IntSubOp [space, StInt 1]])
        assign = StAssign PtrRep result loc
        initialise = StCall SLIT("newArrZh_init") VoidRep [result, n, initial]
     in
        loc = StIndex PtrRep stgHp
              (StPrim IntNegOp [StPrim IntSubOp [space, StInt 1]])
        assign = StAssign PtrRep result loc
        initialise = StCall SLIT("newArrZh_init") VoidRep [result, n, initial]
     in
-       heap_chkr liveness space (StInt 0)      `thenUs` \ heap_chk ->
-
-       returnUs (heap_chk . (\xs -> assign : initialise : xs))
-
-  genprim [res] (NewByteArrayOp pk) args =
-    let        [liveness, count] = map a2stix args
-       result = a2stix res
-       n = StPrim IntMulOp [count, StInt (toInteger (size_of pk))]
-       slop = StPrim IntAddOp [n, StInt (toInteger (size_of IntRep - 1))]
-       words = StPrim IntQuotOp [slop, StInt (toInteger (size_of IntRep))]
-       space = StPrim IntAddOp [n, StPrim IntAddOp [words, data_hs]]
+    heapCheck liveness space (StInt 0) `thenUs` \ heap_chk ->
+
+    returnUs (heap_chk . (\xs -> assign : initialise : xs))
+
+primCode [res] (NewByteArrayOp pk) args
+  = let
+       [liveness, count] = map amodeToStix args
+       result = amodeToStix res
+       n = StPrim IntMulOp [count, StInt (sizeOf pk)]
+       slop = StPrim IntAddOp [n, StInt (sizeOf IntRep - 1)]
+       words = StPrim IntQuotOp [slop, StInt (sizeOf IntRep)]
+       space = StPrim IntAddOp [n, StPrim IntAddOp [words, dataHS]]
        loc = StIndex PtrRep stgHp
              (StPrim IntNegOp [StPrim IntSubOp [space, StInt 1]])
        assign = StAssign PtrRep result loc
        loc = StIndex PtrRep stgHp
              (StPrim IntNegOp [StPrim IntSubOp [space, StInt 1]])
        assign = StAssign PtrRep result loc
@@ -192,117 +173,121 @@ closure, flush stdout and stderr, and jump to the @ErrorIO_innards@.
        init2 = StAssign IntRep
                         (StInd IntRep
                                (StIndex IntRep loc
        init2 = StAssign IntRep
                         (StInd IntRep
                                (StIndex IntRep loc
-                                        (StInt (toInteger fixed_hs))))
+                                        (StInt (toInteger fixedHdrSizeInWords))))
                         (StPrim IntAddOp [words,
                         (StPrim IntAddOp [words,
-                                         StInt (toInteger (var_hs (DataRep 0)))])
+                                         StInt (toInteger (varHdrSizeInWords (DataRep 0)))])
     in
     in
-       heap_chkr liveness space (StInt 0)      `thenUs` \ heap_chk ->
+    heapCheck liveness space (StInt 0) `thenUs` \ heap_chk ->
 
 
-       returnUs (heap_chk . (\xs -> assign : init1 : init2 : xs))
+    returnUs (heap_chk . (\xs -> assign : init1 : init2 : xs))
 
 
-  genprim [res] SameMutableArrayOp args =
-    let compare = StPrim AddrEqOp (map a2stix args)
-       assign = StAssign IntRep (a2stix res) compare
+primCode [res] SameMutableArrayOp args
+  = let
+       compare = StPrim AddrEqOp (map amodeToStix args)
+       assign = StAssign IntRep (amodeToStix res) compare
     in
     in
-       returnUs (\xs -> assign : xs)
-
-  genprim res@[_] SameMutableByteArrayOp args =
-    genprim res SameMutableArrayOp args
+    returnUs (\xs -> assign : xs)
 
 
+primCode res@[_] SameMutableByteArrayOp args
+  = primCode res SameMutableArrayOp args
 \end{code}
 
 \end{code}
 
-Freezing an array of pointers is a double assignment.  We fix the header of
-the ``new'' closure because the lhs is probably a better addressing mode for
-the indirection (most likely, it's a VanillaReg).
+Freezing an array of pointers is a double assignment.  We fix the
+header of the ``new'' closure because the lhs is probably a better
+addressing mode for the indirection (most likely, it's a VanillaReg).
 
 \begin{code}
 
 
 \begin{code}
 
-  genprim [lhs] UnsafeFreezeArrayOp [rhs] =
-    let lhs' = a2stix lhs
-       rhs' = a2stix rhs
+primCode [lhs] UnsafeFreezeArrayOp [rhs]
+  = let
+       lhs' = amodeToStix lhs
+       rhs' = amodeToStix rhs
        header = StInd PtrRep lhs'
        assign = StAssign PtrRep lhs' rhs'
        freeze = StAssign PtrRep header imMutArrayOfPtrs_info
     in
        header = StInd PtrRep lhs'
        assign = StAssign PtrRep lhs' rhs'
        freeze = StAssign PtrRep header imMutArrayOfPtrs_info
     in
-       returnUs (\xs -> assign : freeze : xs)
-
-  genprim [lhs] UnsafeFreezeByteArrayOp [rhs] =
-    simpleCoercion PtrRep lhs rhs
+    returnUs (\xs -> assign : freeze : xs)
 
 
+primCode [lhs] UnsafeFreezeByteArrayOp [rhs]
+  = simpleCoercion PtrRep lhs rhs
 \end{code}
 
 Most other array primitives translate to simple indexing.
 
 \begin{code}
 
 \end{code}
 
 Most other array primitives translate to simple indexing.
 
 \begin{code}
 
-  genprim lhs@[_] IndexArrayOp args =
-    genprim lhs ReadArrayOp args
+primCode lhs@[_] IndexArrayOp args
+  = primCode lhs ReadArrayOp args
 
 
-  genprim [lhs] ReadArrayOp [obj, ix] =
-    let lhs' = a2stix lhs
-       obj' = a2stix obj
-       ix' = a2stix ix
-       base = StIndex IntRep obj' mut_hs
+primCode [lhs] ReadArrayOp [obj, ix]
+  = let
+       lhs' = amodeToStix lhs
+       obj' = amodeToStix obj
+       ix' = amodeToStix ix
+       base = StIndex IntRep obj' mutHS
        assign = StAssign PtrRep lhs' (StInd PtrRep (StIndex PtrRep base ix'))
     in
        assign = StAssign PtrRep lhs' (StInd PtrRep (StIndex PtrRep base ix'))
     in
-       returnUs (\xs -> assign : xs)
-
-  genprim [lhs] WriteArrayOp [obj, ix, v] =
-    let        obj' = a2stix obj
-       ix' = a2stix ix
-       v' = a2stix v
-       base = StIndex IntRep obj' mut_hs
+    returnUs (\xs -> assign : xs)
+
+primCode [lhs] WriteArrayOp [obj, ix, v]
+  = let
+       obj' = amodeToStix obj
+       ix' = amodeToStix ix
+       v' = amodeToStix v
+       base = StIndex IntRep obj' mutHS
        assign = StAssign PtrRep (StInd PtrRep (StIndex PtrRep base ix')) v'
     in
        assign = StAssign PtrRep (StInd PtrRep (StIndex PtrRep base ix')) v'
     in
-       returnUs (\xs -> assign : xs)
+    returnUs (\xs -> assign : xs)
 
 
-  genprim lhs@[_] (IndexByteArrayOp pk) args =
-    genprim lhs (ReadByteArrayOp pk) args
+primCode lhs@[_] (IndexByteArrayOp pk) args
+  = primCode lhs (ReadByteArrayOp pk) args
 
 -- NB: indexing in "pk" units, *not* in bytes (WDP 95/09)
 
 
 -- NB: indexing in "pk" units, *not* in bytes (WDP 95/09)
 
-  genprim [lhs] (ReadByteArrayOp pk) [obj, ix] =
-    let lhs' = a2stix lhs
-       obj' = a2stix obj
-       ix' = a2stix ix
-       base = StIndex IntRep obj' data_hs
+primCode [lhs] (ReadByteArrayOp pk) [obj, ix]
+  = let
+       lhs' = amodeToStix lhs
+       obj' = amodeToStix obj
+       ix' = amodeToStix ix
+       base = StIndex IntRep obj' dataHS
        assign = StAssign pk lhs' (StInd pk (StIndex pk base ix'))
     in
        assign = StAssign pk lhs' (StInd pk (StIndex pk base ix'))
     in
-       returnUs (\xs -> assign : xs)
+    returnUs (\xs -> assign : xs)
 
 
-  genprim [lhs] (IndexOffAddrOp pk) [obj, ix] =
-    let lhs' = a2stix lhs
-       obj' = a2stix obj
-       ix' = a2stix ix
+primCode [lhs] (IndexOffAddrOp pk) [obj, ix]
+  = let
+       lhs' = amodeToStix lhs
+       obj' = amodeToStix obj
+       ix' = amodeToStix ix
        assign = StAssign pk lhs' (StInd pk (StIndex pk obj' ix'))
     in
        assign = StAssign pk lhs' (StInd pk (StIndex pk obj' ix'))
     in
-       returnUs (\xs -> assign : xs)
-
-  genprim [] (WriteByteArrayOp pk) [obj, ix, v] =
-    let        obj' = a2stix obj
-       ix' = a2stix ix
-       v' = a2stix v
-       base = StIndex IntRep obj' data_hs
+    returnUs (\xs -> assign : xs)
+
+primCode [] (WriteByteArrayOp pk) [obj, ix, v]
+  = let
+       obj' = amodeToStix obj
+       ix' = amodeToStix ix
+       v' = amodeToStix v
+       base = StIndex IntRep obj' dataHS
        assign = StAssign pk (StInd pk (StIndex pk base ix')) v'
     in
        assign = StAssign pk (StInd pk (StIndex pk base ix')) v'
     in
-       returnUs (\xs -> assign : xs)
+    returnUs (\xs -> assign : xs)
 \end{code}
 
 Stable pointer operations.
 
 First the easy one.
 \end{code}
 
 Stable pointer operations.
 
 First the easy one.
-
 \begin{code}
 
 \begin{code}
 
-  genprim [lhs] DeRefStablePtrOp [sp] =
-    let lhs' = a2stix lhs
+primCode [lhs] DeRefStablePtrOp [sp]
+  = let
+       lhs' = amodeToStix lhs
        pk = getAmodeRep lhs
        pk = getAmodeRep lhs
-       sp' = a2stix sp
+       sp' = amodeToStix sp
        call = StCall SLIT("deRefStablePointer") pk [sp', smStablePtrTable]
        assign = StAssign pk lhs' call
     in
        call = StCall SLIT("deRefStablePointer") pk [sp', smStablePtrTable]
        assign = StAssign pk lhs' call
     in
-       returnUs (\xs -> assign : xs)
-
+    returnUs (\xs -> assign : xs)
 \end{code}
 
 Now the hard one.  For comparison, here's the code from StgMacros:
 \end{code}
 
 Now the hard one.  For comparison, here's the code from StgMacros:
@@ -349,8 +334,8 @@ Notes for ADR:
     --JSM
 
 \begin{pseudocode}
     --JSM
 
 \begin{pseudocode}
-  genprim [lhs] MakeStablePtrOp args =
-    let
+primCode [lhs] MakeStablePtrOp args
+  = let
        -- some useful abbreviations (I'm sure these must exist already)
        add = trPrim . IntAddOp
        sub = trPrim . IntSubOp
        -- some useful abbreviations (I'm sure these must exist already)
        add = trPrim . IntAddOp
        sub = trPrim . IntSubOp
@@ -359,7 +344,7 @@ Notes for ADR:
        inc x = trAssign IntRep [x, add [x, one]]
 
        -- tedious hardwiring in of closure layout offsets (from SMClosures)
        inc x = trAssign IntRep [x, add [x, one]]
 
        -- tedious hardwiring in of closure layout offsets (from SMClosures)
-       dynHS = 2 + fixedHeaderSize md sty + varHeaderSize md sty DynamicRep
+       dynHS = 2 + fixedHdrSizeInWords + varHdrSizeInWords DynamicRep
        spt_SIZE c   = trIndex PtrRep [c, trInt [fhs + gc_reserved] ]
        spt_NoPTRS c = trIndex PtrRep [c, trInt [fhs + gc_reserved + 1] ]
        spt_SPTR c i = trIndex PtrRep [c, add [trInt [dynHS], i]]
        spt_SIZE c   = trIndex PtrRep [c, trInt [fhs + gc_reserved] ]
        spt_NoPTRS c = trIndex PtrRep [c, trInt [fhs + gc_reserved + 1] ]
        spt_SPTR c i = trIndex PtrRep [c, add [trInt [dynHS], i]]
@@ -380,8 +365,8 @@ Notes for ADR:
        ]
 
        -- now to get down to business
        ]
 
        -- now to get down to business
-       lhs' = amodeCode sty md lhs
-       [liveness, unstable] = map (amodeCode sty md) args
+       lhs' = amodeCode lhs
+       [liveness, unstable] = map amodeCode args
 
        spt = smStablePtrTable
 
 
        spt = smStablePtrTable
 
@@ -408,81 +393,81 @@ Notes for ADR:
 \end{pseudocode}
 
 \begin{code}
 \end{pseudocode}
 
 \begin{code}
-  genprim res Word2IntegerOp args = panic "genPrimCode:Word2IntegerOp"
-
-  genprim lhs (CCallOp fn is_asm may_gc arg_tys result_ty) rhs
-   | is_asm = error "ERROR: Native code generator can't handle casm"
-   | otherwise =
-    case lhs of
-       [] -> returnUs (\xs -> (StCall fn VoidRep args) : xs)
-       [lhs] ->
-           let lhs' = a2stix lhs
-               pk = if isFloatingRep (getAmodeRep lhs) then DoubleRep else IntRep
-               call = StAssign pk lhs' (StCall fn pk args)
-           in
-               returnUs (\xs -> call : xs)
-    where
-       args = map amodeCodeForCCall rhs
-       amodeCodeForCCall x =
-           let base = a2stix' x
-           in
-               case getAmodeRep x of
-                   ArrayRep -> StIndex PtrRep base mut_hs
-                   ByteArrayRep -> StIndex IntRep base data_hs
-                   MallocPtrRep -> error "ERROR: native-code generator can't handle Malloc Ptrs (yet): use -fvia-C!"
-                   _ -> base
+primCode res Word2IntegerOp args = panic "primCode:Word2IntegerOp"
+
+primCode lhs (CCallOp fn is_asm may_gc arg_tys result_ty) rhs
+  | is_asm = error "ERROR: Native code generator can't handle casm"
+  | otherwise
+  = case lhs of
+      [] -> returnUs (\xs -> (StCall fn VoidRep args) : xs)
+      [lhs] ->
+         let lhs' = amodeToStix lhs
+             pk = if isFloatingRep (getAmodeRep lhs) then DoubleRep else IntRep
+             call = StAssign pk lhs' (StCall fn pk args)
+         in
+             returnUs (\xs -> call : xs)
+  where
+    args = map amodeCodeForCCall rhs
+    amodeCodeForCCall x =
+       let base = amodeToStix' x
+       in
+           case getAmodeRep x of
+             ArrayRep -> StIndex PtrRep base mutHS
+             ByteArrayRep -> StIndex IntRep base dataHS
+             MallocPtrRep -> error "ERROR: native-code generator can't handle Malloc Ptrs (yet): use -fvia-C!"
+             _ -> base
 \end{code}
 
 Now the more mundane operations.
 
 \begin{code}
 \end{code}
 
 Now the more mundane operations.
 
 \begin{code}
-  genprim lhs op rhs =
-    let lhs' = map a2stix  lhs
-       rhs' = map a2stix' rhs
+primCode lhs op rhs
+  = let
+       lhs' = map amodeToStix  lhs
+       rhs' = map amodeToStix' rhs
     in
     in
-       returnUs (\ xs -> simplePrim lhs' op rhs' : xs)
-
-  {-
-  simpleCoercion
-      :: Target
-      -> PrimRep
-      -> [CAddrMode]
-      -> [CAddrMode]
+    returnUs (\ xs -> simplePrim lhs' op rhs' : xs)
+\end{code}
+
+\begin{code}
+simpleCoercion
+      :: PrimRep
+      -> CAddrMode
+      -> CAddrMode
       -> UniqSM StixTreeList
       -> UniqSM StixTreeList
-  -}
-  simpleCoercion pk lhs rhs =
-      returnUs (\xs -> StAssign pk (a2stix lhs) (a2stix rhs) : xs)
 
 
+simpleCoercion pk lhs rhs
+  = returnUs (\xs -> StAssign pk (amodeToStix lhs) (amodeToStix rhs) : xs)
 \end{code}
 
 \end{code}
 
-Here we try to rewrite primitives into a form the code generator
-can understand.         Any primitives not handled here must be handled
-at the level of the specific code generator.
+Here we try to rewrite primitives into a form the code generator can
+understand.  Any primitives not handled here must be handled at the
+level of the specific code generator.
 
 \begin{code}
 
 \begin{code}
-  {-
-  simplePrim
-    :: Target
-    -> [StixTree]
+simplePrim
+    :: [StixTree]
     -> PrimOp
     -> [StixTree]
     -> StixTree
     -> PrimOp
     -> [StixTree]
     -> StixTree
-  -}
 \end{code}
 
 Now look for something more conventional.
 
 \begin{code}
 \end{code}
 
 Now look for something more conventional.
 
 \begin{code}
-
-  simplePrim [lhs] op rest = StAssign pk lhs (StPrim op rest)
-    where pk = if isCompareOp op then IntRep
-              else case getPrimOpResultInfo op of
-                ReturnsPrim pk -> pk
-                _ -> simplePrim_error op
-
-  simplePrim _ op _ = simplePrim_error op
-
-  simplePrim_error op
+simplePrim [lhs] op rest
+  = StAssign pk lhs (StPrim op rest)
+  where
+    pk = if isCompareOp op then
+           IntRep
+        else
+           case getPrimOpResultInfo op of
+              ReturnsPrim pk -> pk
+              _ -> simplePrim_error op
+
+simplePrim _ op _ = simplePrim_error op
+
+simplePrim_error op
     = error ("ERROR: primitive operation `"++showPrimOp PprDebug op++"'cannot be handled\nby the native-code generator.  Workaround: use -fvia-C.\n(Perhaps you should report it as a GHC bug, also.)\n")
 \end{code}
 
     = error ("ERROR: primitive operation `"++showPrimOp PprDebug op++"'cannot be handled\nby the native-code generator.  Workaround: use -fvia-C.\n(Perhaps you should report it as a GHC bug, also.)\n")
 \end{code}
 
@@ -490,120 +475,109 @@ Now look for something more conventional.
 
 Here we generate the Stix code for CAddrModes.
 
 
 Here we generate the Stix code for CAddrModes.
 
-When a character is fetched from a mixed type location, we have to
-do an extra cast.  This is reflected in amodeCode', which is for rhs
+When a character is fetched from a mixed type location, we have to do
+an extra cast.  This is reflected in amodeCode', which is for rhs
 amodes that might possibly need the extra cast.
 
 \begin{code}
 amodes that might possibly need the extra cast.
 
 \begin{code}
+amodeToStix, amodeToStix' :: CAddrMode -> StixTree
 
 
-amodeCode, amodeCode'
-    :: Target
-    -> CAddrMode
-    -> StixTree
-
-amodeCode'{-'-} target_STRICT am@(CVal rr CharRep)
-    | mixedTypeLocn am = StPrim ChrOp [amodeToStix target am]
-    | otherwise = amodeToStix target am
-
-amodeCode' target am = amodeToStix target am
+amodeToStix'{-'-} am@(CVal rr CharRep)
+    | mixedTypeLocn am = StPrim ChrOp [amodeToStix am]
+    | otherwise = amodeToStix am
 
 
-amodeCode target_STRICT am
- = acode am
- where
- -- grab "target" things:
- hp_rel    = hpRel target
- char_like = charLikeClosureSize target
- int_like  = intLikeClosureSize target
- a2stix    = amodeToStix target
+amodeToStix' am = amodeToStix am
 
 
- -- real code: ----------------------------------
- acode am@(CVal rr CharRep) | mixedTypeLocn am =
-        StInd IntRep (acode (CAddr rr))
+-----------
+amodeToStix am@(CVal rr CharRep)
+  | mixedTypeLocn am
+  = StInd IntRep (amodeToStix (CAddr rr))
 
 
- acode (CVal rr pk) = StInd pk (acode (CAddr rr))
+amodeToStix (CVal rr pk) = StInd pk (amodeToStix (CAddr rr))
 
 
- acode (CAddr (SpARel spA off)) =
-     StIndex PtrRep stgSpA (StInt (toInteger (spARelToInt spA off)))
+amodeToStix (CAddr (SpARel spA off))
+  = StIndex PtrRep stgSpA (StInt (toInteger (spARelToInt spA off)))
 
 
- acode (CAddr (SpBRel spB off)) =
-     StIndex IntRep stgSpB (StInt (toInteger (spBRelToInt spB off)))
+amodeToStix (CAddr (SpBRel spB off))
+  = StIndex IntRep stgSpB (StInt (toInteger (spBRelToInt spB off)))
 
 
- acode (CAddr (HpRel hp off)) =
-     StIndex IntRep stgHp (StInt (toInteger (-(hp_rel (hp `subOff` off)))))
+amodeToStix (CAddr (HpRel hp off))
+  = StIndex IntRep stgHp (StInt (toInteger (-(hpRelToInt (hp `subOff` off)))))
 
 
- acode (CAddr (NodeRel off)) =
-     StIndex IntRep stgNode (StInt (toInteger (hp_rel off)))
+amodeToStix (CAddr (NodeRel off))
+  = StIndex IntRep stgNode (StInt (toInteger (hpRelToInt off)))
 
 
- acode (CReg magic) = StReg (StixMagicId magic)
- acode (CTemp uniq pk) = StReg (StixTemp uniq pk)
+amodeToStix (CReg magic)    = StReg (StixMagicId magic)
+amodeToStix (CTemp uniq pk) = StReg (StixTemp uniq pk)
 
 
- acode (CLbl lbl _) = StCLbl lbl
+amodeToStix (CLbl      lbl _) = StCLbl lbl
+amodeToStix (CUnVecLbl dir _) = StCLbl dir
 
 
- acode (CUnVecLbl dir _) = StCLbl dir
-
- acode (CTableEntry base off pk) =
-     StInd pk (StIndex pk (acode base) (acode off))
+amodeToStix (CTableEntry base off pk)
+  = StInd pk (StIndex pk (amodeToStix base) (amodeToStix off))
 
  -- For CharLike and IntLike, we attempt some trivial constant-folding here.
 
 
  -- For CharLike and IntLike, we attempt some trivial constant-folding here.
 
- acode (CCharLike (CLit (MachChar c))) =
-     StLitLbl (uppBeside (uppPStr SLIT("CHARLIKE_closures+")) (uppInt off))
-     where off = char_like * ord c
+amodeToStix (CCharLike (CLit (MachChar c)))
+  = StLitLbl (uppBeside (uppPStr SLIT("CHARLIKE_closures+")) (uppInt off))
+  where
+    off = charLikeSize * ord c
 
 
- acode (CCharLike x) =
-     StPrim IntAddOp [charLike, off]
-     where off = StPrim IntMulOp [acode x,
-            StInt (toInteger (char_like))]
+amodeToStix (CCharLike x)
+  = StPrim IntAddOp [charLike, off]
+  where
+    off = StPrim IntMulOp [amodeToStix x, StInt (toInteger charLikeSize)]
 
 
- acode (CIntLike (CLit (MachInt i _))) =
-     StPrim IntAddOp [intLikePtr, StInt off]
-     where off = toInteger int_like * i
+amodeToStix (CIntLike (CLit (MachInt i _)))
+  = StPrim IntAddOp [intLikePtr, StInt off]
+  where
+    off = toInteger intLikeSize * i
 
 
- acode (CIntLike x) =
-     StPrim IntAddOp [intLikePtr, off]
-     where off = StPrim IntMulOp [acode x,
-            StInt (toInteger int_like)]
+amodeToStix (CIntLike x)
+  = StPrim IntAddOp [intLikePtr, off]
+  where
+    off = StPrim IntMulOp [amodeToStix x, StInt (toInteger intLikeSize)]
 
  -- A CString is just a (CLit . MachStr)
 
  -- A CString is just a (CLit . MachStr)
- acode (CString s) = StString s
-
- acode (CLit core) = case core of
-     (MachChar c) -> StInt (toInteger (ord c))
-     (MachStr s) -> StString s
-     (MachAddr a) -> StInt a
-     (MachInt i _) -> StInt i
-     (MachLitLit s _) -> StLitLit s
-     (MachFloat d) -> StDouble d
-     (MachDouble d) -> StDouble d
-     _ -> panic "amodeCode:core literal"
+amodeToStix (CString s) = StString s
+
+amodeToStix (CLit core)
+  = case core of
+      MachChar c     -> StInt (toInteger (ord c))
+      MachStr s             -> StString s
+      MachAddr a     -> StInt a
+      MachInt i _    -> StInt i
+      MachLitLit s _ -> StLitLit s
+      MachFloat d    -> StDouble d
+      MachDouble d   -> StDouble d
+      _ -> panic "amodeToStix:core literal"
 
  -- A CLitLit is just a (CLit . MachLitLit)
 
  -- A CLitLit is just a (CLit . MachLitLit)
- acode (CLitLit s _) = StLitLit s
+amodeToStix (CLitLit s _) = StLitLit s
 
  -- COffsets are in words, not bytes!
 
  -- COffsets are in words, not bytes!
- acode (COffset off) = StInt (toInteger (hp_rel off))
-
- acode (CMacroExpr _ macro [arg]) =
-     case macro of
-        INFO_PTR -> StInd PtrRep (a2stix arg)
-        ENTRY_CODE -> a2stix arg
-        INFO_TAG -> tag
-        EVAL_TAG -> StPrim IntGeOp [tag, StInt 0]
+amodeToStix (COffset off) = StInt (toInteger (hpRelToInt off))
+
+amodeToStix (CMacroExpr _ macro [arg])
+  = case macro of
+      INFO_PTR   -> StInd PtrRep (amodeToStix arg)
+      ENTRY_CODE -> amodeToStix arg
+      INFO_TAG   -> tag
+      EVAL_TAG   -> StPrim IntGeOp [tag, StInt 0]
    where
    where
-     tag = StInd IntRep (StIndex IntRep (a2stix arg) (StInt (-2)))
-     -- That ``-2'' really bothers me. (JSM)
+     tag = StInd IntRep (StIndex IntRep (amodeToStix arg) (StInt (-2)))
+     -- That ``-2'' really bothers me. (JSM) (Replace w/ oTHER_TAG? [WDP])
 
 
- acode (CCostCentre cc print_as_string)
-   = if noCostCentreAttached cc
-     then StComment SLIT("") -- sigh
-     else panic "amodeCode:CCostCentre"
+amodeToStix (CCostCentre cc print_as_string)
+  = if noCostCentreAttached cc
+    then StComment SLIT("") -- sigh
+    else panic "amodeToStix:CCostCentre"
 \end{code}
 
 \end{code}
 
-Sizes of the CharLike and IntLike closures that are arranged as arrays in the
-data segment.  (These are in bytes.)
+Sizes of the CharLike and IntLike closures that are arranged as arrays
+in the data segment.  (These are in bytes.)
 
 \begin{code}
 
 \begin{code}
-
 -- The INTLIKE base pointer
 
 intLikePtr :: StixTree
 -- The INTLIKE base pointer
 
 intLikePtr :: StixTree
@@ -624,6 +598,5 @@ topClosure = StInd PtrRep (sStLitLbl SLIT("TopClosure"))
 flushStdout = StCall SLIT("fflush") VoidRep [StLitLit SLIT("stdout")]
 flushStderr = StCall SLIT("fflush") VoidRep [StLitLit SLIT("stderr")]
 errorIO = StJump (StInd PtrRep (sStLitLbl SLIT("ErrorIO_innards")))
 flushStdout = StCall SLIT("fflush") VoidRep [StLitLit SLIT("stdout")]
 flushStderr = StCall SLIT("fflush") VoidRep [StLitLit SLIT("stderr")]
 errorIO = StJump (StInd PtrRep (sStLitLbl SLIT("ErrorIO_innards")))
-
 \end{code}
 
 \end{code}
 
index 6a4066b..3600897 100644 (file)
@@ -13,7 +13,6 @@ module UgenAll (
        U_constr.. ,
        U_coresyn.. ,
        U_entidt.. ,
        U_constr.. ,
        U_coresyn.. ,
        U_entidt.. ,
-       U_finfot.. ,
        U_hpragma.. ,
        U_list.. ,
        U_literal.. ,
        U_hpragma.. ,
        U_list.. ,
        U_literal.. ,
@@ -35,7 +34,6 @@ import U_binding
 import U_constr
 import U_coresyn
 import U_entidt
 import U_constr
 import U_coresyn
 import U_entidt
-import U_finfot
 import U_hpragma
 import U_list
 import U_literal
 import U_hpragma
 import U_list
 import U_literal
index 5cfe16d..892d2f9 100644 (file)
@@ -50,13 +50,13 @@ static unsigned char CharTable[NCHARS] = {
 /* dle */      0,      0,      0,      0,      0,      0,      0,      0,
 /* can */      0,      0,      0,      0,      0,      0,      0,      0,
 /* sp  */      _S,     0,      0,      0,      0,      0,      0,      0,
 /* dle */      0,      0,      0,      0,      0,      0,      0,      0,
 /* can */      0,      0,      0,      0,      0,      0,      0,      0,
 /* sp  */      _S,     0,      0,      0,      0,      0,      0,      0,
-/* '(' */       _C,    0,      0,      0,      0,      0,      0,      0,      /* ( */
+/* '(' */       _C,    0,      0,      0,      0,      0,      0,      0,
 /* '0' */      _D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,
 /* '8' */      _D|_H,  _D|_H,  _C,     0,      0,      0,      0,      0,
 /* '@' */      0,      _H|_C,  _H|_C,  _H|_C,  _H|_C,  _H|_C,  _H|_C,  _C,
 /* 'H' */      _C,     _C,     _C,     _C,     _C,     _C,     _C,     _C,
 /* 'P' */      _C,     _C,     _C,     _C,     _C,     _C,     _C,     _C,
 /* '0' */      _D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,_D|_H|_O,
 /* '8' */      _D|_H,  _D|_H,  _C,     0,      0,      0,      0,      0,
 /* '@' */      0,      _H|_C,  _H|_C,  _H|_C,  _H|_C,  _H|_C,  _H|_C,  _C,
 /* 'H' */      _C,     _C,     _C,     _C,     _C,     _C,     _C,     _C,
 /* 'P' */      _C,     _C,     _C,     _C,     _C,     _C,     _C,     _C,
-/* 'X' */      _C,     _C,     _C,     _C,     0,      0,      0,      0,      /* [ */
+/* 'X' */      _C,     _C,     _C,     _C,     0,      0,      0,      0,
 /* '`' */      0,      _H,     _H,     _H,     _H,     _H,     _H,     0,
 /* 'h' */      0,      0,      0,      0,      0,      0,      0,      0,
 /* 'p' */      0,      0,      0,      0,      0,      0,      0,      0,
 /* '`' */      0,      _H,     _H,     _H,     _H,     _H,     _H,     0,
 /* 'h' */      0,      0,      0,      0,      0,      0,      0,      0,
 /* 'p' */      0,      0,      0,      0,      0,      0,      0,      0,
index a3e9917..0743c55 100644 (file)
@@ -1662,6 +1662,7 @@ aexp      :  qvar                                 { $$ = mkident($1); }
        |  gcon                                 { $$ = mkident($1); }
        |  lit_constant                         { $$ = mklit($1); }
        |  OPAREN exp CPAREN                    { $$ = mkpar($2); }       /* mkpar: stop infix parsing at ()'s */
        |  gcon                                 { $$ = mkident($1); }
        |  lit_constant                         { $$ = mklit($1); }
        |  OPAREN exp CPAREN                    { $$ = mkpar($2); }       /* mkpar: stop infix parsing at ()'s */
+       |  qcon OCURLY CCURLY                   { $$ = mkrecord($1,Lnil); }
        |  qcon OCURLY rbinds CCURLY            { $$ = mkrecord($1,$3); } /* 1 S/R conflict on OCURLY -> shift */
        |  OBRACK list_exps CBRACK              { $$ = mkllist($2); }
        |  OPAREN exp COMMA texps CPAREN        { if (ttree($4) == tuple)
        |  qcon OCURLY rbinds CCURLY            { $$ = mkrecord($1,$3); } /* 1 S/R conflict on OCURLY -> shift */
        |  OBRACK list_exps CBRACK              { $$ = mkllist($2); }
        |  OPAREN exp COMMA texps CPAREN        { if (ttree($4) == tuple)
index 18d0e56..e60b8d6 100644 (file)
@@ -101,7 +101,7 @@ import FiniteMap
 import Id              ( mkTupleCon, GenId{-instances-} )
 import Name            ( Name(..) )
 import NameTypes       ( mkPreludeCoreName, FullName, ShortName )
 import Id              ( mkTupleCon, GenId{-instances-} )
 import Name            ( Name(..) )
 import NameTypes       ( mkPreludeCoreName, FullName, ShortName )
-import TyCon           ( getTyConDataCons, mkFunTyCon, mkTupleTyCon, TyCon{-instances-} )
+import TyCon           ( tyConDataCons, mkFunTyCon, mkTupleTyCon, TyCon{-instances-} )
 import Type
 import Unique          -- *Key stuff
 import Util            ( nOfThem, panic )
 import Type
 import Unique          -- *Key stuff
 import Util            ( nOfThem, panic )
@@ -401,5 +401,5 @@ pcTyConNameInfo tc = (getOccurrenceName tc, WiredInTyCon tc)
 pcDataConNameInfo :: TyCon -> [(FAST_STRING, Name)]
 pcDataConNameInfo tycon
   = -- slurp out its data constructors...
 pcDataConNameInfo :: TyCon -> [(FAST_STRING, Name)]
 pcDataConNameInfo tycon
   = -- slurp out its data constructors...
-    [ (getOccurrenceName con, WiredInVal con) | con <- getTyConDataCons tycon ]
+    [ (getOccurrenceName con, WiredInVal con) | con <- tyConDataCons tycon ]
 \end{code}
 \end{code}
index 457d11b..b4845f7 100644 (file)
@@ -10,6 +10,7 @@ module PrelVals where
 
 import Ubiq
 import IdLoop          ( UnfoldingGuidance(..) )
 
 import Ubiq
 import IdLoop          ( UnfoldingGuidance(..) )
+import Id              ( Id(..), GenId, mkPreludeId, mkTemplateLocals )
 import PrelLoop
 
 -- friends:
 import PrelLoop
 
 -- friends:
@@ -29,13 +30,13 @@ import SpecEnv              ( SpecEnv(..), nullSpecEnv )
 import TyVar           ( alphaTyVar, betaTyVar )
 import Unique          -- lots of *Keys
 import Util            ( panic )
 import TyVar           ( alphaTyVar, betaTyVar )
 import Unique          -- lots of *Keys
 import Util            ( panic )
+\end{code}
+
 
 
--- only used herein:
-mkPreludeId = panic "PrelVals:Id.mkPreludeId"
-mkSpecId = panic "PrelVals:Id.mkSpecId"
-mkTemplateLocals = panic "PrelVals:Id.mkTemplateLocals"
-specialiseTy = panic "PrelVals:specialiseTy"
 
 
+
+\begin{code}
+-- only used herein:
 pcMiscPrelId :: Unique{-IdKey-} -> FAST_STRING -> FAST_STRING -> Type -> IdInfo -> Id
 
 pcMiscPrelId key mod name ty info
 pcMiscPrelId :: Unique{-IdKey-} -> FAST_STRING -> FAST_STRING -> Type -> IdInfo -> Id
 
 pcMiscPrelId key mod name ty info
index 5dd0ccb..0fd25b7 100644 (file)
@@ -11,22 +11,21 @@ module PrimOp (
        tagOf_PrimOp, -- ToDo: rm
        primOp_str,   -- sigh
        primOpType, isCompareOp,
        tagOf_PrimOp, -- ToDo: rm
        primOp_str,   -- sigh
        primOpType, isCompareOp,
+       commutableOp,
 
        PrimOpResultInfo(..),
        getPrimOpResultInfo,
 
 
        PrimOpResultInfo(..),
        getPrimOpResultInfo,
 
---MOVE:        primOpCanTriggerGC, primOpNeedsWrapper,
---MOVE:        primOpOkForSpeculation, primOpIsCheap,
---MOVE:        fragilePrimOp,
---MOVE:        HeapRequirement(..), primOpHeapReq,
+       primOpCanTriggerGC, primOpNeedsWrapper,
+       primOpOkForSpeculation, primOpIsCheap,
+       fragilePrimOp,
+       HeapRequirement(..), primOpHeapReq,
 
        -- export for the Native Code Generator
        primOpInfo, -- needed for primOpNameInfo
        PrimOpInfo(..),
 
        pprPrimOp, showPrimOp
 
        -- export for the Native Code Generator
        primOpInfo, -- needed for primOpNameInfo
        PrimOpInfo(..),
 
        pprPrimOp, showPrimOp
-
-       -- and to make the interface self-sufficient....
     ) where
 
 import Ubiq{-uitous-}
     ) where
 
 import Ubiq{-uitous-}
@@ -37,19 +36,19 @@ import TysWiredIn
 
 import CStrings                ( identToC )
 import CgCompInfo      ( mIN_MP_INT_SIZE, mP_STRUCT_SIZE )
 
 import CStrings                ( identToC )
 import CgCompInfo      ( mIN_MP_INT_SIZE, mP_STRUCT_SIZE )
+import HeapOffs                ( addOff, intOff, totHdrSize )
 import NameTypes       ( mkPreludeCoreName, FullName, ShortName )
 import PprStyle                ( codeStyle )
 import NameTypes       ( mkPreludeCoreName, FullName, ShortName )
 import PprStyle                ( codeStyle )
+import PprType         ( pprParendGenType, GenTyVar{-instance Outputable-} )
 import Pretty
 import SMRep           ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
 import TyCon           ( TyCon{-instances-} )
 import Type            ( getAppDataTyCon, maybeAppDataTyCon,
 import Pretty
 import SMRep           ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
 import TyCon           ( TyCon{-instances-} )
 import Type            ( getAppDataTyCon, maybeAppDataTyCon,
-                         mkForAllTys, mkFunTys, applyTyCon )
-import TyVar           ( alphaTyVar, betaTyVar )
+                         mkForAllTys, mkFunTys, applyTyCon, typePrimRep
+                       )
+import TyVar           ( alphaTyVar, betaTyVar, GenTyVar{-instance Eq-} )
+import Unique          ( Unique{-instance Eq-} )
 import Util            ( panic#, assoc, panic{-ToDo:rm-} )
 import Util            ( panic#, assoc, panic{-ToDo:rm-} )
-
-glueTyArgs = panic "PrimOp:glueTyArgs"
-pprParendType = panic "PrimOp:pprParendType"
-primRepFromType = panic "PrimOp:primRepFromType"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -1305,7 +1304,6 @@ unfortunate few, some unknown amount of heap is required (these are the
 ops which can trigger GC).
 
 \begin{code}
 ops which can trigger GC).
 
 \begin{code}
-{- MOVE:
 data HeapRequirement
     = NoHeapRequired
     | FixedHeapRequired HeapOffset
 data HeapRequirement
     = NoHeapRequired
     | FixedHeapRequired HeapOffset
@@ -1395,7 +1393,6 @@ primOpHeapReq ParLocalOp  = trace "primOpHeapReq:ParLocalOp:verify!" (
 #endif {-GRAN-}
 
 primOpHeapReq other_op         = NoHeapRequired
 #endif {-GRAN-}
 
 primOpHeapReq other_op         = NoHeapRequired
--}
 \end{code}
 
 Primops which can trigger GC have to be called carefully.
 \end{code}
 
 Primops which can trigger GC have to be called carefully.
@@ -1403,9 +1400,8 @@ In particular, their arguments are guaranteed to be in registers,
 and a liveness mask tells which regs are live.
 
 \begin{code}
 and a liveness mask tells which regs are live.
 
 \begin{code}
-{- MOVE:
-primOpCanTriggerGC op =
-    case op of
+primOpCanTriggerGC op
+  = case op of
        TakeMVarOp  -> True
        ReadIVarOp  -> True
        DelayOp     -> True
        TakeMVarOp  -> True
        ReadIVarOp  -> True
        DelayOp     -> True
@@ -1414,7 +1410,6 @@ primOpCanTriggerGC op =
            case primOpHeapReq op of
                VariableHeapRequired -> True
                _                    -> False
            case primOpHeapReq op of
                VariableHeapRequired -> True
                _                    -> False
--}
 \end{code}
 
 Sometimes we may choose to execute a PrimOp even though it isn't
 \end{code}
 
 Sometimes we may choose to execute a PrimOp even though it isn't
@@ -1429,7 +1424,6 @@ There should be no worries about side effects; that's all taken care
 of by data dependencies.
 
 \begin{code}
 of by data dependencies.
 
 \begin{code}
-{- MOVE:
 primOpOkForSpeculation :: PrimOp -> Bool
 
 -- Int.
 primOpOkForSpeculation :: PrimOp -> Bool
 
 -- Int.
@@ -1470,24 +1464,20 @@ primOpOkForSpeculation ParLocalOp       = False         -- Could be expensive!
 
 -- The default is "yes it's ok for speculation"
 primOpOkForSpeculation other_op                = True
 
 -- The default is "yes it's ok for speculation"
 primOpOkForSpeculation other_op                = True
--}
 \end{code}
 
 @primOpIsCheap@, as used in \tr{SimplUtils.lhs}.  For now (HACK
 WARNING), we just borrow some other predicates for a
 what-should-be-good-enough test.
 \begin{code}
 \end{code}
 
 @primOpIsCheap@, as used in \tr{SimplUtils.lhs}.  For now (HACK
 WARNING), we just borrow some other predicates for a
 what-should-be-good-enough test.
 \begin{code}
-{-MOVE:
 primOpIsCheap op
   = primOpOkForSpeculation op && not (primOpCanTriggerGC op)
 primOpIsCheap op
   = primOpOkForSpeculation op && not (primOpCanTriggerGC op)
--}
 \end{code}
 
 And some primops have side-effects and so, for example, must not be
 duplicated.
 
 \begin{code}
 \end{code}
 
 And some primops have side-effects and so, for example, must not be
 duplicated.
 
 \begin{code}
-{- MOVE:
 fragilePrimOp :: PrimOp -> Bool
 
 fragilePrimOp ParOp = True
 fragilePrimOp :: PrimOp -> Bool
 
 fragilePrimOp ParOp = True
@@ -1504,14 +1494,12 @@ fragilePrimOp NoFollowOp = trace "fragilePrimOp:NoFollowOp" True  -- Possibly no
 #endif {-GRAN-}
 
 fragilePrimOp other = False
 #endif {-GRAN-}
 
 fragilePrimOp other = False
--}
 \end{code}
 
 Primitive operations that perform calls need wrappers to save any live variables
 that are stored in caller-saves registers
 
 \begin{code}
 \end{code}
 
 Primitive operations that perform calls need wrappers to save any live variables
 that are stored in caller-saves registers
 
 \begin{code}
-{- MOVE:
 primOpNeedsWrapper :: PrimOp -> Bool
 
 primOpNeedsWrapper (CCallOp _ _ _ _ _)         = True
 primOpNeedsWrapper :: PrimOp -> Bool
 
 primOpNeedsWrapper (CCallOp _ _ _ _ _)         = True
@@ -1574,7 +1562,6 @@ primOpNeedsWrapper DelayOp                = True
 primOpNeedsWrapper WaitOp              = True
 
 primOpNeedsWrapper other_op            = False
 primOpNeedsWrapper WaitOp              = True
 
 primOpNeedsWrapper other_op            = False
--}
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -1601,10 +1588,10 @@ primOpType op
       Coerce str ty1 ty2 -> mkFunTys [ty1] ty2
 
       PrimResult str tyvars arg_tys prim_tycon kind res_tys ->
       Coerce str ty1 ty2 -> mkFunTys [ty1] ty2
 
       PrimResult str tyvars arg_tys prim_tycon kind res_tys ->
-       mkForAllTys tyvars (glueTyArgs arg_tys (applyTyCon prim_tycon res_tys))
+       mkForAllTys tyvars (mkFunTys arg_tys (applyTyCon prim_tycon res_tys))
 
       AlgResult str tyvars arg_tys tycon res_tys ->
 
       AlgResult str tyvars arg_tys tycon res_tys ->
-       mkForAllTys tyvars (glueTyArgs arg_tys (applyTyCon tycon res_tys))
+       mkForAllTys tyvars (mkFunTys arg_tys (applyTyCon tycon res_tys))
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -1619,10 +1606,10 @@ getPrimOpResultInfo :: PrimOp -> PrimOpResultInfo
 
 getPrimOpResultInfo op
   = case (primOpInfo op) of
 
 getPrimOpResultInfo op
   = case (primOpInfo op) of
-      Dyadic  _ ty              -> ReturnsPrim (primRepFromType ty)
-      Monadic _ ty              -> ReturnsPrim (primRepFromType ty)
+      Dyadic  _ ty              -> ReturnsPrim (typePrimRep ty)
+      Monadic _ ty              -> ReturnsPrim (typePrimRep ty)
       Compare _ ty              -> ReturnsAlg  boolTyCon
       Compare _ ty              -> ReturnsAlg  boolTyCon
-      Coerce  _ _ ty            -> ReturnsPrim (primRepFromType ty)
+      Coerce  _ _ ty            -> ReturnsPrim (typePrimRep ty)
       PrimResult _ _ _ _ kind _         -> ReturnsPrim kind
       AlgResult _ _ _ tycon _   -> ReturnsAlg  tycon
 
       PrimResult _ _ _ _ kind _         -> ReturnsPrim kind
       AlgResult _ _ _ tycon _   -> ReturnsAlg  tycon
 
@@ -1634,6 +1621,33 @@ isCompareOp op
       _                  -> False
 \end{code}
 
       _                  -> False
 \end{code}
 
+The commutable ops are those for which we will try to move constants
+to the right hand side for strength reduction.
+
+\begin{code}
+commutableOp :: PrimOp -> Bool
+
+commutableOp CharEqOp    = True
+commutableOp CharNeOp    = True
+commutableOp IntAddOp    = True
+commutableOp IntMulOp    = True
+commutableOp AndOp       = True
+commutableOp OrOp        = True
+commutableOp IntEqOp     = True
+commutableOp IntNeOp     = True
+commutableOp IntegerAddOp = True
+commutableOp IntegerMulOp = True
+commutableOp FloatAddOp          = True
+commutableOp FloatMulOp          = True
+commutableOp FloatEqOp   = True
+commutableOp FloatNeOp   = True
+commutableOp DoubleAddOp  = True
+commutableOp DoubleMulOp  = True
+commutableOp DoubleEqOp          = True
+commutableOp DoubleNeOp          = True
+commutableOp _           = False
+\end{code}
+
 Utils:
 \begin{code}
 dyadic_fun_ty  ty = mkFunTys [ty, ty] ty
 Utils:
 \begin{code}
 dyadic_fun_ty  ty = mkFunTys [ty, ty] ty
@@ -1662,8 +1676,8 @@ pprPrimOp sty (CCallOp fun is_casm may_gc arg_tys res_ty)
 
        pp_tys
          = ppBesides [ppStr " { [",
 
        pp_tys
          = ppBesides [ppStr " { [",
-               ppIntersperse pp'SP{-'-} (map (pprParendType sty) arg_tys),
-               ppRbrack, ppSP, pprParendType sty res_ty, ppStr " })"]
+               ppIntersperse pp'SP{-'-} (map (pprParendGenType sty) arg_tys),
+               ppRbrack, ppSP, pprParendGenType sty res_ty, ppStr " })"]
 
     in
     ppBesides [ppStr before, ppPStr fun, after, pp_tys]
 
     in
     ppBesides [ppStr before, ppPStr fun, after, pp_tys]
index c16c6b8..092a9f4 100644 (file)
@@ -17,8 +17,7 @@ import Kind           ( mkUnboxedTypeKind, mkBoxedTypeKind )
 import NameTypes       ( mkPreludeCoreName, FullName )
 import PrelMods                ( pRELUDE_BUILTIN )
 import PrimRep         ( PrimRep(..) ) -- getPrimRepInfo uses PrimRep repn
 import NameTypes       ( mkPreludeCoreName, FullName )
 import PrelMods                ( pRELUDE_BUILTIN )
 import PrimRep         ( PrimRep(..) ) -- getPrimRepInfo uses PrimRep repn
-import TyCon           ( mkPrimTyCon, mkDataTyCon,
-                         ConsVisible(..), NewOrData(..) )
+import TyCon           ( mkPrimTyCon, mkDataTyCon, NewOrData(..) )
 import TyVar           ( GenTyVar(..), alphaTyVars )
 import Type            ( applyTyCon, mkTyVarTys )
 import Usage           ( usageOmega )
 import TyVar           ( GenTyVar(..), alphaTyVars )
 import Type            ( applyTyCon, mkTyVarTys )
 import Usage           ( usageOmega )
@@ -119,7 +118,6 @@ realWorldTyCon
        [{-no context-}]
        [{-no data cons!-}] -- we tell you *nothing* about this guy
        [{-no derivings-}]
        [{-no context-}]
        [{-no data cons!-}] -- we tell you *nothing* about this guy
        [{-no derivings-}]
-       ConsInvisible
        DataType
   where
     full_name = mkPreludeCoreName pRELUDE_BUILTIN SLIT("_RealWorld")
        DataType
   where
     full_name = mkPreludeCoreName pRELUDE_BUILTIN SLIT("_RealWorld")
index 514682d..977758f 100644 (file)
@@ -100,7 +100,8 @@ import NameTypes    ( mkPreludeCoreName, mkShortName )
 import Kind            ( mkBoxedTypeKind, mkArrowKind )
 import SrcLoc          ( mkBuiltinSrcLoc )
 import TyCon           ( mkDataTyCon, mkTupleTyCon, mkSynTyCon,
 import Kind            ( mkBoxedTypeKind, mkArrowKind )
 import SrcLoc          ( mkBuiltinSrcLoc )
 import TyCon           ( mkDataTyCon, mkTupleTyCon, mkSynTyCon,
-                         ConsVisible(..), NewOrData(..), TyCon )
+                         NewOrData(..), TyCon
+                       )
 import Type            ( mkTyConTy, applyTyCon, mkSynTy, mkSigmaTy,
                          mkFunTys, maybeAppDataTyCon,
                          GenType(..), ThetaType(..), TauType(..) )
 import Type            ( mkTyConTy, applyTyCon, mkSynTy, mkSigmaTy,
                          mkFunTys, maybeAppDataTyCon,
                          GenType(..), ThetaType(..), TauType(..) )
@@ -117,7 +118,7 @@ pcDataTyCon :: Unique{-TyConKey-} -> FAST_STRING -> FAST_STRING -> [TyVar] -> [I
 pcDataTyCon key mod name tyvars cons
   = mkDataTyCon key tycon_kind full_name tyvars
                [{-no context-}] cons [{-no derivings-}]
 pcDataTyCon key mod name tyvars cons
   = mkDataTyCon key tycon_kind full_name tyvars
                [{-no context-}] cons [{-no derivings-}]
-               ConsVisible DataType
+               DataType
   where
     full_name = mkPreludeCoreName mod name
     tycon_kind = foldr (mkArrowKind . getTyVarKind) mkBoxedTypeKind tyvars
   where
     full_name = mkPreludeCoreName mod name
     tycon_kind = foldr (mkArrowKind . getTyVarKind) mkBoxedTypeKind tyvars
index 58ca3cb..9702645 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[SCCfinal]{Modify and collect code generation for final STG program}
 
 %
 \section[SCCfinal]{Modify and collect code generation for final STG program}
 
@@ -27,35 +27,35 @@ This is now a sort-of-normal STG-to-STG pass (WDP 94/06), run by stg2stg.
 
 module SCCfinal ( stgMassageForProfiling ) where
 
 
 module SCCfinal ( stgMassageForProfiling ) where
 
-import Pretty          -- ToDo: rm (debugging only)
+import Ubiq{-uitous-}
 
 
-import Type            ( isFunType, getTauType )
-import CmdLineOpts
-import CostCentre
-import Id              ( mkSysLocal, idType )
-import SrcLoc          ( mkUnknownSrcLoc )
 import StgSyn
 import StgSyn
-import UniqSupply
-import UniqSet         ( emptyUniqSet
-                         IF_ATTACK_PRAGMAS(COMMA emptyUFM)
+
+import CmdLineOpts     ( opt_AutoSccsOnIndividualCafs,
+                         opt_CompilingPrelude
                        )
                        )
-import Util
+import CostCentre      -- lots of things
+import Id              ( idType, mkSysLocal, emptyIdSet )
+import Maybes          ( maybeToBool )
+import SrcLoc          ( mkUnknownSrcLoc )
+import Type            ( splitSigmaTy, getFunTy_maybe )
+import UniqSupply      ( getUnique, splitUniqSupply )
+import Util            ( removeDups, assertPanic )
 
 infixr 9 `thenMM`, `thenMM_`
 \end{code}
 
 \begin{code}
 
 infixr 9 `thenMM`, `thenMM_`
 \end{code}
 
 \begin{code}
-type CollectedCCs = ([CostCentre],         -- locally defined ones
-                    [CostCentre])          -- ones needing "extern" decls
+type CollectedCCs = ([CostCentre],     -- locally defined ones
+                    [CostCentre])      -- ones needing "extern" decls
 
 stgMassageForProfiling
 
 stgMassageForProfiling
-       :: FAST_STRING -> FAST_STRING       -- module name, group name
-       -> UniqSupply               -- unique supply
-       -> (GlobalSwitch -> Bool)           -- command-line opts checker
-       -> [StgBinding]             -- input
+       :: FAST_STRING -> FAST_STRING   -- module name, group name
+       -> UniqSupply                   -- unique supply
+       -> [StgBinding]                 -- input
        -> (CollectedCCs, [StgBinding])
 
        -> (CollectedCCs, [StgBinding])
 
-stgMassageForProfiling mod_name grp_name us sw_chkr stg_binds
+stgMassageForProfiling mod_name grp_name us stg_binds
   = let
        ((local_ccs, extern_ccs),
         stg_binds2)
   = let
        ((local_ccs, extern_ccs),
         stg_binds2)
@@ -71,8 +71,8 @@ stgMassageForProfiling mod_name grp_name us sw_chkr stg_binds
     in
     ((fixed_ccs ++ local_ccs_no_dups, extern_ccs_no_dups), stg_binds2)
   where
     in
     ((fixed_ccs ++ local_ccs_no_dups, extern_ccs_no_dups), stg_binds2)
   where
-    do_auto_sccs_on_cafs  = sw_chkr AutoSccsOnIndividualCafs  -- only use!
-    doing_prelude        = sw_chkr CompilingPrelude
+    do_auto_sccs_on_cafs  = opt_AutoSccsOnIndividualCafs  -- only use!
+    doing_prelude        = opt_CompilingPrelude
 
     all_cafs_cc = if doing_prelude
                  then preludeCafsCostCentre
 
     all_cafs_cc = if doing_prelude
                  then preludeCafsCostCentre
@@ -298,7 +298,9 @@ boxHigherOrderArgs almost_expr args live_vars
            in
            returnMM ( (new_var, old_var) : bindings, StgVarArg new_var )
       where
            in
            returnMM ( (new_var, old_var) : bindings, StgVarArg new_var )
       where
-       is_fun_type ty = isFunType (getTauType ty)
+       is_fun_type ty
+         = case (splitSigmaTy ty) of { (_, _, tau_ty) ->
+           maybeToBool (getFunTy_maybe tau_ty) }
 
     ---------------
     mk_stg_let :: CostCentre -> (Id, Id) -> StgExpr -> StgExpr
 
     ---------------
     mk_stg_let :: CostCentre -> (Id, Id) -> StgExpr -> StgExpr
@@ -313,7 +315,7 @@ boxHigherOrderArgs almost_expr args live_vars
        in
        StgLet (StgNonRec new_var rhs) body
       where
        in
        StgLet (StgNonRec new_var rhs) body
       where
-       bOGUS_LVs = emptyUniqSet -- easier to print than: panic "mk_stg_let: LVs"
+       bOGUS_LVs = emptyIdSet -- easier to print than: panic "mk_stg_let: LVs"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index 6043f72..733dd7f 100644 (file)
@@ -31,7 +31,7 @@ import MainMonad      ( thenMn, MainIO(..) )
 import PprStyle                ( PprStyle(..) )
 import Pretty
 import ProtoName       ( isConopPN, ProtoName(..) )
 import PprStyle                ( PprStyle(..) )
 import Pretty
 import ProtoName       ( isConopPN, ProtoName(..) )
-import Util            ( nOfThem, panic )
+import Util            ( nOfThem, pprError, panic )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -327,7 +327,7 @@ wlkExpr expr
       U_record con rbinds -> -- record construction
        wlkQid  con             `thenUgn` \ rcon     ->
        wlkList rdRbind rbinds  `thenUgn` \ recbinds ->
       U_record con rbinds -> -- record construction
        wlkQid  con             `thenUgn` \ rcon     ->
        wlkList rdRbind rbinds  `thenUgn` \ recbinds ->
-       returnUgn (RecordCon rcon recbinds)
+       returnUgn (RecordCon (HsVar rcon) recbinds)
 
       U_rupdate updexp updbinds -> -- record update
        wlkExpr updexp           `thenUgn` \ aexp ->
 
       U_rupdate updexp updbinds -> -- record update
        wlkExpr updexp           `thenUgn` \ aexp ->
@@ -352,7 +352,11 @@ rdRbind pt
   = rdU_tree pt                `thenUgn` \ (U_rbind var exp) ->
     wlkQid   var       `thenUgn` \ rvar ->
     wlkMaybe rdExpr exp        `thenUgn` \ expr_maybe ->
   = rdU_tree pt                `thenUgn` \ (U_rbind var exp) ->
     wlkQid   var       `thenUgn` \ rvar ->
     wlkMaybe rdExpr exp        `thenUgn` \ expr_maybe ->
-    returnUgn (rvar, expr_maybe)
+    returnUgn (
+      case expr_maybe of
+       Nothing -> (rvar, HsVar rvar, True{-pun-})
+       Just re -> (rvar, re,         False)
+    )
 \end{code}
 
 Patterns: just bear in mind that lists of patterns are represented as
 \end{code}
 
 Patterns: just bear in mind that lists of patterns are represented as
@@ -406,9 +410,8 @@ wlkPat pat
                  ConPatIn x []     -> (x,  lpats)
                  ConOpPatIn x op y -> (op, x:y:lpats)
                  _ -> -- sorry about the weedy msg; the parser missed this one
                  ConPatIn x []     -> (x,  lpats)
                  ConOpPatIn x op y -> (op, x:y:lpats)
                  _ -> -- sorry about the weedy msg; the parser missed this one
-                      error (ppShow 100 (ppCat [
-                          ppStr "ERROR: an illegal `application' of a pattern to another one:",
-                          ppInterleave ppSP (map (ppr PprForUser) (lpat:lpats))]))
+                      pprError "ERROR: an illegal `application' of a pattern to another one:"
+                         (ppInterleave ppSP (map (ppr PprForUser) (lpat:lpats)))
        in
        returnUgn (ConPatIn n arg_pats)
        where
        in
        returnUgn (ConPatIn n arg_pats)
        where
@@ -444,7 +447,11 @@ wlkPat pat
            = rdU_tree pt        `thenUgn` \ (U_rbind var pat) ->
              wlkQid   var       `thenUgn` \ rvar ->
              wlkMaybe rdPat pat `thenUgn` \ pat_maybe ->
            = rdU_tree pt        `thenUgn` \ (U_rbind var pat) ->
              wlkQid   var       `thenUgn` \ rvar ->
              wlkMaybe rdPat pat `thenUgn` \ pat_maybe ->
-             returnUgn (rvar, pat_maybe)
+             returnUgn (
+               case pat_maybe of
+                 Nothing -> (rvar, VarPatIn rvar, True{-pun-})
+                 Just rp -> (rvar, rp,            False)
+             )
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -748,7 +755,7 @@ mk_class_assertion :: ProtoNameMonoType -> (ProtoName, ProtoName)
 
 mk_class_assertion (MonoTyApp name [(MonoTyVar tyname)]) = (name, tyname)
 mk_class_assertion other
 
 mk_class_assertion (MonoTyApp name [(MonoTyVar tyname)]) = (name, tyname)
 mk_class_assertion other
-  = error ("ERROR: malformed type context: "++ppShow 80 (ppr PprForUser other)++"\n")
+  = pprError "ERROR: malformed type context: " (ppr PprForUser other)
     -- regrettably, the parser does let some junk past
     -- e.g., f :: Num {-nothing-} => a -> ...
 \end{code}
     -- regrettably, the parser does let some junk past
     -- e.g., f :: Num {-nothing-} => a -> ...
 \end{code}
@@ -784,14 +791,14 @@ wlkConDecl (U_constrrec ccon cfields srcline)
   = mkSrcLocUgn srcline                `thenUgn` \ src_loc      ->
     wlkQid     ccon            `thenUgn` \ con          ->
     wlkList rd_field cfields   `thenUgn` \ fields_lists ->
   = mkSrcLocUgn srcline                `thenUgn` \ src_loc      ->
     wlkQid     ccon            `thenUgn` \ con          ->
     wlkList rd_field cfields   `thenUgn` \ fields_lists ->
-    returnUgn (RecConDecl con (concat fields_lists) src_loc)
+    returnUgn (RecConDecl con fields_lists src_loc)
   where
   where
-    rd_field :: ParseTree -> UgnM [(ProtoName, BangType ProtoName)]
+    rd_field :: ParseTree -> UgnM ([ProtoName], BangType ProtoName)
     rd_field pt
       = rdU_constr pt          `thenUgn` \ (U_field fvars fty) ->
        wlkList rdQid   fvars   `thenUgn` \ vars ->
        wlkBangType fty         `thenUgn` \ ty ->
     rd_field pt
       = rdU_constr pt          `thenUgn` \ (U_field fvars fty) ->
        wlkList rdQid   fvars   `thenUgn` \ vars ->
        wlkBangType fty         `thenUgn` \ ty ->
-       returnUgn [ (var, ty) | var <- vars ]
+       returnUgn (vars, ty)
 
 -----------------
 rdBangType pt = rdU_ttype pt `thenUgn` \ ty -> wlkBangType ty
 
 -----------------
 rdBangType pt = rdU_ttype pt `thenUgn` \ ty -> wlkBangType ty
index 418c626..57303d8 100644 (file)
@@ -15,8 +15,6 @@ module RnBinds4 (
        rnTopBinds, rnMethodBinds,
        rnBinds,
        FreeVars(..), DefinedVars(..)
        rnTopBinds, rnMethodBinds,
        rnBinds,
        FreeVars(..), DefinedVars(..)
-
-       -- and to make the interface self-sufficient...
    ) where
 
 import Ubiq{-uitous-}
    ) where
 
 import Ubiq{-uitous-}
@@ -37,9 +35,9 @@ import Name           ( isUnboundName, Name{-instances-} )
 import Pretty
 import ProtoName       ( elemByLocalNames, eqByLocalName, ProtoName{-instances-} )
 import RnExpr4         -- OK to look here; but not the other way 'round
 import Pretty
 import ProtoName       ( elemByLocalNames, eqByLocalName, ProtoName{-instances-} )
 import RnExpr4         -- OK to look here; but not the other way 'round
-import UniqSet         ( emptyUniqSet, singletonUniqSet, mkUniqSet,
+import UniqSet         ( emptyUniqSet, unitUniqSet, mkUniqSet,
                          unionUniqSets, unionManyUniqSets,
                          unionUniqSets, unionManyUniqSets,
-                         elementOfUniqSet,
+                         elementOfUniqSet, addOneToUniqSet,
                          uniqSetToList,
                          UniqSet(..)
                        )
                          uniqSetToList,
                          UniqSet(..)
                        )
@@ -368,7 +366,7 @@ flattenMonoBinds uniq sigs (FunMonoBind name matches locn)
     returnRn4 (
       uniq + 1,
       [(uniq,
     returnRn4 (
       uniq + 1,
       [(uniq,
-       singletonUniqSet name',
+       unitUniqSet name',
        fvs `unionUniqSets` sigs_fvs,
        FunMonoBind name' new_matches locn,
        sigs_for_me
        fvs `unionUniqSets` sigs_fvs,
        FunMonoBind name' new_matches locn,
        sigs_for_me
@@ -391,7 +389,7 @@ sig_for_here want_me acc other_wise                  = acc
 -- acct in the dependency analysis (or we get an
 -- unexpected out-of-scope error)! WDP 95/07
 
 -- acct in the dependency analysis (or we get an
 -- unexpected out-of-scope error)! WDP 95/07
 
-sig_fv (SpecSig _ _ (Just blah) _) acc = acc `unionUniqSets` singletonUniqSet blah
+sig_fv (SpecSig _ _ (Just blah) _) acc = addOneToUniqSet acc blah
 sig_fv _                          acc = acc
 \end{code}
 
 sig_fv _                          acc = acc
 \end{code}
 
index 21f5346..99f0b75 100644 (file)
@@ -30,7 +30,7 @@ import RnMonad4
 import Name            ( Name(..) )
 import NameTypes       ( FullName{-instances-} )
 import Outputable      ( isConop )
 import Name            ( Name(..) )
 import NameTypes       ( FullName{-instances-} )
 import Outputable      ( isConop )
-import UniqSet         ( emptyUniqSet, singletonUniqSet,
+import UniqSet         ( emptyUniqSet, unitUniqSet,
                          unionUniqSets, unionManyUniqSets,
                          UniqSet(..)
                        )
                          unionUniqSets, unionManyUniqSets,
                          UniqSet(..)
                        )
@@ -193,11 +193,11 @@ rnExpr (HsVar v)
   = lookupValue v      `thenRn4` \ vname ->
     returnRn4 (HsVar vname, fv_set vname)
   where
   = lookupValue v      `thenRn4` \ vname ->
     returnRn4 (HsVar vname, fv_set vname)
   where
-    fv_set n@(Short uniq sname)            = singletonUniqSet n
+    fv_set n@(Short uniq sname)            = unitUniqSet n
     fv_set n@(ValName uniq fname)
          | isLocallyDefined fname
          && not (isConop (getOccurrenceName fname))
     fv_set n@(ValName uniq fname)
          | isLocallyDefined fname
          && not (isConop (getOccurrenceName fname))
-                                   = singletonUniqSet n
+                                   = unitUniqSet n
     fv_set other                   = emptyUniqSet
 
 rnExpr (HsLit lit)  = returnRn4 (HsLit lit, emptyUniqSet)
     fv_set other                   = emptyUniqSet
 
 rnExpr (HsLit lit)  = returnRn4 (HsLit lit, emptyUniqSet)
index b141a30..278fc65 100644 (file)
@@ -32,6 +32,7 @@ type RenamedGenPragmas                = GenPragmas            Name
 type RenamedHsBinds            = HsBinds               Fake Fake Name RenamedPat
 type RenamedHsExpr             = HsExpr                Fake Fake Name RenamedPat
 type RenamedHsModule           = HsModule              Fake Fake Name RenamedPat
 type RenamedHsBinds            = HsBinds               Fake Fake Name RenamedPat
 type RenamedHsExpr             = HsExpr                Fake Fake Name RenamedPat
 type RenamedHsModule           = HsModule              Fake Fake Name RenamedPat
+type RenamedRecordBinds                = HsRecordBinds         Fake Fake Name RenamedPat
 type RenamedImportedInterface  = ImportedInterface     Fake Fake Name RenamedPat
 type RenamedInstDecl           = InstDecl              Fake Fake Name RenamedPat
 type RenamedInstancePragmas    = InstancePragmas       Name
 type RenamedImportedInterface  = ImportedInterface     Fake Fake Name RenamedPat
 type RenamedInstDecl           = InstDecl              Fake Fake Name RenamedPat
 type RenamedInstancePragmas    = InstancePragmas       Name
index 53f4bb6..bd76c69 100644 (file)
@@ -652,7 +652,7 @@ doIfaceTyDecls1 sifun full_tc_nf ty_decls
     do_condecl cf_nf tc_nf (RecConDecl con fields src_loc)
       = RecConDecl (cf_nf con) (map do_field fields) src_loc
       where
     do_condecl cf_nf tc_nf (RecConDecl con fields src_loc)
       = RecConDecl (cf_nf con) (map do_field fields) src_loc
       where
-       do_field (var, ty) = (cf_nf var, do_bang tc_nf ty)
+       do_field (vars, ty) = (map cf_nf vars, do_bang tc_nf ty)
 
     --------------------------------------------
     do_bang tc_nf (Banged   ty) = Banged   (doIfaceMonoType1 tc_nf ty)
 
     --------------------------------------------
     do_bang tc_nf (Banged   ty) = Banged   (doIfaceMonoType1 tc_nf ty)
index 9aaa2e7..5006d17 100644 (file)
@@ -292,7 +292,12 @@ rnInstDecl (InstDecl cname ty mbinds from_here modname uprags pragmas src_loc)
     in
     mkTyVarNamesEnv src_loc tyvars             `thenRn4` \ (tv_env,_) ->
     lookupClass cname                  `thenRn4` \ cname' ->
     in
     mkTyVarNamesEnv src_loc tyvars             `thenRn4` \ (tv_env,_) ->
     lookupClass cname                  `thenRn4` \ cname' ->
-    rnPolyType False{-no invisibles-} tv_env ty
+
+    rnPolyType False{-no invisibles-} [] ty
+       -- The "[]" was tv_env, but that means the InstDecl's tyvars aren't
+       -- pinned on the HsForAllType, which they should be.
+       -- Urgh!  Improve in the new renamer!
+
                                        `thenRn4` \ ty' ->
     rnMethodBinds cname' mbinds        `thenRn4` \ mbinds' ->
     mapRn4 (rn_uprag cname') uprags    `thenRn4` \ new_uprags ->
                                        `thenRn4` \ ty' ->
     rnMethodBinds cname' mbinds        `thenRn4` \ mbinds' ->
     mapRn4 (rn_uprag cname') uprags    `thenRn4` \ new_uprags ->
index 7e45607..8422c18 100644 (file)
@@ -8,29 +8,36 @@
 
 module AnalFBWW ( analFBWW ) where
 
 
 module AnalFBWW ( analFBWW ) where
 
-import Util
-import Id                      ( addIdFBTypeInfo )
-import IdInfo
-import PrelInfo          ( foldrId, buildId,
-                         nilDataCon, consDataCon, mkListTy, mkFunTy,
-                         unpackCStringAppendId
-                       )
-import BinderInfo
-import SimplEnv                -- everything
-import OccurAnal       -- OLD: was NewOccurAnal
-import Maybes
-
+import Ubiq{-uitous-}
+
+import CoreSyn         ( CoreBinding(..) )
+import Util            ( panic{-ToDo:rm-} )
+
+--import Util
+--import Id                    ( addIdFBTypeInfo )
+--import IdInfo
+--import PrelInfo          ( foldrId, buildId,
+--                       nilDataCon, consDataCon, mkListTy, mkFunTy,
+--                       unpackCStringAppendId
+--                     )
+--import BinderInfo
+--import SimplEnv              -- everything
+--import OccurAnal     -- OLD: was NewOccurAnal
+--import Maybes
 \end{code}
 
 \begin{code}
 analFBWW
 \end{code}
 
 \begin{code}
 analFBWW
-       :: (GlobalSwitch -> Bool)
-       -> [CoreBinding]
+       :: [CoreBinding]
        -> [CoreBinding]
        -> [CoreBinding]
-analFBWW switch top_binds = trace "ANALFBWW" (snd anno)
+
+analFBWW = panic "analFBWW (ToDo)"
+
+{- LATER:
+analFBWW top_binds = trace "ANALFBWW" (snd anno)
  where
        anals :: [InBinding]
  where
        anals :: [InBinding]
-       anals = newOccurAnalyseBinds top_binds switch (const False)
+       anals = newOccurAnalyseBinds top_binds (const False)
        anno = mapAccumL annotateBindingFBWW nullIdEnv anals
 \end{code}
 
        anno = mapAccumL annotateBindingFBWW nullIdEnv anals
 \end{code}
 
@@ -136,14 +143,14 @@ analExprFBWW (SCC lab e) env   = analExprFBWW e env
 analExprFBWW (Let binds e) env = analExprFBWW e (analBind binds env)
 analExprFBWW (Case e alts) env = foldl1 joinFBType (analAltsFBWW alts env)
 
 analExprFBWW (Let binds e) env = analExprFBWW e (analBind binds env)
 analExprFBWW (Case e alts) env = foldl1 joinFBType (analAltsFBWW alts env)
 
-analAltsFBWW (AlgAlts alts deflt) env =
-    case analDefFBWW deflt env of
+analAltsFBWW (AlgAlts alts deflt) env
+  = case analDefFBWW deflt env of
        Just ty -> ty : tys
        Nothing -> tys
    where
      tys = map (\(con,binders,e) -> analExprFBWW e (delManyFromIdEnv env (map fst binders))) alts
        Just ty -> ty : tys
        Nothing -> tys
    where
      tys = map (\(con,binders,e) -> analExprFBWW e (delManyFromIdEnv env (map fst binders))) alts
-analAltsFBWW (PrimAlts alts deflt) env =
-    case analDefFBWW deflt env of
+analAltsFBWW (PrimAlts alts deflt) env
+  = case analDefFBWW deflt env of
        Just ty -> ty : tys
        Nothing -> tys
    where
        Just ty -> ty : tys
        Nothing -> tys
    where
@@ -162,8 +169,8 @@ Only add a type info if:
 
 \begin{code}
 analBindExpr :: BinderInfo -> InExpr -> IdEnv OurFBType -> OurFBType
 
 \begin{code}
 analBindExpr :: BinderInfo -> InExpr -> IdEnv OurFBType -> OurFBType
-analBindExpr bnd expr env =
-       case analExprFBWW expr env of
+analBindExpr bnd expr env
+  =    case analExprFBWW expr env of
              IsFB ty@(FBType [] _) ->
                   if oneSafeOcc False bnd
                   then IsFB ty
              IsFB ty@(FBType [] _) ->
                   if oneSafeOcc False bnd
                   then IsFB ty
@@ -246,4 +253,5 @@ annotateBindingFBWW env bnds = (env',bnds')
                    | not (null xs) -> pprTrace "ADDED to:" (ppr PprDebug v)
                                        (addIdFBTypeInfo v (mkFBTypeInfo ty))
                   _ -> v)
                    | not (null xs) -> pprTrace "ADDED to:" (ppr PprDebug v)
                                        (addIdFBTypeInfo v (mkFBTypeInfo ty))
                   _ -> v)
+-}
 \end{code}
 \end{code}
index 27b6c08..0eb1529 100644 (file)
@@ -172,12 +172,11 @@ fiExpr to_drop (_,AnnLam b@(TyBinder tyvar) body)
   where
     whnf :: CoreExprWithFVs -> Bool
 
   where
     whnf :: CoreExprWithFVs -> Bool
 
-    whnf (_,AnnLit _)              = True
-    whnf (_,AnnCon _ _)                    = True
-    whnf (_,AnnLam (ValBinder _) _) = True
-    whnf (_,AnnLam _             e) = whnf e
-    whnf (_,AnnSCC _ e)                    = whnf e
-    whnf _                         = False
+    whnf (_,AnnLit _)  = True
+    whnf (_,AnnCon _ _)        = True
+    whnf (_,AnnLam x e) = if isValBinder x then True else whnf e
+    whnf (_,AnnSCC _ e)        = whnf e
+    whnf _             = False
 \end{code}
 
 Applications: we could float inside applications, but it's probably
 \end{code}
 
 Applications: we could float inside applications, but it's probably
index 7c97d54..99fa850 100644 (file)
@@ -8,38 +8,43 @@
 
 module FoldrBuildWW ( mkFoldrBuildWW ) where
 
 
 module FoldrBuildWW ( mkFoldrBuildWW ) where
 
-IMPORT_Trace
-import Outputable
-import Pretty
-import Type            ( cloneTyVarFromTemplate, mkTyVarTy,
-                         splitTypeWithDictsAsArgs, eqTyCon,  mkForallTy )
-import TysPrim         ( alphaTy )
-import TyVar           ( alphaTyVar )
-
-import Type            ( Type(..) ) -- **** CAN SEE THE CONSTRUCTORS ****
-import UniqSupply      ( runBuiltinUs )
-import WwLib            -- share the same monad (is this eticit ?)
-import PrelInfo                ( listTyCon, mkListTy, nilDataCon, consDataCon,
-                         foldrId, buildId
-                       )
-import Id               ( getIdFBTypeInfo, mkWorkerId, getIdInfo,
-                         replaceIdInfo, mkSysLocal, idType
-                       )
-import IdInfo
-import Maybes
-import SrcLoc          ( mkUnknownSrcLoc, SrcLoc )
-import Util
+import Ubiq{-uitous-}
+
+import CoreSyn         ( CoreBinding(..) )
+import Util            ( panic{-ToDo:rm?-} )
+
+--import Type          ( cloneTyVarFromTemplate, mkTyVarTy,
+--                       splitTypeWithDictsAsArgs, eqTyCon,  mkForallTy )
+--import TysPrim               ( alphaTy )
+--import TyVar         ( alphaTyVar )
+--
+--import Type          ( Type(..) ) -- **** CAN SEE THE CONSTRUCTORS ****
+--import UniqSupply    ( runBuiltinUs )
+--import WwLib            -- share the same monad (is this eticit ?)
+--import PrelInfo              ( listTyCon, mkListTy, nilDataCon, consDataCon,
+--                       foldrId, buildId
+--                     )
+--import Id               ( getIdFBTypeInfo, mkWorkerId, getIdInfo,
+--                       replaceIdInfo, mkSysLocal, idType
+--                     )
+--import IdInfo
+--import Maybes
+--import SrcLoc                ( mkUnknownSrcLoc, SrcLoc )
+--import Util
 \end{code}
 
 \begin{code}
 mkFoldrBuildWW
 \end{code}
 
 \begin{code}
 mkFoldrBuildWW
-       :: (GlobalSwitch -> Bool)
-       -> UniqSupply
+       :: UniqSupply
        -> [CoreBinding]
        -> [CoreBinding]
        -> [CoreBinding]
        -> [CoreBinding]
-mkFoldrBuildWW switch us top_binds =
+
+mkFoldrBuildWW = panic "mkFoldrBuildWW (ToDo)"
+
+{- LATER:
+mkFoldrBuildWW us top_binds =
    (mapWw wwBind top_binds `thenWw` \ top_binds2 ->
    (mapWw wwBind top_binds `thenWw` \ top_binds2 ->
-   returnWw (concat top_binds2)) us switch
+   returnWw (concat top_binds2)) us
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -176,5 +181,5 @@ try_split_bind id expr =
        else
        returnWw  [(worker_id,worker_rhs),(wrapper_id,wrapper_rhs)]
     _ -> returnWw [(id,expr')]
        else
        returnWw  [(worker_id,worker_rhs),(wrapper_id,wrapper_rhs)]
     _ -> returnWw [(id,expr')]
+-}
 \end{code}
 \end{code}
-
index a56b4c9..47d0a27 100644 (file)
@@ -14,6 +14,7 @@ module MagicUFs (
     ) where
 
 import Ubiq{-uitous-}
     ) where
 
 import Ubiq{-uitous-}
+import IdLoop          -- paranoia checking
 
 import CoreSyn
 import PrelInfo                ( mkListTy )
 
 import CoreSyn
 import PrelInfo                ( mkListTy )
@@ -317,8 +318,8 @@ foldr_fun env (TypeArg ty1:TypeArg ty2:ValArg arg_k:rest_args)
 foldr_fun _ _ = returnSmpl Nothing
 
 isConsFun :: SimplEnv -> CoreArg -> Bool
 foldr_fun _ _ = returnSmpl Nothing
 
 isConsFun :: SimplEnv -> CoreArg -> Bool
-isConsFun env (VarArg v) =
-    case lookupUnfolding env v of
+isConsFun env (VarArg v)
+  = case lookupUnfolding env v of
        GenForm _ _ (Lam (x,_) (Lam (y,_)
                        (Con con tys [VarArg x',VarArg y']))) _
                        | con == consDataCon && x==x' && y==y'
        GenForm _ _ (Lam (x,_) (Lam (y,_)
                        (Con con tys [VarArg x',VarArg y']))) _
                        | con == consDataCon && x==x' && y==y'
@@ -327,8 +328,8 @@ isConsFun env (VarArg v) =
 isConsFun env _ = False
 
 isNilForm :: SimplEnv -> CoreArg -> Bool
 isConsFun env _ = False
 
 isNilForm :: SimplEnv -> CoreArg -> Bool
-isNilForm env (VarArg v) =
-    case lookupUnfolding env v of
+isNilForm env (VarArg v)
+  = case lookupUnfolding env v of
        GenForm _ _ (CoTyApp (Var id) _) _
          | id == nilDataCon -> True
        ConForm id _ _
        GenForm _ _ (CoTyApp (Var id) _) _
          | id == nilDataCon -> True
        ConForm id _ _
@@ -338,8 +339,8 @@ isNilForm env (VarArg v) =
 isNilForm env _ = False
 
 getBuildForm :: SimplEnv -> CoreArg -> Maybe Id
 isNilForm env _ = False
 
 getBuildForm :: SimplEnv -> CoreArg -> Maybe Id
-getBuildForm env (VarArg v) =
-    case lookupUnfolding env v of
+getBuildForm env (VarArg v)
+  = case lookupUnfolding env v of
        GenForm False _ _ _ -> Nothing
                                        -- not allowed to inline :-(
        GenForm _ _ (App (CoTyApp (Var bld) _) (VarArg g)) _
        GenForm False _ _ _ -> Nothing
                                        -- not allowed to inline :-(
        GenForm _ _ (App (CoTyApp (Var bld) _) (VarArg g)) _
@@ -353,8 +354,8 @@ getBuildForm env _ = Nothing
 
 
 getAugmentForm :: SimplEnv -> CoreArg -> Maybe (Id,CoreArg)
 
 
 getAugmentForm :: SimplEnv -> CoreArg -> Maybe (Id,CoreArg)
-getAugmentForm env (VarArg v) =
-    case lookupUnfolding env v of
+getAugmentForm env (VarArg v)
+  = case lookupUnfolding env v of
        GenForm False _ _ _ -> Nothing
                                -- not allowed to inline :-(
        GenForm _ _ (App (App (CoTyApp (Var bld) _)
        GenForm False _ _ _ -> Nothing
                                -- not allowed to inline :-(
        GenForm _ _ (App (App (CoTyApp (Var bld) _)
@@ -387,8 +388,8 @@ getListForm
        :: SimplEnv
        -> CoreArg
        -> Maybe ([CoreArg],CoreArg)
        :: SimplEnv
        -> CoreArg
        -> Maybe ([CoreArg],CoreArg)
-getListForm env (VarArg v) =
-    case lookupUnfolding env v of
+getListForm env (VarArg v)
+  = case lookupUnfolding env v of
        ConForm id _ [head,tail]
          | id == consDataCon ->
                case getListForm env tail of
        ConForm id _ [head,tail]
          | id == consDataCon ->
                case getListForm env tail of
@@ -398,8 +399,8 @@ getListForm env (VarArg v) =
 getListForm env _ = Nothing
 
 isInterestingArg :: SimplEnv -> CoreArg -> Bool
 getListForm env _ = Nothing
 
 isInterestingArg :: SimplEnv -> CoreArg -> Bool
-isInterestingArg env (VarArg v) =
-    case lookupUnfolding env v of
+isInterestingArg env (VarArg v)
+  = case lookupUnfolding env v of
        GenForm False _ _ UnfoldNever -> False
        GenForm _ _ exp guide -> True
        _ -> False
        GenForm False _ _ UnfoldNever -> False
        GenForm _ _ exp guide -> True
        _ -> False
index b04eb4b..94e9fc6 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 %************************************************************************
 %*                                                                     *
 %
 %************************************************************************
 %*                                                                     *
@@ -15,19 +15,34 @@ core expression with (hopefully) improved usage information.
 
 module OccurAnal (
        occurAnalyseBinds, occurAnalyseExpr, occurAnalyseGlobalExpr
 
 module OccurAnal (
        occurAnalyseBinds, occurAnalyseExpr, occurAnalyseGlobalExpr
-
-       -- and to make the interface self-sufficient...
     ) where
 
     ) where
 
-import Type
+import Ubiq{-uitous-}
+
 import BinderInfo
 import BinderInfo
-import CmdLineOpts     ( GlobalSwitch(..), SimplifierSwitch(..) )
+import CmdLineOpts     ( opt_D_dump_occur_anal, SimplifierSwitch(..) )
+import CoreSyn
 import Digraph         ( stronglyConnComp )
 import Digraph         ( stronglyConnComp )
-import Id              ( eqId, idWantsToBeINLINEd, isConstMethodId,
-                         isSpecPragmaId_maybe, SpecInfo )
-import Maybes
-import UniqSet
-import Util
+import Id              ( idWantsToBeINLINEd, isConstMethodId,
+                         emptyIdSet, unionIdSets, mkIdSet,
+                         unitIdSet, elementOfIdSet,
+                         addOneToIdSet, IdSet(..),
+                         nullIdEnv, unitIdEnv, combineIdEnvs,
+                         delOneFromIdEnv, delManyFromIdEnv,
+                         mapIdEnv, lookupIdEnv, IdEnv(..),
+                         GenId{-instance Eq-}
+                       )
+import Maybes          ( maybeToBool )
+import Outputable      ( isExported, Outputable(..){-instance * (,) -} )
+import PprCore
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-}, GenTyVar{-ditto-} )
+import Pretty          ( ppAboves )
+import TyVar           ( GenTyVar{-instance Eq-} )
+import Unique          ( Unique{-instance Eq-} )
+import Util            ( assoc, pprTrace, panic )
+
+isSpecPragmaId_maybe = panic "OccurAnal.isSpecPragmaId_maybe (ToDo)"
 \end{code}
 
 
 \end{code}
 
 
@@ -56,18 +71,18 @@ data OccEnv =
    Bool                -- IgnoreINLINEPragma flag
                -- False <=> OK to use INLINEPragma information
                -- True  <=> ignore INLINEPragma information
    Bool                -- IgnoreINLINEPragma flag
                -- False <=> OK to use INLINEPragma information
                -- True  <=> ignore INLINEPragma information
-   (UniqSet Id)        -- Candidates
+   IdSet       -- Candidates
 
 addNewCands :: OccEnv -> [Id] -> OccEnv
 addNewCands (OccEnv kd ks kc ip cands) ids
 
 addNewCands :: OccEnv -> [Id] -> OccEnv
 addNewCands (OccEnv kd ks kc ip cands) ids
-  = OccEnv kd ks kc ip (cands `unionUniqSets` mkUniqSet ids)
+  = OccEnv kd ks kc ip (cands `unionIdSets` mkIdSet ids)
 
 addNewCand :: OccEnv -> Id -> OccEnv
 addNewCand (OccEnv ks kd kc ip cands) id
 
 addNewCand :: OccEnv -> Id -> OccEnv
 addNewCand (OccEnv ks kd kc ip cands) id
-  = OccEnv kd ks kc ip (cands `unionUniqSets` singletonUniqSet id)
+  = OccEnv kd ks kc ip (addOneToIdSet cands id)
 
 isCandidate :: OccEnv -> Id -> Bool
 
 isCandidate :: OccEnv -> Id -> Bool
-isCandidate (OccEnv _ _ _ _ cands) id = id `elementOfUniqSet` cands
+isCandidate (OccEnv _ _ _ _ cands) id = id `elementOfIdSet` cands
 
 ignoreINLINEPragma :: OccEnv -> Bool
 ignoreINLINEPragma (OccEnv _ _ _ ip _) = ip
 
 ignoreINLINEPragma :: OccEnv -> Bool
 ignoreINLINEPragma (OccEnv _ _ _ ip _) = ip
@@ -86,37 +101,34 @@ combineUsageDetails, combineAltsUsageDetails
        :: UsageDetails -> UsageDetails -> UsageDetails
 
 combineUsageDetails usage1 usage2
        :: UsageDetails -> UsageDetails -> UsageDetails
 
 combineUsageDetails usage1 usage2
-  = --BSCC("combineUsages")
-    combineIdEnvs combineBinderInfo usage1 usage2
-    --ESCC
+  = combineIdEnvs combineBinderInfo usage1 usage2
 
 combineAltsUsageDetails usage1 usage2
 
 combineAltsUsageDetails usage1 usage2
-  = --BSCC("combineUsages")
-    combineIdEnvs combineAltsBinderInfo usage1 usage2
-    --ESCC
+  = combineIdEnvs combineAltsBinderInfo usage1 usage2
 
 addOneOcc :: UsageDetails -> Id -> BinderInfo -> UsageDetails
 
 addOneOcc :: UsageDetails -> Id -> BinderInfo -> UsageDetails
-addOneOcc usage id info = combineIdEnvs combineBinderInfo usage (unitIdEnv id info)
+addOneOcc usage id info
+  = combineIdEnvs combineBinderInfo usage (unitIdEnv id info)
        -- ToDo: make this more efficient
 
 emptyDetails = (nullIdEnv :: UsageDetails)
 
 unitDetails id info = (unitIdEnv id info :: UsageDetails)
 
        -- ToDo: make this more efficient
 
 emptyDetails = (nullIdEnv :: UsageDetails)
 
 unitDetails id info = (unitIdEnv id info :: UsageDetails)
 
-tagBinders :: UsageDetails             -- Of scope
-          -> [Id]                      -- Binders
-          -> (UsageDetails,            -- Details with binders removed
-             [(Id,BinderInfo)])        -- Tagged binders
+tagBinders :: UsageDetails         -- Of scope
+          -> [Id]                  -- Binders
+          -> (UsageDetails,        -- Details with binders removed
+             [(Id,BinderInfo)])    -- Tagged binders
 
 tagBinders usage binders
   = (usage `delManyFromIdEnv` binders,
 
 tagBinders usage binders
   = (usage `delManyFromIdEnv` binders,
-     [(binder, usage_of usage binder) | binder <- binders]
+     [ (binder, usage_of usage binder) | binder <- binders ]
     )
 
     )
 
-tagBinder :: UsageDetails              -- Of scope
-         -> Id                         -- Binders
-         -> (UsageDetails,             -- Details with binders removed
-             (Id,BinderInfo))          -- Tagged binders
+tagBinder :: UsageDetails          -- Of scope
+         -> Id                     -- Binders
+         -> (UsageDetails,         -- Details with binders removed
+             (Id,BinderInfo))      -- Tagged binders
 
 tagBinder usage binder
   = (usage `delOneFromIdEnv` binder,
 
 tagBinder usage binder
   = (usage `delOneFromIdEnv` binder,
@@ -126,12 +138,12 @@ tagBinder usage binder
 usage_of usage binder
   | isExported binder = ManyOcc        0 -- Exported things count as many
   | otherwise
 usage_of usage binder
   | isExported binder = ManyOcc        0 -- Exported things count as many
   | otherwise
-  = case lookupIdEnv usage binder of
+  = case (lookupIdEnv usage binder) of
       Nothing   -> DeadCode
       Just info -> info
 
 isNeeded env usage binder
       Nothing   -> DeadCode
       Just info -> info
 
 isNeeded env usage binder
-  = case usage_of usage binder of
+  = case (usage_of usage binder) of
       DeadCode  -> keepUnusedBinding env binder        -- Maybe keep it anyway
       other     -> True
 \end{code}
       DeadCode  -> keepUnusedBinding env binder        -- Maybe keep it anyway
       other     -> True
 \end{code}
@@ -148,13 +160,14 @@ Here's the externally-callable interface:
 \begin{code}
 occurAnalyseBinds
        :: [CoreBinding]                -- input
 \begin{code}
 occurAnalyseBinds
        :: [CoreBinding]                -- input
-       -> (GlobalSwitch -> Bool)
        -> (SimplifierSwitch -> Bool)
        -> [SimplifiableCoreBinding]    -- output
 
        -> (SimplifierSwitch -> Bool)
        -> [SimplifiableCoreBinding]    -- output
 
-occurAnalyseBinds binds global_sw_chkr simplifier_sw_chkr
-  | global_sw_chkr D_dump_occur_anal = pprTrace "OccurAnal:" (ppr PprDebug binds') binds'
-  | otherwise                       = binds'
+occurAnalyseBinds binds simplifier_sw_chkr
+  | opt_D_dump_occur_anal = pprTrace "OccurAnal:"
+                                    (ppAboves (map (ppr PprDebug) binds'))
+                                    binds'
+  | otherwise            = binds'
   where
     (_, binds') = do initial_env binds
 
   where
     (_, binds') = do initial_env binds
 
@@ -162,7 +175,7 @@ occurAnalyseBinds binds global_sw_chkr simplifier_sw_chkr
                         (simplifier_sw_chkr KeepSpecPragmaIds)
                         (not (simplifier_sw_chkr SimplMayDeleteConjurableIds))
                         (simplifier_sw_chkr IgnoreINLINEPragma)
                         (simplifier_sw_chkr KeepSpecPragmaIds)
                         (not (simplifier_sw_chkr SimplMayDeleteConjurableIds))
                         (simplifier_sw_chkr IgnoreINLINEPragma)
-                        emptyUniqSet
+                        emptyIdSet
 
     do env [] = (emptyDetails, [])
     do env (bind:binds)
 
     do env [] = (emptyDetails, [])
     do env (bind:binds)
@@ -170,15 +183,13 @@ occurAnalyseBinds binds global_sw_chkr simplifier_sw_chkr
       where
        new_env                  = env `addNewCands` (bindersOf bind)
        (binds_usage, the_rest)  = do new_env binds
       where
        new_env                  = env `addNewCands` (bindersOf bind)
        (binds_usage, the_rest)  = do new_env binds
-       (final_usage, new_binds) = --BSCC("occAnalBind1")
-                                  occAnalBind env bind binds_usage
-                                  --ESCC
+       (final_usage, new_binds) = occAnalBind env bind binds_usage
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-occurAnalyseExpr :: UniqSet Id                         -- Set of interesting free vars
+occurAnalyseExpr :: IdSet              -- Set of interesting free vars
                 -> CoreExpr
                 -> CoreExpr
-                -> (IdEnv BinderInfo,          -- Occ info for interesting free vars
+                -> (IdEnv BinderInfo,  -- Occ info for interesting free vars
                     SimplifiableCoreExpr)
 
 occurAnalyseExpr candidates expr
                     SimplifiableCoreExpr)
 
 occurAnalyseExpr candidates expr
@@ -194,7 +205,7 @@ occurAnalyseGlobalExpr :: CoreExpr -> SimplifiableCoreExpr
 occurAnalyseGlobalExpr expr
   =    -- Top level expr, so no interesting free vars, and
        -- discard occurence info returned
 occurAnalyseGlobalExpr expr
   =    -- Top level expr, so no interesting free vars, and
        -- discard occurence info returned
-    expr' where (_, expr') = occurAnalyseExpr emptyUniqSet expr
+    expr' where (_, expr') = occurAnalyseExpr emptyIdSet expr
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -291,7 +302,7 @@ occAnalBind env (Rec pairs) body_usage
     sccs :: [[Id]]
     sccs = case binders of
                [_]   -> [binders]      -- Singleton; no need to analyse
     sccs :: [[Id]]
     sccs = case binders of
                [_]   -> [binders]      -- Singleton; no need to analyse
-               other -> stronglyConnComp eqId edges binders
+               other -> stronglyConnComp (==) edges binders
 
     ---- stuff to "re-constitute" bindings from dependency-analysis info ------
 
 
     ---- stuff to "re-constitute" bindings from dependency-analysis info ------
 
@@ -336,7 +347,7 @@ ToDo: try using the occurrence info for the inline'd binder.
 
 \begin{code}
 occAnalRhs :: OccEnv
 
 \begin{code}
 occAnalRhs :: OccEnv
-          -> Id                -- Binder
+          -> Id        -- Binder
           -> CoreExpr  -- Rhs
           -> (UsageDetails, SimplifiableCoreExpr)
 
           -> CoreExpr  -- Rhs
           -> (UsageDetails, SimplifiableCoreExpr)
 
@@ -356,7 +367,7 @@ Expressions
 \begin{code}
 occAnal :: OccEnv
        -> CoreExpr
 \begin{code}
 occAnal :: OccEnv
        -> CoreExpr
-       -> (UsageDetails,               -- Gives info only about the "interesting" Ids
+       -> (UsageDetails,       -- Gives info only about the "interesting" Ids
            SimplifiableCoreExpr)
 
 occAnal env (Var v)
            SimplifiableCoreExpr)
 
 occAnal env (Var v)
@@ -367,8 +378,8 @@ occAnal env (Var v)
   = (emptyDetails, Var v)
 
 occAnal env (Lit lit)     = (emptyDetails, Lit lit)
   = (emptyDetails, Var v)
 
 occAnal env (Lit lit)     = (emptyDetails, Lit lit)
-occAnal env (Con con tys args) = (occAnalAtoms env args, Con con tys args)
-occAnal env (Prim op tys args) = (occAnalAtoms env args, Prim op tys args)
+occAnal env (Con con args) = (occAnalArgs env args, Con con args)
+occAnal env (Prim op args) = (occAnalArgs env args, Prim op args)
 
 occAnal env (SCC cc body)
   = (mapIdEnv markInsideSCC usage, SCC cc body')
 
 occAnal env (SCC cc body)
   = (mapIdEnv markInsideSCC usage, SCC cc body')
@@ -378,26 +389,25 @@ occAnal env (SCC cc body)
 occAnal env (App fun arg)
   = (fun_usage `combineUsageDetails` arg_usage, App fun' arg)
   where
 occAnal env (App fun arg)
   = (fun_usage `combineUsageDetails` arg_usage, App fun' arg)
   where
-    (fun_usage, fun') = occAnal env fun
-    arg_usage        = occAnalAtom env arg
+    (fun_usage, fun') = occAnal    env fun
+    arg_usage        = occAnalArg env arg
 
 
-occAnal env (CoTyApp fun ty)
-  = (fun_usage, CoTyApp fun' ty)
+occAnal env (Lam (ValBinder binder) body)
+  = (mapIdEnv markDangerousToDup final_usage,
+     Lam (ValBinder tagged_binder) body')
   where
   where
-    (fun_usage, fun') = occAnal env fun
-
-occAnal env (Lam binder body)
-  = (mapIdEnv markDangerousToDup final_usage, Lam tagged_binder body')
-  where
-    (body_usage, body')          = occAnal (env `addNewCand` binder) body
+    (body_usage, body')         = occAnal (env `addNewCand` binder) body
     (final_usage, tagged_binder) = tagBinder body_usage binder
 
 -- ANDY: WE MUST THINK ABOUT THIS! (ToDo)
     (final_usage, tagged_binder) = tagBinder body_usage binder
 
 -- ANDY: WE MUST THINK ABOUT THIS! (ToDo)
-occAnal env (CoTyLam tyvar body)
-  = (mapIdEnv markDangerousToDup body_usage, CoTyLam tyvar body')
+occAnal env (Lam (TyBinder tyvar) body)
+  = (mapIdEnv markDangerousToDup body_usage,
+     Lam (TyBinder tyvar) body')
   where
     (body_usage, body') = occAnal env body
 
   where
     (body_usage, body') = occAnal env body
 
+occAnal env (Lam (UsageBinder _) _) = panic "OccurAnal.occAnal Lam UsageBinder"
+
 occAnal env (Case scrut alts)
   = (scrut_usage `combineUsageDetails` alts_usage,
      Case scrut' alts')
 occAnal env (Case scrut alts)
   = (scrut_usage `combineUsageDetails` alts_usage,
      Case scrut' alts')
@@ -410,9 +420,7 @@ occAnal env (Let bind body)
   where
     new_env                 = env `addNewCands` (bindersOf bind)
     (body_usage, body')      = occAnal new_env body
   where
     new_env                 = env `addNewCands` (bindersOf bind)
     (body_usage, body')      = occAnal new_env body
-    (final_usage, new_binds) = --BSCC("occAnalBind2")
-                              occAnalBind env bind body_usage
-                              --ESCC
+    (final_usage, new_binds) = occAnalBind env bind body_usage
 \end{code}
 
 Case alternatives
 \end{code}
 
 Case alternatives
@@ -460,21 +468,21 @@ occAnalDeflt env (BindDefault binder rhs)
 Atoms
 ~~~~~
 \begin{code}
 Atoms
 ~~~~~
 \begin{code}
-occAnalAtoms :: OccEnv -> [CoreArg] -> UsageDetails
+occAnalArgs :: OccEnv -> [CoreArg] -> UsageDetails
 
 
-occAnalAtoms env atoms
+occAnalArgs env atoms
   = foldr do_one_atom emptyDetails atoms
   where
   = foldr do_one_atom emptyDetails atoms
   where
-    do_one_atom (LitArg lit) usage = usage
     do_one_atom (VarArg v) usage
        | isCandidate env v = addOneOcc usage v (argOccurrence 0)
        | otherwise         = usage
     do_one_atom (VarArg v) usage
        | isCandidate env v = addOneOcc usage v (argOccurrence 0)
        | otherwise         = usage
+    do_one_atom other_arg  usage = usage
 
 
 
 
-occAnalAtom  :: OccEnv -> CoreArg -> UsageDetails
+occAnalArg  :: OccEnv -> CoreArg -> UsageDetails
 
 
-occAnalAtom env (LitArg lit) = emptyDetails
-occAnalAtom env (VarArg v)
+occAnalArg env (VarArg v)
   | isCandidate env v = unitDetails v (argOccurrence 0)
   | otherwise         = emptyDetails
   | isCandidate env v = unitDetails v (argOccurrence 0)
   | otherwise         = emptyDetails
+occAnalArg _   _      = emptyDetails
 \end{code}
 \end{code}
index 7c70bca..6783e11 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The AQUA Project, Glasgow University, 1994-1995
+% (c) The AQUA Project, Glasgow University, 1994-1996
 %
 \section[SimplCase]{Simplification of `case' expression}
 
 %
 \section[SimplCase]{Simplification of `case' expression}
 
@@ -10,33 +10,35 @@ Support code for @Simplify@.
 
 module SimplCase ( simplCase, bindLargeRhs ) where
 
 
 module SimplCase ( simplCase, bindLargeRhs ) where
 
-import SimplMonad
-import SimplEnv
+import Ubiq{-uitous-}
+import SmplLoop                ( simplBind, simplExpr, MagicUnfoldingFun )
 
 
-import PrelInfo                ( getPrimOpResultInfo, PrimOpResultInfo(..), PrimOp,
-                         voidPrimTy, voidPrimId, mkFunTy, primOpOkForSpeculation
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
+import BinderInfo      -- too boring to try to select things...
+import CmdLineOpts     ( SimplifierSwitch(..) )
+import CoreSyn
+import CoreUnfold      ( UnfoldingDetails(..), UnfoldingGuidance(..),
+                         FormSummary(..)
                        )
                        )
-import Type            ( splitSigmaTy, splitTyArgs, glueTyArgs,
-                         getTyConFamilySize, isPrimType,
-                         maybeAppDataTyCon
+import CoreUtils       ( coreAltsType, nonErrorRHSs, maybeErrorApp,
+                         unTagBindersAlts
                        )
                        )
-import Literal         ( isNoRepLit, Literal )
-import CmdLineOpts     ( SimplifierSwitch(..) )
-import Id
-import IdInfo
-import Maybes          ( catMaybes, maybeToBool, Maybe(..) )
-import Simplify
-import SimplUtils
-import SimplVar                ( completeVar )
-import Util
+import Id              ( idType, isDataCon, getIdDemandInfo,
+                         DataCon(..), GenId{-instance Eq-}
+                       )
+import IdInfo          ( willBeDemanded, DemandInfo )
+import Literal         ( isNoRepLit, Literal{-instance Eq-} )
+import Maybes          ( maybeToBool )
+import PrelInfo                ( voidPrimTy, voidPrimId )
+import PrimOp          ( primOpOkForSpeculation, PrimOp{-instance Eq-} )
+import SimplEnv
+import SimplMonad
+import SimplUtils      ( mkValLamTryingEta )
+import Type            ( isPrimType, maybeAppDataTyCon, mkFunTys, eqTy )
+import Unique          ( Unique{-instance Eq-} )
+import Usage           ( GenUsage{-instance Eq-} )
+import Util            ( isIn, isSingleton, panic, assertPanic )
 \end{code}
 
 \end{code}
 
-
-
-
-
 Float let out of case.
 
 \begin{code}
 Float let out of case.
 
 \begin{code}
@@ -44,7 +46,7 @@ simplCase :: SimplEnv
          -> InExpr     -- Scrutinee
          -> InAlts     -- Alternatives
          -> (SimplEnv -> InExpr -> SmplM OutExpr)      -- Rhs handler
          -> InExpr     -- Scrutinee
          -> InAlts     -- Alternatives
          -> (SimplEnv -> InExpr -> SmplM OutExpr)      -- Rhs handler
-         -> OutUniType                         -- Type of result expression
+         -> OutType                            -- Type of result expression
          -> SmplM OutExpr
 
 simplCase env (Let bind body) alts rhs_c result_ty
          -> SmplM OutExpr
 
 simplCase env (Let bind body) alts rhs_c result_ty
@@ -185,10 +187,10 @@ completeCase env (Lit lit) alts rhs_c
     tick KnownBranch           `thenSmpl_`
     completePrimCaseWithKnownLit env lit alts rhs_c
 
     tick KnownBranch           `thenSmpl_`
     completePrimCaseWithKnownLit env lit alts rhs_c
 
-completeCase env expr@(Con con tys con_args) alts rhs_c
+completeCase env expr@(Con con con_args) alts rhs_c
   =    -- Ha! Staring us in the face -- select the appropriate alternative
     tick KnownBranch           `thenSmpl_`
   =    -- Ha! Staring us in the face -- select the appropriate alternative
     tick KnownBranch           `thenSmpl_`
-    completeAlgCaseWithKnownCon env con tys con_args alts rhs_c
+    completeAlgCaseWithKnownCon env con con_args alts rhs_c
 \end{code}
 
 Case elimination
 \end{code}
 
 Case elimination
@@ -310,7 +312,7 @@ completeCase env scrut alts rhs_c
                                               not (alt_con `is_elem` not_these)]
 
 #ifdef DEBUG
                                               not (alt_con `is_elem` not_these)]
 
 #ifdef DEBUG
---                             ConForm c t v -> pprPanic "completeCase!" (ppAbove (ppCat [ppr PprDebug c, ppr PprDebug t, ppr PprDebug v]) (ppr PprDebug alts))
+--                             ConForm c v -> pprPanic "completeCase!" (ppAbove (ppCat [ppr PprDebug c, ppStr "<args>"]) (ppr PprDebug alts))
                                  -- ConForm can't happen, since we'd have
                                  -- inlined it, and be in completeCaseWithKnownCon by now
 #endif
                                  -- ConForm can't happen, since we'd have
                                  -- inlined it, and be in completeCaseWithKnownCon by now
 #endif
@@ -328,19 +330,19 @@ completeCase env scrut alts rhs_c
        -- If the scrut is already eval'd then there's no worry about
        -- eliminating the case
     scrut_is_evald = case scrut_form of
        -- If the scrut is already eval'd then there's no worry about
        -- eliminating the case
     scrut_is_evald = case scrut_form of
-                       OtherLitForm _     -> True
-                       ConForm _ _ _  -> True
-                       OtherConForm _ -> True
-                       other                  -> False
+                       OtherLitForm _   -> True
+                       ConForm      _ _ -> True
+                       OtherConForm _   -> True
+                       other            -> False
 
 
     scrut_is_eliminable_primitive
       = case scrut of
 
 
     scrut_is_eliminable_primitive
       = case scrut of
-          Prim op _ _ -> primOpOkForSpeculation op
-          Var _       -> case alts of
-                               PrimAlts _ _ -> True    -- Primitive, hence non-bottom
-                               AlgAlts _ _  -> False   -- Not primitive
-          other         -> False
+          Prim op _ -> primOpOkForSpeculation op
+          Var _     -> case alts of
+                         PrimAlts _ _ -> True  -- Primitive, hence non-bottom
+                         AlgAlts _ _  -> False -- Not primitive
+          other     -> False
 
        -- case v of w -> e{strict in w}  ===>   e[v/w]
     scrut_is_var_and_single_strict_default
 
        -- case v of w -> e{strict in w}  ===>   e[v/w]
     scrut_is_var_and_single_strict_default
@@ -390,7 +392,7 @@ completeCase env scrut alts rhs_c
 bindLargeAlts :: SimplEnv
              -> InAlts
              -> (SimplEnv -> InExpr -> SmplM OutExpr)          -- Old rhs handler
 bindLargeAlts :: SimplEnv
              -> InAlts
              -> (SimplEnv -> InExpr -> SmplM OutExpr)          -- Old rhs handler
-             -> OutUniType                                     -- Result type
+             -> OutType                                        -- Result type
              -> SmplM ([OutBinding],   -- Extra bindings
                        InAlts)         -- Modified alts
 
              -> SmplM ([OutBinding],   -- Extra bindings
                        InAlts)         -- Modified alts
 
@@ -427,7 +429,7 @@ bindLargeDefault env (BindDefault binder rhs) rhs_ty rhs_c
 \begin{code}
 bindLargeRhs :: SimplEnv
             -> [InBinder]      -- The args wrt which the rhs should be abstracted
 \begin{code}
 bindLargeRhs :: SimplEnv
             -> [InBinder]      -- The args wrt which the rhs should be abstracted
-            -> OutUniType
+            -> OutType
             -> (SimplEnv -> SmplM OutExpr)             -- Rhs handler
             -> SmplM (OutBinding,      -- New bindings (singleton or empty)
                       InExpr)          -- Modified rhs
             -> (SimplEnv -> SmplM OutExpr)             -- Rhs handler
             -> SmplM (OutBinding,      -- New bindings (singleton or empty)
                       InExpr)          -- Modified rhs
@@ -473,15 +475,15 @@ bindLargeRhs env args rhs_ty rhs_c
        -- it's processed the OutId won't be found in the environment, so it
        -- will be left unmodified.
   where
        -- it's processed the OutId won't be found in the environment, so it
        -- will be left unmodified.
   where
-    rhs_fun_ty :: OutUniType
-    rhs_fun_ty = glueTyArgs [simplTy env (idType id) | (id,_) <- used_args] rhs_ty
+    rhs_fun_ty :: OutType
+    rhs_fun_ty = mkFunTys [simplTy env (idType id) | (id,_) <- used_args] rhs_ty
 
     used_args      = [arg | arg@(_,usage) <- args, not (dead usage)]
     used_arg_atoms = [VarArg arg_id | (arg_id,_) <- used_args]
     dead DeadCode  = True
     dead other     = False
 
 
     used_args      = [arg | arg@(_,usage) <- args, not (dead usage)]
     used_arg_atoms = [VarArg arg_id | (arg_id,_) <- used_args]
     dead DeadCode  = True
     dead other     = False
 
-    prim_rhs_fun_ty = mkFunTy voidPrimTy rhs_ty
+    prim_rhs_fun_ty = mkFunTys [voidPrimTy] rhs_ty
 \end{code}
 
 Case alternatives when we don't know the scrutinee
 \end{code}
 
 Case alternatives when we don't know the scrutinee
@@ -517,8 +519,8 @@ simplAlts env scrut (AlgAlts alts deflt) rhs_c
        let
            env1    = extendIdEnvWithClones env con_args con_args'
            new_env = case scrut of
        let
            env1    = extendIdEnvWithClones env con_args con_args'
            new_env = case scrut of
-                      Var var -> _scc_ "euegC1" (extendUnfoldEnvGivenConstructor env1 var con con_args')
-                      other     -> env1
+                      Var v -> extendUnfoldEnvGivenConstructor env1 v con con_args'
+                      other -> env1
        in
        rhs_c new_env rhs                               `thenSmpl` \ rhs' ->
        returnSmpl (con, con_args', rhs')
        in
        rhs_c new_env rhs                               `thenSmpl` \ rhs' ->
        returnSmpl (con, con_args', rhs')
@@ -532,8 +534,8 @@ simplAlts env scrut (PrimAlts alts deflt) rhs_c
     do_alt (lit, rhs)
       = let
            new_env = case scrut of
     do_alt (lit, rhs)
       = let
            new_env = case scrut of
-                       Var var -> _scc_ "euegFD1" (extendUnfoldEnvGivenFormDetails env var (LitForm lit))
-                       other     -> env
+                       Var v -> extendUnfoldEnvGivenFormDetails env v (LitForm lit)
+                       other -> env
        in
        rhs_c new_env rhs                               `thenSmpl` \ rhs' ->
        returnSmpl (lit, rhs')
        in
        rhs_c new_env rhs                               `thenSmpl` \ rhs' ->
        returnSmpl (lit, rhs')
@@ -588,12 +590,12 @@ simplDefault env (Var scrut_var) (BindDefault binder rhs) form_from_this_case rh
       final_form
        = case (form_from_this_case, scrut_form) of
            (OtherConForm cs, OtherConForm ds) -> OtherConForm (cs++ds)
       final_form
        = case (form_from_this_case, scrut_form) of
            (OtherConForm cs, OtherConForm ds) -> OtherConForm (cs++ds)
-           (OtherLitForm cs,     OtherLitForm ds)     -> OtherLitForm (cs++ds)
+           (OtherLitForm cs, OtherLitForm ds) -> OtherLitForm (cs++ds)
                        -- ConForm, LitForm impossible
                        -- (ASSERT?  ASSERT?  Hello? WDP 95/05)
                        -- ConForm, LitForm impossible
                        -- (ASSERT?  ASSERT?  Hello? WDP 95/05)
-           other                                              -> form_from_this_case
+           other                              -> form_from_this_case
 
 
-      env2 = _scc_ "euegFD2" (extendUnfoldEnvGivenFormDetails env1 binder' final_form)
+      env2 = extendUnfoldEnvGivenFormDetails env1 binder' final_form
 
        -- Change unfold details for scrut var.  We now want to unfold it
        -- to binder'
 
        -- Change unfold details for scrut var.  We now want to unfold it
        -- to binder'
@@ -609,7 +611,7 @@ simplDefault env scrut (BindDefault binder rhs) form rhs_c
   = cloneId env binder         `thenSmpl` \ binder' ->
     let
        env1    = extendIdEnvWithAtom env binder (VarArg binder')
   = cloneId env binder         `thenSmpl` \ binder' ->
     let
        env1    = extendIdEnvWithAtom env binder (VarArg binder')
-       new_env = _scc_ "euegFD2" (extendUnfoldEnvGivenFormDetails env1 binder' form)
+       new_env = extendUnfoldEnvGivenFormDetails env1 binder' form
     in
     rhs_c new_env rhs                  `thenSmpl` \ rhs' ->
     returnSmpl (BindDefault binder' rhs')
     in
     rhs_c new_env rhs                  `thenSmpl` \ rhs' ->
     returnSmpl (BindDefault binder' rhs')
@@ -663,13 +665,13 @@ var [substitute \tr{y} out of existence].
 \begin{code}
 completeAlgCaseWithKnownCon
        :: SimplEnv
 \begin{code}
 completeAlgCaseWithKnownCon
        :: SimplEnv
-       -> DataCon -> [Type] -> [InAtom]
+       -> DataCon -> [InArg]
                -- Scrutinee is (con, type, value arguments)
        -> InAlts
        -> (SimplEnv -> InExpr -> SmplM OutExpr)        -- Rhs handler
        -> SmplM OutExpr
 
                -- Scrutinee is (con, type, value arguments)
        -> InAlts
        -> (SimplEnv -> InExpr -> SmplM OutExpr)        -- Rhs handler
        -> SmplM OutExpr
 
-completeAlgCaseWithKnownCon env con tys con_args (AlgAlts alts deflt) rhs_c
+completeAlgCaseWithKnownCon env con con_args (AlgAlts alts deflt) rhs_c
   = ASSERT(isDataCon con)
     search_alts alts
   where
   = ASSERT(isDataCon con)
     search_alts alts
   where
@@ -698,11 +700,11 @@ completeAlgCaseWithKnownCon env con tys con_args (AlgAlts alts deflt) rhs_c
                cloneId env binder              `thenSmpl` \ id' ->
                let
                    env1    = extendIdEnvWithClone env binder id'
                cloneId env binder              `thenSmpl` \ id' ->
                let
                    env1    = extendIdEnvWithClone env binder id'
-                   new_env = _scc_ "euegFD3" (extendUnfoldEnvGivenFormDetails env1 id'
-                                       (ConForm con tys con_args))
+                   new_env = extendUnfoldEnvGivenFormDetails env1 id'
+                                       (ConForm con con_args)
                in
                rhs_c new_env rhs               `thenSmpl` \ rhs' ->
                in
                rhs_c new_env rhs               `thenSmpl` \ rhs' ->
-               returnSmpl (Let (NonRec id' (Con con tys con_args)) rhs')
+               returnSmpl (Let (NonRec id' (Con con con_args)) rhs')
 \end{code}
 
 Case absorption and identity-case elimination
 \end{code}
 
 Case absorption and identity-case elimination
@@ -787,7 +789,7 @@ mkCoCase scrut (AlgAlts outer_alts
     munge_alt (con, args, rhs) = (con, args, Let (NonRec deflt_var v) rhs)
        where
         v | scrut_is_var = Var scrut_var
     munge_alt (con, args, rhs) = (con, args, Let (NonRec deflt_var v) rhs)
        where
         v | scrut_is_var = Var scrut_var
-          | otherwise    = Con con arg_tys (map VarArg args)
+          | otherwise    = Con con (map TyArg arg_tys ++ map VarArg args)
 
     arg_tys = case maybeAppDataTyCon (idType deflt_var) of
                Just (_, arg_tys, _) -> arg_tys
 
     arg_tys = case maybeAppDataTyCon (idType deflt_var) of
                Just (_, arg_tys, _) -> arg_tys
@@ -856,7 +858,7 @@ mkCoCase scrut alts
     identity_alts (AlgAlts alts deflt)  = all identity_alg_alt  alts && identity_deflt deflt
     identity_alts (PrimAlts alts deflt) = all identity_prim_alt alts && identity_deflt deflt
 
     identity_alts (AlgAlts alts deflt)  = all identity_alg_alt  alts && identity_deflt deflt
     identity_alts (PrimAlts alts deflt) = all identity_prim_alt alts && identity_deflt deflt
 
-    identity_alg_alt (con, args, Con con' _ args')
+    identity_alg_alt (con, args, Con con' args')
         = con == con'
           && and (zipWith eq_arg args args')
           && length args == length args'
         = con == con'
           && and (zipWith eq_arg args args')
           && length args == length args'
@@ -913,26 +915,30 @@ munge_alg_deflt deflt_var (BindDefault d' rhs)
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-       -- A cheap equality test which bales out fast!
 cheap_eq :: InExpr -> InExpr -> Bool
 cheap_eq :: InExpr -> InExpr -> Bool
+       -- A cheap equality test which bales out fast!
+
 cheap_eq (Var v1) (Var v2) = v1==v2
 cheap_eq (Lit l1) (Lit l2) = l1==l2
 cheap_eq (Var v1) (Var v2) = v1==v2
 cheap_eq (Lit l1) (Lit l2) = l1==l2
-cheap_eq (Con con1 tys1 args1) (Con con2 tys2 args2) = (con1==con2) &&
-                                                          (args1 `eq_args` args2)
-                                                          -- Types bound to be equal
-cheap_eq (Prim op1 tys1 args1) (Prim op2 tys2 args2) = (op1==op2) &&
-                                                          (args1 `eq_args` args2)
-                                                          -- Types bound to be equal
-cheap_eq (App   f1 a1) (App   f2 a2) = (f1 `cheap_eq` f2) && (a1 `eq_atom` a2)
-cheap_eq (CoTyApp f1 t1) (CoTyApp f2 t2) = (f1 `cheap_eq` f2) && (t1 == t2)
+cheap_eq (Con con1 args1) (Con con2 args2)
+  = con1 == con2 && args1 `eq_args` args2
+
+cheap_eq (Prim op1 args1) (Prim op2 args2)
+  = op1 ==op2 && args1 `eq_args` args2
+
+cheap_eq (App f1 a1) (App f2 a2)
+  = f1 `cheap_eq` f2 && a1 `eq_arg` a2
+
 cheap_eq _ _ = False
 
 -- ToDo: make CoreArg an instance of Eq
 cheap_eq _ _ = False
 
 -- ToDo: make CoreArg an instance of Eq
-eq_args (arg1: args1) (arg2 : args2) = (arg1 `eq_atom` arg2) && (args1 `eq_args` args2)
-eq_args []                    []                     = True
-eq_args other1                other2                 = False
-
-eq_atom (LitArg l1) (LitArg l2) =  l1==l2
-eq_atom (VarArg v1) (VarArg v2) =  v1==v2
-eq_atom other1        other2         =  False
+eq_args (a1:as1) (a2:as2) = a1 `eq_arg` a2 && as1 `eq_args` as2
+eq_args []      []       = True
+eq_args _       _        = False
+
+eq_arg (LitArg          l1) (LitArg   l2) = l1 == l2
+eq_arg (VarArg          v1) (VarArg   v2) = v1 == v2
+eq_arg (TyArg           t1) (TyArg    t2) = t1 `eqTy` t2
+eq_arg (UsageArg u1) (UsageArg u2) = u1 == u2
+eq_arg _            _             =  False
 \end{code}
 \end{code}
index 2ada373..1c99c71 100644 (file)
@@ -1,61 +1,84 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[SimplCore]{Driver for simplifying @Core@ programs}
 
 \begin{code}
 #include "HsVersions.h"
 
 %
 \section[SimplCore]{Driver for simplifying @Core@ programs}
 
 \begin{code}
 #include "HsVersions.h"
 
-module SimplCore (
-       core2core
-    ) where
+module SimplCore ( core2core ) where
 
 
-import Type            ( getTyConDataCons )
---SAVE:import ArityAnal        ( arityAnalProgram )
-import Bag
-import BinderInfo      ( BinderInfo) -- instances only
+import Ubiq{-uitous-}
+
+import AnalFBWW                ( analFBWW )
+import Bag             ( isEmptyBag, foldBag )
+import BinderInfo      ( BinderInfo{-instance Outputable-} )
 import CgCompInfo      ( uNFOLDING_CREATION_THRESHOLD,
                          uNFOLDING_USE_THRESHOLD,
                          uNFOLDING_OVERRIDE_THRESHOLD,
                          uNFOLDING_CON_DISCOUNT_WEIGHT
                        )
 import CgCompInfo      ( uNFOLDING_CREATION_THRESHOLD,
                          uNFOLDING_USE_THRESHOLD,
                          uNFOLDING_OVERRIDE_THRESHOLD,
                          uNFOLDING_CON_DISCOUNT_WEIGHT
                        )
-import CmdLineOpts
+import CmdLineOpts     ( CoreToDo(..), SimplifierSwitch(..), switchIsOn,
+                         opt_D_show_passes,
+                         opt_D_simplifier_stats,
+                         opt_D_verbose_core2core,
+                         opt_DoCoreLinting,
+                         opt_FoldrBuildOn,
+                         opt_ReportWhyUnfoldingsDisallowed,
+                         opt_ShowImportSpecs,
+                         opt_UnfoldingCreationThreshold,
+                         opt_UnfoldingOverrideThreshold,
+                         opt_UnfoldingUseThreshold
+                       )
 import CoreLint                ( lintCoreBindings )
 import CoreLint                ( lintCoreBindings )
+import CoreSyn
+import CoreUnfold
+import CoreUtils       ( substCoreBindings, manifestlyWHNF )
 import FloatIn         ( floatInwards )
 import FloatOut                ( floatOutwards )
 import FloatIn         ( floatInwards )
 import FloatOut                ( floatOutwards )
-import Id              ( getIdUnfolding,
-                         idType, toplevelishId,
-                         idWantsToBeINLINEd,
-                         unfoldingUnfriendlyId, isWrapperId,
-                         mkTemplateLocals
+import FoldrBuildWW    ( mkFoldrBuildWW )
+import Id              ( idType, toplevelishId, idWantsToBeINLINEd,
+                         unfoldingUnfriendlyId,
+                         nullIdEnv, addOneToIdEnv, delOneFromIdEnv,
+                         lookupIdEnv, IdEnv(..),
+                         GenId{-instance Outputable-}
                        )
                        )
-import IdInfo
+import IdInfo          ( mkUnfolding )
 import LiberateCase    ( liberateCase )
 import LiberateCase    ( liberateCase )
-import MainMonad
-import Maybes
+import MagicUFs                ( MagicUnfoldingFun )
+import MainMonad       ( writeMn, exitMn, thenMn, thenMn_, returnMn,
+                         MainIO(..)
+                       )
+import Maybes          ( maybeToBool )
+import Outputable      ( Outputable(..){-instance * (,) -} )
+import PprCore         ( pprCoreBinding, GenCoreExpr{-instance Outputable-} )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-}, GenTyVar{-ditto-} )
+import Pretty          ( ppShow, ppAboves, ppAbove, ppCat, ppStr )
 import SAT             ( doStaticArgs )
 import SAT             ( doStaticArgs )
-import SCCauto
---ANDY:
---import SimplHaskell  ( coreToHaskell )
-import SimplMonad      ( zeroSimplCount, showSimplCount, TickType, SimplCount )
+import SCCauto         ( addAutoCostCentres )
+import SimplMonad      ( zeroSimplCount, showSimplCount, SimplCount )
 import SimplPgm                ( simplifyPgm )
 import SimplVar                ( leastItCouldCost )
 import Specialise
 import SpecUtils       ( pprSpecErrs )
 import StrictAnal      ( saWwTopBinds )
 import SimplPgm                ( simplifyPgm )
 import SimplVar                ( leastItCouldCost )
 import Specialise
 import SpecUtils       ( pprSpecErrs )
 import StrictAnal      ( saWwTopBinds )
-import FoldrBuildWW
-import AnalFBWW
+import TyVar           ( nullTyVarEnv, GenTyVar{-instance Eq-} )
+import Unique          ( Unique{-instance Eq-} )
+import UniqSupply      ( splitUniqSupply )
+import Util            ( panic{-ToDo:rm-} )
+
 #if ! OMIT_DEFORESTER
 import Deforest                ( deforestProgram )
 import DefUtils                ( deforestable )
 #endif
 #if ! OMIT_DEFORESTER
 import Deforest                ( deforestProgram )
 import DefUtils                ( deforestable )
 #endif
-import UniqSupply
-import Util
+
+isWrapperFor = panic "SimplCore.isWrapperFor (ToDo)"
+isWrapperId = panic "SimplCore.isWrapperId (ToDo)"
 \end{code}
 
 \begin{code}
 core2core :: [CoreToDo]                        -- spec of what core-to-core passes to do
 \end{code}
 
 \begin{code}
 core2core :: [CoreToDo]                        -- spec of what core-to-core passes to do
-         -> (GlobalSwitch->SwitchResult)-- "global" command-line info lookup fn
          -> FAST_STRING                -- module name (profiling only)
          -> PprStyle                   -- printing style (for debugging only)
          -> UniqSupply         -- a name supply
          -> FAST_STRING                -- module name (profiling only)
          -> PprStyle                   -- printing style (for debugging only)
          -> UniqSupply         -- a name supply
@@ -67,12 +90,14 @@ core2core :: [CoreToDo]                     -- spec of what core-to-core passes to do
               IdEnv UnfoldingDetails,  --  unfoldings to be exported from here
              SpecialiseData)           --  specialisation data
 
               IdEnv UnfoldingDetails,  --  unfoldings to be exported from here
              SpecialiseData)           --  specialisation data
 
-core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs binds
+core2core core_todos module_name ppr_style us local_tycons tycon_specs binds
   = BSCC("Core2Core")
     if null core_todos then -- very rare, I suspect...
        -- well, we still must do some renumbering
        returnMn (
   = BSCC("Core2Core")
     if null core_todos then -- very rare, I suspect...
        -- well, we still must do some renumbering
        returnMn (
-       (snd (instCoreBindings (mkUniqueSupplyGrimily us) binds), nullIdEnv, init_specdata)
+       (substCoreBindings nullIdEnv nullTyVarEnv binds us,
+        nullIdEnv,
+        init_specdata)
        )
     else
        (if do_verbose_core2core then
        )
     else
        (if do_verbose_core2core then
@@ -85,7 +110,7 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
                core_todos
                `thenMn` \ (processed_binds, _, inline_env, spec_data, simpl_stats) ->
 
                core_todos
                `thenMn` \ (processed_binds, _, inline_env, spec_data, simpl_stats) ->
 
-       (if  switch_is_on D_simplifier_stats
+       (if  opt_D_simplifier_stats
         then writeMn stderr ("\nSimplifier Stats:\n")
                `thenMn_`
              writeMn stderr (showSimplCount simpl_stats)
         then writeMn stderr ("\nSimplifier Stats:\n")
                `thenMn_`
              writeMn stderr (showSimplCount simpl_stats)
@@ -99,18 +124,16 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
   where
     init_specdata = initSpecData local_tycons tycon_specs
 
   where
     init_specdata = initSpecData local_tycons tycon_specs
 
-    switch_is_on = switchIsOn sw_chkr
-
-    do_verbose_core2core = switch_is_on D_verbose_core2core
+    do_verbose_core2core = opt_D_verbose_core2core
 
     lib_case_threshold -- ToDo: HACK HACK HACK : FIX ME FIX ME FIX ME
                        -- Use 4x a known threshold
 
     lib_case_threshold -- ToDo: HACK HACK HACK : FIX ME FIX ME FIX ME
                        -- Use 4x a known threshold
-      = case (intSwitchSet sw_chkr UnfoldingOverrideThreshold) of
+      = case opt_UnfoldingOverrideThreshold of
          Nothing -> 4 * uNFOLDING_USE_THRESHOLD
          Just xx -> 4 * xx
 
     -------------
          Nothing -> 4 * uNFOLDING_USE_THRESHOLD
          Just xx -> 4 * xx
 
     -------------
-    core_linter = if switch_is_on DoCoreLinting
+    core_linter = if opt_DoCoreLinting
                  then lintCoreBindings ppr_style
                  else ( \ whodunnit spec_done binds -> binds )
 
                  then lintCoreBindings ppr_style
                  else ( \ whodunnit spec_done binds -> binds )
 
@@ -124,7 +147,7 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
            -> BSCC("CoreSimplify")
               begin_pass ("Simplify" ++ if switchIsOn simpl_sw_chkr SimplDoFoldrBuild
                                         then " (foldr/build)" else "") `thenMn_`
            -> BSCC("CoreSimplify")
               begin_pass ("Simplify" ++ if switchIsOn simpl_sw_chkr SimplDoFoldrBuild
                                         then " (foldr/build)" else "") `thenMn_`
-              case (simplifyPgm binds sw_chkr simpl_sw_chkr simpl_stats us1) of
+              case (simplifyPgm binds simpl_sw_chkr simpl_stats us1) of
                 (p, it_cnt, simpl_stats2)
                   -> end_pass False us2 p inline_env spec_data simpl_stats2
                               ("Simplify (" ++ show it_cnt ++ ")"
                 (p, it_cnt, simpl_stats2)
                   -> end_pass False us2 p inline_env spec_data simpl_stats2
                               ("Simplify (" ++ show it_cnt ++ ")"
@@ -135,14 +158,14 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
          CoreDoFoldrBuildWorkerWrapper
            -> BSCC("CoreDoFoldrBuildWorkerWrapper")
               begin_pass "FBWW" `thenMn_`
          CoreDoFoldrBuildWorkerWrapper
            -> BSCC("CoreDoFoldrBuildWorkerWrapper")
               begin_pass "FBWW" `thenMn_`
-              case (mkFoldrBuildWW switch_is_on us1 binds) of { binds2 ->
+              case (mkFoldrBuildWW us1 binds) of { binds2 ->
               end_pass False us2 binds2 inline_env spec_data simpl_stats "FBWW"
               } ESCC
 
          CoreDoFoldrBuildWWAnal
            -> BSCC("CoreDoFoldrBuildWWAnal")
               begin_pass "AnalFBWW" `thenMn_`
               end_pass False us2 binds2 inline_env spec_data simpl_stats "FBWW"
               } ESCC
 
          CoreDoFoldrBuildWWAnal
            -> BSCC("CoreDoFoldrBuildWWAnal")
               begin_pass "AnalFBWW" `thenMn_`
-              case (analFBWW switch_is_on binds) of { binds2 ->
+              case (analFBWW binds) of { binds2 ->
               end_pass False us2 binds2 inline_env spec_data simpl_stats "AnalFBWW"
               } ESCC
 
               end_pass False us2 binds2 inline_env spec_data simpl_stats "AnalFBWW"
               } ESCC
 
@@ -156,14 +179,14 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
          CoreDoCalcInlinings1  -- avoid inlinings w/ cost-centres
            -> BSCC("CoreInlinings1")
               begin_pass "CalcInlinings" `thenMn_`
          CoreDoCalcInlinings1  -- avoid inlinings w/ cost-centres
            -> BSCC("CoreInlinings1")
               begin_pass "CalcInlinings" `thenMn_`
-              case (calcInlinings False sw_chkr inline_env binds) of { inline_env2 ->
+              case (calcInlinings False inline_env binds) of { inline_env2 ->
               end_pass False us2 binds inline_env2 spec_data simpl_stats "CalcInlinings"
               } ESCC
 
          CoreDoCalcInlinings2  -- allow inlinings w/ cost-centres
            -> BSCC("CoreInlinings2")
               begin_pass "CalcInlinings" `thenMn_`
               end_pass False us2 binds inline_env2 spec_data simpl_stats "CalcInlinings"
               } ESCC
 
          CoreDoCalcInlinings2  -- allow inlinings w/ cost-centres
            -> BSCC("CoreInlinings2")
               begin_pass "CalcInlinings" `thenMn_`
-              case (calcInlinings True sw_chkr inline_env binds) of { inline_env2 ->
+              case (calcInlinings True inline_env binds) of { inline_env2 ->
               end_pass False us2 binds inline_env2 spec_data simpl_stats "CalcInlinings"
               } ESCC
 
               end_pass False us2 binds inline_env2 spec_data simpl_stats "CalcInlinings"
               } ESCC
 
@@ -177,7 +200,7 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
          CoreDoFullLaziness
            -> BSCC("CoreFloating")
               begin_pass "FloatOut" `thenMn_`
          CoreDoFullLaziness
            -> BSCC("CoreFloating")
               begin_pass "FloatOut" `thenMn_`
-              case (floatOutwards switch_is_on us1 binds) of { binds2 ->
+              case (floatOutwards us1 binds) of { binds2 ->
               end_pass False us2 binds2 inline_env spec_data simpl_stats "FloatOut"
               } ESCC
 
               end_pass False us2 binds2 inline_env spec_data simpl_stats "FloatOut"
               } ESCC
 
@@ -194,20 +217,20 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
          CoreDoStrictness
            -> BSCC("CoreStranal")
               begin_pass "StrAnal" `thenMn_`
          CoreDoStrictness
            -> BSCC("CoreStranal")
               begin_pass "StrAnal" `thenMn_`
-              case (saWwTopBinds us1 switch_is_on binds) of { binds2 ->
+              case (saWwTopBinds us1 binds) of { binds2 ->
               end_pass False us2 binds2 inline_env spec_data simpl_stats "StrAnal"
               } ESCC
 
          CoreDoSpecialising
            -> BSCC("Specialise")
               begin_pass "Specialise" `thenMn_`
               end_pass False us2 binds2 inline_env spec_data simpl_stats "StrAnal"
               } ESCC
 
          CoreDoSpecialising
            -> BSCC("Specialise")
               begin_pass "Specialise" `thenMn_`
-              case (specProgram switch_is_on us1 binds spec_data) of {
+              case (specProgram us1 binds spec_data) of {
                 (p, spec_data2@(SpecData _ spec_noerrs _ _ _
                                          spec_errs spec_warn spec_tyerrs)) ->
 
                   -- if we got errors, we die straight away
                   (if not spec_noerrs ||
                 (p, spec_data2@(SpecData _ spec_noerrs _ _ _
                                          spec_errs spec_warn spec_tyerrs)) ->
 
                   -- if we got errors, we die straight away
                   (if not spec_noerrs ||
-                      (switch_is_on ShowImportSpecs && not (isEmptyBag spec_warn)) then
+                      (opt_ShowImportSpecs && not (isEmptyBag spec_warn)) then
                        writeMn stderr (ppShow 1000 {-pprCols-}
                            (pprSpecErrs module_name spec_errs spec_warn spec_tyerrs))
                        `thenMn_` writeMn stderr "\n"
                        writeMn stderr (ppShow 1000 {-pprCols-}
                            (pprSpecErrs module_name spec_errs spec_warn spec_tyerrs))
                        `thenMn_` writeMn stderr "\n"
@@ -229,7 +252,7 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
 #else
            -> BSCC("Deforestation")
               begin_pass "Deforestation" `thenMn_`
 #else
            -> BSCC("Deforestation")
               begin_pass "Deforestation" `thenMn_`
-              case (deforestProgram sw_chkr binds us1) of { binds2 ->
+              case (deforestProgram binds us1) of { binds2 ->
               end_pass False us2 binds2 inline_env spec_data simpl_stats "Deforestation"
               }
               ESCC
               end_pass False us2 binds2 inline_env spec_data simpl_stats "Deforestation"
               }
               ESCC
@@ -238,7 +261,7 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
          CoreDoAutoCostCentres
            -> BSCC("AutoSCCs")
               begin_pass "AutoSCCs" `thenMn_`
          CoreDoAutoCostCentres
            -> BSCC("AutoSCCs")
               begin_pass "AutoSCCs" `thenMn_`
-              case (addAutoCostCentres sw_chkr module_name binds) of { binds2 ->
+              case (addAutoCostCentres module_name binds) of { binds2 ->
               end_pass False us2 binds2 inline_env spec_data simpl_stats "AutoSCCs"
               }
               ESCC
               end_pass False us2 binds2 inline_env spec_data simpl_stats "AutoSCCs"
               }
               ESCC
@@ -250,7 +273,7 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
     -------------------------------------------------
 
     begin_pass
     -------------------------------------------------
 
     begin_pass
-      = if switch_is_on D_show_passes
+      = if opt_D_show_passes
        then \ what -> writeMn stderr ("*** Core2Core: "++what++"\n")
        else \ what -> returnMn ()
 
        then \ what -> writeMn stderr ("*** Core2Core: "++what++"\n")
        else \ what -> returnMn ()
 
@@ -264,7 +287,7 @@ core2core core_todos sw_chkr module_name ppr_style us local_tycons tycon_specs b
            writeMn stderr ("\n*** "++what++":\n")
                `thenMn_`
            writeMn stderr (ppShow 1000
            writeMn stderr ("\n*** "++what++":\n")
                `thenMn_`
            writeMn stderr (ppShow 1000
-               (ppAboves (map (pprPlainCoreBinding ppr_style) binds2)))
+               (ppAboves (map (pprCoreBinding ppr_style) binds2)))
                `thenMn_`
            writeMn stderr "\n"
         else
                `thenMn_`
            writeMn stderr "\n"
         else
@@ -307,12 +330,11 @@ will be visible on the other side of an interface, too.
 
 \begin{code}
 calcInlinings :: Bool  -- True => inlinings with _scc_s are OK
 
 \begin{code}
 calcInlinings :: Bool  -- True => inlinings with _scc_s are OK
-             -> (GlobalSwitch -> SwitchResult)
              -> IdEnv UnfoldingDetails
              -> [CoreBinding]
              -> IdEnv UnfoldingDetails
 
              -> IdEnv UnfoldingDetails
              -> [CoreBinding]
              -> IdEnv UnfoldingDetails
 
-calcInlinings scc_s_OK sw_chkr inline_env_so_far top_binds
+calcInlinings scc_s_OK inline_env_so_far top_binds
   = let
        result = foldl calci inline_env_so_far top_binds
     in
   = let
        result = foldl calci inline_env_so_far top_binds
     in
@@ -323,30 +345,28 @@ calcInlinings scc_s_OK sw_chkr inline_env_so_far top_binds
       = ppCat [ppr PprDebug binder, ppStr "=>", pp_det details]
       where
        pp_det NoUnfoldingDetails   = ppStr "_N_"
       = ppCat [ppr PprDebug binder, ppStr "=>", pp_det details]
       where
        pp_det NoUnfoldingDetails   = ppStr "_N_"
-       pp_det (IWantToBeINLINEd _) = ppStr "INLINE"
+--LATER:       pp_det (IWantToBeINLINEd _) = ppStr "INLINE"
        pp_det (GenForm _ _ expr guide)
          = ppAbove (ppr PprDebug guide) (ppr PprDebug expr)
        pp_det other                = ppStr "???"
 
     ------------
        pp_det (GenForm _ _ expr guide)
          = ppAbove (ppr PprDebug guide) (ppr PprDebug expr)
        pp_det other                = ppStr "???"
 
     ------------
-    switch_is_on = switchIsOn sw_chkr
-
-    my_trace =  if (switch_is_on ReportWhyUnfoldingsDisallowed)
+    my_trace =  if opt_ReportWhyUnfoldingsDisallowed
                then trace
                else \ msg stuff -> stuff
 
     (unfolding_creation_threshold, explicit_creation_threshold)
                then trace
                else \ msg stuff -> stuff
 
     (unfolding_creation_threshold, explicit_creation_threshold)
-      = case (intSwitchSet sw_chkr UnfoldingCreationThreshold) of
+      = case opt_UnfoldingCreationThreshold of
          Nothing -> (uNFOLDING_CREATION_THRESHOLD, False)
          Just xx -> (xx, True)
 
     unfold_use_threshold
          Nothing -> (uNFOLDING_CREATION_THRESHOLD, False)
          Just xx -> (xx, True)
 
     unfold_use_threshold
-      = case (intSwitchSet sw_chkr UnfoldingUseThreshold) of
+      = case opt_UnfoldingUseThreshold of
          Nothing -> uNFOLDING_USE_THRESHOLD
          Just xx -> xx
 
     unfold_override_threshold
          Nothing -> uNFOLDING_USE_THRESHOLD
          Just xx -> xx
 
     unfold_override_threshold
-      = case (intSwitchSet sw_chkr UnfoldingOverrideThreshold) of
+      = case opt_UnfoldingOverrideThreshold of
          Nothing -> uNFOLDING_OVERRIDE_THRESHOLD
          Just xx -> xx
 
          Nothing -> uNFOLDING_OVERRIDE_THRESHOLD
          Just xx -> xx
 
@@ -378,20 +398,15 @@ calcInlinings scc_s_OK sw_chkr inline_env_so_far top_binds
 
            which = if scc_s_OK then " (late):" else " (early):"
        in
 
            which = if scc_s_OK then " (late):" else " (early):"
        in
-       --pprTrace "giving up on size:" (ppCat [ppr PprDebug binder, ppr PprDebug
-       --      [rhs_mentions_an_unmentionable, explicit_INLINE_requested,
-       --       rhs_looks_like_a_caf, guidance_says_don't, guidance_size_too_big]]) (
        my_my_trace ("unfolding disallowed for"++which++(ppShow 80 (ppr PprDebug binder))) (
        ignominious_defeat
        )
        my_my_trace ("unfolding disallowed for"++which++(ppShow 80 (ppr PprDebug binder))) (
        ignominious_defeat
        )
-       --)
 
       | rhs `isWrapperFor` binder
        -- Don't add an explicit "unfolding"; let the worker/wrapper
        -- stuff do its thing.  INLINE things don't get w/w'd, so
        -- they will be OK.
 
       | rhs `isWrapperFor` binder
        -- Don't add an explicit "unfolding"; let the worker/wrapper
        -- stuff do its thing.  INLINE things don't get w/w'd, so
        -- they will be OK.
-      = --pprTrace "giving up on isWrapperFor:" (ppr PprDebug binder)
-       ignominious_defeat
+      = ignominious_defeat
 
 #if ! OMIT_DEFORESTER
        -- For the deforester: bypass the barbed wire for recursive
 
 #if ! OMIT_DEFORESTER
        -- For the deforester: bypass the barbed wire for recursive
@@ -474,8 +489,8 @@ calcInlinings scc_s_OK sw_chkr inline_env_so_far top_binds
 
        rhs_looks_like_a_data_val
          = case (collectBinders rhs) of
 
        rhs_looks_like_a_data_val
          = case (collectBinders rhs) of
-             (_, _, [], Con _ _ _) -> True
-             other                 -> False
+             (_, _, [], Con _ _) -> True
+             other               -> False
 
        rhs_arg_tys
          = case (collectBinders rhs) of
 
        rhs_arg_tys
          = case (collectBinders rhs) of
@@ -485,13 +500,11 @@ calcInlinings scc_s_OK sw_chkr inline_env_so_far top_binds
          = mentionedInUnfolding (\x -> x) rhs
 
        rhs_mentions_an_unmentionable
          = mentionedInUnfolding (\x -> x) rhs
 
        rhs_mentions_an_unmentionable
-         = --pprTrace "mentions:" (ppCat [ppr PprDebug binder, ppr PprDebug [(i,unfoldingUnfriendlyId i) | i <- mentioned_ids ]]) (
-           any unfoldingUnfriendlyId mentioned_ids
+         = foldBag (||) unfoldingUnfriendlyId False mentioned_ids
            || mentions_litlit
            || mentions_litlit
-           --)
            -- ToDo: probably need to chk tycons/classes...
 
            -- ToDo: probably need to chk tycons/classes...
 
-       mentions_no_other_ids = null mentioned_ids
+       mentions_no_other_ids = isEmptyBag mentioned_ids
 
        explicit_INLINE_requested
            -- did it come from a user {-# INLINE ... #-}?
 
        explicit_INLINE_requested
            -- did it come from a user {-# INLINE ... #-}?
@@ -530,7 +543,7 @@ calcInlinings scc_s_OK sw_chkr inline_env_so_far top_binds
          = let
                new_env = addOneToIdEnv inline_env binder (mkUnfolding guidance rhs)
 
          = let
                new_env = addOneToIdEnv inline_env binder (mkUnfolding guidance rhs)
 
-               foldr_building = switch_is_on FoldrBuildOn
+               foldr_building = opt_FoldrBuildOn
            in
            if (not have_inlining_already) then
                -- Not in env: we take it no matter what
            in
            if (not have_inlining_already) then
                -- Not in env: we take it no matter what
index 6712d6a..ee87e0a 100644 (file)
@@ -58,6 +58,7 @@ import CoreUnfold     ( UnfoldingDetails(..), mkGenForm, modifyUnfoldingDetails,
                        )
 import FiniteMap       -- lots of things
 import Id              ( idType, getIdUnfolding, getIdStrictness,
                        )
 import FiniteMap       -- lots of things
 import Id              ( idType, getIdUnfolding, getIdStrictness,
+                         applyTypeEnvToId,
                          nullIdEnv, growIdEnvList, rngIdEnv, lookupIdEnv,
                          addOneToIdEnv, modifyIdEnv,
                          IdEnv(..), IdSet(..), GenId )
                          nullIdEnv, growIdEnvList, rngIdEnv, lookupIdEnv,
                          addOneToIdEnv, modifyIdEnv,
                          IdEnv(..), IdSet(..), GenId )
@@ -68,19 +69,18 @@ import PprCore              -- various instances
 import PprStyle                ( PprStyle(..) )
 import PprType         ( GenType, GenTyVar )
 import Pretty
 import PprStyle                ( PprStyle(..) )
 import PprType         ( GenType, GenTyVar )
 import Pretty
-import Type            ( getAppDataTyCon )
+import Type            ( getAppDataTyCon, applyTypeEnvToTy )
 import TyVar           ( nullTyVarEnv, addOneToIdEnv, addOneToTyVarEnv,
                          growTyVarEnvList,
 import TyVar           ( nullTyVarEnv, addOneToIdEnv, addOneToTyVarEnv,
                          growTyVarEnvList,
-                         TyVarEnv(..), GenTyVar )
-import Unique          ( Unique )
+                         TyVarEnv(..), GenTyVar{-instance Eq-}
+                       )
+import Unique          ( Unique{-instance Outputable-} )
 import UniqSet         -- lots of things
 import Usage           ( UVar(..), GenUsage{-instances-} )
 import Util            ( zipEqual, panic, assertPanic )
 
 type TypeEnv = TyVarEnv Type
 addToUFM_Directly = panic "addToUFM_Directly (SimplEnv)"
 import UniqSet         -- lots of things
 import Usage           ( UVar(..), GenUsage{-instances-} )
 import Util            ( zipEqual, panic, assertPanic )
 
 type TypeEnv = TyVarEnv Type
 addToUFM_Directly = panic "addToUFM_Directly (SimplEnv)"
-applyTypeEnvToId = panic "applyTypeEnvToId (SimplEnv)"
-applyTypeEnvToTy = panic "applyTypeEnvToTy (SimplEnv)"
 bottomIsGuaranteed = panic "bottomIsGuaranteed (SimplEnv)"
 cmpType = panic "cmpType (SimplEnv)"
 exprSmallEnoughToDup = panic "exprSmallEnoughToDup (SimplEnv)"
 bottomIsGuaranteed = panic "bottomIsGuaranteed (SimplEnv)"
 cmpType = panic "cmpType (SimplEnv)"
 exprSmallEnoughToDup = panic "exprSmallEnoughToDup (SimplEnv)"
@@ -303,7 +303,7 @@ grow_unfold_env (UFE u_env interesting_ids con_apps) id
     -- Only interested in Ids which have a "dangerous" unfolding; that is
     -- one that claims to have a single occurrence.
   = UFE (addOneToIdEnv u_env id (UnfoldItem id uf_details encl_cc))
     -- Only interested in Ids which have a "dangerous" unfolding; that is
     -- one that claims to have a single occurrence.
   = UFE (addOneToIdEnv u_env id (UnfoldItem id uf_details encl_cc))
-       (interesting_ids `unionUniqSets` singletonUniqSet id)
+       (addOneToUniqSet interesting_ids id)
        con_apps
 
 grow_unfold_env (UFE u_env interesting_ids con_apps) id uf_details encl_cc
        con_apps
 
 grow_unfold_env (UFE u_env interesting_ids con_apps) id uf_details encl_cc
@@ -496,7 +496,6 @@ extendTyEnvList (SimplEnv chkr encl_cc ty_env id_env unfold_env) pairs
     new_ty_env = growTyVarEnvList ty_env pairs
 
 simplTy     (SimplEnv _ _ ty_env _ _) ty = applyTypeEnvToTy ty_env ty
     new_ty_env = growTyVarEnvList ty_env pairs
 
 simplTy     (SimplEnv _ _ ty_env _ _) ty = applyTypeEnvToTy ty_env ty
-
 simplTyInId (SimplEnv _ _ ty_env _ _) id = applyTypeEnvToId ty_env id
 \end{code}
 
 simplTyInId (SimplEnv _ _ ty_env _ _) id = applyTypeEnvToId ty_env id
 \end{code}
 
@@ -768,7 +767,7 @@ extendUnfoldEnvGivenRhs env@(SimplEnv chkr encl_cc ty_env id_env unfold_env)
        -- (This is brought to you by *ANDY* Magic Constants, Inc.)
     is_really_small
       = case collectArgs new_rhs of
        -- (This is brought to you by *ANDY* Magic Constants, Inc.)
     is_really_small
       = case collectArgs new_rhs of
-         (Var _, xs) -> length xs < 10
+         (Var _, _, _, xs) -> length xs < 10
          _ -> False
 -}
 \end{code}
          _ -> False
 -}
 \end{code}
index bc8fac7..1569843 100644 (file)
@@ -26,18 +26,16 @@ import Ubiq{-uitous-}
 
 import SmplLoop                -- well, cheating sort of
 
 
 import SmplLoop                -- well, cheating sort of
 
-import Id              ( mkSysLocal )
+import Id              ( mkSysLocal, mkIdWithNewUniq )
 import SimplEnv
 import SrcLoc          ( mkUnknownSrcLoc )
 import SimplEnv
 import SrcLoc          ( mkUnknownSrcLoc )
+import TyVar           ( cloneTyVar )
 import UniqSupply      ( getUnique, getUniques, splitUniqSupply,
                          UniqSupply
                        )
 import Util            ( zipWithEqual, panic )
 
 infixr 9  `thenSmpl`, `thenSmpl_`
 import UniqSupply      ( getUnique, getUniques, splitUniqSupply,
                          UniqSupply
                        )
 import Util            ( zipWithEqual, panic )
 
 infixr 9  `thenSmpl`, `thenSmpl_`
-
-cloneTyVar = panic "cloneTyVar (SimplMonad)"
-mkIdWithNewUniq = panic "mkIdWithNewUniq (SimplMonad)"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index ee791a6..dc9d1c4 100644 (file)
@@ -1,47 +1,52 @@
 %
 %
-% (c) The AQUA Project, Glasgow University, 1993-1995
+% (c) The AQUA Project, Glasgow University, 1993-1996
 %
 %
-\section[SimplPgm]{Interface to the ``new'' simplifier}
+\section[SimplPgm]{Interface to the simplifier}
 
 \begin{code}
 #include "HsVersions.h"
 
 module SimplPgm ( simplifyPgm ) where
 
 
 \begin{code}
 #include "HsVersions.h"
 
 module SimplPgm ( simplifyPgm ) where
 
-import Type            ( getTyVarMaybe )
-import CmdLineOpts     ( switchIsOn, intSwitchSet,
-                         GlobalSwitch(..), SimplifierSwitch(..)
+import Ubiq{-uitous-}
+
+import CmdLineOpts     ( opt_D_verbose_core2core,
+                         switchIsOn, intSwitchSet, SimplifierSwitch(..)
+                       )
+import CoreSyn
+import CoreUtils       ( substCoreExpr )
+import Id              ( externallyVisibleId,
+                         mkIdEnv, lookupIdEnv, IdEnv(..),
+                         GenId{-instance Ord3-}
                        )
                        )
-import Id              ( externallyVisibleId )
-import IdInfo
-import Maybes          ( catMaybes, Maybe(..) )
-import Outputable
+import Maybes          ( catMaybes )
+import OccurAnal       ( occurAnalyseBinds )
+import Outputable      ( isExported )
+import Pretty          ( ppAboves, ppBesides, ppInt, ppChar, ppStr )
 import SimplEnv
 import SimplMonad
 import Simplify                ( simplTopBinds )
 import SimplEnv
 import SimplMonad
 import Simplify                ( simplTopBinds )
-import OccurAnal       -- occurAnalyseBinds
-import UniqSupply
-import Util
+import TyVar           ( nullTyVarEnv, TyVarEnv(..) )
+import UniqSupply      ( thenUs, returnUs, mapUs, splitUniqSupply, UniqSM(..) )
+import Util            ( isIn, isn'tIn, removeDups, pprTrace )
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-simplifyPgm :: [CoreBinding]           -- input
-           -> (GlobalSwitch->SwitchResult)     -- switch lookup fns (global
-           -> (SimplifierSwitch->SwitchResult) -- and this-simplification-specific)
-           -> SimplCount                       -- info about how many times
-                                               -- each transformation has occurred
+simplifyPgm :: [CoreBinding]   -- input
+           -> (SimplifierSwitch->SwitchResult)
+           -> SimplCount       -- info about how many times
+                               -- each transformation has occurred
            -> UniqSupply
            -> ([CoreBinding],  -- output
            -> UniqSupply
            -> ([CoreBinding],  -- output
-                Int,                   -- info about how much happened
-                SimplCount)            -- accumulated simpl stats
+                Int,           -- info about how much happened
+                SimplCount)    -- accumulated simpl stats
 
 
-simplifyPgm binds g_sw_chkr s_sw_chkr simpl_stats us
+simplifyPgm binds s_sw_chkr simpl_stats us
   = case (splitUniqSupply us)               of { (s1, s2) ->
     case (initSmpl s1 (simpl_pgm 0 1 binds)) of { ((pgm2, it_count, simpl_stats2), _) ->
     case (tidy_top pgm2 s2)                 of { pgm3 ->
     (pgm3, it_count, combineSimplCounts simpl_stats simpl_stats2) }}}
   where
   = case (splitUniqSupply us)               of { (s1, s2) ->
     case (initSmpl s1 (simpl_pgm 0 1 binds)) of { ((pgm2, it_count, simpl_stats2), _) ->
     case (tidy_top pgm2 s2)                 of { pgm3 ->
     (pgm3, it_count, combineSimplCounts simpl_stats simpl_stats2) }}}
   where
-    global_switch_is_on = switchIsOn g_sw_chkr
     simpl_switch_is_on  = switchIsOn s_sw_chkr
 
     occur_anal = occurAnalyseBinds
     simpl_switch_is_on  = switchIsOn s_sw_chkr
 
     occur_anal = occurAnalyseBinds
@@ -56,11 +61,8 @@ simplifyPgm binds g_sw_chkr s_sw_chkr simpl_stats us
     simpl_pgm n iterations pgm
       =        -- find out what top-level binders are used,
        -- and prepare to unfold all the "simple" bindings
     simpl_pgm n iterations pgm
       =        -- find out what top-level binders are used,
        -- and prepare to unfold all the "simple" bindings
-       -- pprTrace ("\niteration "++show iterations++":\n") (ppr PprDebug pgm) (
        let
        let
-           tagged_pgm = BSCC("OccurBinds")
-                        occur_anal pgm global_switch_is_on simpl_switch_is_on
-                        ESCC
+           tagged_pgm = occur_anal pgm simpl_switch_is_on
        in
              -- do the business
        simplTopBinds (nullSimplEnv s_sw_chkr) tagged_pgm `thenSmpl` \ new_pgm ->
        in
              -- do the business
        simplTopBinds (nullSimplEnv s_sw_chkr) tagged_pgm `thenSmpl` \ new_pgm ->
@@ -74,11 +76,11 @@ simplifyPgm binds g_sw_chkr s_sw_chkr simpl_stats us
            show_status = pprTrace "NewSimpl: " (ppAboves [
                ppBesides [ppInt iterations, ppChar '/', ppInt max_simpl_iterations],
                ppStr (showSimplCount dr)
            show_status = pprTrace "NewSimpl: " (ppAboves [
                ppBesides [ppInt iterations, ppChar '/', ppInt max_simpl_iterations],
                ppStr (showSimplCount dr)
---DEBUG:       , ppAboves (map (pprPlainCoreBinding PprDebug) new_pgm)
+--DEBUG:       , ppAboves (map (pprCoreBinding PprDebug) new_pgm)
                ])
        in
 
                ])
        in
 
-       (if global_switch_is_on D_verbose_core2core
+       (if opt_D_verbose_core2core
         || simpl_switch_is_on  ShowSimplifierProgress
         then show_status
         else id)
         || simpl_switch_is_on  ShowSimplifierProgress
         then show_status
         else id)
@@ -98,7 +100,6 @@ simplifyPgm binds g_sw_chkr s_sw_chkr simpl_stats us
        else
            simpl_pgm r (iterations + 1) new_pgm
        )
        else
            simpl_pgm r (iterations + 1) new_pgm
        )
-       -- )
 \end{code}
 
 In @tidy_top@, we look for things at the top-level of the form...
 \end{code}
 
 In @tidy_top@, we look for things at the top-level of the form...
@@ -131,10 +132,8 @@ tidy_top binds_in
   = if null blast_alist then
        returnUs binds_in    -- no joy there
     else
   = if null blast_alist then
        returnUs binds_in    -- no joy there
     else
-       -- pprTrace "undup output length:" (ppInt (length blast_alist)) (
        mapUs blast binds_in    `thenUs` \ binds_maybe ->
        returnUs (catMaybes binds_maybe)
        mapUs blast binds_in    `thenUs` \ binds_maybe ->
        returnUs (catMaybes binds_maybe)
-       -- )
   where
     blast_alist  = undup (foldl find_cand [] binds_in)
     blast_id_env = mkIdEnv blast_alist
   where
     blast_alist  = undup (foldl find_cand [] binds_in)
     blast_id_env = mkIdEnv blast_alist
@@ -158,13 +157,11 @@ tidy_top binds_in
     undup :: [(Id, Id)] -> [(Id, Id)]
 
     undup blast_list
     undup :: [(Id, Id)] -> [(Id, Id)]
 
     undup blast_list
-      = -- pprTrace "undup input length:" (ppInt (length blast_list)) (
-       let
+      = let
            (singles, dups) = removeDups compare blast_list
            list_of_dups    = concat dups
        in
        [ s | s <- singles, s `not_elem` list_of_dups ]
            (singles, dups) = removeDups compare blast_list
            list_of_dups    = concat dups
        in
        [ s | s <- singles, s `not_elem` list_of_dups ]
-       -- )
       where
        compare (x,_) (y,_) = x `cmp` y
 
       where
        compare (x,_) (y,_) = x `cmp` y
 
@@ -186,25 +183,23 @@ tidy_top binds_in
        returnUs (Just (Rec blasted_pairs))
       where
        blast_pr (binder, rhs)
        returnUs (Just (Rec blasted_pairs))
       where
        blast_pr (binder, rhs)
-         = subst_CoreExprUS blast_val_env nullTyVarEnv rhs `thenUs` \ blasted_rhs ->
+         = substCoreExpr blast_val_env nullTyVarEnv rhs `thenUs` \ new_rhs ->
            returnUs (
            returnUs (
-           case lookupIdEnv blast_id_env binder of
-             Just exportee -> (exportee, blasted_rhs)
-             Nothing       -> (binder,   blasted_rhs)
+           case (lookupIdEnv blast_id_env binder) of
+             Just exportee -> (exportee, new_rhs)
+             Nothing       -> (binder,   new_rhs)
            )
 
     blast (NonRec binder rhs)
       = if binder `is_elem` blast_all_exps then
           returnUs Nothing -- this binding dies!
        else
            )
 
     blast (NonRec binder rhs)
       = if binder `is_elem` blast_all_exps then
           returnUs Nothing -- this binding dies!
        else
-          subst_CoreExprUS blast_val_env nullTyVarEnv rhs `thenUs` \ blasted_rhs ->
+          substCoreExpr blast_val_env nullTyVarEnv rhs `thenUs` \ new_rhs ->
           returnUs (Just (
           returnUs (Just (
-          case lookupIdEnv blast_id_env binder of
-            Just exportee -> NonRec exportee blasted_rhs
-            Nothing       -> NonRec binder   blasted_rhs
+          case (lookupIdEnv blast_id_env binder) of
+            Just exportee -> NonRec exportee new_rhs
+            Nothing       -> NonRec binder   new_rhs
           ))
       where
        is_elem = isIn "blast"
           ))
       where
        is_elem = isIn "blast"
-
-subst_CoreExprUS e1 e2 rhs us = snd (substCoreExprUS e1 e2 rhs (mkUniqueSupplyGrimily us))
 \end{code}
 \end{code}
index 3f5c1a5..f546fbc 100644 (file)
@@ -24,18 +24,23 @@ module SimplUtils (
 import Ubiq{-uitous-}
 
 import BinderInfo
 import Ubiq{-uitous-}
 
 import BinderInfo
+import CmdLineOpts     ( SimplifierSwitch(..) )
 import CoreSyn
 import CoreUtils       ( manifestlyWHNF )
 import CoreSyn
 import CoreUtils       ( manifestlyWHNF )
-import Id              ( idType, isBottomingId, getIdArity )
+import Id              ( idType, isBottomingId, idWantsToBeINLINEd,
+                         getIdArity, GenId{-instance Eq-}
+                       )
 import IdInfo          ( arityMaybe )
 import Maybes          ( maybeToBool )
 import PrelInfo                ( augmentId, buildId, realWorldStateTy )
 import IdInfo          ( arityMaybe )
 import Maybes          ( maybeToBool )
 import PrelInfo                ( augmentId, buildId, realWorldStateTy )
+import PrimOp          ( primOpIsCheap )
 import SimplEnv
 import SimplMonad
 import SimplEnv
 import SimplMonad
-import Type            ( isPrimType, maybeAppDataTyCon, getTyVar_maybe )
+import Type            ( eqTy, isPrimType, maybeAppDataTyCon, getTyVar_maybe )
+import TyVar           ( GenTyVar{-instance Eq-} )
 import Util            ( isIn, panic )
 
 import Util            ( isIn, panic )
 
-primOpIsCheap = panic "SimplUtils. (ToDo)"
+getInstantiatedDataConSig =  panic "SimplUtils.getInstantiatedDataConSig (ToDo)"
 \end{code}
 
 
 \end{code}
 
 
@@ -50,13 +55,13 @@ floatExposesHNF
        :: Bool                 -- Float let(rec)s out of rhs
        -> Bool                 -- Float cheap primops out of rhs
        -> Bool                 -- OK to duplicate code
        :: Bool                 -- Float let(rec)s out of rhs
        -> Bool                 -- Float cheap primops out of rhs
        -> Bool                 -- OK to duplicate code
-       -> GenCoreExpr bdr Id
+       -> GenCoreExpr bdr Id tyvar uvar
        -> Bool
 
 floatExposesHNF float_lets float_primops ok_to_dup rhs
   = try rhs
   where
        -> Bool
 
 floatExposesHNF float_lets float_primops ok_to_dup rhs
   = try rhs
   where
-    try (Case (Prim _ _ _) (PrimAlts alts deflt) )
+    try (Case (Prim _ _) (PrimAlts alts deflt) )
       | float_primops && (null alts || ok_to_dup)
       = or (try_deflt deflt : map try_alt alts)
 
       | float_primops && (null alts || ok_to_dup)
       = or (try_deflt deflt : map try_alt alts)
 
@@ -132,7 +137,7 @@ mkValLamTryingEta orig_ids body
 
     reduce_it (id:ids) (App fun (VarArg arg))
       | id == arg
 
     reduce_it (id:ids) (App fun (VarArg arg))
       | id == arg
-      && idType id /= realWorldStateTy
+      && not (idType id `eqTy` realWorldStateTy)
         -- *never* eta-reduce away a PrimIO state token! (WDP 94/11)
       = reduce_it ids fun
 
         -- *never* eta-reduce away a PrimIO state token! (WDP 94/11)
       = reduce_it ids fun
 
@@ -171,7 +176,7 @@ arguments as you care to give it.  For this special case we return
 100, to represent "infinity", which is a bit of a hack.
 
 \begin{code}
 100, to represent "infinity", which is a bit of a hack.
 
 \begin{code}
-etaExpandCount :: GenCoreExpr bdr Id
+etaExpandCount :: GenCoreExpr bdr Id tyvar uvar
               -> Int   -- Number of extra args you can safely abstract
 
 etaExpandCount (Lam (ValBinder _) body)
               -> Int   -- Number of extra args you can safely abstract
 
 etaExpandCount (Lam (ValBinder _) body)
@@ -200,8 +205,8 @@ etaExpandCount other = 0    -- Give up
        -- Case with non-whnf scrutinee
 
 -----------------------------
        -- Case with non-whnf scrutinee
 
 -----------------------------
-eta_fun :: GenCoreExpr bdr Id  -- The function
-       -> Int                  -- How many args it can safely be applied to
+eta_fun :: GenCoreExpr bdr Id tv uv -- The function
+       -> Int                      -- How many args it can safely be applied to
 
 eta_fun (App fun arg) | notValArg arg = eta_fun fun
 
 
 eta_fun (App fun arg) | notValArg arg = eta_fun fun
 
@@ -240,17 +245,14 @@ which aren't WHNF but are ``cheap'' are:
        where op is a cheap primitive operator
 
 \begin{code}
        where op is a cheap primitive operator
 
 \begin{code}
-manifestlyCheap :: GenCoreExpr bndr Id -> Bool
+manifestlyCheap :: GenCoreExpr bndr Id tv uv -> Bool
 
 
-manifestlyCheap (Var _)       = True
-manifestlyCheap (Lit _)       = True
-manifestlyCheap (Con _ _ _)   = True
-manifestlyCheap (SCC _ e)     = manifestlyCheap e
-
-manifestlyCheap (Lam (ValBinder _) _) = True
-manifestlyCheap (Lam other_binder e)  = manifestlyCheap e
-
-manifestlyCheap (Prim op _ _) = primOpIsCheap op
+manifestlyCheap (Var _)     = True
+manifestlyCheap (Lit _)     = True
+manifestlyCheap (Con _ _)   = True
+manifestlyCheap (SCC _ e)   = manifestlyCheap e
+manifestlyCheap (Lam x e)   = if isValBinder x then True else manifestlyCheap e
+manifestlyCheap (Prim op _) = primOpIsCheap op
 
 manifestlyCheap (Let bind body)
   = manifestlyCheap body && all manifestlyCheap (rhssOfBind bind)
 
 manifestlyCheap (Let bind body)
   = manifestlyCheap body && all manifestlyCheap (rhssOfBind bind)
@@ -259,7 +261,7 @@ manifestlyCheap (Case scrut alts)
   = manifestlyCheap scrut && all manifestlyCheap (rhssOfAlts alts)
 
 manifestlyCheap other_expr   -- look for manifest partial application
   = manifestlyCheap scrut && all manifestlyCheap (rhssOfAlts alts)
 
 manifestlyCheap other_expr   -- look for manifest partial application
-  = case (collectArgs other_expr) of { (fun, args) ->
+  = case (collectArgs other_expr) of { (fun, _, _, vargs) ->
     case fun of
 
       Var f | isBottomingId f -> True  -- Application of a function which
     case fun of
 
       Var f | isBottomingId f -> True  -- Application of a function which
@@ -268,7 +270,7 @@ manifestlyCheap other_expr   -- look for manifest partial application
                                        -- need to be shared!
 
       Var f -> let
                                        -- need to be shared!
 
       Var f -> let
-                   num_val_args = numValArgs args
+                   num_val_args = length vargs
               in
               num_val_args == 0 ||     -- Just a type application of
                                        -- a variable (f t1 t2 t3)
               in
               num_val_args == 0 ||     -- Just a type application of
                                        -- a variable (f t1 t2 t3)
@@ -381,7 +383,7 @@ mkIdentityAlts rhs_ty
            in
            returnSmpl (
              AlgAlts
            in
            returnSmpl (
              AlgAlts
-               [(data_con, new_binders, Con data_con ty_args (map VarArg new_bindees))]
+               [(data_con, new_binders, mkCon data_con [] ty_args (map VarArg new_bindees))]
                NoDefault
            )
 
                NoDefault
            )
 
index c0a91cd..84555a7 100644 (file)
@@ -11,26 +11,31 @@ module SimplVar (
        leastItCouldCost
     ) where
 
        leastItCouldCost
     ) where
 
-import SimplMonad
-import SimplEnv
-import Literal         ( isNoRepLit )
+import Ubiq{-uitous-}
+import SmplLoop                ( simplExpr )
 
 
-import Type            ( getAppDataTyCon, maybeAppDataTyCon,
-                         getTyConFamilySize, isPrimType
-                       )
-import BinderInfo      ( oneTextualOcc, oneSafeOcc )
 import CgCompInfo      ( uNFOLDING_USE_THRESHOLD,
                          uNFOLDING_CON_DISCOUNT_WEIGHT
                        )
 import CgCompInfo      ( uNFOLDING_USE_THRESHOLD,
                          uNFOLDING_CON_DISCOUNT_WEIGHT
                        )
-import CmdLineOpts     ( switchIsOn, intSwitchSet, SimplifierSwitch(..) )
-import Id              ( idType, getIdInfo )
-import IdInfo
-import Maybes          ( maybeToBool, Maybe(..) )
-import Simplify                ( simplExpr )
-import SimplUtils      ( simplIdWantsToBeINLINEd )
-import MagicUFs
-import Pretty
-import Util
+import CmdLineOpts     ( intSwitchSet, switchIsOn, SimplifierSwitch(..) )
+import CoreSyn
+import CoreUnfold      ( UnfoldingDetails(..), UnfoldingGuidance(..),
+                         FormSummary(..)
+                       )
+import Id              ( idType, getIdInfo,
+                         GenId{-instance Outputable-}
+                       )
+import IdInfo          ( DeforestInfo(..) )
+import Literal         ( isNoRepLit )
+import MagicUFs                ( applyMagicUnfoldingFun, MagicUnfoldingFun )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-} )
+import Pretty          ( ppBesides, ppStr )
+import SimplEnv
+import SimplMonad
+import TyCon           ( tyConFamilySize )
+import Type            ( isPrimType, getAppDataTyCon, maybeAppDataTyCon )
+import Util            ( pprTrace, assertPanic, panic )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -56,11 +61,11 @@ completeVar env var args
        -> ASSERT( null args )
           returnSmpl (Lit lit)
 
        -> ASSERT( null args )
           returnSmpl (Lit lit)
 
-      ConForm con ty_args val_args
+      ConForm con args
                -- Always inline constructors.
                -- See comments before completeLetBinding
        -> ASSERT( null args )
                -- Always inline constructors.
                -- See comments before completeLetBinding
        -> ASSERT( null args )
-          returnSmpl (Con con ty_args val_args)
+          returnSmpl (Con con args)
 
       GenForm txt_occ form_summary template guidance
        -> considerUnfolding env var args
 
       GenForm txt_occ form_summary template guidance
        -> considerUnfolding env var args
@@ -82,7 +87,8 @@ completeVar env var args
                tick MagicUnfold                `thenSmpl_`
                returnSmpl magic_result
 
                tick MagicUnfold                `thenSmpl_`
                returnSmpl magic_result
 
-      IWantToBeINLINEd _ -> returnSmpl boring_result
+-- LATER:
+--    IWantToBeINLINEd _ -> returnSmpl boring_result
 
       other -> returnSmpl boring_result
 \end{code}
 
       other -> returnSmpl boring_result
 \end{code}
@@ -135,7 +141,7 @@ considerUnfolding env var args txt_occ form_summary template guidance
   = go_for_it
 
   | (case form_summary of {BottomForm -> True; other -> False} &&
   = go_for_it
 
   | (case form_summary of {BottomForm -> True; other -> False} &&
-    not (any isPrimType [ ty | (TypeArg ty) <- args ]))
+    not (any isPrimType [ ty | (TyArg ty) <- args ]))
                -- Always inline bottoming applications, unless
                -- there's a primitive type lurking around...
   = go_for_it
                -- Always inline bottoming applications, unless
                -- there's a primitive type lurking around...
   = go_for_it
@@ -193,16 +199,19 @@ considerUnfolding env var args txt_occ form_summary template guidance
     con_discount  -- ToDo: ************ get from a switch *********
       = uNFOLDING_CON_DISCOUNT_WEIGHT
 
     con_discount  -- ToDo: ************ get from a switch *********
       = uNFOLDING_CON_DISCOUNT_WEIGHT
 
-    (tyargs, valargs, args_left) = decomposeArgs args
+    (_, _, tyargs, valargs) = collectArgs args_in_dummy_expr
     no_tyargs  = length tyargs
     no_valargs = length valargs
     no_tyargs  = length tyargs
     no_valargs = length valargs
+    args_in_dummy_expr = mkGenApp (Var (panic "SimplVar.dummy")) args
+    -- we concoct this dummy expr, just so we can use collectArgs
+    -- (rather than make up a special-purpose bit of code)
 
     rhs_looks_like_a_Con
       = let
            (_,_,val_binders,body) = collectBinders template
        in
        case (val_binders, body) of
 
     rhs_looks_like_a_Con
       = let
            (_,_,val_binders,body) = collectBinders template
        in
        case (val_binders, body) of
-         ([], Con _ _ _) -> True
+         ([], Con _ _) -> True
          other -> False
 
     dont_go_for_it = returnSmpl (mkGenApp (Var var) args)
          other -> False
 
     dont_go_for_it = returnSmpl (mkGenApp (Var var) args)
@@ -229,7 +238,7 @@ discountedCost
        -> Int              -- the size/cost of the expr
        -> Int              -- the number of val args (== length args)
        -> ArgInfoVector    -- what we know about the *use* of the arguments
        -> Int              -- the size/cost of the expr
        -> Int              -- the number of val args (== length args)
        -> ArgInfoVector    -- what we know about the *use* of the arguments
-       -> [OutAtom]        -- *an actual set of value arguments*!
+       -> [OutArg]         -- *an actual set of value arguments*!
        -> Int
 
     -- If we apply an expression (usually a function) of given "costs"
        -> Int
 
     -- If we apply an expression (usually a function) of given "costs"
@@ -249,8 +258,7 @@ discountedCost env con_discount_weight size no_args is_con_vec args
            full_price           = disc size
            take_something_off v = let
                                     (tycon, _, _) = getAppDataTyCon (idType v)
            full_price           = disc size
            take_something_off v = let
                                     (tycon, _, _) = getAppDataTyCon (idType v)
-                                    no_cons = case (getTyConFamilySize tycon) of
-                                                Just n -> n
+                                    no_cons = tyConFamilySize tycon
                                     reduced_size
                                       = size - (no_cons * con_discount_weight)
                                   in
                                     reduced_size
                                       = size - (no_cons * con_discount_weight)
                                   in
@@ -262,8 +270,8 @@ discountedCost env con_discount_weight size no_args is_con_vec args
            case arg of
              LitArg _ -> full_price
              VarArg v -> case lookupUnfolding env v of
            case arg of
              LitArg _ -> full_price
              VarArg v -> case lookupUnfolding env v of
-                              ConForm _ _ _ -> take_something_off v
-                              other_form            -> full_price
+                              ConForm _ _ -> take_something_off v
+                              other_form  -> full_price
 
        ) want_cons rest_args
 \end{code}
 
        ) want_cons rest_args
 \end{code}
@@ -294,7 +302,7 @@ leastItCouldCost con_discount_weight size no_val_args is_con_vec arg_tys
       = let
            take_something_off tycon
              = let
       = let
            take_something_off tycon
              = let
-                   no_cons = case (getTyConFamilySize tycon) of { Just n -> n }
+                   no_cons = tyConFamilySize tycon
 
                    reduced_size
                      = size - (no_cons * con_discount_weight)
 
                    reduced_size
                      = size - (no_cons * con_discount_weight)
index 36591fc..962b6d0 100644 (file)
@@ -8,34 +8,38 @@
 
 module Simplify ( simplTopBinds, simplExpr, simplBind ) where
 
 
 module Simplify ( simplTopBinds, simplExpr, simplBind ) where
 
-import Pretty          -- these are for debugging only
-import Outputable
+import Ubiq{-uitous-}
+import SmplLoop                -- paranoia checking
 
 
-import SimplMonad
-import SimplEnv
-
-import PrelInfo                ( getPrimOpResultInfo, PrimOpResultInfo(..),
-                         primOpOkForSpeculation, PrimOp(..), PrimRep,
-                         realWorldStateTy
-                         IF_ATTACK_PRAGMAS(COMMA realWorldTy)
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                       )
-import Type            ( maybeAppDataTyCon, mkTyVarTy, mkTyVarTys, applyTy,
-                         splitTyArgs, splitTypeWithDictsAsArgs,
-                         maybeUnpackFunTy, isPrimType
-                       )
-import Literal         ( isNoRepLit, Literal(..) )
 import BinderInfo
 import CmdLineOpts     ( SimplifierSwitch(..) )
 import ConFold         ( completePrim )
 import BinderInfo
 import CmdLineOpts     ( SimplifierSwitch(..) )
 import ConFold         ( completePrim )
-import Id
-import IdInfo
-import Maybes          ( Maybe(..), catMaybes, maybeToBool )
-import SimplCase
-import SimplUtils
+import CoreSyn
+import CoreUtils       ( coreExprType, nonErrorRHSs, maybeErrorApp,
+                         unTagBinders, squashableDictishCcExpr,
+                         manifestlyWHNF
+                       )
+import Id              ( idType, idWantsToBeINLINEd,
+                         getIdDemandInfo, addIdDemandInfo,
+                         GenId{-instance NamedThing-}
+                       )
+import IdInfo          ( willBeDemanded, DemandInfo )
+import Literal         ( isNoRepLit )
+import Maybes          ( maybeToBool )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-} )
+import PrelInfo                ( realWorldStateTy )
+import Pretty          ( ppAbove )
+import PrimOp          ( primOpOkForSpeculation, PrimOp(..) )
+import SimplCase       ( simplCase, bindLargeRhs )
+import SimplEnv
+import SimplMonad
 import SimplVar                ( completeVar )
 import SimplVar                ( completeVar )
-import Util
+import SimplUtils
+import Type            ( mkTyVarTy, mkTyVarTys, mkAppTy,
+                         splitFunTy, getFunTy_maybe, eqTy
+                       )
+import Util            ( isSingleton, panic, pprPanic, assertPanic )
 \end{code}
 
 The controlling flags, and what they do
 \end{code}
 
 The controlling flags, and what they do
@@ -122,12 +126,12 @@ would occur].   But consider:
            f = \y -> ...y...y...y...
        in f x
 @
            f = \y -> ...y...y...y...
        in f x
 @
-Now, it seems that @x@ appears only once, but even so it is NOT safe to put @x@
-in the UnfoldEnv, because @f@ will be inlined, and will duplicate the references to
-@x@.
+Now, it seems that @x@ appears only once, but even so it is NOT safe
+to put @x@ in the UnfoldEnv, because @f@ will be inlined, and will
+duplicate the references to @x@.
 
 
-Becuase of this, the "unconditional-inline" mechanism above is the only way
-in which non-HNFs can get inlined.
+Because of this, the "unconditional-inline" mechanism above is the
+only way in which non-HNFs can get inlined.
 
 INLINE pragmas
 ~~~~~~~~~~~~~~
 
 INLINE pragmas
 ~~~~~~~~~~~~~~
@@ -185,12 +189,10 @@ simplTopBinds env [] = returnSmpl []
 
 simplTopBinds env (NonRec binder@(in_id, occ_info) rhs : binds)
   | inlineUnconditionally ok_to_dup_code occ_info
 
 simplTopBinds env (NonRec binder@(in_id, occ_info) rhs : binds)
   | inlineUnconditionally ok_to_dup_code occ_info
-  = --pprTrace "simplTopBinds (inline):" (ppr PprDebug in_id) (
-    let
+  = let
        new_env = extendIdEnvWithInlining env env binder rhs
     in
     simplTopBinds new_env binds
        new_env = extendIdEnvWithInlining env env binder rhs
     in
     simplTopBinds new_env binds
-    --)
   where
     ok_to_dup_code = switchIsSet env SimplOkToDupCode
 
   where
     ok_to_dup_code = switchIsSet env SimplOkToDupCode
 
@@ -200,12 +202,10 @@ simplTopBinds env (NonRec binder@(in_id,occ_info) rhs : binds)
     simplRhsExpr env binder rhs                `thenSmpl` \ rhs' ->
     let
        new_env = case rhs' of
     simplRhsExpr env binder rhs                `thenSmpl` \ rhs' ->
     let
        new_env = case rhs' of
-        Var var                          -> extendIdEnvWithAtom env binder (VarArg var)
-        Lit lit | not (isNoRepLit lit) -> extendIdEnvWithAtom env binder (LitArg lit)
-        other                            -> extendUnfoldEnvGivenRhs env binder in_id rhs'
+        Var v                      -> extendIdEnvWithAtom env binder (VarArg v)
+        Lit i | not (isNoRepLit i) -> extendIdEnvWithAtom env binder (LitArg i)
+        other                      -> extendUnfoldEnvGivenRhs env binder in_id rhs'
     in
     in
-    --pprTrace "simplTopBinds (nonrec):" (ppCat [ppr PprDebug in_id, ppr PprDebug rhs']) (
-
        -- Process the other bindings
     simplTopBinds new_env binds        `thenSmpl` \ binds' ->
 
        -- Process the other bindings
     simplTopBinds new_env binds        `thenSmpl` \ binds' ->
 
@@ -214,19 +214,15 @@ simplTopBinds env (NonRec binder@(in_id,occ_info) rhs : binds)
        -- an unused atom binding. This localises the decision about
        -- discarding top-level bindings.
     returnSmpl (NonRec in_id rhs' : binds')
        -- an unused atom binding. This localises the decision about
        -- discarding top-level bindings.
     returnSmpl (NonRec in_id rhs' : binds')
-    --)
 
 simplTopBinds env (Rec pairs : binds)
   = simplRecursiveGroup env triples    `thenSmpl` \ (bind', new_env) ->
 
 
 simplTopBinds env (Rec pairs : binds)
   = simplRecursiveGroup env triples    `thenSmpl` \ (bind', new_env) ->
 
-    --pprTrace "simplTopBinds (rec):" (ppCat [ppr PprDebug bind']) (
-
        -- Process the other bindings
     simplTopBinds new_env binds                `thenSmpl` \ binds' ->
 
        -- Glue together and return
     returnSmpl (bind' : binds')
        -- Process the other bindings
     simplTopBinds new_env binds                `thenSmpl` \ binds' ->
 
        -- Glue together and return
     returnSmpl (bind' : binds')
-    --)
   where
     triples = [(id, (binder, rhs)) | (binder@(id,_), rhs) <- pairs]
                -- No cloning necessary at top level
   where
     triples = [(id, (binder, rhs)) | (binder@(id,_), rhs) <- pairs]
                -- No cloning necessary at top level
@@ -251,15 +247,14 @@ applied to the specified arguments.
 
 Variables
 ~~~~~~~~~
 
 Variables
 ~~~~~~~~~
-Check if there's a macro-expansion, and if so rattle on.  Otherwise
-do the more sophisticated stuff.
+Check if there's a macro-expansion, and if so rattle on.  Otherwise do
+the more sophisticated stuff.
 
 \begin{code}
 simplExpr env (Var v) args
 
 \begin{code}
 simplExpr env (Var v) args
-  = --pprTrace "simplExpr:Var:" (ppr PprDebug v) (
-    case lookupId env v of
+  = case (lookupId env v) of
       Nothing -> let
       Nothing -> let
-                       new_v = simplTyInId env v
+                   new_v = simplTyInId env v
                 in
                 completeVar env new_v args
 
                 in
                 completeVar env new_v args
 
@@ -278,15 +273,16 @@ simplExpr env (Var v) args
 
          InlineIt id_env ty_env in_expr        -- A macro-expansion
            -> simplExpr (replaceInEnvs env (ty_env, id_env)) in_expr args
 
          InlineIt id_env ty_env in_expr        -- A macro-expansion
            -> simplExpr (replaceInEnvs env (ty_env, id_env)) in_expr args
-    --)
 \end{code}
 
 Literals
 \end{code}
 
 Literals
-~~~~~~~~~
+~~~~~~~~
 
 \begin{code}
 simplExpr env (Lit l) [] = returnSmpl (Lit l)
 
 \begin{code}
 simplExpr env (Lit l) [] = returnSmpl (Lit l)
+#ifdef DEBUG
 simplExpr env (Lit l) _  = panic "simplExpr:Lit with argument"
 simplExpr env (Lit l) _  = panic "simplExpr:Lit with argument"
+#endif
 \end{code}
 
 Primitive applications are simple.
 \end{code}
 
 Primitive applications are simple.
@@ -296,14 +292,13 @@ NB: Prim expects an empty argument list! (Because it should be
 saturated and not higher-order. ADR)
 
 \begin{code}
 saturated and not higher-order. ADR)
 
 \begin{code}
-simplExpr env (Prim op tys prim_args) args
+simplExpr env (Prim op prim_args) args
   = ASSERT (null args)
     let
   = ASSERT (null args)
     let
-       tys'       = [simplTy   env ty       | ty       <- tys]
-       prim_args' = [simplAtom env prim_arg | prim_arg <- prim_args]
+       prim_args' = [simplArg env prim_arg | prim_arg <- prim_args]
        op'        = simpl_op op
     in
        op'        = simpl_op op
     in
-    completePrim env op' tys' prim_args'
+    completePrim env op' prim_args'
   where
     -- PrimOps just need any types in them renamed.
 
   where
     -- PrimOps just need any types in them renamed.
 
@@ -323,12 +318,9 @@ Nothing to try here.  We only reuse constructors when they appear as the
 rhs of a let binding (see completeLetBinding).
 
 \begin{code}
 rhs of a let binding (see completeLetBinding).
 
 \begin{code}
-simplExpr env (Con con tys con_args) args
+simplExpr env (Con con con_args) args
   = ASSERT( null args )
   = ASSERT( null args )
-    returnSmpl (Con con tys' con_args')
-  where
-    con_args' = [simplAtom env con_arg | con_arg <- con_args]
-    tys'      = [simplTy   env ty      | ty <- tys]
+    returnSmpl (Con con [simplArg env con_arg | con_arg <- con_args])
 \end{code}
 
 
 \end{code}
 
 
@@ -338,10 +330,7 @@ Just stuff 'em in the arg stack
 
 \begin{code}
 simplExpr env (App fun arg) args
 
 \begin{code}
 simplExpr env (App fun arg) args
-  = simplExpr env fun (ValArg (simplAtom env arg) : args)
-
-simplExpr env (CoTyApp fun ty) args
-  = simplExpr env fun (TypeArg (simplTy env ty) : args)
+  = simplExpr env fun (simplArg env arg : args)
 \end{code}
 
 Type lambdas
 \end{code}
 
 Type lambdas
@@ -352,7 +341,7 @@ be eta-reduced. This requires us to collect up all tyvar parameters so
 we can pass them all to @mkTyLamTryingEta@.
 
 \begin{code}
 we can pass them all to @mkTyLamTryingEta@.
 
 \begin{code}
-simplExpr env (CoTyLam tyvar body) (TypeArg ty : args)
+simplExpr env (Lam (TyBinder tyvar) body) (TyArg ty : args)
   = -- ASSERT(not (isPrimType ty))
     let
        new_env = extendTyEnv env tyvar ty
   = -- ASSERT(not (isPrimType ty))
     let
        new_env = extendTyEnv env tyvar ty
@@ -360,10 +349,10 @@ simplExpr env (CoTyLam tyvar body) (TypeArg ty : args)
     tick TyBetaReduction       `thenSmpl_`
     simplExpr new_env body args
 
     tick TyBetaReduction       `thenSmpl_`
     simplExpr new_env body args
 
-simplExpr env tylam@(CoTyLam tyvar body) []
+simplExpr env tylam@(Lam (TyBinder tyvar) body) []
   = do_tylambdas env [] tylam
   where
   = do_tylambdas env [] tylam
   where
-    do_tylambdas env tyvars' (CoTyLam tyvar body)
+    do_tylambdas env tyvars' (Lam (TyBinder tyvar) body)
       =          -- Clone the type variable
        cloneTyVarSmpl tyvar            `thenSmpl` \ tyvar' ->
        let
       =          -- Clone the type variable
        cloneTyVarSmpl tyvar            `thenSmpl` \ tyvar' ->
        let
@@ -376,11 +365,13 @@ simplExpr env tylam@(CoTyLam tyvar body) []
        returnSmpl (
           (if switchIsSet env SimplDoEtaReduction
           then mkTyLamTryingEta
        returnSmpl (
           (if switchIsSet env SimplDoEtaReduction
           then mkTyLamTryingEta
-          else mkCoTyLam) (reverse tyvars')  body'
+          else mkTyLam) (reverse tyvars')  body'
        )
 
        )
 
-simplExpr env (CoTyLam tyvar body) (ValArg _ : _)
-  = panic "simplExpr:CoTyLam ValArg"
+#ifdef DEBUG
+simplExpr env (Lam (TyBinder _) _) (_ : _)
+  = panic "simplExpr:TyLam with non-TyArg"
+#endif
 \end{code}
 
 
 \end{code}
 
 
@@ -388,7 +379,7 @@ Ordinary lambdas
 ~~~~~~~~~~~~~~~~
 
 \begin{code}
 ~~~~~~~~~~~~~~~~
 
 \begin{code}
-simplExpr env (Lam binder body) args
+simplExpr env (Lam (ValBinder binder) body) args
   | null leftover_binders
   =    -- The lambda is saturated (or over-saturated)
     tick BetaReduction `thenSmpl_`
   | null leftover_binders
   =    -- The lambda is saturated (or over-saturated)
     tick BetaReduction `thenSmpl_`
@@ -407,7 +398,7 @@ simplExpr env (Lam binder body) args
             0 {- Guaranteed applied to at least 0 args! -}
 
   where
             0 {- Guaranteed applied to at least 0 args! -}
 
   where
-    (binder_args_pairs, leftover_binders, leftover_args) = collect_val_args [binder] args
+    (binder_args_pairs, leftover_binders, leftover_args) = collect_val_args binder args
 
     env_for_enough_args  = extendIdEnvWithAtomList env binder_args_pairs
 
 
     env_for_enough_args  = extendIdEnvWithAtomList env binder_args_pairs
 
@@ -427,24 +418,23 @@ simplExpr env (Lam binder body) args
     zapped_binder_args_pairs = [ ((id, markDangerousToDup occ_info), arg)
                               | ((id, occ_info), arg) <- binder_args_pairs ]
 
     zapped_binder_args_pairs = [ ((id, markDangerousToDup occ_info), arg)
                               | ((id, occ_info), arg) <- binder_args_pairs ]
 
-    collect_val_args :: [InBinder]     -- Binders
-                    -> [OutArg]        -- Arguments
-                    -> ([(InBinder,OutAtom)],  -- Binder,arg pairs
-                         [InBinder],           -- Leftover binders
-                         [OutArg])             -- Leftover args
+    collect_val_args :: InBinder               -- Binder
+                    -> [OutArg]                -- Arguments
+                    -> ([(InBinder,OutArg)],   -- Binder,arg pairs (ToDo: a maybe?)
+                        [InBinder],            -- Leftover binders (ToDo: a maybe)
+                        [OutArg])              -- Leftover args
 
        -- collect_val_args strips off the leading ValArgs from
        -- the current arg list, returning them along with the
        -- depleted list
 
        -- collect_val_args strips off the leading ValArgs from
        -- the current arg list, returning them along with the
        -- depleted list
-    collect_val_args []      args = ([], [], args)
-    collect_val_args binders []   = ([], binders, [])
-    collect_val_args (binder:binders) (ValArg val_arg : args)
-       = ((binder,val_arg):rest_pairs, leftover_binders, leftover_args)
-       where
-         (rest_pairs, leftover_binders, leftover_args) = collect_val_args binders args
-
-    collect_val_args (binder:binders) (other_val_arg : args) = panic "collect_val_args"
-               -- TypeArg should never meet a Lam
+    collect_val_args binder []   = ([], [binder], [])
+    collect_val_args binder (arg : args) | isValArg arg
+       = ([(binder,arg)], [], args)
+
+#ifdef DEBUG
+    collect_val_args _ (other_val_arg : _) = panic "collect_val_args"
+               -- TyArg should never meet a Lam
+#endif
 \end{code}
 
 
 \end{code}
 
 
@@ -486,9 +476,6 @@ interfaces change less (arities).
 \begin{code}
 simplExpr env (SCC cc (Lam binder body)) args
   = simplExpr env (Lam binder (SCC cc body)) args
 \begin{code}
 simplExpr env (SCC cc (Lam binder body)) args
   = simplExpr env (Lam binder (SCC cc body)) args
-
-simplExpr env (SCC cc (CoTyLam tyvar body)) args
-  = simplExpr env (CoTyLam tyvar (SCC cc body)) args
 \end{code}
 
 Some other slightly turgid SCC tidying-up cases:
 \end{code}
 
 Some other slightly turgid SCC tidying-up cases:
@@ -559,7 +546,7 @@ simplRhsExpr env binder@(id,occ_info) rhs
     returnSmpl (
        (if switchIsSet env SimplDoEtaReduction
        then mkTyLamTryingEta
     returnSmpl (
        (if switchIsSet env SimplDoEtaReduction
        then mkTyLamTryingEta
-       else mkCoTyLam) tyvars' lambda'
+       else mkTyLam) tyvars' lambda'
     )
   where
        -- Note from ANDY:
     )
   where
        -- Note from ANDY:
@@ -590,10 +577,12 @@ simplRhsExpr env binder@(id,occ_info) rhs
        -- non-trivial.
     dont_eta_expand (Lit _)     = True
     dont_eta_expand (Var _)     = True
        -- non-trivial.
     dont_eta_expand (Lit _)     = True
     dont_eta_expand (Var _)     = True
-    dont_eta_expand (CoTyApp f _) = dont_eta_expand f
-    dont_eta_expand (CoTyLam _ b) = dont_eta_expand b
-    dont_eta_expand (Con _ _ _) = True
-    dont_eta_expand _            = False
+    dont_eta_expand (Con _ _)   = True
+    dont_eta_expand (App f a)
+      | notValArg    a         = dont_eta_expand f
+    dont_eta_expand (Lam x b)
+      | notValBinder x         = dont_eta_expand b
+    dont_eta_expand _          = False
 \end{code}
 
 
 \end{code}
 
 
@@ -628,8 +617,8 @@ simplLam env binders body min_no_of_args
     let
        new_env = extendIdEnvWithClones env binders binders'
     in
     let
        new_env = extendIdEnvWithClones env binders binders'
     in
-    newIds extra_binder_tys                                            `thenSmpl` \ extra_binders' ->
-    simplExpr new_env body (map (ValArg.VarArg) extra_binders')        `thenSmpl` \ body' ->
+    newIds extra_binder_tys                            `thenSmpl` \ extra_binders' ->
+    simplExpr new_env body (map VarArg extra_binders') `thenSmpl` \ body' ->
     returnSmpl (
       (if switchIsSet new_env SimplDoEtaReduction
        then mkValLamTryingEta
     returnSmpl (
       (if switchIsSet new_env SimplDoEtaReduction
        then mkValLamTryingEta
@@ -638,7 +627,7 @@ simplLam env binders body min_no_of_args
 
   where
     (potential_extra_binder_tys, res_ty)
 
   where
     (potential_extra_binder_tys, res_ty)
-       = splitTyArgs (simplTy env (coreExprType (unTagBinders body)))
+       = splitFunTy (simplTy env (coreExprType (unTagBinders body)))
        -- Note: it's possible that simplLam will be applied to something
        -- with a forall type.  Eg when being applied to the rhs of
        --              let x = wurble
        -- Note: it's possible that simplLam will be applied to something
        -- with a forall type.  Eg when being applied to the rhs of
        --              let x = wurble
@@ -661,8 +650,8 @@ simplLam env binders body min_no_of_args
                                -- but usually doesn't
                           `max`
                           case potential_extra_binder_tys of
                                -- but usually doesn't
                           `max`
                           case potential_extra_binder_tys of
-                               [ty] | ty == realWorldStateTy -> 1
-                               other                         -> 0
+                               [ty] | ty `eqTy` realWorldStateTy -> 1
+                               other                             -> 0
 
 \end{code}
 
 
 \end{code}
 
@@ -677,7 +666,7 @@ simplLam env binders body min_no_of_args
 simplBind :: SimplEnv
          -> InBinding
          -> (SimplEnv -> SmplM OutExpr)
 simplBind :: SimplEnv
          -> InBinding
          -> (SimplEnv -> SmplM OutExpr)
-         -> OutUniType
+         -> OutType
          -> SmplM OutExpr
 \end{code}
 
          -> SmplM OutExpr
 \end{code}
 
@@ -1028,8 +1017,8 @@ simplRecursiveGroup env triples
        (early_triples, late_triples)
          = partition is_early_triple ordinary_triples
 
        (early_triples, late_triples)
          = partition is_early_triple ordinary_triples
 
-       is_early_triple (_, (_, Con _ _ _)) = True
-       is_early_triple (i, _               ) = idWantsToBeINLINEd i
+       is_early_triple (_, (_, Con _ _)) = True
+       is_early_triple (i, _           ) = idWantsToBeINLINEd i
     in
        -- Process the early bindings first
     mapSmpl (do_one_binding env_w_inlinings) early_triples     `thenSmpl` \ early_triples' ->
     in
        -- Process the early bindings first
     mapSmpl (do_one_binding env_w_inlinings) early_triples     `thenSmpl` \ early_triples' ->
@@ -1102,7 +1091,7 @@ completeLet
        -> InExpr               -- Original RHS
        -> OutExpr              -- The simplified RHS
        -> (SimplEnv -> SmplM OutExpr)          -- Body handler
        -> InExpr               -- Original RHS
        -> OutExpr              -- The simplified RHS
        -> (SimplEnv -> SmplM OutExpr)          -- Body handler
-       -> OutUniType           -- Type of body
+       -> OutType              -- Type of body
        -> SmplM OutExpr
 
 completeLet env binder@(id,binder_info) old_rhs new_rhs body_c body_ty
        -> SmplM OutExpr
 
 completeLet env binder@(id,binder_info) old_rhs new_rhs body_c body_ty
@@ -1126,7 +1115,7 @@ completeLet env binder@(id,binder_info) old_rhs new_rhs body_c body_ty
   = cloneId env binder                 `thenSmpl` \ id' ->
     let
        env1    = extendIdEnvWithClone env binder id'
   = cloneId env binder                 `thenSmpl` \ id' ->
     let
        env1    = extendIdEnvWithClone env binder id'
-       new_env = _scc_ "euegR2" (extendUnfoldEnvGivenRhs env1 binder id' new_rhs)
+       new_env = extendUnfoldEnvGivenRhs env1 binder id' new_rhs
     in
     body_c new_env                     `thenSmpl` \ body' ->
     returnSmpl (Let (NonRec id' new_rhs) body')
     in
     body_c new_env                     `thenSmpl` \ body' ->
     returnSmpl (Let (NonRec id' new_rhs) body')
@@ -1137,7 +1126,7 @@ completeLet env binder@(id,binder_info) old_rhs new_rhs body_c body_ty
 
     Just (rhs_atom, atom_tick_type) = maybe_atomic_rhs
 
 
     Just (rhs_atom, atom_tick_type) = maybe_atomic_rhs
 
-    maybe_atomic_rhs :: Maybe (OutAtom, TickType)
+    maybe_atomic_rhs :: Maybe (OutArg, TickType)
        -- If the RHS is atomic, we return Just (atom, tick type)
        -- otherwise Nothing
 
        -- If the RHS is atomic, we return Just (atom, tick type)
        -- otherwise Nothing
 
@@ -1148,7 +1137,7 @@ completeLet env binder@(id,binder_info) old_rhs new_rhs body_c body_ty
          Lit lit | not (isNoRepLit lit)
            -> Just (LitArg lit, AtomicRhs)
 
          Lit lit | not (isNoRepLit lit)
            -> Just (LitArg lit, AtomicRhs)
 
-         Con con tys con_args
+         Con con con_args
            | try_to_reuse_constr
                   -- Look out for
                   --   let v = C args
            | try_to_reuse_constr
                   -- Look out for
                   --   let v = C args
@@ -1156,7 +1145,7 @@ completeLet env binder@(id,binder_info) old_rhs new_rhs body_c body_ty
                   --- ...(let w = C same-args in ...)...
                   -- Then use v instead of w.   This may save
                   -- re-constructing an existing constructor.
                   --- ...(let w = C same-args in ...)...
                   -- Then use v instead of w.   This may save
                   -- re-constructing an existing constructor.
-            -> case lookForConstructor env con tys con_args of
+            -> case (lookForConstructor env con con_args) of
                  Nothing  -> Nothing
                  Just var -> Just (VarArg var, ConReused)
 
                  Nothing  -> Nothing
                  Just var -> Just (VarArg var, ConReused)
 
@@ -1173,15 +1162,16 @@ completeLet env binder@(id,binder_info) old_rhs new_rhs body_c body_ty
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-simplAtom :: SimplEnv -> InAtom -> OutAtom
+simplArg :: SimplEnv -> InArg -> OutArg
 
 
-simplAtom env (LitArg lit) = LitArg lit
+simplArg env (LitArg lit) = LitArg lit
+simplArg env (TyArg  ty)  = TyArg  (simplTy env ty)
 
 
-simplAtom env (VarArg id)
+simplArg env (VarArg id)
   | isLocallyDefined id
   = case lookupId env id of
        Just (ItsAnAtom atom) -> atom
   | isLocallyDefined id
   = case lookupId env id of
        Just (ItsAnAtom atom) -> atom
-       Just (InlineIt _ _ _) -> pprPanic "simplAtom InLineIt:" (ppAbove (ppr PprDebug id) (pprSimplEnv env))
+       Just (InlineIt _ _ _) -> pprPanic "simplArg InLineIt:" (ppAbove (ppr PprDebug id) (pprSimplEnv env))
        Nothing               -> VarArg id      -- Must be an uncloned thing
 
   | otherwise
        Nothing               -> VarArg id      -- Must be an uncloned thing
 
   | otherwise
@@ -1209,20 +1199,20 @@ fix_up_demandedness False {- May not be demanded -} (Rec pairs)
 
 un_demandify (id, occ_info) = (id `addIdDemandInfo` noInfo, occ_info)
 
 
 un_demandify (id, occ_info) = (id `addIdDemandInfo` noInfo, occ_info)
 
-is_cheap_prim_app (Prim op tys args) = primOpOkForSpeculation op
-is_cheap_prim_app other                       = False
+is_cheap_prim_app (Prim op _) = primOpOkForSpeculation op
+is_cheap_prim_app other              = False
 
 
-computeResultType :: SimplEnv -> InExpr -> [OutArg] -> OutUniType
+computeResultType :: SimplEnv -> InExpr -> [OutArg] -> OutType
 computeResultType env expr args
 computeResultType env expr args
-  = do expr_ty' args
+  = go expr_ty' args
   where
     expr_ty  = coreExprType (unTagBinders expr)
     expr_ty' = simplTy env expr_ty
 
   where
     expr_ty  = coreExprType (unTagBinders expr)
     expr_ty' = simplTy env expr_ty
 
-    do ty [] = ty
-    do ty (TypeArg ty_arg : args) = do (applyTy ty ty_arg) args
-    do ty (ValArg a       : args) = case maybeUnpackFunTy ty of
-                                     Just (_, res_ty) -> do res_ty args
-                                     Nothing          -> panic "computeResultType"
+    go ty [] = ty
+    go ty (TyArg ty_arg : args) = go (mkAppTy ty ty_arg) args
+    go ty (a:args) | isValArg a = case (getFunTy_maybe ty) of
+                                   Just (_, res_ty) -> go res_ty args
+                                   Nothing          -> panic "computeResultType"
 \end{code}
 
 \end{code}
 
index 89de04b..3a9e349 100644 (file)
@@ -1,10 +1,26 @@
 Breaks the loop between SimplEnv and MagicUFs, by telling SimplEnv all
 it needs to know about MagicUFs (not much).
 
 Breaks the loop between SimplEnv and MagicUFs, by telling SimplEnv all
 it needs to know about MagicUFs (not much).
 
+Also break the loop between SimplVar/SimplCase (which use
+Simplify.simplExpr) and SimplExpr (which uses whatever
+SimplVar/SimplCase cough up).
+
 \begin{code}
 interface SmplLoop where
 
 \begin{code}
 interface SmplLoop where
 
-import MagicUFs (MagicUnfoldingFun )
+import MagicUFs            ( MagicUnfoldingFun )
+import SimplEnv            ( SimplEnv, InBinding(..), InExpr(..),
+                     OutArg(..), OutExpr(..), OutType(..)
+                   )
+import Simplify            ( simplExpr, simplBind )
+import SimplMonad   ( SmplM(..) )
 
 data MagicUnfoldingFun
 
 data MagicUnfoldingFun
+
+simplExpr :: SimplEnv -> InExpr -> [OutArg] -> SmplM OutExpr
+simplBind :: SimplEnv
+         -> InBinding
+         -> (SimplEnv -> SmplM OutExpr)
+         -> OutType
+         -> SmplM OutExpr
 \end{code}
 \end{code}
index 40d180a..b1c83dd 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The AQUA Project, Glasgow University, 1994-1995
+% (c) The AQUA Project, Glasgow University, 1994-1996
 %
 \section[LambdaLift]{A STG-code lambda lifter}
 
 %
 \section[LambdaLift]{A STG-code lambda lifter}
 
@@ -8,18 +8,20 @@
 
 module LambdaLift ( liftProgram ) where
 
 
 module LambdaLift ( liftProgram ) where
 
+import Ubiq{-uitous-}
+
 import StgSyn
 
 import StgSyn
 
-import Type            ( mkForallTy, splitForalls, glueTyArgs,
-                         Type, RhoType(..), TauType(..)
+import Bag             ( emptyBag, unionBags, unitBag, snocBag, bagToList )
+import Id              ( idType, mkSysLocal, addIdArity,
+                         mkIdSet, unitIdSet, minusIdSet,
+                         unionManyIdSets, idSetToList, IdSet(..),
+                         nullIdEnv, growIdEnvList, lookupIdEnv, IdEnv(..)
                        )
                        )
-import Bag
-import Id              ( mkSysLocal, idType, addIdArity, Id )
-import Maybes
-import UniqSupply
-import SrcLoc          ( mkUnknownSrcLoc, SrcLoc )
-import UniqSet
-import Util
+import SrcLoc          ( mkUnknownSrcLoc )
+import Type            ( splitForAllTy, mkForAllTys, mkFunTys )
+import UniqSupply      ( getUnique, splitUniqSupply )
+import Util            ( zipEqual, panic, assertPanic )
 \end{code}
 
 This is the lambda lifter.  It turns lambda abstractions into
 \end{code}
 
 This is the lambda lifter.  It turns lambda abstractions into
@@ -251,9 +253,9 @@ liftExpr (StgLet (StgRec pairs) body)
       let
        -- Find the free vars of all the rhss,
        -- excluding the binders themselves.
       let
        -- Find the free vars of all the rhss,
        -- excluding the binders themselves.
-       rhs_free_vars = unionManyUniqSets (map rhsFreeVars rhss)
-                       `minusUniqSet`
-                       mkUniqSet binders
+       rhs_free_vars = unionManyIdSets (map rhsFreeVars rhss)
+                       `minusIdSet`
+                       mkIdSet binders
 
        rhs_info      = unionLiftInfos rhs_infos
       in
 
        rhs_info      = unionLiftInfos rhs_infos
       in
@@ -335,7 +337,7 @@ isLiftableRec (StgRhsClosure _ (StgBinderInfo arg_occ _ _ _ unapplied_occ) fvs _
 isLiftableRec other_rhs = False
 
 rhsFreeVars :: StgRhs -> IdSet
 isLiftableRec other_rhs = False
 
 rhsFreeVars :: StgRhs -> IdSet
-rhsFreeVars (StgRhsClosure _ _ fvs _ _ _) = mkUniqSet fvs
+rhsFreeVars (StgRhsClosure _ _ fvs _ _ _) = mkIdSet fvs
 rhsFreeVars other                        = panic "rhsFreeVars"
 \end{code}
 
 rhsFreeVars other                        = panic "rhsFreeVars"
 \end{code}
 
@@ -364,22 +366,18 @@ mkScPieces :: IdSet               -- Extra args for the supercombinator
 mkScPieces extra_arg_set (id, StgRhsClosure cc bi _ upd args body)
   = ASSERT( n_args > 0 )
        -- Construct the rhs of the supercombinator, and its Id
 mkScPieces extra_arg_set (id, StgRhsClosure cc bi _ upd args body)
   = ASSERT( n_args > 0 )
        -- Construct the rhs of the supercombinator, and its Id
-    -- this trace blackholes sometimes, don't use it
-    -- trace ("LL " ++ show (length (uniqSetToList extra_arg_set))) (
     newSupercombinator sc_ty arity  `thenLM` \ sc_id ->
     newSupercombinator sc_ty arity  `thenLM` \ sc_id ->
-
     returnLM ((sc_id, extra_args), (sc_id, sc_rhs))
     returnLM ((sc_id, extra_args), (sc_id, sc_rhs))
-    --)
   where
     n_args     = length args
   where
     n_args     = length args
-    extra_args = uniqSetToList extra_arg_set
+    extra_args = idSetToList extra_arg_set
     arity      = n_args + length extra_args
 
        -- Construct the supercombinator type
     type_of_original_id = idType id
     extra_arg_tys       = map idType extra_args
     arity      = n_args + length extra_args
 
        -- Construct the supercombinator type
     type_of_original_id = idType id
     extra_arg_tys       = map idType extra_args
-    (tyvars, rest)      = splitForalls type_of_original_id
-    sc_ty              = mkForallTy tyvars (glueTyArgs extra_arg_tys rest)
+    (tyvars, rest)      = splitForAllTy type_of_original_id
+    sc_ty              = mkForAllTys tyvars (mkFunTys extra_arg_tys rest)
 
     sc_rhs = StgRhsClosure cc bi [] upd (extra_args ++ args) body
 \end{code}
 
     sc_rhs = StgRhsClosure cc bi [] upd (extra_args ++ args) body
 \end{code}
@@ -451,9 +449,9 @@ newSupercombinator ty arity ci us idenv
 
 lookup :: Id -> LiftM (Id,[Id])
 lookup v ci us idenv
 
 lookup :: Id -> LiftM (Id,[Id])
 lookup v ci us idenv
-  = case lookupIdEnv idenv v of
-       Just result -> result
-       Nothing     -> (v, [])
+  = case (lookupIdEnv idenv v) of
+      Just result -> result
+      Nothing     -> (v, [])
 
 addScInlines :: [Id] -> [(Id,[Id])] -> LiftM a -> LiftM a
 addScInlines ids values m ci us idenv
 
 addScInlines :: [Id] -> [(Id,[Id])] -> LiftM a -> LiftM a
 addScInlines ids values m ci us idenv
@@ -488,14 +486,13 @@ addScInlines ids values m ci us idenv
 getFinalFreeVars :: IdSet -> LiftM IdSet
 
 getFinalFreeVars free_vars ci us idenv
 getFinalFreeVars :: IdSet -> LiftM IdSet
 
 getFinalFreeVars free_vars ci us idenv
-  = unionManyUniqSets (map munge_it (uniqSetToList free_vars))
+  = unionManyIdSets (map munge_it (idSetToList free_vars))
   where
     munge_it :: Id -> IdSet    -- Takes a free var and maps it to the "real"
                                -- free var
   where
     munge_it :: Id -> IdSet    -- Takes a free var and maps it to the "real"
                                -- free var
-    munge_it id = case lookupIdEnv idenv id of
-                       Just (_, args) -> mkUniqSet args
-                       Nothing        -> singletonUniqSet id
-
+    munge_it id = case (lookupIdEnv idenv id) of
+                   Just (_, args) -> mkIdSet args
+                   Nothing        -> unitIdSet id
 \end{code}
 
 
 \end{code}
 
 
index 16c903e..2c9dcfc 100644 (file)
@@ -1,8 +1,10 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[SatStgRhs]{Saturates RHSs when they are partial applications}
 
 %
 \section[SatStgRhs]{Saturates RHSs when they are partial applications}
 
+96/03: This is actually an essential module, as it sets arity info
+for the code generator.
 
 \begin{display}
 Subject: arg satis check
 
 \begin{display}
 Subject: arg satis check
@@ -58,20 +60,22 @@ This is done for local definitions as well.
 
 module SatStgRhs ( satStgRhs ) where
 
 
 module SatStgRhs ( satStgRhs ) where
 
+import Ubiq{-uitous-}
+
 import StgSyn
 
 import StgSyn
 
-import Type            ( splitTypeWithDictsAsArgs, Class,
-                         TyVarTemplate, TauType(..)
+import CostCentre      ( isCafCC, subsumedCosts, useCurrentCostCentre )
+import Id              ( idType, getIdArity, addIdArity, mkSysLocal,
+                         nullIdEnv, addOneToIdEnv, growIdEnvList,
+                         lookupIdEnv, IdEnv(..)
                        )
                        )
-import CostCentre
-import Id              ( mkSysLocal, idType, getIdArity, addIdArity )
-import IdInfo          -- SIGH: ( arityMaybe, ArityInfo, OptIdInfo(..) )
-import SrcLoc          ( mkUnknownSrcLoc, SrcLoc )
-import UniqSupply
-import Util
-import Maybes
-
-type Arity = Int
+import IdInfo          ( arityMaybe )
+import SrcLoc          ( mkUnknownSrcLoc )
+import UniqSupply      ( returnUs, thenUs, mapUs, getUnique, UniqSM(..) )
+import Util            ( panic, assertPanic )
+
+splitTypeWithDictsAsArgs = panic "SatStgRhs.splitTypeWithDictsAsArgs (ToDo)"
+
 type Count = Int
 
 type ExprArityInfo = Maybe Int     -- Just n  => This expression has a guaranteed
 type Count = Int
 
 type ExprArityInfo = Maybe Int     -- Just n  => This expression has a guaranteed
index be139b7..7ecb01c 100644 (file)
@@ -8,7 +8,7 @@
 
 module SimplStg ( stg2stg ) where
 
 
 module SimplStg ( stg2stg ) where
 
-IMPORT_Trace
+import Ubiq{-uitous-}
 
 import StgSyn
 import StgUtils
 
 import StgSyn
 import StgUtils
@@ -16,36 +16,43 @@ import StgUtils
 import LambdaLift      ( liftProgram )
 import SCCfinal                ( stgMassageForProfiling )
 import SatStgRhs       ( satStgRhs )
 import LambdaLift      ( liftProgram )
 import SCCfinal                ( stgMassageForProfiling )
 import SatStgRhs       ( satStgRhs )
+import StgLint         ( lintStgBindings )
+import StgSAT          ( doStaticArgs )
 import StgStats                ( showStgStats )
 import StgVarInfo      ( setStgVarInfo )
 import UpdAnal         ( updateAnalyse )
 
 import StgStats                ( showStgStats )
 import StgVarInfo      ( setStgVarInfo )
 import UpdAnal         ( updateAnalyse )
 
-import CmdLineOpts
-import Id              ( unlocaliseId )
-import MainMonad
-import Maybes          ( maybeToBool, Maybe(..) )
-import Outputable
-import Pretty
-import StgLint         ( lintStgBindings )
-import StgSAT          ( doStaticArgs )
-import UniqSet
-import UniqSupply
-import Util
+import CmdLineOpts     ( opt_EnsureSplittableC, opt_SccGroup,
+                         opt_StgDoLetNoEscapes, opt_D_verbose_stg2stg,
+                         StgToDo(..)
+                       )
+import Id              ( nullIdEnv, lookupIdEnv, addOneToIdEnv,
+                         growIdEnvList, isNullIdEnv, IdEnv(..),
+                         GenId{-instance Eq/Outputable -}
+                       )
+import MainMonad       ( writeMn, thenMn_, thenMn, returnMn, MainIO(..) )
+import Maybes          ( maybeToBool )
+import Outputable      ( isExported )
+import PprType         ( GenType{-instance Outputable-} )
+import Pretty          ( ppShow, ppAbove, ppAboves, ppStr )
+import UniqSupply      ( splitUniqSupply )
+import Util            ( mapAccumL, panic, assertPanic )
+
+unlocaliseId = panic "SimplStg.unlocaliseId (ToDo)"
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-stg2stg :: [StgToDo]                   -- spec of what stg-to-stg passes to do
-       -> (GlobalSwitch -> SwitchResult)-- access to all global cmd-line opts
-       -> FAST_STRING                  -- module name (profiling only)
-       -> PprStyle                     -- printing style (for debugging only)
+stg2stg :: [StgToDo]           -- spec of what stg-to-stg passes to do
+       -> FAST_STRING          -- module name (profiling only)
+       -> PprStyle             -- printing style (for debugging only)
        -> UniqSupply           -- a name supply
        -> [StgBinding]         -- input...
        -> MainIO
        -> UniqSupply           -- a name supply
        -> [StgBinding]         -- input...
        -> MainIO
-           ([StgBinding],              -- output program...
-            ([CostCentre],             -- local cost-centres that need to be decl'd
-             [CostCentre]))            -- "extern" cost-centres
+           ([StgBinding],      -- output program...
+            ([CostCentre],     -- local cost-centres that need to be decl'd
+             [CostCentre]))    -- "extern" cost-centres
 
 
-stg2stg stg_todos sw_chkr module_name ppr_style us binds
+stg2stg stg_todos module_name ppr_style us binds
   = BSCC("Stg2Stg")
     case (splitUniqSupply us)  of { (us4now, us4later) ->
 
   = BSCC("Stg2Stg")
     case (splitUniqSupply us)  of { (us4now, us4later) ->
 
@@ -98,18 +105,16 @@ stg2stg stg_todos sw_chkr module_name ppr_style us binds
     }}
     ESCC
   where
     }}
     ESCC
   where
-    switch_is_on = switchIsOn sw_chkr
-
-    do_let_no_escapes  = switch_is_on StgDoLetNoEscapes
-    do_verbose_stg2stg = switch_is_on D_verbose_stg2stg
+    do_let_no_escapes  = opt_StgDoLetNoEscapes
+    do_verbose_stg2stg = opt_D_verbose_stg2stg
 
     (do_unlocalising, unlocal_tag)
 
     (do_unlocalising, unlocal_tag)
-      = case (stringSwitchSet sw_chkr EnsureSplittableC) of
+      = case (opt_EnsureSplittableC) of
              Nothing  -> (False, panic "tag")
              Nothing  -> (False, panic "tag")
-             Just tag -> (True,  _PK_ tag)
+             Just tag -> (True,  tag)
 
 
-    grp_name  = case (stringSwitchSet sw_chkr SccGroup) of
-                 Just xx -> _PK_ xx
+    grp_name  = case (opt_SccGroup) of
+                 Just xx -> xx
                  Nothing -> module_name -- default: module name
 
     -------------
                  Nothing -> module_name -- default: module name
 
     -------------
@@ -158,7 +163,7 @@ stg2stg stg_todos sw_chkr module_name ppr_style us binds
             BSCC("ProfMassage")
             let
                 (collected_CCs, binds3)
             BSCC("ProfMassage")
             let
                 (collected_CCs, binds3)
-                  = stgMassageForProfiling module_name grp_name us1 switch_is_on binds
+                  = stgMassageForProfiling module_name grp_name us1 binds
             in
             end_pass us2 "ProfMassage" collected_CCs binds3
             ESCC
             in
             end_pass us2 "ProfMassage" collected_CCs binds3
             ESCC
index c8a5e35..a70205e 100644 (file)
@@ -33,19 +33,19 @@ useless as map' will be transformed back to what map was.
 
 module StgSAT (        doStaticArgs ) where
 
 
 module StgSAT (        doStaticArgs ) where
 
-import Maybes          ( Maybe(..) )
+import Ubiq{-uitous-}
+
 import StgSyn
 import StgSyn
-import SATMonad                ( SATEnv(..), SATInfo(..), Arg(..), updSAEnv, insSAEnv,
-                         SatM(..), initSAT, thenSAT, thenSAT_,
-                         emptyEnvSAT, returnSAT, mapSAT )
-import StgSATMonad
-import UniqSupply
-import Util
+import UniqSupply      ( UniqSM(..) )
+import Util            ( panic )
 \end{code}
 
 \begin{code}
 doStaticArgs :: [StgBinding] -> UniqSupply -> [StgBinding]
 
 \end{code}
 
 \begin{code}
 doStaticArgs :: [StgBinding] -> UniqSupply -> [StgBinding]
 
+doStaticArgs = panic "StgSAT.doStaticArgs"
+
+{- LATER: to end of file:
 doStaticArgs binds
   = initSAT (mapSAT sat_bind binds)
   where
 doStaticArgs binds
   = initSAT (mapSAT sat_bind binds)
   where
@@ -174,5 +174,5 @@ satRhs rhs@(StgRhsCon cc v args) = returnSAT rhs
 satRhs (StgRhsClosure cc bi fvs upd args body)
   = satExpr body               `thenSAT` \ body' ->
     returnSAT (StgRhsClosure cc bi fvs upd args body')
 satRhs (StgRhsClosure cc bi fvs upd args body)
   = satExpr body               `thenSAT` \ body' ->
     returnSAT (StgRhsClosure cc bi fvs upd args body')
+-}
 \end{code}
 \end{code}
-
index 5996c18..57fff4d 100644 (file)
 \begin{code}
 #include "HsVersions.h"
 
 \begin{code}
 #include "HsVersions.h"
 
-module StgSATMonad (
-       getArgLists, saTransform
-    ) where
-
-import Type            ( mkSigmaTy, TyVarTemplate,
-                         splitSigmaTy, splitTyArgs,
-                         glueTyArgs, instantiateTy, TauType(..),
-                         Class, ThetaType(..), SigmaType(..),
-                         InstTyEnv(..)
-                       )
-import Id              ( mkSysLocal, idType, eqId )
-import Maybes          ( Maybe(..) )
-import StgSyn
-import SATMonad         ( SATEnv(..), SATInfo(..), Arg(..), updSAEnv, insSAEnv,
-                         SatM(..), initSAT, thenSAT, thenSAT_,
-                         emptyEnvSAT, returnSAT, mapSAT, isStatic, dropStatics,
-                         getSATInfo, newSATName )
-import SrcLoc          ( SrcLoc, mkUnknownSrcLoc )
-import UniqSupply
-import UniqSet         ( UniqSet(..), emptyUniqSet )
-import Util
+module StgSATMonad ( getArgLists, saTransform ) where
 
 
+import Ubiq{-uitous-}
+
+import Util            ( panic )
+
+getArgLists = panic "StgSATMonad.getArgLists"
+saTransform = panic "StgSATMonad.saTransform"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -41,6 +27,8 @@ import Util
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
+{- LATER: to end of file:
+
 newSATNames :: [Id] -> SatM [Id]
 newSATNames [] = returnSAT []
 newSATNames (id:ids) = newSATName id (idType id)       `thenSAT` \ id' ->
 newSATNames :: [Id] -> SatM [Id]
 newSATNames [] = returnSAT []
 newSATNames (id:ids) = newSATName id (idType id)       `thenSAT` \ id' ->
@@ -175,4 +163,5 @@ doStgSubst binder orig_args subst_env body
       = remove_static_args origs as
     remove_static_args (NotStatic:origs) (a:as)
       = substAtom a:remove_static_args origs as
       = remove_static_args origs as
     remove_static_args (NotStatic:origs) (a:as)
       = substAtom a:remove_static_args origs as
+-}
 \end{code}
 \end{code}
index a513b50..8fba50e 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1994
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[StgStats]{Gathers statistical information about programs}
 
 %
 \section[StgStats]{Gathers statistical information about programs}
 
@@ -25,11 +25,11 @@ The program gather statistics about
 
 module StgStats ( showStgStats ) where
 
 
 module StgStats ( showStgStats ) where
 
-import StgSyn
+import Ubiq{-uitous-}
 
 
-import FiniteMap
+import StgSyn
 
 
-import Util
+import FiniteMap       ( emptyFM, plusFM_C, unitFM, fmToList )
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -63,10 +63,10 @@ combineSEs :: [StatEnv] -> StatEnv
 combineSEs = foldr combineSE emptySE
 
 countOne :: CounterType -> StatEnv
 combineSEs = foldr combineSE emptySE
 
 countOne :: CounterType -> StatEnv
-countOne c = singletonFM c 1
+countOne c = unitFM c 1
 
 countN :: CounterType -> Int -> StatEnv
 
 countN :: CounterType -> Int -> StatEnv
-countN = singletonFM
+countN = unitFM
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index 258ab15..c43d816 100644 (file)
@@ -11,18 +11,23 @@ let-no-escapes.
 
 module StgVarInfo ( setStgVarInfo ) where
 
 
 module StgVarInfo ( setStgVarInfo ) where
 
-IMPORT_Trace           -- ToDo: rm (debugging only)
-import Pretty
-import Outputable
+import Ubiq{-uitous-}
 
 import StgSyn
 
 
 import StgSyn
 
-import Id              ( getIdArity, externallyVisibleId )
-import IdInfo          -- ( arityMaybe, ArityInfo )
-
-import Maybes          ( maybeToBool, Maybe(..) )
-import UniqSet
-import Util
+import Id              ( emptyIdSet, mkIdSet, minusIdSet,
+                         unionIdSets, unionManyIdSets, isEmptyIdSet,
+                         unitIdSet, intersectIdSets,
+                         addOneToIdSet, IdSet(..),
+                         nullIdEnv, growIdEnvList, lookupIdEnv,
+                         unitIdEnv, combineIdEnvs, delManyFromIdEnv,
+                         rngIdEnv, IdEnv(..),
+                         GenId{-instance Eq-}
+                       )
+import Maybes          ( maybeToBool )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-} )
+import Util            ( panic, pprPanic, assertPanic )
 
 infixr 9 `thenLne`, `thenLne_`
 \end{code}
 
 infixr 9 `thenLne`, `thenLne_`
 \end{code}
@@ -116,7 +121,7 @@ varsTopBinds (bind:binds)
     env_extension = [(b, LetrecBound
                                True {- top level -}
                                (rhsArity rhs)
     env_extension = [(b, LetrecBound
                                True {- top level -}
                                (rhsArity rhs)
-                               emptyUniqSet)
+                               emptyIdSet)
                    | (b,rhs) <- pairs]
 
     pairs         = case bind of
                    | (b,rhs) <- pairs]
 
     pairs         = case bind of
@@ -164,9 +169,9 @@ varsRhs scope_fv_info (binder, StgRhsClosure cc _ _ upd args body)
   = extendVarEnv [ (a, LambdaBound) | a <- args ] (
     do_body args body  `thenLne` \ (body2, body_fvs, body_escs) ->
     let
   = extendVarEnv [ (a, LambdaBound) | a <- args ] (
     do_body args body  `thenLne` \ (body2, body_fvs, body_escs) ->
     let
-       set_of_args     = mkUniqSet args
+       set_of_args     = mkIdSet args
        rhs_fvs         = body_fvs  `minusFVBinders` args
        rhs_fvs         = body_fvs  `minusFVBinders` args
-       rhs_escs        = body_escs `minusUniqSet`   set_of_args
+       rhs_escs        = body_escs `minusIdSet`   set_of_args
        binder_info     = lookupFVInfo scope_fv_info binder
     in
     returnLne (StgRhsClosure cc binder_info (getFVs rhs_fvs) upd args body2,
        binder_info     = lookupFVInfo scope_fv_info binder
     in
     returnLne (StgRhsClosure cc binder_info (getFVs rhs_fvs) upd args body2,
@@ -227,9 +232,7 @@ decisions.  Hence no black holes.
 
 \begin{code}
 varsExpr (StgApp lit@(StgLitArg _) args _)
 
 \begin{code}
 varsExpr (StgApp lit@(StgLitArg _) args _)
-  = --(if null args then id else (trace (ppShow 80 (ppr PprShowAll args)))) (
-    returnLne (StgApp lit [] emptyUniqSet, emptyFVInfo, emptyUniqSet)
-    --)
+  = returnLne (StgApp lit [] emptyIdSet, emptyFVInfo, emptyIdSet)
 
 varsExpr (StgApp fun@(StgVarArg f) args _) = varsApp Nothing f args
 
 
 varsExpr (StgApp fun@(StgVarArg f) args _) = varsApp Nothing f args
 
@@ -257,7 +260,7 @@ varsExpr (StgCase scrut _ _ uniq alts)
     vars_alts alts               `thenLne` \ (alts2, alts_fvs, alts_escs) ->
     lookupLiveVarsForSet alts_fvs `thenLne` \ alts_lvs ->
     let
     vars_alts alts               `thenLne` \ (alts2, alts_fvs, alts_escs) ->
     lookupLiveVarsForSet alts_fvs `thenLne` \ alts_lvs ->
     let
-       live_in_alts = live_in_cont `unionUniqSets` alts_lvs
+       live_in_alts = live_in_cont `unionIdSets` alts_lvs
     in
        -- we tell the scrutinee that everything live in the alts
        -- is live in it, too.
     in
        -- we tell the scrutinee that everything live in the alts
        -- is live in it, too.
@@ -266,12 +269,12 @@ varsExpr (StgCase scrut _ _ uniq alts)
     )                             `thenLne` \ (scrut2, scrut_fvs, scrut_escs) ->
     lookupLiveVarsForSet scrut_fvs `thenLne` \ scrut_lvs ->
     let
     )                             `thenLne` \ (scrut2, scrut_fvs, scrut_escs) ->
     lookupLiveVarsForSet scrut_fvs `thenLne` \ scrut_lvs ->
     let
-       live_in_whole_case = live_in_alts `unionUniqSets` scrut_lvs
+       live_in_whole_case = live_in_alts `unionIdSets` scrut_lvs
     in
     returnLne (
       StgCase scrut2 live_in_whole_case live_in_alts uniq alts2,
       scrut_fvs `unionFVInfo` alts_fvs,
     in
     returnLne (
       StgCase scrut2 live_in_whole_case live_in_alts uniq alts2,
       scrut_fvs `unionFVInfo` alts_fvs,
-      alts_escs `unionUniqSets` (getFVSet scrut_fvs)   -- All free vars in the scrutinee escape
+      alts_escs `unionIdSets` (getFVSet scrut_fvs)   -- All free vars in the scrutinee escape
     )
   where
     vars_alts (StgAlgAlts ty alts deflt)
     )
   where
     vars_alts (StgAlgAlts ty alts deflt)
@@ -279,13 +282,13 @@ varsExpr (StgCase scrut _ _ uniq alts)
                        `thenLne` \ (alts2,  alts_fvs_list,  alts_escs_list) ->
        let
            alts_fvs  = unionFVInfos alts_fvs_list
                        `thenLne` \ (alts2,  alts_fvs_list,  alts_escs_list) ->
        let
            alts_fvs  = unionFVInfos alts_fvs_list
-           alts_escs = unionManyUniqSets alts_escs_list
+           alts_escs = unionManyIdSets alts_escs_list
        in
        vars_deflt deflt `thenLne` \ (deflt2, deflt_fvs, deflt_escs) ->
        returnLne (
            StgAlgAlts ty alts2 deflt2,
            alts_fvs  `unionFVInfo`   deflt_fvs,
        in
        vars_deflt deflt `thenLne` \ (deflt2, deflt_fvs, deflt_escs) ->
        returnLne (
            StgAlgAlts ty alts2 deflt2,
            alts_fvs  `unionFVInfo`   deflt_fvs,
-           alts_escs `unionUniqSets` deflt_escs
+           alts_escs `unionIdSets` deflt_escs
        )
       where
        vars_alg_alt (con, binders, worthless_use_mask, rhs)
        )
       where
        vars_alg_alt (con, binders, worthless_use_mask, rhs)
@@ -298,7 +301,7 @@ varsExpr (StgCase scrut _ _ uniq alts)
            returnLne (
                (con, binders, good_use_mask, rhs2),
                rhs_fvs  `minusFVBinders` binders,
            returnLne (
                (con, binders, good_use_mask, rhs2),
                rhs_fvs  `minusFVBinders` binders,
-               rhs_escs `minusUniqSet`   mkUniqSet binders     -- ToDo: remove the minusUniqSet;
+               rhs_escs `minusIdSet`   mkIdSet binders -- ToDo: remove the minusIdSet;
                                                        -- since escs won't include
                                                        -- any of these binders
            ))
                                                        -- since escs won't include
                                                        -- any of these binders
            ))
@@ -308,13 +311,13 @@ varsExpr (StgCase scrut _ _ uniq alts)
                        `thenLne` \ (alts2,  alts_fvs_list,  alts_escs_list) ->
        let
            alts_fvs  = unionFVInfos alts_fvs_list
                        `thenLne` \ (alts2,  alts_fvs_list,  alts_escs_list) ->
        let
            alts_fvs  = unionFVInfos alts_fvs_list
-           alts_escs = unionManyUniqSets alts_escs_list
+           alts_escs = unionManyIdSets alts_escs_list
        in
        vars_deflt deflt `thenLne` \ (deflt2, deflt_fvs, deflt_escs) ->
        returnLne (
            StgPrimAlts ty alts2 deflt2,
            alts_fvs  `unionFVInfo`   deflt_fvs,
        in
        vars_deflt deflt `thenLne` \ (deflt2, deflt_fvs, deflt_escs) ->
        returnLne (
            StgPrimAlts ty alts2 deflt2,
            alts_fvs  `unionFVInfo`   deflt_fvs,
-           alts_escs `unionUniqSets` deflt_escs
+           alts_escs `unionIdSets` deflt_escs
        )
       where
        vars_prim_alt (lit, rhs)
        )
       where
        vars_prim_alt (lit, rhs)
@@ -322,7 +325,7 @@ varsExpr (StgCase scrut _ _ uniq alts)
            returnLne ((lit, rhs2), rhs_fvs, rhs_escs)
 
     vars_deflt StgNoDefault
            returnLne ((lit, rhs2), rhs_fvs, rhs_escs)
 
     vars_deflt StgNoDefault
-      = returnLne (StgNoDefault, emptyFVInfo, emptyUniqSet)
+      = returnLne (StgNoDefault, emptyFVInfo, emptyIdSet)
 
     vars_deflt (StgBindDefault binder _ rhs)
       = extendVarEnv [(binder, CaseBound)] (
 
     vars_deflt (StgBindDefault binder _ rhs)
       = extendVarEnv [(binder, CaseBound)] (
@@ -333,7 +336,7 @@ varsExpr (StgCase scrut _ _ uniq alts)
        returnLne (
            StgBindDefault binder used_in_rhs rhs2,
            rhs_fvs  `minusFVBinders` [binder],
        returnLne (
            StgBindDefault binder used_in_rhs rhs2,
            rhs_fvs  `minusFVBinders` [binder],
-           rhs_escs `minusUniqSet`   singletonUniqSet binder
+           rhs_escs `minusIdSet`   unitIdSet binder
        ))
 \end{code}
 
        ))
 \end{code}
 
@@ -402,17 +405,17 @@ varsApp maybe_thunk_body f args
            other ->    NoStgBinderInfo
                -- uninteresting variable
 
            other ->    NoStgBinderInfo
                -- uninteresting variable
 
-       myself = singletonUniqSet f
+       myself = unitIdSet f
 
        fun_escs = case how_bound of
 
                     LetrecBound _ arity lvs ->
                       if arity == n_args then
 
        fun_escs = case how_bound of
 
                     LetrecBound _ arity lvs ->
                       if arity == n_args then
-                         emptyUniqSet -- Function doesn't escape
+                         emptyIdSet -- Function doesn't escape
                       else
                          myself -- Inexact application; it does escape
 
                       else
                          myself -- Inexact application; it does escape
 
-                    other -> emptyUniqSet      -- Only letrec-bound escapees
+                    other -> emptyIdSet        -- Only letrec-bound escapees
                                                -- are interesting
 
        -- At the moment of the call:
                                                -- are interesting
 
        -- At the moment of the call:
@@ -427,14 +430,14 @@ varsApp maybe_thunk_body f args
        --         two regardless.
 
        live_at_call
        --         two regardless.
 
        live_at_call
-         = live_in_cont `unionUniqSets` case how_bound of
-                                  LetrecBound _ _ lvs -> lvs `minusUniqSet` myself
-                                  other               -> emptyUniqSet
+         = live_in_cont `unionIdSets` case how_bound of
+                                  LetrecBound _ _ lvs -> lvs `minusIdSet` myself
+                                  other               -> emptyIdSet
     in
     returnLne (
        StgApp (StgVarArg f) args live_at_call,
        fun_fvs  `unionFVInfo` args_fvs,
     in
     returnLne (
        StgApp (StgVarArg f) args live_at_call,
        fun_fvs  `unionFVInfo` args_fvs,
-       fun_escs `unionUniqSets` (getFVSet args_fvs)
+       fun_escs `unionIdSets` (getFVSet args_fvs)
                                -- All the free vars of the args are disqualified
                                -- from being let-no-escaped.
     )
                                -- All the free vars of the args are disqualified
                                -- from being let-no-escaped.
     )
@@ -458,7 +461,7 @@ vars_let let_no_escape bind body
        -- we ain't in a let-no-escape world
        getVarsLiveInCont               `thenLne` \ live_in_cont ->
        setVarsLiveInCont
        -- we ain't in a let-no-escape world
        getVarsLiveInCont               `thenLne` \ live_in_cont ->
        setVarsLiveInCont
-               (if let_no_escape then live_in_cont else emptyUniqSet)
+               (if let_no_escape then live_in_cont else emptyIdSet)
                (vars_bind rec_bind_lvs rec_body_fvs bind)
                                        `thenLne` \ (bind2, bind_fvs, bind_escs, env_ext) ->
 
                (vars_bind rec_bind_lvs rec_body_fvs bind)
                                        `thenLne` \ (bind2, bind_fvs, bind_escs, env_ext) ->
 
@@ -467,7 +470,7 @@ vars_let let_no_escape bind body
        -- together with the live_in_cont ones
        lookupLiveVarsForSet (bind_fvs `minusFVBinders` binders)        `thenLne` \ lvs_from_fvs ->
        let
        -- together with the live_in_cont ones
        lookupLiveVarsForSet (bind_fvs `minusFVBinders` binders)        `thenLne` \ lvs_from_fvs ->
        let
-               bind_lvs = lvs_from_fvs `unionUniqSets` live_in_cont
+               bind_lvs = lvs_from_fvs `unionIdSets` live_in_cont
        in
 
        -- bind_fvs and bind_escs still include the binders of the let(rec)
        in
 
        -- bind_fvs and bind_escs still include the binders of the let(rec)
@@ -498,7 +501,7 @@ vars_let let_no_escape bind body
          = (bind_fvs `unionFVInfo` body_fvs) `minusFVBinders` binders
 
        live_in_whole_let
          = (bind_fvs `unionFVInfo` body_fvs) `minusFVBinders` binders
 
        live_in_whole_let
-         = bind_lvs `unionUniqSets` (body_lvs `minusUniqSet` set_of_binders)
+         = bind_lvs `unionIdSets` (body_lvs `minusIdSet` set_of_binders)
 
        real_bind_escs = if let_no_escape then
                            bind_escs
 
        real_bind_escs = if let_no_escape then
                            bind_escs
@@ -506,12 +509,12 @@ vars_let let_no_escape bind body
                            getFVSet bind_fvs
                            -- Everything escapes which is free in the bindings
 
                            getFVSet bind_fvs
                            -- Everything escapes which is free in the bindings
 
-       let_escs = (real_bind_escs `unionUniqSets` body_escs) `minusUniqSet` set_of_binders
+       let_escs = (real_bind_escs `unionIdSets` body_escs) `minusIdSet` set_of_binders
 
 
-       all_escs = bind_escs `unionUniqSets` body_escs  -- Still includes binders of
+       all_escs = bind_escs `unionIdSets` body_escs    -- Still includes binders of
                                                -- this let(rec)
 
                                                -- this let(rec)
 
-       no_binder_escapes = isEmptyUniqSet (set_of_binders `intersectUniqSets` all_escs)
+       no_binder_escapes = isEmptyIdSet (set_of_binders `intersectIdSets` all_escs)
                -- Mustn't depend on the passed-in let_no_escape flag, since
                -- no_binder_escapes is used by the caller to derive the flag!
     in
                -- Mustn't depend on the passed-in let_no_escape flag, since
                -- no_binder_escapes is used by the caller to derive the flag!
     in
@@ -525,7 +528,7 @@ vars_let let_no_escape bind body
     binders            = case bind of
                            StgNonRec binder rhs -> [binder]
                            StgRec pairs         -> map fst pairs
     binders            = case bind of
                            StgNonRec binder rhs -> [binder]
                            StgRec pairs         -> map fst pairs
-    set_of_binders     = mkUniqSet binders
+    set_of_binders     = mkIdSet binders
 
     mk_binding bind_lvs (binder,rhs)
        = (binder,
 
     mk_binding bind_lvs (binder,rhs)
        = (binder,
@@ -535,9 +538,9 @@ vars_let let_no_escape bind body
          )
        where
           live_vars = if let_no_escape then
          )
        where
           live_vars = if let_no_escape then
-                           bind_lvs `unionUniqSets` singletonUniqSet binder
+                           addOneToIdSet bind_lvs binder
                       else
                       else
-                           singletonUniqSet binder
+                           unitIdSet binder
 
     vars_bind :: StgLiveVars
              -> FreeVarsInfo                   -- Free var info for body of binding
 
     vars_bind :: StgLiveVars
              -> FreeVarsInfo                   -- Free var info for body of binding
@@ -567,7 +570,7 @@ vars_let let_no_escape bind body
                mapAndUnzip3Lne (varsRhs rec_scope_fvs) pairs `thenLne` \ (rhss2, fvss, escss) ->
                let
                        fvs  = unionFVInfos      fvss
                mapAndUnzip3Lne (varsRhs rec_scope_fvs) pairs `thenLne` \ (rhss2, fvss, escss) ->
                let
                        fvs  = unionFVInfos      fvss
-                       escs = unionManyUniqSets escss
+                       escs = unionManyIdSets escss
                in
                returnLne (StgRec (binders `zip` rhss2), fvs, escs, env_ext)
        ))
                in
                returnLne (StgRec (binders `zip` rhss2), fvs, escs, env_ext)
        ))
@@ -588,15 +591,13 @@ type LneM a =  Bool                       -- True <=> do let-no-escapes
            -> StgLiveVars              -- vars live in continuation
            -> a
 
            -> StgLiveVars              -- vars live in continuation
            -> a
 
-type Arity = Int
-
 data HowBound
   = ImportBound
   | CaseBound
   | LambdaBound
   | LetrecBound
 data HowBound
   = ImportBound
   | CaseBound
   | LambdaBound
   | LetrecBound
-       Bool                    -- True <=> bound at top level
-       Arity                   -- Arity
+       Bool            -- True <=> bound at top level
+       Arity           -- Arity
        StgLiveVars     -- Live vars... see notes below
 \end{code}
 
        StgLiveVars     -- Live vars... see notes below
 \end{code}
 
@@ -610,7 +611,7 @@ in the LetrecBound constructor; x itself *is* included.
 The std monad functions:
 \begin{code}
 initLne :: Bool -> LneM a -> a
 The std monad functions:
 \begin{code}
 initLne :: Bool -> LneM a -> a
-initLne want_LNEs m = m want_LNEs nullIdEnv emptyUniqSet
+initLne want_LNEs m = m want_LNEs nullIdEnv emptyIdSet
 
 {-# INLINE thenLne #-}
 {-# INLINE thenLne_ #-}
 
 {-# INLINE thenLne #-}
 {-# INLINE thenLne_ #-}
@@ -692,17 +693,17 @@ lookupVarEnv v sw env lvs_cont
 lookupLiveVarsForSet :: FreeVarsInfo -> LneM StgLiveVars
 
 lookupLiveVarsForSet fvs sw env lvs_cont
 lookupLiveVarsForSet :: FreeVarsInfo -> LneM StgLiveVars
 
 lookupLiveVarsForSet fvs sw env lvs_cont
-  = returnLne (unionManyUniqSets (map do_one (getFVs fvs)))
+  = returnLne (unionManyIdSets (map do_one (getFVs fvs)))
              sw env lvs_cont
   where
     do_one v
       = if isLocallyDefined v then
            case (lookupIdEnv env v) of
              sw env lvs_cont
   where
     do_one v
       = if isLocallyDefined v then
            case (lookupIdEnv env v) of
-             Just (LetrecBound _ _ lvs) -> lvs `unionUniqSets` singletonUniqSet v
-             Just _                     -> singletonUniqSet v
+             Just (LetrecBound _ _ lvs) -> addOneToIdSet lvs v
+             Just _                     -> unitIdSet v
              Nothing -> pprPanic "lookupVarEnv/do_one:" (ppr PprShowAll v)
        else
              Nothing -> pprPanic "lookupVarEnv/do_one:" (ppr PprShowAll v)
        else
-           emptyUniqSet
+           emptyIdSet
 \end{code}
 
 
 \end{code}
 
 
@@ -724,7 +725,7 @@ type FreeVarsInfo = IdEnv (Id, Bool, StgBinderInfo)
                        --
                        -- The Bool is True <=> the Id is top level letrec bound
 
                        --
                        -- The Bool is True <=> the Id is top level letrec bound
 
-type EscVarsSet   = UniqSet Id
+type EscVarsSet   = IdSet
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -756,8 +757,8 @@ lookupFVInfo fvs id = case lookupIdEnv fvs id of
 getFVs :: FreeVarsInfo -> [Id] -- Non-top-level things only
 getFVs fvs = [id | (id,False,_) <- rngIdEnv fvs]
 
 getFVs :: FreeVarsInfo -> [Id] -- Non-top-level things only
 getFVs fvs = [id | (id,False,_) <- rngIdEnv fvs]
 
-getFVSet :: FreeVarsInfo -> UniqSet Id
-getFVSet fvs = mkUniqSet (getFVs fvs)
+getFVSet :: FreeVarsInfo -> IdSet
+getFVSet fvs = mkIdSet (getFVs fvs)
 
 plusFVInfo (id1,top1,info1) (id2,top2,info2)
   = ASSERT (id1 == id2 && top1 == top2)
 
 plusFVInfo (id1,top1,info1) (id2,top2,info2)
   = ASSERT (id1 == id2 && top1 == top2)
index f4ac876..553acac 100644 (file)
@@ -1,7 +1,7 @@
 \section{Update Avoidance Analyser}                    -*-haskell-literate-*-
 
 (c) Simon Marlow, Andre Santos 1992-1993
 \section{Update Avoidance Analyser}                    -*-haskell-literate-*-
 
 (c) Simon Marlow, Andre Santos 1992-1993
-(c) The AQUA Project, Glasgow University, 1995
+(c) The AQUA Project, Glasgow University, 1995-1996
 
 %-----------------------------------------------------------------------------
 \subsection{Module Interface}
 
 %-----------------------------------------------------------------------------
 \subsection{Module Interface}
 
 > module UpdAnal ( updateAnalyse ) where
 >
 
 > module UpdAnal ( updateAnalyse ) where
 >
-> import Type          ( splitTyArgs, splitSigmaTy, Class, TyVarTemplate,
->                        TauType(..)
->                      )
-> import Id
-> import IdInfo
-> import Outputable    ( isExported )
-> import Pretty
-> import SrcLoc        ( mkUnknownSrcLoc )
+> import Ubiq{-uitous-}
+>
 > import StgSyn
 > import StgSyn
-> import UniqSet
-> import UniqSupply    ( getBuiltinUniques )
-> import Util
+> import Util          ( panic )
+>
+> updateAnalyse :: [StgBinding] -> [StgBinding] {- Exported -}
+> updateAnalyse = panic "UpdAnal.updateAnalyse"
+>
+> {- LATER: to end of file:
+> --import Type                ( splitTyArgs, splitSigmaTy, Class, TyVarTemplate,
+> --                     TauType(..)
+> --                   )
+> --import Id
+> --import IdInfo
+> --import Outputable  ( isExported )
+> --import Pretty
+> --import SrcLoc      ( mkUnknownSrcLoc )
+> --import StgSyn
+> --import UniqSet
+> --import UniqSupply  ( getBuiltinUniques )
+> --import Util
 
 %-----------------------------------------------------------------------------
 \subsection{Reverse application}
 
 %-----------------------------------------------------------------------------
 \subsection{Reverse application}
@@ -503,5 +512,6 @@ suffice for now.
 >                              addIdUpdateInfo v
 >                                      (mkUpdateInfo (mkUpdateSpec v c))
 >              | otherwise    = v
 >                              addIdUpdateInfo v
 >                                      (mkUpdateInfo (mkUpdateSpec v c))
 >              | otherwise    = v
+> -}
 
 %-----------------------------------------------------------------------------
 
 %-----------------------------------------------------------------------------
index 374b4c0..64319b8 100644 (file)
@@ -115,7 +115,8 @@ lookupSpecId unspec_id ty_maybes
 
     case (firstJust (map try spec_infos)) of
       Just id -> id
 
     case (firstJust (map try spec_infos)) of
       Just id -> id
-      Nothing -> error ("ERROR: There is some confusion about a value specialised to a type;\ndetails follow (and more info in the User's Guide):\n\t"++(ppShow 80 (ppr PprDebug unspec_id)))
+      Nothing -> pprError "ERROR: There is some confusion about a value specialised to a type;\ndetails follow (and more info in the User's Guide):\n\t"
+                         (ppr PprDebug unspec_id)
     }
   where
     try (SpecInfo template_maybes _ id)
     }
   where
     try (SpecInfo template_maybes _ id)
@@ -188,7 +189,7 @@ lookupSpecEnv se@(SpecEnv spec_infos) spec_tys
     match [{-out of templates-}] [] = Just []
 
     match (Nothing:ty_maybes) (spec_ty:spec_tys)
     match [{-out of templates-}] [] = Just []
 
     match (Nothing:ty_maybes) (spec_ty:spec_tys)
-      = case (isUnboxedDataType spec_ty) of
+      = case (isUnboxedType spec_ty) of
          True  -> Nothing      -- Can only match boxed type against
                                -- type argument which has not been
                                -- specialised on
          True  -> Nothing      -- Can only match boxed type against
                                -- type argument which has not been
                                -- specialised on
@@ -248,6 +249,6 @@ pp_specs sty print_spec_ids better_id_fn inline_env (SpecEnv specs)
     pp_the_list (p:ps) = ppBesides [p, pp'SP{-'-}, pp_the_list ps]
 
     pp_maybe Nothing  = ifPprInterface sty pp_NONE
     pp_the_list (p:ps) = ppBesides [p, pp'SP{-'-}, pp_the_list ps]
 
     pp_maybe Nothing  = ifPprInterface sty pp_NONE
-    pp_maybe (Just t) = pprParendType sty t
+    pp_maybe (Just t) = pprParendGenType sty t
 \end{pseudocode}
 
 \end{pseudocode}
 
index 8a01992..c360e61 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
 %
 \section[Specialise]{Stamping out overloading, and (optionally) polymorphism}
 
 %
 \section[Specialise]{Stamping out overloading, and (optionally) polymorphism}
 
@@ -21,19 +21,39 @@ module SpecUtils (
        pprSpecErrs
     ) where
 
        pprSpecErrs
     ) where
 
-import Type
-import Bag             ( Bag, isEmptyBag, bagToList )
-import FiniteMap       ( FiniteMap, emptyFM, addListToFM_C,
-                         plusFM_C, keysFM, lookupWithDefaultFM
+import Ubiq{-uitous-}
+
+import Bag             ( isEmptyBag, bagToList )
+import Class           ( getClassOpString, GenClass{-instance NamedThing-} )
+import FiniteMap       ( emptyFM, addListToFM_C, plusFM_C, keysFM,
+                         lookupWithDefaultFM
                        )
                        )
-import Id              ( mkSameSpecCon, idType,
-                         isDictFunId, isConstMethodId_maybe,
+import Id              ( idType, isDictFunId, isConstMethodId_maybe,
                          isDefaultMethodId_maybe,
                          isDefaultMethodId_maybe,
-                         getInstIdModule, Id )
-import Maybes
-import Outputable
-import Pretty
-import Util
+                         GenId {-instance NamedThing -}
+                       )
+import Maybes          ( maybeToBool, catMaybes, firstJust )
+import Outputable      ( isAvarop, pprNonOp )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( pprGenType, pprParendGenType, pprMaybeTy,
+                         TyCon{-ditto-}, GenType{-ditto-}, GenTyVar
+                       )
+import Pretty          -- plenty of it
+import TyCon           ( tyConTyVars, TyCon{-instance NamedThing-} )
+import Type            ( splitSigmaTy, mkTyVarTy, mkForAllTys,
+                         getTyVar_maybe, isUnboxedType
+                       )
+import TyVar           ( GenTyVar{-instance Eq-} )
+import Unique          ( Unique{-instance Eq-} )
+import Util            ( equivClasses, zipWithEqual, cmpPString,
+                         assertPanic, panic{-ToDo:rm-}
+                       )
+
+cmpType = panic "SpecUtils.cmpType (ToDo: get rid of)"
+mkSameSpecCon = panic "SpecUtils.mkSameSpecCon (ToDo)"
+getInstIdModule = panic "SpecUtils.getInstIdModule (ToDo)"
+specialiseTy :: Type -> [Maybe Type] -> Int -> Type
+specialiseTy = panic "SpecUtils.specialiseTy (ToDo)"
 \end{code}
 
 @specialiseCallTys@ works out which type args don't need to be specialised on,
 \end{code}
 
 @specialiseCallTys@ works out which type args don't need to be specialised on,
@@ -52,7 +72,7 @@ specialiseCallTys True _ _ cvec tys
 specialiseCallTys False spec_unboxed spec_overloading cvec tys
   = zipWithEqual spec_ty_other cvec tys
   where
 specialiseCallTys False spec_unboxed spec_overloading cvec tys
   = zipWithEqual spec_ty_other cvec tys
   where
-    spec_ty_other c ty | (spec_unboxed && isUnboxedDataType ty)
+    spec_ty_other c ty | (spec_unboxed && isUnboxedType ty)
                         || (spec_overloading && c)
                         = Just ty
                       | otherwise
                         || (spec_overloading && c)
                         = Just ty
                       | otherwise
@@ -85,16 +105,16 @@ gained by specialising wrt them.
 
 \begin{code}
 getIdOverloading :: Id
 
 \begin{code}
 getIdOverloading :: Id
-                -> ([TyVarTemplate], [(Class,TyVarTemplate)])
+                -> ([TyVar], [(Class,TyVar)])
 getIdOverloading id
   = (tyvars, tyvar_part_of theta)
   where
     (tyvars, theta, _) = splitSigmaTy (idType id)
 
 getIdOverloading id
   = (tyvars, tyvar_part_of theta)
   where
     (tyvars, theta, _) = splitSigmaTy (idType id)
 
-    tyvar_part_of []                 = []
-    tyvar_part_of ((clas,ty) : theta) = case getTyVarTemplateMaybe ty of
-                                           Nothing    -> []
-                                           Just tyvar -> (clas, tyvar) : tyvar_part_of theta
+    tyvar_part_of []            = []
+    tyvar_part_of ((c,ty):theta) = case (getTyVar_maybe ty) of
+                                    Nothing -> []
+                                    Just tv -> (c, tv) : tyvar_part_of theta
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -115,7 +135,7 @@ isUnboxedSpecialisation :: [Maybe Type] -> Bool
 isUnboxedSpecialisation tys
   = any is_unboxed tys
   where
 isUnboxedSpecialisation tys
   = any is_unboxed tys
   where
-    is_unboxed (Just ty) = isUnboxedDataType ty
+    is_unboxed (Just ty) = isUnboxedType ty
     is_unboxed Nothing   = False
 \end{code}
 
     is_unboxed Nothing   = False
 \end{code}
 
@@ -129,7 +149,7 @@ specialiseConstrTys :: [Type]
 specialiseConstrTys tys
   = map maybe_unboxed_ty tys
   where
 specialiseConstrTys tys
   = map maybe_unboxed_ty tys
   where
-    maybe_unboxed_ty ty = case isUnboxedDataType ty of
+    maybe_unboxed_ty ty = case isUnboxedType ty of
                            True  -> Just ty
                            False -> Nothing
 \end{code}
                            True  -> Just ty
                            False -> Nothing
 \end{code}
@@ -156,13 +176,13 @@ argTysMatchSpecTys_error spec_tys arg_tys
     then Nothing
     else Just (ppSep [ppStr "Spec and Arg Types Inconsistent:",
                      ppStr "spectys=", ppSep [pprMaybeTy PprDebug ty | ty <- spec_tys],
     then Nothing
     else Just (ppSep [ppStr "Spec and Arg Types Inconsistent:",
                      ppStr "spectys=", ppSep [pprMaybeTy PprDebug ty | ty <- spec_tys],
-                     ppStr "argtys=", ppSep [pprParendType PprDebug ty | ty <- arg_tys]])
+                     ppStr "argtys=", ppSep [pprParendGenType PprDebug ty | ty <- arg_tys]])
   where
     match (Nothing:spec_tys) (arg:arg_tys)
   where
     match (Nothing:spec_tys) (arg:arg_tys)
-      = not (isUnboxedDataType arg) &&
+      = not (isUnboxedType arg) &&
        match spec_tys arg_tys
     match (Just spec:spec_tys) (arg:arg_tys)
        match spec_tys arg_tys
     match (Just spec:spec_tys) (arg:arg_tys)
-      = case (cmpUniType True{-properly-} spec arg) of
+      = case (cmpType True{-properly-} spec arg) of
          EQ_   -> match spec_tys arg_tys
          other -> False
     match [] [] = True
          EQ_   -> match spec_tys arg_tys
          other -> False
     match [] [] = True
@@ -261,7 +281,7 @@ pprSpecErrs this_mod spec_errs spec_warn spec_tyerrs
        mod_tyspecs = lookupWithDefaultFM tyspecs_fm [] mod
        mod_idspecs = lookupWithDefaultFM idspecs_fm [] mod
        have_specs  = not (null mod_tyspecs && null mod_idspecs)
        mod_tyspecs = lookupWithDefaultFM tyspecs_fm [] mod
        mod_idspecs = lookupWithDefaultFM idspecs_fm [] mod
        have_specs  = not (null mod_tyspecs && null mod_idspecs)
-       ty_sty = PprInterface (error "SpecUtils:PprInterface:sw_chkr")
+       ty_sty = PprInterface
 
 pp_module mod
   = ppBesides [ppPStr mod, ppStr ":"]
 
 pp_module mod
   = ppBesides [ppPStr mod, ppStr ":"]
@@ -271,15 +291,15 @@ pp_tyspec :: PprStyle -> Pretty -> (FAST_STRING, TyCon, [Maybe Type]) -> Pretty
 pp_tyspec sty pp_mod (_, tycon, tys)
   = ppCat [pp_mod,
           ppStr "{-# SPECIALIZE", ppStr "data",
 pp_tyspec sty pp_mod (_, tycon, tys)
   = ppCat [pp_mod,
           ppStr "{-# SPECIALIZE", ppStr "data",
-          pprNonOp PprForUser tycon, ppCat (map (pprParendType sty) spec_tys),
+          pprNonOp PprForUser tycon, ppCat (map (pprParendGenType sty) spec_tys),
           ppStr "#-}", ppStr "{- Essential -}"
           ]
   where
           ppStr "#-}", ppStr "{- Essential -}"
           ]
   where
-    tvs = getTyConTyVarTemplates tycon
+    tvs = tyConTyVars tycon
     (spec_args, tv_maybes) = unzip (map choose_ty (tvs `zip` tys))
     (spec_args, tv_maybes) = unzip (map choose_ty (tvs `zip` tys))
-    spec_tys = map (mkForallTy (catMaybes tv_maybes)) spec_args
+    spec_tys = map (mkForAllTys (catMaybes tv_maybes)) spec_args
 
 
-    choose_ty (tv, Nothing) = (mkTyVarTemplateTy tv, Just tv)
+    choose_ty (tv, Nothing) = (mkTyVarTy tv, Just tv)
     choose_ty (tv, Just ty) = (ty, Nothing)
 
 pp_idspec :: PprStyle -> Pretty -> (FAST_STRING, Id, [Maybe Type], Bool) -> Pretty
     choose_ty (tv, Just ty) = (ty, Nothing)
 
 pp_idspec :: PprStyle -> Pretty -> (FAST_STRING, Id, [Maybe Type], Bool) -> Pretty
@@ -289,7 +309,7 @@ pp_idspec sty pp_mod (_, id, tys, is_err)
   = ppCat [pp_mod,
           ppStr "{-# SPECIALIZE",
           ppStr "instance",
   = ppCat [pp_mod,
           ppStr "{-# SPECIALIZE",
           ppStr "instance",
-          pprType sty spec_ty,
+          pprGenType sty spec_ty,
           ppStr "#-}", pp_essential ]
 
   | is_const_method_id
           ppStr "#-}", pp_essential ]
 
   | is_const_method_id
@@ -301,9 +321,9 @@ pp_idspec sty pp_mod (_, id, tys, is_err)
     ppCat [pp_mod,
           ppStr "{-# SPECIALIZE",
           pp_clsop clsop_str, ppStr "::",
     ppCat [pp_mod,
           ppStr "{-# SPECIALIZE",
           pp_clsop clsop_str, ppStr "::",
-          pprType sty spec_ty,
+          pprGenType sty spec_ty,
           ppStr "#-} {- IN instance",
           ppStr "#-} {- IN instance",
-          ppPStr cls_str, pprParendType sty clsty,
+          ppPStr cls_str, pprParendGenType sty clsty,
           ppStr "-}", pp_essential ]
 
   | is_default_method_id
           ppStr "-}", pp_essential ]
 
   | is_default_method_id
@@ -317,14 +337,14 @@ pp_idspec sty pp_mod (_, id, tys, is_err)
           ppPStr cls_str,
           ppStr "EXPLICIT METHOD REQUIRED",
           pp_clsop clsop_str, ppStr "::",
           ppPStr cls_str,
           ppStr "EXPLICIT METHOD REQUIRED",
           pp_clsop clsop_str, ppStr "::",
-          pprType sty spec_ty,
+          pprGenType sty spec_ty,
           ppStr "-}", pp_essential ]
 
   | otherwise
   = ppCat [pp_mod,
           ppStr "{-# SPECIALIZE",
           pprNonOp PprForUser id, ppStr "::",
           ppStr "-}", pp_essential ]
 
   | otherwise
   = ppCat [pp_mod,
           ppStr "{-# SPECIALIZE",
           pprNonOp PprForUser id, ppStr "::",
-          pprType sty spec_ty,
+          pprGenType sty spec_ty,
           ppStr "#-}", pp_essential ]
   where
     spec_ty = specialiseTy (idType id) tys 100   -- HACK to drop all dicts!!!
           ppStr "#-}", pp_essential ]
   where
     spec_ty = specialiseTy (idType id) tys 100   -- HACK to drop all dicts!!!
index e96941a..42cd011 100644 (file)
@@ -15,25 +15,84 @@ module Specialise (
 
     ) where
 
 
     ) where
 
-import SpecUtils
+import Ubiq{-uitous-}
 
 
-import PrelInfo                ( liftDataCon, PrimOp(..), PrimRep -- for CCallOp
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
+import Bag             ( emptyBag, unitBag, isEmptyBag, unionBags,
+                         partitionBag, listToBag, bagToList
+                       )
+import Class           ( GenClass{-instance Eq-} )
+import CmdLineOpts     ( opt_SpecialiseImports, opt_D_simplifier_stats,
+                         opt_CompilingPrelude, opt_SpecialiseTrace,
+                         opt_SpecialiseOverloaded, opt_SpecialiseUnboxed,
+                         opt_SpecialiseAll
                        )
                        )
-import Type
-import Bag
-import CmdLineOpts     ( GlobalSwitch(..) )
 import CoreLift                ( mkLiftedId, liftExpr, bindUnlift, applyBindUnlifts )
 import CoreLift                ( mkLiftedId, liftExpr, bindUnlift, applyBindUnlifts )
-import FiniteMap
-import Id
-import IdInfo          -- All of it
-import Maybes          ( catMaybes, firstJust, maybeToBool, Maybe(..) )
-import UniqSet         -- All of it
-import Util
-import UniqSupply
+import CoreSyn
+import CoreUtils       ( coreExprType, squashableDictishCcExpr )
+import FiniteMap       ( addListToFM_C )
+import Id              ( idType, isDefaultMethodId_maybe, toplevelishId,
+                         isSuperDictSelId_maybe, isBottomingId,
+                         isConstMethodId_maybe, isDataCon,
+                         isImportedId, mkIdWithNewUniq,
+                         dataConTyCon, applyTypeEnvToId,
+                         nullIdEnv, addOneToIdEnv, growIdEnvList,
+                         lookupIdEnv, IdEnv(..),
+                         emptyIdSet, mkIdSet, unitIdSet,
+                         elementOfIdSet, minusIdSet,
+                         unionIdSets, unionManyIdSets, IdSet(..),
+                         GenId{-instance Eq-}
+                       )
+import Literal         ( Literal{-instance Outputable-} )
+import Maybes          ( catMaybes, firstJust, maybeToBool )
+import Outputable      ( interppSP, Outputable(..){-instance * []-} )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( pprGenType, pprParendGenType, pprMaybeTy,
+                         GenType{-instance Outputable-}, GenTyVar{-ditto-},
+                         TyCon{-ditto-}
+                       )
+import PrelInfo                ( liftDataCon )
+import Pretty          ( ppHang, ppCat, ppStr, ppAboves, ppBesides,
+                         ppInt, ppSP, ppInterleave, ppNil, Pretty(..)
+                       )
+import PrimOp          ( PrimOp(..) )
+import SpecUtils
+import Type            ( mkTyVarTy, mkTyVarTys, isTyVarTy, getAppDataTyCon,
+                         tyVarsOfTypes, applyTypeEnvToTy, isUnboxedType
+                       )
+import TyCon           ( TyCon{-instance Eq-} )
+import TyVar           ( cloneTyVar,
+                         elementOfTyVarSet, TyVarSet(..),
+                         nullTyVarEnv, growTyVarEnvList, TyVarEnv(..),
+                         GenTyVar{-instance Eq-}
+                       )
+import Unique          ( Unique{-instance Eq-} )
+import UniqSet         ( mkUniqSet, unionUniqSets, uniqSetToList )
+import UniqSupply      ( splitUniqSupply, getUniques, getUnique )
+import Util            ( equivClasses, mapAccumL, assoc, zipWithEqual,
+                         panic, pprTrace, pprPanic, assertPanic
+                       )
 
 infixr 9 `thenSM`
 
 infixr 9 `thenSM`
+
+--ToDo:kill
+data SpecInfo = SpecInfo [Maybe Type] Int Id
+
+addIdSpecialisation = panic "Specialise.addIdSpecialisation (ToDo)"
+cmpUniTypeMaybeList = panic "Specialise.cmpUniTypeMaybeList (ToDo)"
+getIdSpecialisation = panic "Specialise.getIdSpecialisation (ToDo)"
+isClassOpId = panic "Specialise.isClassOpId (ToDo)"
+isDictTy = panic "Specialise.isDictTy (ToDo)"
+isLocalGenTyCon = panic "Specialise.isLocalGenTyCon (ToDo)"
+isLocalSpecTyCon = panic "Specialise.isLocalSpecTyCon (ToDo)"
+isSpecId_maybe = panic "Specialise.isSpecId_maybe (ToDo)"
+isSpecPragmaId_maybe = panic "Specialise.isSpecPragmaId_maybe (ToDo)"
+lookupClassInstAtSimpleType = panic "Specialise.lookupClassInstAtSimpleType (ToDo)"
+lookupSpecEnv = panic "Specialise.lookupSpecEnv (ToDo)"
+mkPolySysTyVar = panic "Specialise.mkPolySysTyVar (ToDo)"
+mkSpecEnv = panic "Specialise.mkSpecEnv (ToDo)"
+mkSpecId = panic "Specialise.mkSpecId (ToDo)"
+selectIdInfoForSpecId = panic "Specialise.selectIdInfoForSpecId (ToDo)"
+specialiseTy = panic "Specialise.specialiseTy (ToDo)"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -614,18 +673,18 @@ strictness analyser deems the lifted binding strict.
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-type FreeVarsSet   = UniqSet Id
-type FreeTyVarsSet = UniqSet TyVar
+type FreeVarsSet   = IdSet
+type FreeTyVarsSet = TyVarSet
 
 data CallInstance
   = CallInstance
 
 data CallInstance
   = CallInstance
-               Id                      -- This Id; *new* ie *cloned* id
-               [Maybe Type]            -- Specialised at these types (*new*, cloned)
-                                       -- Nothing => no specialisation on this type arg
-                                       --            is required (flag dependent).
-               [CoreArg]               -- And these dictionaries; all ValArgs
-               FreeVarsSet             -- Free vars of the dict-args in terms of *new* ids
-               (Maybe SpecInfo)        -- For specialisation with explicit SpecId
+               Id                -- This Id; *new* ie *cloned* id
+               [Maybe Type]      -- Specialised at these types (*new*, cloned)
+                                 -- Nothing => no specialisation on this type arg
+                                 --          is required (flag dependent).
+               [CoreArg]         -- And these dictionaries; all ValArgs
+               FreeVarsSet       -- Free vars of the dict-args in terms of *new* ids
+               (Maybe SpecInfo)  -- For specialisation with explicit SpecId
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -634,14 +693,19 @@ pprCI (CallInstance id spec_tys dicts _ maybe_specinfo)
   = ppHang (ppCat [ppStr "Call inst for", ppr PprDebug id])
         4 (ppAboves [ppCat (ppStr "types" : [pprMaybeTy PprDebug ty | ty <- spec_tys]),
                      case maybe_specinfo of
   = ppHang (ppCat [ppStr "Call inst for", ppr PprDebug id])
         4 (ppAboves [ppCat (ppStr "types" : [pprMaybeTy PprDebug ty | ty <- spec_tys]),
                      case maybe_specinfo of
-                       Nothing -> ppCat (ppStr "dicts" : [ppr PprDebug dict | dict <- dicts])
+                       Nothing -> ppCat (ppStr "dicts" : [ppr_arg PprDebug dict | dict <- dicts])
                        Just (SpecInfo _ _ spec_id)
                                -> ppCat [ppStr "Explicit SpecId", ppr PprDebug spec_id]
                     ])
 
                        Just (SpecInfo _ _ spec_id)
                                -> ppCat [ppStr "Explicit SpecId", ppr PprDebug spec_id]
                     ])
 
+-- ToDo: instance Outputable CoreArg?
+ppr_arg sty (TyArg  t) = ppr sty t
+ppr_arg sty (LitArg i) = ppr sty i
+ppr_arg sty (VarArg v) = ppr sty v
+
 isUnboxedCI :: CallInstance -> Bool
 isUnboxedCI (CallInstance _ spec_tys _ _ _)
 isUnboxedCI :: CallInstance -> Bool
 isUnboxedCI (CallInstance _ spec_tys _ _ _)
-  = any isUnboxedDataType (catMaybes spec_tys)
+  = any isUnboxedType (catMaybes spec_tys)
 
 isExplicitCI :: CallInstance -> Bool
 isExplicitCI (CallInstance _ _ _ _ (Just _))
 
 isExplicitCI :: CallInstance -> Bool
 isExplicitCI (CallInstance _ _ _ _ (Just _))
@@ -668,22 +732,22 @@ eqCI_tys c1 c2
 
 isCIofTheseIds :: [Id] -> CallInstance -> Bool
 isCIofTheseIds ids (CallInstance ci_id _ _ _ _)
 
 isCIofTheseIds :: [Id] -> CallInstance -> Bool
 isCIofTheseIds ids (CallInstance ci_id _ _ _ _)
-  = any (eqId ci_id) ids
+  = any ((==) ci_id) ids
 
 singleCI :: Id -> [Maybe Type] -> [CoreArg] -> UsageDetails
 singleCI id tys dicts
   = UsageDetails (unitBag (CallInstance id tys dicts fv_set Nothing))
 
 singleCI :: Id -> [Maybe Type] -> [CoreArg] -> UsageDetails
 singleCI id tys dicts
   = UsageDetails (unitBag (CallInstance id tys dicts fv_set Nothing))
-                emptyBag [] emptyUniqSet 0 0
+                emptyBag [] emptyIdSet 0 0
   where
   where
-    fv_set = mkUniqSet (id : [dict | ValArg (VarArg dict) <- dicts])
+    fv_set = mkIdSet (id : [dict | (VarArg dict) <- dicts])
 
 explicitCI :: Id -> [Maybe Type] -> SpecInfo -> UsageDetails
 explicitCI id tys specinfo
 
 explicitCI :: Id -> [Maybe Type] -> SpecInfo -> UsageDetails
 explicitCI id tys specinfo
-  = UsageDetails (unitBag call_inst) emptyBag [] emptyUniqSet 0 0
+  = UsageDetails (unitBag call_inst) emptyBag [] emptyIdSet 0 0
   where
     call_inst = CallInstance id tys dicts fv_set (Just specinfo)
     dicts  = panic "Specialise:explicitCI:dicts"
   where
     call_inst = CallInstance id tys dicts fv_set (Just specinfo)
     dicts  = panic "Specialise:explicitCI:dicts"
-    fv_set = singletonUniqSet id
+    fv_set = unitIdSet id
 
 -- We do not process the CIs for top-level dfuns or defms
 -- Instead we require an explicit SPEC inst pragma for dfuns
 
 -- We do not process the CIs for top-level dfuns or defms
 -- Instead we require an explicit SPEC inst pragma for dfuns
@@ -703,7 +767,9 @@ getCIs top_lev ids (UsageDetails cis tycon_cis dbs fvs c i)
        cis_here_list = bagToList cis_here
     in
     -- pprTrace "getCIs:"
        cis_here_list = bagToList cis_here
     in
     -- pprTrace "getCIs:"
-    -- (ppHang (ppBesides [ppStr "{", ppr PprDebug ids, ppStr "}"])
+    -- (ppHang (ppBesides [ppStr "{",
+    --                    interppSP PprDebug ids,
+    --                    ppStr "}"])
     --      4 (ppAboves (map pprCI cis_here_list)))
     (cis_here_list, UsageDetails cis_not_here tycon_cis dbs fvs c i)
 
     --      4 (ppAboves (map pprCI cis_here_list)))
     (cis_here_list, UsageDetails cis_not_here tycon_cis dbs fvs c i)
 
@@ -730,7 +796,9 @@ dumpCIs cis top_lev floating inst_cis bound_ids full_ids
     then
        pprTrace ("dumpCIs: dumping CI which was not instantiated ... \n" ++
                 "         (may be a non-HM recursive call)\n")
     then
        pprTrace ("dumpCIs: dumping CI which was not instantiated ... \n" ++
                 "         (may be a non-HM recursive call)\n")
-       (ppHang (ppBesides [ppStr "{", ppr PprDebug bound_ids, ppStr "}"])
+       (ppHang (ppBesides [ppStr "{",
+                          interppSP PprDebug bound_ids,
+                          ppStr "}"])
             4 (ppAboves [ppStr "Dumping CIs:",
                          ppAboves (map pprCI (bagToList cis_of_bound_id)),
                          ppStr "Instantiating CIs:",
             4 (ppAboves [ppStr "Dumping CIs:",
                          ppAboves (map pprCI (bagToList cis_of_bound_id)),
                          ppStr "Instantiating CIs:",
@@ -741,7 +809,9 @@ dumpCIs cis top_lev floating inst_cis bound_ids full_ids
    else
        (if not (isEmptyBag cis_dump_unboxed)
        then pprTrace "dumpCIs: bound dictionary arg ... WITH UNBOXED TYPES!\n"
    else
        (if not (isEmptyBag cis_dump_unboxed)
        then pprTrace "dumpCIs: bound dictionary arg ... WITH UNBOXED TYPES!\n"
-            (ppHang (ppBesides [ppStr "{", ppr PprDebug full_ids, ppStr "}"])
+            (ppHang (ppBesides [ppStr "{",
+                                interppSP PprDebug full_ids,
+                                ppStr "}"])
                   4 (ppAboves (map pprCI (bagToList cis_dump))))
        else id)
        cis_keep_not_bound_id
                   4 (ppAboves (map pprCI (bagToList cis_dump))))
        else id)
        cis_keep_not_bound_id
@@ -754,7 +824,7 @@ dumpCIs cis top_lev floating inst_cis bound_ids full_ids
       = partitionBag ok_to_dump_ci cis_not_bound_id
 
    ok_to_dump_ci (CallInstance _ _ _ fv_set _)
       = partitionBag ok_to_dump_ci cis_not_bound_id
 
    ok_to_dump_ci (CallInstance _ _ _ fv_set _)
-       = or [i `elementOfUniqSet` fv_set | i <- full_ids]
+       = any (\ i -> i `elementOfIdSet` fv_set) full_ids
 
    (_, cis_of_bound_id_without_inst_cis) = partitionBag have_inst_ci cis_of_bound_id
    have_inst_ci ci = any (eqCI_tys ci) inst_cis
 
    (_, cis_of_bound_id_without_inst_cis) = partitionBag have_inst_ci cis_of_bound_id
    have_inst_ci ci = any (eqCI_tys ci) inst_cis
@@ -803,10 +873,10 @@ cmpTyConI_tys (TyConInstance _ tys1) (TyConInstance _ tys2)
 
 singleTyConI :: TyCon -> [Maybe Type] -> UsageDetails
 singleTyConI ty_con spec_tys
 
 singleTyConI :: TyCon -> [Maybe Type] -> UsageDetails
 singleTyConI ty_con spec_tys
-  = UsageDetails emptyBag (unitBag (TyConInstance ty_con spec_tys)) [] emptyUniqSet 0 0
+  = UsageDetails emptyBag (unitBag (TyConInstance ty_con spec_tys)) [] emptyIdSet 0 0
 
 isTyConIofThisTyCon :: TyCon -> TyConInstance -> Bool
 
 isTyConIofThisTyCon :: TyCon -> TyConInstance -> Bool
-isTyConIofThisTyCon ty_con (TyConInstance inst_ty_con _) = eqTyCon ty_con inst_ty_con
+isTyConIofThisTyCon ty_con (TyConInstance inst_ty_con _) = ty_con == inst_ty_con
 
 isLocalSpecTyConI :: Bool -> TyConInstance -> Bool
 isLocalSpecTyConI comp_prel (TyConInstance inst_ty_con _) = isLocalSpecTyCon comp_prel inst_ty_con
 
 isLocalSpecTyConI :: Bool -> TyConInstance -> Bool
 isLocalSpecTyConI comp_prel (TyConInstance inst_ty_con _) = isLocalSpecTyCon comp_prel inst_ty_con
@@ -869,22 +939,22 @@ tickSpecCall found (UsageDetails cis ty_cis dbs fvs c i)
 tickSpecInsts (UsageDetails cis ty_cis dbs fvs c i)
  = UsageDetails cis ty_cis dbs fvs c (i+1)
 
 tickSpecInsts (UsageDetails cis ty_cis dbs fvs c i)
  = UsageDetails cis ty_cis dbs fvs c (i+1)
 
-emptyUDs = UsageDetails emptyBag emptyBag [] emptyUniqSet 0 0
+emptyUDs = UsageDetails emptyBag emptyBag [] emptyIdSet 0 0
 
 unionUDs (UsageDetails cis1 tycon_cis1 dbs1 fvs1 c1 i1) (UsageDetails cis2 tycon_cis2 dbs2 fvs2 c2 i2)
  = UsageDetails (unionBags cis1 cis2) (unionBags tycon_cis1 tycon_cis2)
 
 unionUDs (UsageDetails cis1 tycon_cis1 dbs1 fvs1 c1 i1) (UsageDetails cis2 tycon_cis2 dbs2 fvs2 c2 i2)
  = UsageDetails (unionBags cis1 cis2) (unionBags tycon_cis1 tycon_cis2)
-               (dbs1 ++ dbs2) (fvs1 `unionUniqSets` fvs2) (c1+c2) (i1+i2)
+               (dbs1 ++ dbs2) (fvs1 `unionIdSets` fvs2) (c1+c2) (i1+i2)
        -- The append here is really redundant, since the bindings don't
        -- scope over each other.  ToDo.
 
 unionUDList = foldr unionUDs emptyUDs
 
 singleFvUDs (VarArg v) | not (isImportedId v)
        -- The append here is really redundant, since the bindings don't
        -- scope over each other.  ToDo.
 
 unionUDList = foldr unionUDs emptyUDs
 
 singleFvUDs (VarArg v) | not (isImportedId v)
- = UsageDetails emptyBag emptyBag [] (singletonUniqSet v) 0 0
+ = UsageDetails emptyBag emptyBag [] (unitIdSet v) 0 0
 singleFvUDs other
  = emptyUDs
 
 singleFvUDs other
  = emptyUDs
 
-singleConUDs con = UsageDetails emptyBag emptyBag [] (singletonUniqSet con) 0 0
+singleConUDs con = UsageDetails emptyBag emptyBag [] (unitIdSet con) 0 0
 
 dumpDBs :: [DictBindDetails]
        -> Bool                 -- True <=> top level bound Ids
 
 dumpDBs :: [DictBindDetails]
        -> Bool                 -- True <=> top level bound Ids
@@ -911,11 +981,11 @@ dumpDBs [] top_lev bound_tyvars bound_ids fvs
 dumpDBs ((db@(DictBindDetails dbinders dbind db_fvs db_ftv)):dbs)
        top_lev bound_tyvars bound_ids fvs
   | top_lev
 dumpDBs ((db@(DictBindDetails dbinders dbind db_fvs db_ftv)):dbs)
        top_lev bound_tyvars bound_ids fvs
   | top_lev
-    || or [i `elementOfUniqSet` db_fvs  | i <- bound_ids]
-    || or [tv `elementOfUniqSet` db_ftv | tv <- bound_tyvars]
+    || any (\ i -> i `elementOfIdSet`    db_fvs) bound_ids
+    || any (\ t -> t `elementOfTyVarSet` db_ftv) bound_tyvars
   = let                -- Ha!  Dump it!
        (dbinds_here, dbs_outer, full_bound_ids, full_fvs)
   = let                -- Ha!  Dump it!
        (dbinds_here, dbs_outer, full_bound_ids, full_fvs)
-          = dumpDBs dbs top_lev bound_tyvars (dbinders ++ bound_ids) (db_fvs `unionUniqSets` fvs)
+          = dumpDBs dbs top_lev bound_tyvars (dbinders ++ bound_ids) (db_fvs `unionIdSets` fvs)
     in
     (dbind : dbinds_here, dbs_outer, full_bound_ids, full_fvs)
 
     in
     (dbind : dbinds_here, dbs_outer, full_bound_ids, full_fvs)
 
@@ -943,7 +1013,7 @@ dumpUDs (UsageDetails cis tycon_cis dbs fvs c i) top_lev floating inst_cis bound
        (dict_binds_here, dbs_outer, full_bound_ids, full_fvs)
                  = dumpDBs dbs top_lev tvs bound_ids fvs
        cis_outer = dumpCIs cis top_lev floating inst_cis bound_ids full_bound_ids
        (dict_binds_here, dbs_outer, full_bound_ids, full_fvs)
                  = dumpDBs dbs top_lev tvs bound_ids fvs
        cis_outer = dumpCIs cis top_lev floating inst_cis bound_ids full_bound_ids
-       fvs_outer = full_fvs `minusUniqSet` (mkUniqSet full_bound_ids)
+       fvs_outer = full_fvs `minusIdSet` (mkIdSet full_bound_ids)
     in
     (dict_binds_here, UsageDetails cis_outer tycon_cis dbs_outer fvs_outer c i)
 \end{code}
     in
     (dict_binds_here, UsageDetails cis_outer tycon_cis dbs_outer fvs_outer c i)
 \end{code}
@@ -1057,23 +1127,22 @@ ToDo[sansom]: Transformation data to process specialisation requests.
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-specProgram :: (GlobalSwitch -> Bool)
-           -> UniqSupply
+specProgram :: UniqSupply
            -> [CoreBinding]    -- input ...
            -> SpecialiseData
            -> ([CoreBinding],  -- main result
                SpecialiseData)         -- result specialise data
 
            -> [CoreBinding]    -- input ...
            -> SpecialiseData
            -> ([CoreBinding],  -- main result
                SpecialiseData)         -- result specialise data
 
-specProgram sw_chker uniqs binds
+specProgram uniqs binds
           (SpecData False _ local_tycons _ init_specs init_errs init_warn init_tyerrs)
           (SpecData False _ local_tycons _ init_specs init_errs init_warn init_tyerrs)
-  = case (initSM (specTyConsAndScope (specTopBinds binds)) sw_chker uniqs) of
+  = case (initSM (specTyConsAndScope (specTopBinds binds)) uniqs) of
       (final_binds, tycon_specs_list,
        UsageDetails import_cis import_tycis _ fvs spec_calls spec_insts)
         -> let
                used_conids   = filter isDataCon (uniqSetToList fvs)
       (final_binds, tycon_specs_list,
        UsageDetails import_cis import_tycis _ fvs spec_calls spec_insts)
         -> let
                used_conids   = filter isDataCon (uniqSetToList fvs)
-               used_tycons   = map getDataConTyCon used_conids
+               used_tycons   = map dataConTyCon used_conids
                used_gen      = filter isLocalGenTyCon used_tycons
                used_gen      = filter isLocalGenTyCon used_tycons
-               gen_tycons    = setToList (mkSet local_tycons `union` mkSet used_gen)
+               gen_tycons    = uniqSetToList (mkUniqSet local_tycons `unionUniqSets` mkUniqSet used_gen)
 
                result_specs  = addListToFM_C (++) init_specs tycon_specs_list
 
 
                result_specs  = addListToFM_C (++) init_specs tycon_specs_list
 
@@ -1088,9 +1157,9 @@ specProgram sw_chker uniqs binds
                tycis_errs    = init_tyerrs `unionBags` listToBag tycis_unboxed
 
                no_errs       = isEmptyBag cis_errs && isEmptyBag tycis_errs
                tycis_errs    = init_tyerrs `unionBags` listToBag tycis_unboxed
 
                no_errs       = isEmptyBag cis_errs && isEmptyBag tycis_errs
-                                 && (not (sw_chker SpecialiseImports) || isEmptyBag cis_warn)
+                                 && (not opt_SpecialiseImports || isEmptyBag cis_warn)
            in
            in
-           (if sw_chker D_simplifier_stats then
+           (if opt_D_simplifier_stats then
                pprTrace "\nSpecialiser Stats:\n" (ppAboves [
                                        ppBesides [ppStr "SpecCalls  ", ppInt spec_calls],
                                        ppBesides [ppStr "SpecInsts  ", ppInt spec_insts],
                pprTrace "\nSpecialiser Stats:\n" (ppAboves [
                                        ppBesides [ppStr "SpecCalls  ", ppInt spec_calls],
                                        ppBesides [ppStr "SpecInsts  ", ppInt spec_insts],
@@ -1101,7 +1170,7 @@ specProgram sw_chker uniqs binds
             SpecData True no_errs local_tycons gen_tycons result_specs
                                   cis_errs cis_warn tycis_errs)
 
             SpecData True no_errs local_tycons gen_tycons result_specs
                                   cis_errs cis_warn tycis_errs)
 
-specProgram sw_chker uniqs binds (SpecData True _ _ _ _ _ _ _)
+specProgram uniqs binds (SpecData True _ _ _ _ _ _ _)
   = panic "Specialise:specProgram: specialiser called more than once"
 
 -- It may be possible safely to call the specialiser more than once,
   = panic "Specialise:specProgram: specialiser called more than once"
 
 -- It may be possible safely to call the specialiser more than once,
@@ -1128,14 +1197,13 @@ specTyConsAndScope :: SpecM ([CoreBinding], UsageDetails)
 
 specTyConsAndScope scopeM
   = scopeM                     `thenSM` \ (binds, scope_uds) ->
 
 specTyConsAndScope scopeM
   = scopeM                     `thenSM` \ (binds, scope_uds) ->
-    getSwitchCheckerSM         `thenSM` \ sw_chkr ->
     let
        (tycons_cis, gotci_scope_uds)
     let
        (tycons_cis, gotci_scope_uds)
-        = getLocalSpecTyConIs (sw_chkr CompilingPrelude) scope_uds
+        = getLocalSpecTyConIs opt_CompilingPrelude scope_uds
 
        tycon_specs_list = collectTyConSpecs tycons_cis
     in
 
        tycon_specs_list = collectTyConSpecs tycons_cis
     in
-    (if sw_chkr SpecialiseTrace && not (null tycon_specs_list) then
+    (if opt_SpecialiseTrace && not (null tycon_specs_list) then
         pprTrace "Specialising TyCons:\n"
         (ppAboves [ if not (null specs) then
                         ppHang (ppCat [(ppr PprDebug tycon), ppStr "at types"])
         pprTrace "Specialising TyCons:\n"
         (ppAboves [ if not (null specs) then
                         ppHang (ppCat [(ppr PprDebug tycon), ppStr "at types"])
@@ -1180,8 +1248,8 @@ specTopBinds binds
        (dbinders_s, dbinds, dfvs_s)
           = unzip3 [(dbinders, dbind, dfvs) | DictBindDetails dbinders dbind dfvs _ <- dbind_details]
 
        (dbinders_s, dbinds, dfvs_s)
           = unzip3 [(dbinders, dbind, dfvs) | DictBindDetails dbinders dbind dfvs _ <- dbind_details]
 
-       full_fvs  = fvs `unionUniqSets` unionManyUniqSets dfvs_s
-       fvs_outer = full_fvs `minusUniqSet` (mkUniqSet (concat dbinders_s))
+       full_fvs  = fvs `unionIdSets` unionManyIdSets dfvs_s
+       fvs_outer = full_fvs `minusIdSet` (mkIdSet (concat dbinders_s))
 
        -- It is just to complex to try to sort out top-level dependencies
        -- So we just place all the top-level binds in a *global* Rec and
 
        -- It is just to complex to try to sort out top-level dependencies
        -- So we just place all the top-level binds in a *global* Rec and
@@ -1211,11 +1279,11 @@ specTopBinds binds
 \begin{code}
 specExpr :: CoreExpr
         -> [CoreArg]           -- The arguments:
 \begin{code}
 specExpr :: CoreExpr
         -> [CoreArg]           -- The arguments:
-                                       --    TypeArgs are speced
-                                       --    ValArgs are unprocessed
+                               --    TypeArgs are speced
+                               --    ValArgs are unprocessed
         -> SpecM (CoreExpr,    -- Result expression with specialised versions installed
         -> SpecM (CoreExpr,    -- Result expression with specialised versions installed
-                  UsageDetails)        -- Details of usage of enclosing binders in the result
-                                       -- expression.
+                  UsageDetails)-- Details of usage of enclosing binders in the result
+                               -- expression.
 
 specExpr (Var v) args
   = lookupId v                 `thenSM` \ vlookup ->
 
 specExpr (Var v) args
   = lookupId v                 `thenSM` \ vlookup ->
@@ -1228,7 +1296,7 @@ specExpr (Var v) args
                returnSM (bindUnlift vl vu (Var vu), singleFvUDs (VarArg vl))
 
        NoLift vatom@(VarArg new_v)
                returnSM (bindUnlift vl vu (Var vu), singleFvUDs (VarArg vl))
 
        NoLift vatom@(VarArg new_v)
-            -> mapSM specArg args                      `thenSM` \ arg_info ->
+            -> mapSM specOutArg args                   `thenSM` \ arg_info ->
                mkCallInstance v new_v arg_info         `thenSM` \ call_uds ->
                mkCall new_v arg_info                   `thenSM` \ ~(speced, call) ->
                let
                mkCallInstance v new_v arg_info         `thenSM` \ call_uds ->
                mkCall new_v arg_info                   `thenSM` \ ~(speced, call) ->
                let
@@ -1243,29 +1311,38 @@ specExpr expr@(Lit _) null_args
   = ASSERT (null null_args)
     returnSM (expr, emptyUDs)
 
   = ASSERT (null null_args)
     returnSM (expr, emptyUDs)
 
-specExpr (Con con tys args) null_args
+specExpr (Con con args) null_args
   = ASSERT (null null_args)
   = ASSERT (null null_args)
-    mapSM specTy tys                   `thenSM` \ tys ->
-    mapAndUnzip3SM specAtom args       `thenSM` \ (args, args_uds_s, unlifts) ->
-    mkTyConInstance con tys            `thenSM` \ con_uds ->
-    returnSM (applyBindUnlifts unlifts (Con con tys args),
+    let
+       (targs, vargs) = partition_args args
+    in
+    mapAndUnzipSM  specTyArg  targs `thenSM` \ (targs, tys) ->
+    mapAndUnzip3SM specValArg vargs `thenSM` \ (vargs, args_uds_s, unlifts) ->
+    mkTyConInstance con tys        `thenSM` \ con_uds ->
+    returnSM (applyBindUnlifts unlifts (Con con (targs ++ vargs)),
              unionUDList args_uds_s `unionUDs` con_uds)
 
              unionUDList args_uds_s `unionUDs` con_uds)
 
-specExpr (Prim op@(CCallOp str is_asm may_gc arg_tys res_ty) tys args) null_args
+specExpr (Prim op@(CCallOp str is_asm may_gc arg_tys res_ty) args) null_args
   = ASSERT (null null_args)
   = ASSERT (null null_args)
-    ASSERT (null tys)
-    mapSM specTy arg_tys               `thenSM` \ arg_tys ->
-    specTy res_ty                      `thenSM` \ res_ty ->
-    mapAndUnzip3SM specAtom args       `thenSM` \ (args, args_uds_s, unlifts) ->
-    returnSM (applyBindUnlifts unlifts (Prim (CCallOp str is_asm may_gc arg_tys res_ty) tys args),
+    let
+       (targs, vargs) = partition_args args
+    in
+    ASSERT (null targs)
+    mapSM specTy arg_tys           `thenSM` \ arg_tys ->
+    specTy res_ty                  `thenSM` \ res_ty ->
+    mapAndUnzip3SM specValArg vargs `thenSM` \ (vargs, args_uds_s, unlifts) ->
+    returnSM (applyBindUnlifts unlifts (Prim (CCallOp str is_asm may_gc arg_tys res_ty) vargs),
              unionUDList args_uds_s)
 
              unionUDList args_uds_s)
 
-specExpr (Prim prim tys args) null_args
+specExpr (Prim prim args) null_args
   = ASSERT (null null_args)
   = ASSERT (null null_args)
-    mapSM specTy tys                   `thenSM` \ tys ->
-    mapAndUnzip3SM specAtom args       `thenSM` \ (args, args_uds_s, unlifts) ->
+    let
+       (targs, vargs) = partition_args args
+    in
+    mapAndUnzipSM  specTyArg  targs `thenSM` \ (targs, tys) ->
+    mapAndUnzip3SM specValArg vargs `thenSM` \ (vargs, args_uds_s, unlifts) ->
     -- specPrimOp prim tys             `thenSM` \ (prim, tys, prim_uds) ->
     -- specPrimOp prim tys             `thenSM` \ (prim, tys, prim_uds) ->
-    returnSM (applyBindUnlifts unlifts (Prim prim tys args),
+    returnSM (applyBindUnlifts unlifts (Prim prim (targs ++ vargs)),
              unionUDList args_uds_s {-`unionUDs` prim_uds-} )
 
 {- ToDo: specPrimOp
              unionUDList args_uds_s {-`unionUDs` prim_uds-} )
 
 {- ToDo: specPrimOp
@@ -1286,33 +1363,27 @@ specPrimOp :: PrimOp
 
 
 specExpr (App fun arg) args
 
 
 specExpr (App fun arg) args
-  =    -- Arg is passed on unprocessed
-    specExpr fun (ValArg arg : args)   `thenSM` \ (expr,uds) ->
+  =    -- If TyArg, arg will be processed; otherwise, left alone
+    preSpecArg arg                     `thenSM` \ new_arg    ->
+    specExpr   fun (new_arg : args)    `thenSM` \ (expr,uds) ->
     returnSM (expr, uds)
 
     returnSM (expr, uds)
 
-specExpr (CoTyApp fun ty) args
-  =    -- Spec the tyarg and pass it on
-    specTy ty                          `thenSM` \ ty ->
-    specExpr fun (TypeArg ty : args)
-
-specExpr (Lam binder body) (ValArg arg : args)
+specExpr (Lam (ValBinder binder) body) (arg : args) | isValArg arg
   = lookup_arg arg `thenSM` \ arg ->
     bindId binder arg (specExpr body args)
   where
     lookup_arg (LitArg l) = returnSM (NoLift (LitArg l))
     lookup_arg (VarArg v) = lookupId v
 
   = lookup_arg arg `thenSM` \ arg ->
     bindId binder arg (specExpr body args)
   where
     lookup_arg (LitArg l) = returnSM (NoLift (LitArg l))
     lookup_arg (VarArg v) = lookupId v
 
-specExpr (Lam binder body) []
+specExpr (Lam (ValBinder binder) body) []
   = specLambdaOrCaseBody [binder] body [] `thenSM` \ ([binder], body, uds) ->
   = specLambdaOrCaseBody [binder] body [] `thenSM` \ ([binder], body, uds) ->
-    returnSM (Lam binder body, uds)
+    returnSM (Lam (ValBinder binder) body, uds)
 
 
-specExpr (CoTyLam tyvar body) (TypeArg ty : args)
+specExpr (Lam (TyBinder tyvar) body) (TyArg ty : args)
   =    -- Type lambda with argument; argument already spec'd
   =    -- Type lambda with argument; argument already spec'd
-    bindTyVar tyvar ty (
-       specExpr body args
-    )
+    bindTyVar tyvar ty ( specExpr body args )
 
 
-specExpr (CoTyLam tyvar body) []
+specExpr (Lam (TyBinder tyvar) body) []
   =    -- No arguments
     cloneTyVarSM tyvar                 `thenSM` \ new_tyvar ->
     bindTyVar tyvar (mkTyVarTy new_tyvar) (
   =    -- No arguments
     cloneTyVarSM tyvar                 `thenSM` \ new_tyvar ->
     bindTyVar tyvar (mkTyVarTy new_tyvar) (
@@ -1320,7 +1391,9 @@ specExpr (CoTyLam tyvar body) []
        let
            (binds_here, final_uds) = dumpUDs body_uds False False [] [] [new_tyvar]
        in
        let
            (binds_here, final_uds) = dumpUDs body_uds False False [] [] [new_tyvar]
        in
-       returnSM (CoTyLam new_tyvar (mkCoLetsNoUnboxed binds_here body), final_uds)
+       returnSM (Lam (TyBinder new_tyvar)
+                     (mkCoLetsNoUnboxed binds_here body),
+                 final_uds)
     )
 
 specExpr (Case scrutinee alts) args
     )
 
 specExpr (Case scrutinee alts) args
@@ -1330,7 +1403,6 @@ specExpr (Case scrutinee alts) args
   where
     scrutinee_type = coreExprType scrutinee
 
   where
     scrutinee_type = coreExprType scrutinee
 
-
 specExpr (Let bind body) args
   = specBindAndScope False bind (
        specExpr body args      `thenSM` \ (body, body_uds) ->
 specExpr (Let bind body) args
   = specBindAndScope False bind (
        specExpr body args      `thenSM` \ (body, body_uds) ->
@@ -1339,8 +1411,8 @@ specExpr (Let bind body) args
     returnSM (mkCoLetsUnboxedToCase binds body, all_uds)
 
 specExpr (SCC cc expr) args
     returnSM (mkCoLetsUnboxedToCase binds body, all_uds)
 
 specExpr (SCC cc expr) args
-  = specExpr expr []           `thenSM` \ (expr, expr_uds) ->
-    mapAndUnzip3SM specArg args        `thenSM` \ (args, args_uds_s, unlifts) ->
+  = specExpr expr []               `thenSM` \ (expr, expr_uds) ->
+    mapAndUnzip3SM specOutArg args  `thenSM` \ (args, args_uds_s, unlifts) ->
     let
        scc_expr
          = if squashableDictishCcExpr cc expr -- can toss the _scc_
     let
        scc_expr
          = if squashableDictishCcExpr cc expr -- can toss the _scc_
@@ -1420,7 +1492,6 @@ Now we must specialise op1 at {* Int#} which requires a version of
 meth1 at {Int#}. But since meth1 was extracted from a dictionary we do
 not have access to its code to create the specialised version.
 
 meth1 at {Int#}. But since meth1 was extracted from a dictionary we do
 not have access to its code to create the specialised version.
 
-
 If we specialise on overloaded types as well we specialise op1 at
 {Int Int#} d.Foo.Int:
 
 If we specialise on overloaded types as well we specialise op1 at
 {Int Int#} d.Foo.Int:
 
@@ -1455,9 +1526,10 @@ specAlts (AlgAlts alts deflt) scrutinee_ty args
     specDeflt deflt args                       `thenSM` \ (deflt, deflt_uds) ->
     returnSM (AlgAlts alts deflt,
              unionUDList alts_uds_s `unionUDs` deflt_uds)
     specDeflt deflt args                       `thenSM` \ (deflt, deflt_uds) ->
     returnSM (AlgAlts alts deflt,
              unionUDList alts_uds_s `unionUDs` deflt_uds)
-
   where
   where
-    -- We use ty_args of scrutinee type to identify specialisation of alternatives
+    -- We use ty_args of scrutinee type to identify specialisation of
+    -- alternatives:
+
     (_, ty_args, _) = getAppDataTyCon scrutinee_ty
 
     specAlgAlt ty_args (con,binders,rhs)
     (_, ty_args, _) = getAppDataTyCon scrutinee_ty
 
     specAlgAlt ty_args (con,binders,rhs)
@@ -1489,13 +1561,30 @@ specDeflt (BindDefault binder rhs) args
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-specAtom :: CoreArg -> SpecM (CoreArg, UsageDetails,
-                                   CoreExpr -> CoreExpr)
+partition_args :: [CoreArg] -> ([CoreArg], [CoreArg])
+partition_args args
+  = span is_ty_arg args
+  where
+    is_ty_arg (TyArg _) = True
+    is_ty_arg _                = False
+
+----------
+preSpecArg :: CoreArg -> SpecM CoreArg -- diddle TyArgs, but nothing else
 
 
-specAtom (LitArg lit)
+preSpecArg (TyArg ty)
+  = specTy ty  `thenSM` \ new_ty ->
+    returnSM (TyArg new_ty)
+
+preSpecArg other = returnSM other
+
+--------------------
+specValArg :: CoreArg -> SpecM (CoreArg, UsageDetails,
+                               CoreExpr -> CoreExpr)
+
+specValArg (LitArg lit)
   = returnSM (LitArg lit, emptyUDs, id)
 
   = returnSM (LitArg lit, emptyUDs, id)
 
-specAtom (VarArg v)
+specValArg (VarArg v)
   = lookupId v         `thenSM` \ vlookup ->
     case vlookup of
       Lifted vl vu
   = lookupId v         `thenSM` \ vlookup ->
     case vlookup of
       Lifted vl vu
@@ -1505,15 +1594,20 @@ specAtom (VarArg v)
         -> returnSM (vatom, singleFvUDs vatom, id)
 
 
         -> returnSM (vatom, singleFvUDs vatom, id)
 
 
-specArg :: CoreArg -> SpecM (CoreArg, UsageDetails,
+------------------
+specTyArg (TyArg ty)
+  = specTy ty  `thenSM` \ new_ty ->
+    returnSM (TyArg new_ty, new_ty)
+
+--------------
+specOutArg :: CoreArg -> SpecM (CoreArg, UsageDetails,
                                  CoreExpr -> CoreExpr)
 
                                  CoreExpr -> CoreExpr)
 
-specArg (ValArg arg)   -- unprocessed; spec the atom
-  = specAtom arg       `thenSM` \ (arg, uds, unlift) ->
-    returnSM (ValArg arg, uds, unlift)
+specOutArg (TyArg ty)  -- already speced; no action
+  = returnSM (TyArg ty, emptyUDs, id)
 
 
-specArg (TypeArg ty)   -- already speced; no action
-  = returnSM (TypeArg ty, emptyUDs, id)
+specOutArg other_arg   -- unprocessed; spec the atom
+  = specValArg other_arg
 \end{code}
 
 
 \end{code}
 
 
@@ -1744,14 +1838,16 @@ instBind top_lev new_ids@(first_binder:other_binders) bind equiv_ciss inst_cis
     else if top_lev
     then pprTrace "dumpCIs: not same overloading ... top level \n"
     else (\ x y -> y)
     else if top_lev
     then pprTrace "dumpCIs: not same overloading ... top level \n"
     else (\ x y -> y)
-   ) (ppHang (ppBesides [ppStr "{", ppr PprDebug new_ids, ppStr "}"])
-          4 (ppAboves [ppAboves (map (pprType PprDebug . idType) new_ids),
+   ) (ppHang (ppBesides [ppStr "{",
+                        interppSP PprDebug new_ids,
+                        ppStr "}"])
+          4 (ppAboves [ppAboves (map (pprGenType PprDebug . idType) new_ids),
                        ppAboves (map pprCI (concat equiv_ciss))]))
    (returnSM ([], emptyUDs, []))
 
  where
     (tyvar_tmpls, class_tyvar_pairs) = getIdOverloading first_binder
                        ppAboves (map pprCI (concat equiv_ciss))]))
    (returnSM ([], emptyUDs, []))
 
  where
     (tyvar_tmpls, class_tyvar_pairs) = getIdOverloading first_binder
-    tyvar_tmpl_tys = map mkTyVarTemplateTy tyvar_tmpls
+    tyvar_tmpl_tys = mkTyVarTys tyvar_tmpls
 
     no_of_tyvars = length tyvar_tmpls
     no_of_dicts  = length class_tyvar_pairs
 
     no_of_tyvars = length tyvar_tmpls
     no_of_dicts  = length class_tyvar_pairs
@@ -1841,8 +1937,7 @@ mkOneInst :: CallInstance
 
 mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
          no_of_dicts_to_specialise top_lev inst_cis new_ids orig_bind
 
 mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
          no_of_dicts_to_specialise top_lev inst_cis new_ids orig_bind
-  = getSwitchCheckerSM                                 `thenSM` \ sw_chkr ->
-    newSpecIds new_ids spec_tys no_of_dicts_to_specialise
+  = newSpecIds new_ids spec_tys no_of_dicts_to_specialise
                                                        `thenSM` \ spec_ids ->
     newTyVars (length [() | Nothing <- spec_tys])      `thenSM` \ poly_tyvars ->
     let
                                                        `thenSM` \ spec_ids ->
     newTyVars (length [() | Nothing <- spec_tys])      `thenSM` \ poly_tyvars ->
     let
@@ -1852,7 +1947,7 @@ mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
        (_,arg_tys) = mapAccumL do_the_wotsit poly_tyvars spec_tys
 
        args :: [CoreArg]
        (_,arg_tys) = mapAccumL do_the_wotsit poly_tyvars spec_tys
 
        args :: [CoreArg]
-       args = map TypeArg arg_tys ++ dict_args
+       args = map TyArg arg_tys ++ dict_args
 
        (new_id:_) = new_ids
        (spec_id:_) = spec_ids
 
        (new_id:_) = new_ids
        (spec_id:_) = spec_ids
@@ -1877,7 +1972,7 @@ mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
                -- a specialised instance has been created but specialisation
                -- "required" by one of the other Ids in the Rec
          | top_lev && maybeToBool lookup_orig_spec
                -- a specialised instance has been created but specialisation
                -- "required" by one of the other Ids in the Rec
          | top_lev && maybeToBool lookup_orig_spec
-         = (if sw_chkr SpecialiseTrace
+         = (if opt_SpecialiseTrace
             then trace_nospec "  Exists: " exists_id
             else id) (
 
             then trace_nospec "  Exists: " exists_id
             else id) (
 
@@ -1887,7 +1982,7 @@ mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
                -- Check for a (single) explicit call instance for this id
          | not (null explicit_cis_for_this_id)
          = ASSERT (length explicit_cis_for_this_id == 1)
                -- Check for a (single) explicit call instance for this id
          | not (null explicit_cis_for_this_id)
          = ASSERT (length explicit_cis_for_this_id == 1)
-           (if sw_chkr SpecialiseTrace
+           (if opt_SpecialiseTrace
             then trace_nospec "  Explicit: " explicit_id
             else id) (
 
             then trace_nospec "  Explicit: " explicit_id
             else id) (
 
@@ -1912,7 +2007,7 @@ mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
 
                spec_info = Just (SpecInfo spec_tys no_of_dicts_to_specialise spec_id)
            in
 
                spec_info = Just (SpecInfo spec_tys no_of_dicts_to_specialise spec_id)
            in
-           if isUnboxedDataType (idType spec_id) then
+           if isUnboxedType (idType spec_id) then
                ASSERT (null poly_tyvars)
                liftId spec_id          `thenSM` \ (lift_spec_id, unlift_spec_id) ->
                mkTyConInstance liftDataCon [idType unlift_spec_id]
                ASSERT (null poly_tyvars)
                liftId spec_id          `thenSM` \ (lift_spec_id, unlift_spec_id) ->
                mkTyConInstance liftDataCon [idType unlift_spec_id]
@@ -1922,7 +2017,7 @@ mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
                          tickSpecInsts (final_uds `unionUDs` lift_uds), spec_info)
            else
                returnSM (Just (spec_id,
                          tickSpecInsts (final_uds `unionUDs` lift_uds), spec_info)
            else
                returnSM (Just (spec_id,
-                               mkCoLetsNoUnboxed local_dict_binds (mkCoTyLam poly_tyvars inst_rhs)),
+                               mkCoLetsNoUnboxed local_dict_binds (mkTyLam poly_tyvars inst_rhs)),
                          tickSpecInsts final_uds, spec_info)
          where
            lookup_orig_spec = lookupSpecEnv (getIdSpecialisation orig_id) arg_tys
                          tickSpecInsts final_uds, spec_info)
          where
            lookup_orig_spec = lookupSpecEnv (getIdSpecialisation orig_id) arg_tys
@@ -1932,14 +2027,17 @@ mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
            [CallInstance _ _ _ _ (Just explicit_spec_info)] = explicit_cis_for_this_id
            SpecInfo _ _ explicit_id = explicit_spec_info
 
            [CallInstance _ _ _ _ (Just explicit_spec_info)] = explicit_cis_for_this_id
            SpecInfo _ _ explicit_id = explicit_spec_info
 
+           trace_nospec :: String -> Id -> a -> a
            trace_nospec str spec_id
              = pprTrace str
                (ppCat [ppr PprDebug new_id, ppInterleave ppNil (map pp_ty arg_tys),
                        ppStr "==>", ppr PprDebug spec_id])
     in
            trace_nospec str spec_id
              = pprTrace str
                (ppCat [ppr PprDebug new_id, ppInterleave ppNil (map pp_ty arg_tys),
                        ppStr "==>", ppr PprDebug spec_id])
     in
-    (if sw_chkr SpecialiseTrace then
+    (if opt_SpecialiseTrace then
        pprTrace "Specialising:"
        pprTrace "Specialising:"
-       (ppHang (ppBesides [ppStr "{", ppr PprDebug new_ids, ppStr "}"])
+       (ppHang (ppBesides [ppStr "{",
+                           interppSP PprDebug new_ids,
+                           ppStr "}"])
              4 (ppAboves [
                 ppBesides [ppStr "types: ", ppInterleave ppNil (map pp_ty arg_tys)],
                 if isExplicitCI do_cis then ppNil else
              4 (ppAboves [
                 ppBesides [ppStr "types: ", ppInterleave ppNil (map pp_ty arg_tys)],
                 if isExplicitCI do_cis then ppNil else
@@ -1952,8 +2050,8 @@ mkOneInst do_cis@(CallInstance _ spec_tys dict_args _ _) explicit_cis
     returnSM (maybe_inst_bind, inst_uds, spec_infos)
     )
   where
     returnSM (maybe_inst_bind, inst_uds, spec_infos)
     )
   where
-    pp_dict (ValArg d) = ppr PprDebug d
-    pp_ty t = pprParendType PprDebug t
+    pp_dict d = ppr_arg PprDebug d
+    pp_ty t   = pprParendGenType PprDebug t
 
     do_the_wotsit (tyvar:tyvars) Nothing   = (tyvars, mkTyVarTy tyvar)
     do_the_wotsit tyvars         (Just ty) = (tyvars, ty)
 
     do_the_wotsit (tyvar:tyvars) Nothing   = (tyvars, mkTyVarTy tyvar)
     do_the_wotsit tyvars         (Just ty) = (tyvars, ty)
@@ -1994,11 +2092,10 @@ mkCallInstance id new_id args
        -- instances for a ConstMethodId extracted from its SpecEnv
 
   | otherwise
        -- instances for a ConstMethodId extracted from its SpecEnv
 
   | otherwise
-  = getSwitchCheckerSM         `thenSM` \ sw_chkr ->
-    let
-       spec_overloading = sw_chkr SpecialiseOverloaded
-       spec_unboxed     = sw_chkr SpecialiseUnboxed
-       spec_all         = sw_chkr SpecialiseAll
+  = let
+       spec_overloading = opt_SpecialiseOverloaded
+       spec_unboxed     = opt_SpecialiseUnboxed
+       spec_all         = opt_SpecialiseAll
 
        (tyvars, class_tyvar_pairs) = getIdOverloading id
 
 
        (tyvars, class_tyvar_pairs) = getIdOverloading id
 
@@ -2019,7 +2116,7 @@ mkCallInstance id new_id args
     in
     if (not enough_args) then
        pprPanic "Specialise:recordCallInst: Unsaturated Type & Dict Application:\n\t"
     in
     if (not enough_args) then
        pprPanic "Specialise:recordCallInst: Unsaturated Type & Dict Application:\n\t"
-                (ppCat [ppr PprDebug id, ppr PprDebug [arg | (arg,_,_) <- args] ])
+                (ppCat (ppr PprDebug id : map (ppr_arg PprDebug) [arg | (arg,_,_) <- args]))
     else
     case record_spec id tys of
        (False, _, _)
     else
     case record_spec id tys of
        (False, _, _)
@@ -2075,25 +2172,26 @@ mkCallInstance id new_id args
                    (returnSM emptyUDs)
 
 
                    (returnSM emptyUDs)
 
 
-take_type_args (_:tyvars) class_tyvar_pairs ((TypeArg ty,_,_):args)
-       = case take_type_args tyvars class_tyvar_pairs args of
-               Nothing                   -> Nothing
-               Just (tys, dicts, others) -> Just (ty:tys, dicts, others)
-take_type_args (_:tyvars) class_tyvar_pairs []
-       = Nothing
+take_type_args (_:tyvars) class_tyvar_pairs ((TyArg ty,_,_):args)
+       = case (take_type_args tyvars class_tyvar_pairs args) of
+           Nothing               -> Nothing
+           Just (tys, dicts, others) -> Just (ty:tys, dicts, others)
+
+take_type_args (_:tyvars) class_tyvar_pairs [] = Nothing
+
 take_type_args [] class_tyvar_pairs args
 take_type_args [] class_tyvar_pairs args
-       = case take_dict_args class_tyvar_pairs args of
-               Nothing              -> Nothing
-               Just (dicts, others) -> Just ([], dicts, others)
-
-take_dict_args (_:class_tyvar_pairs) ((dict@(ValArg _),_,_):args)
-       = case take_dict_args class_tyvar_pairs args of
-               Nothing              -> Nothing
-               Just (dicts, others) -> Just (dict:dicts, others)
-take_dict_args (_:class_tyvar_pairs) []
-       = Nothing
-take_dict_args [] args
-       = Just ([], args)
+       = case (take_dict_args class_tyvar_pairs args) of
+           Nothing              -> Nothing
+           Just (dicts, others) -> Just ([], dicts, others)
+
+take_dict_args (_:class_tyvar_pairs) ((dict,_,_):args) | isValArg dict
+       = case (take_dict_args class_tyvar_pairs args) of
+           Nothing              -> Nothing
+           Just (dicts, others) -> Just (dict:dicts, others)
+
+take_dict_args (_:class_tyvar_pairs) [] = Nothing
+
+take_dict_args [] args = Just ([], args)
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -2103,7 +2201,7 @@ mkCall :: Id
 
 mkCall new_id args
   | maybeToBool (isSuperDictSelId_maybe new_id)
 
 mkCall new_id args
   | maybeToBool (isSuperDictSelId_maybe new_id)
-    && any isUnboxedDataType ty_args
+    && any isUnboxedType ty_args
        -- No specialisations for super-dict selectors
        -- Specialise unboxed calls to SuperDictSelIds by extracting
        -- the super class dictionary directly form the super class
        -- No specialisations for super-dict selectors
        -- Specialise unboxed calls to SuperDictSelIds by extracting
        -- the super class dictionary directly form the super class
@@ -2149,7 +2247,7 @@ mkCall new_id args
                        -- These top level defns should have been lifted.
                        -- We must add code to unlift such a spec_id.
 
                        -- These top level defns should have been lifted.
                        -- We must add code to unlift such a spec_id.
 
-                  if isUnboxedDataType (idType spec_id) then
+                  if isUnboxedType (idType spec_id) then
                       ASSERT (null tys_left && null args_left)
                       if toplevelishId spec_id then
                           liftId spec_id       `thenSM` \ (lift_spec_id, unlift_spec_id) ->
                       ASSERT (null tys_left && null args_left)
                       if toplevelishId spec_id then
                           liftId spec_id       `thenSM` \ (lift_spec_id, unlift_spec_id) ->
@@ -2158,13 +2256,13 @@ mkCall new_id args
                       else
                           pprPanic "Specialise:mkCall: unboxed spec_id not top-level ...\n"
                                    (ppCat [ppr PprDebug new_id,
                       else
                           pprPanic "Specialise:mkCall: unboxed spec_id not top-level ...\n"
                                    (ppCat [ppr PprDebug new_id,
-                                           ppInterleave ppNil (map (pprParendType PprDebug) ty_args),
+                                           ppInterleave ppNil (map (pprParendGenType PprDebug) ty_args),
                                            ppStr "==>",
                                            ppr PprDebug spec_id])
                   else
                   let
                       (vals_left, _, unlifts_left) = unzip3 args_left
                                            ppStr "==>",
                                            ppr PprDebug spec_id])
                   else
                   let
                       (vals_left, _, unlifts_left) = unzip3 args_left
-                      applied_tys  = mkCoTyApps (Var spec_id) tys_left
+                      applied_tys  = mkTyApp (Var spec_id) tys_left
                       applied_vals = mkGenApp applied_tys vals_left
                   in
                   returnSM (True, applyBindUnlifts unlifts_left applied_vals)
                       applied_vals = mkGenApp applied_tys vals_left
                   in
                   returnSM (True, applyBindUnlifts unlifts_left applied_vals)
@@ -2179,33 +2277,34 @@ mkCall new_id args
 
     (ty_args, val_args) = get args
       where
 
     (ty_args, val_args) = get args
       where
-       get ((TypeArg ty,_,_) : args) = (ty : tys, rest) where (tys,rest) = get args
-       get args                      = ([],       args)
+       get ((TyArg ty,_,_) : args) = (ty : tys, rest) where (tys,rest) = get args
+       get args                    = ([],       args)
 
 
        -- toss_dicts chucks away dict args, checking that they ain't types!
 
 
        -- toss_dicts chucks away dict args, checking that they ain't types!
-    toss_dicts 0 args               = args
-    toss_dicts n ((ValArg _,_,_) : args) = toss_dicts (n-1) args
+    toss_dicts 0 args              = args
+    toss_dicts n ((a,_,_) : args)
+      | isValArg a                 = toss_dicts (n-1) args
 
 \end{code}
 
 \begin{code}
 checkUnspecOK :: Id -> [Type] -> a -> a
 checkUnspecOK check_id tys
 
 \end{code}
 
 \begin{code}
 checkUnspecOK :: Id -> [Type] -> a -> a
 checkUnspecOK check_id tys
-  = if isLocallyDefined check_id && any isUnboxedDataType tys
+  = if isLocallyDefined check_id && any isUnboxedType tys
     then pprPanic "Specialise:checkUnspecOK: unboxed instance for local id not found\n"
                  (ppCat [ppr PprDebug check_id,
     then pprPanic "Specialise:checkUnspecOK: unboxed instance for local id not found\n"
                  (ppCat [ppr PprDebug check_id,
-                         ppInterleave ppNil (map (pprParendType PprDebug) tys)])
+                         ppInterleave ppNil (map (pprParendGenType PprDebug) tys)])
     else id
 
 checkSpecOK :: Id -> [Type] -> Id -> [Type] -> a -> a
 checkSpecOK check_id tys spec_id tys_left
     else id
 
 checkSpecOK :: Id -> [Type] -> Id -> [Type] -> a -> a
 checkSpecOK check_id tys spec_id tys_left
-  = if any isUnboxedDataType tys_left
+  = if any isUnboxedType tys_left
     then pprPanic "Specialise:checkSpecOK: unboxed type args in specialised application\n"
                  (ppAboves [ppCat [ppr PprDebug check_id,
     then pprPanic "Specialise:checkSpecOK: unboxed type args in specialised application\n"
                  (ppAboves [ppCat [ppr PprDebug check_id,
-                                   ppInterleave ppNil (map (pprParendType PprDebug) tys)],
+                                   ppInterleave ppNil (map (pprParendGenType PprDebug) tys)],
                             ppCat [ppr PprDebug spec_id,
                             ppCat [ppr PprDebug spec_id,
-                                   ppInterleave ppNil (map (pprParendType PprDebug) tys_left)]])
+                                   ppInterleave ppNil (map (pprParendGenType PprDebug) tys_left)]])
     else id
 \end{code}
 
     else id
 \end{code}
 
@@ -2231,7 +2330,7 @@ mkTyConInstance con tys
           --                    ppStr ")"]])
           (returnSM (singleTyConI tycon spec_tys `unionUDs` singleConUDs con))
   where
           --                    ppStr ")"]])
           (returnSM (singleTyConI tycon spec_tys `unionUDs` singleConUDs con))
   where
-    tycon = getDataConTyCon con
+    tycon = dataConTyCon con
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -2274,35 +2373,32 @@ Monad has:
  threaded in and out: unique supply
 
 \begin{code}
  threaded in and out: unique supply
 
 \begin{code}
+type TypeEnv = TyVarEnv Type
+
 type SpecM result
 type SpecM result
-  =  (GlobalSwitch -> Bool)
-  -> TypeEnv
+  =  TypeEnv
   -> SpecIdEnv
   -> UniqSupply
   -> result
 
   -> SpecIdEnv
   -> UniqSupply
   -> result
 
-initSM m sw_chker uniqs
-  = m sw_chker nullTyVarEnv nullIdEnv uniqs
+initSM m uniqs
+  = m nullTyVarEnv nullIdEnv uniqs
 
 returnSM :: a -> SpecM a
 thenSM  :: SpecM a -> (a -> SpecM b) -> SpecM b
 fixSM    :: (a -> SpecM a) -> SpecM a
 
 
 returnSM :: a -> SpecM a
 thenSM  :: SpecM a -> (a -> SpecM b) -> SpecM b
 fixSM    :: (a -> SpecM a) -> SpecM a
 
-thenSM m k sw_chkr tvenv idenv us
+thenSM m k tvenv idenv us
   = case splitUniqSupply us       of { (s1, s2) ->
   = case splitUniqSupply us       of { (s1, s2) ->
-    case (m sw_chkr tvenv idenv s1) of { r ->
-    k r sw_chkr tvenv idenv s2 }}
+    case (m tvenv idenv s1) of { r ->
+    k r tvenv idenv s2 }}
 
 
-returnSM r sw_chkr tvenv idenv us = r
+returnSM r tvenv idenv us = r
 
 
-fixSM k sw_chkr tvenv idenv us
+fixSM k tvenv idenv us
  = r
  where
  = r
  where
-   r = k r sw_chkr tvenv idenv us      -- Recursive in r!
-\end{code}
-
-\begin{code}
-getSwitchCheckerSM sw_chkr tvenv idenv us = sw_chkr
+   r = k r tvenv idenv us      -- Recursive in r!
 \end{code}
 
 The only interesting bit is figuring out the type of the SpecId!
 \end{code}
 
 The only interesting bit is figuring out the type of the SpecId!
@@ -2313,7 +2409,7 @@ newSpecIds :: [Id]                -- The id of which to make a specialised version
           -> Int               -- No of dicts to specialise
           -> SpecM [Id]
 
           -> Int               -- No of dicts to specialise
           -> SpecM [Id]
 
-newSpecIds new_ids maybe_tys dicts_to_ignore sw_chkr tvenv idenv us
+newSpecIds new_ids maybe_tys dicts_to_ignore tvenv idenv us
   = [ mkSpecId uniq id maybe_tys (spec_id_ty id) (selectIdInfoForSpecId id)
       | (id,uniq) <- new_ids `zip` uniqs ]
   where
   = [ mkSpecId uniq id maybe_tys (spec_id_ty id) (selectIdInfoForSpecId id)
       | (id,uniq) <- new_ids `zip` uniqs ]
   where
@@ -2321,7 +2417,7 @@ newSpecIds new_ids maybe_tys dicts_to_ignore sw_chkr tvenv idenv us
     spec_id_ty id = specialiseTy (idType id) maybe_tys dicts_to_ignore
 
 newTyVars :: Int -> SpecM [TyVar]
     spec_id_ty id = specialiseTy (idType id) maybe_tys dicts_to_ignore
 
 newTyVars :: Int -> SpecM [TyVar]
-newTyVars n sw_chkr tvenv idenv us
+newTyVars n tvenv idenv us
  = map mkPolySysTyVar uniqs
  where
    uniqs = getUniques n us
  = map mkPolySysTyVar uniqs
  where
    uniqs = getUniques n us
@@ -2343,7 +2439,7 @@ As well as returning the list of cloned @Id@s they also return a list of
 cloneLambdaOrCaseBinders :: [Id]                       -- Old binders
                         -> SpecM ([Id], [CloneInfo])   -- New ones
 
 cloneLambdaOrCaseBinders :: [Id]                       -- Old binders
                         -> SpecM ([Id], [CloneInfo])   -- New ones
 
-cloneLambdaOrCaseBinders old_ids sw_chkr tvenv idenv us
+cloneLambdaOrCaseBinders old_ids tvenv idenv us
   = let
        uniqs = getUniques (length old_ids) us
     in
   = let
        uniqs = getUniques (length old_ids) us
     in
@@ -2359,7 +2455,7 @@ cloneLetBinders :: Bool                   -- Top level ?
                -> [Id]                         -- Old binders
                -> SpecM ([Id], [CloneInfo])    -- New ones
 
                -> [Id]                         -- Old binders
                -> SpecM ([Id], [CloneInfo])    -- New ones
 
-cloneLetBinders top_lev is_rec old_ids sw_chkr tvenv idenv us
+cloneLetBinders top_lev is_rec old_ids tvenv idenv us
   = let
        uniqs = getUniques (2 * length old_ids) us
     in
   = let
        uniqs = getUniques (2 * length old_ids) us
     in
@@ -2379,7 +2475,7 @@ cloneLetBinders top_lev is_rec old_ids sw_chkr tvenv idenv us
         -- (c) the thing is polymorphic so no need to subst
 
       | otherwise
         -- (c) the thing is polymorphic so no need to subst
 
       | otherwise
-       = if (is_rec && isUnboxedDataType new_ty && not (isUnboxedDataType old_ty))
+       = if (is_rec && isUnboxedType new_ty && not (isUnboxedType old_ty))
          then (lifted_id,
                Lifted lifted_id unlifted_id) : clone_rest
          else (new_id,
          then (lifted_id,
                Lifted lifted_id unlifted_id) : clone_rest
          else (new_id,
@@ -2397,7 +2493,7 @@ cloneLetBinders top_lev is_rec old_ids sw_chkr tvenv idenv us
 
 cloneTyVarSM :: TyVar -> SpecM TyVar
 
 
 cloneTyVarSM :: TyVar -> SpecM TyVar
 
-cloneTyVarSM old_tyvar sw_chkr tvenv idenv us
+cloneTyVarSM old_tyvar tvenv idenv us
   = let
        uniq = getUnique us
     in
   = let
        uniq = getUnique us
     in
@@ -2405,13 +2501,13 @@ cloneTyVarSM old_tyvar sw_chkr tvenv idenv us
 
 bindId :: Id -> CloneInfo -> SpecM thing -> SpecM thing
 
 
 bindId :: Id -> CloneInfo -> SpecM thing -> SpecM thing
 
-bindId id val specm sw_chkr tvenv idenv us
- = specm sw_chkr tvenv (addOneToIdEnv idenv id val) us
+bindId id val specm tvenv idenv us
+ = specm tvenv (addOneToIdEnv idenv id val) us
 
 bindIds :: [Id] -> [CloneInfo] -> SpecM thing -> SpecM thing
 
 
 bindIds :: [Id] -> [CloneInfo] -> SpecM thing -> SpecM thing
 
-bindIds olds news specm sw_chkr tvenv idenv us
- = specm sw_chkr tvenv (growIdEnvList idenv (zip olds news)) us
+bindIds olds news specm tvenv idenv us
+ = specm tvenv (growIdEnvList idenv (zip olds news)) us
 
 bindSpecIds :: [Id]                    -- Old
            -> [(CloneInfo)]            -- New
 
 bindSpecIds :: [Id]                    -- Old
            -> [(CloneInfo)]            -- New
@@ -2421,8 +2517,8 @@ bindSpecIds :: [Id]                       -- Old
            -> SpecM thing
            -> SpecM thing
 
            -> SpecM thing
            -> SpecM thing
 
-bindSpecIds olds clones spec_infos specm sw_chkr tvenv idenv us
- = specm sw_chkr tvenv (growIdEnvList idenv old_to_clone) us
+bindSpecIds olds clones spec_infos specm tvenv idenv us
+ = specm tvenv (growIdEnvList idenv old_to_clone) us
  where
    old_to_clone = mk_old_to_clone olds clones spec_infos
 
  where
    old_to_clone = mk_old_to_clone olds clones spec_infos
 
@@ -2444,14 +2540,14 @@ bindSpecIds olds clones spec_infos specm sw_chkr tvenv idenv us
 
 bindTyVar :: TyVar -> Type -> SpecM thing -> SpecM thing
 
 
 bindTyVar :: TyVar -> Type -> SpecM thing -> SpecM thing
 
-bindTyVar tyvar ty specm sw_chkr tvenv idenv us
- = specm sw_chkr (growTyVarEnvList tvenv [(tyvar,ty)]) idenv us
+bindTyVar tyvar ty specm tvenv idenv us
+ = specm (growTyVarEnvList tvenv [(tyvar,ty)]) idenv us
 \end{code}
 
 \begin{code}
 lookupId :: Id -> SpecM CloneInfo
 
 \end{code}
 
 \begin{code}
 lookupId :: Id -> SpecM CloneInfo
 
-lookupId id sw_chkr tvenv idenv us
+lookupId id tvenv idenv us
   = case lookupIdEnv idenv id of
       Nothing   -> NoLift (VarArg id)
       Just info -> info
   = case lookupIdEnv idenv id of
       Nothing   -> NoLift (VarArg id)
       Just info -> info
@@ -2460,13 +2556,13 @@ lookupId id sw_chkr tvenv idenv us
 \begin{code}
 specTy :: Type -> SpecM Type   -- Apply the current type envt to the type
 
 \begin{code}
 specTy :: Type -> SpecM Type   -- Apply the current type envt to the type
 
-specTy ty sw_chkr tvenv idenv us
+specTy ty tvenv idenv us
   = applyTypeEnvToTy tvenv ty
 \end{code}
 
 \begin{code}
 liftId :: Id -> SpecM (Id, Id)
   = applyTypeEnvToTy tvenv ty
 \end{code}
 
 \begin{code}
 liftId :: Id -> SpecM (Id, Id)
-liftId id sw_chkr tvenv idenv us
+liftId id tvenv idenv us
   = let
        uniq = getUnique us
     in
   = let
        uniq = getUnique us
     in
index 5afb086..50a9bc0 100644 (file)
@@ -13,39 +13,35 @@ Convert a @CoreSyntax@ program to a @StgSyntax@ program.
 \begin{code}
 #include "HsVersions.h"
 
 \begin{code}
 #include "HsVersions.h"
 
-module CoreToStg (
-       topCoreBindsToStg
+module CoreToStg ( topCoreBindsToStg ) where
 
 
-       -- and to make the interface self-sufficient...
-    ) where
+import Ubiq{-uitous-}
 
 
-import AnnCoreSyn      -- intermediate form on which all work is done
+import CoreSyn         -- input
 import StgSyn          -- output
 import StgSyn          -- output
-import UniqSupply
 
 
+import Bag             ( emptyBag, unitBag, unionBags, unionManyBags, bagToList )
+import CoreUtils       ( coreExprType )
+import CostCentre      ( noCostCentre )
+import Id              ( mkSysLocal, idType, isBottomingId,
+                         nullIdEnv, addOneToIdEnv, lookupIdEnv,
+                         IdEnv(..), GenId{-instance NamedThing-}
+                       )
+import Literal         ( mkMachInt, Literal(..) )
+import Outputable      ( isExported )
 import PrelInfo                ( unpackCStringId, unpackCString2Id, stringTy,
                          integerTy, rationalTy, ratioDataCon,
 import PrelInfo                ( unpackCStringId, unpackCString2Id, stringTy,
                          integerTy, rationalTy, ratioDataCon,
-                         PrimOp(..),           -- For Int2IntegerOp etc
                          integerZeroId, integerPlusOneId,
                          integerPlusTwoId, integerMinusOneId
                          integerZeroId, integerPlusOneId,
                          integerPlusTwoId, integerMinusOneId
-                         IF_ATTACK_PRAGMAS(COMMA mkListTy COMMA charTy)
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                       )
-
-import Type            ( isPrimType, isLeakFreeType, getAppDataTyCon )
-import Bag             -- Bag operations
-import Literal         ( mkMachInt, Literal(..) )      -- ToDo: its use is ugly...
-import CostCentre      ( noCostCentre, CostCentre )
-import Id              ( mkSysLocal, idType, isBottomingId
-                         IF_ATTACK_PRAGMAS(COMMA bottomIsGuaranteed)
                        )
                        )
-import Maybes          ( Maybe(..), catMaybes )
-import Outputable      ( isExported )
-import Pretty          -- debugging only!
+import PrimOp          ( PrimOp(..) )
 import SpecUtils       ( mkSpecialisedCon )
 import SpecUtils       ( mkSpecialisedCon )
-import SrcLoc          ( SrcLoc, mkUnknownSrcLoc )
-import Util
+import SrcLoc          ( mkUnknownSrcLoc )
+import Type            ( getAppDataTyCon )
+import UniqSupply      -- all of it, really
+import Util            ( panic )
+
+isLeakFreeType = panic "CoreToStg.isLeakFreeType (ToDo)"
 \end{code}
 
 
 \end{code}
 
 
@@ -360,10 +356,20 @@ litToStgArg other_lit = returnUs (StgLitArg other_lit, emptyBag)
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-coreAtomToStg :: StgEnv -> CoreArg -> UniqSM (StgArg, Bag StgBinding)
+coreArgsToStg :: StgEnv -> [CoreArg] -> UniqSM ([Type], [StgArg], Bag StgBinding)
 
 
-coreAtomToStg env (VarArg var) = returnUs (stgLookup env var, emptyBag)
-coreAtomToStg env (LitArg lit) = litToStgArg lit
+coreArgsToStg env [] = returnUs ([], [], emptyBag)
+coreArgsToStg env (a:as)
+  = coreArgsToStg env as    `thenUs` \ (tys, args, binds) ->
+    do_arg a tys args binds
+  where
+    do_arg a trest vrest binds
+      = case a of
+         TyArg    t -> returnUs (t:trest, vrest, binds)
+         UsageArg u -> returnUs (trest, vrest, binds)
+         VarArg   v -> returnUs (trest, stgLookup env v : vrest, binds)
+         LitArg   i -> litToStgArg i `thenUs` \ (v, bs) ->
+                       returnUs (trest, v:vrest, bs `unionBags` binds)
 \end{code}
 
 There's not anything interesting we can ASSERT about \tr{var} if it
 \end{code}
 
 There's not anything interesting we can ASSERT about \tr{var} if it
@@ -397,28 +403,16 @@ coreExprToStg env (Lit lit)
 coreExprToStg env (Var var)
   = returnUs (StgApp (stgLookup env var) [] bOGUS_LVs, emptyBag)
 
 coreExprToStg env (Var var)
   = returnUs (StgApp (stgLookup env var) [] bOGUS_LVs, emptyBag)
 
-coreExprToStg env (Con con types args)
-  = mapAndUnzipUs (coreAtomToStg env) args `thenUs` \ (stg_atoms, stg_binds) ->
-    returnUs (StgCon spec_con stg_atoms bOGUS_LVs, unionManyBags stg_binds)
-  where
-    spec_con = mkSpecialisedCon con types
-
-coreExprToStg env (Prim op tys args)
-  = mapAndUnzipUs (coreAtomToStg env) args `thenUs` \ (stg_atoms, stg_binds) ->
-    returnUs (StgPrim op stg_atoms bOGUS_LVs, unionManyBags stg_binds)
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsubsection[coreToStg-type-stuff]{Type application and abstraction}
-%*                                                                     *
-%************************************************************************
-
-This type information dies in this Core-to-STG translation.
+coreExprToStg env (Con con args)
+  = coreArgsToStg env args  `thenUs` \ (types, stg_atoms, stg_binds) ->
+    let
+       spec_con = mkSpecialisedCon con types
+    in
+    returnUs (StgCon spec_con stg_atoms bOGUS_LVs, stg_binds)
 
 
-\begin{code}
-coreExprToStg env (CoTyLam tyvar expr) = coreExprToStg env expr
-coreExprToStg env (CoTyApp expr  ty)   = coreExprToStg env expr
+coreExprToStg env (Prim op args)
+  = coreArgsToStg env args  `thenUs` \ (_, stg_atoms, stg_binds) ->
+    returnUs (StgPrim op stg_atoms bOGUS_LVs, stg_binds)
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -429,7 +423,10 @@ coreExprToStg env (CoTyApp expr  ty)   = coreExprToStg env expr
 
 \begin{code}
 coreExprToStg env expr@(Lam _ _)
 
 \begin{code}
 coreExprToStg env expr@(Lam _ _)
-  = coreExprToStg env body             `thenUs` \ (stg_body, binds) ->
+  = let
+       (_,_, binders, body) = collectBinders expr
+    in
+    coreExprToStg env body             `thenUs` \ (stg_body, binds) ->
     newStgVar (coreExprType expr)      `thenUs` \ var ->
     returnUs
       (StgLet (StgNonRec var (StgRhsClosure noCostCentre
     newStgVar (coreExprType expr)      `thenUs` \ var ->
     returnUs
       (StgLet (StgNonRec var (StgRhsClosure noCostCentre
@@ -440,14 +437,6 @@ coreExprToStg env expr@(Lam _ _)
                              stg_body))
        (StgApp (StgVarArg var) [] bOGUS_LVs),
        binds)
                              stg_body))
        (StgApp (StgVarArg var) [] bOGUS_LVs),
        binds)
-  where
-    (binders,body) = collect expr
-
-    -- Collect lambda-bindings, discarding type abstractions and applications
-    collect (Lam x e)   = (x:binders, body) where (binders,body) = collect e
-    collect (CoTyLam _ e) = collect e
-    collect (CoTyApp e _) = collect e
-    collect body         = ([], body)
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -458,13 +447,15 @@ coreExprToStg env expr@(Lam _ _)
 
 \begin{code}
 coreExprToStg env expr@(App _ _)
 
 \begin{code}
 coreExprToStg env expr@(App _ _)
-  =    -- Deal with the arguments
-    mapAndUnzipUs (coreAtomToStg env) args `thenUs` \ (stg_args, arg_binds) ->
+  = let
+       (fun, _, _, args) = collectArgs expr
+    in
+       -- Deal with the arguments
+    coreArgsToStg env args `thenUs` \ (_, stg_args, arg_binds) ->
 
        -- Now deal with the function
     case fun of
 
        -- Now deal with the function
     case fun of
-      Var fun_id -> returnUs (StgApp (stgLookup env fun_id) stg_args bOGUS_LVs,
-                               unionManyBags arg_binds)
+      Var fun_id -> returnUs (StgApp (stgLookup env fun_id) stg_args bOGUS_LVs, arg_binds)
 
       other -> -- A non-variable applied to things; better let-bind it.
                newStgVar (coreExprType fun)    `thenUs` \ fun_id ->
 
       other -> -- A non-variable applied to things; better let-bind it.
                newStgVar (coreExprType fun)    `thenUs` \ fun_id ->
@@ -479,16 +470,7 @@ coreExprToStg env expr@(App _ _)
                in
                returnUs (StgLet (StgNonRec fun_id fun_rhs)
                                  (StgApp (StgVarArg fun_id) stg_args bOGUS_LVs),
                in
                returnUs (StgLet (StgNonRec fun_id fun_rhs)
                                  (StgApp (StgVarArg fun_id) stg_args bOGUS_LVs),
-                          unionManyBags arg_binds `unionBags`
-                          fun_binds)
-  where
-    (fun,args) = collect_args expr []
-
-    -- Collect arguments, discarding type abstractions and applications
-    collect_args (App fun arg) args = collect_args fun (arg:args)
-    collect_args (CoTyLam _ e)   args = collect_args e args
-    collect_args (CoTyApp e _)   args = collect_args e args
-    collect_args fun             args = (fun, args)
+                          arg_binds `unionBags` fun_binds)
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -517,9 +499,9 @@ to
 
 \begin{code}
 
 
 \begin{code}
 
-coreExprToStg env (Case discrim@(Prim op tys args) alts)
-  | funnyParallelOp op =
-    getUnique                  `thenUs` \ uniq ->
+coreExprToStg env (Case discrim@(Prim op _) alts)
+  | funnyParallelOp op
+  = getUnique                  `thenUs` \ uniq ->
     coreExprToStg env discrim  `thenUs` \ (stg_discrim, discrim_binds) ->
     alts_to_stg alts           `thenUs` \ (stg_alts, alts_binds) ->
     returnUs (
     coreExprToStg env discrim  `thenUs` \ (stg_discrim, discrim_binds) ->
     alts_to_stg alts           `thenUs` \ (stg_alts, alts_binds) ->
     returnUs (
index b97ef11..74abea7 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
 %
 \section[StgLint]{A ``lint'' pass to check for Stg correctness}
 
 %
 \section[StgLint]{A ``lint'' pass to check for Stg correctness}
 
@@ -8,25 +8,34 @@
 
 module StgLint ( lintStgBindings ) where
 
 
 module StgLint ( lintStgBindings ) where
 
-import PrelInfo                ( primOpType, mkFunTy, PrimOp(..), PrimRep
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
-                       )
-import Type
-import Bag
-import Literal         ( literalType, Literal )
+import Ubiq{-uitous-}
+
+import StgSyn
+
+import Bag             ( emptyBag, isEmptyBag, snocBag, foldBag )
 import Id              ( idType, isDataCon,
 import Id              ( idType, isDataCon,
-                         getInstantiatedDataConSig
+                         emptyIdSet, isEmptyIdSet, elementOfIdSet,
+                         mkIdSet, intersectIdSets,
+                         unionIdSets, idSetToList, IdSet(..),
+                         GenId{-instanced NamedThing-}
                        )
                        )
-import Maybes
-import Outputable
-import Pretty
-import SrcLoc          ( SrcLoc )
-import StgSyn
-import UniqSet
-import Util
+import Literal         ( literalType, Literal{-instance Outputable-} )
+import Maybes          ( catMaybes )
+import Outputable      ( Outputable(..){-instance * []-} )
+import PprType         ( GenType{-instance Outputable-}, TyCon )
+import Pretty          -- quite a bit of it
+import PrimOp          ( primOpType )
+import SrcLoc          ( SrcLoc{-instance Outputable-} )
+import Type            ( mkFunTys, splitFunTy, maybeAppDataTyCon,
+                         isTyVarTy, eqTy
+                       )
+import Util            ( zipEqual, pprPanic, panic, panic# )
 
 infixr 9 `thenL`, `thenL_`, `thenMaybeL`, `thenMaybeL_`
 
 infixr 9 `thenL`, `thenL_`, `thenMaybeL`, `thenMaybeL_`
+
+getInstantiatedDataConSig = panic "StgLint.getInstantiatedDataConSig (ToDo)"
+splitTypeWithDictsAsArgs = panic "StgLint.splitTypeWithDictsAsArgs (ToDo)"
+unDictifyTy = panic "StgLint.unDictifyTy (ToDo)"
 \end{code}
 
 Checks for
 \end{code}
 
 Checks for
@@ -114,7 +123,7 @@ lintStgRhs (StgRhsClosure _ _ _ _ binders expr)
   = addLoc (LambdaBodyOf binders) (
     addInScopeVars binders (
        lintStgExpr expr   `thenMaybeL` \ body_ty ->
   = addLoc (LambdaBodyOf binders) (
     addInScopeVars binders (
        lintStgExpr expr   `thenMaybeL` \ body_ty ->
-       returnL (Just (foldr (mkFunTy . idType) body_ty binders))
+       returnL (Just (mkFunTys (map idType binders) body_ty))
     ))
 
 lintStgRhs (StgRhsCon _ con args)
     ))
 
 lintStgRhs (StgRhsCon _ con args)
@@ -193,7 +202,6 @@ lintStgAlts :: StgCaseAlts
 lintStgAlts alts scrut_ty case_tycon
   = (case alts of
         StgAlgAlts _ alg_alts deflt ->
 lintStgAlts alts scrut_ty case_tycon
   = (case alts of
         StgAlgAlts _ alg_alts deflt ->
-          chk_non_abstract_type case_tycon     `thenL_`
           mapL (lintAlgAlt scrut_ty) alg_alts  `thenL` \ maybe_alt_tys ->
           lintDeflt deflt scrut_ty             `thenL` \ maybe_deflt_ty ->
           returnL (maybe_deflt_ty : maybe_alt_tys)
           mapL (lintAlgAlt scrut_ty) alg_alts  `thenL` \ maybe_alt_tys ->
           lintDeflt deflt scrut_ty             `thenL` \ maybe_deflt_ty ->
           returnL (maybe_deflt_ty : maybe_alt_tys)
@@ -211,11 +219,6 @@ lintStgAlts alts scrut_ty case_tycon
                        returnL (Just first_ty)
        where
          check ty = checkTys first_ty ty (mkCaseAltMsg alts)
                        returnL (Just first_ty)
        where
          check ty = checkTys first_ty ty (mkCaseAltMsg alts)
-  where
-    chk_non_abstract_type tycon
-      = case (getTyConFamilySize tycon) of
-         Nothing -> addErrL (mkCaseAbstractMsg tycon)
-         Just  _ -> returnL () -- that's cool
 
 lintAlgAlt scrut_ty (con, args, _, rhs)
   = (case maybeAppDataTyCon scrut_ty of
 
 lintAlgAlt scrut_ty (con, args, _, rhs)
   = (case maybeAppDataTyCon scrut_ty of
@@ -264,7 +267,7 @@ lintDeflt deflt@(StgBindDefault binder _ rhs) scrut_ty
 
 \begin{code}
 type LintM a = [LintLocInfo]   -- Locations
 
 \begin{code}
 type LintM a = [LintLocInfo]   -- Locations
-           -> UniqSet Id       -- Local vars in scope
+           -> IdSet            -- Local vars in scope
            -> Bag ErrMsg       -- Error messages so far
            -> (a, Bag ErrMsg)  -- Result and error messages (if any)
 
            -> Bag ErrMsg       -- Error messages so far
            -> (a, Bag ErrMsg)  -- Result and error messages (if any)
 
@@ -298,12 +301,12 @@ pp_binders sty bs
 \begin{code}
 initL :: LintM a -> Maybe ErrMsg
 initL m
 \begin{code}
 initL :: LintM a -> Maybe ErrMsg
 initL m
-  = case (m [] emptyUniqSet emptyBag) of { (_, errs) ->
+  = case (m [] emptyIdSet emptyBag) of { (_, errs) ->
     if isEmptyBag errs then
        Nothing
     else
        Just ( \ sty ->
     if isEmptyBag errs then
        Nothing
     else
        Just ( \ sty ->
-         ppAboves [ msg sty | msg <- bagToList errs ]
+         foldBag ppAbove ( \ msg -> msg sty ) ppNil errs
        )
     }
 
        )
     }
 
@@ -374,17 +377,16 @@ addInScopeVars ids m loc scope errs
     -- For now, it's just a "trace"; we may make
     -- a real error out of it...
     let
     -- For now, it's just a "trace"; we may make
     -- a real error out of it...
     let
-       new_set = mkUniqSet ids
+       new_set = mkIdSet ids
 
 
-       shadowed = scope `intersectUniqSets` new_set
+       shadowed = scope `intersectIdSets` new_set
     in
 --  After adding -fliberate-case, Simon decided he likes shadowed
 --  names after all.  WDP 94/07
     in
 --  After adding -fliberate-case, Simon decided he likes shadowed
 --  names after all.  WDP 94/07
---  (if isEmptyUniqSet shadowed
+--  (if isEmptyIdSet shadowed
 --  then id
 --  then id
---  else pprTrace "Shadowed vars:" (ppr PprDebug (uniqSetToList shadowed))) (
-    m loc (scope `unionUniqSets` new_set) errs
---  )
+--  else pprTrace "Shadowed vars:" (ppr PprDebug (idSetToList shadowed))) $
+    m loc (scope `unionIdSets` new_set) errs
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -399,38 +401,38 @@ checkFunApp fun_ty arg_tys msg loc scope errs
     (_, expected_arg_tys, res_ty) = splitTypeWithDictsAsArgs fun_ty
 
     cfa res_ty expected []     -- Args have run out; that's fine
     (_, expected_arg_tys, res_ty) = splitTypeWithDictsAsArgs fun_ty
 
     cfa res_ty expected []     -- Args have run out; that's fine
-      = (Just (glueTyArgs expected res_ty), errs)
+      = (Just (mkFunTys expected res_ty), errs)
 
     cfa res_ty [] arg_tys      -- Expected arg tys ran out first;
                                -- first see if res_ty is a tyvar template;
                                -- otherwise, maybe res_ty is a
                                -- dictionary type which is actually a function?
 
     cfa res_ty [] arg_tys      -- Expected arg tys ran out first;
                                -- first see if res_ty is a tyvar template;
                                -- otherwise, maybe res_ty is a
                                -- dictionary type which is actually a function?
-      | isTyVarTemplateTy res_ty
+      | isTyVarTy res_ty
       = (Just res_ty, errs)
       | otherwise
       = (Just res_ty, errs)
       | otherwise
-      = case splitTyArgs (unDictifyTy res_ty) of
+      = case splitFunTy (unDictifyTy res_ty) of
          ([], _)                 -> (Nothing, addErr errs msg loc)     -- Too many args
          (new_expected, new_res) -> cfa new_res new_expected arg_tys
 
     cfa res_ty (expected_arg_ty:expected_arg_tys) (arg_ty:arg_tys)
          ([], _)                 -> (Nothing, addErr errs msg loc)     -- Too many args
          (new_expected, new_res) -> cfa new_res new_expected arg_tys
 
     cfa res_ty (expected_arg_ty:expected_arg_tys) (arg_ty:arg_tys)
-      = case (sleazy_cmp_ty expected_arg_ty arg_ty) of
-         EQ_ -> cfa res_ty expected_arg_tys arg_tys
-         _   -> (Nothing, addErr errs msg loc) -- Arg mis-match
+      = if (sleazy_eq_ty expected_arg_ty arg_ty)
+       then cfa res_ty expected_arg_tys arg_tys
+       else (Nothing, addErr errs msg loc) -- Arg mis-match
 \end{code}
 
 \begin{code}
 checkInScope :: Id -> LintM ()
 checkInScope id loc scope errs
 \end{code}
 
 \begin{code}
 checkInScope :: Id -> LintM ()
 checkInScope id loc scope errs
-  = if isLocallyDefined id && not (isDataCon id) && not (id `elementOfUniqSet` scope) then
+  = if isLocallyDefined id && not (isDataCon id) && not (id `elementOfIdSet` scope) then
        ((), addErr errs (\ sty -> ppCat [ppr sty id, ppStr "is out of scope"]) loc)
     else
        ((), errs)
 
 checkTys :: Type -> Type -> ErrMsg -> LintM ()
 checkTys ty1 ty2 msg loc scope errs
        ((), addErr errs (\ sty -> ppCat [ppr sty id, ppStr "is out of scope"]) loc)
     else
        ((), errs)
 
 checkTys :: Type -> Type -> ErrMsg -> LintM ()
 checkTys ty1 ty2 msg loc scope errs
-  = case (sleazy_cmp_ty ty1 ty2) of
-      EQ_   -> ((), errs)
-      other -> ((), addErr errs msg loc)
+  = if (sleazy_eq_ty ty1 ty2)
+    then ((), errs)
+    else ((), addErr errs msg loc)
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -520,14 +522,15 @@ mkRhsMsg binder ty sty
 pp_expr :: PprStyle -> StgExpr -> Pretty
 pp_expr sty expr = ppr sty expr
 
 pp_expr :: PprStyle -> StgExpr -> Pretty
 pp_expr sty expr = ppr sty expr
 
-sleazy_cmp_ty ty1 ty2
+sleazy_eq_ty ty1 ty2
        -- NB: probably severe overkill (WDP 95/04)
   = case (splitTypeWithDictsAsArgs ty1) of { (_,tyargs1,tyres1) ->
     case (splitTypeWithDictsAsArgs ty2) of { (_,tyargs2,tyres2) ->
     let
        -- NB: probably severe overkill (WDP 95/04)
   = case (splitTypeWithDictsAsArgs ty1) of { (_,tyargs1,tyres1) ->
     case (splitTypeWithDictsAsArgs ty2) of { (_,tyargs2,tyres2) ->
     let
-       ty11 = glueTyArgs tyargs1 tyres1
-       ty22 = glueTyArgs tyargs2 tyres2
+       ty11 = mkFunTys tyargs1 tyres1
+       ty22 = mkFunTys tyargs2 tyres2
     in
     in
-    cmpUniType False{-!!!NOT PROPERLY!!!-} ty11 ty22
+    trace "StgLint.sleazy_cmp_ty" $
+    ty11 `eqTy` ty22
     }}
 \end{code}
     }}
 \end{code}
index 456a7f8..395eaa0 100644 (file)
@@ -41,27 +41,20 @@ module StgSyn (
 
 import Ubiq{-uitous-}
 
 
 import Ubiq{-uitous-}
 
-{-
-import PrelInfo                ( getPrimOpResultInfo, PrimOpResultInfo(..),
-                         PrimOp, PrimRep
-                         IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
-                         IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
+import CostCentre      ( showCostCentre )
+import Id              ( idPrimRep, GenId{-instance NamedThing-} )
+import Literal         ( literalPrimRep, isLitLitLit, Literal{-instance Outputable-} )
+import Outputable      ( isExported, isOpLexeme, ifPprDebug,
+                         interppSP, interpp'SP,
+                         Outputable(..){-instance * Bool-}
                        )
                        )
-import HsSyn           ( HsBinds, HsExpr, GRHS, GRHSsAndBinds, InPat )
-import Type
-import Literal         ( literalPrimRep, isLitLitLit,
-                         Literal(..) -- (..) for pragmas
-                       )
-import Id              ( idType, getIdPrimRep, toplevelishId,
-                         isTopLevId, Id, IdInfo
-                       )
-import Maybes          ( Maybe(..), catMaybes )
-import Outputable
-import Pretty
-import CostCentre      ( showCostCentre, CostCentre )
-import UniqSet
-import Util
--}
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-} )
+import Pretty          -- all of it
+import PrimOp          ( PrimOp{-instance Outputable-} )
+import Unique          ( pprUnique )
+import UniqSet         ( isEmptyUniqSet, uniqSetToList, UniqSet(..) )
+import Util            ( panic )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -94,8 +87,8 @@ data GenStgArg occ
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-getArgPrimRep (StgVarArg  local) = getIdPrimRep local
-getArgPrimRep (StgLitArg  lit) = literalPrimRep lit
+getArgPrimRep (StgVarArg  local) = idPrimRep local
+getArgPrimRep (StgLitArg  lit)  = literalPrimRep lit
 
 isLitLitArg (StgLitArg x) = isLitLitLit x
 isLitLitArg _            = False
 
 isLitLitArg (StgLitArg x) = isLitLitLit x
 isLitLitArg _            = False
index 830a752..7c89ac3 100644 (file)
@@ -1,5 +1,5 @@
 x%
 x%
-% (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
 %
 \section[StgUtils]{Utility functions for @STG@ programs}
 
 %
 \section[StgUtils]{Utility functions for @STG@ programs}
 
@@ -8,11 +8,11 @@ x%
 
 module StgUtils ( mapStgBindeesRhs ) where
 
 
 module StgUtils ( mapStgBindeesRhs ) where
 
-import StgSyn
+import Ubiq{-uitous-}
 
 
+import Id              ( GenId{-instanced NamedThing-} )
+import StgSyn
 import UniqSet
 import UniqSet
-
-import Util
 \end{code}
 
 This utility function simply applies the given function to every
 \end{code}
 
 This utility function simply applies the given function to every
@@ -36,21 +36,21 @@ mapStgBindeesRhs fn (StgRhsClosure cc bi fvs u args expr)
        (mapStgBindeesExpr fn expr)
 
 mapStgBindeesRhs fn (StgRhsCon cc con atoms)
        (mapStgBindeesExpr fn expr)
 
 mapStgBindeesRhs fn (StgRhsCon cc con atoms)
-  = StgRhsCon cc con (map (mapStgBindeesAtom fn) atoms)
+  = StgRhsCon cc con (map (mapStgBindeesArg fn) atoms)
 
 ------------------
 mapStgBindeesExpr :: (Id -> Id) -> StgExpr -> StgExpr
 
 mapStgBindeesExpr fn (StgApp f args lvs)
 
 ------------------
 mapStgBindeesExpr :: (Id -> Id) -> StgExpr -> StgExpr
 
 mapStgBindeesExpr fn (StgApp f args lvs)
-  = StgApp (mapStgBindeesAtom fn f)
-          (map (mapStgBindeesAtom fn) args)
+  = StgApp (mapStgBindeesArg fn f)
+          (map (mapStgBindeesArg fn) args)
           (mapUniqSet fn lvs)
 
 mapStgBindeesExpr fn (StgCon con atoms lvs)
           (mapUniqSet fn lvs)
 
 mapStgBindeesExpr fn (StgCon con atoms lvs)
-  = StgCon con (map (mapStgBindeesAtom fn) atoms) (mapUniqSet fn lvs)
+  = StgCon con (map (mapStgBindeesArg fn) atoms) (mapUniqSet fn lvs)
 
 mapStgBindeesExpr fn (StgPrim op atoms lvs)
 
 mapStgBindeesExpr fn (StgPrim op atoms lvs)
-  = StgPrim op (map (mapStgBindeesAtom fn) atoms) (mapUniqSet fn lvs)
+  = StgPrim op (map (mapStgBindeesArg fn) atoms) (mapUniqSet fn lvs)
 
 mapStgBindeesExpr fn (StgLet bind expr)
   = StgLet (mapStgBindeesBind fn bind) (mapStgBindeesExpr fn expr)
 
 mapStgBindeesExpr fn (StgLet bind expr)
   = StgLet (mapStgBindeesBind fn bind) (mapStgBindeesExpr fn expr)
@@ -83,8 +83,8 @@ mapStgBindeesExpr fn (StgCase expr lvs1 lvs2 uniq alts)
     mapStgBindeesDeflt (StgBindDefault b used expr) = StgBindDefault b used (mapStgBindeesExpr fn expr)
 
 ------------------
     mapStgBindeesDeflt (StgBindDefault b used expr) = StgBindDefault b used (mapStgBindeesExpr fn expr)
 
 ------------------
-mapStgBindeesAtom :: (Id -> Id) -> StgArg -> StgArg
+mapStgBindeesArg :: (Id -> Id) -> StgArg -> StgArg
 
 
-mapStgBindeesAtom fn a@(StgLitArg _)   = a
-mapStgBindeesAtom fn a@(StgVarArg id)  = StgVarArg (fn id)
+mapStgBindeesArg fn a@(StgLitArg _)    = a
+mapStgBindeesArg fn a@(StgVarArg id)  = StgVarArg (fn id)
 \end{code}
 \end{code}
index 156f2ae..1020b67 100644 (file)
@@ -15,30 +15,37 @@ module SaAbsInt (
        isBot
     ) where
 
        isBot
     ) where
 
-IMPORT_Trace           -- ToDo: rm
-import Pretty
---import FiniteMap
-import Outputable
-
-import PrelInfo                ( PrimOp(..),
-                         intTyCon, integerTyCon, doubleTyCon,
-                         floatTyCon, wordTyCon, addrTyCon,
-                         PrimRep
+import Ubiq{-uitous-}
+
+import CoreSyn
+import CoreUnfold      ( UnfoldingDetails(..), FormSummary )
+import CoreUtils       ( unTagBinders )
+import Id              ( idType, getIdStrictness, getIdUnfolding,
+                         dataConSig
                        )
                        )
-import Type            ( isPrimType, maybeAppDataTyCon,
-                         maybeSingleConstructorTyCon,
-                         returnsRealWorld,
-                         isEnumerationTyCon, TyVarTemplate, TyCon
+import IdInfo          ( StrictnessInfo(..), Demand(..),
+                         wwPrim, wwStrict, wwEnum, wwUnpack
                        )
                        )
-import CoreUtils       ( unTagBinders )
-import Id              ( getIdStrictness, idType, getIdUnfolding,
-                         getDataConSig, getInstantiatedDataConSig,
-                         DataCon(..), isBottomingId
+import MagicUFs                ( MagicUnfoldingFun )
+import Maybes          ( maybeToBool )
+import Outputable      ( Outputable(..){-instance * []-} )
+import PprStyle                ( PprStyle(..) )
+import PrelInfo                ( intTyCon, integerTyCon, doubleTyCon,
+                         floatTyCon, wordTyCon, addrTyCon
                        )
                        )
-import IdInfo          -- various bits
-import Maybes          ( maybeToBool, Maybe(..) )
+import Pretty          ( ppStr )
+import PrimOp          ( PrimOp(..) )
 import SaLib
 import SaLib
-import Util
+import TyCon           ( maybeTyConSingleCon, isEnumerationTyCon,
+                         TyCon{-instance Eq-}
+                       )
+import Type            ( maybeAppDataTyCon, isPrimType )
+import Util            ( isIn, isn'tIn, nOfThem, zipWithEqual,
+                         pprTrace, panic, pprPanic, assertPanic
+                       )
+
+getInstantiatedDataConSig = panic "SaAbsInt.getInstantiatedDataConSig (ToDo)"
+returnsRealWorld = panic "SaAbsInt.returnsRealWorld (ToDo)"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -390,7 +397,7 @@ absId anal var env
        (Nothing, NoStrictnessInfo, LitForm _) ->
                        AbsTop  -- Literals all terminate, and have no poison
 
        (Nothing, NoStrictnessInfo, LitForm _) ->
                        AbsTop  -- Literals all terminate, and have no poison
 
-       (Nothing, NoStrictnessInfo, ConForm _ _ _) ->
+       (Nothing, NoStrictnessInfo, ConForm _ _) ->
                        AbsTop -- An imported constructor won't have
                               -- bottom components, nor poison!
 
                        AbsTop -- An imported constructor won't have
                               -- bottom components, nor poison!
 
@@ -474,12 +481,13 @@ Things are a little different for absence analysis, because we want
 to make sure that any poison (?????)
 
 \begin{code}
 to make sure that any poison (?????)
 
 \begin{code}
-absEval StrAnal (Prim SeqOp [t] [e]) env
-  = if isBot (absEvalAtom StrAnal e env) then AbsBot else AbsTop
+absEval StrAnal (Prim SeqOp [TyArg _, e]) env
+  = ASSERT(isValArg e)
+    if isBot (absEvalAtom StrAnal e env) then AbsBot else AbsTop
        -- This is a special case to ensure that seq# is strict in its argument.
        -- The comments below (for most normal PrimOps) do not apply.
 
        -- This is a special case to ensure that seq# is strict in its argument.
        -- The comments below (for most normal PrimOps) do not apply.
 
-absEval StrAnal (Prim op ts es) env = AbsTop
+absEval StrAnal (Prim op es) env = AbsTop
        -- The arguments are all of unboxed type, so they will already
        -- have been eval'd.  If the boxed version was bottom, we'll
        -- already have returned bottom.
        -- The arguments are all of unboxed type, so they will already
        -- have been eval'd.  If the boxed version was bottom, we'll
        -- already have returned bottom.
@@ -490,15 +498,15 @@ absEval StrAnal (Prim op ts es) env = AbsTop
        -- uses boxed args and we don't know whether or not it's
        -- strict, so we assume laziness. (JSM)
 
        -- uses boxed args and we don't know whether or not it's
        -- strict, so we assume laziness. (JSM)
 
-absEval AbsAnal (Prim op ts as) env
-  = if any anyBot [absEvalAtom AbsAnal a env | a <- as]
+absEval AbsAnal (Prim op as) env
+  = if any anyBot [absEvalAtom AbsAnal a env | a <- as, isValArg a]
     then AbsBot
     else AbsTop
        -- For absence analysis, we want to see if the poison shows up...
 
     then AbsBot
     else AbsTop
        -- For absence analysis, we want to see if the poison shows up...
 
-absEval anal (Con con ts as) env
+absEval anal (Con con as) env
   | has_single_con
   | has_single_con
-  = AbsProd [absEvalAtom anal a env | a <- as]
+  = AbsProd [absEvalAtom anal a env | a <- as, isValArg a]
 
   | otherwise  -- Not single-constructor
   = case anal of
 
   | otherwise  -- Not single-constructor
   = case anal of
@@ -507,22 +515,22 @@ absEval anal (Con con ts as) env
        AbsAnal ->      -- In the absence case we need to be more
                        -- careful: look to see if there's any
                        -- poison in the components
        AbsAnal ->      -- In the absence case we need to be more
                        -- careful: look to see if there's any
                        -- poison in the components
-                  if any anyBot [absEvalAtom AbsAnal a env | a <- as]
+                  if any anyBot [absEvalAtom AbsAnal a env | a <- as, isValArg a]
                   then AbsBot
                   else AbsTop
   where
                   then AbsBot
                   else AbsTop
   where
-    (_,_,_, tycon) = getDataConSig con
-    has_single_con = maybeToBool (maybeSingleConstructorTyCon tycon)
+    (_,_,_, tycon) = dataConSig con
+    has_single_con = maybeToBool (maybeTyConSingleCon tycon)
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-absEval anal (Lam binder body) env
+absEval anal (Lam (ValBinder binder) body) env
   = AbsFun [binder] body env
   = AbsFun [binder] body env
-absEval anal (CoTyLam ty expr) env
+absEval anal (Lam other_binder expr) env
   = absEval  anal expr env
   = absEval  anal expr env
-absEval anal (App e1 e2) env
-  = absApply anal (absEval anal e1 env) (absEvalAtom anal e2 env)
-absEval anal (CoTyApp expr ty) env
+absEval anal (App f a) env | isValArg a
+  = absApply anal (absEval anal f env) (absEvalAtom anal a env)
+absEval anal (App expr _) env
   = absEval anal expr env
 \end{code}
 
   = absEval anal expr env
 \end{code}
 
index c4b7797..ef42acd 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
 %
 \section[SaLib]{Basic datatypes, functions for the strictness analyser}
 
 %
 \section[SaLib]{Basic datatypes, functions for the strictness analyser}
 
@@ -16,13 +16,19 @@ module SaLib (
        nullAbsValEnv, addOneToAbsValEnv, growAbsValEnvList,
        lookupAbsValEnv,
        absValFromStrictness
        nullAbsValEnv, addOneToAbsValEnv, growAbsValEnvList,
        lookupAbsValEnv,
        absValFromStrictness
-
-       -- and to make the interface self-sufficient...
     ) where
 
     ) where
 
-import IdInfo
-import Outputable
-import Pretty
+import Ubiq{-uitous-}
+
+import CoreSyn         ( CoreExpr(..) )
+import Id              ( nullIdEnv, addOneToIdEnv, growIdEnvList,
+                         lookupIdEnv, IdEnv(..),
+                         GenId{-instance Outputable-}
+                       )
+import IdInfo          ( StrictnessInfo(..), Demand{-instance Outputable-} )
+import Outputable      ( Outputable(..){-instance * []-} )
+import PprType         ( GenType{-instance Outputable-} )
+import Pretty          ( ppStr, ppCat )
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index 6605d26..dc9926d 100644 (file)
@@ -11,16 +11,31 @@ Semantique analyser) was written by Andy Gill.
 
 module StrictAnal ( saWwTopBinds, saTopBinds ) where
 
 
 module StrictAnal ( saWwTopBinds, saTopBinds ) where
 
-import Id              ( addIdDemandInfo, isWrapperId, addIdStrictness,
-                         idType, getIdDemandInfo
+import Ubiq{-uitous-}
+
+import CmdLineOpts     ( opt_AllStrict, opt_NumbersStrict,
+                         opt_D_dump_stranal, opt_D_simplifier_stats
+                       )
+import CoreSyn
+import Id              ( idType, addIdStrictness,
+                         getIdDemandInfo, addIdDemandInfo,
+                         GenId{-instance Outputable-}
+                       )
+import IdInfo          ( mkStrictnessInfo, mkBottomStrictnessInfo,
+                         mkDemandInfo, willBeDemanded, DemandInfo
                        )
                        )
-import IdInfo
+import PprCore         ( pprCoreBinding, pprBigCoreBinder )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( GenType{-instance Outputable-}, GenTyVar{-ditto-} )
+import Pretty          ( ppBesides, ppStr, ppInt, ppChar, ppAboves )
 import SaAbsInt
 import SaLib
 import SaAbsInt
 import SaLib
-import UniqSupply
-import Util
+import TyVar           ( GenTyVar{-instance Eq-} )
 import WorkWrap                -- "back-end" of strictness analyser
 import WorkWrap                -- "back-end" of strictness analyser
-import WwLib           ( WwM(..) )
+import Unique          ( Unique{-instance Eq -} )
+import Util            ( zipWith4Equal, pprTrace, panic{-ToDo:rm-} )
+
+isWrapperId = panic "StrictAnal.isWrapperId (ToDo)"
 \end{code}
 
 
 \end{code}
 
 
@@ -72,13 +87,12 @@ Alas and alack.
 
 \begin{code}
 saWwTopBinds :: UniqSupply
 
 \begin{code}
 saWwTopBinds :: UniqSupply
-            -> (GlobalSwitch -> Bool)
             -> [CoreBinding]
             -> [CoreBinding]
 
             -> [CoreBinding]
             -> [CoreBinding]
 
-saWwTopBinds us switch_chker binds
+saWwTopBinds us binds
   = let
   = let
-       strflags = (switch_chker AllStrict, switch_chker NumbersStrict)
+       strflags = (opt_AllStrict, opt_NumbersStrict)
 
        -- mark each binder with its strictness
 #ifndef OMIT_STRANAL_STATS
 
        -- mark each binder with its strictness
 #ifndef OMIT_STRANAL_STATS
@@ -90,13 +104,13 @@ saWwTopBinds us switch_chker binds
 #endif
     in
     -- possibly show what we decided about strictness...
 #endif
     in
     -- possibly show what we decided about strictness...
-    (if switch_chker D_dump_stranal
+    (if opt_D_dump_stranal
      then pprTrace "Strictness:\n" (ppAboves (
      then pprTrace "Strictness:\n" (ppAboves (
-          map (pprCoreBinding PprDebug pprBigCoreBinder pprBigCoreBinder ppr) binds_w_strictness))
+          map (pprCoreBinding PprDebug)  binds_w_strictness))
      else id
     )
     -- possibly show how many things we marked as demanded...
      else id
     )
     -- possibly show how many things we marked as demanded...
-    ((if switch_chker D_simplifier_stats
+    ((if opt_D_simplifier_stats
 #ifndef OMIT_STRANAL_STATS
      then pp_stats sa_stats
 #else
 #ifndef OMIT_STRANAL_STATS
      then pp_stats sa_stats
 #else
@@ -107,7 +121,7 @@ saWwTopBinds us switch_chker binds
        -- create worker/wrappers, and mark binders with their
        -- "strictness info" [which encodes their
        -- worker/wrapper-ness]
        -- create worker/wrappers, and mark binders with their
        -- "strictness info" [which encodes their
        -- worker/wrapper-ness]
-    (workersAndWrappers binds_w_strictness us switch_chker))
+    (workersAndWrappers binds_w_strictness us))
 #ifndef OMIT_STRANAL_STATS
   where
     pp_stats (SaStats tlam dlam tc dc tlet dlet)
 #ifndef OMIT_STRANAL_STATS
   where
     pp_stats (SaStats tlam dlam tc dc tlet dlet)
@@ -232,31 +246,27 @@ environment.
 \begin{code}
 saExpr :: StrictEnv -> AbsenceEnv -> CoreExpr -> SaM CoreExpr
 
 \begin{code}
 saExpr :: StrictEnv -> AbsenceEnv -> CoreExpr -> SaM CoreExpr
 
-saExpr _ _ e@(Var _)      = returnSa e
-saExpr _ _ e@(Lit _)      = returnSa e
-saExpr _ _ e@(Con _ _ _)  = returnSa e
-saExpr _ _ e@(Prim _ _ _) = returnSa e
+saExpr _ _ e@(Var _)   = returnSa e
+saExpr _ _ e@(Lit _)   = returnSa e
+saExpr _ _ e@(Con  _ _)        = returnSa e
+saExpr _ _ e@(Prim _ _)        = returnSa e
 
 
-saExpr str_env abs_env (Lam arg body)
+saExpr str_env abs_env (Lam (ValBinder arg) body)
   = saExpr str_env abs_env body        `thenSa` \ new_body ->
     let
        new_arg = addDemandInfoToId str_env abs_env body arg
     in
     tickLambda new_arg `thenSa_` -- stats
   = saExpr str_env abs_env body        `thenSa` \ new_body ->
     let
        new_arg = addDemandInfoToId str_env abs_env body arg
     in
     tickLambda new_arg `thenSa_` -- stats
-    returnSa (Lam new_arg new_body)
+    returnSa (Lam (ValBinder new_arg) new_body)
 
 
-saExpr str_env abs_env (CoTyLam ty expr)
+saExpr str_env abs_env (Lam other_binder expr)
   = saExpr str_env abs_env expr        `thenSa` \ new_expr ->
   = saExpr str_env abs_env expr        `thenSa` \ new_expr ->
-    returnSa (CoTyLam ty new_expr)
+    returnSa (Lam other_binder new_expr)
 
 saExpr str_env abs_env (App fun arg)
   = saExpr str_env abs_env fun `thenSa` \ new_fun ->
     returnSa (App new_fun arg)
 
 
 saExpr str_env abs_env (App fun arg)
   = saExpr str_env abs_env fun `thenSa` \ new_fun ->
     returnSa (App new_fun arg)
 
-saExpr str_env abs_env (CoTyApp expr ty)
-  = saExpr str_env abs_env expr        `thenSa` \ new_expr ->
-    returnSa (CoTyApp new_expr ty)
-
 saExpr str_env abs_env (SCC cc expr)
   = saExpr str_env abs_env expr        `thenSa` \ new_expr ->
     returnSa (SCC cc new_expr)
 saExpr str_env abs_env (SCC cc expr)
   = saExpr str_env abs_env expr        `thenSa` \ new_expr ->
     returnSa (SCC cc new_expr)
@@ -447,7 +457,7 @@ returnSa      :: a -> SaM a
 {-# INLINE thenSa_ #-}
 {-# INLINE returnSa #-}
 
 {-# INLINE thenSa_ #-}
 {-# INLINE returnSa #-}
 
-tickLambda :: [Id] -> SaM ()
+tickLambda :: Id   -> SaM ()
 tickCases  :: [Id] -> SaM ()
 tickLet    :: Id   -> SaM ()
 
 tickCases  :: [Id] -> SaM ()
 tickLet    :: Id   -> SaM ()
 
@@ -465,7 +475,7 @@ thenSa_ expr cont stats
 returnSa x stats = (x, stats)
 
 tickLambda var (SaStats tlam dlam tc dc tlet dlet)
 returnSa x stats = (x, stats)
 
 tickLambda var (SaStats tlam dlam tc dc tlet dlet)
-  = case (tick_demanded (0,0) var) of { (IBOX(tot), IBOX(demanded)) ->
+  = case (tick_demanded var (0,0)) of { (IBOX(tot), IBOX(demanded)) ->
     ((), SaStats (tlam _ADD_ tot) (dlam _ADD_ demanded) tc dc tlet dlet) }
 
 tickCases vars (SaStats tlam dlam tc dc tlet dlet)
     ((), SaStats (tlam _ADD_ tot) (dlam _ADD_ demanded) tc dc tlet dlet) }
 
 tickCases vars (SaStats tlam dlam tc dc tlet dlet)
index a82579d..4a7b076 100644 (file)
@@ -1,5 +1,5 @@
 %
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
 %
 \section[WorkWrap]{Worker/wrapper-generating back-end of strictness analyser}
 
 %
 \section[WorkWrap]{Worker/wrapper-generating back-end of strictness analyser}
 
@@ -8,20 +8,24 @@
 
 module WorkWrap ( workersAndWrappers ) where
 
 
 module WorkWrap ( workersAndWrappers ) where
 
-IMPORT_Trace
-import Outputable
-import Pretty
+import Ubiq{-uitous-}
 
 
-import Id              ( idType, addIdStrictness, getIdStrictness,
-                         getIdUnfolding, mkWorkerId,
-                         replaceIdInfo, getIdInfo, idWantsToBeINLINEd
+import CoreSyn
+import CoreUnfold      ( UnfoldingGuidance(..) )
+import CoreUtils       ( coreExprType )
+import Id              ( idWantsToBeINLINEd, getIdStrictness, mkWorkerId,
+                         getIdInfo
+                       )
+import IdInfo          ( noIdInfo, addInfo_UF, indicatesWorker,
+                         mkStrictnessInfo, StrictnessInfo(..)
                        )
                        )
-import IdInfo          -- bits and pieces
-import Maybes          ( maybeToBool, Maybe(..) )
 import SaLib
 import SaLib
-import SrcLoc          ( mkUnknownSrcLoc, SrcLoc )
-import Util
+import UniqSupply      ( returnUs, thenUs, mapUs, getUnique, UniqSM(..) )
 import WwLib
 import WwLib
+import Util            ( panic{-ToDo:rm-} )
+
+replaceIdInfo = panic "WorkWrap.replaceIdInfo (ToDo)"
+iWantToBeINLINEd = panic "WorkWrap.iWantToBeINLINEd (ToDo)"
 \end{code}
 
 We take Core bindings whose binders have their strictness attached (by
 \end{code}
 
 We take Core bindings whose binders have their strictness attached (by
@@ -37,14 +41,14 @@ info for exported values).
 \end{enumerate}
 
 \begin{code}
 \end{enumerate}
 
 \begin{code}
-workersAndWrappers :: [CoreBinding] -> WwM [CoreBinding]
+workersAndWrappers :: [CoreBinding] -> UniqSM [CoreBinding]
 
 workersAndWrappers top_binds
 
 workersAndWrappers top_binds
-  = mapWw (wwBind True{-top-level-}) top_binds `thenWw` \ top_binds2 ->
+  = mapUs (wwBind True{-top-level-}) top_binds `thenUs` \ top_binds2 ->
     let
        top_binds3 = map make_top_binding top_binds2
     in
     let
        top_binds3 = map make_top_binding top_binds2
     in
-    returnWw (concat top_binds3)
+    returnUs (concat top_binds3)
   where
     make_top_binding :: WwBinding -> [CoreBinding]
 
   where
     make_top_binding :: WwBinding -> [CoreBinding]
 
@@ -63,24 +67,24 @@ turn.  Non-recursive case first, then recursive...
 \begin{code}
 wwBind :: Bool                 -- True <=> top-level binding
        -> CoreBinding
 \begin{code}
 wwBind :: Bool                 -- True <=> top-level binding
        -> CoreBinding
-       -> WwM WwBinding        -- returns a WwBinding intermediate form;
+       -> UniqSM WwBinding     -- returns a WwBinding intermediate form;
                                -- the caller will convert to Expr/Binding,
                                -- as appropriate.
 
 wwBind top_level (NonRec binder rhs)
                                -- the caller will convert to Expr/Binding,
                                -- as appropriate.
 
 wwBind top_level (NonRec binder rhs)
-  = wwExpr rhs                 `thenWw` \ new_rhs ->
-    tryWW binder new_rhs       `thenWw` \ new_pairs ->
-    returnWw (WwLet [NonRec b e | (b,e) <- new_pairs])
+  = wwExpr rhs                 `thenUs` \ new_rhs ->
+    tryWW binder new_rhs       `thenUs` \ new_pairs ->
+    returnUs (WwLet [NonRec b e | (b,e) <- new_pairs])
       -- Generated bindings must be non-recursive
       -- because the original binding was.
 
 ------------------------------
 
 wwBind top_level (Rec pairs)
       -- Generated bindings must be non-recursive
       -- because the original binding was.
 
 ------------------------------
 
 wwBind top_level (Rec pairs)
-  = mapWw do_one pairs         `thenWw` \ new_pairs ->
-    returnWw (WwLet [Rec (concat new_pairs)])
+  = mapUs do_one pairs         `thenUs` \ new_pairs ->
+    returnUs (WwLet [Rec (concat new_pairs)])
   where
   where
-    do_one (binder, rhs) = wwExpr rhs  `thenWw` \ new_rhs ->
+    do_one (binder, rhs) = wwExpr rhs  `thenUs` \ new_rhs ->
                           tryWW binder new_rhs
 \end{code}
 
                           tryWW binder new_rhs
 \end{code}
 
@@ -91,70 +95,62 @@ matching by looking for strict arguments of the correct type.
 ???????????????? ToDo
 
 \begin{code}
 ???????????????? ToDo
 
 \begin{code}
-wwExpr :: CoreExpr -> WwM CoreExpr
-
-wwExpr e@(Var _)       = returnWw e
-wwExpr e@(Lit _)       = returnWw e
-wwExpr e@(Con  _ _ _) = returnWw e
-wwExpr e@(Prim _ _ _) = returnWw e
-
-wwExpr (Lam binders expr)
-  = wwExpr expr                        `thenWw` \ new_expr ->
-    returnWw (Lam binders new_expr)
+wwExpr :: CoreExpr -> UniqSM CoreExpr
 
 
-wwExpr (CoTyLam ty expr)
-  = wwExpr expr                        `thenWw` \ new_expr ->
-    returnWw (CoTyLam ty new_expr)
+wwExpr e@(Var _)    = returnUs e
+wwExpr e@(Lit _)    = returnUs e
+wwExpr e@(Con  _ _) = returnUs e
+wwExpr e@(Prim _ _) = returnUs e
 
 
-wwExpr (App e1 e2)
-  = wwExpr e1                  `thenWw` \ new_e1 ->
-    returnWw (App new_e1 e2)
+wwExpr (Lam binder expr)
+  = wwExpr expr                        `thenUs` \ new_expr ->
+    returnUs (Lam binder new_expr)
 
 
-wwExpr (CoTyApp expr ty)
-  = wwExpr expr                        `thenWw` \ new_expr ->
-    returnWw (CoTyApp new_expr ty)
+wwExpr (App f a)
+  = wwExpr f                   `thenUs` \ new_f ->
+    returnUs (App new_f a)
 
 wwExpr (SCC cc expr)
 
 wwExpr (SCC cc expr)
-  = wwExpr expr                        `thenWw` \ new_expr ->
-    returnWw (SCC cc new_expr)
+  = wwExpr expr                        `thenUs` \ new_expr ->
+    returnUs (SCC cc new_expr)
 
 wwExpr (Let bind expr)
 
 wwExpr (Let bind expr)
-  = wwBind False{-not top-level-} bind `thenWw` \ intermediate_bind ->
-    wwExpr expr                                `thenWw` \ new_expr ->
-    returnWw (mash_ww_bind intermediate_bind new_expr)
+  = wwBind False{-not top-level-} bind `thenUs` \ intermediate_bind ->
+    wwExpr expr                                `thenUs` \ new_expr ->
+    returnUs (mash_ww_bind intermediate_bind new_expr)
   where
     mash_ww_bind (WwLet  binds)   body = mkCoLetsNoUnboxed binds body
     mash_ww_bind (WwCase case_fn) body = case_fn body
 
 wwExpr (Case expr alts)
   where
     mash_ww_bind (WwLet  binds)   body = mkCoLetsNoUnboxed binds body
     mash_ww_bind (WwCase case_fn) body = case_fn body
 
 wwExpr (Case expr alts)
-  = wwExpr expr                                `thenWw` \ new_expr ->
-    ww_alts alts                       `thenWw` \ new_alts ->
-    returnWw (Case new_expr new_alts)
+  = wwExpr expr                                `thenUs` \ new_expr ->
+    ww_alts alts                       `thenUs` \ new_alts ->
+    returnUs (Case new_expr new_alts)
   where
     ww_alts (AlgAlts alts deflt)
   where
     ww_alts (AlgAlts alts deflt)
-      = mapWw ww_alg_alt alts          `thenWw` \ new_alts ->
-       ww_deflt deflt                  `thenWw` \ new_deflt ->
-       returnWw (AlgAlts new_alts new_deflt)
+      = mapUs ww_alg_alt alts          `thenUs` \ new_alts ->
+       ww_deflt deflt                  `thenUs` \ new_deflt ->
+       returnUs (AlgAlts new_alts new_deflt)
 
     ww_alts (PrimAlts alts deflt)
 
     ww_alts (PrimAlts alts deflt)
-      = mapWw ww_prim_alt alts         `thenWw` \ new_alts ->
-       ww_deflt deflt                  `thenWw` \ new_deflt ->
-       returnWw (PrimAlts new_alts new_deflt)
+      = mapUs ww_prim_alt alts         `thenUs` \ new_alts ->
+       ww_deflt deflt                  `thenUs` \ new_deflt ->
+       returnUs (PrimAlts new_alts new_deflt)
 
     ww_alg_alt (con, binders, rhs)
 
     ww_alg_alt (con, binders, rhs)
-      =        wwExpr rhs                      `thenWw` \ new_rhs ->
-       returnWw (con, binders, new_rhs)
+      =        wwExpr rhs                      `thenUs` \ new_rhs ->
+       returnUs (con, binders, new_rhs)
 
     ww_prim_alt (lit, rhs)
 
     ww_prim_alt (lit, rhs)
-      = wwExpr rhs                     `thenWw` \ new_rhs ->
-       returnWw (lit, new_rhs)
+      = wwExpr rhs                     `thenUs` \ new_rhs ->
+       returnUs (lit, new_rhs)
 
     ww_deflt NoDefault
 
     ww_deflt NoDefault
-      = returnWw NoDefault
+      = returnUs NoDefault
 
     ww_deflt (BindDefault binder rhs)
 
     ww_deflt (BindDefault binder rhs)
-      = wwExpr rhs                     `thenWw` \ new_rhs ->
-       returnWw (BindDefault binder new_rhs)
+      = wwExpr rhs                     `thenUs` \ new_rhs ->
+       returnUs (BindDefault binder new_rhs)
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -179,7 +175,7 @@ The only reason this is monadised is for the unique supply.
 tryWW  :: Id                           -- the fn binder
        -> CoreExpr             -- the bound rhs; its innards
                                        --   are already ww'd
 tryWW  :: Id                           -- the fn binder
        -> CoreExpr             -- the bound rhs; its innards
                                        --   are already ww'd
-       -> WwM [(Id, CoreExpr)] -- either *one* or *two* pairs;
+       -> UniqSM [(Id, CoreExpr)]      -- either *one* or *two* pairs;
                                        -- if one, then no worker (only
                                        -- the orig "wrapper" lives on);
                                        -- if two, then a worker and a
                                        -- if one, then no worker (only
                                        -- the orig "wrapper" lives on);
                                        -- if two, then a worker and a
@@ -209,7 +205,7 @@ tryWW fn_id rhs
             (uvars, tyvars, args, body) = collectBinders rhs
             body_ty                     = coreExprType body
        in
             (uvars, tyvars, args, body) = collectBinders rhs
             body_ty                     = coreExprType body
        in
-       uniqSMtoWwM (mkWwBodies body_ty tyvars args args_info) `thenWw` \ result ->
+       mkWwBodies body_ty tyvars args args_info `thenUs` \ result ->
        case result of
 
          Nothing ->    -- Very peculiar. This can only happen if we hit an
        case result of
 
          Nothing ->    -- Very peculiar. This can only happen if we hit an
@@ -223,7 +219,7 @@ tryWW fn_id rhs
          Just (wrapper_w_hole, worker_w_hole, worker_strictness, worker_ty_w_hole) ->
 
                -- Terrific!  It worked!
          Just (wrapper_w_hole, worker_w_hole, worker_strictness, worker_ty_w_hole) ->
 
                -- Terrific!  It worked!
-           getUniqueWw         `thenWw` \ worker_uniq ->
+           getUnique           `thenUs` \ worker_uniq ->
            let
                worker_ty   = worker_ty_w_hole body_ty
 
            let
                worker_ty   = worker_ty_w_hole body_ty
 
@@ -246,8 +242,8 @@ tryWW fn_id rhs
                -- NB! the "iWantToBeINLINEd" part adds an INLINE pragma to
                -- the wrapper, which is of course what we want.
            in
                -- NB! the "iWantToBeINLINEd" part adds an INLINE pragma to
                -- the wrapper, which is of course what we want.
            in
-           returnWw [ (worker_id,  worker_rhs),   -- worker comes first
+           returnUs [ (worker_id,  worker_rhs),   -- worker comes first
                       (wrapper_id, wrapper_rhs) ] -- because wrapper mentions it
   where
                       (wrapper_id, wrapper_rhs) ] -- because wrapper mentions it
   where
-    do_nothing = returnWw [ (fn_id, rhs) ]
+    do_nothing = returnUs [ (fn_id, rhs) ]
 \end{code}
 \end{code}
index 4fa859a..4d1fa7a 100644 (file)
@@ -9,38 +9,24 @@
 module WwLib (
        WwBinding(..),
 
 module WwLib (
        WwBinding(..),
 
-       mkWwBodies, mAX_WORKER_ARGS,
-
-       -- our friendly worker/wrapper monad:
-       WwM(..),
-       returnWw, thenWw, mapWw,
-       getUniqueWw, uniqSMtoWwM
-
-       -- and to make the interface self-sufficient...
+       mkWwBodies, mAX_WORKER_ARGS
     ) where
 
 import Ubiq{-uitous-}
 
     ) where
 
 import Ubiq{-uitous-}
 
+import CoreSyn
+import Id              ( idType, mkSysLocal )
+import IdInfo          ( mkStrictnessInfo, nonAbsentArgs, Demand(..) )
 import PrelInfo                ( aBSENT_ERROR_ID )
 import PrelInfo                ( aBSENT_ERROR_ID )
-{-
-import Id              ( mkWorkerId, mkSysLocal, idType,
-                         getInstantiatedDataConSig, getIdInfo,
-                         replaceIdInfo, addIdStrictness, DataCon(..)
-                       )
-import IdInfo          -- lots of things
-import Maybes          ( maybeToBool, Maybe(..), MaybeErr )
-import SaLib
 import SrcLoc          ( mkUnknownSrcLoc )
 import SrcLoc          ( mkUnknownSrcLoc )
-import Type            ( mkTyVarTys, mkFunTys, isPrimType,
-                         maybeAppDataTyCon, quantifyTy
+import Type            ( isPrimType, mkTyVarTys, mkFunTys, maybeAppDataTyCon )
+import UniqSupply      ( returnUs, thenUs, thenMaybeUs,
+                         getUniques, UniqSM(..)
                        )
                        )
-import UniqSupply
--}
-import Util            ( panic )
-
-infixr 9 `thenWw`
+import Util            ( zipWithEqual, assertPanic, panic )
 
 quantifyTy = panic "WwLib.quantifyTy"
 
 quantifyTy = panic "WwLib.quantifyTy"
+getInstantiatedDataConSig = panic "WwLib.getInstantiatedDataConSig"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -221,7 +207,7 @@ mkWwBodies body_ty tyvars args arg_infos
 
     else -- the rest...
     mk_ww_arg_processing args arg_infos (mAX_WORKER_ARGS - nonAbsentArgs arg_infos)
 
     else -- the rest...
     mk_ww_arg_processing args arg_infos (mAX_WORKER_ARGS - nonAbsentArgs arg_infos)
-               `thenUsMaybe` \ (wrap_frag, work_args_info, work_frag) ->
+               `thenMaybeUs` \ (wrap_frag, work_args_info, work_frag) ->
     let
        (work_args, wrkr_demands) = unzip work_args_info
 
     let
        (work_args, wrkr_demands) = unzip work_args_info
 
@@ -230,7 +216,7 @@ mkWwBodies body_ty tyvars args arg_infos
        wrapper_w_hole = \ worker_id ->
                                mkLam tyvars args (
                                wrap_frag (
        wrapper_w_hole = \ worker_id ->
                                mkLam tyvars args (
                                wrap_frag (
-                               mkCoTyApps (Var worker_id) (mkTyVarTys tyvars)
+                               mkTyApp (Var worker_id) (mkTyVarTys tyvars)
                         ))
 
        worker_w_hole = \ orig_body ->
                         ))
 
        worker_w_hole = \ orig_body ->
@@ -302,7 +288,7 @@ mk_ww_arg_processing (arg : args) (WwLazy True : infos) max_extra_args
     mk_ww_arg_processing args infos max_extra_args
                                    -- we've already discounted for absent args,
                                    -- so we don't change max_extra_args
     mk_ww_arg_processing args infos max_extra_args
                                    -- we've already discounted for absent args,
                                    -- so we don't change max_extra_args
-                  `thenUsMaybe` \ (wrap_rest, work_args_info, work_rest) ->
+                  `thenMaybeUs` \ (wrap_rest, work_args_info, work_rest) ->
 
                        -- wrapper doesn't pass this arg to worker:
     returnUs (Just (
 
                        -- wrapper doesn't pass this arg to worker:
     returnUs (Just (
@@ -317,7 +303,7 @@ mk_ww_arg_processing (arg : args) (WwLazy True : infos) max_extra_args
   where
     mk_absent_let arg arg_ty body
       = if not (isPrimType arg_ty) then
   where
     mk_absent_let arg arg_ty body
       = if not (isPrimType arg_ty) then
-           Let (NonRec arg (mkCoTyApp (Var aBSENT_ERROR_ID) arg_ty)) body
+           Let (NonRec arg (mkTyApp (Var aBSENT_ERROR_ID) [arg_ty])) body
        else -- quite horrible
            panic "WwLib: haven't done mk_absent_let for primitives yet"
 
        else -- quite horrible
            panic "WwLib: haven't done mk_absent_let for primitives yet"
 
@@ -354,7 +340,7 @@ mk_ww_arg_processing (arg : args) (WwUnpack cmpnt_infos : infos) max_extra_args
                -- In processing the rest, push the sub-component args
                -- and infos on the front of the current bunch
            mk_ww_arg_processing (unpk_args ++ args) (cmpnt_infos ++ infos) new_max_extra_args
                -- In processing the rest, push the sub-component args
                -- and infos on the front of the current bunch
            mk_ww_arg_processing (unpk_args ++ args) (cmpnt_infos ++ infos) new_max_extra_args
-                       `thenUsMaybe` \ (wrap_rest, work_args_info, work_rest) ->
+                       `thenMaybeUs` \ (wrap_rest, work_args_info, work_rest) ->
 
            returnUs (Just (
              -- wrapper: unpack the value
 
            returnUs (Just (
              -- wrapper: unpack the value
@@ -383,7 +369,8 @@ mk_ww_arg_processing (arg : args) (WwUnpack cmpnt_infos : infos) max_extra_args
        )
 
     mk_pk_let arg boxing_con con_tys unpk_args body
        )
 
     mk_pk_let arg boxing_con con_tys unpk_args body
-      = Let (NonRec arg (Con boxing_con con_tys [VarArg a | a <- unpk_args]))
+      = Let (NonRec arg (Con boxing_con
+                           (map TyArg con_tys ++ map VarArg unpk_args)))
              body
 
 mk_ww_arg_processing (arg : args) (arg_demand : infos) max_extra_args
              body
 
 mk_ww_arg_processing (arg : args) (arg_demand : infos) max_extra_args
@@ -394,7 +381,7 @@ mk_ww_arg_processing (arg : args) (arg_demand : infos) max_extra_args
 
        -- Finish args to the right...
     mk_ww_arg_processing args infos max_extra_args
 
        -- Finish args to the right...
     mk_ww_arg_processing args infos max_extra_args
-                       `thenUsMaybe` \ (wrap_rest, work_args_info, work_rest) ->
+                       `thenMaybeUs` \ (wrap_rest, work_args_info, work_rest) ->
 
     returnUs (Just (
              -- wrapper:
 
     returnUs (Just (
              -- wrapper:
@@ -406,55 +393,3 @@ mk_ww_arg_processing (arg : args) (arg_demand : infos) max_extra_args
     ))
     --)
 \end{code}
     ))
     --)
 \end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[monad-WwLib]{Simple monad for worker/wrapper}
-%*                                                                     *
-%************************************************************************
-
-In this monad, we thread a @UniqueSupply@, and we carry a
-@GlobalSwitch@-lookup function downwards.
-
-\begin{code}
-type WwM result
-  =  UniqSupply
-  -> (GlobalSwitch -> Bool)
-  -> result
-
-{-# INLINE thenWw #-}
-{-# INLINE returnWw #-}
-
-returnWw :: a -> WwM a
-thenWw  :: WwM a -> (a -> WwM b) -> WwM b
-mapWw   :: (a -> WwM b) -> [a] -> WwM [b]
-
-returnWw expr ns sw = expr
-
-thenWw m k us sw_chk
-  = case splitUniqSupply us    of { (s1, s2) ->
-    case (m s1 sw_chk)         of { m_res ->
-    k m_res s2 sw_chk }}
-
-mapWw f []     = returnWw []
-mapWw f (x:xs)
-  = f x                `thenWw` \ x'  ->
-    mapWw f xs `thenWw` \ xs' ->
-    returnWw (x':xs')
-\end{code}
-
-\begin{code}
-getUniqueWw :: WwM Unique
-uniqSMtoWwM :: UniqSM a -> WwM a
-
-getUniqueWw us sw_chk = getUnique us
-
-uniqSMtoWwM u_obj us sw_chk = u_obj us
-
-thenUsMaybe :: UniqSM (Maybe a) -> (a -> UniqSM (Maybe b)) -> UniqSM (Maybe b)
-thenUsMaybe m k
-  = m  `thenUs` \ result ->
-    case result of
-      Nothing -> returnUs Nothing
-      Just x  -> k x
-\end{code}
index 27e4a00..438e59a 100644 (file)
@@ -9,8 +9,7 @@
 module GenSpecEtc (
        TcSigInfo(..), 
        genBinds, 
 module GenSpecEtc (
        TcSigInfo(..), 
        genBinds, 
-       checkSigTyVars, checkSigTyVarsGivenGlobals,
-       specTy
+       checkSigTyVars, checkSigTyVarsGivenGlobals
     ) where
 
 import Ubiq
     ) where
 
 import Ubiq
@@ -26,7 +25,7 @@ import TcType         ( TcType(..), TcThetaType(..), TcTauType(..),
 import HsSyn           ( HsBinds(..), Bind(..), MonoBinds(..), HsExpr, OutPat(..), 
                          Sig, HsLit, ArithSeqInfo, InPat, GRHSsAndBinds, Match, Fake
                        )
 import HsSyn           ( HsBinds(..), Bind(..), MonoBinds(..), HsExpr, OutPat(..), 
                          Sig, HsLit, ArithSeqInfo, InPat, GRHSsAndBinds, Match, Fake
                        )
-import TcHsSyn         ( TcIdOcc(..), TcIdBndr(..), TcHsBinds(..), TcBind(..), TcExpr(..) )
+import TcHsSyn         ( TcIdOcc(..), TcIdBndr(..), TcHsBinds(..), TcBind(..), TcExpr(..),                                    tcIdType )
 
 import Bag             ( Bag, foldBag, bagToList, listToBag, isEmptyBag )
 import Class           ( GenClass )
 
 import Bag             ( Bag, foldBag, bagToList, listToBag, isEmptyBag )
 import Class           ( GenClass )
@@ -155,7 +154,7 @@ genBinds binder_names mono_ids bind lie sig_infos prag_info_fn
         -- BUILD THE NEW LOCALS
     let
        tyvars      = tyVarSetToList reduced_tyvars_to_gen      -- Commit to a particular order
         -- BUILD THE NEW LOCALS
     let
        tyvars      = tyVarSetToList reduced_tyvars_to_gen      -- Commit to a particular order
-       dict_tys    = [idType d | TcId d <- dicts_bound]        -- Slightly ugh-ish
+       dict_tys    = map tcIdType dicts_bound
        poly_tys    = map (mkForAllTys tyvars . mkFunTys dict_tys) mono_id_types
        poly_ids    = zipWithEqual mk_poly binder_names poly_tys
        mk_poly name ty = mkUserId name ty (prag_info_fn name)
        poly_tys    = map (mkForAllTys tyvars . mkFunTys dict_tys) mono_id_types
        poly_ids    = zipWithEqual mk_poly binder_names poly_tys
        mk_poly name ty = mkUserId name ty (prag_info_fn name)
@@ -282,12 +281,12 @@ The error message here is somewhat unsatisfactory, but it'll do for
 now (ToDo).
 
 \begin{code}
 now (ToDo).
 
 \begin{code}
-checkSigMatch :: TcSigInfo s -> TcM s [TcTyVar s]
+checkSigMatch :: TcSigInfo s -> TcM s ()
 
 checkSigMatch (TySigInfo id sig_tyvars _ tau_ty src_loc)
   = tcAddSrcLoc src_loc        $
     tcAddErrCtxt (sigCtxt id) $
 
 checkSigMatch (TySigInfo id sig_tyvars _ tau_ty src_loc)
   = tcAddSrcLoc src_loc        $
     tcAddErrCtxt (sigCtxt id) $
-    checkSigTyVars sig_tyvars tau_ty (idType id)
+    checkSigTyVars sig_tyvars tau_ty
 \end{code}
 
 
 \end{code}
 
 
@@ -337,6 +336,8 @@ are
                eg matching signature [(a,b)] against inferred type [(p,p)]
                [then a and b will be unified together]
 
                eg matching signature [(a,b)] against inferred type [(p,p)]
                [then a and b will be unified together]
 
+BUT ACTUALLY THESE FIRST TWO ARE FORCED BY USING DontBind TYVARS
+
        (c) not mentioned in the environment
                eg the signature for f in this:
 
        (c) not mentioned in the environment
                eg the signature for f in this:
 
@@ -351,71 +352,30 @@ Before doing this, the substitution is applied to the signature type variable.
 \begin{code}
 checkSigTyVars :: [TcTyVar s]          -- The original signature type variables
               -> TcType s              -- signature type (for err msg)
 \begin{code}
 checkSigTyVars :: [TcTyVar s]          -- The original signature type variables
               -> TcType s              -- signature type (for err msg)
-              -> TcType s              -- inferred type (for err msg)
-              -> TcM s [TcTyVar s]     -- Post-substitution signature type variables
+              -> TcM s ()
 
 
-checkSigTyVars sig_tyvars sig_tau inferred_tau
+checkSigTyVars sig_tyvars sig_tau
   = tcGetGlobalTyVars                  `thenNF_Tc` \ env_tyvars ->
   = tcGetGlobalTyVars                  `thenNF_Tc` \ env_tyvars ->
-    checkSigTyVarsGivenGlobals env_tyvars sig_tyvars sig_tau inferred_tau
+    checkSigTyVarsGivenGlobals env_tyvars sig_tyvars sig_tau
 
 checkSigTyVarsGivenGlobals
         :: TcTyVarSet s        -- Consider these fully-zonked tyvars as global
         -> [TcTyVar s]         -- The original signature type variables
         -> TcType s            -- signature type (for err msg)
 
 checkSigTyVarsGivenGlobals
         :: TcTyVarSet s        -- Consider these fully-zonked tyvars as global
         -> [TcTyVar s]         -- The original signature type variables
         -> TcType s            -- signature type (for err msg)
-        -> TcType s            -- inferred type (for err msg)
-        -> TcM s [TcTyVar s]   -- Post-substitution signature type variables
-
-checkSigTyVarsGivenGlobals globals sig_tyvars sig_tau inferred_tau
-  =     -- Check point (a) above
-    mapNF_Tc (zonkTcType.mkTyVarTy) sig_tyvars                         `thenNF_Tc` \ sig_tys ->
-    checkMaybeTcM (allMaybes (map getTyVar_maybe sig_tys)) match_err   `thenTc` \ sig_tyvars' ->
-
-        -- Check point (b)
-    checkTcM (hasNoDups sig_tyvars') match_err         `thenTc_`
+        -> TcM s ()
 
 
-       -- Check point (c)
+checkSigTyVarsGivenGlobals globals sig_tyvars sig_tau
+  =    -- Check point (c)
        -- We want to report errors in terms of the original signature tyvars,
        -- ie sig_tyvars, NOT sig_tyvars'.  sig_tys and sig_tyvars' correspond
        -- 1-1 with sig_tyvars, so we can just map back.
        -- We want to report errors in terms of the original signature tyvars,
        -- ie sig_tyvars, NOT sig_tyvars'.  sig_tys and sig_tyvars' correspond
        -- 1-1 with sig_tyvars, so we can just map back.
-    let
-       mono_tyvars = [ sig_tyvar
-                     | (sig_tyvar,sig_tyvar') <- zipEqual sig_tyvars sig_tyvars',
-                       sig_tyvar' `elementOfTyVarSet` globals
-                     ]
-    in
     checkTc (null mono_tyvars)
     checkTc (null mono_tyvars)
-           (notAsPolyAsSigErr sig_tau mono_tyvars)     `thenTc_`
-
-    returnTc sig_tyvars'
+           (notAsPolyAsSigErr sig_tau mono_tyvars)
   where
   where
-    match_err = zonkTcType inferred_tau        `thenNF_Tc` \ inferred_tau' ->
-               failTc (badMatchErr sig_tau inferred_tau')
+    mono_tyvars = filter (`elementOfTyVarSet` globals) sig_tyvars
 \end{code}
 
 
 \end{code}
 
 
-%************************************************************************
-%*                                                                     *
-\subsection[GenEtc-SpecTy]{Instantiate a type and create new dicts for it}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-specTy :: InstOrigin s
-       -> Type
-       -> NF_TcM s ([TcTyVar s], LIE s, TcType s, [TcIdOcc s])
-
-specTy origin sigma_ty
-  = tcInstType [] sigma_ty             `thenNF_Tc` \ tc_sigma_ty ->
-    let
-       (tyvars, theta, tau) = splitSigmaTy tc_sigma_ty
-    in
-        -- Instantiate the dictionary types
-    newDicts origin theta              `thenNF_Tc` \ (dicts, dict_ids) ->
-
-        -- Return the list of tyvars, the list of dicts and the tau type
-    returnNF_Tc (tyvars, dicts, tau, dict_ids)
-\end{code}
-
 
 
 Contexts and errors
 
 
 Contexts and errors
index 7ad462e..e4a9584 100644 (file)
@@ -10,7 +10,7 @@ module Inst (
        Inst(..),       -- Visible only to TcSimplify
 
        InstOrigin(..), OverloadedLit(..),
        Inst(..),       -- Visible only to TcSimplify
 
        InstOrigin(..), OverloadedLit(..),
-       LIE(..), emptyLIE, unitLIE, plusLIE, consLIE, zonkLIE,
+       LIE(..), emptyLIE, unitLIE, plusLIE, consLIE, zonkLIE, plusLIEs,
 
         InstanceMapper(..),
 
 
         InstanceMapper(..),
 
@@ -41,7 +41,7 @@ import TcEnv  ( tcLookupGlobalValueByKey )
 import TcType  ( TcType(..), TcRhoType(..), TcMaybe, TcTyVarSet(..),
                  tcInstType, tcInstTcType, zonkTcType )
 
 import TcType  ( TcType(..), TcRhoType(..), TcMaybe, TcTyVarSet(..),
                  tcInstType, tcInstTcType, zonkTcType )
 
-import Bag     ( Bag, emptyBag, unitBag, unionBags, listToBag, consBag )
+import Bag     ( emptyBag, unitBag, unionBags, unionManyBags, listToBag, consBag )
 import Class   ( Class(..), GenClass, ClassInstEnv(..), getClassInstEnv )
 import Id      ( GenId, idType, mkInstId )
 import MatchEnv        ( lookupMEnv, insertMEnv )
 import Class   ( Class(..), GenClass, ClassInstEnv(..), getClassInstEnv )
 import Id      ( GenId, idType, mkInstId )
 import MatchEnv        ( lookupMEnv, insertMEnv )
@@ -78,6 +78,7 @@ emptyLIE          = emptyBag
 unitLIE inst     = unitBag inst
 plusLIE lie1 lie2 = lie1 `unionBags` lie2
 consLIE inst lie  = inst `consBag` lie
 unitLIE inst     = unitBag inst
 plusLIE lie1 lie2 = lie1 `unionBags` lie2
 consLIE inst lie  = inst `consBag` lie
+plusLIEs lies    = unionManyBags lies
 
 zonkLIE :: LIE s -> NF_TcM s (LIE s)
 zonkLIE lie = mapBagNF_Tc zonkInst lie
 
 zonkLIE :: LIE s -> NF_TcM s (LIE s)
 zonkLIE lie = mapBagNF_Tc zonkInst lie
index 9ecbe7f..912a415 100644 (file)
@@ -182,7 +182,7 @@ tcBindAndSigs binder_names bind sigs prag_info_fn
        -- If typechecking the binds fails, then return with each
        -- binder given type (forall a.a), to minimise subsequent
        -- error messages
        -- If typechecking the binds fails, then return with each
        -- binder given type (forall a.a), to minimise subsequent
        -- error messages
-       newTcTyVar Nothing mkBoxedTypeKind              `thenNF_Tc` \ alpha_tv ->
+       newTcTyVar mkBoxedTypeKind              `thenNF_Tc` \ alpha_tv ->
        let
          forall_a_a = mkForAllTy alpha_tv (mkTyVarTy alpha_tv)
          poly_ids   = [ mkUserId name forall_a_a (prag_info_fn name)
        let
          forall_a_a = mkForAllTy alpha_tv (mkTyVarTy alpha_tv)
          poly_ids   = [ mkUserId name forall_a_a (prag_info_fn name)
@@ -271,13 +271,15 @@ tcTySigs :: [RenamedSig] -> TcM s [TcSigInfo s]
 tcTySigs (Sig v ty _ src_loc : other_sigs)
  = tcAddSrcLoc src_loc (
        tcPolyType ty                   `thenTc` \ sigma_ty ->
 tcTySigs (Sig v ty _ src_loc : other_sigs)
  = tcAddSrcLoc src_loc (
        tcPolyType ty                   `thenTc` \ sigma_ty ->
-       tcInstType [] sigma_ty          `thenNF_Tc` \ tc_sigma_ty ->
+       tcInstType [] sigma_ty          `thenNF_Tc` \ sigma_ty' ->
        let
        let
-           (tyvars, theta, tau_ty) = splitSigmaTy tc_sigma_ty
+           (tyvars', theta', tau') = splitSigmaTy sigma_ty'
        in
        in
+
        tcLookupLocalValueOK "tcSig1" v `thenNF_Tc` \ val ->
        tcLookupLocalValueOK "tcSig1" v `thenNF_Tc` \ val ->
-       unifyTauTy (idType val) tau_ty  `thenTc_`
-       returnTc (TySigInfo val tyvars theta tau_ty src_loc)
+       unifyTauTy (idType val) tau'    `thenTc_`
+
+       returnTc (TySigInfo val tyvars' theta' tau' src_loc)
    )           `thenTc` \ sig_info1 ->
 
    tcTySigs other_sigs `thenTc` \ sig_infos ->
    )           `thenTc` \ sig_info1 ->
 
    tcTySigs other_sigs `thenTc` \ sig_infos ->
@@ -386,7 +388,7 @@ tcPragmaSig (SpecSig name poly_ty maybe_spec_name src_loc)
 
        -- Get and instantiate its alleged specialised type
     tcPolyType poly_ty                         `thenTc` \ sig_sigma ->
 
        -- Get and instantiate its alleged specialised type
     tcPolyType poly_ty                         `thenTc` \ sig_sigma ->
-    tcInstType [] (idType sig_sigma)           `thenNF_Tc` \ sig_ty ->
+    tcInstType [] sig_sigma                    `thenNF_Tc` \ sig_ty ->
     let
        (sig_tyvars, sig_theta, sig_tau) = splitSigmaTy sig_ty
        origin = ValSpecOrigin name
     let
        (sig_tyvars, sig_theta, sig_tau) = splitSigmaTy sig_ty
        origin = ValSpecOrigin name
@@ -407,8 +409,8 @@ tcPragmaSig (SpecSig name poly_ty maybe_spec_name src_loc)
 
        -- Check that the specialised type is indeed an instance of
        -- the type of the main function.
 
        -- Check that the specialised type is indeed an instance of
        -- the type of the main function.
-    unifyTauTy sig_tau main_tau                        `thenTc_`
-    checkSigTyVars sig_tyvars sig_tau main_tau `thenTc_`
+    unifyTauTy sig_tau main_tau                `thenTc_`
+    checkSigTyVars sig_tyvars sig_tau  `thenTc_`
 
        -- Check that the type variables of the polymorphic function are
        -- either left polymorphic, or instantiate to ground type.
 
        -- Check that the type variables of the polymorphic function are
        -- either left polymorphic, or instantiate to ground type.
@@ -447,8 +449,8 @@ tcPragmaSig (SpecSig name poly_ty maybe_spec_name src_loc)
 
                -- Check that it has the correct type, and doesn't constrain the
                -- signature variables at all
 
                -- Check that it has the correct type, and doesn't constrain the
                -- signature variables at all
-       unifyTauTy sig_tau spec_tau                     `thenTc_`
-       checkSigTyVars sig_tyvars sig_tau spec_tau      `thenTc_`
+       unifyTauTy sig_tau spec_tau             `thenTc_`
+       checkSigTyVars sig_tyvars sig_tau       `thenTc_`
 
            -- Make a local SpecId to bind to applied spec_id
        newSpecId main_id main_arg_tys sig_ty   `thenNF_Tc` \ local_spec_id ->
 
            -- Make a local SpecId to bind to applied spec_id
        newSpecId main_id main_arg_tys sig_ty   `thenNF_Tc` \ local_spec_id ->
index 7bb5dc7..e5cb1f3 100644 (file)
@@ -24,13 +24,12 @@ import TcHsSyn              ( TcIdOcc(..), TcHsBinds(..), TcMonoBinds(..), TcExpr(..),
                          mkHsTyApp, mkHsTyLam, mkHsDictApp, mkHsDictLam, unZonkId )
 
 import TcMonad
                          mkHsTyApp, mkHsTyLam, mkHsDictApp, mkHsDictLam, unZonkId )
 
 import TcMonad
-import GenSpecEtc      ( specTy )
 import Inst            ( Inst, InstOrigin(..), LIE(..), emptyLIE, plusLIE, newDicts )
 import TcEnv           ( tcLookupClass, tcLookupTyVar, tcLookupTyCon, newLocalIds)
 import TcInstDcls      ( processInstBinds )
 import TcKind          ( unifyKind )
 import TcMonoType      ( tcMonoType, tcContext )
 import Inst            ( Inst, InstOrigin(..), LIE(..), emptyLIE, plusLIE, newDicts )
 import TcEnv           ( tcLookupClass, tcLookupTyVar, tcLookupTyCon, newLocalIds)
 import TcInstDcls      ( processInstBinds )
 import TcKind          ( unifyKind )
 import TcMonoType      ( tcMonoType, tcContext )
-import TcType          ( TcTyVar(..), tcInstType, tcInstTyVar )
+import TcType          ( TcType(..), TcTyVar(..), tcInstType, tcInstSigTyVars )
 import TcKind          ( TcKind )
 
 import Bag             ( foldBag )
 import TcKind          ( TcKind )
 
 import Bag             ( foldBag )
@@ -246,6 +245,11 @@ tcClassDecl2 :: RenamedClassDecl   -- The class declaration
 
 tcClassDecl2 (ClassDecl context class_name
                        tyvar_name class_sigs default_binds pragmas src_loc)
 
 tcClassDecl2 (ClassDecl context class_name
                        tyvar_name class_sigs default_binds pragmas src_loc)
+
+  | not (isLocallyDefined class_name)
+  = returnNF_Tc (emptyLIE, EmptyBinds)
+
+  | otherwise  -- It is locally defined
   = recoverNF_Tc (returnNF_Tc (emptyLIE, EmptyBinds)) $
     tcAddSrcLoc src_loc                                      $
 
   = recoverNF_Tc (returnNF_Tc (emptyLIE, EmptyBinds)) $
     tcAddSrcLoc src_loc                                      $
 
@@ -255,14 +259,14 @@ tcClassDecl2 (ClassDecl context class_name
        (tyvar, scs, sc_sel_ids, ops, op_sel_ids, defm_ids)
          = getClassBigSig clas
     in
        (tyvar, scs, sc_sel_ids, ops, op_sel_ids, defm_ids)
          = getClassBigSig clas
     in
-    tcInstTyVar tyvar                  `thenNF_Tc` \ clas_tyvar ->
+    tcInstSigTyVars [tyvar]            `thenNF_Tc` \ ([clas_tyvar], _, _) ->
 
        -- Generate bindings for the selector functions
 
        -- Generate bindings for the selector functions
-    buildSelectors clas clas_tyvar scs sc_sel_ids ops op_sel_ids
-                                               `thenNF_Tc` \ sel_binds ->
+    buildSelectors clas tyvar clas_tyvar scs sc_sel_ids ops op_sel_ids
+                                       `thenNF_Tc` \ sel_binds ->
        -- Ditto for the methods
     buildDefaultMethodBinds clas clas_tyvar defm_ids default_binds
        -- Ditto for the methods
     buildDefaultMethodBinds clas clas_tyvar defm_ids default_binds
-                                               `thenTc` \ (const_insts, meth_binds) ->
+                                       `thenTc` \ (const_insts, meth_binds) ->
 
     returnTc (const_insts, sel_binds `ThenBinds` meth_binds)
 \end{code}
 
     returnTc (const_insts, sel_binds `ThenBinds` meth_binds)
 \end{code}
@@ -275,29 +279,33 @@ tcClassDecl2 (ClassDecl context class_name
 
 \begin{code}
 buildSelectors :: Class                        -- The class object
 
 \begin{code}
 buildSelectors :: Class                        -- The class object
-              -> TcTyVar s             -- Class type variable
+              -> TyVar                 -- Class type variable
+              -> TcTyVar s             -- Instantiated class type variable (TyVarTy)
               -> [Class] -> [Id]       -- Superclasses and selectors
               -> [ClassOp] -> [Id]     -- Class ops and selectors
               -> NF_TcM s (TcHsBinds s)
 
               -> [Class] -> [Id]       -- Superclasses and selectors
               -> [ClassOp] -> [Id]     -- Class ops and selectors
               -> NF_TcM s (TcHsBinds s)
 
-buildSelectors clas clas_tyvar scs sc_sel_ids ops op_sel_ids
+buildSelectors clas clas_tyvar clas_tc_tyvar scs sc_sel_ids ops op_sel_ids
   =
        -- Make new Ids for the components of the dictionary
   =
        -- Make new Ids for the components of the dictionary
-    mapNF_Tc (tcInstType [] . getClassOpLocalType) ops  `thenNF_Tc` \ op_tys ->
-
+    let
+       clas_tyvar_ty = mkTyVarTy clas_tc_tyvar
+       mk_op_ty = tcInstType [(clas_tyvar, clas_tyvar_ty)] . getClassOpLocalType 
+    in
+    mapNF_Tc mk_op_ty ops                              `thenNF_Tc` \ op_tys ->
     newLocalIds (map getClassOpString ops) op_tys      `thenNF_Tc` \ method_ids ->
 
     newDicts ClassDeclOrigin 
     newLocalIds (map getClassOpString ops) op_tys      `thenNF_Tc` \ method_ids ->
 
     newDicts ClassDeclOrigin 
-            [ (super_clas, mkTyVarTy clas_tyvar)
+            [ (super_clas, clas_tyvar_ty)
             | super_clas <- scs ]                      `thenNF_Tc` \ (_,dict_ids) ->
 
     newDicts ClassDeclOrigin 
             | super_clas <- scs ]                      `thenNF_Tc` \ (_,dict_ids) ->
 
     newDicts ClassDeclOrigin 
-            [ (clas, mkTyVarTy clas_tyvar) ]           `thenNF_Tc` \ (_,[clas_dict]) ->
+            [ (clas, clas_tyvar_ty) ]                  `thenNF_Tc` \ (_,[clas_dict]) ->
 
         -- Make suitable bindings for the selectors
     let
        mk_sel sel_id method_or_dict
 
         -- Make suitable bindings for the selectors
     let
        mk_sel sel_id method_or_dict
-         = mkSelBind sel_id clas_tyvar clas_dict dict_ids method_ids method_or_dict
+         = mkSelBind sel_id clas_tc_tyvar clas_dict dict_ids method_ids method_or_dict
     in
     listNF_Tc (zipWithEqual mk_sel op_sel_ids method_ids) `thenNF_Tc` \ op_sel_binds ->
     listNF_Tc (zipWithEqual mk_sel sc_sel_ids dict_ids)   `thenNF_Tc` \ sc_sel_binds ->
     in
     listNF_Tc (zipWithEqual mk_sel op_sel_ids method_ids) `thenNF_Tc` \ op_sel_binds ->
     listNF_Tc (zipWithEqual mk_sel sc_sel_ids dict_ids)   `thenNF_Tc` \ sc_sel_binds ->
@@ -444,7 +452,7 @@ dfun.Foo.List
   = /\ a -> \ dfoo_a ->
     let rec
        op1 = defm.Foo.op1 [a] dfoo_list
   = /\ a -> \ dfoo_a ->
     let rec
        op1 = defm.Foo.op1 [a] dfoo_list
-       op2 = /\b -> defm.Foo.op2 [a] b dfoo_list
+       op2 = /\b -> \dord -> defm.Foo.op2 [a] b dfoo_list dord
        dfoo_list = (op1, op2)
     in
        dfoo_list
        dfoo_list = (op1, op2)
     in
        dfoo_list
@@ -483,7 +491,11 @@ makeClassDeclDefaultMethodRhs
        -> NF_TcM s (TcExpr s)
 
 makeClassDeclDefaultMethodRhs clas method_ids tag
        -> NF_TcM s (TcExpr s)
 
 makeClassDeclDefaultMethodRhs clas method_ids tag
-  = specTy ClassDeclOrigin (idType method_id) `thenNF_Tc` \ (tyvars, dicts, tau, dict_ids) ->
+  = tcInstType [] (idType method_id)   `thenNF_Tc` \ method_ty ->
+    let 
+       (tyvars, theta, tau) = splitSigmaTy method_ty 
+    in 
+    newDicts ClassDeclOrigin theta     `thenNF_Tc` \ (lie, dict_ids) ->
 
     returnNF_Tc (mkHsTyLam tyvars (
                 mkHsDictLam dict_ids (
 
     returnNF_Tc (mkHsTyLam tyvars (
                 mkHsDictLam dict_ids (
index 8912626..06e15fc 100644 (file)
@@ -35,8 +35,8 @@ import RnBinds4               ( rnMethodBinds, rnTopBinds )
 
 import Bag             ( Bag, isEmptyBag, unionBags, listToBag )
 import Class           ( GenClass, getClassKey )
 
 import Bag             ( Bag, isEmptyBag, unionBags, listToBag )
 import Class           ( GenClass, getClassKey )
-import ErrUtils                ( pprBagOfErrors, addErrLoc, TcError(..) )
-import Id              ( getDataConSig, getDataConArity )
+import ErrUtils                ( pprBagOfErrors, addErrLoc )
+import Id              ( dataConSig, dataConArity )
 import Maybes          ( assocMaybe, maybeToBool, Maybe(..) )
 import Name            ( Name(..) )
 import NameTypes       ( mkPreludeCoreName, Provenance(..) )
 import Maybes          ( assocMaybe, maybeToBool, Maybe(..) )
 import Name            ( Name(..) )
 import NameTypes       ( mkPreludeCoreName, Provenance(..) )
@@ -46,7 +46,7 @@ import PprStyle
 import Pretty
 import ProtoName       ( eqProtoName, ProtoName(..), Name )
 import SrcLoc          ( mkGeneratedSrcLoc, mkUnknownSrcLoc, SrcLoc )
 import Pretty
 import ProtoName       ( eqProtoName, ProtoName(..), Name )
 import SrcLoc          ( mkGeneratedSrcLoc, mkUnknownSrcLoc, SrcLoc )
-import TyCon           ( getTyConTyVars, getTyConDataCons, getTyConDerivings,
+import TyCon           ( tyConTyVars, tyConDataCons, tyConDerivings,
                          maybeTyConSingleCon, isEnumerationTyCon, TyCon )
 import Type            ( GenType(..), TauType(..), mkTyVarTys, applyTyCon,
                          mkSigmaTy, mkDictTy, isPrimType, instantiateTy,
                          maybeTyConSingleCon, isEnumerationTyCon, TyCon )
 import Type            ( GenType(..), TauType(..), mkTyVarTys, applyTyCon,
                          mkSigmaTy, mkDictTy, isPrimType, instantiateTy,
@@ -266,7 +266,7 @@ makeDerivEqns
 
     need_deriving tycons_to_consider
       = foldr ( \ tycon acc ->
 
     need_deriving tycons_to_consider
       = foldr ( \ tycon acc ->
-                  case (getTyConDerivings tycon) of
+                  case (tyConDerivings tycon) of
                     [] -> acc
                     cs -> [ (clas,tycon) | clas <- cs ] ++ acc
              )
                     [] -> acc
                     cs -> [ (clas,tycon) | clas <- cs ] ++ acc
              )
@@ -303,9 +303,9 @@ makeDerivEqns
     mk_eqn (clas, tycon)
       = (clas, tycon, tyvars, constraints)
       where
     mk_eqn (clas, tycon)
       = (clas, tycon, tyvars, constraints)
       where
-       tyvars    = getTyConTyVars tycon        -- ToDo: Do we need new tyvars ???
+       tyvars    = tyConTyVars tycon   -- ToDo: Do we need new tyvars ???
        tyvar_tys = mkTyVarTys tyvars
        tyvar_tys = mkTyVarTys tyvars
-       data_cons = getTyConDataCons tycon
+       data_cons = tyConDataCons tycon
        constraints = concat (map mk_constraints data_cons)
 
        mk_constraints data_con
        constraints = concat (map mk_constraints data_cons)
 
        mk_constraints data_con
@@ -314,7 +314,7 @@ makeDerivEqns
               not (isPrimType arg_ty)  -- No constraints for primitive types
             ]
           where
               not (isPrimType arg_ty)  -- No constraints for primitive types
             ]
           where
-            (con_tyvars, _, arg_tys, _) = getDataConSig data_con
+            (con_tyvars, _, arg_tys, _) = dataConSig data_con
             inst_env = con_tyvars `zipEqual` tyvar_tys
                        -- same number of tyvars in data constr and type constr!
 \end{code}
             inst_env = con_tyvars `zipEqual` tyvar_tys
                        -- same number of tyvars in data constr and type constr!
 \end{code}
@@ -638,7 +638,7 @@ gen_taggery_Names eqns
   where
     do_con2tag acc_Names tycon
       = if (we_are_deriving eqClassKey tycon
   where
     do_con2tag acc_Names tycon
       = if (we_are_deriving eqClassKey tycon
-           && any ( (== 0).getDataConArity ) (getTyConDataCons tycon))
+           && any ( (== 0).dataConArity ) (tyConDataCons tycon))
        || (we_are_deriving ordClassKey  tycon
            && not (maybeToBool (maybeTyConSingleCon tycon)))
        || (we_are_deriving enumClassKey tycon)
        || (we_are_deriving ordClassKey  tycon
            && not (maybeToBool (maybeTyConSingleCon tycon)))
        || (we_are_deriving enumClassKey tycon)
index 42a6c9b..8ca0034 100644 (file)
@@ -13,7 +13,7 @@ module TcEnv(
 
        tcExtendGlobalValEnv, tcExtendLocalValEnv,
        tcLookupLocalValue, tcLookupLocalValueOK, tcLookupLocalValueByKey, 
 
        tcExtendGlobalValEnv, tcExtendLocalValEnv,
        tcLookupLocalValue, tcLookupLocalValueOK, tcLookupLocalValueByKey, 
-       tcLookupGlobalValue, tcLookupGlobalValueByKey,
+       tcLookupGlobalValue, tcLookupGlobalValueByKey, tcGlobalOcc,
 
        newMonoIds, newLocalIds, newLocalId,
        tcGetGlobalTyVars
 
        newMonoIds, newLocalIds, newLocalId,
        tcGetGlobalTyVars
@@ -25,11 +25,13 @@ import TcMLoop  -- for paranoia checking
 
 import Id      ( Id(..), GenId, idType, mkUserLocal )
 import TcHsSyn ( TcIdBndr(..), TcIdOcc(..) )
 
 import Id      ( Id(..), GenId, idType, mkUserLocal )
 import TcHsSyn ( TcIdBndr(..), TcIdOcc(..) )
-import TcKind  ( TcKind, newKindVars, tcKindToKind, kindToTcKind )
-import TcType  ( TcType(..), TcMaybe, TcTyVar(..), TcTyVarSet(..), newTyVarTys, zonkTcTyVars )
+import TcKind  ( TcKind, newKindVars, tcDefaultKind, kindToTcKind )
+import TcType  ( TcType(..), TcMaybe, TcTyVar(..), TcTyVarSet(..),
+                 newTyVarTys, tcInstTyVars, tcInstType, zonkTcTyVars
+               )
 import TyVar   ( mkTyVar, getTyVarKind, unionTyVarSets, emptyTyVarSet )
 import Type    ( tyVarsOfTypes )
 import TyVar   ( mkTyVar, getTyVarKind, unionTyVarSets, emptyTyVarSet )
 import Type    ( tyVarsOfTypes )
-import TyCon   ( TyCon, Arity(..), getTyConKind, getSynTyConArity )
+import TyCon   ( TyCon, Arity(..), tyConKind, synTyConArity )
 import Class   ( Class(..), GenClass, getClassSig )
 
 import TcMonad
 import Class   ( Class(..), GenClass, getClassSig )
 
 import TcMonad
@@ -37,9 +39,10 @@ import TcMonad
 import Name    ( Name(..), getNameShortName )
 import PprStyle
 import Pretty
 import Name    ( Name(..), getNameShortName )
 import PprStyle
 import Pretty
+import Type    ( splitForAllTy )
 import Unique  ( Unique )
 import UniqFM
 import Unique  ( Unique )
 import UniqFM
-import Util    ( zipWithEqual, zipWith3Equal, zipLazy, panic )
+import Util    ( zipWithEqual, zipWith3Equal, zipLazy, panic, pprPanic )
 \end{code}
 
 Data type declarations
 \end{code}
 
 Data type declarations
@@ -89,7 +92,7 @@ tcTyVarScopeGivenKinds names kinds thing_inside
                 (thing_inside rec_tyvars)      `thenTc` \ result ->
  
                -- Get the tyvar's Kinds from their TcKinds
                 (thing_inside rec_tyvars)      `thenTc` \ result ->
  
                -- Get the tyvar's Kinds from their TcKinds
-       mapNF_Tc tcKindToKind kinds             `thenNF_Tc` \ kinds' ->
+       mapNF_Tc tcDefaultKind kinds            `thenNF_Tc` \ kinds' ->
 
                -- Construct the real TyVars
        let
 
                -- Construct the real TyVars
        let
@@ -123,7 +126,10 @@ tcExtendTyConEnv names_w_arities tycons scope
                                                                  (kinds `zipLazy` tycons)
                                ]
     in
                                                                  (kinds `zipLazy` tycons)
                                ]
     in
-    tcSetEnv (TcEnv tve tce' ce gve lve gtvs) scope
+    tcSetEnv (TcEnv tve tce' ce gve lve gtvs) scope    `thenTc` \ result ->
+    mapNF_Tc tcDefaultKind kinds                       `thenNF_Tc_`
+    returnTc result 
+
 
 tcExtendClassEnv :: [Name] -> [Class] -> TcM s r -> TcM s r
 tcExtendClassEnv names classes scope
 
 tcExtendClassEnv :: [Name] -> [Class] -> TcM s r -> TcM s r
 tcExtendClassEnv names classes scope
@@ -132,7 +138,9 @@ tcExtendClassEnv names classes scope
     let
        ce' = addListToUFM ce (names `zip` (kinds `zipLazy` classes))
     in
     let
        ce' = addListToUFM ce (names `zip` (kinds `zipLazy` classes))
     in
-    tcSetEnv (TcEnv tve tce ce' gve lve gtvs) scope
+    tcSetEnv (TcEnv tve tce ce' gve lve gtvs) scope    `thenTc` \ result ->
+    mapNF_Tc tcDefaultKind kinds                       `thenNF_Tc_`
+    returnTc result 
 \end{code}
 
 
 \end{code}
 
 
@@ -145,7 +153,7 @@ tcLookupTyVar name
 
 
 tcLookupTyCon (WiredInTyCon tc)                -- wired in tycons
 
 
 tcLookupTyCon (WiredInTyCon tc)                -- wired in tycons
-  = returnNF_Tc (kindToTcKind (getTyConKind tc), getSynTyConArity tc, tc)
+  = returnNF_Tc (kindToTcKind (tyConKind tc), synTyConArity tc, tc)
 
 tcLookupTyCon name
   = tcGetEnv           `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
 
 tcLookupTyCon name
   = tcGetEnv           `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
@@ -154,7 +162,9 @@ tcLookupTyCon name
 tcLookupTyConByKey uniq
   = tcGetEnv           `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
     let 
 tcLookupTyConByKey uniq
   = tcGetEnv           `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
     let 
-       (kind, arity, tycon) =  lookupWithDefaultUFM_Directly tce (panic "tcLookupTyCon") uniq
+       (kind, arity, tycon) =  lookupWithDefaultUFM_Directly tce 
+                                       (pprPanic "tcLookupTyCon:" (ppr PprDebug uniq)) 
+                                       uniq
     in
     returnNF_Tc tycon
 
     in
     returnNF_Tc tycon
 
@@ -165,7 +175,9 @@ tcLookupClass name
 tcLookupClassByKey uniq
   = tcGetEnv           `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
     let
 tcLookupClassByKey uniq
   = tcGetEnv           `thenNF_Tc` \ (TcEnv tve tce ce gve lve gtvs) ->
     let
-       (kind, clas) = lookupWithDefaultUFM_Directly ce (panic "tcLookupClas") uniq
+       (kind, clas) = lookupWithDefaultUFM_Directly ce 
+                               (pprPanic "tcLookupClas:" (ppr PprDebug uniq))
+                               uniq
     in
     returnNF_Tc clas
 \end{code}
     in
     returnNF_Tc clas
 \end{code}
@@ -236,11 +248,27 @@ tcLookupGlobalValue name
     returnNF_Tc (lookupWithDefaultUFM gve def name)
   where
 #ifdef DEBUG
     returnNF_Tc (lookupWithDefaultUFM gve def name)
   where
 #ifdef DEBUG
-    def = panic ("tcLookupGlobalValue:" ++ ppShow 1000 (ppr PprDebug name))
+    def = pprPanic "tcLookupGlobalValue:" (ppr PprDebug name)
 #else
     def = panic "tcLookupGlobalValue"
 #endif
 
 #else
     def = panic "tcLookupGlobalValue"
 #endif
 
+-- A useful function that takes an occurrence of a global thing
+-- and instantiates its type with fresh type variables
+tcGlobalOcc :: Name 
+           -> NF_TcM s (Id,            -- The Id
+                         [TcType s],   -- Instance types
+                         TcType s)     -- Rest of its type
+
+tcGlobalOcc name
+  = tcLookupGlobalValue name   `thenNF_Tc` \ id ->
+    let
+      (tyvars, rho) = splitForAllTy (idType id)
+    in
+    tcInstTyVars tyvars                `thenNF_Tc` \ (tyvars', arg_tys, tenv) ->
+    tcInstType tenv rho                `thenNF_Tc` \ rho' ->
+    returnNF_Tc (id, arg_tys, rho')
+
 
 tcLookupGlobalValueByKey :: Unique -> NF_TcM s Id
 tcLookupGlobalValueByKey uniq
 
 tcLookupGlobalValueByKey :: Unique -> NF_TcM s Id
 tcLookupGlobalValueByKey uniq
@@ -248,7 +276,7 @@ tcLookupGlobalValueByKey uniq
     returnNF_Tc (lookupWithDefaultUFM_Directly gve def uniq)
   where
 #ifdef DEBUG
     returnNF_Tc (lookupWithDefaultUFM_Directly gve def uniq)
   where
 #ifdef DEBUG
-    def = panic ("tcLookupGlobalValueByKey:" ++ ppShow 1000 (ppr PprDebug uniq))
+    def = pprPanic "tcLookupGlobalValueByKey:" (ppr PprDebug uniq)
 #else
     def = panic "tcLookupGlobalValueByKey"
 #endif
 #else
     def = panic "tcLookupGlobalValueByKey"
 #endif
index 9f911d4..660c970 100644 (file)
@@ -15,45 +15,56 @@ import HsSyn                ( HsExpr(..), Qual(..), Stmt(..),
                          ArithSeqInfo(..), HsLit(..), Sig, GRHSsAndBinds,
                          Match, Fake, InPat, OutPat, PolyType,
                          irrefutablePat, collectPatBinders )
                          ArithSeqInfo(..), HsLit(..), Sig, GRHSsAndBinds,
                          Match, Fake, InPat, OutPat, PolyType,
                          irrefutablePat, collectPatBinders )
-import RnHsSyn         ( RenamedHsExpr(..), RenamedQual(..), RenamedStmt(..) )
-import TcHsSyn         ( TcExpr(..), TcQual(..), TcStmt(..), TcIdOcc(..) )
+import RnHsSyn         ( RenamedHsExpr(..), RenamedQual(..),
+                         RenamedStmt(..), RenamedRecordBinds(..)
+                       )
+import TcHsSyn         ( TcExpr(..), TcQual(..), TcStmt(..),
+                         TcIdOcc(..), TcRecordBinds(..),
+                         mkHsTyApp
+                       )
 
 import TcMonad
 import Inst            ( Inst, InstOrigin(..), OverloadedLit(..),
 
 import TcMonad
 import Inst            ( Inst, InstOrigin(..), OverloadedLit(..),
-                         LIE(..), emptyLIE, plusLIE, newOverloadedLit,
+                         LIE(..), emptyLIE, plusLIE, plusLIEs, newOverloadedLit,
                          newMethod, newMethodWithGivenTy, newDicts )
 import TcBinds         ( tcBindsAndThen )
 import TcEnv           ( tcLookupLocalValue, tcLookupGlobalValue, tcLookupClassByKey,
                          newMethod, newMethodWithGivenTy, newDicts )
 import TcBinds         ( tcBindsAndThen )
 import TcEnv           ( tcLookupLocalValue, tcLookupGlobalValue, tcLookupClassByKey,
-                         tcLookupGlobalValueByKey, newMonoIds, tcGetGlobalTyVars )
+                         tcLookupGlobalValueByKey, newMonoIds, tcGetGlobalTyVars,
+                         tcGlobalOcc
+                       )
 import TcMatches       ( tcMatchesCase, tcMatch )
 import TcMonoType      ( tcPolyType )
 import TcPat           ( tcPat )
 import TcSimplify      ( tcSimplifyAndCheck, tcSimplifyRank2 )
 import TcMatches       ( tcMatchesCase, tcMatch )
 import TcMonoType      ( tcPolyType )
 import TcPat           ( tcPat )
 import TcSimplify      ( tcSimplifyAndCheck, tcSimplifyRank2 )
-import TcType          ( TcType(..), TcMaybe(..), tcReadTyVar,
-                         tcInstType, tcInstTcType, 
-                         tcInstTyVar, newTyVarTy, zonkTcTyVars )
+import TcType          ( TcType(..), TcMaybe(..),
+                         tcInstType, tcInstTcType, tcInstTyVars,
+                         newTyVarTy, zonkTcTyVars, zonkTcType )
 import TcKind          ( TcKind )
 
 import Class           ( Class(..), getClassSig )
 import TcKind          ( TcKind )
 
 import Class           ( Class(..), getClassSig )
-import Id              ( Id(..), GenId, idType )
-import Kind            ( Kind, mkBoxedTypeKind, mkTypeKind )
-import GenSpecEtc      ( checkSigTyVars, checkSigTyVarsGivenGlobals, specTy )
+import FieldLabel      ( fieldLabelName )
+import Id              ( Id(..), GenId, idType, dataConFieldLabels )
+import Kind            ( Kind, mkBoxedTypeKind, mkTypeKind, mkArrowKind )
+import GenSpecEtc      ( checkSigTyVars, checkSigTyVarsGivenGlobals )
 import PrelInfo                ( intPrimTy, charPrimTy, doublePrimTy,
                          floatPrimTy, addrPrimTy, addrTy,
                          boolTy, charTy, stringTy, mkListTy,
                          mkTupleTy, mkPrimIoTy )
 import Type            ( mkFunTy, mkAppTy, mkTyVarTy, mkTyVarTys,
                          getTyVar_maybe, getFunTy_maybe,
 import PrelInfo                ( intPrimTy, charPrimTy, doublePrimTy,
                          floatPrimTy, addrPrimTy, addrTy,
                          boolTy, charTy, stringTy, mkListTy,
                          mkTupleTy, mkPrimIoTy )
 import Type            ( mkFunTy, mkAppTy, mkTyVarTy, mkTyVarTys,
                          getTyVar_maybe, getFunTy_maybe,
-                         splitForAllTy, splitRhoTy, splitSigmaTy,
-                         isTauTy, mkFunTys, tyVarsOfType, getForAllTy_maybe )
+                         splitForAllTy, splitRhoTy, splitSigmaTy, splitFunTy,
+                         isTauTy, mkFunTys, tyVarsOfType, getForAllTy_maybe,
+                         maybeAppDataTyCon
+                       )
 import TyVar           ( GenTyVar, TyVarSet(..), unionTyVarSets, mkTyVarSet )
 import TyVar           ( GenTyVar, TyVarSet(..), unionTyVarSets, mkTyVarSet )
-import Unify           ( unifyTauTy, unifyTauTyList, unifyTauTyLists )
+import Unify           ( unifyTauTy, unifyTauTyList, unifyTauTyLists, unifyFunTy )
 import Unique          ( Unique, cCallableClassKey, cReturnableClassKey, 
                          enumFromClassOpKey, enumFromThenClassOpKey,
                          enumFromToClassOpKey, enumFromThenToClassOpKey,
                          monadClassKey, monadZeroClassKey )
 
 import Name            ( Name )                -- Instance 
 import Unique          ( Unique, cCallableClassKey, cReturnableClassKey, 
                          enumFromClassOpKey, enumFromThenClassOpKey,
                          enumFromToClassOpKey, enumFromThenToClassOpKey,
                          monadClassKey, monadZeroClassKey )
 
 import Name            ( Name )                -- Instance 
+import Outputable      ( interpp'SP )
 import PprType         ( GenType, GenTyVar )   -- Instances
 import Maybes          ( maybeToBool )
 import Pretty
 import PprType         ( GenType, GenTyVar )   -- Instances
 import Maybes          ( maybeToBool )
 import Pretty
@@ -302,24 +313,18 @@ tcExpr (HsDo stmts src_loc)
   =    -- get the Monad and MonadZero classes
        -- create type consisting of a fresh monad tyvar
     tcAddSrcLoc src_loc        $
   =    -- get the Monad and MonadZero classes
        -- create type consisting of a fresh monad tyvar
     tcAddSrcLoc src_loc        $
-    tcLookupClassByKey monadClassKey           `thenNF_Tc` \ monadClass ->
-    tcLookupClassByKey monadZeroClassKey       `thenNF_Tc` \ monadZeroClass ->
-    let
-       (tv,_,_) = getClassSig monadClass
-    in
-    tcInstTyVar tv                             `thenNF_Tc` \ m_tyvar ->
-    let
-       m = mkTyVarTy m_tyvar
-    in
-    tcDoStmts False m stmts                    `thenTc` \ ((stmts',monad,mzero), lie, do_ty) ->
+    newTyVarTy monadKind       `thenNF_Tc` \ m ->
+    tcDoStmts False m stmts    `thenTc` \ ((stmts',monad,mzero), lie, do_ty) ->
 
        -- create dictionaries for monad and possibly monadzero
     (if monad then
 
        -- create dictionaries for monad and possibly monadzero
     (if monad then
+       tcLookupClassByKey monadClassKey                `thenNF_Tc` \ monadClass ->
        newDicts DoOrigin [(monadClass, m)]     
     else
        returnNF_Tc (emptyLIE, [panic "TcExpr: MonadZero dictionary"])
     )                                          `thenNF_Tc` \ (m_lie,  [m_id])  ->
     (if mzero then
        newDicts DoOrigin [(monadClass, m)]     
     else
        returnNF_Tc (emptyLIE, [panic "TcExpr: MonadZero dictionary"])
     )                                          `thenNF_Tc` \ (m_lie,  [m_id])  ->
     (if mzero then
+       tcLookupClassByKey monadZeroClassKey    `thenNF_Tc` \ monadZeroClass ->
        newDicts DoOrigin [(monadZeroClass, m)]
      else
         returnNF_Tc (emptyLIE, [panic "TcExpr: MonadZero dictionary"])
        newDicts DoOrigin [(monadZeroClass, m)]
      else
         returnNF_Tc (emptyLIE, [panic "TcExpr: MonadZero dictionary"])
@@ -328,6 +333,8 @@ tcExpr (HsDo stmts src_loc)
     returnTc (HsDoOut stmts' m_id mz_id src_loc,
              lie `plusLIE` m_lie `plusLIE` mz_lie,
              do_ty)
     returnTc (HsDoOut stmts' m_id mz_id src_loc,
              lie `plusLIE` m_lie `plusLIE` mz_lie,
              do_ty)
+  where
+    monadKind = mkArrowKind mkBoxedTypeKind mkBoxedTypeKind
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -346,10 +353,41 @@ tcExpr (ExplicitTuple exprs)
   = tcExprs exprs                      `thenTc` \ (exprs', lie, tys) ->
     returnTc (ExplicitTuple exprs', lie, mkTupleTy (length tys) tys)
 
   = tcExprs exprs                      `thenTc` \ (exprs', lie, tys) ->
     returnTc (ExplicitTuple exprs', lie, mkTupleTy (length tys) tys)
 
-tcExpr (RecordCon con rbinds)
-  = panic "tcExpr:RecordCon"
-tcExpr (RecordUpd exp rbinds)
-  = panic "tcExpr:RecordUpd"
+tcExpr (RecordCon (HsVar con) rbinds)
+  = tcGlobalOcc con            `thenNF_Tc` \ (con_id, arg_tys, con_rho) ->
+    let
+       (con_theta, con_tau) = splitRhoTy con_rho
+       (_, record_ty)       = splitFunTy con_tau
+       con_expr             = mkHsTyApp (HsVar (RealId con_id)) arg_tys
+    in
+       -- TEMPORARY ASSERT
+    ASSERT( null con_theta )
+
+       -- Con is syntactically constrained to be a data constructor
+    ASSERT( maybeToBool (maybeAppDataTyCon record_ty ) )
+
+    tcRecordBinds record_ty rbinds             `thenTc` \ (rbinds', rbinds_lie) ->
+
+    checkTc (checkRecordFields rbinds con_id)
+           (badFieldsCon con rbinds)           `thenTc_`
+
+    returnTc (RecordCon con_expr rbinds', panic "tcExpr:RecordCon:con_lie???" {-con_lie???-} `plusLIE` rbinds_lie, record_ty)
+
+tcExpr (RecordUpd record_expr rbinds)
+  = tcExpr record_expr                 `thenTc` \ (record_expr', record_lie, record_ty) ->
+    tcRecordBinds record_ty rbinds     `thenTc` \ (rbinds', rbinds_lie) ->
+
+       -- Check that the field names are plausible
+    zonkTcType record_ty               `thenNF_Tc` \ record_ty' ->
+    let
+       maybe_tycon_stuff = maybeAppDataTyCon record_ty'
+       Just (tycon, args_tys, data_cons) = maybe_tycon_stuff
+    in
+    checkTc (maybeToBool maybe_tycon_stuff)
+           (panic "TcExpr:Records:mystery error message") `thenTc_`
+    checkTc (any (checkRecordFields rbinds) data_cons)
+           (badFieldsUpd rbinds)               `thenTc_`
+    returnTc (RecordUpd record_expr' rbinds', record_lie `plusLIE` rbinds_lie, record_ty)
 
 tcExpr (ArithSeqIn seq@(From expr))
   = tcExpr expr                                        `thenTc`    \ (expr', lie1, ty) ->
 
 tcExpr (ArithSeqIn seq@(From expr))
   = tcExpr expr                                        `thenTc`    \ (expr', lie1, ty) ->
@@ -425,13 +463,17 @@ tcExpr in_expr@(ExprWithTySig expr poly_ty)
 
        -- Check the tau-type part
    tcSetErrCtxt (exprSigCtxt in_expr)  $
 
        -- Check the tau-type part
    tcSetErrCtxt (exprSigCtxt in_expr)  $
-   specTy SignatureOrigin sigma_sig    `thenNF_Tc` \ (sig_tyvars, sig_dicts, sig_tau, _) ->
-   unifyTauTy tau_ty sig_tau           `thenTc_`
+   tcInstType [] sigma_sig             `thenNF_Tc` \ sigma_sig' ->
+   let
+       (sig_tyvars', sig_theta', sig_tau') = splitSigmaTy sigma_sig'
+   in
+   unifyTauTy tau_ty sig_tau'          `thenTc_`
 
        -- Check the type variables of the signature
 
        -- Check the type variables of the signature
-   checkSigTyVars sig_tyvars sig_tau tau_ty    `thenTc`    \ sig_tyvars' ->
+   checkSigTyVars sig_tyvars' sig_tau' `thenTc_`
 
        -- Check overloading constraints
 
        -- Check overloading constraints
+   newDicts SignatureOrigin sig_theta'         `thenNF_Tc` \ (sig_dicts, _) ->
    tcSimplifyAndCheck
        (mkTyVarSet sig_tyvars')
        sig_dicts lie                           `thenTc_`
    tcSimplifyAndCheck
        (mkTyVarSet sig_tyvars')
        sig_dicts lie                           `thenTc_`
@@ -485,46 +527,23 @@ tcApp_help :: RenamedHsExpr -> Int        -- Function and arg position, used in error m
 tcApp_help orig_fun arg_no fun_ty []
   = returnTc ([], emptyLIE, fun_ty)
 
 tcApp_help orig_fun arg_no fun_ty []
   = returnTc ([], emptyLIE, fun_ty)
 
-tcApp_help orig_fun arg_no fun_ty (arg:args)
-  | maybeToBool maybe_arrow_ty
-  =    -- The function's type is A->B
+tcApp_help orig_fun arg_no fun_ty all_args@(arg:args)
+  =    -- Expect the function to have type A->B
+    tcAddErrCtxt (tooManyArgsCtxt orig_fun) (
+           unifyFunTy fun_ty
+    )                                                  `thenTc` \ (expected_arg_ty, result_ty) ->
+
+       -- Type check the argument
     tcAddErrCtxt (funAppCtxt orig_fun arg_no arg) (
     tcAddErrCtxt (funAppCtxt orig_fun arg_no arg) (
-       tcArg expected_arg_ty arg
-    )                                          `thenTc` \ (arg', lie_arg) ->
+               tcArg expected_arg_ty arg
+    )                                                  `thenTc` \ (arg', lie_arg) ->
 
 
+       -- Do the other args
     tcApp_help orig_fun (arg_no+1) result_ty args      `thenTc` \ (args', lie_args, res_ty) ->
     tcApp_help orig_fun (arg_no+1) result_ty args      `thenTc` \ (args', lie_args, res_ty) ->
-    returnTc (arg':args', lie_arg `plusLIE` lie_args, res_ty)
-
-  | maybeToBool maybe_tyvar_ty
-  =    -- The function's type is just a type variable
-    tcReadTyVar fun_tyvar                      `thenNF_Tc` \ maybe_fun_ty ->
-    case maybe_fun_ty of
-
-       BoundTo new_fun_ty ->   -- The tyvar in the corner of the function is bound
-                               -- to something ... so carry on ....
-               tcApp_help orig_fun arg_no new_fun_ty (arg:args)
-
-       UnBound ->      -- Extra args match against an unbound type
-                       -- variable as the final result type, so unify the tyvar.
-               newTyVarTy mkTypeKind   `thenNF_Tc` \ result_ty ->
-               tcExprs args            `thenTc`    \ (args', lie_args, arg_tys) ->
-
-               -- Unification can't fail, since we're unifying against a tyvar
-               unifyTauTy fun_ty (mkFunTys arg_tys result_ty)  `thenTc_`
-
-               returnTc (args', lie_args, result_ty)
-
-  | otherwise
-  =    -- Must be an error: a lurking for-all, or (more commonly)
-       -- a TyConTy... we've applied the function to too many args
-    failTc (tooManyArgs orig_fun)
 
 
-  where
-    maybe_arrow_ty                   = getFunTy_maybe fun_ty
-    Just (expected_arg_ty, result_ty) = maybe_arrow_ty
+       -- Done
+    returnTc (arg':args', lie_arg `plusLIE` lie_args, res_ty)
 
 
-    maybe_tyvar_ty = getTyVar_maybe fun_ty
-    Just fun_tyvar = maybe_tyvar_ty
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -550,7 +569,7 @@ tcArg expected_arg_ty arg
     let
        (expected_tyvars, expected_theta, expected_tau) = splitSigmaTy expected_arg_ty
     in
     let
        (expected_tyvars, expected_theta, expected_tau) = splitSigmaTy expected_arg_ty
     in
-    ASSERT( null expected_theta )
+    ASSERT( null expected_theta )      -- And expected_tyvars are all DontBind things
 
        -- Type-check the arg and unify with expected type
     tcExpr arg                                 `thenTc` \ (arg', lie_arg, actual_arg_ty) ->
 
        -- Type-check the arg and unify with expected type
     tcExpr arg                                 `thenTc` \ (arg', lie_arg, actual_arg_ty) ->
@@ -571,19 +590,19 @@ tcArg expected_arg_ty arg
     zonkTcTyVars (tyVarsOfType expected_arg_ty)                        `thenNF_Tc` \ free_tyvars ->
     checkSigTyVarsGivenGlobals
        (env_tyvars `unionTyVarSets` free_tyvars)
     zonkTcTyVars (tyVarsOfType expected_arg_ty)                        `thenNF_Tc` \ free_tyvars ->
     checkSigTyVarsGivenGlobals
        (env_tyvars `unionTyVarSets` free_tyvars)
-       expected_tyvars expected_tau actual_arg_ty              `thenTc` \ arg_tyvars' ->
+       expected_tyvars expected_tau                            `thenTc_`
 
        -- Check that there's no overloading involved
 
        -- Check that there's no overloading involved
-       -- Even if there isn't, there may be some Insts which mention the arg_tyvars,
+       -- Even if there isn't, there may be some Insts which mention the expected_tyvars,
        -- but which, on simplification, don't actually need a dictionary involving
        -- the tyvar.  So we have to do a proper simplification right here.
        -- but which, on simplification, don't actually need a dictionary involving
        -- the tyvar.  So we have to do a proper simplification right here.
-    tcSimplifyRank2 (mkTyVarSet arg_tyvars') 
+    tcSimplifyRank2 (mkTyVarSet expected_tyvars) 
                    lie_arg                             `thenTc` \ (free_insts, inst_binds) ->
 
        -- This HsLet binds any Insts which came out of the simplification.
        -- It's a bit out of place here, but using AbsBind involves inventing
        -- a couple of new names which seems worse.
                    lie_arg                             `thenTc` \ (free_insts, inst_binds) ->
 
        -- This HsLet binds any Insts which came out of the simplification.
        -- It's a bit out of place here, but using AbsBind involves inventing
        -- a couple of new names which seems worse.
-    returnTc (TyLam arg_tyvars' (HsLet (mk_binds inst_binds) arg'), free_insts)
+    returnTc (TyLam expected_tyvars (HsLet (mk_binds inst_binds) arg'), free_insts)
     )
   where
 
     )
   where
 
@@ -605,29 +624,30 @@ tcArg expected_arg_ty arg
 tcId :: Name -> TcM s (TcExpr s, LIE s, TcType s)
 tcId name
   =    -- Look up the Id and instantiate its type
 tcId :: Name -> TcM s (TcExpr s, LIE s, TcType s)
 tcId name
   =    -- Look up the Id and instantiate its type
-    (tcLookupLocalValue name   `thenNF_Tc` \ maybe_local ->
-     case maybe_local of
-       Just tc_id -> tcInstTcType [] (idType tc_id)    `thenNF_Tc` \ ty ->
-                     returnNF_Tc (TcId tc_id, ty)
-
-       Nothing ->    tcLookupGlobalValue name          `thenNF_Tc` \ id ->
-                     tcInstType [] (idType id)         `thenNF_Tc` \ ty ->
-                     returnNF_Tc (RealId id, ty)
-    )                                                  `thenNF_Tc` \ (tc_id_occ, ty) ->
-    let
-       (tyvars, rho) = splitForAllTy ty
-       (theta,tau)   = splitRhoTy rho
-       arg_tys       = mkTyVarTys tyvars
-    in
+    tcLookupLocalValue name    `thenNF_Tc` \ maybe_local ->
+
+    (case maybe_local of
+       Just tc_id -> let
+                       (tyvars, rho) = splitForAllTy (idType tc_id)
+                     in
+                     tcInstTyVars tyvars               `thenNF_Tc` \ (tyvars', arg_tys', tenv)  ->
+                     tcInstTcType tenv rho             `thenNF_Tc` \ rho' ->
+                     returnNF_Tc (TcId tc_id, arg_tys', rho')
+
+       Nothing ->    tcGlobalOcc name                  `thenNF_Tc` \ (id, arg_tys, rho) ->
+                     returnNF_Tc (RealId id, arg_tys, rho)
+
+    )                                  `thenNF_Tc` \ (tc_id_occ, arg_tys, rho) ->
+
        -- Is it overloaded?
        -- Is it overloaded?
-    case theta of
-      [] ->    -- Not overloaded, so just make a type application
-           returnTc (TyApp (HsVar tc_id_occ) arg_tys, emptyLIE, tau)
-
-      _  ->    -- Overloaded, so make a Method inst
-           newMethodWithGivenTy (OccurrenceOf tc_id_occ)
-                       tc_id_occ arg_tys rho           `thenNF_Tc` \ (lie, meth_id) ->
-           returnTc (HsVar meth_id, lie, tau)
+    case splitRhoTy rho of
+      ([], tau)    ->  -- Not overloaded, so just make a type application
+                       returnTc (mkHsTyApp (HsVar tc_id_occ) arg_tys, emptyLIE, tau)
+
+      (theta, tau) ->  -- Overloaded, so make a Method inst
+                       newMethodWithGivenTy (OccurrenceOf tc_id_occ)
+                               tc_id_occ arg_tys rho           `thenNF_Tc` \ (lie, meth_id) ->
+                       returnTc (HsVar meth_id, lie, tau)
 \end{code}
 
 
 \end{code}
 
 
@@ -752,6 +772,65 @@ tcDoStmts monad m (LetStmt binds : stmts)
 
 \end{code}
 
 
 \end{code}
 
+Game plan for record bindings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+For each binding 
+       field = value
+1. look up "field", to find its selector Id, which must have type
+       forall a1..an. T a1 .. an -> tau
+   where tau is the type of the field.  
+
+2. Instantiate this type
+
+3. Unify the (T a1 .. an) part with the "expected result type", which
+   is passed in.  This checks that all the field labels come from the
+   same type.
+
+4. Type check the value using tcArg, passing tau as the expected
+   argument type.
+
+This extends OK when the field types are universally quantified.
+
+Actually, to save excessive creation of fresh type variables,
+we 
+       
+\begin{code}
+tcRecordBinds
+       :: TcType s             -- Expected type of whole record
+       -> RenamedRecordBinds
+       -> TcM s (TcRecordBinds s, LIE s)
+
+tcRecordBinds expected_record_ty rbinds
+  = mapAndUnzipTc do_bind rbinds       `thenTc` \ (rbinds', lies) ->
+    returnTc (rbinds', plusLIEs lies)
+  where
+    do_bind (field_label, rhs, pun_flag)
+      = tcGlobalOcc field_label                `thenNF_Tc` \ (sel_id, _, tau) ->
+
+               -- Record selectors all have type
+               --      forall a1..an.  T a1 .. an -> tau
+       ASSERT( maybeToBool (getFunTy_maybe tau) )
+       let
+               -- Selector must have type RecordType -> FieldType
+         Just (record_ty, field_ty) = getFunTy_maybe tau
+       in
+       unifyTauTy expected_record_ty record_ty         `thenTc_`
+       tcArg field_ty rhs                              `thenTc` \ (rhs', lie) ->
+       returnTc ((RealId sel_id, rhs', pun_flag), lie)
+
+checkRecordFields :: RenamedRecordBinds -> Id -> Bool  -- True iff all the fields in
+                                                       -- RecordBinds are field of the
+                                                       -- specified constructor
+checkRecordFields rbinds data_con
+  = all ok rbinds
+  where 
+    data_con_fields = dataConFieldLabels data_con
+
+    ok (field_name, _, _) = any (match field_name) data_con_fields
+
+    match field_name field_label = field_name == fieldLabelName field_label
+\end{code}
+
 %************************************************************************
 %*                                                                     *
 \subsection{@tcExprs@ typechecks a {\em list} of expressions}
 %************************************************************************
 %*                                                                     *
 \subsection{@tcExprs@ typechecks a {\em list} of expressions}
@@ -821,7 +900,7 @@ stmtCtxt stmt sty
   = ppHang (ppStr "In a do statement:") 
          4 (ppr sty stmt)
 
   = ppHang (ppStr "In a do statement:") 
          4 (ppr sty stmt)
 
-tooManyArgs f sty
+tooManyArgsCtxt f sty
   = ppHang (ppStr "Too many arguments in an application of the function")
         4 (ppr sty f)
 
   = ppHang (ppStr "Too many arguments in an application of the function")
         4 (ppr sty f)
 
@@ -834,5 +913,16 @@ rank2ArgCtxt arg expected_arg_ty sty
   = ppHang (ppStr "In a polymorphic function argument:")
         4 (ppSep [ppBeside (ppr sty arg) (ppStr " ::"),
                   ppr sty expected_arg_ty])
   = ppHang (ppStr "In a polymorphic function argument:")
         4 (ppSep [ppBeside (ppr sty arg) (ppStr " ::"),
                   ppr sty expected_arg_ty])
-\end{code}
 
 
+badFieldsUpd rbinds sty
+  = ppHang (ppStr "In a record update construct, no constructor has all these fields:")
+        4 (interpp'SP sty fields)
+  where
+    fields = [field | (field, _, _) <- rbinds]
+
+badFieldsCon con rbinds sty
+  = ppHang (ppBesides [ppStr "Inconsistent constructor:", ppr sty con])
+        4 (ppBesides [ppStr "and fields:", interpp'SP sty fields])
+  where
+    fields = [field | (field, _, _) <- rbinds]
+\end{code}
index 6a70127..3dfcc03 100644 (file)
@@ -73,8 +73,8 @@ import RnHsSyn                ( RenamedFixityDecl(..) )
 import RnMonad4                -- initRn4, etc.
 import RnUtils
 
 import RnMonad4                -- initRn4, etc.
 import RnUtils
 
-import Id              ( GenId, getDataConArity, getDataConTag,
-                         getDataConSig, fIRST_TAG,
+import Id              ( GenId, dataConArity, dataConTag,
+                         dataConSig, fIRST_TAG,
                          isDataCon, DataCon(..), ConTag(..) )
 import IdUtils         ( primOpId )
 import Maybes          ( maybeToBool )
                          isDataCon, DataCon(..), ConTag(..) )
 import IdUtils         ( primOpId )
 import Maybes          ( maybeToBool )
@@ -86,7 +86,7 @@ import PrelInfo
 import Pretty
 import ProtoName       ( ProtoName(..) )
 import SrcLoc          ( mkGeneratedSrcLoc )
 import Pretty
 import ProtoName       ( ProtoName(..) )
 import SrcLoc          ( mkGeneratedSrcLoc )
-import TyCon           ( TyCon, getTyConDataCons, isEnumerationTyCon, maybeTyConSingleCon )
+import TyCon           ( TyCon, tyConDataCons, isEnumerationTyCon, maybeTyConSingleCon )
 import Type            ( eqTy, isPrimType )
 import Unique
 import Util
 import Type            ( eqTy, isPrimType )
 import Unique
 import Util
@@ -175,8 +175,8 @@ instance ... Eq (Foo ...) where
 gen_Eq_binds :: TyCon -> ProtoNameMonoBinds
 
 gen_Eq_binds tycon
 gen_Eq_binds :: TyCon -> ProtoNameMonoBinds
 
 gen_Eq_binds tycon
-  = case (partition (\ con -> getDataConArity con == 0)
-                   (getTyConDataCons tycon))
+  = case (partition (\ con -> dataConArity con == 0)
+                   (tyConDataCons tycon))
     of { (nullary_cons, nonnullary_cons) ->
     let
        rest
     of { (nullary_cons, nonnullary_cons) ->
     let
        rest
@@ -201,9 +201,9 @@ gen_Eq_binds tycon
            con2_pat = ConPatIn data_con_PN (map VarPatIn bs_needed)
 
            data_con_PN = Prel (WiredInVal data_con)
            con2_pat = ConPatIn data_con_PN (map VarPatIn bs_needed)
 
            data_con_PN = Prel (WiredInVal data_con)
-           as_needed   = take (getDataConArity data_con) as_PNs
-           bs_needed   = take (getDataConArity data_con) bs_PNs
-           tys_needed  = case (getDataConSig data_con) of
+           as_needed   = take (dataConArity data_con) as_PNs
+           bs_needed   = take (dataConArity data_con) bs_PNs
+           tys_needed  = case (dataConSig data_con) of
                            (_,_, arg_tys, _) -> arg_tys
        in
        ([con1_pat, con2_pat], nested_eq_expr tys_needed as_needed bs_needed)
                            (_,_, arg_tys, _) -> arg_tys
        in
        ([con1_pat, con2_pat], nested_eq_expr tys_needed as_needed bs_needed)
@@ -342,7 +342,7 @@ gen_Ord_binds tycon
                    (cmp_tags_Expr ltH_PN ah_PN bh_PN ltTag_Expr gtTag_Expr)))
 
     (nullary_cons, nonnullary_cons)
                    (cmp_tags_Expr ltH_PN ah_PN bh_PN ltTag_Expr gtTag_Expr)))
 
     (nullary_cons, nonnullary_cons)
-      = partition (\ con -> getDataConArity con == 0) (getTyConDataCons tycon)
+      = partition (\ con -> dataConArity con == 0) (tyConDataCons tycon)
 
     cmp_eq
       = mk_FunMonoBind cmp_eq_PN (map pats_etc nonnullary_cons ++ deflt_pats_etc)
 
     cmp_eq
       = mk_FunMonoBind cmp_eq_PN (map pats_etc nonnullary_cons ++ deflt_pats_etc)
@@ -355,9 +355,9 @@ gen_Ord_binds tycon
            con2_pat = ConPatIn data_con_PN (map VarPatIn bs_needed)
 
            data_con_PN = Prel (WiredInVal data_con)
            con2_pat = ConPatIn data_con_PN (map VarPatIn bs_needed)
 
            data_con_PN = Prel (WiredInVal data_con)
-           as_needed   = take (getDataConArity data_con) as_PNs
-           bs_needed   = take (getDataConArity data_con) bs_PNs
-           tys_needed  = case (getDataConSig data_con) of
+           as_needed   = take (dataConArity data_con) as_PNs
+           bs_needed   = take (dataConArity data_con) bs_PNs
+           tys_needed  = case (dataConSig data_con) of
                            (_,_, arg_tys, _) -> arg_tys
 
            nested_compare_expr [ty] [a] [b]
                            (_,_, arg_tys, _) -> arg_tys
 
            nested_compare_expr [ty] [a] [b]
@@ -570,21 +570,21 @@ gen_Ix_binds tycon
       =        case maybeTyConSingleCon tycon of -- just checking...
          Nothing -> panic "get_Ix_binds"
          Just dc -> let
       =        case maybeTyConSingleCon tycon of -- just checking...
          Nothing -> panic "get_Ix_binds"
          Just dc -> let
-                        (_, _, arg_tys, _) = getDataConSig dc
+                        (_, _, arg_tys, _) = dataConSig dc
                     in
                     if any isPrimType arg_tys then
                         error ("ERROR: Can't derive Ix for a single-constructor type with primitive argument types: "++tycon_str)
                     else
                         dc
 
                     in
                     if any isPrimType arg_tys then
                         error ("ERROR: Can't derive Ix for a single-constructor type with primitive argument types: "++tycon_str)
                     else
                         dc
 
-    con_arity   = getDataConArity data_con
+    con_arity   = dataConArity data_con
     data_con_PN = Prel (WiredInVal data_con)
     con_pat  xs = ConPatIn data_con_PN (map VarPatIn xs)
     con_expr xs = foldl HsApp (HsVar data_con_PN) (map HsVar xs)
 
     data_con_PN = Prel (WiredInVal data_con)
     con_pat  xs = ConPatIn data_con_PN (map VarPatIn xs)
     con_expr xs = foldl HsApp (HsVar data_con_PN) (map HsVar xs)
 
-    as_needed = take (getDataConArity data_con) as_PNs
-    bs_needed = take (getDataConArity data_con) bs_PNs
-    cs_needed = take (getDataConArity data_con) cs_PNs
+    as_needed = take (dataConArity data_con) as_PNs
+    bs_needed = take (dataConArity data_con) bs_PNs
+    cs_needed = take (dataConArity data_con) cs_PNs
 
     --------------------------------------------------------------
     single_con_range
 
     --------------------------------------------------------------
     single_con_range
@@ -645,7 +645,7 @@ gen_Read_binds fixities tycon
     reads_prec
       = let
            read_con_comprehensions
     reads_prec
       = let
            read_con_comprehensions
-             = map read_con (getTyConDataCons tycon)
+             = map read_con (tyConDataCons tycon)
        in
        mk_easy_FunMonoBind readsPrec_PN [a_Pat, b_Pat] [] (
              foldl1 append_Expr read_con_comprehensions
        in
        mk_easy_FunMonoBind readsPrec_PN [a_Pat, b_Pat] [] (
              foldl1 append_Expr read_con_comprehensions
@@ -655,10 +655,10 @@ gen_Read_binds fixities tycon
          = let
                data_con_PN = Prel (WiredInVal data_con)
                data_con_str= snd  (getOrigName data_con)
          = let
                data_con_PN = Prel (WiredInVal data_con)
                data_con_str= snd  (getOrigName data_con)
-               as_needed   = take (getDataConArity data_con) as_PNs
-               bs_needed   = take (getDataConArity data_con) bs_PNs
+               as_needed   = take (dataConArity data_con) as_PNs
+               bs_needed   = take (dataConArity data_con) bs_PNs
                con_expr    = foldl HsApp (HsVar data_con_PN) (map HsVar as_needed)
                con_expr    = foldl HsApp (HsVar data_con_PN) (map HsVar as_needed)
-               nullary_con = getDataConArity data_con == 0
+               nullary_con = dataConArity data_con == 0
 
                con_qual
                  = GeneratorQual
 
                con_qual
                  = GeneratorQual
@@ -696,14 +696,14 @@ gen_Show_binds fixities tycon
                  (HsApp (HsVar _showList_PN) (HsApp (HsVar showsPrec_PN) (HsLit (HsInt 0))))
     -----------------------------------------------------------------------
     shows_prec
                  (HsApp (HsVar _showList_PN) (HsApp (HsVar showsPrec_PN) (HsLit (HsInt 0))))
     -----------------------------------------------------------------------
     shows_prec
-      = mk_FunMonoBind showsPrec_PN (map pats_etc (getTyConDataCons tycon))
+      = mk_FunMonoBind showsPrec_PN (map pats_etc (tyConDataCons tycon))
       where
        pats_etc data_con
          = let
                data_con_PN = Prel (WiredInVal data_con)
       where
        pats_etc data_con
          = let
                data_con_PN = Prel (WiredInVal data_con)
-               bs_needed   = take (getDataConArity data_con) bs_PNs
+               bs_needed   = take (dataConArity data_con) bs_PNs
                con_pat     = ConPatIn data_con_PN (map VarPatIn bs_needed)
                con_pat     = ConPatIn data_con_PN (map VarPatIn bs_needed)
-               nullary_con = getDataConArity data_con == 0
+               nullary_con = dataConArity data_con == 0
 
                show_con
                  = let (mod, nm)   = getOrigName data_con
 
                show_con
                  = let (mod, nm)   = getOrigName data_con
@@ -773,19 +773,19 @@ gen_tag_n_con_monobind
     -> ProtoNameMonoBinds
 
 gen_tag_n_con_monobind (pn, _, tycon, GenCon2Tag)
     -> ProtoNameMonoBinds
 
 gen_tag_n_con_monobind (pn, _, tycon, GenCon2Tag)
-  = mk_FunMonoBind pn (map mk_stuff (getTyConDataCons tycon))
+  = mk_FunMonoBind pn (map mk_stuff (tyConDataCons tycon))
   where
     mk_stuff :: DataCon -> ([ProtoNamePat], ProtoNameHsExpr)
 
     mk_stuff var
       = ASSERT(isDataCon var)
   where
     mk_stuff :: DataCon -> ([ProtoNamePat], ProtoNameHsExpr)
 
     mk_stuff var
       = ASSERT(isDataCon var)
-       ([pat], HsLit (HsIntPrim (toInteger ((getDataConTag var) - fIRST_TAG))))
+       ([pat], HsLit (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG))))
       where
       where
-       pat    = ConPatIn var_PN (nOfThem (getDataConArity var) WildPatIn)
+       pat    = ConPatIn var_PN (nOfThem (dataConArity var) WildPatIn)
        var_PN = Prel (WiredInVal var)
 
 gen_tag_n_con_monobind (pn, _, tycon, GenTag2Con)
        var_PN = Prel (WiredInVal var)
 
 gen_tag_n_con_monobind (pn, _, tycon, GenTag2Con)
-  = mk_FunMonoBind pn (map mk_stuff (getTyConDataCons tycon))
+  = mk_FunMonoBind pn (map mk_stuff (tyConDataCons tycon))
   where
     mk_stuff :: DataCon -> ([ProtoNamePat], ProtoNameHsExpr)
 
   where
     mk_stuff :: DataCon -> ([ProtoNamePat], ProtoNameHsExpr)
 
@@ -793,13 +793,13 @@ gen_tag_n_con_monobind (pn, _, tycon, GenTag2Con)
       = ASSERT(isDataCon var)
        ([lit_pat], HsVar var_PN)
       where
       = ASSERT(isDataCon var)
        ([lit_pat], HsVar var_PN)
       where
-       lit_pat = ConPatIn mkInt_PN [LitPatIn (HsIntPrim (toInteger ((getDataConTag var) - fIRST_TAG)))]
+       lit_pat = ConPatIn mkInt_PN [LitPatIn (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG)))]
        var_PN  = Prel (WiredInVal var)
 
 gen_tag_n_con_monobind (pn, _, tycon, GenMaxTag)
   = mk_easy_FunMonoBind pn [] [] (HsApp (HsVar mkInt_PN) (HsLit (HsIntPrim max_tag)))
   where
        var_PN  = Prel (WiredInVal var)
 
 gen_tag_n_con_monobind (pn, _, tycon, GenMaxTag)
   = mk_easy_FunMonoBind pn [] [] (HsApp (HsVar mkInt_PN) (HsLit (HsIntPrim max_tag)))
   where
-    max_tag =  case (getTyConDataCons tycon) of
+    max_tag =  case (tyConDataCons tycon) of
                 data_cons -> toInteger ((length data_cons) - fIRST_TAG)
 \end{code}
 
                 data_cons -> toInteger ((length data_cons) - fIRST_TAG)
 \end{code}
 
index 005fec5..996658b 100644 (file)
@@ -10,16 +10,21 @@ checker.
 module TcHsSyn (
        TcIdBndr(..), TcIdOcc(..),
        
 module TcHsSyn (
        TcIdBndr(..), TcIdOcc(..),
        
-       TcMonoBinds(..), TcHsBinds(..), TcBind(..), TcPat(..), TcExpr(..), TcGRHSsAndBinds(..),
-       TcGRHS(..), TcMatch(..), TcQual(..), TcStmt(..), TcArithSeqInfo(..), TcHsModule(..),
+       TcMonoBinds(..), TcHsBinds(..), TcBind(..), TcPat(..),
+       TcExpr(..), TcGRHSsAndBinds(..), TcGRHS(..), TcMatch(..),
+       TcQual(..), TcStmt(..), TcArithSeqInfo(..), TcRecordBinds(..),
+       TcHsModule(..),
        
        
-       TypecheckedHsBinds(..), TypecheckedBind(..), TypecheckedMonoBinds(..),
-       TypecheckedPat(..), TypecheckedHsExpr(..), TypecheckedArithSeqInfo(..),
-       TypecheckedQual(..), TypecheckedStmt(..), TypecheckedMatch(..), 
-       TypecheckedHsModule(..), TypecheckedGRHSsAndBinds(..), TypecheckedGRHS(..),
+       TypecheckedHsBinds(..), TypecheckedBind(..),
+       TypecheckedMonoBinds(..), TypecheckedPat(..),
+       TypecheckedHsExpr(..), TypecheckedArithSeqInfo(..),
+       TypecheckedQual(..), TypecheckedStmt(..),
+       TypecheckedMatch(..), TypecheckedHsModule(..),
+       TypecheckedGRHSsAndBinds(..), TypecheckedGRHS(..),
 
        mkHsTyApp, mkHsDictApp,
        mkHsTyLam, mkHsDictLam,
 
        mkHsTyApp, mkHsDictApp,
        mkHsTyLam, mkHsDictLam,
+       tcIdType,
 
        zonkBinds,
        zonkInst,
 
        zonkBinds,
        zonkInst,
@@ -32,7 +37,7 @@ import Ubiq{-uitous-}
 -- friends:
 import HsSyn   -- oodles of it
 import Id      ( GenId(..), IdDetails, PragmaInfo,     -- Can meddle modestly with Ids
 -- friends:
 import HsSyn   -- oodles of it
 import Id      ( GenId(..), IdDetails, PragmaInfo,     -- Can meddle modestly with Ids
-                 DictVar(..)
+                 DictVar(..), idType
                )
 
 -- others:
                )
 
 -- others:
@@ -76,6 +81,7 @@ type TcMatch s                = Match (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
 type TcQual s          = Qual (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
 type TcStmt s          = Stmt (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
 type TcArithSeqInfo s  = ArithSeqInfo (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
 type TcQual s          = Qual (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
 type TcStmt s          = Stmt (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
 type TcArithSeqInfo s  = ArithSeqInfo (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
+type TcRecordBinds s   = HsRecordBinds (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
 type TcHsModule s      = HsModule (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
 
 type TypecheckedPat            = OutPat        TyVar UVar Id
 type TcHsModule s      = HsModule (TcTyVar s) UVar (TcIdOcc s) (TcPat s)
 
 type TypecheckedPat            = OutPat        TyVar UVar Id
@@ -104,6 +110,10 @@ mkHsTyLam tyvars expr = TyLam tyvars expr
 
 mkHsDictLam []    expr = expr
 mkHsDictLam dicts expr = DictLam dicts expr
 
 mkHsDictLam []    expr = expr
 mkHsDictLam dicts expr = DictLam dicts expr
+
+tcIdType :: TcIdOcc s -> TcType s
+tcIdType (TcId id) = idType id
+tcIdType other     = panic "tcIdType"
 \end{code}
 
 
 \end{code}
 
 
index 6e3db5b..43d29fb 100644 (file)
@@ -25,13 +25,13 @@ import RnHsSyn              ( RenamedHsBinds(..), RenamedMonoBinds(..),
                          RenamedInstDecl(..), RenamedFixityDecl(..),
                          RenamedSig(..), RenamedSpecInstSig(..) )
 import TcHsSyn         ( TcIdOcc(..), TcHsBinds(..),
                          RenamedInstDecl(..), RenamedFixityDecl(..),
                          RenamedSig(..), RenamedSpecInstSig(..) )
 import TcHsSyn         ( TcIdOcc(..), TcHsBinds(..),
-                         TcMonoBinds(..), TcExpr(..),
+                         TcMonoBinds(..), TcExpr(..), tcIdType,
                          mkHsTyLam, mkHsTyApp,
                          mkHsDictLam, mkHsDictApp )
 
 
 import TcMonad
                          mkHsTyLam, mkHsTyApp,
                          mkHsDictLam, mkHsDictApp )
 
 
 import TcMonad
-import GenSpecEtc      ( checkSigTyVars, specTy )
+import GenSpecEtc      ( checkSigTyVars )
 import Inst            ( Inst, InstOrigin(..), InstanceMapper(..),
                          newDicts, newMethod, LIE(..), emptyLIE, plusLIE )
 import TcBinds         ( tcPragmaSigs )
 import Inst            ( Inst, InstOrigin(..), InstanceMapper(..),
                          newDicts, newMethod, LIE(..), emptyLIE, plusLIE )
 import TcBinds         ( tcPragmaSigs )
@@ -44,7 +44,8 @@ import TcMatches      ( tcMatchesFun )
 import TcMonoType      ( tcContext, tcMonoTypeKind )
 import TcSimplify      ( tcSimplifyAndCheck, tcSimplifyThetas )
 import TcType          ( TcType(..), TcTyVar(..),
 import TcMonoType      ( tcContext, tcMonoTypeKind )
 import TcSimplify      ( tcSimplifyAndCheck, tcSimplifyThetas )
 import TcType          ( TcType(..), TcTyVar(..),
-                         tcInstTyVar, tcInstType, tcInstTheta )
+                         tcInstSigTyVars, tcInstType, tcInstTheta
+                       )
 import Unify           ( unifyTauTy )
 
 
 import Unify           ( unifyTauTy )
 
 
@@ -64,7 +65,7 @@ import Name           ( Name, getTagFromClassOpName )
 import Outputable
 import PrelInfo                ( pAT_ERROR_ID )
 import PprType         ( GenType, GenTyVar, GenClass, GenClassOp, TyCon,
 import Outputable
 import PrelInfo                ( pAT_ERROR_ID )
 import PprType         ( GenType, GenTyVar, GenClass, GenClassOp, TyCon,
-                         pprParendType )
+                         pprParendGenType )
 import PprStyle
 import Pretty
 import RnUtils         ( GlobalNameMappers(..), GlobalNameMapper(..) )
 import PprStyle
 import Pretty
 import RnUtils         ( GlobalNameMappers(..), GlobalNameMapper(..) )
@@ -346,10 +347,8 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
     tcAddSrcLoc locn                                   $
 
        -- Get the class signature
     tcAddSrcLoc locn                                   $
 
        -- Get the class signature
-    mapNF_Tc tcInstTyVar inst_tyvars   `thenNF_Tc` \ inst_tyvars' ->
+    tcInstSigTyVars inst_tyvars                `thenNF_Tc` \ (inst_tyvars', _, tenv) ->
     let 
     let 
-       tenv = inst_tyvars `zip` (mkTyVarTys inst_tyvars')
-
         (class_tyvar,
         super_classes, sc_sel_ids,
         class_ops, op_sel_ids, defm_ids) = getClassBigSig clas
         (class_tyvar,
         super_classes, sc_sel_ids,
         class_ops, op_sel_ids, defm_ids) = getClassBigSig clas
@@ -378,9 +377,9 @@ tcInstDecl2 (InstInfo clas inst_tyvars inst_ty
 
        mk_method_expr
          = if opt_OmitDefaultInstanceMethods then
 
        mk_method_expr
          = if opt_OmitDefaultInstanceMethods then
-               makeInstanceDeclNoDefaultExpr origin clas meth_ids defm_ids inst_mod inst_ty'
+               makeInstanceDeclNoDefaultExpr     origin meth_ids defm_ids inst_ty' clas inst_mod
            else
            else
-               makeInstanceDeclDefaultMethodExpr origin this_dict_id class_ops defm_ids inst_ty'
+               makeInstanceDeclDefaultMethodExpr origin meth_ids defm_ids inst_ty' this_dict_id 
     in
     processInstBinds mk_method_expr inst_tyvars' avail_insts meth_ids monobinds
                                                `thenTc` \ (insts_needed, method_mbinds) ->
     in
     processInstBinds mk_method_expr inst_tyvars' avail_insts meth_ids monobinds
                                                `thenTc` \ (insts_needed, method_mbinds) ->
@@ -495,20 +494,18 @@ See the notes under default decls in TcClassDcl.lhs.
 \begin{code}
 makeInstanceDeclDefaultMethodExpr
        :: InstOrigin s
 \begin{code}
 makeInstanceDeclDefaultMethodExpr
        :: InstOrigin s
-       -> TcIdOcc s
-       -> [ClassOp]
+       -> [TcIdOcc s]
        -> [Id]
        -> TcType s
        -> [Id]
        -> TcType s
+       -> TcIdOcc s
        -> Int
        -> NF_TcM s (TcExpr s)
 
        -> Int
        -> NF_TcM s (TcExpr s)
 
-makeInstanceDeclDefaultMethodExpr origin this_dict class_ops defm_ids inst_ty tag
-  = specTy origin (getClassOpLocalType class_op)
-                               `thenNF_Tc` \ (op_tyvars, op_lie, op_tau, op_dicts) ->
+makeInstanceDeclDefaultMethodExpr origin meth_ids defm_ids inst_ty this_dict tag
+  = newDicts origin op_theta           `thenNF_Tc` \ (op_lie,op_dicts) ->
 
        -- def_op_id = /\ op_tyvars -> \ op_dicts ->
        --                defm_id inst_ty op_tyvars this_dict op_dicts
 
        -- def_op_id = /\ op_tyvars -> \ op_dicts ->
        --                defm_id inst_ty op_tyvars this_dict op_dicts
-
     returnNF_Tc (
       mkHsTyLam op_tyvars (
       mkHsDictLam op_dicts (
     returnNF_Tc (
       mkHsTyLam op_tyvars (
       mkHsDictLam op_dicts (
@@ -517,25 +514,23 @@ makeInstanceDeclDefaultMethodExpr origin this_dict class_ops defm_ids inst_ty ta
                  (this_dict : op_dicts)
       )))
  where
                  (this_dict : op_dicts)
       )))
  where
-    idx             = tag - 1
-    class_op = class_ops !! idx
-    defm_id  = defm_ids  !! idx
+    idx            = tag - 1
+    meth_id = meth_ids !! idx
+    defm_id = defm_ids  !! idx
+    (op_tyvars, op_theta, op_tau) = splitSigmaTy (tcIdType meth_id)
 
 makeInstanceDeclNoDefaultExpr
        :: InstOrigin s
 
 makeInstanceDeclNoDefaultExpr
        :: InstOrigin s
-       -> Class
        -> [TcIdOcc s]
        -> [Id]
        -> [TcIdOcc s]
        -> [Id]
-       -> FAST_STRING
        -> TcType s
        -> TcType s
+       -> Class
+       -> FAST_STRING
        -> Int
        -> NF_TcM s (TcExpr s)
 
        -> Int
        -> NF_TcM s (TcExpr s)
 
-makeInstanceDeclNoDefaultExpr origin clas method_occs defm_ids inst_mod inst_ty tag
-  = let
-       (op_tyvars,op_theta,op_tau) = splitSigmaTy (idType method_id)
-    in
-    newDicts origin op_theta           `thenNF_Tc` \ (op_lie,op_dicts) ->
+makeInstanceDeclNoDefaultExpr origin meth_ids defm_ids inst_ty clas inst_mod tag
+  = newDicts origin op_theta           `thenNF_Tc` \ (op_lie, op_dicts) ->
 
        -- Produce a warning if the default instance method
        -- has been omitted when one exists in the class
 
        -- Produce a warning if the default instance method
        -- has been omitted when one exists in the class
@@ -547,12 +542,12 @@ makeInstanceDeclNoDefaultExpr origin clas method_occs defm_ids inst_mod inst_ty
                 HsApp (mkHsTyApp (HsVar (RealId pAT_ERROR_ID)) [op_tau])
                     (HsLitOut (HsString (_PK_ error_msg)) stringTy))))
   where
                 HsApp (mkHsTyApp (HsVar (RealId pAT_ERROR_ID)) [op_tau])
                     (HsLitOut (HsString (_PK_ error_msg)) stringTy))))
   where
-    idx                   = tag - 1
-    method_occ     = method_occs  !! idx
-    clas_op        = (getClassOps clas) !! idx
-    defm_id        = defm_ids  !! idx
+    idx            = tag - 1
+    meth_id = meth_ids  !! idx
+    clas_op = (getClassOps clas) !! idx
+    defm_id = defm_ids  !! idx
+    (op_tyvars,op_theta,op_tau) = splitSigmaTy (tcIdType meth_id)
 
 
-    TcId method_id = method_occ
     Just (_, _, err_defm_ok) = isDefaultMethodId_maybe defm_id
 
     error_msg = "%E"   -- => No explicit method for \"
     Just (_, _, err_defm_ok) = isDefaultMethodId_maybe defm_id
 
     error_msg = "%E"   -- => No explicit method for \"
@@ -673,12 +668,6 @@ processInstBinds1 inst_tyvars avail_insts method_ids mbind
 
                -- Type check the method itself
        tcMethodBind method_id method_tau mbind `thenTc` \ (mbind', lieIop) ->
 
                -- Type check the method itself
        tcMethodBind method_id method_tau mbind `thenTc` \ (mbind', lieIop) ->
-
-               -- Make sure that the instance tyvars havn't been
-               -- unified with each other or with the method tyvars.
-       tcSetErrCtxt (methodSigCtxt op method_tau) (
-         checkSigTyVars inst_tyvars method_tau method_tau
-       )                                       `thenTc_`
        returnTc ([tag], lieIop, mbind')
 
       other -> -- It's a locally-polymorphic and/or overloaded method; UGH!
        returnTc ([tag], lieIop, mbind')
 
       other -> -- It's a locally-polymorphic and/or overloaded method; UGH!
@@ -696,12 +685,6 @@ processInstBinds1 inst_tyvars avail_insts method_ids mbind
                -- Typecheck the method
        tcMethodBind local_id method_tau mbind `thenTc` \ (mbind', lieIop) ->
 
                -- Typecheck the method
        tcMethodBind local_id method_tau mbind `thenTc` \ (mbind', lieIop) ->
 
-               -- Make sure that the instance tyvars haven't been
-               -- unified with each other or with the method tyvars.
-       tcAddErrCtxt (methodSigCtxt op method_tau) (
-         checkSigTyVars inst_method_tyvars method_tau method_tau
-       )                                       `thenTc_`
-
                -- Check the overloading part of the signature.
                -- Simplify everything fully, even though some
                -- constraints could "really" be left to the next
                -- Check the overloading part of the signature.
                -- Simplify everything fully, even though some
                -- constraints could "really" be left to the next
@@ -839,12 +822,12 @@ tcSpecInstSig e ce tce inst_infos inst_mapper (SpecInstSig class_name ty src_loc
        (ppAboves [ppCat [if null simpl_theta then ppNil else ppr PprDebug simpl_theta,
                          if null simpl_theta then ppNil else ppStr "=>",
                          ppr PprDebug clas,
        (ppAboves [ppCat [if null simpl_theta then ppNil else ppr PprDebug simpl_theta,
                          if null simpl_theta then ppNil else ppStr "=>",
                          ppr PprDebug clas,
-                         pprParendType PprDebug inst_ty],
+                         pprParendGenType PprDebug inst_ty],
                   ppCat [ppStr "        derived from:",
                          if null unspec_theta then ppNil else ppr PprDebug unspec_theta,
                          if null unspec_theta then ppNil else ppStr "=>",
                          ppr PprDebug clas,
                   ppCat [ppStr "        derived from:",
                          if null unspec_theta then ppNil else ppr PprDebug unspec_theta,
                          if null unspec_theta then ppNil else ppStr "=>",
                          ppr PprDebug clas,
-                         pprParendType PprDebug unspec_inst_ty]])
+                         pprParendGenType PprDebug unspec_inst_ty]])
     else id) (
 
     returnTc (unitBag (InstInfo clas inst_tmpls inst_ty simpl_theta
     else id) (
 
     returnTc (unitBag (InstInfo clas inst_tmpls inst_ty simpl_theta
@@ -962,7 +945,7 @@ nonBoxedPrimCCallErr clas inst_ty sty
 omitDefaultMethodWarn clas_op clas_name inst_ty sty
   = ppCat [ppStr "Warning: Omitted default method for",
           ppr sty clas_op, ppStr "in instance",
 omitDefaultMethodWarn clas_op clas_name inst_ty sty
   = ppCat [ppStr "Warning: Omitted default method for",
           ppr sty clas_op, ppStr "in instance",
-          ppPStr clas_name, pprParendType sty inst_ty]
+          ppPStr clas_name, pprParendGenType sty inst_ty]
 
 
 patMonoBindsCtxt pbind sty
 
 
 patMonoBindsCtxt pbind sty
index a233623..05b4a03 100644 (file)
@@ -11,7 +11,7 @@ module TcKind (
        unifyKind,      -- TcKind s -> TcKind s -> TcM s ()
 
        kindToTcKind,   -- Kind     -> TcKind s
        unifyKind,      -- TcKind s -> TcKind s -> TcM s ()
 
        kindToTcKind,   -- Kind     -> TcKind s
-       tcKindToKind    -- TcKind s -> NF_TcM s Kind
+       tcDefaultKind   -- TcKind s -> NF_TcM s Kind
   ) where
 
 import Kind
   ) where
 
 import Kind
@@ -77,7 +77,7 @@ I'm not convinced it would save time, and it's a little tricky to get right.
 unify_var uniq1 box1 kind2
   = tcReadMutVar box1  `thenNF_Tc` \ maybe_kind1 ->
     case maybe_kind1 of
 unify_var uniq1 box1 kind2
   = tcReadMutVar box1  `thenNF_Tc` \ maybe_kind1 ->
     case maybe_kind1 of
-      Just kind1 -> unify_kind kind1 kind1
+      Just kind1 -> unify_kind kind1 kind2
       Nothing    -> unify_unbound_var uniq1 box1 kind2
 
 unify_unbound_var uniq1 box1 kind2@(TcVarKind uniq2 box2)
       Nothing    -> unify_unbound_var uniq1 box1 kind2
 
 unify_unbound_var uniq1 box1 kind2@(TcVarKind uniq2 box2)
@@ -127,22 +127,27 @@ kindToTcKind UnboxedTypeKind   = TcTypeKind
 kindToTcKind (ArrowKind k1 k2) = TcArrowKind (kindToTcKind k1) (kindToTcKind k2)
 
 
 kindToTcKind (ArrowKind k1 k2) = TcArrowKind (kindToTcKind k1) (kindToTcKind k2)
 
 
-tcKindToKind :: TcKind s -> NF_TcM s Kind
+-- Default all unbound kinds to TcTypeKind, and return the
+-- corresponding Kind as well.
+tcDefaultKind :: TcKind s -> NF_TcM s Kind
 
 
-tcKindToKind TcTypeKind
-  = returnNF_Tc TypeKind
+tcDefaultKind TcTypeKind
+  = returnNF_Tc BoxedTypeKind
 
 
-tcKindToKind (TcArrowKind kind1 kind2)
-  = tcKindToKind kind1 `thenNF_Tc` \ k1 ->
-    tcKindToKind kind2 `thenNF_Tc` \ k2 ->
+tcDefaultKind (TcArrowKind kind1 kind2)
+  = tcDefaultKind kind1        `thenNF_Tc` \ k1 ->
+    tcDefaultKind kind2        `thenNF_Tc` \ k2 ->
     returnNF_Tc (ArrowKind k1 k2)
 
        -- Here's where we "default" unbound kinds to BoxedTypeKind
     returnNF_Tc (ArrowKind k1 k2)
 
        -- Here's where we "default" unbound kinds to BoxedTypeKind
-tcKindToKind (TcVarKind uniq box)
+tcDefaultKind (TcVarKind uniq box)
   = tcReadMutVar box   `thenNF_Tc` \ maybe_kind ->
     case maybe_kind of
   = tcReadMutVar box   `thenNF_Tc` \ maybe_kind ->
     case maybe_kind of
-       Nothing   -> returnNF_Tc BoxedTypeKind  -- Default is kind Type for unbound
-       Just kind -> tcKindToKind kind
+       Just kind -> tcDefaultKind kind
+
+       Nothing   ->    -- Default unbound variables to kind Type
+                    tcWriteMutVar box (Just TcTypeKind)        `thenNF_Tc_`
+                    returnNF_Tc BoxedTypeKind
 
 zonkTcKind :: TcKind s -> NF_TcM s (TcKind s)
 -- Removes variables that have now been bound.
 
 zonkTcKind :: TcKind s -> NF_TcM s (TcKind s)
 -- Removes variables that have now been bound.
@@ -200,6 +205,6 @@ kindMisMatchErr kind1 kind2 sty
  = ppHang (ppStr "Couldn't match the kind") 4
        (ppSep [ppBesides [ppStr "`", ppr sty kind1, ppStr "'"],
                ppStr "against",
  = ppHang (ppStr "Couldn't match the kind") 4
        (ppSep [ppBesides [ppStr "`", ppr sty kind1, ppStr "'"],
                ppStr "against",
-               ppBesides [ppStr "`", ppr sty kind1, ppStr "'"]
+               ppBesides [ppStr "`", ppr sty kind2, ppStr "'"]
        ])
 \end{code}
        ])
 \end{code}
index 31a3150..d5bae68 100644 (file)
@@ -210,7 +210,7 @@ matchCtxt MCase match sty
 
 matchCtxt (MFun fun) match sty
   = ppHang (ppBesides [ppStr "In an equation for function ", ppr sty fun, ppChar ':'])
 
 matchCtxt (MFun fun) match sty
   = ppHang (ppBesides [ppStr "In an equation for function ", ppr sty fun, ppChar ':'])
-        4 (ppBesides [ppr sty fun, pprMatch sty False{-not case-} match])
+        4 (ppBesides [ppr sty fun, ppSP, pprMatch sty False{-not case-} match])
 \end{code}
 
 
 \end{code}
 
 
index 4daf3b4..de24068 100644 (file)
@@ -61,7 +61,8 @@ tycon_specs = emptyFM
 \begin{code}
 tcModule :: GlobalNameMappers          -- final renamer info for derivings
         -> RenamedHsModule             -- input
 \begin{code}
 tcModule :: GlobalNameMappers          -- final renamer info for derivings
         -> RenamedHsModule             -- input
-        -> TcM s ((TypecheckedHsBinds, -- binds from class decls; does NOT
+        -> TcM s ((TypecheckedHsBinds, -- record selector binds
+                   TypecheckedHsBinds, -- binds from class decls; does NOT
                                        -- include default-methods bindings
                    TypecheckedHsBinds, -- binds from instance decls; INCLUDES
                                        -- class default-methods binds
                                        -- include default-methods bindings
                    TypecheckedHsBinds, -- binds from instance decls; INCLUDES
                                        -- class default-methods binds
@@ -94,17 +95,17 @@ tcModule renamer_name_funs
        -- pragmas, which is done lazily [ie failure just drops the pragma
        -- without having any global-failure effect].
 
        -- pragmas, which is done lazily [ie failure just drops the pragma
        -- without having any global-failure effect].
 
-    fixTc (\ ~(_, _, _, _, _, sig_ids) ->
+    fixTc (\ ~(_, _, _, _, _, _, sig_ids) ->
        tcExtendGlobalValEnv sig_ids (
 
        -- The knot for instance information.  This isn't used at all
        -- till we type-check value declarations
        tcExtendGlobalValEnv sig_ids (
 
        -- The knot for instance information.  This isn't used at all
        -- till we type-check value declarations
-       fixTc ( \ ~(rec_inst_mapper, _, _, _, _) ->
+       fixTc ( \ ~(rec_inst_mapper, _, _, _, _, _) ->
 
             -- Type-check the type and class decls
            trace "tcTyAndClassDecls:"  $
            tcTyAndClassDecls1 rec_inst_mapper ty_decls_bag cls_decls_bag
 
             -- Type-check the type and class decls
            trace "tcTyAndClassDecls:"  $
            tcTyAndClassDecls1 rec_inst_mapper ty_decls_bag cls_decls_bag
-                                       `thenTc` \ env ->
+                                       `thenTc` \ (env, record_binds) ->
 
                -- Typecheck the instance decls, includes deriving
            tcSetEnv env (
 
                -- Typecheck the instance decls, includes deriving
            tcSetEnv env (
@@ -115,9 +116,9 @@ tcModule renamer_name_funs
 
            buildInstanceEnvs inst_info `thenTc` \ inst_mapper ->
 
 
            buildInstanceEnvs inst_info `thenTc` \ inst_mapper ->
 
-           returnTc (inst_mapper, env, inst_info, deriv_binds, ddump_deriv)
+           returnTc (inst_mapper, env, record_binds, inst_info, deriv_binds, ddump_deriv)
 
 
-       ) `thenTc` \ (_, env, inst_info, deriv_binds, ddump_deriv) ->
+       ) `thenTc` \ (_, env, record_binds, inst_info, deriv_binds, ddump_deriv) ->
        tcSetEnv env (
 
            -- Default declarations
        tcSetEnv env (
 
            -- Default declarations
@@ -132,9 +133,9 @@ tcModule renamer_name_funs
            --   we silently discard the pragma
        tcInterfaceSigs sigs            `thenTc` \ sig_ids ->
 
            --   we silently discard the pragma
        tcInterfaceSigs sigs            `thenTc` \ sig_ids ->
 
-       returnTc (env, inst_info, deriv_binds, ddump_deriv, defaulting_tys, sig_ids)
+       returnTc (env, inst_info, record_binds, deriv_binds, ddump_deriv, defaulting_tys, sig_ids)
 
 
-    )))) `thenTc` \ (env, inst_info, deriv_binds, ddump_deriv, defaulting_tys, _) ->
+    )))) `thenTc` \ (env, inst_info, record_binds, deriv_binds, ddump_deriv, defaulting_tys, _) ->
 
     tcSetEnv env (                             -- to the end...
     tcSetDefaultTys defaulting_tys (           -- ditto
 
     tcSetEnv env (                             -- to the end...
     tcSetDefaultTys defaulting_tys (           -- ditto
@@ -181,6 +182,7 @@ tcModule renamer_name_funs
        -- simplification step may have instantiated some
        -- ambiguous types.  So, sadly, we need to back-substitute
        -- over the whole bunch of bindings.
        -- simplification step may have instantiated some
        -- ambiguous types.  So, sadly, we need to back-substitute
        -- over the whole bunch of bindings.
+    zonkBinds record_binds             `thenNF_Tc` \ record_binds' ->
     zonkBinds val_binds                        `thenNF_Tc` \ val_binds' ->
     zonkBinds inst_binds               `thenNF_Tc` \ inst_binds' ->
     zonkBinds cls_binds                        `thenNF_Tc` \ cls_binds' ->
     zonkBinds val_binds                        `thenNF_Tc` \ val_binds' ->
     zonkBinds inst_binds               `thenNF_Tc` \ inst_binds' ->
     zonkBinds cls_binds                        `thenNF_Tc` \ cls_binds' ->
@@ -189,7 +191,7 @@ tcModule renamer_name_funs
 
        -- FINISHED AT LAST
     returnTc (
 
        -- FINISHED AT LAST
     returnTc (
-       (cls_binds', inst_binds', val_binds', const_insts'),
+       (record_binds', cls_binds', inst_binds', val_binds', const_insts'),
 
             -- the next collection is just for mkInterface
        (fixities, exported_ids', tycons, classes, inst_info),
 
             -- the next collection is just for mkInterface
        (fixities, exported_ids', tycons, classes, inst_info),
index 59b9967..2ea7586 100644 (file)
@@ -26,6 +26,9 @@ module TcMonad(
 
        rn4MtoTcM,
 
 
        rn4MtoTcM,
 
+       TcError(..), TcWarning(..), Message(..),
+       mkTcErr, arityErr,
+
        -- For closure
        MutableVar(..), _MutableArray
   ) where
        -- For closure
        MutableVar(..), _MutableArray
   ) where
@@ -36,8 +39,6 @@ import TcMLoop                ( TcEnv, initEnv, TcMaybe )  -- We need the type TcEnv and an in
 import Type            ( Type(..), GenType )
 import TyVar           ( TyVar(..), GenTyVar )
 import Usage           ( Usage(..), GenUsage )
 import Type            ( Type(..), GenType )
 import TyVar           ( TyVar(..), GenTyVar )
 import Usage           ( Usage(..), GenUsage )
-import ErrUtils                ( Error(..), Message(..), ErrCtxt(..),
-                         TcWarning(..), TcError(..), mkTcErr )
 
 import SST
 import RnMonad4
 
 import SST
 import RnMonad4
@@ -46,9 +47,8 @@ import RnUtils                ( GlobalNameMappers(..), GlobalNameMapper(..) )
 import Bag             ( Bag, emptyBag, isEmptyBag,
                          foldBag, unitBag, unionBags, snocBag )
 import FiniteMap       ( FiniteMap, emptyFM )
 import Bag             ( Bag, emptyBag, isEmptyBag,
                          foldBag, unitBag, unionBags, snocBag )
 import FiniteMap       ( FiniteMap, emptyFM )
-import Pretty          ( Pretty(..), PrettyRep )
-import PprStyle                ( PprStyle )
 import Outputable      ( Outputable(..), NamedThing(..), ExportFlag )
 import Outputable      ( Outputable(..), NamedThing(..), ExportFlag )
+import ErrUtils                ( Error(..) )
 import Maybes          ( MaybeErr(..) )
 import Name            ( Name )
 import ProtoName       ( ProtoName )
 import Maybes          ( MaybeErr(..) )
 import Name            ( Name )
 import ProtoName       ( ProtoName )
@@ -57,6 +57,8 @@ import UniqFM         ( UniqFM, emptyUFM )
 import UniqSupply      ( UniqSupply, getUnique, getUniques, splitUniqSupply )
 import Unique          ( Unique )
 import Util
 import UniqSupply      ( UniqSupply, getUnique, getUniques, splitUniqSupply )
 import Unique          ( Unique )
 import Util
+import Pretty
+import PprStyle                ( PprStyle(..) )
 
 infixr 9 `thenTc`, `thenTc_`, `thenNF_Tc`, `thenNF_Tc_` 
 \end{code}
 
 infixr 9 `thenTc`, `thenTc_`, `thenNF_Tc`, `thenNF_Tc_` 
 \end{code}
@@ -226,8 +228,8 @@ Error handling
 \begin{code}
 failTc :: Message -> TcM s a
 failTc err_msg down env
 \begin{code}
 failTc :: Message -> TcM s a
 failTc err_msg down env
-  = readMutVarSST errs_var                             `thenSST` \ (warns,errs) ->
-    foldr thenNF_Tc_ (returnNF_Tc []) ctxt down env    `thenSST` \ ctxt_msgs ->
+  = readMutVarSST errs_var     `thenSST` \ (warns,errs) ->
+    listNF_Tc ctxt down env    `thenSST` \ ctxt_msgs ->
     let
        err = mkTcErr loc ctxt_msgs err_msg
     in
     let
        err = mkTcErr loc ctxt_msgs err_msg
     in
@@ -442,3 +444,37 @@ rn4MtoTcM name_funs rn_action down env
   where
     u_var = getUniqSupplyVar down
 \end{code}
   where
     u_var = getUniqSupplyVar down
 \end{code}
+
+
+TypeChecking Errors
+~~~~~~~~~~~~~~~~~~~
+
+\begin{code}
+type Message   = PprStyle -> Pretty
+type TcError   = Message
+type TcWarning = Message
+
+
+mkTcErr :: SrcLoc              -- Where
+       -> [Message]            -- Context
+       -> Message              -- What went wrong
+       -> TcError              -- The complete error report
+
+mkTcErr locn ctxt msg sty
+  = ppHang (ppBesides [ppr PprForUser locn, ppStr ": ", msg sty])
+        4 (ppAboves [msg sty | msg <- ctxt])
+
+
+arityErr kind name n m sty
+  = ppBesides [ ppStr "`", ppr sty name, ppStr "' should have ",
+               n_arguments, ppStr ", but has been given ", ppInt m, ppChar '.']
+    where
+       errmsg = kind ++ " has too " ++ quantity ++ " arguments"
+       quantity | m < n     = "few"
+                | otherwise = "many"
+       n_arguments | n == 0 = ppStr "no arguments"
+                   | n == 1 = ppStr "1 argument"
+                   | True   = ppCat [ppInt n, ppStr "arguments"]
+\end{code}
+
+
index 91b1677..1825cdf 100644 (file)
@@ -24,9 +24,8 @@ import TcKind         ( TcKind, mkTcTypeKind, mkBoxedTypeKind,
                          mkTcArrowKind, unifyKind, newKindVar,
                          kindToTcKind
                        )
                          mkTcArrowKind, unifyKind, newKindVar,
                          kindToTcKind
                        )
-import ErrUtils                ( arityErr )
 import Type            ( GenType, Type(..), ThetaType(..), 
 import Type            ( GenType, Type(..), ThetaType(..), 
-                         mkTyVarTy, mkTyConTy, mkFunTy, mkAppTy,
+                         mkTyVarTy, mkTyConTy, mkFunTy, mkAppTy, mkSynTy,
                          mkSigmaTy
                        )
 import TyVar           ( GenTyVar, TyVar(..), mkTyVar )
                          mkSigmaTy
                        )
 import TyVar           ( GenTyVar, TyVar(..), mkTyVar )
@@ -79,26 +78,18 @@ tcMonoTypeKind (MonoFunTy ty1 ty2)
     tcMonoType ty2     `thenTc` \ tau_ty2 ->
     returnTc (mkTcTypeKind, mkFunTy tau_ty1 tau_ty2)
 
     tcMonoType ty2     `thenTc` \ tau_ty2 ->
     returnTc (mkTcTypeKind, mkFunTy tau_ty1 tau_ty2)
 
-tcMonoTypeKind (MonoTyApp name tys)
-  = mapAndUnzipTc tcMonoTypeKind tys   `thenTc`    \ (arg_kinds, arg_tys) ->
-
-    tc_mono_name name                  `thenNF_Tc` \ (fun_kind, maybe_arity, fun_ty) ->
-
-    newKindVar                         `thenNF_Tc` \ result_kind ->
-    unifyKind fun_kind (foldr mkTcArrowKind result_kind arg_kinds)     `thenTc_`
-
-       -- Check for saturated application in the special case of
-       -- type synoyms.
-    (case maybe_arity of
-       Just arity | arity /= n_args -> failTc (err arity)
-       other                        -> returnTc ()
-    )                                                                  `thenTc_`
-
-    returnTc (result_kind, foldl mkAppTy fun_ty arg_tys)
-  where
-    err arity = arityErr "Type synonym constructor" name arity n_args
-    n_args    = length tys
+tcMonoTypeKind (MonoTyApp name@(Short _ _) tys)
+  =    -- Must be a type variable
+    tcLookupTyVar name                 `thenNF_Tc` \ (kind,tyvar) ->
+    tcMonoTyApp kind (mkTyVarTy tyvar) tys
 
 
+tcMonoTypeKind (MonoTyApp name tys)
+  | isTyConName name   -- Must be a type constructor
+  = tcLookupTyCon name                 `thenNF_Tc` \ (kind,maybe_arity,tycon) ->
+    case maybe_arity of
+       Just arity -> tcSynApp name kind arity tycon tys        -- synonum
+       Nothing    -> tcMonoTyApp kind (mkTyConTy tycon) tys    -- newtype or data
+       
 -- for unfoldings only:
 tcMonoTypeKind (MonoForAllTy tyvars_w_kinds ty)
   = tcTyVarScopeGivenKinds names tc_kinds (\ tyvars ->
 -- for unfoldings only:
 tcMonoTypeKind (MonoForAllTy tyvars_w_kinds ty)
   = tcTyVarScopeGivenKinds names tc_kinds (\ tyvars ->
@@ -116,19 +107,28 @@ tcMonoTypeKind (MonoDictTy class_name ty)
     tcLookupClass class_name           `thenNF_Tc` \ (class_kind, clas) ->
     unifyKind class_kind arg_kind      `thenTc_`
     returnTc (mkTcTypeKind, mkDictTy clas arg_ty)
     tcLookupClass class_name           `thenNF_Tc` \ (class_kind, clas) ->
     unifyKind class_kind arg_kind      `thenTc_`
     returnTc (mkTcTypeKind, mkDictTy clas arg_ty)
+\end{code}
 
 
+Help functions for type applications
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+\begin{code}
+tcMonoTyApp fun_kind fun_ty tys
+  = mapAndUnzipTc tcMonoTypeKind tys   `thenTc`    \ (arg_kinds, arg_tys) ->
+    newKindVar                         `thenNF_Tc` \ result_kind ->
+    unifyKind fun_kind (foldr mkTcArrowKind result_kind arg_kinds)     `thenTc_`
+    returnTc (result_kind, foldl mkAppTy fun_ty arg_tys)
 
 
-tc_mono_name :: Name -> NF_TcM s (TcKind s, Maybe Arity, Type)
-tc_mono_name name@(Short _ _)          -- Must be a type variable
-  = tcLookupTyVar name                 `thenNF_Tc` \ (kind,tyvar) ->
-    returnNF_Tc (kind, Nothing, mkTyVarTy tyvar)
+tcSynApp name syn_kind arity tycon tys
+  = mapAndUnzipTc tcMonoTypeKind tys   `thenTc`    \ (arg_kinds, arg_tys) ->
+    newKindVar                         `thenNF_Tc` \ result_kind ->
+    unifyKind syn_kind (foldr mkTcArrowKind result_kind arg_kinds)     `thenTc_`
 
 
-tc_mono_name name | isTyConName name   -- Must be a type constructor
-  = tcLookupTyCon name                 `thenNF_Tc` \ (kind,maybe_arity,tycon) ->
-    returnNF_Tc (kind, maybe_arity, mkTyConTy tycon)
-       
-tc_mono_name name                      -- Renamer should have got it right
-  = panic ("tc_mono_name:" ++ ppShow 1000 (ppr PprDebug name))
+       -- Check that it's applied to the right number of arguments
+    checkTc (arity == n_args) (err arity)                              `thenTc_`
+    returnTc (result_kind, mkSynTy tycon arg_tys)
+  where
+    err arity = arityErr "Type synonym constructor" name arity n_args
+    n_args    = length tys
 \end{code}
 
 
 \end{code}
 
 
index 52e9f05..dfd92d1 100644 (file)
@@ -17,28 +17,33 @@ import RnHsSyn              ( RenamedPat(..) )
 import TcHsSyn         ( TcPat(..), TcIdOcc(..) )
 
 import TcMonad
 import TcHsSyn         ( TcPat(..), TcIdOcc(..) )
 
 import TcMonad
-import Inst            ( Inst, OverloadedLit(..), InstOrigin(..), LIE(..),
-                         emptyLIE, plusLIE, newMethod, newOverloadedLit )
+import Inst            ( Inst, OverloadedLit(..), InstOrigin(..),
+                         emptyLIE, plusLIE, plusLIEs, LIE(..),
+                         newMethod, newOverloadedLit
+                       )
 import TcEnv           ( tcLookupGlobalValue, tcLookupGlobalValueByKey, 
 import TcEnv           ( tcLookupGlobalValue, tcLookupGlobalValueByKey, 
-                         tcLookupLocalValueOK )
+                         tcLookupLocalValueOK, tcGlobalOcc )
 import TcType          ( TcType(..), TcMaybe, tcInstType, newTyVarTy, newTyVarTys )
 import Unify           ( unifyTauTy, unifyTauTyList, unifyTauTyLists )
 
 import Bag             ( Bag )
 import CmdLineOpts     ( opt_IrrefutableTuples )
 import TcType          ( TcType(..), TcMaybe, tcInstType, newTyVarTy, newTyVarTys )
 import Unify           ( unifyTauTy, unifyTauTyList, unifyTauTyLists )
 
 import Bag             ( Bag )
 import CmdLineOpts     ( opt_IrrefutableTuples )
-import ErrUtils                ( arityErr )
 import Id              ( GenId, idType )
 import Kind            ( Kind, mkBoxedTypeKind, mkTypeKind )
 import Id              ( GenId, idType )
 import Kind            ( Kind, mkBoxedTypeKind, mkTypeKind )
+import Maybes          ( maybeToBool )
 import Name            ( Name )
 import PprType         ( GenType, GenTyVar )
 import PrelInfo                ( charPrimTy, intPrimTy, floatPrimTy,
                          doublePrimTy, charTy, stringTy, mkListTy,
                          mkTupleTy, addrTy, addrPrimTy )
 import Pretty
 import Name            ( Name )
 import PprType         ( GenType, GenTyVar )
 import PrelInfo                ( charPrimTy, intPrimTy, floatPrimTy,
                          doublePrimTy, charTy, stringTy, mkListTy,
                          mkTupleTy, addrTy, addrPrimTy )
 import Pretty
-import Type            ( Type(..), GenType, splitFunTy, splitSigmaTy )
+import Type            ( splitFunTy, splitRhoTy, splitSigmaTy, mkTyVarTys,
+                         getFunTy_maybe, maybeAppDataTyCon,
+                         Type(..), GenType
+                       )
 import TyVar           ( GenTyVar )
 import Unique          ( Unique, eqClassOpKey )
 import TyVar           ( GenTyVar )
 import Unique          ( Unique, eqClassOpKey )
-
+import Util            ( assertPanic, panic{-ToDo:rm-} )
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -147,25 +152,21 @@ efficient?
 
 \begin{code}
 tcPat pat_in@(ConPatIn name pats)
 
 \begin{code}
 tcPat pat_in@(ConPatIn name pats)
-  = tcLookupGlobalValue name           `thenNF_Tc` \ con_id ->
-
-    tcPats pats                                `thenTc` \ (pats', lie, tys) ->
+  = tcPats pats                                `thenTc` \ (pats', lie, tys) ->
 
     tcAddErrCtxt (patCtxt pat_in)      $
 
     tcAddErrCtxt (patCtxt pat_in)      $
-    matchConArgTys con_id tys          `thenTc` \ data_ty ->
+    matchConArgTys name tys            `thenTc` \ (con_id, data_ty) ->
 
     returnTc (ConPat con_id data_ty pats', 
              lie, 
              data_ty)
 
 tcPat pat_in@(ConOpPatIn pat1 op pat2) -- & in binary-op form...
 
     returnTc (ConPat con_id data_ty pats', 
              lie, 
              data_ty)
 
 tcPat pat_in@(ConOpPatIn pat1 op pat2) -- & in binary-op form...
-  = tcLookupGlobalValue op             `thenNF_Tc` \ con_id ->
-
-    tcPat pat1                         `thenTc` \ (pat1', lie1, ty1) ->
+  = tcPat pat1                         `thenTc` \ (pat1', lie1, ty1) ->
     tcPat pat2                         `thenTc` \ (pat2', lie2, ty2) ->
 
     tcAddErrCtxt (patCtxt pat_in)      $
     tcPat pat2                         `thenTc` \ (pat2', lie2, ty2) ->
 
     tcAddErrCtxt (patCtxt pat_in)      $
-    matchConArgTys con_id [ty1,ty2]    `thenTc` \ data_ty ->
+    matchConArgTys op [ty1,ty2]        `thenTc` \ (con_id, data_ty) ->
 
     returnTc (ConOpPat pat1' con_id pat2' data_ty, 
              lie1 `plusLIE` lie2, 
 
     returnTc (ConOpPat pat1' con_id pat2' data_ty, 
              lie1 `plusLIE` lie2, 
@@ -174,6 +175,52 @@ tcPat pat_in@(ConOpPatIn pat1 op pat2) -- & in binary-op form...
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
+\subsection{Records}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+tcPat pat_in@(RecPatIn name rpats)
+  = tcGlobalOcc name           `thenNF_Tc` \ (con_id, _, con_rho) ->
+    let
+       (_, con_tau) = splitRhoTy con_rho
+            -- Ignore the con_theta; overloaded constructors only
+            -- behave differently when called, not when used for
+            -- matching.
+       (_, record_ty) = splitFunTy con_tau
+    in
+       -- Con is syntactically constrained to be a data constructor
+    ASSERT( maybeToBool (maybeAppDataTyCon record_ty ) )
+
+    mapAndUnzipTc (do_bind record_ty) rpats    `thenTc` \ (rpats', lies) ->
+
+    returnTc (panic "tcPat:RecPatIn:avoid type errors"{-RecPat con_id record_ty rpats', 
+             plusLIEs lies, 
+             record_ty-})
+
+  where
+    do_bind expected_record_ty (field_label, rhs_pat, pun_flag)
+      = tcGlobalOcc field_label                `thenNF_Tc` \ (sel_id, _, tau) ->
+
+               -- Record selectors all have type
+               --      forall a1..an.  T a1 .. an -> tau
+       ASSERT( maybeToBool (getFunTy_maybe tau) )
+       let
+               -- Selector must have type RecordType -> FieldType
+         Just (record_ty, field_ty) = getFunTy_maybe tau
+       in
+       tcAddErrCtxt (recordLabel field_label) (
+         unifyTauTy expected_record_ty record_ty
+       )                                               `thenTc_`
+       tcPat rhs_pat                                   `thenTc` \ (rhs_pat', lie, rhs_ty) ->
+       tcAddErrCtxt (recordRhs field_label rhs_pat) (
+         unifyTauTy field_ty rhs_ty
+       )                                               `thenTc_`
+       returnTc ((sel_id, rhs_pat', pun_flag), lie)
+\end{code}
+
+%************************************************************************
+%*                                                                     *
 \subsection{Non-overloaded literals}
 %*                                                                     *
 %************************************************************************
 \subsection{Non-overloaded literals}
 %*                                                                     *
 %************************************************************************
@@ -266,24 +313,25 @@ tcPats (pat:pats)
 unifies the actual args against the expected ones.
 
 \begin{code}
 unifies the actual args against the expected ones.
 
 \begin{code}
-matchConArgTys :: Id -> [TcType s] -> TcM s (TcType s)
+matchConArgTys :: Name -> [TcType s] -> TcM s (Id, TcType s)
 
 
-matchConArgTys con_id arg_tys
-  = tcInstType [] (idType con_id)              `thenNF_Tc` \ con_ty ->
+matchConArgTys con arg_tys
+  = tcGlobalOcc con            `thenNF_Tc` \ (con_id, _, con_rho) ->
     let
     let
-       no_of_args = length arg_tys
-       (con_tyvars, con_theta, con_tau) = splitSigmaTy con_ty
-            -- Ignore the sig_theta; overloaded constructors only
+       (con_theta, con_tau) = splitRhoTy con_rho
+            -- Ignore the con_theta; overloaded constructors only
             -- behave differently when called, not when used for
             -- matching.
             -- behave differently when called, not when used for
             -- matching.
+
        (con_args, con_result) = splitFunTy con_tau
        con_arity  = length con_args
        (con_args, con_result) = splitFunTy con_tau
        con_arity  = length con_args
+       no_of_args = length arg_tys
     in
     checkTc (con_arity == no_of_args)
            (arityErr "Constructor" con_id con_arity no_of_args)        `thenTc_`
 
     unifyTauTyLists arg_tys con_args                                   `thenTc_`
     in
     checkTc (con_arity == no_of_args)
            (arityErr "Constructor" con_id con_arity no_of_args)        `thenTc_`
 
     unifyTauTyLists arg_tys con_args                                   `thenTc_`
-    returnTc con_result
+    returnTc (con_id, con_result)
 \end{code}
 
 
 \end{code}
 
 
@@ -293,4 +341,12 @@ Errors and contexts
 ~~~~~~~~~~~~~~~~~~~
 \begin{code}
 patCtxt pat sty = ppHang (ppStr "In the pattern:") 4 (ppr sty pat)
 ~~~~~~~~~~~~~~~~~~~
 \begin{code}
 patCtxt pat sty = ppHang (ppStr "In the pattern:") 4 (ppr sty pat)
+
+recordLabel field_label sty
+  = ppHang (ppBesides [ppStr "When matching record field", ppr sty field_label])
+        4 (ppBesides [ppStr "with its immediately enclosing constructor"])
+
+recordRhs field_label pat sty
+  = ppHang (ppStr "In the record field pattern")
+        4 (ppSep [ppr sty field_label, ppStr "=", ppr sty pat])
 \end{code}
 \end{code}
index 12b7009..59153c5 100644 (file)
@@ -665,7 +665,7 @@ tcDataPragmas rec_tce tve rec_tycon new_tyvars (DataPragmas con_decls specs)
                                      (length new_tyvars) maybe_tys locn)
                                `thenB_Tc_`
 
                                      (length new_tyvars) maybe_tys locn)
                                `thenB_Tc_`
 
-       checkB_Tc (not (all isUnboxedDataType (catMaybes maybe_tys)))
+       checkB_Tc (not (all isUnboxedType (catMaybes maybe_tys)))
                (badSpecialisationErr "data" "not all unboxed types"
                                      (length new_tyvars) maybe_tys locn)
                                `thenB_Tc_`
                (badSpecialisationErr "data" "not all unboxed types"
                                      (length new_tyvars) maybe_tys locn)
                                `thenB_Tc_`
index 205c881..b2afd9f 100644 (file)
@@ -14,8 +14,9 @@ import Ubiq{-uitous-}
 
 import HsSyn           ( TyDecl(..),  ConDecl(..), BangType(..),
                          ClassDecl(..), MonoType(..), PolyType(..),
 
 import HsSyn           ( TyDecl(..),  ConDecl(..), BangType(..),
                          ClassDecl(..), MonoType(..), PolyType(..),
-                         Sig(..), MonoBinds, Fake, InPat )
+                         Sig(..), MonoBinds, Fake, InPat, HsBinds(..), Bind, HsExpr )
 import RnHsSyn         ( RenamedTyDecl(..), RenamedClassDecl(..) )
 import RnHsSyn         ( RenamedTyDecl(..), RenamedClassDecl(..) )
+import TcHsSyn         ( TcHsBinds(..), TcIdOcc(..) )
 
 import TcMonad
 import Inst            ( InstanceMapper(..) )
 
 import TcMonad
 import Inst            ( InstanceMapper(..) )
@@ -24,7 +25,7 @@ import TcEnv          ( tcExtendTyConEnv, tcExtendClassEnv,
                          tcExtendGlobalValEnv, 
                          tcTyVarScope, tcGetEnv )
 import TcKind          ( TcKind, newKindVars )
                          tcExtendGlobalValEnv, 
                          tcTyVarScope, tcGetEnv )
 import TcKind          ( TcKind, newKindVars )
-import TcTyDecls       ( tcTyDecl )
+import TcTyDecls       ( tcTyDecl, tcRecordSelectors )
 
 import Bag     
 import Class           ( Class(..), getClassSelIds )
 
 import Bag     
 import Class           ( Class(..), getClassSelIds )
@@ -33,10 +34,10 @@ import Name         ( Name, isTyConName )
 import PprStyle
 import Pretty
 import UniqSet         ( UniqSet(..), emptyUniqSet,
 import PprStyle
 import Pretty
 import UniqSet         ( UniqSet(..), emptyUniqSet,
-                         singletonUniqSet, unionUniqSets, 
+                         unitUniqSet, unionUniqSets, 
                          unionManyUniqSets, uniqSetToList ) 
 import SrcLoc          ( SrcLoc )
                          unionManyUniqSets, uniqSetToList ) 
 import SrcLoc          ( SrcLoc )
-import TyCon           ( TyCon, getTyConDataCons )
+import TyCon           ( TyCon, tyConDataCons )
 import Unique          ( Unique )
 import Util            ( panic, pprTrace )
 
 import Unique          ( Unique )
 import Util            ( panic, pprTrace )
 
@@ -49,7 +50,7 @@ data Decl = TyD RenamedTyDecl | ClD RenamedClassDecl
 
 tcTyAndClassDecls1 :: InstanceMapper
                   -> Bag RenamedTyDecl -> Bag RenamedClassDecl
 
 tcTyAndClassDecls1 :: InstanceMapper
                   -> Bag RenamedTyDecl -> Bag RenamedClassDecl
-                  -> TcM s (TcEnv s)
+                  -> TcM s (TcEnv s, TcHsBinds s)
 
 tcTyAndClassDecls1 inst_mapper rnty_decls rncls_decls
   = sortByDependency syn_decls cls_decls decls `thenTc` \ groups ->
 
 tcTyAndClassDecls1 inst_mapper rnty_decls rncls_decls
   = sortByDependency syn_decls cls_decls decls `thenTc` \ groups ->
@@ -65,22 +66,24 @@ tcTyAndClassDecls1 inst_mapper rnty_decls rncls_decls
 
 tcGroups inst_mapper []
   = tcGetEnv           `thenNF_Tc` \ env ->
 
 tcGroups inst_mapper []
   = tcGetEnv           `thenNF_Tc` \ env ->
-    returnTc env
+    returnTc (env, EmptyBinds)
 
 tcGroups inst_mapper (group:groups)
 
 tcGroups inst_mapper (group:groups)
-  = tcGroup inst_mapper group  `thenTc` \ new_env ->
+  = tcGroup inst_mapper group  `thenTc` \ (new_env, binds1) ->
 
        -- Extend the environment using the new tycons and classes
     tcSetEnv new_env $
 
        -- Do the remaining groups
 
        -- Extend the environment using the new tycons and classes
     tcSetEnv new_env $
 
        -- Do the remaining groups
-    tcGroups inst_mapper groups
+    tcGroups inst_mapper groups        `thenTc` \ (final_env, binds2) ->
+
+    returnTc (final_env, binds1 `ThenBinds` binds2)
 \end{code}
 
 Dealing with a group
 ~~~~~~~~~~~~~~~~~~~~
 \begin{code}
 \end{code}
 
 Dealing with a group
 ~~~~~~~~~~~~~~~~~~~~
 \begin{code}
-tcGroup :: InstanceMapper -> Bag Decl -> TcM s (TcEnv s)
+tcGroup :: InstanceMapper -> Bag Decl -> TcM s (TcEnv s, TcHsBinds s)
 tcGroup inst_mapper decls
   = pprTrace "tcGroup: " (ppCat (map (fst.fmt_decl) (bagToList decls))) $
 
 tcGroup inst_mapper decls
   = pprTrace "tcGroup: " (ppCat (map (fst.fmt_decl) (bagToList decls))) $
 
@@ -94,11 +97,6 @@ tcGroup inst_mapper decls
                -- extend-env things work properly.  A bit UGH-ish.
       tcExtendTyConEnv tycon_names_w_arities tycons              $
       tcExtendClassEnv class_names classes                       $
                -- extend-env things work properly.  A bit UGH-ish.
       tcExtendTyConEnv tycon_names_w_arities tycons              $
       tcExtendClassEnv class_names classes                       $
-      tcExtendGlobalValEnv (concat (map getTyConDataCons tycons)) $
-      tcExtendGlobalValEnv (concat (map getClassSelIds classes))  $
-
-               -- SNAFFLE ENV TO RETURN
-      tcGetEnv                                 `thenNF_Tc` \ final_env ->
 
                -- DEAL WITH TYPE VARIABLES
       tcTyVarScope tyvar_names                         ( \ tyvars ->
 
                -- DEAL WITH TYPE VARIABLES
       tcTyVarScope tyvar_names                         ( \ tyvars ->
@@ -107,11 +105,34 @@ tcGroup inst_mapper decls
        foldBag combine (tcDecl inst_mapper)
                (returnTc (emptyBag, emptyBag))
                decls
        foldBag combine (tcDecl inst_mapper)
                (returnTc (emptyBag, emptyBag))
                decls
-      )                                                `thenTc` \ (tycons,classes) ->
+      )                                                `thenTc` \ (tycon_bag,class_bag) ->
+      let
+       tycons = bagToList tycon_bag
+       classes = bagToList class_bag
+      in 
 
 
-      returnTc (bagToList tycons, bagToList classes, final_env)
-    ) `thenTc` \ (_, _, final_env) ->
-    returnTc final_env
+               -- SNAFFLE ENV TO RETURN
+      tcGetEnv                                 `thenNF_Tc` \ final_env ->
+
+      returnTc (tycons, classes, final_env)
+    ) `thenTc` \ (tycons, classes, final_env) ->
+
+
+       -- Create any necessary record selector Ids and their bindings
+    mapAndUnzipTc tcRecordSelectors tycons     `thenTc` \ (sel_ids_s, binds) ->
+       
+       -- Extend the global value environment with 
+       --      a) constructors
+       --      b) record selectors
+       --      c) class op selectors
+
+    tcSetEnv final_env                                         $
+    tcExtendGlobalValEnv (concat (map tyConDataCons tycons))   $
+    tcExtendGlobalValEnv (concat sel_ids_s)                    $
+    tcExtendGlobalValEnv (concat (map getClassSelIds classes))  $
+    tcGetEnv                   `thenNF_Tc` \ really_final_env ->
+
+    returnTc (really_final_env, foldr ThenBinds EmptyBinds binds)
 
   where
     (tyvar_names, tycon_names_w_arities, class_names) = get_binders decls
 
   where
     (tyvar_names, tycon_names_w_arities, class_names) = get_binders decls
@@ -170,8 +191,14 @@ sortByDependency syn_decls cls_decls decls
    bag_acyclic (AcyclicSCC scc) = unitBag scc
    bag_acyclic (CyclicSCC sccs) = sccs
 
    bag_acyclic (AcyclicSCC scc) = unitBag scc
    bag_acyclic (CyclicSCC sccs) = sccs
 
-fmt_decl (TyD (TySynonym name _ _ _))       = (ppr PprForUser name, getSrcLoc name)
-fmt_decl (ClD (ClassDecl _ name _ _ _ _ _)) = (ppr PprForUser name, getSrcLoc name)
+fmt_decl decl
+  = (ppr PprForUser name, getSrcLoc name)
+  where
+    name = get_name decl
+    get_name (TyD (TyData _ name _ _ _ _ _))    = name
+    get_name (TyD (TyNew  _ name _ _ _ _ _))    = name
+    get_name (TyD (TySynonym name _ _ _))       = name
+    get_name (ClD (ClassDecl _ name _ _ _ _ _)) = name
 \end{code}
 
 Edges in Type/Class decls
 \end{code}
 
 Edges in Type/Class decls
@@ -230,7 +257,7 @@ get_sigs sigs
     get_sig (ClassOpSig _ ty _ _) = get_pty ty
     get_sig other = panic "TcTyClsDecls:get_sig"
 
     get_sig (ClassOpSig _ ty _ _) = get_pty ty
     get_sig other = panic "TcTyClsDecls:get_sig"
 
-set_name name = singletonUniqSet (getItsUnique name)
+set_name name = unitUniqSet (getItsUnique name)
 
 set_to_bag set = listToBag (uniqSetToList set)
 \end{code}
 
 set_to_bag set = listToBag (uniqSetToList set)
 \end{code}
index 9d6c08f..8e37985 100644 (file)
@@ -8,29 +8,42 @@
 
 module TcTyDecls (
        tcTyDecl,
 
 module TcTyDecls (
        tcTyDecl,
-       tcConDecl
+       tcConDecl,
+       tcRecordSelectors
     ) where
 
 import Ubiq{-uitous-}
 
     ) where
 
 import Ubiq{-uitous-}
 
-import HsSyn           ( TyDecl(..), ConDecl(..), BangType(..), MonoType )
+import HsSyn           ( TyDecl(..), ConDecl(..), BangType(..), HsExpr(..), 
+                         Match(..), GRHSsAndBinds(..), GRHS(..), OutPat(..), 
+                         HsBinds(..), HsLit, Stmt, Qual, ArithSeqInfo, PolyType, 
+                         Bind(..), MonoBinds(..), Sig, 
+                         MonoType )
 import RnHsSyn         ( RenamedTyDecl(..), RenamedConDecl(..) )
 import RnHsSyn         ( RenamedTyDecl(..), RenamedConDecl(..) )
+import TcHsSyn         ( TcHsBinds(..), TcIdOcc(..), mkHsTyLam )
 
 import TcMonoType      ( tcMonoTypeKind, tcMonoType, tcContext )
 
 import TcMonoType      ( tcMonoTypeKind, tcMonoType, tcContext )
-import TcEnv           ( tcLookupTyCon, tcLookupTyVar, tcLookupClass )
+import TcType          ( tcInstTyVars, tcInstType )
+import TcEnv           ( tcLookupTyCon, tcLookupTyVar, tcLookupClass,
+                         newLocalId
+                       )
 import TcMonad
 import TcKind          ( TcKind, unifyKind, mkTcArrowKind, mkTcTypeKind )
 
 import TcMonad
 import TcKind          ( TcKind, unifyKind, mkTcArrowKind, mkTcTypeKind )
 
-import Id              ( mkDataCon, StrictnessMark(..) )
+import Id              ( mkDataCon, dataConSig, mkRecordSelectorId,
+                         dataConFieldLabels, StrictnessMark(..)
+                       )
+import FieldLabel
 import Kind            ( Kind, mkArrowKind, mkBoxedTypeKind )
 import SpecEnv         ( SpecEnv(..), nullSpecEnv )
 import Name            ( getNameFullName, Name(..) )
 import Pretty
 import Kind            ( Kind, mkArrowKind, mkBoxedTypeKind )
 import SpecEnv         ( SpecEnv(..), nullSpecEnv )
 import Name            ( getNameFullName, Name(..) )
 import Pretty
-import TyCon           ( TyCon, ConsVisible(..), NewOrData(..), mkSynTyCon, mkDataTyCon )
-import Type            ( getTypeKind )
-import TyVar           ( getTyVarKind )
-import Util            ( panic )
-
+import TyCon           ( TyCon, NewOrData(..), mkSynTyCon, mkDataTyCon, tyConDataCons )
+import Type            ( getTypeKind, getTyVar, tyVarsOfTypes, eqTy, applyTyCon,
+                         mkForAllTys, mkFunTy )
+import TyVar           ( getTyVarKind, elementOfTyVarSet )
+import UniqSet         ( emptyUniqSet, mkUniqSet, uniqSetToList, unionManyUniqSets, UniqSet(..) )
+import Util            ( panic, equivClasses )
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -57,11 +70,16 @@ tcTyDecl (TySynonym tycon_name tyvar_names rhs src_loc)
        (foldr mkTcArrowKind rhs_kind tyvar_kinds)
                                                `thenTc_`
     let
        (foldr mkTcArrowKind rhs_kind tyvar_kinds)
                                                `thenTc_`
     let
-       -- Construct the tycon
+       -- Getting the TyCon's kind is a bit of a nuisance.  We can't use the tycon_kind,
+       -- because that's a TcKind and may not yet be fully unified with other kinds.
+       -- We could have augmented the tycon environment with a knot-tied kind,
+       -- but the simplest thing to do seems to be to get the Kind by (lazily)
+       -- looking at the tyvars and rhs_ty.
        result_kind, final_tycon_kind :: Kind   -- NB not TcKind!
        result_kind      = getTypeKind rhs_ty
        final_tycon_kind = foldr (mkArrowKind . getTyVarKind) result_kind rec_tyvars
 
        result_kind, final_tycon_kind :: Kind   -- NB not TcKind!
        result_kind      = getTypeKind rhs_ty
        final_tycon_kind = foldr (mkArrowKind . getTyVarKind) result_kind rec_tyvars
 
+       -- Construct the tycon
        tycon = mkSynTyCon (getItsUnique tycon_name)
                           (getNameFullName tycon_name)
                           final_tycon_kind
        tycon = mkSynTyCon (getItsUnique tycon_name)
                           (getNameFullName tycon_name)
                           final_tycon_kind
@@ -99,6 +117,7 @@ tcTyDataOrNew data_or_new context tycon_name tyvar_names con_decls derivings pra
     unifyKind tycon_kind
        (foldr mkTcArrowKind mkTcTypeKind tyvar_kinds)
                                                `thenTc_`
     unifyKind tycon_kind
        (foldr mkTcArrowKind mkTcTypeKind tyvar_kinds)
                                                `thenTc_`
+
        -- Walk the condecls
     mapTc (tcConDecl rec_tycon rec_tyvars ctxt) con_decls
                                                `thenTc` \ con_ids ->
        -- Walk the condecls
     mapTc (tcConDecl rec_tycon rec_tyvars ctxt) con_decls
                                                `thenTc` \ con_ids ->
@@ -114,19 +133,109 @@ tcTyDataOrNew data_or_new context tycon_name tyvar_names con_decls derivings pra
                            ctxt
                            con_ids
                            derived_classes
                            ctxt
                            con_ids
                            derived_classes
-                           ConsVisible         -- For now; if constrs are from pragma we are *abstract*
                            data_or_new
     in
     returnTc tycon
                            data_or_new
     in
     returnTc tycon
-  where
-    tc_derivs Nothing   = returnNF_Tc []
-    tc_derivs (Just ds) = mapNF_Tc tc_deriv ds
 
 
-    tc_deriv name
-      = tcLookupClass name `thenNF_Tc` \ (_, clas) ->
-       returnNF_Tc clas
+tc_derivs Nothing   = returnNF_Tc []
+tc_derivs (Just ds) = mapNF_Tc tc_deriv ds
+
+tc_deriv name
+  = tcLookupClass name `thenNF_Tc` \ (_, clas) ->
+    returnNF_Tc clas
 \end{code}
 
 \end{code}
 
+Generating selector bindings for record delarations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+\begin{code}
+tcRecordSelectors :: TyCon -> TcM s ([Id], TcHsBinds s)
+tcRecordSelectors tycon
+  = mapAndUnzipTc (tcRecordSelector tycon) groups      `thenTc` \ (ids, binds) ->
+    returnTc (ids, SingleBind (NonRecBind (foldr AndMonoBinds EmptyMonoBinds binds)))
+  where
+    data_cons = tyConDataCons tycon
+    fields = [ (con, field) | con   <- data_cons,
+                             field <- dataConFieldLabels con
+            ]
+
+       -- groups is list of fields that share a common name
+    groups = equivClasses cmp_name fields
+    cmp_name (_, field1) (_, field2) 
+       = fieldLabelName field1 `cmp` fieldLabelName field2
+\end{code}
+
+We're going to build a record selector that looks like this:
+
+       data T a b c = T1 { op :: a, ...}
+                    | T2 { op :: a, ...}
+                    | T3
+
+       sel :: forall a b c. T a b c -> a
+       sel = /\ a b c -> \ T1 { sel = x } -> x
+                           T2 { sel = 2 } -> x
+
+Note that the selector Id itself is used as the field
+label; it has to be an Id, you see!
+
+\begin{code}
+tcRecordSelector tycon fields@((first_con, first_field_label) : other_fields)
+  = panic "tcRecordSelector: don't typecheck"
+{-
+  = let
+       field_ty   = fieldLabelType first_field_label
+       field_name = fieldLabelName first_field_label
+       other_tys  = [fieldLabelType fl | (_, fl) <- fields]
+       (tyvars, _, _, _) = dataConSig first_con
+       -- tyvars of first_con may be free in first_ty
+    in
+   
+       -- Check that all the fields in the group have the same type
+       -- This check assumes that all the constructors of a given
+       -- data type use the same type variables
+    checkTc (all (eqTy field_ty) other_tys)
+           (fieldTypeMisMatch field_name)      `thenTc_`
+    
+       -- Create an Id for the field itself
+    tcInstTyVars tyvars                        `thenNF_Tc` \ (tyvars', tyvar_tys, tenv) ->
+    tcInstType tenv field_ty           `thenNF_Tc` \ field_ty' ->
+    let
+      data_ty'     = applyTyCon tycon tyvar_tys
+    in
+    newLocalId SLIT("x") field_ty'     `thenNF_Tc` \ field_id ->
+    newLocalId SLIT("r") data_ty'      `thenNF_Tc` \ record_id ->
+
+       -- Now build the selector
+    let
+      tycon_src_loc = getSrcLoc tycon
+
+      selector_ty  = mkForAllTys tyvars' $
+                    mkFunTy data_ty' $
+                    field_ty'
+      
+      selector_id = mkRecordSelectorId first_field_label selector_ty
+
+       -- HsSyn is dreadfully verbose for defining the selector!
+      selector_rhs = mkHsTyLam tyvars' $
+                    HsLam $
+                    PatMatch (VarPat record_id) $
+                    GRHSMatch $
+                    GRHSsAndBindsOut [OtherwiseGRHS selector_body tycon_src_loc] 
+                                     EmptyBinds field_ty'
+
+      selector_body = HsCase (HsVar record_id) (map mk_match fields) tycon_src_loc
+
+      mk_match (con_id, field_label) 
+       = PatMatch (RecPat con_id data_ty' [(selector_id, VarPat field_id, False)]) $
+         GRHSMatch $
+         GRHSsAndBindsOut [OtherwiseGRHS (HsVar field_id) 
+                                         (getSrcLoc (fieldLabelName field_label))] 
+                          EmptyBinds
+                          field_ty'
+    in
+    returnTc (selector_id, VarMonoBind selector_id selector_rhs)
+-}
+\end{code}
 
 Constructors
 ~~~~~~~~~~~~
 
 Constructors
 ~~~~~~~~~~~~
@@ -134,65 +243,88 @@ Constructors
 tcConDecl :: TyCon -> [TyVar] -> [(Class,Type)] -> RenamedConDecl -> TcM s Id
 
 tcConDecl tycon tyvars ctxt (ConDecl name btys src_loc)
 tcConDecl :: TyCon -> [TyVar] -> [(Class,Type)] -> RenamedConDecl -> TcM s Id
 
 tcConDecl tycon tyvars ctxt (ConDecl name btys src_loc)
+  = tcDataCon tycon tyvars ctxt name btys src_loc
+
+tcConDecl tycon tyvars ctxt (ConOpDecl bty1 op bty2 src_loc)
+  = tcDataCon tycon tyvars ctxt op [bty1,bty2] src_loc
+
+tcConDecl tycon tyvars ctxt (NewConDecl name ty src_loc)
   = tcAddSrcLoc src_loc        $
   = tcAddSrcLoc src_loc        $
-    let
-       (stricts, tys) = sep_bangs btys
-    in
-    mapTc tcMonoType tys `thenTc` \ arg_tys ->
+    tcMonoType ty `thenTc` \ arg_ty ->
     let
       data_con = mkDataCon (getItsUnique name)
                           (getNameFullName name)
     let
       data_con = mkDataCon (getItsUnique name)
                           (getNameFullName name)
-                          stricts
+                          [NotMarkedStrict]
+                          [{- No labelled fields -}]
                           tyvars
                           tyvars
-                          [] -- ToDo: ctxt; limited to tyvars in arg_tys
-                          arg_tys
+                          ctxt
+                          [arg_ty]
                           tycon
                        -- nullSpecEnv
     in
     returnTc data_con
 
                           tycon
                        -- nullSpecEnv
     in
     returnTc data_con
 
-tcConDecl tycon tyvars ctxt (ConOpDecl bty1 op bty2 src_loc)
+tcConDecl tycon tyvars ctxt (RecConDecl name fields src_loc)
   = tcAddSrcLoc src_loc        $
   = tcAddSrcLoc src_loc        $
+    mapTc tcField fields       `thenTc` \ field_label_infos_s ->
     let
     let
-       (stricts, tys) = sep_bangs [bty1, bty2]
-    in
-    mapTc tcMonoType tys `thenTc` \ arg_tys ->
-    let
-      data_con = mkDataCon (getItsUnique op)
-                          (getNameFullName op)
+      field_label_infos = concat field_label_infos_s
+      stricts           = [strict | (_, _, strict) <- field_label_infos]
+      arg_tys          = [ty     | (_, ty, _)     <- field_label_infos]
+
+      field_labels      = [ mkFieldLabel name ty tag 
+                         | ((name, ty, _), tag) <- field_label_infos `zip` allFieldLabelTags
+                         ]
+
+      data_con = mkDataCon (getItsUnique name)
+                          (getNameFullName name)
                           stricts
                           stricts
+                          field_labels
                           tyvars
                           tyvars
-                          [] -- ToDo: ctxt
+                          (thinContext arg_tys ctxt)
                           arg_tys
                           tycon
                        -- nullSpecEnv
     in
     returnTc data_con
 
                           arg_tys
                           tycon
                        -- nullSpecEnv
     in
     returnTc data_con
 
-tcConDecl tycon tyvars ctxt (NewConDecl name ty src_loc)
+tcField (field_label_names, bty)
+  = tcMonoType (get_ty bty)    `thenTc` \ field_ty ->
+    returnTc [(name, field_ty, get_strictness bty) | name <- field_label_names]
+
+tcDataCon tycon tyvars ctxt name btys src_loc
   = tcAddSrcLoc src_loc        $
   = tcAddSrcLoc src_loc        $
-    tcMonoType ty `thenTc` \ arg_ty ->
+    let
+       stricts = map get_strictness btys
+       tys     = map get_ty btys
+    in
+    mapTc tcMonoType tys `thenTc` \ arg_tys ->
     let
       data_con = mkDataCon (getItsUnique name)
                           (getNameFullName name)
     let
       data_con = mkDataCon (getItsUnique name)
                           (getNameFullName name)
-                          [NotMarkedStrict]
+                          stricts
+                          [{- No field labels -}]
                           tyvars
                           tyvars
-                          [] -- ToDo: ctxt
-                          [arg_ty]
+                          (thinContext arg_tys ctxt)
+                          arg_tys
                           tycon
                        -- nullSpecEnv
     in
     returnTc data_con
 
                           tycon
                        -- nullSpecEnv
     in
     returnTc data_con
 
-tcConDecl tycon tyvars ctxt (RecConDecl con fields src_loc)
-  = panic "tcConDecls:RecConDecl"
-
-
-sep_bangs btys
-  = unzip (map sep_bang btys)
-  where 
-    sep_bang (Banged ty)   = (MarkedStrict, ty)
-    sep_bang (Unbanged ty) = (NotMarkedStrict, ty)
+-- The context for a data constructor should be limited to
+-- the type variables mentioned in the arg_tys
+thinContext arg_tys ctxt
+  = filter in_arg_tys ctxt
+  where
+      arg_tyvars = tyVarsOfTypes arg_tys
+      in_arg_tys (clas,ty) = getTyVar "tcDataCon" ty `elementOfTyVarSet` arg_tyvars
+  
+get_strictness (Banged ty)   = MarkedStrict
+get_strictness (Unbanged ty) = NotMarkedStrict
+
+get_ty (Banged ty)   = ty
+get_ty (Unbanged ty) = ty
 \end{code}
 
 
 \end{code}
 
 
@@ -208,4 +340,7 @@ tyDataCtxt tycon_name sty
 
 tyNewCtxt tycon_name sty
   = ppCat [ppStr "In the newtype declaration for", ppr sty tycon_name]
 
 tyNewCtxt tycon_name sty
   = ppCat [ppStr "In the newtype declaration for", ppr sty tycon_name]
+
+fieldTypeMisMatch field_name sty
+  = ppSep [ppStr "Declared types differ for field", ppr sty field_name]
 \end{code}
 \end{code}
index 1008e0c..530e41a 100644 (file)
@@ -18,12 +18,10 @@ module TcType (
   tcReadTyVar,         -- :: TcTyVar s -> NF_TcM (TcMaybe s)
 
 
   tcReadTyVar,         -- :: TcTyVar s -> NF_TcM (TcMaybe s)
 
 
-  tcInstTyVar,    -- TyVar -> NF_TcM s (TcTyVar s)
+  tcInstTyVars,    -- TyVar -> NF_TcM s (TcTyVar s)
+  tcInstSigTyVars, 
   tcInstType, tcInstTcType, tcInstTheta,
 
   tcInstType, tcInstTcType, tcInstTheta,
 
---  zonkTcType,                -- TcType s     -> NF_TcM s (TcType s)
---  zonkTcTheta,       -- TcThetaType s -> NF_TcM s (TcThetaType s)
-
     zonkTcTyVars,      -- TcTyVarSet s -> NF_TcM s (TcTyVarSet s)
     zonkTcType,                -- TcType s -> NF_TcM s (TcType s)
     zonkTcTypeToType,  -- TcType s -> NF_TcM s Type
     zonkTcTyVars,      -- TcTyVarSet s -> NF_TcM s (TcTyVarSet s)
     zonkTcType,                -- TcType s -> NF_TcM s (TcType s)
     zonkTcTypeToType,  -- TcType s -> NF_TcM s Type
@@ -51,7 +49,12 @@ import Unique                ( Unique )
 import UniqFM          ( UniqFM )
 import Name            ( getNameShortName )
 import Maybes          ( assocMaybe )
 import UniqFM          ( UniqFM )
 import Name            ( getNameShortName )
 import Maybes          ( assocMaybe )
-import Util            ( panic )
+import Util            ( panic, pprPanic )
+
+import Outputable      ( Outputable(..) )      -- Debugging messages
+import PprType         ( GenTyVar, GenType )
+import Pretty                                  -- ditto
+import PprStyle                ( PprStyle(..) )        -- ditto
 \end{code}
 
 
 \end{code}
 
 
@@ -74,6 +77,12 @@ type Box s = MutableVar s (TcMaybe s)
 
 data TcMaybe s = UnBound
               | BoundTo (TcType s)
 
 data TcMaybe s = UnBound
               | BoundTo (TcType s)
+              | DontBind               -- This variant is used for tyvars
+                                       -- arising from type signatures, or
+                                       -- existentially quantified tyvars;
+                                       -- The idea is that we must not unify
+                                       -- such tyvars with anything except
+                                       -- themselves.
 
 -- Interestingly, you can't use (Maybe (TcType s)) instead of (TcMaybe s),
 -- because you get a synonym loop if you do!
 
 -- Interestingly, you can't use (Maybe (TcType s)) instead of (TcMaybe s),
 -- because you get a synonym loop if you do!
@@ -91,23 +100,41 @@ Type instantiation
 ~~~~~~~~~~~~~~~~~~
 
 \begin{code}
 ~~~~~~~~~~~~~~~~~~
 
 \begin{code}
-newTcTyVar :: Maybe ShortName -> Kind -> NF_TcM s (TcTyVar s)
-newTcTyVar name kind
+newTcTyVar :: Kind -> NF_TcM s (TcTyVar s)
+newTcTyVar kind
   = tcGetUnique        `thenNF_Tc` \ uniq ->
     tcNewMutVar UnBound        `thenNF_Tc` \ box ->
   = tcGetUnique        `thenNF_Tc` \ uniq ->
     tcNewMutVar UnBound        `thenNF_Tc` \ box ->
-    returnNF_Tc (TyVar uniq kind name box)
+    returnNF_Tc (TyVar uniq kind Nothing box)
 
 newTyVarTy  :: Kind -> NF_TcM s (TcType s)
 newTyVarTy kind
 
 newTyVarTy  :: Kind -> NF_TcM s (TcType s)
 newTyVarTy kind
-  = newTcTyVar Nothing kind    `thenNF_Tc` \ tc_tyvar ->
+  = newTcTyVar kind    `thenNF_Tc` \ tc_tyvar ->
     returnNF_Tc (TyVarTy tc_tyvar)
 
 newTyVarTys :: Int -> Kind -> NF_TcM s [TcType s]
 newTyVarTys n kind = mapNF_Tc newTyVarTy (take n (repeat kind))
 
     returnNF_Tc (TyVarTy tc_tyvar)
 
 newTyVarTys :: Int -> Kind -> NF_TcM s [TcType s]
 newTyVarTys n kind = mapNF_Tc newTyVarTy (take n (repeat kind))
 
-tcInstTyVar :: TyVar -> NF_TcM s (TcTyVar s)
-tcInstTyVar tyvar@(TyVar uniq kind name _)
-  = newTcTyVar name kind
+
+
+-- For signature type variables, mark them as "DontBind"
+tcInstTyVars, tcInstSigTyVars
+       :: [GenTyVar flexi] 
+       -> NF_TcM s ([TcTyVar s], [TcType s], [(GenTyVar flexi, TcType s)])
+tcInstTyVars    tyvars = inst_tyvars UnBound  tyvars
+tcInstSigTyVars tyvars = inst_tyvars DontBind tyvars
+
+
+inst_tyvars initial_cts tyvars
+  = mapNF_Tc (inst_tyvar initial_cts) tyvars   `thenNF_Tc` \ tc_tyvars ->
+    let
+       tys = map TyVarTy tc_tyvars
+    in
+    returnNF_Tc (tc_tyvars, tys, tyvars `zip` tys)
+
+inst_tyvar initial_cts (TyVar _ kind name _) 
+  = tcGetUnique                `thenNF_Tc` \ uniq ->
+    tcNewMutVar initial_cts    `thenNF_Tc` \ box ->
+    returnNF_Tc (TyVar uniq kind name box)
 \end{code}
 
 @tcInstType@ and @tcInstTcType@ both create a fresh instance of a
 \end{code}
 
 @tcInstType@ and @tcInstTcType@ both create a fresh instance of a
@@ -143,13 +170,14 @@ tcInstType tenv ty_to_inst
     do env (DictTy clas ty usage)= do env ty           `thenNF_Tc` \ ty' ->
                                   returnNF_Tc (DictTy clas ty' usage)
 
     do env (DictTy clas ty usage)= do env ty           `thenNF_Tc` \ ty' ->
                                   returnNF_Tc (DictTy clas ty' usage)
 
-    do env (TyVarTy (TyVar uniq kind name _))
+    do env (TyVarTy tv@(TyVar uniq kind name _))
        = case assocMaybe env uniq of
                Just tc_ty -> returnNF_Tc tc_ty
        = case assocMaybe env uniq of
                Just tc_ty -> returnNF_Tc tc_ty
-               Nothing    -> panic "tcInstType"
+               Nothing    -> pprPanic "tcInstType:" (ppAboves [ppr PprDebug tenv, 
+                                             ppr PprDebug ty_to_inst, ppr PprDebug tv])
 
 
-    do env (ForAllTy (TyVar uniq kind name _) ty)
-       = newTcTyVar name kind  `thenNF_Tc` \ tc_tyvar ->
+    do env (ForAllTy tyvar@(TyVar uniq kind name _) ty)
+       = inst_tyvar DontBind tyvar     `thenNF_Tc` \ tc_tyvar ->
          let
                new_env = (uniq, TyVarTy tc_tyvar) : env
          in
          let
                new_env = (uniq, TyVarTy tc_tyvar) : env
          in
@@ -166,6 +194,8 @@ tcInstTheta tenv theta
     go (clas,ty) = tcInstType tenv ty  `thenNF_Tc` \ tc_ty ->
                   returnNF_Tc (clas, tc_ty)
 
     go (clas,ty) = tcInstType tenv ty  `thenNF_Tc` \ tc_ty ->
                   returnNF_Tc (clas, tc_ty)
 
+--???tcSpecTy :: Type -> NF_TcM s (
+
 tcInstTcType ::  [(TcTyVar s,TcType s)] -> TcType s -> NF_TcM s (TcType s)
 tcInstTcType tenv ty_to_inst
   = do [(uniq,ty) | (TyVar uniq _ _ _, ty) <- tenv] ty_to_inst
 tcInstTcType ::  [(TcTyVar s,TcType s)] -> TcType s -> NF_TcM s (TcType s)
 tcInstTcType tenv ty_to_inst
   = do [(uniq,ty) | (TyVar uniq _ _ _, ty) <- tenv] ty_to_inst
@@ -193,15 +223,10 @@ tcInstTcType tenv ty_to_inst
                Just tc_ty -> returnNF_Tc tc_ty
                Nothing    -> returnNF_Tc ty
 
                Just tc_ty -> returnNF_Tc tc_ty
                Nothing    -> returnNF_Tc ty
 
-    do env (ForAllTy (TyVar uniq kind name _) ty)
-       = newTcTyVar name kind  `thenNF_Tc` \ tc_tyvar ->
-         let
-               new_env = (uniq, TyVarTy tc_tyvar) : env
-         in
-         do new_env ty `thenNF_Tc` \ ty' ->
-         returnNF_Tc (ForAllTy tc_tyvar ty')
+    do env (ForAllTy (TyVar uniq kind name _) ty) = panic "tcInstTcType"
 
    -- ForAllUsage impossible
 
    -- ForAllUsage impossible
+
 \end{code}
 
 Reading and writing TcTyVars
 \end{code}
 
 Reading and writing TcTyVars
@@ -232,20 +257,22 @@ We return Nothing iff the original box was unbound.
 tcReadTyVar (TyVar uniq kind name box)
   = tcReadMutVar box   `thenNF_Tc` \ maybe_ty ->
     case maybe_ty of
 tcReadTyVar (TyVar uniq kind name box)
   = tcReadMutVar box   `thenNF_Tc` \ maybe_ty ->
     case maybe_ty of
-       UnBound    -> returnNF_Tc UnBound
        BoundTo ty -> short_out ty                      `thenNF_Tc` \ ty' ->
                      tcWriteMutVar box (BoundTo ty')   `thenNF_Tc_`
                      returnNF_Tc (BoundTo ty')
 
        BoundTo ty -> short_out ty                      `thenNF_Tc` \ ty' ->
                      tcWriteMutVar box (BoundTo ty')   `thenNF_Tc_`
                      returnNF_Tc (BoundTo ty')
 
+       other      -> returnNF_Tc other
+
 short_out :: TcType s -> NF_TcM s (TcType s)
 short_out ty@(TyVarTy (TyVar uniq kind name box))
   = tcReadMutVar box   `thenNF_Tc` \ maybe_ty ->
     case maybe_ty of
 short_out :: TcType s -> NF_TcM s (TcType s)
 short_out ty@(TyVarTy (TyVar uniq kind name box))
   = tcReadMutVar box   `thenNF_Tc` \ maybe_ty ->
     case maybe_ty of
-       UnBound     -> returnNF_Tc ty
        BoundTo ty' -> short_out ty'                    `thenNF_Tc` \ ty' ->
                       tcWriteMutVar box (BoundTo ty')  `thenNF_Tc_`
                       returnNF_Tc ty'
 
        BoundTo ty' -> short_out ty'                    `thenNF_Tc` \ ty' ->
                       tcWriteMutVar box (BoundTo ty')  `thenNF_Tc_`
                       returnNF_Tc ty'
 
+       other       -> returnNF_Tc ty
+
 short_out other_ty = returnNF_Tc other_ty
 \end{code}
 
 short_out other_ty = returnNF_Tc other_ty
 \end{code}
 
@@ -310,8 +337,8 @@ zonk tyvar_fn (DictTy c ty u)
 zonk_tv tyvar_fn tyvar
   = tcReadTyVar tyvar          `thenNF_Tc` \ maybe_ty ->
     case maybe_ty of
 zonk_tv tyvar_fn tyvar
   = tcReadTyVar tyvar          `thenNF_Tc` \ maybe_ty ->
     case maybe_ty of
-       UnBound    -> returnNF_Tc (TyVarTy (tyvar_fn tyvar))
        BoundTo ty -> zonk tyvar_fn ty
        BoundTo ty -> zonk tyvar_fn ty
+       other      -> returnNF_Tc (TyVarTy (tyvar_fn tyvar))
 
 
 zonk_tv_to_tv tyvar_fn tyvar
 
 
 zonk_tv_to_tv tyvar_fn tyvar
index d1893e3..64b33b7 100644 (file)
@@ -19,7 +19,6 @@ import HsSyn
 import RnHsSyn
 import TcHsSyn
 
 import RnHsSyn
 import TcHsSyn
 
-import ErrUtils                ( TcWarning(..), TcError(..) )
 import Pretty
 import RnUtils         ( GlobalNameMappers(..), GlobalNameMapper(..) )
 import Maybes          ( MaybeErr(..) )
 import Pretty
 import RnUtils         ( GlobalNameMappers(..), GlobalNameMapper(..) )
 import Maybes          ( MaybeErr(..) )
@@ -41,7 +40,8 @@ typecheckModule
     -> -- OUTPUTS ...
     MaybeErr
        -- SUCCESS ...
     -> -- OUTPUTS ...
     MaybeErr
        -- SUCCESS ...
-      (((TypecheckedHsBinds,      -- binds from class decls; does NOT
+      (((TypecheckedHsBinds,      -- record selector definitions
+        TypecheckedHsBinds,       -- binds from class decls; does NOT
                                   --    include default-methods bindings
         TypecheckedHsBinds,       -- binds from instance decls; INCLUDES
                                   --    class default-methods binds
                                   --    include default-methods bindings
         TypecheckedHsBinds,       -- binds from instance decls; INCLUDES
                                   --    class default-methods binds
index 74c2755..c8edce0 100644 (file)
@@ -9,20 +9,21 @@ updatable substitution).
 \begin{code}
 #include "HsVersions.h"
 
 \begin{code}
 #include "HsVersions.h"
 
-module Unify ( unifyTauTy, unifyTauTyList, unifyTauTyLists ) where
+module Unify ( unifyTauTy, unifyTauTyList, unifyTauTyLists, unifyFunTy ) where
 
 import Ubiq
 
 -- friends: 
 import TcMonad
 
 import Ubiq
 
 -- friends: 
 import TcMonad
-import Type    ( GenType(..), getTypeKind )
-import TyCon   ( TyCon(..), ConsVisible, NewOrData )
-import TyVar   ( GenTyVar(..), TyVar(..) )
+import Type    ( GenType(..), getTypeKind, mkFunTy, getFunTy_maybe )
+import TyCon   ( TyCon, mkFunTyCon )
+import TyVar   ( GenTyVar(..), TyVar(..), getTyVarKind )
 import TcType  ( TcType(..), TcMaybe(..), TcTauType(..), TcTyVar(..),
 import TcType  ( TcType(..), TcMaybe(..), TcTauType(..), TcTyVar(..),
-                 tcReadTyVar, tcWriteTyVar
+                 newTyVarTy, tcReadTyVar, tcWriteTyVar, zonkTcType
                )
 -- others:
                )
 -- others:
-import Kind    ( Kind, isSubKindOf )
+import Kind    ( Kind, isSubKindOf, mkTypeKind )
+import Usage   ( duffUsage )
 import PprType ( GenTyVar, GenType )   -- instances
 import Pretty
 import Unique  ( Unique )              -- instances
 import PprType ( GenTyVar, GenType )   -- instances
 import Pretty
 import Unique  ( Unique )              -- instances
@@ -44,7 +45,7 @@ Unify two @TauType@s.  Dead straightforward.
 \begin{code}
 unifyTauTy :: TcTauType s -> TcTauType s -> TcM s ()
 unifyTauTy ty1 ty2 
 \begin{code}
 unifyTauTy :: TcTauType s -> TcTauType s -> TcM s ()
 unifyTauTy ty1 ty2 
-  = tcAddErrCtxt (unifyCtxt ty1 ty2) $
+  = tcAddErrCtxtM (unifyCtxt ty1 ty2) $
     uTys ty1 ty1 ty2 ty2
 \end{code}
 
     uTys ty1 ty1 ty2 ty2
 \end{code}
 
@@ -99,8 +100,21 @@ uTys ps_ty1 ty1 ps_ty2 (TyVarTy tyvar2) = uVar tyvar2 ps_ty1 ty1
        -- Applications and functions; just check the two parts
 uTys _ (FunTy fun1 arg1 _) _ (FunTy fun2 arg2 _)
   = uTys fun1 fun1 fun2 fun2   `thenTc_`    uTys arg1 arg1 arg2 arg2
        -- Applications and functions; just check the two parts
 uTys _ (FunTy fun1 arg1 _) _ (FunTy fun2 arg2 _)
   = uTys fun1 fun1 fun2 fun2   `thenTc_`    uTys arg1 arg1 arg2 arg2
-uTys _ (AppTy fun1 arg1) _ (AppTy fun2 arg2)
-  = uTys fun1 fun1 fun2 fun2   `thenTc_`    uTys arg1 arg1 arg2 arg2
+uTys _ (AppTy s1 t1) _ (AppTy s2 t2)
+  = uTys s1 s1 s2 s2   `thenTc_`    uTys t1 t1 t2 t2
+
+       -- Special case: converts  a -> b to (->) a b
+uTys _ (AppTy s1 t1) _ (FunTy fun2 arg2 _)
+  = uTys s1 s1 s2 s2   `thenTc_`    uTys t1 t1 t2 t2
+  where
+    s2 = AppTy (TyConTy mkFunTyCon duffUsage) fun2
+    t2 = arg2
+
+uTys _ (FunTy fun1 arg1 _) _ (AppTy s2 t2)
+  = uTys s1 s1 s2 s2   `thenTc_`    uTys t1 t1 t2 t2
+  where
+    s1 = AppTy (TyConTy mkFunTyCon duffUsage) fun1
+    t1 = arg1
 
        -- Type constructors must match
 uTys ps_ty1 (TyConTy con1 _) ps_ty2 (TyConTy con2 _)
 
        -- Type constructors must match
 uTys ps_ty1 (TyConTy con1 _) ps_ty2 (TyConTy con2 _)
@@ -110,16 +124,62 @@ uTys ps_ty1 (TyConTy con1 _) ps_ty2 (TyConTy con2 _)
 uTys ps_ty1 (SynTy con1 args1 ty1) ps_ty2 ty2 = uTys ps_ty1 ty1 ps_ty2 ty2
 uTys ps_ty1 ty1 ps_ty2 (SynTy con2 args2 ty2) = uTys ps_ty1 ty1 ps_ty2 ty2
 
 uTys ps_ty1 (SynTy con1 args1 ty1) ps_ty2 ty2 = uTys ps_ty1 ty1 ps_ty2 ty2
 uTys ps_ty1 ty1 ps_ty2 (SynTy con2 args2 ty2) = uTys ps_ty1 ty1 ps_ty2 ty2
 
-       -- Special case: converts  (->) a b  to  a -> b
-uTys ps_ty1 (AppTy (AppTy (TyConTy FunTyCon u) fun) arg) ps_ty2 ty2
-  = uTys ps_ty1 (FunTy fun arg u) ps_ty2 ty2
-uTys ps_ty1 ty1 ps_ty2 (AppTy (AppTy (TyConTy FunTyCon u) fun) arg)
-  = uTys ps_ty1 ty1 ps_ty2 (FunTy fun arg u)
-
        -- Anything else fails
 uTys ps_ty1 ty1 ps_ty2 ty2  = failTc (unifyMisMatch ps_ty1 ps_ty2)
 \end{code}
 
        -- Anything else fails
 uTys ps_ty1 ty1 ps_ty2 ty2  = failTc (unifyMisMatch ps_ty1 ps_ty2)
 \end{code}
 
+Notes on synonyms
+~~~~~~~~~~~~~~~~~
+If you are tempted to make a short cut on synonyms, as in this
+pseudocode...
+
+\begin{verbatim}
+uTys (SynTy con1 args1 ty1) (SynTy con2 args2 ty2)
+  = if (con1 == con2) then
+       -- Good news!  Same synonym constructors, so we can shortcut
+       -- by unifying their arguments and ignoring their expansions.
+       unifyTauTypeLists args1 args2
+    else
+       -- Never mind.  Just expand them and try again
+       uTys ty1 ty2
+\end{verbatim}
+
+then THINK AGAIN.  Here is the whole story, as detected and reported
+by Chris Okasaki \tr{<Chris_Okasaki@loch.mess.cs.cmu.edu>}:
+\begin{quotation}
+Here's a test program that should detect the problem:
+
+\begin{verbatim}
+       type Bogus a = Int
+       x = (1 :: Bogus Char) :: Bogus Bool
+\end{verbatim}
+
+The problem with [the attempted shortcut code] is that
+\begin{verbatim}
+       con1 == con2
+\end{verbatim}
+is not a sufficient condition to be able to use the shortcut!
+You also need to know that the type synonym actually USES all
+its arguments.  For example, consider the following type synonym
+which does not use all its arguments.
+\begin{verbatim}
+       type Bogus a = Int
+\end{verbatim}
+
+If you ever tried unifying, say, \tr{Bogus Char} with \tr{Bogus Bool},
+the unifier would blithely try to unify \tr{Char} with \tr{Bool} and
+would fail, even though the expanded forms (both \tr{Int}) should
+match.
+
+Similarly, unifying \tr{Bogus Char} with \tr{Bogus t} would
+unnecessarily bind \tr{t} to \tr{Char}.
+
+... You could explicitly test for the problem synonyms and mark them
+somehow as needing expansion, perhaps also issuing a warning to the
+user.
+\end{quotation}
+
+
 %************************************************************************
 %*                                                                     *
 \subsection[Unify-uVar]{@uVar@: unifying with a type variable}
 %************************************************************************
 %*                                                                     *
 \subsection[Unify-uVar]{@uVar@: unifying with a type variable}
@@ -145,14 +205,16 @@ uVar tv1 ps_ty2 ty2
   = tcReadTyVar tv1    `thenNF_Tc` \ maybe_ty1 ->
     case maybe_ty1 of
        BoundTo ty1 -> uTys ty1 ty1 ps_ty2 ty2
   = tcReadTyVar tv1    `thenNF_Tc` \ maybe_ty1 ->
     case maybe_ty1 of
        BoundTo ty1 -> uTys ty1 ty1 ps_ty2 ty2
-       UnBound  -> uUnboundVar tv1 ps_ty2 ty2
+       other       -> uUnboundVar tv1 maybe_ty1 ps_ty2 ty2
 
        -- Expand synonyms
 
        -- Expand synonyms
-uUnboundVar tv1 ps_ty2 (SynTy _ _ ty2) = uUnboundVar tv1 ps_ty2 ty2
+uUnboundVar tv1 maybe_ty1 ps_ty2 (SynTy _ _ ty2)
+  = uUnboundVar tv1 maybe_ty1 ps_ty2 ty2
 
 
        -- The both-type-variable case
 uUnboundVar tv1@(TyVar uniq1 kind1 name1 box1)
 
 
        -- The both-type-variable case
 uUnboundVar tv1@(TyVar uniq1 kind1 name1 box1)
+           maybe_ty1
            ps_ty2
            ty2@(TyVarTy tv2@(TyVar uniq2 kind2 name2 box2))
 
            ps_ty2
            ty2@(TyVarTy tv2@(TyVar uniq2 kind2 name2 box2))
 
@@ -161,24 +223,34 @@ uUnboundVar tv1@(TyVar uniq1 kind1 name1 box1)
   = returnTc ()
 
        -- Distinct type variables
   = returnTc ()
 
        -- Distinct type variables
+       -- ASSERT maybe_ty1 /= BoundTo
   | otherwise
   = tcReadTyVar tv2    `thenNF_Tc` \ maybe_ty2 ->
   | otherwise
   = tcReadTyVar tv2    `thenNF_Tc` \ maybe_ty2 ->
-    case maybe_ty2 of
-       BoundTo ty2' -> uUnboundVar tv1 ty2' ty2'
-       UnBound   -> if kind2 `isSubKindOf` kind1 then
-                       tcWriteTyVar tv1 ty2            `thenNF_Tc_` returnTc ()
-                    else if kind1 `isSubKindOf` kind2 then
-                       tcWriteTyVar tv2 (TyVarTy tv1)  `thenNF_Tc_` returnTc ()
-                    else
-                       failTc (unifyKindErr tv1 ps_ty2)
+    case (maybe_ty1, maybe_ty2) of
+       (_, BoundTo ty2') -> uUnboundVar tv1 maybe_ty1 ty2' ty2'
+
+       (DontBind,DontBind) 
+                    -> failTc (unifyDontBindErr tv1 ps_ty2)
+
+       (UnBound, _) |  kind2 `isSubKindOf` kind1
+                    -> tcWriteTyVar tv1 ty2            `thenNF_Tc_` returnTc ()
+       
+       (_, UnBound) |  kind1 `isSubKindOf` kind2
+                    -> tcWriteTyVar tv2 (TyVarTy tv1)  `thenNF_Tc_` returnTc ()
+
+       other        -> failTc (unifyKindErr tv1 ps_ty2)
 
        -- Second one isn't a type variable
 
        -- Second one isn't a type variable
-uUnboundVar tv1@(TyVar uniq1 kind1 name1 box1) ps_ty2 non_var_ty2
-  = occur_check non_var_ty2                    `thenTc_`
-    checkTc (getTypeKind non_var_ty2 `isSubKindOf` kind1)
-           (unifyKindErr tv1 ps_ty2)           `thenTc_`
-    tcWriteTyVar tv1 non_var_ty2               `thenNF_Tc_`
-    returnTc ()
+uUnboundVar tv1@(TyVar uniq1 kind1 name1 box1) maybe_ty1 ps_ty2 non_var_ty2
+  = case maybe_ty1 of
+       DontBind -> failTc (unifyDontBindErr tv1 ps_ty2)
+
+       UnBound  |  getTypeKind non_var_ty2 `isSubKindOf` kind1
+                -> occur_check non_var_ty2                     `thenTc_`
+                   tcWriteTyVar tv1 ps_ty2                     `thenNF_Tc_`
+                   returnTc ()
+
+       other    -> failTc (unifyKindErr tv1 ps_ty2)
   where
     occur_check (TyVarTy tv2@(TyVar uniq2 _ _ box2))
        | uniq1 == uniq2                -- Same tyvar; fail
   where
     occur_check (TyVarTy tv2@(TyVar uniq2 _ _ box2))
        | uniq1 == uniq2                -- Same tyvar; fail
@@ -188,7 +260,7 @@ uUnboundVar tv1@(TyVar uniq1 kind1 name1 box1) ps_ty2 non_var_ty2
        = tcReadTyVar tv2       `thenNF_Tc` \ maybe_ty2 ->
         case maybe_ty2 of
                BoundTo ty2' -> occur_check ty2'
        = tcReadTyVar tv2       `thenNF_Tc` \ maybe_ty2 ->
         case maybe_ty2 of
                BoundTo ty2' -> occur_check ty2'
-               UnBound   -> returnTc ()
+               other        -> returnTc ()
 
     occur_check (AppTy fun arg)   = occur_check fun `thenTc_` occur_check arg
     occur_check (FunTy fun arg _) = occur_check fun `thenTc_` occur_check arg
 
     occur_check (AppTy fun arg)   = occur_check fun `thenTc_` occur_check arg
     occur_check (FunTy fun arg _) = occur_check fun `thenTc_` occur_check arg
@@ -197,78 +269,79 @@ uUnboundVar tv1@(TyVar uniq1 kind1 name1 box1) ps_ty2 non_var_ty2
     occur_check other            = panic "Unexpected Dict or ForAll in occurCheck"
 \end{code}
 
     occur_check other            = panic "Unexpected Dict or ForAll in occurCheck"
 \end{code}
 
-Notes on synonyms
-~~~~~~~~~~~~~~~~~
-If you are tempted to make a short cut on synonyms, as in this
-pseudocode...
+%************************************************************************
+%*                                                                     *
+\subsection[Unify-fun]{@unifyFunTy@}
+%*                                                                     *
+%************************************************************************
 
 
-\begin{verbatim}
-uTys (SynTy con1 args1 ty1) (SynTy con2 args2 ty2)
-  = if (con1 == con2) then
-       -- Good news!  Same synonym constructors, so we can shortcut
-       -- by unifying their arguments and ignoring their expansions.
-       unifyTauTypeLists args1 args2
-    else
-       -- Never mind.  Just expand them and try again
-       uTys ty1 ty2
-\end{verbatim}
+@unifyFunTy@ is used to avoid the fruitless creation of type variables.
 
 
-then THINK AGAIN.  Here is the whole story, as detected and reported
-by Chris Okasaki \tr{<Chris_Okasaki@loch.mess.cs.cmu.edu>}:
-\begin{quotation}
-Here's a test program that should detect the problem:
+\begin{code}
+unifyFunTy :: TcType s                         -- Fail if ty isn't a function type
+          -> TcM s (TcType s, TcType s)        -- otherwise return arg and result types
 
 
-\begin{verbatim}
-       type Bogus a = Int
-       x = (1 :: Bogus Char) :: Bogus Bool
-\end{verbatim}
+unifyFunTy ty@(TyVarTy tyvar)
+  = tcReadTyVar tyvar  `thenNF_Tc` \ maybe_ty ->
+    case maybe_ty of
+       BoundTo ty' -> unifyFunTy ty'
 
 
-The problem with [the attempted shortcut code] is that
-\begin{verbatim}
-       con1 == con2
-\end{verbatim}
-is not a sufficient condition to be able to use the shortcut!
-You also need to know that the type synonym actually USES all
-its arguments.  For example, consider the following type synonym
-which does not use all its arguments.
-\begin{verbatim}
-       type Bogus a = Int
-\end{verbatim}
+       UnBound     -> newTyVarTy mkTypeKind                    `thenNF_Tc` \ arg ->
+                      newTyVarTy mkTypeKind                    `thenNF_Tc` \ res ->
+                      tcWriteTyVar tyvar (mkFunTy arg res)     `thenNF_Tc_`
+                      returnTc (arg,res)
 
 
-If you ever tried unifying, say, \tr{Bogus Char} with \tr{Bogus Bool},
-the unifier would blithely try to unify \tr{Char} with \tr{Bool} and
-would fail, even though the expanded forms (both \tr{Int}) should
-match.
+       DontBind    -> failTc (expectedFunErr ty)
 
 
-Similarly, unifying \tr{Bogus Char} with \tr{Bogus t} would
-unnecessarily bind \tr{t} to \tr{Char}.
+unifyFunTy other_ty
+  = case getFunTy_maybe other_ty of
+       Just arg_and_res -> returnTc arg_and_res
+       Nothing          -> failTc (expectedFunErr other_ty)
+\end{code}
 
 
-... You could explicitly test for the problem synonyms and mark them
-somehow as needing expansion, perhaps also issuing a warning to the
-user.
-\end{quotation}
 
 
+%************************************************************************
+%*                                                                     *
+\subsection[Unify-context]{Errors and contexts}
+%*                                                                     *
+%************************************************************************
 
 Errors
 ~~~~~~
 
 \begin{code}
 
 Errors
 ~~~~~~
 
 \begin{code}
-unifyCtxt ty1 ty2 sty
-  = ppAboves [
-       ppCat [ppStr "Expected:", ppr sty ty1],
-       ppCat [ppStr "  Actual:", ppr sty ty2]
-    ]
+unifyCtxt ty1 ty2
+  = zonkTcType ty1     `thenNF_Tc` \ ty1' ->
+    zonkTcType ty2     `thenNF_Tc` \ ty2' ->
+    returnNF_Tc (err ty1' ty2')
+  where
+    err ty1' ty2' sty = ppAboves [
+                          ppCat [ppStr "When matching:", ppr sty ty1'],
+                          ppCat [ppStr "      against:", ppr sty ty2']
+                       ]
 
 unifyMisMatch ty1 ty2 sty
   = ppHang (ppStr "Couldn't match the type")
         4 (ppSep [ppr sty ty1, ppStr "against", ppr sty ty2])
 
 
 unifyMisMatch ty1 ty2 sty
   = ppHang (ppStr "Couldn't match the type")
         4 (ppSep [ppr sty ty1, ppStr "against", ppr sty ty2])
 
+expectedFunErr ty sty
+  = ppHang (ppStr "Function type expected, but found the type")
+        4 (ppr sty ty)
+
 unifyKindErr tyvar ty sty
 unifyKindErr tyvar ty sty
-  = ppHang (ppStr "Kind mis-match between")
-        4 (ppSep [ppr sty tyvar, ppStr "and", ppr sty ty])
+  = ppHang (ppStr "Compiler bug: kind mis-match between")
+        4 (ppSep [ppr sty tyvar, ppLparen, ppr sty (getTyVarKind tyvar), ppRparen,
+                  ppStr "and", 
+                  ppr sty ty, ppLparen, ppr sty (getTypeKind ty), ppRparen])
+
+unifyDontBindErr tyvar ty sty
+  = ppHang (ppStr "Couldn't match the *signature/existential* type variable")
+        4 (ppSep [ppr sty tyvar,
+                  ppStr "with the type", 
+                  ppr sty ty])
 
 unifyOccurCheck tyvar ty sty
 
 unifyOccurCheck tyvar ty sty
-  = ppHang (ppStr "Occur check: cannot construct the infinite type")
+  = ppHang (ppStr "Cannot construct the infinite type (occur check)")
         4 (ppSep [ppr sty tyvar, ppStr "=", ppr sty ty])
 \end{code}
 
         4 (ppSep [ppr sty tyvar, ppStr "=", ppr sty ty])
 \end{code}
 
index 0b247e4..945c66b 100644 (file)
@@ -19,6 +19,8 @@ module Kind (
 import Ubiq{-uitous-}
 
 import Util            ( panic )
 import Ubiq{-uitous-}
 
 import Util            ( panic )
+import Outputable      ( Outputable(..) )
+import Pretty
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -48,3 +50,18 @@ argKind :: Kind -> Kind              -- Get argument from arrow kind
 argKind (ArrowKind arg_kind _) = arg_kind
 argKind other_kind            = panic "argKind"
 \end{code}
 argKind (ArrowKind arg_kind _) = arg_kind
 argKind other_kind            = panic "argKind"
 \end{code}
+
+Printing
+~~~~~~~~
+\begin{code}
+instance Outputable Kind where
+  ppr sty kind = pprKind kind
+
+pprKind TypeKind        = ppStr "*"
+pprKind BoxedTypeKind   = ppStr "*b"
+pprKind UnboxedTypeKind = ppStr "*u"
+pprKind (ArrowKind k1 k2) = ppSep [pprKind_parend k1, ppStr "->", pprKind k2]
+
+pprKind_parend k@(ArrowKind _ _) = ppBesides [ppLparen, pprKind k, ppRparen]
+pprKind_parend k                = pprKind k
+\end{code}
index 1c2c089..be52e99 100644 (file)
@@ -7,15 +7,17 @@
 #include "HsVersions.h"
 
 module PprType(
 #include "HsVersions.h"
 
 module PprType(
-       GenTyVar, pprTyVar,
-       TyCon, pprTyCon,
-       GenType, pprType, pprParendType,
-       pprType_Internal,
+       GenTyVar, pprGenTyVar,
+       TyCon, pprTyCon, showTyCon,
+       GenType,
+       pprGenType, pprParendGenType,
+       pprType, pprParendType,
+       pprMaybeTy,
        getTypeString,
        typeMaybeString,
        specMaybeTysSuffix,
        GenClass, 
        getTypeString,
        typeMaybeString,
        specMaybeTysSuffix,
        GenClass, 
-       GenClassOp, pprClassOp
+       GenClassOp, pprGenClassOp
  ) where
 
 import Ubiq
  ) where
 
 import Ubiq
@@ -28,7 +30,7 @@ import NameLoop       -- for paranoia checking
 import Type            ( GenType(..), maybeAppTyCon,
                          splitForAllTy, splitSigmaTy, splitRhoTy, splitAppTy )
 import TyVar           ( GenTyVar(..) )
 import Type            ( GenType(..), maybeAppTyCon,
                          splitForAllTy, splitSigmaTy, splitRhoTy, splitAppTy )
 import TyVar           ( GenTyVar(..) )
-import TyCon           ( TyCon(..), ConsVisible, NewOrData )
+import TyCon           ( TyCon(..), NewOrData )
 import Class           ( Class(..), GenClass(..),
                          ClassOp(..), GenClassOp(..) )
 import Kind            ( Kind(..) )
 import Class           ( Class(..), GenClass(..),
                          ClassOp(..), GenClassOp(..) )
 import Kind            ( Kind(..) )
@@ -39,7 +41,7 @@ import CmdLineOpts    ( opt_OmitInterfacePragmas )
 import Maybes          ( maybeToBool )
 import NameTypes       ( ShortName, FullName )
 import Outputable      ( ifPprShowAll, isAvarop, interpp'SP )
 import Maybes          ( maybeToBool )
 import NameTypes       ( ShortName, FullName )
 import Outputable      ( ifPprShowAll, isAvarop, interpp'SP )
-import PprStyle                ( PprStyle(..), codeStyle )
+import PprStyle                ( PprStyle(..), codeStyle, showUserishTypes )
 import Pretty
 import TysWiredIn      ( listTyCon )
 import Unique          ( pprUnique10, pprUnique )
 import Pretty
 import TysWiredIn      ( listTyCon )
 import Unique          ( pprUnique10, pprUnique )
@@ -50,7 +52,7 @@ import Util
 \begin{code}
 instance (Eq tyvar, Outputable tyvar,
          Eq uvar,  Outputable uvar  ) => Outputable (GenType tyvar uvar) where
 \begin{code}
 instance (Eq tyvar, Outputable tyvar,
          Eq uvar,  Outputable uvar  ) => Outputable (GenType tyvar uvar) where
-    ppr sty ty = pprType sty ty
+    ppr sty ty = pprGenType sty ty
 
 instance Outputable TyCon where
     ppr sty tycon = pprTyCon sty tycon
 
 instance Outputable TyCon where
     ppr sty tycon = pprTyCon sty tycon
@@ -60,10 +62,17 @@ instance Outputable (GenClass tyvar uvar) where
     ppr sty (Class u n _ _ _ _ _ _ _ _) = ppr sty n
 
 instance Outputable ty => Outputable (GenClassOp ty) where
     ppr sty (Class u n _ _ _ _ _ _ _ _) = ppr sty n
 
 instance Outputable ty => Outputable (GenClassOp ty) where
-    ppr sty clsop = pprClassOp sty clsop
+    ppr sty clsop = pprGenClassOp sty clsop
 
 instance Outputable (GenTyVar flexi) where
 
 instance Outputable (GenTyVar flexi) where
-    ppr sty tv = pprTyVar sty tv
+    ppr sty tv = pprGenTyVar sty tv
+
+-- and two SPECIALIZEd ones:
+instance Outputable {-Type, i.e.:-}(GenType TyVar UVar) where
+    ppr sty ty = pprGenType sty ty
+
+instance Outputable {-TyVar, i.e.:-}(GenTyVar Usage) where
+    ppr sty ty = pprGenTyVar sty ty
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -72,29 +81,25 @@ instance Outputable (GenTyVar flexi) where
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-@pprType@ is the std @Type@ printer; the overloaded @ppr@ function is
-defined to use this.  @pprParendType@ is the same, except it puts
-parens around the type, except for the atomic cases.  @pprParendType@
+@pprGenType@ is the std @Type@ printer; the overloaded @ppr@ function is
+defined to use this.  @pprParendGenType@ is the same, except it puts
+parens around the type, except for the atomic cases.  @pprParendGenType@
 works just by setting the initial context precedence very high.
 
 \begin{code}
 works just by setting the initial context precedence very high.
 
 \begin{code}
-pprType, pprParendType :: (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar)
+pprGenType, pprParendGenType :: (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar)
                       => PprStyle -> GenType tyvar uvar -> Pretty
 
                       => PprStyle -> GenType tyvar uvar -> Pretty
 
-pprType       sty ty = ppr_ty sty (initial_ve sty) tOP_PREC   ty
-pprParendType sty ty = ppr_ty sty (initial_ve sty) tYCON_PREC ty
+pprGenType       sty ty = ppr_ty sty (initial_ve sty) tOP_PREC   ty
+pprParendGenType sty ty = ppr_ty sty (initial_ve sty) tYCON_PREC ty
+
+pprType         sty ty = ppr_ty sty (initial_ve sty) tOP_PREC   (ty :: Type)
+pprParendType   sty ty = ppr_ty sty (initial_ve sty) tYCON_PREC (ty :: Type)
 
 pprMaybeTy :: (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar)
            => PprStyle -> Maybe (GenType tyvar uvar) -> Pretty
 pprMaybeTy sty Nothing   = ppChar '*'
 
 pprMaybeTy :: (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar)
            => PprStyle -> Maybe (GenType tyvar uvar) -> Pretty
 pprMaybeTy sty Nothing   = ppChar '*'
-pprMaybeTy sty (Just ty) = pprParendType sty ty
-\end{code}
-
-This somewhat sleazy interface is used when printing out Core syntax
-(see PprCore):
-\begin{code}
-pprType_Internal sty tvs ppr_tv uvs ppr_uv ty
-  = ppr_ty sty (VE tvs ppr_tv uvs ppr_uv) tOP_PREC ty
+pprMaybeTy sty (Just ty) = pprParendGenType sty ty
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -270,17 +275,8 @@ tYCON_PREC  = (2 :: Int)
 maybeParen ctxt_prec inner_prec pretty
   | ctxt_prec < inner_prec = pretty
   | otherwise             = ppParens pretty
 maybeParen ctxt_prec inner_prec pretty
   | ctxt_prec < inner_prec = pretty
   | otherwise             = ppParens pretty
-
-
--- True means types like   (Eq a, Text b) => a -> b
--- False means types like  _forall_ a b => Eq a -> Text b -> a -> b
-showUserishTypes PprForUser   = True   
-showUserishTypes PprInterface = True
-showUserishTypes other       = False
 \end{code}
 
 \end{code}
 
-
-
 %************************************************************************
 %*                                                                     *
 \subsection[TyVar]{@TyVar@}
 %************************************************************************
 %*                                                                     *
 \subsection[TyVar]{@TyVar@}
@@ -288,7 +284,7 @@ showUserishTypes other            = False
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-pprTyVar sty (TyVar uniq kind name usage)
+pprGenTyVar sty (TyVar uniq kind name usage)
   = ppBesides [pp_name, pprUnique10 uniq]
   where
     pp_name = case name of
   = ppBesides [pp_name, pprUnique10 uniq]
   where
     pp_name = case name of
@@ -318,7 +314,7 @@ pprTyCon sty FunTyCon                       = ppStr "(->)"
 pprTyCon sty (TupleTyCon arity)                = ppBeside (ppPStr SLIT("Tuple")) (ppInt arity)
 pprTyCon sty (PrimTyCon uniq name kind) = ppr sty name
 
 pprTyCon sty (TupleTyCon arity)                = ppBeside (ppPStr SLIT("Tuple")) (ppInt arity)
 pprTyCon sty (PrimTyCon uniq name kind) = ppr sty name
 
-pprTyCon sty tycon@(DataTyCon uniq kind name tyvars ctxt cons derivings cv nd)
+pprTyCon sty tycon@(DataTyCon uniq kind name tyvars ctxt cons derivings nd)
   = case sty of
       PprDebug   -> pp_tycon_and_uniq
       PprShowAll -> pp_tycon_and_uniq
   = case sty of
       PprDebug   -> pp_tycon_and_uniq
       PprShowAll -> pp_tycon_and_uniq
@@ -341,7 +337,7 @@ pprTyCon sty (SynTyCon uniq name kind arity tyvars expansion)
                (ppCat [ ppStr " {-", 
                         ppInt arity, 
                         interpp'SP sty tyvars,
                (ppCat [ ppStr " {-", 
                         ppInt arity, 
                         interpp'SP sty tyvars,
-                        pprParendType sty expansion,
+                        pprParendGenType sty expansion,
                         ppStr "-}"]))
 \end{code}
 
                         ppStr "-}"]))
 \end{code}
 
@@ -353,9 +349,9 @@ pprTyCon sty (SynTyCon uniq name kind arity tyvars expansion)
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-pprClassOp :: Outputable ty => PprStyle -> GenClassOp ty -> Pretty
+pprGenClassOp :: Outputable ty => PprStyle -> GenClassOp ty -> Pretty
 
 
-pprClassOp sty op = ppr_class_op sty [] op
+pprGenClassOp sty op = ppr_class_op sty [] op
 
 ppr_class_op sty tyvars (ClassOp op_name i ty)
   = case sty of
 
 ppr_class_op sty tyvars (ClassOp op_name i ty)
   = case sty of
@@ -388,7 +384,7 @@ getTypeString ty
   | otherwise     = [mod, string]
   where
     string = _PK_ (tidy (ppShow 1000 ppr_t))
   | otherwise     = [mod, string]
   where
     string = _PK_ (tidy (ppShow 1000 ppr_t))
-    ppr_t  = pprType PprForC ty
+    ppr_t  = pprGenType PprForC ty
                        -- PprForC expands type synonyms as it goes
 
     (is_prelude_ty, mod)
                        -- PprForC expands type synonyms as it goes
 
     (is_prelude_ty, mod)
@@ -446,7 +442,7 @@ pprTyCon sty@PprInterface (SynonymTyCon k n a vs exp unabstract) specs
     ppCat [ppPStr SLIT("type"), ppr sty n, ppIntersperse ppSP pp_tyvars,
           ppEquals, ppr_ty sty lookup_fn tOP_PREC exp]
 
     ppCat [ppPStr SLIT("type"), ppr sty n, ppIntersperse ppSP pp_tyvars,
           ppEquals, ppr_ty sty lookup_fn tOP_PREC exp]
 
-pprTyCon sty@PprInterface this_tycon@(DataTyCon k n a vs ctxt cons derivings unabstract data_or_new) specs
+pprTyCon sty@PprInterface this_tycon@(DataTyCon k n a vs ctxt cons derivings data_or_new) specs
   = ppHang (ppCat [pp_data_or_new,
                   pprContext sty ctxt,
                   ppr sty n,
   = ppHang (ppCat [pp_data_or_new,
                   pprContext sty ctxt,
                   ppr sty n,
@@ -507,7 +503,7 @@ pprTyCon sty@PprInterface this_tycon@(DataTyCon k n a vs ctxt cons derivings una
       where
        ppr_con con
          = let
       where
        ppr_con con
          = let
-               (_, _, con_arg_tys, _) = getDataConSig con
+               (_, _, con_arg_tys, _) = dataConSig con
            in
            ppCat [pprNonOp PprForUser con, -- the data con's name...
                   ppIntersperse ppSP (map (ppr_ty sty lookup_fn tYCON_PREC) con_arg_tys)]
            in
            ppCat [pprNonOp PprForUser con, -- the data con's name...
                   ppIntersperse ppSP (map (ppr_ty sty lookup_fn tYCON_PREC) con_arg_tys)]
@@ -523,7 +519,7 @@ pprTyCon sty@PprInterface this_tycon@(DataTyCon k n a vs ctxt cons derivings una
     pp_the_list (p:ps) = ppAbove (ppBeside p ppComma) (pp_the_list ps)
 
     pp_maybe Nothing   = pp_NONE
     pp_the_list (p:ps) = ppAbove (ppBeside p ppComma) (pp_the_list ps)
 
     pp_maybe Nothing   = pp_NONE
-    pp_maybe (Just ty) = pprParendType sty ty
+    pp_maybe (Just ty) = pprParendGenType sty ty
 
     pp_NONE = ppPStr SLIT("_N_")
 
 
     pp_NONE = ppPStr SLIT("_N_")
 
index 79dae8e..36b70dc 100644 (file)
@@ -9,9 +9,10 @@
 module TyCon(
        TyCon(..),      -- NB: some pals need to see representation
 
 module TyCon(
        TyCon(..),      -- NB: some pals need to see representation
 
-       Arity(..), ConsVisible(..), NewOrData(..),
+       Arity(..), NewOrData(..),
 
 
-       isFunTyCon, isPrimTyCon, isVisibleDataTyCon,
+       isFunTyCon, isPrimTyCon, isBoxedTyCon,
+       isDataTyCon, isSynTyCon,
 
        mkDataTyCon,
        mkFunTyCon,
 
        mkDataTyCon,
        mkFunTyCon,
@@ -21,12 +22,14 @@ module TyCon(
 
        mkSynTyCon,
 
 
        mkSynTyCon,
 
-       getTyConKind,
-       getTyConUnique,
-       getTyConTyVars,
-       getTyConDataCons,
-       getTyConDerivings,
-       getSynTyConArity,
+       tyConKind,
+       tyConUnique,
+       tyConTyVars,
+       tyConDataCons,
+       tyConFamilySize,
+       tyConDerivings,
+       tyConArity, synTyConArity,
+       getSynTyConDefn,
 
         maybeTyConSingleCon,
        isEnumerationTyCon,
 
         maybeTyConSingleCon,
        isEnumerationTyCon,
@@ -39,7 +42,7 @@ import NameLoop       -- for paranoia checking
 import TyLoop          ( Type(..), GenType,
                          Class(..), GenClass,
                          Id(..), GenId,
 import TyLoop          ( Type(..), GenType,
                          Class(..), GenClass,
                          Id(..), GenId,
-                         mkTupleCon, getDataConSig,
+                         mkTupleCon, dataConSig,
                          specMaybeTysSuffix
                        )
 
                          specMaybeTysSuffix
                        )
 
@@ -71,7 +74,6 @@ data TyCon
                [(Class,Type)]  -- Its context
                [Id]            -- Its data constructors, with fully polymorphic types
                [Class]         -- Classes which have derived instances
                [(Class,Type)]  -- Its context
                [Id]            -- Its data constructors, with fully polymorphic types
                [Class]         -- Classes which have derived instances
-               ConsVisible
                NewOrData
 
   | TupleTyCon Arity   -- just a special case of DataTyCon
                NewOrData
 
   | TupleTyCon Arity   -- just a special case of DataTyCon
@@ -106,10 +108,6 @@ data TyCon
                        -- Acts as a template for the expansion when
                        -- the tycon is applied to some types.
 
                        -- Acts as a template for the expansion when
                        -- the tycon is applied to some types.
 
-data ConsVisible
-  = ConsVisible            -- whether or not data constructors are visible
-  | ConsInvisible   -- outside their TyCon's defining module.
-
 data NewOrData
   = NewType        -- "newtype Blah ..."
   | DataType       -- "data Blah ..."
 data NewOrData
   = NewType        -- "newtype Blah ..."
   | DataType       -- "data Blah ..."
@@ -129,8 +127,17 @@ isFunTyCon _ = False
 isPrimTyCon (PrimTyCon _ _ _) = True
 isPrimTyCon _ = False
 
 isPrimTyCon (PrimTyCon _ _ _) = True
 isPrimTyCon _ = False
 
-isVisibleDataTyCon (DataTyCon _ _ _ _ _ _ _ ConsVisible _) = True
-isVisibleDataTyCon _ = False
+-- At present there are no unboxed non-primitive types, so
+-- isBoxedTyCon is just the negation of isPrimTyCon.
+isBoxedTyCon = not . isPrimTyCon
+
+-- isDataTyCon returns False for @newtype@.
+-- Not sure about this decision yet.
+isDataTyCon (DataTyCon _ _ _ _ _ _ _ DataType) = True
+isDataTyCon other                             = False
+
+isSynTyCon (SynTyCon _ _ _ _ _ _) = True
+isSynTyCon _                     = False
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
@@ -138,20 +145,20 @@ isVisibleDataTyCon _ = False
 kind1 = mkBoxedTypeKind `mkArrowKind` mkBoxedTypeKind
 kind2 = mkBoxedTypeKind `mkArrowKind` kind1
 
 kind1 = mkBoxedTypeKind `mkArrowKind` mkBoxedTypeKind
 kind2 = mkBoxedTypeKind `mkArrowKind` kind1
 
-getTyConKind :: TyCon -> Kind
-getTyConKind FunTyCon                        = kind2
-getTyConKind (DataTyCon _ kind _ _ _ _ _ _ _) = kind
-getTyConKind (PrimTyCon _ _ kind)            = kind
+tyConKind :: TyCon -> Kind
+tyConKind FunTyCon                      = kind2
+tyConKind (DataTyCon _ kind _ _ _ _ _ _) = kind
+tyConKind (PrimTyCon _ _ kind)          = kind
 
 
-getTyConKind (SpecTyCon tc tys)
-  = spec (getTyConKind tc) tys
+tyConKind (SpecTyCon tc tys)
+  = spec (tyConKind tc) tys
    where
     spec kind []             = kind
     spec kind (Just _  : tys) = spec (resultKind kind) tys
     spec kind (Nothing : tys) =
       argKind kind `mkArrowKind` spec (resultKind kind) tys
 
    where
     spec kind []             = kind
     spec kind (Just _  : tys) = spec (resultKind kind) tys
     spec kind (Nothing : tys) =
       argKind kind `mkArrowKind` spec (resultKind kind) tys
 
-getTyConKind (TupleTyCon n)
+tyConKind (TupleTyCon n)
   = mkArrow n
    where
     mkArrow 0 = mkBoxedTypeKind
   = mkArrow n
    where
     mkArrow 0 = mkBoxedTypeKind
@@ -161,57 +168,78 @@ getTyConKind (TupleTyCon n)
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-getTyConUnique :: TyCon -> Unique
-getTyConUnique FunTyCon                                = funTyConKey
-getTyConUnique (DataTyCon uniq _ _ _ _ _ _ _ _) = uniq
-getTyConUnique (TupleTyCon a)                  = mkTupleTyConUnique a
-getTyConUnique (PrimTyCon uniq _ _)            = uniq
-getTyConUnique (SynTyCon uniq _ _ _ _ _)        = uniq
-getTyConUnique (SpecTyCon _ _ )                = panic "getTyConUnique:SpecTyCon"
+tyConUnique :: TyCon -> Unique
+tyConUnique FunTyCon                      = funTyConKey
+tyConUnique (DataTyCon uniq _ _ _ _ _ _ _) = uniq
+tyConUnique (TupleTyCon a)                = mkTupleTyConUnique a
+tyConUnique (PrimTyCon uniq _ _)          = uniq
+tyConUnique (SynTyCon uniq _ _ _ _ _)      = uniq
+tyConUnique (SpecTyCon _ _ )              = panic "tyConUnique:SpecTyCon"
+
+tyConArity :: TyCon -> Arity
+tyConArity FunTyCon                     = 2
+tyConArity (DataTyCon _ _ _ tvs _ _ _ _) = length tvs
+tyConArity (TupleTyCon arity)           = arity
+tyConArity (PrimTyCon _ _ _)            = 0    -- ??
+tyConArity (SpecTyCon _ _)              = 0
+tyConArity (SynTyCon _ _ _ arity _ _)    = arity
+
+synTyConArity :: TyCon -> Maybe Arity -- Nothing <=> not a syn tycon
+synTyConArity (SynTyCon _ _ _ arity _ _) = Just arity
+synTyConArity _                                 = Nothing
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-getTyConTyVars :: TyCon -> [TyVar]
-getTyConTyVars FunTyCon                               = [alphaTyVar,betaTyVar]
-getTyConTyVars (DataTyCon _ _ _ tvs _ _ _ _ _) = tvs
-getTyConTyVars (TupleTyCon arity)             = take arity alphaTyVars
-getTyConTyVars (SynTyCon _ _ _ _ tvs _)        = tvs
-getTyConTyVars (PrimTyCon _ _ _)              = panic "getTyConTyVars:PrimTyCon"
-getTyConTyVars (SpecTyCon _ _ )               = panic "getTyConTyVars:SpecTyCon"
+tyConTyVars :: TyCon -> [TyVar]
+tyConTyVars FunTyCon                     = [alphaTyVar,betaTyVar]
+tyConTyVars (DataTyCon _ _ _ tvs _ _ _ _) = tvs
+tyConTyVars (TupleTyCon arity)           = take arity alphaTyVars
+tyConTyVars (SynTyCon _ _ _ _ tvs _)      = tvs
+tyConTyVars (PrimTyCon _ _ _)            = panic "tyConTyVars:PrimTyCon"
+tyConTyVars (SpecTyCon _ _ )             = panic "tyConTyVars:SpecTyCon"
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-getTyConDataCons :: TyCon -> [Id]
-getTyConDataCons (DataTyCon _ _ _ _ _ data_cons _ _ _) = data_cons
-getTyConDataCons (TupleTyCon a)                               = [mkTupleCon a]
+tyConDataCons :: TyCon -> [Id]
+tyConFamilySize  :: TyCon -> Int
+
+tyConDataCons (DataTyCon _ _ _ _ _ data_cons _ _) = data_cons
+tyConDataCons (TupleTyCon a)                     = [mkTupleCon a]
+tyConDataCons other                              = []
+       -- You may think this last equation should fail,
+       -- but it's quite convenient to return no constructors for
+       -- a synonym; see for example the call in TcTyClsDecls.
+
+tyConFamilySize (DataTyCon _ _ _ _ _ data_cons _ _) = length data_cons
+tyConFamilySize (TupleTyCon a)                     = 1
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-getTyConDerivings :: TyCon -> [Class]
-getTyConDerivings (DataTyCon _ _ _ _ _ _ derivs _ _) = derivs
+tyConDerivings :: TyCon -> [Class]
+tyConDerivings (DataTyCon _ _ _ _ _ _ derivs _) = derivs
+tyConDerivings other                              = []
 \end{code}
 
 \begin{code}
 \end{code}
 
 \begin{code}
-getSynTyConArity :: TyCon -> Maybe Arity
-getSynTyConArity (SynTyCon _ _ _ arity _ _) = Just arity
-getSynTyConArity other                     = Nothing
+getSynTyConDefn :: TyCon -> ([TyVar], Type)
+getSynTyConDefn (SynTyCon _ _ _ _ tyvars ty) = (tyvars,ty)
 \end{code}
 
 \begin{code}
 maybeTyConSingleCon :: TyCon -> Maybe Id
 \end{code}
 
 \begin{code}
 maybeTyConSingleCon :: TyCon -> Maybe Id
-maybeTyConSingleCon (TupleTyCon arity)              = Just (mkTupleCon arity)
-maybeTyConSingleCon (DataTyCon _ _ _ _ _ [c] _ _ _)  = Just c
-maybeTyConSingleCon (DataTyCon _ _ _ _ _ _   _ _ _)  = Nothing
-maybeTyConSingleCon (PrimTyCon _ _ _)               = Nothing
-maybeTyConSingleCon (SpecTyCon tc tys)               = panic "maybeTyConSingleCon:SpecTyCon"
-                                                    -- requires DataCons of TyCon
+maybeTyConSingleCon (TupleTyCon arity)           = Just (mkTupleCon arity)
+maybeTyConSingleCon (DataTyCon _ _ _ _ _ [c] _ _) = Just c
+maybeTyConSingleCon (DataTyCon _ _ _ _ _ _   _ _) = Nothing
+maybeTyConSingleCon (PrimTyCon _ _ _)            = Nothing
+maybeTyConSingleCon (SpecTyCon tc tys)            = panic "maybeTyConSingleCon:SpecTyCon"
+                                                 -- requires DataCons of TyCon
 
 isEnumerationTyCon (TupleTyCon arity)
   = arity == 0
 
 isEnumerationTyCon (TupleTyCon arity)
   = arity == 0
-isEnumerationTyCon (DataTyCon _ _ _ _ _ data_cons _ _ _)
+isEnumerationTyCon (DataTyCon _ _ _ _ _ data_cons _ _)
   = not (null data_cons) && all is_nullary data_cons
   where
   = not (null data_cons) && all is_nullary data_cons
   where
-    is_nullary con = case (getDataConSig con) of { (_,_, arg_tys, _) ->
+    is_nullary con = case (dataConSig con) of { (_,_, arg_tys, _) ->
                     null arg_tys }
 \end{code}
 
                     null arg_tys }
 \end{code}
 
@@ -224,8 +252,8 @@ ToDo: what about derivings for specialised tycons !!!
 
 \begin{code}
 derivedFor :: Class -> TyCon -> Bool
 
 \begin{code}
 derivedFor :: Class -> TyCon -> Bool
-derivedFor clas (DataTyCon _ _ _ _ _ _ derivs _ _) = isIn "derivedFor" clas derivs
-derivedFor clas something_weird                           = False
+derivedFor clas (DataTyCon _ _ _ _ _ _ derivs _) = isIn "derivedFor" clas derivs
+derivedFor clas something_weird                         = False
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -241,12 +269,12 @@ the property @(a<=b) || (b<=a)@.
 
 \begin{code}
 instance Ord3 TyCon where
 
 \begin{code}
 instance Ord3 TyCon where
-  cmp FunTyCon                     FunTyCon                      = EQ_
-  cmp (DataTyCon a _ _ _ _ _ _ _ _) (DataTyCon b _ _ _ _ _ _ _ _) = a `cmp` b
-  cmp (SynTyCon a _ _ _ _ _)        (SynTyCon b _ _ _ _ _)        = a `cmp` b
-  cmp (TupleTyCon a)               (TupleTyCon b)                = a `cmp` b
-  cmp (PrimTyCon a _ _)                    (PrimTyCon b _ _)             = a `cmp` b
-  cmp (SpecTyCon tc1 mtys1)        (SpecTyCon tc2 mtys2)
+  cmp FunTyCon                   FunTyCon                    = EQ_
+  cmp (DataTyCon a _ _ _ _ _ _ _) (DataTyCon b _ _ _ _ _ _ _) = a `cmp` b
+  cmp (SynTyCon a _ _ _ _ _)      (SynTyCon b _ _ _ _ _)      = a `cmp` b
+  cmp (TupleTyCon a)             (TupleTyCon b)              = a `cmp` b
+  cmp (PrimTyCon a _ _)                  (PrimTyCon b _ _)           = a `cmp` b
+  cmp (SpecTyCon tc1 mtys1)      (SpecTyCon tc2 mtys2)
     = panic# "cmp on SpecTyCons" -- case (tc1 `cmp` tc2) of { EQ_ -> mtys1 `cmp` mtys2; xxx -> xxx }
 
     -- now we *know* the tags are different, so...
     = panic# "cmp on SpecTyCons" -- case (tc1 `cmp` tc2) of { EQ_ -> mtys1 `cmp` mtys2; xxx -> xxx }
 
     -- now we *know* the tags are different, so...
@@ -256,11 +284,11 @@ instance Ord3 TyCon where
     where
       tag1 = tag_TyCon other_1
       tag2 = tag_TyCon other_2
     where
       tag1 = tag_TyCon other_1
       tag2 = tag_TyCon other_2
-      tag_TyCon FunTyCon                     = ILIT(1)
-      tag_TyCon (DataTyCon _ _ _ _ _ _ _ _ _) = ILIT(2)
-      tag_TyCon (TupleTyCon _)               = ILIT(3)
-      tag_TyCon (PrimTyCon  _ _ _)           = ILIT(4)
-      tag_TyCon (SpecTyCon  _ _)             = ILIT(5)
+      tag_TyCon FunTyCon                   = ILIT(1)
+      tag_TyCon (DataTyCon _ _ _ _ _ _ _ _) = ILIT(2)
+      tag_TyCon (TupleTyCon _)             = ILIT(3)
+      tag_TyCon (PrimTyCon  _ _ _)         = ILIT(4)
+      tag_TyCon (SpecTyCon  _ _)           = ILIT(5)
 
 instance Eq TyCon where
     a == b = case (a `cmp` b) of { EQ_ -> True;   _ -> False }
 
 instance Eq TyCon where
     a == b = case (a `cmp` b) of { EQ_ -> True;   _ -> False }
@@ -305,7 +333,7 @@ instance NamedThing TyCon where
                     Nothing   -> mkBuiltinSrcLoc
                     Just name -> getSrcLoc name
 
                     Nothing   -> mkBuiltinSrcLoc
                     Just name -> getSrcLoc name
 
-    getItsUnique tycon = getTyConUnique tycon
+    getItsUnique tycon = tyConUnique tycon
 
     fromPreludeCore tc = case get_name tc of
                           Nothing   -> True
 
     fromPreludeCore tc = case get_name tc of
                           Nothing   -> True
@@ -315,10 +343,9 @@ instance NamedThing TyCon where
 Emphatically un-exported:
 
 \begin{code}
 Emphatically un-exported:
 
 \begin{code}
-get_name (DataTyCon _ _ n _ _ _ _ _ _) = Just n
-get_name (PrimTyCon _ n _)            = Just n
-get_name (SpecTyCon tc _)             = get_name tc
-get_name (SynTyCon _ n _ _ _ _)               = Just n
-get_name other                        = Nothing
+get_name (DataTyCon _ _ n _ _ _ _ _) = Just n
+get_name (PrimTyCon _ n _)          = Just n
+get_name (SpecTyCon tc _)           = get_name tc
+get_name (SynTyCon _ n _ _ _ _)             = Just n
+get_name other                      = Nothing
 \end{code}
 \end{code}
-
index ac76205..a97c27d 100644 (file)
@@ -8,7 +8,7 @@ import PreludeStdIO ( Maybe )
 import Unique ( Unique )
 
 import Id      ( Id, GenId, StrictnessMark, mkTupleCon, mkDataCon,
 import Unique ( Unique )
 
 import Id      ( Id, GenId, StrictnessMark, mkTupleCon, mkDataCon,
-                getDataConSig, getInstantiatedDataConSig )
+                dataConSig, getInstantiatedDataConSig )
 import PprType ( specMaybeTysSuffix )
 import NameTypes ( FullName )
 import TyCon   ( TyCon )
 import PprType ( specMaybeTysSuffix )
 import NameTypes ( FullName )
 import TyCon   ( TyCon )
@@ -30,7 +30,7 @@ type Id          = GenId (GenType (GenTyVar (GenUsage Unique)) Unique)
 
 -- Needed in TyCon
 mkTupleCon :: Int -> Id
 
 -- Needed in TyCon
 mkTupleCon :: Int -> Id
-getDataConSig :: Id -> ([TyVar], [(Class, Type)], [Type], TyCon)
+dataConSig :: Id -> ([TyVar], [(Class, Type)], [Type], TyCon)
 specMaybeTysSuffix :: [Maybe Type] -> _PackedString
 instance Eq (GenClass a b)
 
 specMaybeTysSuffix :: [Maybe Type] -> _PackedString
 instance Eq (GenClass a b)
 
index c963c1d..f59382a 100644 (file)
@@ -5,6 +5,7 @@ module TyVar (
        GenTyVar(..), TyVar(..),
        mkTyVar,
        getTyVarKind,           -- TyVar -> Kind
        GenTyVar(..), TyVar(..),
        mkTyVar,
        getTyVarKind,           -- TyVar -> Kind
+       cloneTyVar,
 
        alphaTyVars, alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar,
 
 
        alphaTyVars, alphaTyVar, betaTyVar, gammaTyVar, deltaTyVar,
 
@@ -15,7 +16,7 @@ module TyVar (
        growTyVarEnvList, isNullTyVarEnv, lookupTyVarEnv,
 
        GenTyVarSet(..), TyVarSet(..),
        growTyVarEnvList, isNullTyVarEnv, lookupTyVarEnv,
 
        GenTyVarSet(..), TyVarSet(..),
-       emptyTyVarSet, singletonTyVarSet, unionTyVarSets,
+       emptyTyVarSet, unitTyVarSet, unionTyVarSets,
        unionManyTyVarSets, intersectTyVarSets, mkTyVarSet,
        tyVarSetToList, elementOfTyVarSet, minusTyVarSet,
        isEmptyTyVarSet
        unionManyTyVarSets, intersectTyVarSets, mkTyVarSet,
        tyVarSetToList, elementOfTyVarSet, minusTyVarSet,
        isEmptyTyVarSet
@@ -67,6 +68,9 @@ mkTyVar name uniq kind = TyVar  uniq
 
 getTyVarKind :: GenTyVar flexi -> Kind
 getTyVarKind (TyVar _ kind _ _) = kind
 
 getTyVarKind :: GenTyVar flexi -> Kind
 getTyVarKind (TyVar _ kind _ _) = kind
+
+cloneTyVar :: GenTyVar flexi -> Unique -> GenTyVar flexi
+cloneTyVar (TyVar _ k n x) u = TyVar u k n x
 \end{code}
 
 
 \end{code}
 
 
@@ -112,14 +116,14 @@ intersectTyVarSets:: GenTyVarSet flexi -> GenTyVarSet flexi -> GenTyVarSet flexi
 unionTyVarSets    :: GenTyVarSet flexi -> GenTyVarSet flexi -> GenTyVarSet flexi
 unionManyTyVarSets:: [GenTyVarSet flexi] -> GenTyVarSet flexi
 tyVarSetToList    :: GenTyVarSet flexi -> [GenTyVar flexi]
 unionTyVarSets    :: GenTyVarSet flexi -> GenTyVarSet flexi -> GenTyVarSet flexi
 unionManyTyVarSets:: [GenTyVarSet flexi] -> GenTyVarSet flexi
 tyVarSetToList    :: GenTyVarSet flexi -> [GenTyVar flexi]
-singletonTyVarSet :: GenTyVar flexi -> GenTyVarSet flexi
+unitTyVarSet :: GenTyVar flexi -> GenTyVarSet flexi
 elementOfTyVarSet :: GenTyVar flexi -> GenTyVarSet flexi -> Bool
 minusTyVarSet    :: GenTyVarSet flexi -> GenTyVarSet flexi -> GenTyVarSet flexi
 isEmptyTyVarSet   :: GenTyVarSet flexi -> Bool
 mkTyVarSet       :: [GenTyVar flexi] -> GenTyVarSet flexi
 
 emptyTyVarSet            = emptyUniqSet
 elementOfTyVarSet :: GenTyVar flexi -> GenTyVarSet flexi -> Bool
 minusTyVarSet    :: GenTyVarSet flexi -> GenTyVarSet flexi -> GenTyVarSet flexi
 isEmptyTyVarSet   :: GenTyVarSet flexi -> Bool
 mkTyVarSet       :: [GenTyVar flexi] -> GenTyVarSet flexi
 
 emptyTyVarSet            = emptyUniqSet
-singletonTyVarSet = singletonUniqSet
+unitTyVarSet = unitUniqSet
 intersectTyVarSets= intersectUniqSets
 unionTyVarSets           = unionUniqSets
 unionManyTyVarSets= unionManyUniqSets
 intersectTyVarSets= intersectUniqSets
 unionTyVarSets           = unionUniqSets
 unionManyTyVarSets= unionManyUniqSets
index a635130..d84a1da 100644 (file)
@@ -13,7 +13,7 @@ module Type (
        mkForAllUsageTy, getForAllUsageTy,
        applyTy,
 
        mkForAllUsageTy, getForAllUsageTy,
        applyTy,
 
-       isPrimType,
+       isPrimType, isUnboxedType, typePrimRep,
 
        RhoType(..), SigmaType(..), ThetaType(..),
        mkDictTy,
 
        RhoType(..), SigmaType(..), ThetaType(..),
        mkDictTy,
@@ -26,7 +26,8 @@ module Type (
 
        matchTy, matchTys, eqTy, eqSimpleTy, eqSimpleTheta,
 
 
        matchTy, matchTys, eqTy, eqSimpleTy, eqSimpleTheta,
 
-       instantiateTy,instantiateUsage,
+       instantiateTy, instantiateTauTy, instantiateUsage,
+       applyTypeEnvToTy,
 
        isTauTy,
 
 
        isTauTy,
 
@@ -43,17 +44,18 @@ import PrelLoop  -- for paranoia checking
 -- friends:
 import Class   ( getClassSig, getClassOpLocalType, GenClass{-instances-} )
 import Kind    ( mkBoxedTypeKind, resultKind )
 -- friends:
 import Class   ( getClassSig, getClassOpLocalType, GenClass{-instances-} )
 import Kind    ( mkBoxedTypeKind, resultKind )
-import TyCon   ( mkFunTyCon, mkTupleTyCon, isFunTyCon, isPrimTyCon,
-                 getTyConKind, getTyConDataCons, TyCon )
+import TyCon   ( mkFunTyCon, mkTupleTyCon, isFunTyCon, isPrimTyCon, isDataTyCon, tyConArity,
+                 tyConKind, tyConDataCons, getSynTyConDefn, TyCon )
 import TyVar   ( getTyVarKind, GenTyVar{-instances-}, GenTyVarSet(..),
                  emptyTyVarSet, unionTyVarSets, minusTyVarSet,
 import TyVar   ( getTyVarKind, GenTyVar{-instances-}, GenTyVarSet(..),
                  emptyTyVarSet, unionTyVarSets, minusTyVarSet,
-                 singletonTyVarSet, nullTyVarEnv, lookupTyVarEnv,
+                 unitTyVarSet, nullTyVarEnv, lookupTyVarEnv,
                  addOneToTyVarEnv, TyVarEnv(..) )
 import Usage   ( usageOmega, GenUsage, Usage(..), UVar(..), UVarEnv(..),
                  nullUVarEnv, addOneToUVarEnv, lookupUVarEnv, eqUVar,
                  eqUsage )
 
 -- others
                  addOneToTyVarEnv, TyVarEnv(..) )
 import Usage   ( usageOmega, GenUsage, Usage(..), UVar(..), UVarEnv(..),
                  nullUVarEnv, addOneToUVarEnv, lookupUVarEnv, eqUVar,
                  eqUsage )
 
 -- others
+import PrimRep ( PrimRep(..) )
 import Util    ( thenCmp, zipEqual, panic, panic#, assertPanic,
                  Ord3(..){-instances-}
                )
 import Util    ( thenCmp, zipEqual, panic, panic#, assertPanic,
                  Ord3(..){-instances-}
                )
@@ -233,7 +235,9 @@ getTyCon_maybe other_ty              = Nothing
 
 \begin{code}
 mkSynTy syn_tycon tys
 
 \begin{code}
 mkSynTy syn_tycon tys
-  = SynTy syn_tycon tys (panic "Type.mkSynTy:expansion")
+  = SynTy syn_tycon tys (instantiateTauTy (zipEqual tyvars tys) body)
+  where
+    (tyvars, body) = getSynTyConDefn syn_tycon
 \end{code}
 
 Tau stuff
 \end{code}
 
 Tau stuff
@@ -344,11 +348,12 @@ maybeAppDataTyCon
 
 maybeAppDataTyCon ty
   = case (getTyCon_maybe app_ty) of
 
 maybeAppDataTyCon ty
   = case (getTyCon_maybe app_ty) of
-       Nothing    -> Nothing
-       Just tycon | isFunTyCon tycon
-                  -> Nothing
-                  | otherwise
-                  -> Just (tycon, arg_tys, getTyConDataCons tycon)
+       Just tycon |  isDataTyCon tycon && 
+                     tyConArity tycon == length arg_tys
+                       -- Must be saturated for ty to be a data type
+                  -> Just (tycon, arg_tys, tyConDataCons tycon)
+
+       other      -> Nothing
   where
     (app_ty, arg_tys) = splitAppTy ty
 
   where
     (app_ty, arg_tys) = splitAppTy ty
 
@@ -397,7 +402,7 @@ Finding the kind of a type
 \begin{code}
 getTypeKind :: GenType (GenTyVar any) u -> Kind
 getTypeKind (TyVarTy tyvar)            = getTyVarKind tyvar
 \begin{code}
 getTypeKind :: GenType (GenTyVar any) u -> Kind
 getTypeKind (TyVarTy tyvar)            = getTyVarKind tyvar
-getTypeKind (TyConTy tycon usage)      = getTyConKind tycon
+getTypeKind (TyConTy tycon usage)      = tyConKind tycon
 getTypeKind (SynTy _ _ ty)             = getTypeKind ty
 getTypeKind (FunTy fun arg _)          = mkBoxedTypeKind
 getTypeKind (DictTy clas arg _)                = mkBoxedTypeKind
 getTypeKind (SynTy _ _ ty)             = getTypeKind ty
 getTypeKind (FunTy fun arg _)          = mkBoxedTypeKind
 getTypeKind (DictTy clas arg _)                = mkBoxedTypeKind
@@ -412,13 +417,13 @@ Free variables of a type
 \begin{code}
 tyVarsOfType :: GenType (GenTyVar flexi) uvar -> GenTyVarSet flexi
 
 \begin{code}
 tyVarsOfType :: GenType (GenTyVar flexi) uvar -> GenTyVarSet flexi
 
-tyVarsOfType (TyVarTy tv)              = singletonTyVarSet tv
+tyVarsOfType (TyVarTy tv)              = unitTyVarSet tv
 tyVarsOfType (TyConTy tycon usage)     = emptyTyVarSet
 tyVarsOfType (SynTy _ tys ty)          = tyVarsOfTypes tys
 tyVarsOfType (FunTy arg res _)         = tyVarsOfType arg `unionTyVarSets` tyVarsOfType res
 tyVarsOfType (AppTy fun arg)           = tyVarsOfType fun `unionTyVarSets` tyVarsOfType arg
 tyVarsOfType (DictTy clas ty _)                = tyVarsOfType ty
 tyVarsOfType (TyConTy tycon usage)     = emptyTyVarSet
 tyVarsOfType (SynTy _ tys ty)          = tyVarsOfTypes tys
 tyVarsOfType (FunTy arg res _)         = tyVarsOfType arg `unionTyVarSets` tyVarsOfType res
 tyVarsOfType (AppTy fun arg)           = tyVarsOfType fun `unionTyVarSets` tyVarsOfType arg
 tyVarsOfType (DictTy clas ty _)                = tyVarsOfType ty
-tyVarsOfType (ForAllTy tyvar ty)       = tyVarsOfType ty `minusTyVarSet` singletonTyVarSet tyvar
+tyVarsOfType (ForAllTy tyvar ty)       = tyVarsOfType ty `minusTyVarSet` unitTyVarSet tyvar
 tyVarsOfType (ForAllUsageTy _ _ ty)    = tyVarsOfType ty
 
 tyVarsOfTypes :: [GenType (GenTyVar flexi) uvar] -> GenTyVarSet flexi
 tyVarsOfType (ForAllUsageTy _ _ ty)    = tyVarsOfType ty
 
 tyVarsOfTypes :: [GenType (GenTyVar flexi) uvar] -> GenTyVarSet flexi
@@ -453,17 +458,84 @@ instantiateTy tenv ty
 
     go (ForAllUsageTy uvar bds ty) = ForAllUsageTy uvar bds (go ty)
 
 
     go (ForAllUsageTy uvar bds ty) = ForAllUsageTy uvar bds (go ty)
 
+
+-- instantiateTauTy works only (a) on types with no ForAlls,
+--     and when               (b) all the type variables are being instantiated
+-- In return it is more polymorphic than instantiateTy
+
+instantiateTauTy :: Eq t => [(t, GenType t' u)] -> GenType t u -> GenType t' u
+instantiateTauTy tenv ty 
+  = go ty
+  where
+    go (TyVarTy tv)            = case [ty | (tv',ty) <- tenv, tv==tv'] of
+                                 (ty:_) -> ty
+                                 []     -> panic "instantiateTauTy"
+    go (TyConTy tycon usage)    = TyConTy tycon usage
+    go (SynTy tycon tys ty)    = SynTy tycon (map go tys) (go ty)
+    go (FunTy arg res usage)   = FunTy (go arg) (go res) usage
+    go (AppTy fun arg)         = AppTy (go fun) (go arg)
+    go (DictTy clas ty usage)  = DictTy clas (go ty) usage
+
 instantiateUsage
        :: Ord3 u => [(u, GenType t u')] -> GenType t u -> GenType t u'
 instantiateUsage = error "instantiateUsage: not implemented"
 \end{code}
 
 \begin{code}
 instantiateUsage
        :: Ord3 u => [(u, GenType t u')] -> GenType t u -> GenType t u'
 instantiateUsage = error "instantiateUsage: not implemented"
 \end{code}
 
 \begin{code}
-isPrimType :: GenType tyvar uvar -> Bool
+type TypeEnv = TyVarEnv Type
+
+applyTypeEnvToTy :: TypeEnv -> SigmaType -> SigmaType
+applyTypeEnvToTy tenv ty
+  = mapOverTyVars v_fn ty
+  where
+    v_fn v = case (lookupTyVarEnv tenv v) of
+                Just ty -> ty
+               Nothing -> TyVarTy v
+\end{code}
+
+@mapOverTyVars@ is a local function which actually does the work.  It
+does no cloning or other checks for shadowing, so be careful when
+calling this on types with Foralls in them.
+
+\begin{code}
+mapOverTyVars :: (TyVar -> Type) -> Type -> Type
+
+mapOverTyVars v_fn ty
+  = let
+       mapper = mapOverTyVars v_fn
+    in
+    case ty of
+      TyVarTy v                -> v_fn v
+      SynTy c as e     -> SynTy c (map mapper as) (mapper e)
+      FunTy a r u      -> FunTy (mapper a) (mapper r) u
+      AppTy f a                -> AppTy (mapper f) (mapper a)
+      DictTy c t u     -> DictTy c (mapper t) u
+      ForAllTy v t     -> ForAllTy v (mapper t)
+      tc@(TyConTy _ _) -> tc
+\end{code}
+
+At present there are no unboxed non-primitive types, so
+isUnboxedType is the same as isPrimType.
+
+\begin{code}
+isPrimType, isUnboxedType :: GenType tyvar uvar -> Bool
+
 isPrimType (AppTy ty _)      = isPrimType ty
 isPrimType (SynTy _ _ ty)    = isPrimType ty
 isPrimType (TyConTy tycon _) = isPrimTyCon tycon
 isPrimType _                = False
 isPrimType (AppTy ty _)      = isPrimType ty
 isPrimType (SynTy _ _ ty)    = isPrimType ty
 isPrimType (TyConTy tycon _) = isPrimTyCon tycon
 isPrimType _                = False
+
+isUnboxedType = isPrimType
+\end{code}
+
+This is *not* right: it is a placeholder (ToDo 96/03 WDP):
+\begin{code}
+typePrimRep :: GenType tyvar uvar -> PrimRep
+
+typePrimRep (SynTy _ _ ty)  = typePrimRep ty
+typePrimRep (TyConTy tc _)  = if isPrimTyCon tc then panic "typePrimRep:PrimTyCon" else PtrRep
+typePrimRep (AppTy ty _)    = typePrimRep ty
+typePrimRep _              = PtrRep -- the "default"
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
index fcd837d..e7f1ec6 100644 (file)
@@ -18,7 +18,7 @@ Integer and get virtually unlimited sets.
 
 module BitSet (
        BitSet,         -- abstract type
 
 module BitSet (
        BitSet,         -- abstract type
-       mkBS, listBS, emptyBS, singletonBS,
+       mkBS, listBS, emptyBS, unitBS,
        unionBS, minusBS
 #if ! defined(COMPILING_GHC)
        , elementBS, intersectBS, isEmptyBS
        unionBS, minusBS
 #if ! defined(COMPILING_GHC)
        , elementBS, intersectBS, isEmptyBS
@@ -45,10 +45,10 @@ emptyBS :: BitSet
 emptyBS = MkBS (int2Word# 0#)
 
 mkBS :: [Int] -> BitSet
 emptyBS = MkBS (int2Word# 0#)
 
 mkBS :: [Int] -> BitSet
-mkBS xs = foldr (unionBS . singletonBS) emptyBS xs
+mkBS xs = foldr (unionBS . unitBS) emptyBS xs
 
 
-singletonBS :: Int -> BitSet
-singletonBS x = case x of
+unitBS :: Int -> BitSet
+unitBS x = case x of
     I# i# -> MkBS ((int2Word# 1#) `shiftL#` i#)
 
 unionBS :: BitSet -> BitSet -> BitSet
     I# i# -> MkBS ((int2Word# 1#) `shiftL#` i#)
 
 unionBS :: BitSet -> BitSet -> BitSet
@@ -60,8 +60,8 @@ minusBS (MkBS x#) (MkBS y#) = MkBS (x# `and#` (not# y#))
 #if ! defined(COMPILING_GHC)
 -- not used in GHC
 isEmptyBS :: BitSet -> Bool
 #if ! defined(COMPILING_GHC)
 -- not used in GHC
 isEmptyBS :: BitSet -> Bool
-isEmptyBS (MkBS s#) =
-    case word2Int# s# of
+isEmptyBS (MkBS s#)
+  = case word2Int# s# of
        0# -> True
        _  -> False
 
        0# -> True
        _  -> False
 
@@ -95,10 +95,10 @@ emptyBS :: BitSet
 emptyBS = MkBS 0
 
 mkBS :: [Int] -> BitSet
 emptyBS = MkBS 0
 
 mkBS :: [Int] -> BitSet
-mkBS xs = foldr (unionBS . singletonBS) emptyBS xs
+mkBS xs = foldr (unionBS . unitBS) emptyBS xs
 
 
-singletonBS :: Int -> BitSet
-singletonBS x = MkBS (1 `ashInt` x)
+unitBS :: Int -> BitSet
+unitBS x = MkBS (1 `ashInt` x)
 
 unionBS :: BitSet -> BitSet -> BitSet
 unionBS (MkBS x) (MkBS y) = MkBS (x `logiorInt` y)
 
 unionBS :: BitSet -> BitSet -> BitSet
 unionBS (MkBS x) (MkBS y) = MkBS (x `logiorInt` y)
@@ -106,8 +106,8 @@ unionBS (MkBS x) (MkBS y) = MkBS (x `logiorInt` y)
 #if ! defined(COMPILING_GHC)
 -- not used in GHC
 isEmptyBS :: BitSet -> Bool
 #if ! defined(COMPILING_GHC)
 -- not used in GHC
 isEmptyBS :: BitSet -> Bool
-isEmptyBS (MkBS s) =
-    case s of
+isEmptyBS (MkBS s)
+  = case s of
        0 -> True
        _ -> False
 
        0 -> True
        _ -> False
 
@@ -115,8 +115,8 @@ intersectBS :: BitSet -> BitSet -> BitSet
 intersectBS (MkBS x) (MkBS y) = MkBS (x `logandInt` y)
 
 elementBS :: Int -> BitSet -> Bool
 intersectBS (MkBS x) (MkBS y) = MkBS (x `logandInt` y)
 
 elementBS :: Int -> BitSet -> Bool
-elementBS x (MkBS s) =
-    case logbitpInt x s of
+elementBS x (MkBS s)
+  = case logbitpInt x s of
        0 -> False
        _ -> True
 #endif
        0 -> False
        _ -> True
 #endif
@@ -144,10 +144,10 @@ emptyBS :: BitSet
 emptyBS = MkBS 0
 
 mkBS :: [Int] -> BitSet
 emptyBS = MkBS 0
 
 mkBS :: [Int] -> BitSet
-mkBS xs = foldr (unionBS . singletonBS) emptyBS xs
+mkBS xs = foldr (unionBS . unitBS) emptyBS xs
 
 
-singletonBS :: Int -> BitSet
-singletonBS x = MkBS (1 `bitLsh` x)
+unitBS :: Int -> BitSet
+unitBS x = MkBS (1 `bitLsh` x)
 
 unionBS :: BitSet -> BitSet -> BitSet
 unionBS (MkBS x) (MkBS y) = MkBS (x `bitOr` y)
 
 unionBS :: BitSet -> BitSet -> BitSet
 unionBS (MkBS x) (MkBS y) = MkBS (x `bitOr` y)
@@ -155,8 +155,8 @@ unionBS (MkBS x) (MkBS y) = MkBS (x `bitOr` y)
 #if ! defined(COMPILING_GHC)
 -- not used in GHC
 isEmptyBS :: BitSet -> Bool
 #if ! defined(COMPILING_GHC)
 -- not used in GHC
 isEmptyBS :: BitSet -> Bool
-isEmptyBS (MkBS s) =
-    case s of
+isEmptyBS (MkBS s)
+  = case s of
        0 -> True
        _ -> False
 
        0 -> True
        _ -> False
 
@@ -164,8 +164,8 @@ intersectBS :: BitSet -> BitSet -> BitSet
 intersectBS (MkBS x) (MkBS y) = MkBS (x `bitAnd` y)
 
 elementBS :: Int -> BitSet -> Bool
 intersectBS (MkBS x) (MkBS y) = MkBS (x `bitAnd` y)
 
 elementBS :: Int -> BitSet -> Bool
-elementBS x (MkBS s) =
-    case (1 `bitLsh` x) `bitAnd` s of
+elementBS x (MkBS s)
+  = case (1 `bitLsh` x) `bitAnd` s of
        0 -> False
        _ -> True
 #endif
        0 -> False
        _ -> True
 #endif
index daa865a..68948f4 100644 (file)
@@ -65,7 +65,7 @@ cCh   :: Char -> CSeq
 cInt   :: Int -> CSeq
 
 #if defined(COMPILING_GHC)
 cInt   :: Int -> CSeq
 
 #if defined(COMPILING_GHC)
-cAppendFile :: _FILE -> CSeq -> PrimIO ()
+cAppendFile :: _FILE -> CSeq -> IO ()
 #endif
 \end{code}
 
 #endif
 \end{code}
 
@@ -128,7 +128,7 @@ cLength seq = length (cShow seq) -- *not* the best way to do this!
 
 #if defined(COMPILING_GHC)
 cAppendFile file_star seq
 
 #if defined(COMPILING_GHC)
 cAppendFile file_star seq
-  = flattenIO file_star seq
+  = flattenIO file_star seq `seqPrimIO` return ()
 #endif
 \end{code}
 
 #endif
 \end{code}
 
index 0308820..87da3e0 100644 (file)
@@ -36,7 +36,7 @@ near the end (only \tr{#ifdef COMPILING_GHC}).
 module FiniteMap (
        FiniteMap,              -- abstract type
 
 module FiniteMap (
        FiniteMap,              -- abstract type
 
-       emptyFM, singletonFM, listToFM,
+       emptyFM, unitFM, listToFM,
 
        addToFM,   addListToFM,
        IF_NOT_GHC(addToFM_C COMMA)
 
        addToFM,   addListToFM,
        IF_NOT_GHC(addToFM_C COMMA)
@@ -98,7 +98,7 @@ import Pretty
 \begin{code}
 --     BUILDING
 emptyFM                :: FiniteMap key elt
 \begin{code}
 --     BUILDING
 emptyFM                :: FiniteMap key elt
-singletonFM    :: key -> elt -> FiniteMap key elt
+unitFM :: key -> elt -> FiniteMap key elt
 listToFM       :: (Ord key OUTPUTABLE_key) => [(key,elt)] -> FiniteMap key elt
                        -- In the case of duplicates, the last is taken
 
 listToFM       :: (Ord key OUTPUTABLE_key) => [(key,elt)] -> FiniteMap key elt
                        -- In the case of duplicates, the last is taken
 
@@ -201,7 +201,7 @@ emptyFM
 
 -- #define EmptyFM (Branch _ _ IF_GHC(0#,0) _ _)
 
 
 -- #define EmptyFM (Branch _ _ IF_GHC(0#,0) _ _)
 
-singletonFM key elt = Branch key elt IF_GHC(1#,1) emptyFM emptyFM
+unitFM key elt = Branch key elt IF_GHC(1#,1) emptyFM emptyFM
 
 listToFM key_elt_pairs = addListToFM emptyFM key_elt_pairs
 \end{code}
 
 listToFM key_elt_pairs = addListToFM emptyFM key_elt_pairs
 \end{code}
@@ -215,7 +215,7 @@ listToFM key_elt_pairs = addListToFM emptyFM key_elt_pairs
 \begin{code}
 addToFM fm key elt = addToFM_C (\ old new -> new) fm key elt
 
 \begin{code}
 addToFM fm key elt = addToFM_C (\ old new -> new) fm key elt
 
-addToFM_C combiner EmptyFM key elt = singletonFM key elt
+addToFM_C combiner EmptyFM key elt = unitFM key elt
 addToFM_C combiner (Branch key elt size fm_l fm_r) new_key new_elt
 #ifdef __GLASGOW_HASKELL__
   = case _tagCmp new_key key of
 addToFM_C combiner (Branch key elt size fm_l fm_r) new_key new_elt
 #ifdef __GLASGOW_HASKELL__
   = case _tagCmp new_key key of
@@ -404,7 +404,7 @@ eltsFM fm   = foldFM (\ key elt rest -> elt : rest)       [] fm
 @mkBranch@ simply gets the size component right.  This is the ONLY
 (non-trivial) place the Branch object is built, so the ASSERTion
 recursively checks consistency.  (The trivial use of Branch is in
 @mkBranch@ simply gets the size component right.  This is the ONLY
 (non-trivial) place the Branch object is built, so the ASSERTion
 recursively checks consistency.  (The trivial use of Branch is in
-@singletonFM@.)
+@unitFM@.)
 
 \begin{code}
 sIZE_RATIO :: Int
 
 \begin{code}
 sIZE_RATIO :: Int
index 28b8ad2..81271a2 100644 (file)
@@ -9,7 +9,7 @@
 
 module MatchEnv (
        MatchEnv, nullMEnv, mkMEnv,
 
 module MatchEnv (
        MatchEnv, nullMEnv, mkMEnv,
-       lookupMEnv, insertMEnv,
+       isEmptyMEnv, lookupMEnv, insertMEnv,
        mEnvToList
 ) where
 
        mEnvToList
 ) where
 
@@ -36,11 +36,15 @@ match will be the most specific.
 nullMEnv :: MatchEnv a b
 nullMEnv = EmptyME
 
 nullMEnv :: MatchEnv a b
 nullMEnv = EmptyME
 
+isEmptyMEnv EmptyME = True
+isEmptyMEnv _      = False
+
 mkMEnv :: [(key, value)] -> MatchEnv key value
 mkMEnv :: [(key, value)] -> MatchEnv key value
+mkMEnv []    = EmptyME
 mkMEnv stuff = ME stuff
 
 mEnvToList :: MatchEnv key value -> [(key, value)]
 mkMEnv stuff = ME stuff
 
 mEnvToList :: MatchEnv key value -> [(key, value)]
-mEnvToList EmptyME = []
+mEnvToList EmptyME    = []
 mEnvToList (ME stuff) = stuff
 \end{code}
 
 mEnvToList (ME stuff) = stuff
 \end{code}
 
index 5c3e339..b8ee2ed 100644 (file)
@@ -8,7 +8,8 @@
 
 module PprStyle (
        PprStyle(..),
 
 module PprStyle (
        PprStyle(..),
-       codeStyle
+       codeStyle,
+       showUserishTypes
     ) where
 
 CHK_Ubiq() -- debugging consistency check
     ) where
 
 CHK_Ubiq() -- debugging consistency check
@@ -47,3 +48,10 @@ codeStyle (PprForAsm _ _) = True
 codeStyle _              = False
 \end{code}
 
 codeStyle _              = False
 \end{code}
 
+\begin{code}
+-- True means types like   (Eq a, Text b) => a -> b
+-- False means types like  _forall_ a b => Eq a -> Text b -> a -> b
+showUserishTypes PprForUser   = True   
+showUserishTypes PprInterface = True
+showUserishTypes other       = False
+\end{code}
index 5875f03..31bad81 100644 (file)
@@ -94,7 +94,7 @@ ppNest                :: Int -> Pretty -> Pretty
 ppShow         :: Int -> Pretty -> [Char]
 
 #if defined(COMPILING_GHC)
 ppShow         :: Int -> Pretty -> [Char]
 
 #if defined(COMPILING_GHC)
-ppAppendFile   :: _FILE -> Int -> Pretty -> PrimIO ()
+ppAppendFile   :: _FILE -> Int -> Pretty -> IO ()
 #endif
 \end{code}
 
 #endif
 \end{code}
 
index b5783ee..a416851 100644 (file)
@@ -7,14 +7,20 @@ import PreludePS(_PackedString)
 
 import Bag             ( Bag )
 import BinderInfo      ( BinderInfo )
 
 import Bag             ( Bag )
 import BinderInfo      ( BinderInfo )
+import CgBindery       ( CgIdInfo )
+import CharSeq         ( CSeq )
+import CLabel          ( CLabel )
 import Class           ( GenClass, GenClassOp, Class(..), ClassOp )
 import Class           ( GenClass, GenClassOp, Class(..), ClassOp )
+import ClosureInfo     ( ClosureInfo, LambdaFormInfo )
 import CmdLineOpts     ( SimplifierSwitch, SwitchResult )
 import CoreSyn         ( GenCoreArg, GenCoreBinder, GenCoreBinding, GenCoreExpr,
                          GenCoreCaseAlts, GenCoreCaseDefault
                        )
 import CoreUnfold      ( UnfoldingDetails, UnfoldingGuidance )
 import CostCentre      ( CostCentre )
 import CmdLineOpts     ( SimplifierSwitch, SwitchResult )
 import CoreSyn         ( GenCoreArg, GenCoreBinder, GenCoreBinding, GenCoreExpr,
                          GenCoreCaseAlts, GenCoreCaseDefault
                        )
 import CoreUnfold      ( UnfoldingDetails, UnfoldingGuidance )
 import CostCentre      ( CostCentre )
+import FieldLabel      ( FieldLabel )
 import FiniteMap       ( FiniteMap )
 import FiniteMap       ( FiniteMap )
+import HeapOffs                ( HeapOffset )
 import HsCore          ( UnfoldingCoreExpr )
 import HsPat           ( OutPat )
 import HsPragmas       ( ClassOpPragmas, ClassPragmas, DataPragmas, GenPragmas,
 import HsCore          ( UnfoldingCoreExpr )
 import HsPat           ( OutPat )
 import HsPragmas       ( ClassOpPragmas, ClassPragmas, DataPragmas, GenPragmas,
@@ -35,6 +41,7 @@ import Pretty         ( PrettyRep )
 import PrimOp          ( PrimOp )
 import PrimRep         ( PrimRep )
 import ProtoName       ( ProtoName )
 import PrimOp          ( PrimOp )
 import PrimRep         ( PrimRep )
 import ProtoName       ( ProtoName )
+import SMRep           ( SMRep )
 import SrcLoc          ( SrcLoc )
 import TcType          ( TcMaybe )
 import TyCon           ( TyCon, Arity(..) )
 import SrcLoc          ( SrcLoc )
 import TcType          ( TcMaybe )
 import TyCon           ( TyCon, Arity(..) )
@@ -75,13 +82,18 @@ class Outputable a where
 data ArityInfo
 data Bag a
 data BinderInfo
 data ArityInfo
 data Bag a
 data BinderInfo
+data CgIdInfo
+data CLabel
 data ClassOpPragmas a
 data ClassPragmas a
 data ClassOpPragmas a
 data ClassPragmas a
+data ClosureInfo
 data CostCentre
 data CostCentre
+data CSeq
 data DataPragmas a
 data DeforestInfo
 data Demand
 data ExportFlag
 data DataPragmas a
 data DeforestInfo
 data Demand
 data ExportFlag
+data FieldLabel
 data FiniteMap a b
 data FullName  -- NB: fails the optimisation criterion
 data GenClass a b
 data FiniteMap a b
 data FullName  -- NB: fails the optimisation criterion
 data GenClass a b
@@ -97,9 +109,11 @@ data GenPragmas a
 data GenTyVar a        -- NB: fails the optimisation criterion
 data GenType  a b
 data GenUsage a
 data GenTyVar a        -- NB: fails the optimisation criterion
 data GenType  a b
 data GenUsage a
+data HeapOffset
 data IdInfo
 data InstancePragmas a
 data Kind
 data IdInfo
 data InstancePragmas a
 data Kind
+data LambdaFormInfo
 data Literal
 data MaybeErr a b
 data MatchEnv a b
 data Literal
 data MaybeErr a b
 data MatchEnv a b
@@ -113,6 +127,7 @@ data PrimRep        -- NB: an enumeration
 data ProtoName
 data ShortName -- NB: fails the optimisation criterion
 data SimplifierSwitch
 data ProtoName
 data ShortName -- NB: fails the optimisation criterion
 data SimplifierSwitch
+data SMRep
 data SrcLoc
 data StrictnessInfo
 data StrictnessMark
 data SrcLoc
 data StrictnessInfo
 data StrictnessMark
index b9fc0dd..73b325c 100644 (file)
@@ -23,8 +23,8 @@ module UniqFM (
        UniqFM,   -- abstract type
 
        emptyUFM,
        UniqFM,   -- abstract type
 
        emptyUFM,
-       singletonUFM,
-       singletonDirectlyUFM,
+       unitUFM,
+       unitDirectlyUFM,
        listToUFM,
        listToUFM_Directly,
        addToUFM,
        listToUFM,
        listToUFM_Directly,
        addToUFM,
@@ -82,8 +82,8 @@ We use @FiniteMaps@, with a (@getItsUnique@-able) @Unique@ as ``key''.
 \begin{code}
 emptyUFM       :: UniqFM elt
 isNullUFM      :: UniqFM elt -> Bool
 \begin{code}
 emptyUFM       :: UniqFM elt
 isNullUFM      :: UniqFM elt -> Bool
-singletonUFM   :: NamedThing key => key -> elt -> UniqFM elt
-singletonDirectlyUFM -- got the Unique already
+unitUFM        :: NamedThing key => key -> elt -> UniqFM elt
+unitDirectlyUFM -- got the Unique already
                :: Unique -> elt -> UniqFM elt
 listToUFM      :: NamedThing key => [(key,elt)] -> UniqFM elt
 listToUFM_Directly
                :: Unique -> elt -> UniqFM elt
 listToUFM      :: NamedThing key => [(key,elt)] -> UniqFM elt
 listToUFM_Directly
@@ -149,7 +149,7 @@ type RegFinMap   elt = UniqFM elt
 -- I don't think HBC was too happy about this (WDP 94/10)
 
 {-# SPECIALIZE
 -- I don't think HBC was too happy about this (WDP 94/10)
 
 {-# SPECIALIZE
-    singletonUFM :: Id   -> elt -> IdFinMap elt,
+    unitUFM :: Id        -> elt -> IdFinMap elt,
                    TyVar -> elt -> TyVarFinMap elt,
                    Name  -> elt -> NameFinMap elt
     IF_NCG(COMMA    Reg   -> elt -> RegFinMap elt)
                    TyVar -> elt -> TyVarFinMap elt,
                    Name  -> elt -> NameFinMap elt
     IF_NCG(COMMA    Reg   -> elt -> RegFinMap elt)
@@ -285,8 +285,8 @@ First the ways of building a UniqFM.
 
 \begin{code}
 emptyUFM                    = EmptyUFM
 
 \begin{code}
 emptyUFM                    = EmptyUFM
-singletonUFM        key elt = mkLeafUFM (u2i (getItsUnique key)) elt
-singletonDirectlyUFM key elt = mkLeafUFM (u2i key) elt
+unitUFM             key elt = mkLeafUFM (u2i (getItsUnique key)) elt
+unitDirectlyUFM key elt = mkLeafUFM (u2i key) elt
 
 listToUFM key_elt_pairs
   = addListToUFM_C use_snd EmptyUFM key_elt_pairs
 
 listToUFM key_elt_pairs
   = addListToUFM_C use_snd EmptyUFM key_elt_pairs
index 6882e68..eb9511c 100644 (file)
@@ -13,7 +13,8 @@ Basically, the things need to be in class @NamedThing@.
 module UniqSet (
        UniqSet(..),    -- abstract type: NOT
 
 module UniqSet (
        UniqSet(..),    -- abstract type: NOT
 
-       mkUniqSet, uniqSetToList, emptyUniqSet, singletonUniqSet,
+       mkUniqSet, uniqSetToList, emptyUniqSet, unitUniqSet,
+       addOneToUniqSet,
        unionUniqSets, unionManyUniqSets, minusUniqSet,
        elementOfUniqSet, mapUniqSet, intersectUniqSets,
        isEmptyUniqSet
        unionUniqSets, unionManyUniqSets, minusUniqSet,
        elementOfUniqSet, mapUniqSet, intersectUniqSets,
        isEmptyUniqSet
@@ -55,8 +56,8 @@ type UniqSet a = UniqFM a
 emptyUniqSet :: UniqSet a
 emptyUniqSet = MkUniqSet emptyUFM
 
 emptyUniqSet :: UniqSet a
 emptyUniqSet = MkUniqSet emptyUFM
 
-singletonUniqSet :: NamedThing a => a -> UniqSet a
-singletonUniqSet x = MkUniqSet (singletonUFM x x)
+unitUniqSet :: NamedThing a => a -> UniqSet a
+unitUniqSet x = MkUniqSet (unitUFM x x)
 
 uniqSetToList :: UniqSet a -> [a]
 uniqSetToList (MkUniqSet set) = eltsUFM set
 
 uniqSetToList :: UniqSet a -> [a]
 uniqSetToList (MkUniqSet set) = eltsUFM set
@@ -64,6 +65,9 @@ uniqSetToList (MkUniqSet set) = eltsUFM set
 mkUniqSet :: NamedThing a => [a]  -> UniqSet a
 mkUniqSet xs = MkUniqSet (listToUFM [ (x, x) | x <- xs])
 
 mkUniqSet :: NamedThing a => [a]  -> UniqSet a
 mkUniqSet xs = MkUniqSet (listToUFM [ (x, x) | x <- xs])
 
+addOneToUniqSet :: NamedThing a => UniqSet a -> a -> UniqSet a
+addOneToUniqSet set x = set `unionUniqSets` unitUniqSet x
+
 unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
 unionUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (plusUFM set1 set2)
 
 unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
 unionUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (plusUFM set1 set2)
 
@@ -114,7 +118,7 @@ mapUniqSet f (MkUniqSet set)
 #if 0
 #if __GLASGOW_HASKELL__
 {-# SPECIALIZE
 #if 0
 #if __GLASGOW_HASKELL__
 {-# SPECIALIZE
-    singletonUniqSet :: GenId ty       -> GenIdSet ty,
+    unitUniqSet :: GenId ty       -> GenIdSet ty,
                        GenTyVar flexi -> GenTyVarSet flexi,
                        Name  -> NameSet
     IF_NCG(COMMA       Reg   -> RegSet)
                        GenTyVar flexi -> GenTyVarSet flexi,
                        Name  -> NameSet
     IF_NCG(COMMA       Reg   -> RegSet)
index 6b27379..822a7a9 100644 (file)
@@ -13,6 +13,7 @@ module Unpretty (
        uppSP, uppLbrack, uppRbrack, uppLparen, uppRparen,
        uppSemi, uppComma, uppEquals,
 
        uppSP, uppLbrack, uppRbrack, uppLparen, uppRparen,
        uppSemi, uppComma, uppEquals,
 
+       uppBracket, uppParens,
        uppCat, uppBeside, uppBesides, uppAbove, uppAboves,
        uppNest, uppSep, uppInterleave, uppIntersperse,
        uppShow,
        uppCat, uppBeside, uppBesides, uppAbove, uppAboves,
        uppNest, uppSep, uppInterleave, uppIntersperse,
        uppShow,
@@ -50,6 +51,9 @@ uppChar               :: Char -> Unpretty
 uppInt         :: Int -> Unpretty
 uppInteger     :: Integer -> Unpretty
 
 uppInt         :: Int -> Unpretty
 uppInteger     :: Integer -> Unpretty
 
+uppBracket     :: Unpretty -> Unpretty -- put brackets around it
+uppParens      :: Unpretty -> Unpretty -- put parens   around it
+
 uppBeside      :: Unpretty -> Unpretty -> Unpretty
 uppBesides     :: [Unpretty] -> Unpretty
 ppBesideSP     :: Unpretty -> Unpretty -> Unpretty
 uppBeside      :: Unpretty -> Unpretty -> Unpretty
 uppBesides     :: [Unpretty] -> Unpretty
 ppBesideSP     :: Unpretty -> Unpretty -> Unpretty
@@ -65,7 +69,7 @@ uppNest               :: Int -> Unpretty -> Unpretty
 
 uppShow                :: Int -> Unpretty -> [Char]
 
 
 uppShow                :: Int -> Unpretty -> [Char]
 
-uppAppendFile  :: _FILE -> Int -> Unpretty -> PrimIO ()
+uppAppendFile  :: _FILE -> Int -> Unpretty -> IO ()
 \end{code}
 
 %************************************************
 \end{code}
 
 %************************************************
@@ -96,6 +100,9 @@ uppSemi              = cCh ';'
 uppComma       = cCh ','
 uppEquals      = cCh '='
 
 uppComma       = cCh ','
 uppEquals      = cCh '='
 
+uppBracket p = uppBeside uppLbrack (uppBeside p uppRbrack)
+uppParens  p = uppBeside uppLparen (uppBeside p uppRparen)
+
 uppInterleave sep ps = uppSep (pi ps)
   where
    pi []       = []
 uppInterleave sep ps = uppSep (pi ps)
   where
    pi []       = []
index e59113e..68fdb49 100644 (file)
@@ -77,7 +77,7 @@ module Util (
 
        -- error handling
 #if defined(COMPILING_GHC)
 
        -- error handling
 #if defined(COMPILING_GHC)
-       , panic, panic#, pprPanic, pprPanic#, pprTrace
+       , panic, panic#, pprPanic, pprPanic#, pprError, pprTrace
 # ifdef DEBUG
        , assertPanic
 # endif
 # ifdef DEBUG
        , assertPanic
 # endif
@@ -807,6 +807,7 @@ panic x = error ("panic! (the `impossible' happened):\n\t"
              ++ "to glasgow-haskell-bugs@dcs.glasgow.ac.uk.\n\n" )
 
 pprPanic heading pretty_msg = panic (heading++(ppShow 80 pretty_msg))
              ++ "to glasgow-haskell-bugs@dcs.glasgow.ac.uk.\n\n" )
 
 pprPanic heading pretty_msg = panic (heading++(ppShow 80 pretty_msg))
+pprError heading pretty_msg = error (heading++(ppShow 80 pretty_msg))
 pprTrace heading pretty_msg = trace (heading++(ppShow 80 pretty_msg))
 
 -- #-versions because panic can't return an unboxed int, and that's
 pprTrace heading pretty_msg = trace (heading++(ppShow 80 pretty_msg))
 
 -- #-versions because panic can't return an unboxed int, and that's