[project @ 2001-12-14 16:57:36 by sewardj]
[ghc-hetmet.git] / ghc / compiler / nativeGen / RegAllocInfo.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1996-1998
3 %
4 \section[RegAllocInfo]{Machine-specific info used for register allocation}
5
6 The (machine-independent) allocator itself is in @AsmRegAlloc@.
7
8 \begin{code}
9 #include "nativeGen/NCG.h"
10
11 module RegAllocInfo (
12         RegUsage(..),
13         noUsage,
14         regUsage,
15         InsnFuture(..),
16         insnFuture,
17
18         loadReg,
19         patchRegs,
20         spillReg,
21         findReservedRegs,
22
23         RegSet,
24         regSetFromList,
25         regSetToList,
26         isEmptyRegSet,
27         emptyRegSet,
28         eqRegSets,
29         filterRegSet,
30         unitRegSet,
31         elemRegSet,
32         unionRegSets,
33         minusRegSets,
34         intersectionRegSets
35     ) where
36
37 #include "HsVersions.h"
38
39 import List             ( sort )
40 import MachMisc
41 import MachRegs
42 import Stix             ( DestInfo(..) )
43 import CLabel           ( isAsmTemp, CLabel{-instance Ord-} )
44 import FiniteMap        ( addToFM, lookupFM, FiniteMap )
45 import Outputable
46 import Constants        ( rESERVED_C_STACK_BYTES )
47 import Unique           ( Unique, Uniquable(..) )
48 import FastTypes
49
50 \end{code}
51
52 %************************************************************************
53 %*                                                                      *
54 \subsection{Sets of registers}
55 %*                                                                      *
56 %************************************************************************
57
58 \begin{code}
59
60 -- Blargh.  Use ghc stuff soon!  Or: perhaps that's not such a good
61 -- idea.  Most of these sets are either empty or very small, and it
62 -- might be that the overheads of the FiniteMap based set implementation
63 -- is a net loss.  The same might be true of FeSets.
64
65 newtype RegSet = MkRegSet [Reg]
66
67 regSetFromList xs 
68    = MkRegSet (nukeDups (sort xs))
69      where nukeDups :: [Reg] -> [Reg]
70            nukeDups []  = []
71            nukeDups [x] = [x]
72            nukeDups (x:y:xys)
73               = if x == y then nukeDups (y:xys)
74                           else x : nukeDups (y:xys)
75
76 regSetToList   (MkRegSet xs)                 = xs
77 isEmptyRegSet  (MkRegSet xs)                 = null xs
78 emptyRegSet                                  = MkRegSet []
79 eqRegSets      (MkRegSet xs1) (MkRegSet xs2) = xs1 == xs2
80 unitRegSet x                                 = MkRegSet [x]
81 filterRegSet p (MkRegSet xs)                 = MkRegSet (filter p xs)
82
83 elemRegSet x (MkRegSet xs) 
84    = f xs
85      where
86         f []     = False
87         f (y:ys) | x == y    = True
88                  | x < y     = False
89                  | otherwise = f ys
90
91 unionRegSets (MkRegSet xs1) (MkRegSet xs2)
92    = MkRegSet (f xs1 xs2)
93      where
94         f [] bs = bs
95         f as [] = as
96         f (a:as) (b:bs)
97            | a < b      = a : f as (b:bs)
98            | a > b      = b : f (a:as) bs
99            | otherwise  = a : f as bs
100
101 minusRegSets (MkRegSet xs1) (MkRegSet xs2)
102    = MkRegSet (f xs1 xs2)
103      where
104         f [] bs = []
105         f as [] = as
106         f (a:as) (b:bs)
107            | a < b      = a : f as (b:bs)
108            | a > b      = f (a:as) bs
109            | otherwise  = f as bs
110
111 intersectionRegSets (MkRegSet xs1) (MkRegSet xs2)
112    = MkRegSet (f xs1 xs2)
113      where
114         f [] bs = []
115         f as [] = []
116         f (a:as) (b:bs)
117            | a < b      = f as (b:bs)
118            | a > b      = f (a:as) bs
119            | otherwise  = a : f as bs
120 \end{code}
121
122 %************************************************************************
123 %*                                                                      *
124 \subsection{@RegUsage@ type; @noUsage@, @endUsage@, @regUsage@ functions}
125 %*                                                                      *
126 %************************************************************************
127
128 @regUsage@ returns the sets of src and destination registers used by a
129 particular instruction.  Machine registers that are pre-allocated to
130 stgRegs are filtered out, because they are uninteresting from a
131 register allocation standpoint.  (We wouldn't want them to end up on
132 the free list!)  As far as we are concerned, the fixed registers
133 simply don't exist (for allocation purposes, anyway).
134
135 regUsage doesn't need to do any trickery for jumps and such.  Just
136 state precisely the regs read and written by that insn.  The
137 consequences of control flow transfers, as far as register allocation
138 goes, are taken care of by @insnFuture@.
139
140 \begin{code}
141 data RegUsage = RU RegSet RegSet
142
143 noUsage :: RegUsage
144 noUsage  = RU emptyRegSet emptyRegSet
145
146 regUsage :: Instr -> RegUsage
147
148 interesting (VirtualRegI _)  = True
149 interesting (VirtualRegF _)  = True
150 interesting (VirtualRegD _)  = True
151 interesting (RealReg i)      = isFastTrue (freeReg i)
152
153 #if alpha_TARGET_ARCH
154
155 regUsage instr = case instr of
156     LD B reg addr       -> usage (regAddr addr, [reg, t9])
157     LD Bu reg addr      -> usage (regAddr addr, [reg, t9])
158 --  LD W reg addr       -> usage (regAddr addr, [reg, t9]) : UNUSED
159 --  LD Wu reg addr      -> usage (regAddr addr, [reg, t9]) : UNUSED
160     LD sz reg addr      -> usage (regAddr addr, [reg])
161     LDA reg addr        -> usage (regAddr addr, [reg])
162     LDAH reg addr       -> usage (regAddr addr, [reg])
163     LDGP reg addr       -> usage (regAddr addr, [reg])
164     LDI sz reg imm      -> usage ([], [reg])
165     ST B reg addr       -> usage (reg : regAddr addr, [t9, t10])
166 --  ST W reg addr       -> usage (reg : regAddr addr, [t9, t10]) : UNUSED
167     ST sz reg addr      -> usage (reg : regAddr addr, [])
168     CLR reg             -> usage ([], [reg])
169     ABS sz ri reg       -> usage (regRI ri, [reg])
170     NEG sz ov ri reg    -> usage (regRI ri, [reg])
171     ADD sz ov r1 ar r2  -> usage (r1 : regRI ar, [r2])
172     SADD sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
173     SUB sz ov r1 ar r2  -> usage (r1 : regRI ar, [r2])
174     SSUB sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
175     MUL sz ov r1 ar r2  -> usage (r1 : regRI ar, [r2])
176     DIV sz un r1 ar r2  -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
177     REM sz un r1 ar r2  -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
178     NOT ri reg          -> usage (regRI ri, [reg])
179     AND r1 ar r2        -> usage (r1 : regRI ar, [r2])
180     ANDNOT r1 ar r2     -> usage (r1 : regRI ar, [r2])
181     OR r1 ar r2         -> usage (r1 : regRI ar, [r2])
182     ORNOT r1 ar r2      -> usage (r1 : regRI ar, [r2])
183     XOR r1 ar r2        -> usage (r1 : regRI ar, [r2])
184     XORNOT r1 ar r2     -> usage (r1 : regRI ar, [r2])
185     SLL r1 ar r2        -> usage (r1 : regRI ar, [r2])
186     SRL r1 ar r2        -> usage (r1 : regRI ar, [r2])
187     SRA r1 ar r2        -> usage (r1 : regRI ar, [r2])
188     ZAP r1 ar r2        -> usage (r1 : regRI ar, [r2])
189     ZAPNOT r1 ar r2     -> usage (r1 : regRI ar, [r2])
190     CMP co r1 ar r2     -> usage (r1 : regRI ar, [r2])
191     FCLR reg            -> usage ([], [reg])
192     FABS r1 r2          -> usage ([r1], [r2])
193     FNEG sz r1 r2       -> usage ([r1], [r2])
194     FADD sz r1 r2 r3    -> usage ([r1, r2], [r3])
195     FDIV sz r1 r2 r3    -> usage ([r1, r2], [r3])
196     FMUL sz r1 r2 r3    -> usage ([r1, r2], [r3])
197     FSUB sz r1 r2 r3    -> usage ([r1, r2], [r3])
198     CVTxy sz1 sz2 r1 r2 -> usage ([r1], [r2])
199     FCMP sz co r1 r2 r3 -> usage ([r1, r2], [r3])
200     FMOV r1 r2          -> usage ([r1], [r2])
201
202
203     -- We assume that all local jumps will be BI/BF/BR.  JMP must be out-of-line.
204     BI cond reg lbl     -> usage ([reg], [])
205     BF cond reg lbl     -> usage ([reg], [])
206     JMP reg addr hint   -> RU (mkRegSet (filter interesting (regAddr addr))) freeRegSet
207
208     BSR _ n             -> RU (argRegSet n) callClobberedRegSet
209     JSR reg addr n      -> RU (argRegSet n) callClobberedRegSet
210
211     _                   -> noUsage
212
213   where
214     usage (src, dst) = RU (mkRegSet (filter interesting src))
215                           (mkRegSet (filter interesting dst))
216
217     interesting (FixedReg _) = False
218     interesting _ = True
219
220     regAddr (AddrReg r1)      = [r1]
221     regAddr (AddrRegImm r1 _) = [r1]
222     regAddr (AddrImm _)       = []
223
224     regRI (RIReg r) = [r]
225     regRI  _    = []
226
227 #endif {- alpha_TARGET_ARCH -}
228 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
229 #if i386_TARGET_ARCH
230
231 regUsage instr = case instr of
232     MOV    sz src dst   -> usageRW src dst
233     MOVZxL sz src dst   -> usageRW src dst
234     MOVSxL sz src dst   -> usageRW src dst
235     LEA    sz src dst   -> usageRW src dst
236     ADD    sz src dst   -> usageRM src dst
237     SUB    sz src dst   -> usageRM src dst
238     IMUL   sz src dst   -> usageRM src dst
239     IMUL64    sd1 sd2   -> mkRU [sd1,sd2] [sd1,sd2]
240     MUL    sz src dst   -> usageRM src dst
241     IQUOT  sz src dst   -> usageRM src dst
242     IREM   sz src dst   -> usageRM src dst
243     QUOT   sz src dst   -> usageRM src dst
244     REM    sz src dst   -> usageRM src dst
245     AND    sz src dst   -> usageRM src dst
246     OR     sz src dst   -> usageRM src dst
247     XOR    sz src dst   -> usageRM src dst
248     NOT    sz op        -> usageM op
249     NEGI   sz op        -> usageM op
250     SHL    sz imm dst   -> usageM dst
251     SAR    sz imm dst   -> usageM dst
252     SHR    sz imm dst   -> usageM dst
253     BT     sz imm src   -> mkRU (use_R src) []
254
255     PUSH   sz op        -> mkRU (use_R op) []
256     POP    sz op        -> mkRU [] (def_W op)
257     TEST   sz src dst   -> mkRU (use_R src ++ use_R dst) []
258     CMP    sz src dst   -> mkRU (use_R src ++ use_R dst) []
259     SETCC  cond op      -> mkRU [] (def_W op)
260     JXX    cond lbl     -> mkRU [] []
261     JMP    dsts op      -> mkRU (use_R op) []
262     CALL   imm          -> mkRU [] callClobberedRegs
263     CLTD                -> mkRU [eax] [edx]
264     NOP                 -> mkRU [] []
265
266     GMOV   src dst      -> mkRU [src] [dst]
267     GLD    sz src dst   -> mkRU (use_EA src) [dst]
268     GST    sz src dst   -> mkRU (src : use_EA dst) []
269
270     GLDZ   dst          -> mkRU [] [dst]
271     GLD1   dst          -> mkRU [] [dst]
272
273     GFTOI  src dst      -> mkRU [src] [dst]
274     GDTOI  src dst      -> mkRU [src] [dst]
275
276     GITOF  src dst      -> mkRU [src] [dst]
277     GITOD  src dst      -> mkRU [src] [dst]
278
279     GADD   sz s1 s2 dst -> mkRU [s1,s2] [dst]
280     GSUB   sz s1 s2 dst -> mkRU [s1,s2] [dst]
281     GMUL   sz s1 s2 dst -> mkRU [s1,s2] [dst]
282     GDIV   sz s1 s2 dst -> mkRU [s1,s2] [dst]
283
284     GCMP   sz src1 src2 -> mkRU [src1,src2] []
285     GABS   sz src dst   -> mkRU [src] [dst]
286     GNEG   sz src dst   -> mkRU [src] [dst]
287     GSQRT  sz src dst   -> mkRU [src] [dst]
288     GSIN   sz src dst   -> mkRU [src] [dst]
289     GCOS   sz src dst   -> mkRU [src] [dst]
290     GTAN   sz src dst   -> mkRU [src] [dst]
291
292     COMMENT _           -> noUsage
293     SEGMENT _           -> noUsage
294     LABEL   _           -> noUsage
295     ASCII   _ _         -> noUsage
296     DATA    _ _         -> noUsage
297     DELTA   _           -> noUsage
298     _                   -> pprPanic "regUsage(x86)" empty
299
300  where
301     -- 2 operand form; first operand Read; second Written
302     usageRW :: Operand -> Operand -> RegUsage
303     usageRW op (OpReg reg) = mkRU (use_R op) [reg]
304     usageRW op (OpAddr ea) = mkRU (use_R op ++ use_EA ea) []
305
306     -- 2 operand form; first operand Read; second Modified
307     usageRM :: Operand -> Operand -> RegUsage
308     usageRM op (OpReg reg) = mkRU (use_R op ++ [reg]) [reg]
309     usageRM op (OpAddr ea) = mkRU (use_R op ++ use_EA ea) []
310
311     -- 1 operand form; operand Modified
312     usageM :: Operand -> RegUsage
313     usageM (OpReg reg)    = mkRU [reg] [reg]
314     usageM (OpAddr ea)    = mkRU (use_EA ea) []
315
316     -- Registers defd when an operand is written.
317     def_W (OpReg reg)  = [reg]
318     def_W (OpAddr ea)  = []
319
320     -- Registers used when an operand is read.
321     use_R (OpReg reg)  = [reg]
322     use_R (OpImm imm)  = []
323     use_R (OpAddr ea)  = use_EA ea
324
325     -- Registers used to compute an effective address.
326     use_EA (ImmAddr _ _)                           = []
327     use_EA (AddrBaseIndex Nothing  Nothing      _) = []
328     use_EA (AddrBaseIndex (Just b) Nothing      _) = [b]
329     use_EA (AddrBaseIndex Nothing  (Just (i,_)) _) = [i]
330     use_EA (AddrBaseIndex (Just b) (Just (i,_)) _) = [b,i]
331
332     mkRU src dst = RU (regSetFromList (filter interesting src))
333                       (regSetFromList (filter interesting dst))
334
335 #endif {- i386_TARGET_ARCH -}
336 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
337 #if sparc_TARGET_ARCH
338
339 regUsage instr = case instr of
340     LD    sz addr reg   -> usage (regAddr addr, [reg])
341     ST    sz reg addr   -> usage (reg : regAddr addr, [])
342     ADD   x cc r1 ar r2 -> usage (r1 : regRI ar, [r2])
343     SUB   x cc r1 ar r2 -> usage (r1 : regRI ar, [r2])
344     UMUL    cc r1 ar r2 -> usage (r1 : regRI ar, [r2])
345     SMUL    cc r1 ar r2 -> usage (r1 : regRI ar, [r2])
346     RDY   rd            -> usage ([], [rd])
347     AND   b r1 ar r2    -> usage (r1 : regRI ar, [r2])
348     ANDN  b r1 ar r2    -> usage (r1 : regRI ar, [r2])
349     OR    b r1 ar r2    -> usage (r1 : regRI ar, [r2])
350     ORN   b r1 ar r2    -> usage (r1 : regRI ar, [r2])
351     XOR   b r1 ar r2    -> usage (r1 : regRI ar, [r2])
352     XNOR  b r1 ar r2    -> usage (r1 : regRI ar, [r2])
353     SLL   r1 ar r2      -> usage (r1 : regRI ar, [r2])
354     SRL   r1 ar r2      -> usage (r1 : regRI ar, [r2])
355     SRA   r1 ar r2      -> usage (r1 : regRI ar, [r2])
356     SETHI imm reg       -> usage ([], [reg])
357     FABS  s r1 r2       -> usage ([r1], [r2])
358     FADD  s r1 r2 r3    -> usage ([r1, r2], [r3])
359     FCMP  e s r1 r2     -> usage ([r1, r2], [])
360     FDIV  s r1 r2 r3    -> usage ([r1, r2], [r3])
361     FMOV  s r1 r2       -> usage ([r1], [r2])
362     FMUL  s r1 r2 r3    -> usage ([r1, r2], [r3])
363     FNEG  s r1 r2       -> usage ([r1], [r2])
364     FSQRT s r1 r2       -> usage ([r1], [r2])
365     FSUB  s r1 r2 r3    -> usage ([r1, r2], [r3])
366     FxTOy s1 s2 r1 r2   -> usage ([r1], [r2])
367
368     -- We assume that all local jumps will be BI/BF.  JMP must be out-of-line.
369     JMP   dst addr      -> usage (regAddr addr, [])
370
371     CALL  _ n True      -> noUsage
372     CALL  _ n False     -> usage (argRegs n, callClobberedRegs)
373
374     _                   -> noUsage
375   where
376     usage (src, dst) = RU (regSetFromList (filter interesting src))
377                           (regSetFromList (filter interesting dst))
378
379     regAddr (AddrRegReg r1 r2) = [r1, r2]
380     regAddr (AddrRegImm r1 _)  = [r1]
381
382     regRI (RIReg r) = [r]
383     regRI  _    = []
384
385 #endif {- sparc_TARGET_ARCH -}
386 \end{code}
387
388
389 %************************************************************************
390 %*                                                                      *
391 \subsection{Free, reserved, call-clobbered, and argument registers}
392 %*                                                                      *
393 %************************************************************************
394
395 @freeRegs@ is the list of registers we can use in register allocation.
396 @freeReg@ (below) says if a particular register is free.
397
398 With a per-instruction clobber list, we might be able to get some of
399 these back, but it's probably not worth the hassle.
400
401 @callClobberedRegs@ ... the obvious.
402
403 @argRegs@: assuming a call with N arguments, what registers will be
404 used to hold arguments?  (NB: it doesn't know whether the arguments
405 are integer or floating-point...)
406
407 findReservedRegs tells us which regs can be used as spill temporaries.
408 The list of instructions for which we are attempting allocation is
409 supplied.  This is so that we can (at least for x86) examine it to
410 discover which registers are being used in a fixed way -- for example,
411 %eax and %edx are used by integer division, so they can't be used as
412 spill temporaries.  However, most instruction lists don't do integer
413 division, so we don't want to rule them out altogether.
414
415 findReservedRegs returns not a list of spill temporaries, but a list
416 of list of them.  This is so that the allocator can attempt allocating
417 with at first no spill temps, then if that fails, increasing numbers.
418 For x86 it is important that we minimise the number of regs reserved
419 as spill temporaries, since there are so few.  For Alpha and Sparc
420 this isn't a concern; we just ignore the supplied code list and return
421 a singleton list which we know will satisfy all spill demands.
422
423 \begin{code}
424 findReservedRegs :: [Instr] -> [[Reg]]
425 findReservedRegs instrs
426 #if alpha_TARGET_ARCH
427   = --[[NCG_Reserved_I1, NCG_Reserved_I2,
428     --  NCG_Reserved_F1, NCG_Reserved_F2]]
429     error "findReservedRegs: alpha"
430 #endif
431 #if sparc_TARGET_ARCH
432   = [[NCG_SpillTmp_I1, NCG_SpillTmp_I2, 
433       NCG_SpillTmp_D1, NCG_SpillTmp_D2,
434       NCG_SpillTmp_F1, NCG_SpillTmp_F2]]
435 #endif
436 #if i386_TARGET_ARCH
437   -- We can use %fake4 and %fake5 safely for float temps.
438   -- Int regs are more troublesome.  Only %ecx and %edx are
439   -- definitely.  At a pinch, we also could bag %eax if there 
440   -- are no ccalls, but so far we've never encountered
441   -- a situation where three integer temporaries are necessary.
442   -- 
443   -- Because registers are in short supply on x86, we give the
444   -- allocator a whole bunch of possibilities, starting with zero
445   -- temporaries and working up to all that are available.  This
446   -- is inefficient, but spills are pretty rare, so we don't care
447   -- if the register allocator has to try half a dozen or so possibilities
448   -- before getting to one that works.
449   = let f1 = fake5
450         f2 = fake4
451         intregs_avail
452            = [ecx, edx]
453         possibilities
454            = case intregs_avail of
455                 [i1] -> [ [], [i1], [f1], [i1,f1], [f1,f2], 
456                           [i1,f1,f2] ]
457
458                 [i1,i2] -> [ [], [i1], [f1], [i1,i2], [i1,f1], [f1,f2],
459                              [i1,i2,f1], [i1,f1,f2], [i1,i2,f1,f2] ]
460     in
461         possibilities
462 #endif
463 \end{code}
464
465 %************************************************************************
466 %*                                                                      *
467 \subsection{@InsnFuture@ type; @insnFuture@ function}
468 %*                                                                      *
469 %************************************************************************
470
471 @insnFuture@ indicates the places we could get to following the
472 current instruction.  This is used by the register allocator to
473 compute the flow edges between instructions.
474
475 \begin{code}
476 data InsnFuture 
477    = NoFuture              -- makes a non-local jump; for the purposes of
478                            -- register allocation, it exits our domain
479    | Next                  -- falls through to next insn
480    | Branch CLabel         -- unconditional branch to the label
481    | NextOrBranch CLabel   -- conditional branch to the label
482    | MultiFuture [CLabel]  -- multiple specific futures
483
484 --instance Outputable InsnFuture where
485 --   ppr NoFuture            = text "NoFuture"
486 --   ppr Next                = text "Next"
487 --   ppr (Branch clbl)       = text "(Branch " <> ppr clbl <> char ')'
488 --   ppr (NextOrBranch clbl) = text "(NextOrBranch " <> ppr clbl <> char ')'
489
490
491 insnFuture insn
492  = case insn of
493
494 #if alpha_TARGET_ARCH
495
496     -- We assume that all local jumps will be BI/BF.  JMP must be out-of-line.
497
498     BR (ImmCLbl lbl)     -> RL (lookup lbl) future
499     BI _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
500     BF _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
501     JMP _ _ _            -> RL emptyRegSet future
502     BSR _ _              -> RL live future
503     JSR _ _ _            -> RL live future
504     LABEL lbl            -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
505     _                    -> info
506
507 #endif {- alpha_TARGET_ARCH -}
508 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
509 #if i386_TARGET_ARCH
510
511     -- conditional jump
512     JXX _ clbl | isAsmTemp clbl -> NextOrBranch clbl
513     JXX _ _ -> panic "insnFuture: conditional jump to non-local label"
514
515     -- If the insn says what its dests are, use em!
516     JMP (DestInfo dsts) _ -> MultiFuture dsts
517
518     -- unconditional jump to local label
519     JMP NoDestInfo (OpImm (ImmCLbl clbl)) | isAsmTemp clbl -> Branch clbl
520     
521     -- unconditional jump to non-local label
522     JMP NoDestInfo lbl  -> NoFuture
523
524     -- be extra-paranoid
525     JMP _ _ -> panic "insnFuture(x86): JMP wierdness"
526
527     boring      -> Next
528
529 #endif {- i386_TARGET_ARCH -}
530 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
531 #if sparc_TARGET_ARCH
532
533     -- We assume that all local jumps will be BI/BF.
534     BI ALWAYS _ (ImmCLbl clbl) -> Branch clbl
535     BI other  _ (ImmCLbl clbl) -> NextOrBranch clbl
536     BI other  _ _ -> panic "nativeGen(sparc):insnFuture(BI)"
537
538     BF ALWAYS _ (ImmCLbl clbl) -> Branch clbl
539     BF other  _ (ImmCLbl clbl) -> NextOrBranch clbl
540     BF other  _ _ -> panic "nativeGen(sparc):insnFuture(BF)"
541
542     -- CALL(terminal) must be out-of-line.  JMP is not out-of-line
543     -- iff it specifies its destinations.
544     JMP NoDestInfo _      -> NoFuture  -- n.b. NoFuture == MultiFuture []
545     JMP (DestInfo dsts) _ -> MultiFuture dsts
546
547     CALL _ _ True         -> NoFuture
548
549     boring -> Next
550
551 #endif {- sparc_TARGET_ARCH -}
552 \end{code}
553
554 %************************************************************************
555 %*                                                                      *
556 \subsection{@patchRegs@ function}
557 %*                                                                      *
558 %************************************************************************
559
560 @patchRegs@ takes an instruction (possibly with
561 MemoryReg/UnmappedReg registers) and changes all register references
562 according to the supplied environment.
563
564 \begin{code}
565 patchRegs :: Instr -> (Reg -> Reg) -> Instr
566
567 #if alpha_TARGET_ARCH
568
569 patchRegs instr env = case instr of
570     LD sz reg addr -> LD sz (env reg) (fixAddr addr)
571     LDA reg addr -> LDA (env reg) (fixAddr addr)
572     LDAH reg addr -> LDAH (env reg) (fixAddr addr)
573     LDGP reg addr -> LDGP (env reg) (fixAddr addr)
574     LDI sz reg imm -> LDI sz (env reg) imm
575     ST sz reg addr -> ST sz (env reg) (fixAddr addr)
576     CLR reg -> CLR (env reg)
577     ABS sz ar reg -> ABS sz (fixRI ar) (env reg)
578     NEG sz ov ar reg -> NEG sz ov (fixRI ar) (env reg)
579     ADD sz ov r1 ar r2 -> ADD sz ov (env r1) (fixRI ar) (env r2)
580     SADD sz sc r1 ar r2 -> SADD sz sc (env r1) (fixRI ar) (env r2)
581     SUB sz ov r1 ar r2 -> SUB sz ov (env r1) (fixRI ar) (env r2)
582     SSUB sz sc r1 ar r2 -> SSUB sz sc (env r1) (fixRI ar) (env r2)
583     MUL sz ov r1 ar r2 -> MUL sz ov (env r1) (fixRI ar) (env r2)
584     DIV sz un r1 ar r2 -> DIV sz un (env r1) (fixRI ar) (env r2)
585     REM sz un r1 ar r2 -> REM sz un (env r1) (fixRI ar) (env r2)
586     NOT ar reg -> NOT (fixRI ar) (env reg)
587     AND r1 ar r2 -> AND (env r1) (fixRI ar) (env r2)
588     ANDNOT r1 ar r2 -> ANDNOT (env r1) (fixRI ar) (env r2)
589     OR r1 ar r2 -> OR (env r1) (fixRI ar) (env r2)
590     ORNOT r1 ar r2 -> ORNOT (env r1) (fixRI ar) (env r2)
591     XOR r1 ar r2 -> XOR (env r1) (fixRI ar) (env r2)
592     XORNOT r1 ar r2 -> XORNOT (env r1) (fixRI ar) (env r2)
593     SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
594     SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
595     SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
596     ZAP r1 ar r2 -> ZAP (env r1) (fixRI ar) (env r2)
597     ZAPNOT r1 ar r2 -> ZAPNOT (env r1) (fixRI ar) (env r2)
598     CMP co r1 ar r2 -> CMP co (env r1) (fixRI ar) (env r2)
599     FCLR reg -> FCLR (env reg)
600     FABS r1 r2 -> FABS (env r1) (env r2)
601     FNEG s r1 r2 -> FNEG s (env r1) (env r2)
602     FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
603     FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
604     FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
605     FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
606     CVTxy s1 s2 r1 r2 -> CVTxy s1 s2 (env r1) (env r2)
607     FCMP s co r1 r2 r3 -> FCMP s co (env r1) (env r2) (env r3)
608     FMOV r1 r2 -> FMOV (env r1) (env r2)
609     BI cond reg lbl -> BI cond (env reg) lbl
610     BF cond reg lbl -> BF cond (env reg) lbl
611     JMP reg addr hint -> JMP (env reg) (fixAddr addr) hint
612     JSR reg addr i -> JSR (env reg) (fixAddr addr) i
613     _ -> instr
614   where
615     fixAddr (AddrReg r1)       = AddrReg (env r1)
616     fixAddr (AddrRegImm r1 i)  = AddrRegImm (env r1) i
617     fixAddr other              = other
618
619     fixRI (RIReg r) = RIReg (env r)
620     fixRI other = other
621
622 #endif {- alpha_TARGET_ARCH -}
623 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
624 #if i386_TARGET_ARCH
625
626 patchRegs instr env = case instr of
627     MOV  sz src dst     -> patch2 (MOV  sz) src dst
628     MOVZxL sz src dst   -> patch2 (MOVZxL sz) src dst
629     MOVSxL sz src dst   -> patch2 (MOVSxL sz) src dst
630     LEA  sz src dst     -> patch2 (LEA  sz) src dst
631     ADD  sz src dst     -> patch2 (ADD  sz) src dst
632     SUB  sz src dst     -> patch2 (SUB  sz) src dst
633     IMUL sz src dst     -> patch2 (IMUL sz) src dst
634     IMUL64  sd1 sd2     -> IMUL64 (env sd1) (env sd2)
635     MUL sz src dst      -> patch2 (MUL sz) src dst
636     IQUOT sz src dst    -> patch2 (IQUOT sz) src dst
637     IREM sz src dst     -> patch2 (IREM sz) src dst
638     QUOT sz src dst     -> patch2 (QUOT sz) src dst
639     REM sz src dst      -> patch2 (REM sz) src dst
640     AND  sz src dst     -> patch2 (AND  sz) src dst
641     OR   sz src dst     -> patch2 (OR   sz) src dst
642     XOR  sz src dst     -> patch2 (XOR  sz) src dst
643     NOT  sz op          -> patch1 (NOT  sz) op
644     NEGI sz op          -> patch1 (NEGI sz) op
645     SHL  sz imm dst     -> patch1 (SHL sz imm) dst
646     SAR  sz imm dst     -> patch1 (SAR sz imm) dst
647     SHR  sz imm dst     -> patch1 (SHR sz imm) dst
648     BT   sz imm src     -> patch1 (BT  sz imm) src
649     TEST sz src dst     -> patch2 (TEST sz) src dst
650     CMP  sz src dst     -> patch2 (CMP  sz) src dst
651     PUSH sz op          -> patch1 (PUSH sz) op
652     POP  sz op          -> patch1 (POP  sz) op
653     SETCC cond op       -> patch1 (SETCC cond) op
654     JMP dsts op         -> patch1 (JMP dsts) op
655
656     GMOV src dst        -> GMOV (env src) (env dst)
657     GLD sz src dst      -> GLD sz (lookupAddr src) (env dst)
658     GST sz src dst      -> GST sz (env src) (lookupAddr dst)
659
660     GLDZ dst            -> GLDZ (env dst)
661     GLD1 dst            -> GLD1 (env dst)
662
663     GFTOI src dst       -> GFTOI (env src) (env dst)
664     GDTOI src dst       -> GDTOI (env src) (env dst)
665
666     GITOF src dst       -> GITOF (env src) (env dst)
667     GITOD src dst       -> GITOD (env src) (env dst)
668
669     GADD sz s1 s2 dst   -> GADD sz (env s1) (env s2) (env dst)
670     GSUB sz s1 s2 dst   -> GSUB sz (env s1) (env s2) (env dst)
671     GMUL sz s1 s2 dst   -> GMUL sz (env s1) (env s2) (env dst)
672     GDIV sz s1 s2 dst   -> GDIV sz (env s1) (env s2) (env dst)
673
674     GCMP sz src1 src2   -> GCMP sz (env src1) (env src2)
675     GABS sz src dst     -> GABS sz (env src) (env dst)
676     GNEG sz src dst     -> GNEG sz (env src) (env dst)
677     GSQRT sz src dst    -> GSQRT sz (env src) (env dst)
678     GSIN sz src dst     -> GSIN sz (env src) (env dst)
679     GCOS sz src dst     -> GCOS sz (env src) (env dst)
680     GTAN sz src dst     -> GTAN sz (env src) (env dst)
681
682     COMMENT _           -> instr
683     SEGMENT _           -> instr
684     LABEL _             -> instr
685     ASCII _ _           -> instr
686     DATA _ _            -> instr
687     DELTA _             -> instr
688     JXX _ _             -> instr
689     CALL _              -> instr
690     CLTD                -> instr
691     _                   -> pprPanic "patchRegs(x86)" empty
692
693   where
694     patch1 insn op      = insn (patchOp op)
695     patch2 insn src dst = insn (patchOp src) (patchOp dst)
696
697     patchOp (OpReg  reg) = OpReg (env reg)
698     patchOp (OpImm  imm) = OpImm imm
699     patchOp (OpAddr ea)  = OpAddr (lookupAddr ea)
700
701     lookupAddr (ImmAddr imm off) = ImmAddr imm off
702     lookupAddr (AddrBaseIndex base index disp)
703       = AddrBaseIndex (lookupBase base) (lookupIndex index) disp
704       where
705         lookupBase Nothing       = Nothing
706         lookupBase (Just r)      = Just (env r)
707                                  
708         lookupIndex Nothing      = Nothing
709         lookupIndex (Just (r,i)) = Just (env r, i)
710
711 #endif {- i386_TARGET_ARCH -}
712 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
713 #if sparc_TARGET_ARCH
714
715 patchRegs instr env = case instr of
716     LD    sz addr reg   -> LD sz (fixAddr addr) (env reg)
717     ST    sz reg addr   -> ST sz (env reg) (fixAddr addr)
718     ADD   x cc r1 ar r2 -> ADD x cc (env r1) (fixRI ar) (env r2)
719     SUB   x cc r1 ar r2 -> SUB x cc (env r1) (fixRI ar) (env r2)
720     UMUL    cc r1 ar r2 -> UMUL cc (env r1) (fixRI ar) (env r2)
721     SMUL    cc r1 ar r2 -> SMUL cc (env r1) (fixRI ar) (env r2)
722     RDY   rd            -> RDY (env rd)
723     AND   b r1 ar r2    -> AND b (env r1) (fixRI ar) (env r2)
724     ANDN  b r1 ar r2    -> ANDN b (env r1) (fixRI ar) (env r2)
725     OR    b r1 ar r2    -> OR b (env r1) (fixRI ar) (env r2)
726     ORN   b r1 ar r2    -> ORN b (env r1) (fixRI ar) (env r2)
727     XOR   b r1 ar r2    -> XOR b (env r1) (fixRI ar) (env r2)
728     XNOR  b r1 ar r2    -> XNOR b (env r1) (fixRI ar) (env r2)
729     SLL   r1 ar r2      -> SLL (env r1) (fixRI ar) (env r2)
730     SRL   r1 ar r2      -> SRL (env r1) (fixRI ar) (env r2)
731     SRA   r1 ar r2      -> SRA (env r1) (fixRI ar) (env r2)
732     SETHI imm reg       -> SETHI imm (env reg)
733     FABS  s r1 r2       -> FABS s (env r1) (env r2)
734     FADD  s r1 r2 r3    -> FADD s (env r1) (env r2) (env r3)
735     FCMP  e s r1 r2     -> FCMP e s (env r1) (env r2)
736     FDIV  s r1 r2 r3    -> FDIV s (env r1) (env r2) (env r3)
737     FMOV  s r1 r2       -> FMOV s (env r1) (env r2)
738     FMUL  s r1 r2 r3    -> FMUL s (env r1) (env r2) (env r3)
739     FNEG  s r1 r2       -> FNEG s (env r1) (env r2)
740     FSQRT s r1 r2       -> FSQRT s (env r1) (env r2)
741     FSUB  s r1 r2 r3    -> FSUB s (env r1) (env r2) (env r3)
742     FxTOy s1 s2 r1 r2   -> FxTOy s1 s2 (env r1) (env r2)
743     JMP   dsts addr     -> JMP dsts (fixAddr addr)
744     _ -> instr
745   where
746     fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
747     fixAddr (AddrRegImm r1 i)  = AddrRegImm (env r1) i
748
749     fixRI (RIReg r) = RIReg (env r)
750     fixRI other = other
751
752 #endif {- sparc_TARGET_ARCH -}
753 \end{code}
754
755 %************************************************************************
756 %*                                                                      *
757 \subsection{@spillReg@ and @loadReg@ functions}
758 %*                                                                      *
759 %************************************************************************
760
761 Spill to memory, and load it back...
762
763 JRS, 000122: on x86, don't spill directly above the stack pointer,
764 since some insn sequences (int <-> conversions) use this as a temp
765 location.  Leave 8 words (ie, 64 bytes for a 64-bit arch) of slop.
766
767 \begin{code}
768 spillSlotSize :: Int
769 spillSlotSize = IF_ARCH_alpha( 8, IF_ARCH_sparc( 8, IF_ARCH_i386( 12, )))
770
771 maxSpillSlots :: Int
772 maxSpillSlots = ((rESERVED_C_STACK_BYTES - 64) `div` spillSlotSize) - 1
773
774 -- convert a spill slot number to a *byte* offset, with no sign:
775 -- decide on a per arch basis whether you are spilling above or below
776 -- the C stack pointer.
777 spillSlotToOffset :: Int -> Int
778 spillSlotToOffset slot
779    | slot >= 0 && slot < maxSpillSlots
780    = 64 + spillSlotSize * slot
781    | otherwise
782    = pprPanic "spillSlotToOffset:" 
783               (text "invalid spill location: " <> int slot)
784
785 vregToSpillSlot :: FiniteMap VRegUnique Int -> VRegUnique -> Int
786 vregToSpillSlot vreg_to_slot_map u
787    = case lookupFM vreg_to_slot_map u of
788         Just xx -> xx
789         Nothing -> pprPanic "vregToSpillSlot: unmapped vreg" (pprVRegUnique u)
790
791
792 spillReg, loadReg :: FiniteMap VRegUnique Int -> Int -> Reg -> Reg -> Instr
793
794 spillReg vreg_to_slot_map delta dyn vreg
795   | isVirtualReg vreg
796   = let slot_no = vregToSpillSlot vreg_to_slot_map (getVRegUnique vreg)
797         off     = spillSlotToOffset slot_no
798     in
799         {-Alpha: spill below the stack pointer (?)-}
800          IF_ARCH_alpha( ST sz dyn (spRel (- (off `div` 8)))
801
802         {-I386: spill above stack pointer leaving 3 words/spill-}
803         ,IF_ARCH_i386 ( let off_w = (off-delta) `div` 4
804                         in case regClass vreg of
805                               RcInteger -> MOV L (OpReg dyn) (OpAddr (spRel off_w))
806                               _         -> GST F80 dyn (spRel off_w) -- RcFloat/RcDouble
807
808         {-SPARC: spill below frame pointer leaving 2 words/spill-}
809         ,IF_ARCH_sparc( 
810                         let off_w = 1 + (off `div` 4)
811                             sz = case regClass vreg of
812                                     RcInteger -> W
813                                     RcFloat   -> F
814                                     RcDouble  -> DF
815                         in ST sz dyn (fpRel (- off_w))
816         ,)))
817
818    
819 loadReg vreg_to_slot_map delta vreg dyn
820   | isVirtualReg vreg
821   = let slot_no = vregToSpillSlot vreg_to_slot_map (getVRegUnique vreg)
822         off     = spillSlotToOffset slot_no
823     in
824          IF_ARCH_alpha( LD  sz dyn (spRel (- (off `div` 8)))
825
826         ,IF_ARCH_i386 ( let off_w = (off-delta) `div` 4
827                         in case regClass vreg of
828                               RcInteger -> MOV L (OpAddr (spRel off_w)) (OpReg dyn)
829                               _         -> GLD F80 (spRel off_w) dyn -- RcFloat/RcDouble
830
831         ,IF_ARCH_sparc( 
832                         let off_w = 1 + (off `div` 4)
833                             sz = case regClass vreg of
834                                    RcInteger -> W
835                                    RcFloat   -> F
836                                    RcDouble  -> DF
837                         in LD sz (fpRel (- off_w)) dyn
838         ,)))
839 \end{code}