fad365320359d973aa05cb7b15494385072731b0
[ghc-hetmet.git] / ghc / compiler / nativeGen / AsmCodeGen.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1993-1996
3 %
4
5 \begin{code}
6 #include "HsVersions.h"
7
8 module AsmCodeGen ( writeRealAsm, dumpRealAsm ) where
9
10 IMP_Ubiq(){-uitous-}
11 IMPORT_1_3(IO(Handle))
12
13 import MachMisc
14 #if __GLASGOW_HASKELL__ >= 202
15 import MachRegs         hiding (Addr)
16 #else
17 import MachRegs
18 #endif
19 import MachCode
20 import PprMach
21
22 import AbsCStixGen      ( genCodeAbstractC )
23 import AbsCSyn          ( AbstractC, MagicId )
24 import AsmRegAlloc      ( runRegAllocate )
25 import OrdList          ( OrdList )
26 import PrimOp           ( commutableOp, PrimOp(..) )
27 import PrimRep          ( PrimRep{-instance Eq-} )
28 import RegAllocInfo     ( mkMRegsState, MRegsState )
29 import Stix             ( StixTree(..), StixReg(..), CodeSegment )
30 import UniqSupply       ( returnUs, thenUs, mapUs, SYN_IE(UniqSM), UniqSupply )
31 import Outputable       ( printDoc )
32 import Pretty           ( Doc, vcat, Mode(..) )
33 \end{code}
34
35 The 96/03 native-code generator has machine-independent and
36 machine-dependent modules (those \tr{#include}'ing \tr{NCG.h}).
37
38 This module (@AsmCodeGen@) is the top-level machine-independent
39 module.  It uses @AbsCStixGen.genCodeAbstractC@ to produce @StixTree@s
40 (defined in module @Stix@), using support code from @StixInfo@ (info
41 tables), @StixPrim@ (primitive operations), @StixMacro@ (Abstract C
42 macros), and @StixInteger@ (GMP arbitrary-precision operations).
43
44 Before entering machine-dependent land, we do some machine-independent
45 @genericOpt@imisations (defined below) on the @StixTree@s.
46
47 We convert to the machine-specific @Instr@ datatype with
48 @stmt2Instrs@, assuming an ``infinite'' supply of registers.  We then
49 use a machine-independent register allocator (@runRegAllocate@) to
50 rejoin reality.  Obviously, @runRegAllocate@ has machine-specific
51 helper functions (see about @RegAllocInfo@ below).
52
53 The machine-dependent bits break down as follows:
54 \begin{description}
55 \item[@MachRegs@:]  Everything about the target platform's machine
56     registers (and immediate operands, and addresses, which tend to
57     intermingle/interact with registers).
58
59 \item[@MachMisc@:]  Includes the @Instr@ datatype (possibly should
60     have a module of its own), plus a miscellany of other things
61     (e.g., @targetDoubleSize@, @smStablePtrTable@, ...)
62
63 \item[@MachCode@:]  @stmt2Instrs@ is where @Stix@ stuff turns into
64     machine instructions.
65
66 \item[@PprMach@:] @pprInstr@ turns an @Instr@ into text (well, really
67     an @Doc@).
68
69 \item[@RegAllocInfo@:] In the register allocator, we manipulate
70     @MRegsState@s, which are @BitSet@s, one bit per machine register.
71     When we want to say something about a specific machine register
72     (e.g., ``it gets clobbered by this instruction''), we set/unset
73     its bit.  Obviously, we do this @BitSet@ thing for efficiency
74     reasons.
75
76     The @RegAllocInfo@ module collects together the machine-specific
77     info needed to do register allocation.
78 \end{description}
79
80 So, here we go:
81 \begin{code}
82 writeRealAsm :: Handle -> AbstractC -> UniqSupply -> IO ()
83 writeRealAsm handle absC us
84   = _scc_ "writeRealAsm" (printDoc LeftMode handle (runNCG absC us))
85
86 dumpRealAsm :: AbstractC -> UniqSupply -> String
87 dumpRealAsm absC us = show (runNCG absC us)
88
89 runNCG absC
90   = genCodeAbstractC absC       `thenUs` \ treelists ->
91     let
92         stix = map (map genericOpt) treelists
93     in
94     codeGen stix
95 \end{code}
96
97 @codeGen@ is the top-level code-generation function:
98 \begin{code}
99 codeGen :: [[StixTree]] -> UniqSM Doc
100
101 codeGen trees
102   = mapUs genMachCode trees     `thenUs` \ dynamic_codes ->
103     let
104         static_instrs = scheduleMachCode dynamic_codes
105     in
106     returnUs (vcat (map pprInstr static_instrs))
107 \end{code}
108
109 Top level code generator for a chunk of stix code:
110 \begin{code}
111 genMachCode :: [StixTree] -> UniqSM InstrList
112
113 genMachCode stmts
114   = mapUs stmt2Instrs stmts             `thenUs` \ blocks ->
115     returnUs (foldr (.) id blocks asmVoid)
116 \end{code}
117
118 The next bit does the code scheduling.  The scheduler must also deal
119 with register allocation of temporaries.  Much parallelism can be
120 exposed via the OrdList, but more might occur, so further analysis
121 might be needed.
122
123 \begin{code}
124 scheduleMachCode :: [InstrList] -> [Instr]
125
126 scheduleMachCode
127   = concat . map (runRegAllocate freeRegsState reservedRegs)
128   where
129     freeRegsState = mkMRegsState (extractMappedRegNos freeRegs)
130 \end{code}
131
132 %************************************************************************
133 %*                                                                      *
134 \subsection[NCOpt]{The Generic Optimiser}
135 %*                                                                      *
136 %************************************************************************
137
138 This is called between translating Abstract C to its Tree and actually
139 using the Native Code Generator to generate the annotations.  It's a
140 chance to do some strength reductions.
141
142 ** Remember these all have to be machine independent ***
143
144 Note that constant-folding should have already happened, but we might
145 have introduced some new opportunities for constant-folding wrt
146 address manipulations.
147
148 \begin{code}
149 genericOpt :: StixTree -> StixTree
150 \end{code}
151
152 For most nodes, just optimize the children.
153
154 \begin{code}
155 genericOpt (StInd pk addr) = StInd pk (genericOpt addr)
156
157 genericOpt (StAssign pk dst src)
158   = StAssign pk (genericOpt dst) (genericOpt src)
159
160 genericOpt (StJump addr) = StJump (genericOpt addr)
161
162 genericOpt (StCondJump addr test)
163   = StCondJump addr (genericOpt test)
164
165 genericOpt (StCall fn pk args)
166   = StCall fn pk (map genericOpt args)
167 \end{code}
168
169 Fold indices together when the types match:
170 \begin{code}
171 genericOpt (StIndex pk (StIndex pk' base off) off')
172   | pk == pk'
173   = StIndex pk (genericOpt base)
174                (genericOpt (StPrim IntAddOp [off, off']))
175
176 genericOpt (StIndex pk base off)
177   = StIndex pk (genericOpt base) (genericOpt off)
178 \end{code}
179
180 For PrimOps, we first optimize the children, and then we try our hand
181 at some constant-folding.
182
183 \begin{code}
184 genericOpt (StPrim op args) = primOpt op (map genericOpt args)
185 \end{code}
186
187 Replace register leaves with appropriate StixTrees for the given
188 target.
189
190 \begin{code}
191 genericOpt leaf@(StReg (StixMagicId id))
192   = case (stgReg id) of
193         Always tree -> genericOpt tree
194         Save _      -> leaf
195
196 genericOpt other = other
197 \end{code}
198
199 Now, try to constant-fold the PrimOps.  The arguments have already
200 been optimized and folded.
201
202 \begin{code}
203 primOpt
204     :: PrimOp           -- The operation from an StPrim
205     -> [StixTree]       -- The optimized arguments
206     -> StixTree
207
208 primOpt op arg@[StInt x]
209   = case op of
210         IntNegOp -> StInt (-x)
211         IntAbsOp -> StInt (abs x)
212         _ -> StPrim op arg
213
214 primOpt op args@[StInt x, StInt y]
215   = case op of
216         CharGtOp -> StInt (if x > y  then 1 else 0)
217         CharGeOp -> StInt (if x >= y then 1 else 0)
218         CharEqOp -> StInt (if x == y then 1 else 0)
219         CharNeOp -> StInt (if x /= y then 1 else 0)
220         CharLtOp -> StInt (if x < y  then 1 else 0)
221         CharLeOp -> StInt (if x <= y then 1 else 0)
222         IntAddOp -> StInt (x + y)
223         IntSubOp -> StInt (x - y)
224         IntMulOp -> StInt (x * y)
225         IntQuotOp -> StInt (x `quot` y)
226         IntRemOp -> StInt (x `rem` y)
227         IntGtOp -> StInt (if x > y  then 1 else 0)
228         IntGeOp -> StInt (if x >= y then 1 else 0)
229         IntEqOp -> StInt (if x == y then 1 else 0)
230         IntNeOp -> StInt (if x /= y then 1 else 0)
231         IntLtOp -> StInt (if x < y  then 1 else 0)
232         IntLeOp -> StInt (if x <= y then 1 else 0)
233         _ -> StPrim op args
234 \end{code}
235
236 When possible, shift the constants to the right-hand side, so that we
237 can match for strength reductions.  Note that the code generator will
238 also assume that constants have been shifted to the right when
239 possible.
240
241 \begin{code}
242 primOpt op [x@(StInt _), y] | commutableOp op = primOpt op [y, x]
243 \end{code}
244
245 We can often do something with constants of 0 and 1 ...
246
247 \begin{code}
248 primOpt op args@[x, y@(StInt 0)]
249   = case op of
250         IntAddOp -> x
251         IntSubOp -> x
252         IntMulOp -> y
253         AndOp    -> y
254         OrOp     -> x
255         SllOp    -> x
256         SraOp    -> x
257         SrlOp    -> x
258         ISllOp   -> x
259         ISraOp   -> x
260         ISrlOp   -> x
261         _        -> StPrim op args
262
263 primOpt op args@[x, y@(StInt 1)]
264   = case op of
265         IntMulOp  -> x
266         IntQuotOp -> x
267         IntRemOp  -> StInt 0
268         _         -> StPrim op args
269 \end{code}
270
271 Now look for multiplication/division by powers of 2 (integers).
272
273 \begin{code}
274 primOpt op args@[x, y@(StInt n)]
275   = case op of
276         IntMulOp -> case exactLog2 n of
277             Nothing -> StPrim op args
278             Just p  -> StPrim SllOp [x, StInt p]
279         IntQuotOp -> case exactLog2 n of
280             Nothing -> StPrim op args
281             Just p  -> StPrim SraOp [x, StInt p]
282         _ -> StPrim op args
283 \end{code}
284
285 Anything else is just too hard.
286
287 \begin{code}
288 primOpt op args = StPrim op args
289 \end{code}