CodeOutput.lhs 4.99 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
%
% (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
%
\section{Code output phase}

\begin{code}
module CodeOutput( codeOutput ) where

#include "HsVersions.h"

11
#ifndef OMIT_NATIVE_CODEGEN
12 13
import AsmCodeGen	( nativeCodeGen )
#endif
14

15 16 17
#ifdef ILX
import IlxGen		( ilxGen )
#endif
18

19 20 21
import JavaGen		( javaGen )
import qualified PrintJava

22 23 24
import TyCon		( TyCon )
import Id		( Id )
import Class		( Class )
25
import CoreSyn		( CoreBind )
26
import StgSyn		( StgBinding )
27
import AbsCSyn		( AbstractC )
28 29
import PprAbsC		( dumpRealC, writeRealC )
import UniqSupply	( UniqSupply )
30
import Module		( Module )
31
import CmdLineOpts
32
import ErrUtils		( dumpIfSet )
33
import Outputable
34
import IO		( IOMode(..), hClose, openFile, Handle )
35 36 37
\end{code}


38 39 40 41 42 43
%************************************************************************
%*									*
\subsection{Steering}
%*									*
%************************************************************************

44 45
\begin{code}
codeOutput :: Module
46
	   -> [TyCon] -> [Class]	-- Local tycons and classes
47
	   -> [CoreBind]		-- Core bindings
48
	   -> [(StgBinding,[Id])]	-- The STG program with SRTs
49 50 51 52 53
	   -> SDoc 		-- C stubs for foreign exported functions
	   -> SDoc		-- Header file prototype for foreign exported functions
	   -> AbstractC		-- Compiled abstract C
	   -> UniqSupply
	   -> IO ()
54 55
codeOutput mod_name tycons classes core_binds stg_binds 
	   c_code h_code flat_abstractC ncg_uniqs
56 57 58 59
  = -- 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]

60 61 62 63 64 65 66 67 68 69 70
    do  {
	outputForeignStubs c_code h_code ;
	case opt_OutputLanguage of {
	  Nothing     -> return ()	-- No -olang=xxx flag; so no-op
	; Just "asm"  -> outputAsm flat_abstractC ncg_uniqs	
	; Just "C"    -> outputC flat_abstractC	
	; Just "java" -> outputJava mod_name tycons core_binds
	; Just foo    -> pprPanic "Don't understand output language" (quotes (text foo))
	} }


71
doOutput :: (Handle -> IO ()) -> IO ()
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
doOutput io_action
  = (do	handle <- openFile opt_OutputFile WriteMode
	io_action handle
	hClose handle)
    `catch` (\err -> pprPanic "Failed to open or write code output file" (text opt_OutputFile))
\end{code}


%************************************************************************
%*									*
\subsection{C}
%*									*
%************************************************************************

\begin{code}
outputC flat_absC
  = do 
       dumpIfSet opt_D_dump_realC "Real C" (dumpRealC flat_absC)
       doOutput (\ h -> writeRealC h flat_absC)
\end{code}


%************************************************************************
%*									*
\subsection{Assembler}
%*									*
%************************************************************************

\begin{code}
outputAsm flat_absC ncg_uniqs
102
#ifndef OMIT_NATIVE_CODEGEN
103

104 105 106
  = do dumpIfSet opt_D_dump_stix "Final stix code" stix_final
       dumpIfSet opt_D_dump_asm "Asm code" ncg_output_d
       doOutput ( \f -> printForAsm f ncg_output_d)
107 108 109 110 111
  where
    (stix_final, ncg_output_d) = nativeCodeGen flat_absC ncg_uniqs

#else /* OMIT_NATIVE_CODEGEN */

112 113
  = pprPanic "This compiler was built without a native code generator"
	     (text "Use -fvia-C instead")
114 115 116

#endif
\end{code}
117 118


119 120 121 122 123
%************************************************************************
%*									*
\subsection{Java}
%*									*
%************************************************************************
124

125 126 127 128
\begin{code}
outputJava mod tycons core_binds
  = doOutput (\ f -> printForUser f pp_java)
	-- User style printing for now to keep indentation
129
  where
130 131 132
    java_code = javaGen mod [{- Should be imports-}] tycons core_binds
    pp_java   = PrintJava.compilationUnit java_code
\end{code}
133

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149

%************************************************************************
%*									*
\subsection{Foreign import/export}
%*									*
%************************************************************************

\begin{code}
outputForeignStubs c_code h_code
  = do
	dumpIfSet opt_D_dump_foreign "Foreign export header file" stub_h_output_d
	outputForeignStubs_help True{-.h output-} opt_ProduceExportHStubs stub_h_output_w

	dumpIfSet opt_D_dump_foreign "Foreign export stubs" stub_c_output_d
	outputForeignStubs_help False{-not .h-}   opt_ProduceExportCStubs stub_c_output_w
  where
150 151 152 153 154 155 156 157 158
    -- C stubs for "foreign export"ed functions.
    stub_c_output_d = pprCode CStyle c_code
    stub_c_output_w = showSDoc stub_c_output_d

    -- Header file protos for "foreign export"ed functions.
    stub_h_output_d = pprCode CStyle h_code
    stub_h_output_w = showSDoc stub_h_output_d


159 160 161 162 163
-- Don't use doOutput for dumping the f. export stubs
-- since it is more than likely that the stubs file will
-- turn out to be empty, in which case no file should be created.
outputForeignStubs_help is_header switch ""      = return ()
outputForeignStubs_help is_header switch doc_str =
sof's avatar
sof committed
164 165 166 167 168 169 170
  case switch of
    Nothing    -> return ()
    Just fname -> writeFile fname (include_prefix ++ doc_str)
 where
  include_prefix
   | is_header   = "#include \"Rts.h\"\n"
   | otherwise   = "#include \"RtsAPI.h\"\n"
171 172
\end{code}