ec316beb8a47f4656aced82ec06dcf9f70478361
[ghc-hetmet.git] / ghc / compiler / main / CodeOutput.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
3 %
4 \section{Code output phase}
5
6 \begin{code}
7 module CodeOutput( codeOutput ) where
8
9 #include "HsVersions.h"
10
11 #if ! OMIT_NATIVE_CODEGEN
12 import AsmCodeGen       ( nativeCodeGen )
13 #endif
14
15 import AbsCSyn          ( AbstractC, absCNop )
16 import PprAbsC          ( dumpRealC, writeRealC )
17 import UniqSupply       ( UniqSupply )
18 import Module           ( Module, moduleString )
19 import CmdLineOpts
20 import Maybes           ( maybeToBool )
21 import ErrUtils         ( doIfSet, dumpIfSet )
22 import Outputable
23 import IO               ( IOMode(..), hPutStr, hClose, openFile, stderr )
24 \end{code}
25
26
27 \begin{code}
28 codeOutput :: Module
29            -> SDoc              -- C stubs for foreign exported functions
30            -> SDoc              -- Header file prototype for foreign exported functions
31            -> AbstractC         -- Compiled abstract C
32            -> UniqSupply
33            -> IO ()
34 codeOutput mod_name c_code h_code flat_abstractC ncg_uniqs
35   = -- You can have C (c_output) or assembly-language (ncg_output),
36     -- but not both.  [Allowing for both gives a space leak on
37     -- flat_abstractC.  WDP 94/10]
38
39     dumpIfSet opt_D_dump_asm "Asm code" ncg_output_d    >>
40     doOutput opt_ProduceS ncg_output_w                  >>
41
42     dumpIfSet opt_D_dump_foreign "Foreign export header file" stub_h_output_d >>
43     outputHStub opt_ProduceExportHStubs stub_h_output_w >>
44
45     dumpIfSet opt_D_dump_foreign "Foreign export stubs" stub_c_output_d >>
46     outputCStub mod_name opt_ProduceExportCStubs stub_c_output_w        >>
47
48     dumpIfSet opt_D_dump_realC "Real C" c_output_d      >>
49     doOutput opt_ProduceC c_output_w
50
51   where
52     (flat_absC_c, flat_absC_ncg) =
53          case (maybeToBool opt_ProduceC || opt_D_dump_realC,
54                maybeToBool opt_ProduceS || opt_D_dump_asm) of
55              (True,  False) -> (flat_abstractC, absCNop)
56              (False, True)  -> (absCNop, flat_abstractC)
57              (False, False) -> (absCNop, absCNop)
58              (True,  True)  -> error "ERROR: Can't do both .hc and .s at the same time"
59
60     -- C stubs for "foreign export"ed functions.
61     stub_c_output_d = pprCode CStyle c_code
62     stub_c_output_w = showSDoc stub_c_output_d
63
64     -- Header file protos for "foreign export"ed functions.
65     stub_h_output_d = pprCode CStyle h_code
66     stub_h_output_w = showSDoc stub_h_output_d
67
68     c_output_d = dumpRealC flat_absC_c
69     c_output_w = (\ f -> writeRealC f flat_absC_c)
70
71         -- Native code generation done here!
72 #if OMIT_NATIVE_CODEGEN
73     ncg_output_d = error "*** GHC not built with a native-code generator ***"
74     ncg_output_w = ncg_output_d
75 #else
76     ncg_output_d = nativeCodeGen flat_absC_ncg ncg_uniqs
77     ncg_output_w = (\ f -> printForAsm f ncg_output_d)
78 #endif
79
80
81     -- don't use doOutput for dumping the f. export stubs
82     -- since it is more than likely that the stubs file will
83     -- turn out to be empty, in which case no file should be created.
84 outputCStub mod_name switch ""
85   = return ()
86 outputCStub mod_name switch doc_str
87   = case switch of
88           Nothing    -> return ()
89           Just fname -> writeFile fname ("#include \"Rts.h\"\n#include \"RtsAPI.h\"\n"++rest)
90             where
91              rest = "#include "++show (moduleString mod_name ++ "_stub.h") ++ '\n':doc_str
92               
93 outputHStub switch ""
94   = return ()
95 outputHStub switch doc_str
96   = case switch of
97           Nothing    -> return ()
98           Just fname -> writeFile fname ("#include \"Rts.h\"\n"++doc_str)
99
100 doOutput switch io_action
101   = case switch of
102           Nothing    -> return ()
103           Just fname ->
104             openFile fname WriteMode    >>= \ handle ->
105             io_action handle            >>
106             hClose handle
107 \end{code}
108