2 % (c) The AQUA Project, Glasgow University, 1996-1998
4 \section[RegAllocInfo]{Machine-specific info used for register allocation}
6 The (machine-independent) allocator itself is in @AsmRegAlloc@.
9 #include "nativeGen/NCG.h"
54 #include "HsVersions.h"
56 import List ( partition )
59 import MachCode ( InstrList )
61 import BitSet ( unitBS, mkBS, minusBS, unionBS, listBS, BitSet )
62 import CLabel ( pprCLabel_asm, CLabel{-instance Ord-} )
63 import FiniteMap ( addToFM, lookupFM, FiniteMap )
64 import OrdList ( mkUnitList )
65 import PrimRep ( PrimRep(..) )
66 import UniqSet -- quite a bit of it
68 import Constants ( rESERVED_C_STACK_BYTES )
71 %************************************************************************
73 \subsection{Register allocation information}
75 %************************************************************************
78 type RegSet = UniqSet Reg
80 mkRegSet :: [Reg] -> RegSet
82 unionRegSets, minusRegSet :: RegSet -> RegSet -> RegSet
83 elementOfRegSet :: Reg -> RegSet -> Bool
84 isEmptyRegSet :: RegSet -> Bool
85 regSetToList :: RegSet -> [Reg]
88 emptyRegSet = emptyUniqSet
89 unionRegSets = unionUniqSets
90 minusRegSet = minusUniqSet
91 elementOfRegSet = elementOfUniqSet
92 isEmptyRegSet = isEmptyUniqSet
93 regSetToList = uniqSetToList
95 freeRegSet, callClobberedRegSet :: RegSet
96 argRegSet :: Int -> RegSet
98 freeRegSet = mkRegSet freeRegs
99 callClobberedRegSet = mkRegSet callClobberedRegs
100 argRegSet n = mkRegSet (argRegs n)
102 type RegAssignment = FiniteMap Reg Reg
103 type RegConflicts = FiniteMap Int RegSet
105 data FutureLive = FL RegSet (FiniteMap CLabel RegSet)
115 = RF RegSet -- in use
120 = RI RegSet -- in use
122 RegSet -- destinations
127 %************************************************************************
129 \subsection{Register allocation information}
131 %************************************************************************
133 COMMENT ON THE EXTRA BitSet FOR SPARC MRegsState: Getting the conflicts
134 right is a bit tedious for doubles. We'd have to add a conflict
135 function to the MachineRegisters class, and we'd have to put a PrimRep
136 in the MappedReg datatype, or use some kludge (e.g. register 64 + n is
137 really the same as 32 + n, except that it's used for a double, so it
138 also conflicts with 33 + n) to deal with it. It's just not worth the
139 bother, so we just partition the free floating point registers into
140 two sets: one for single precision and one for double precision. We
141 never seem to run out of floating point registers anyway.
145 = MRs BitSet -- integer registers
146 BitSet -- floating-point registers
147 IF_ARCH_sparc(BitSet,) -- double registers handled separately
151 #if alpha_TARGET_ARCH
152 # define INT_FLPT_CUTOFF 32
155 # define INT_FLPT_CUTOFF 8
157 #if sparc_TARGET_ARCH
158 # define INT_FLPT_CUTOFF 32
159 # define SNGL_DBL_CUTOFF 48
162 mkMRegsState :: [RegNo] -> MRegsState
163 possibleMRegs :: PrimRep -> MRegsState -> [RegNo]
164 useMReg :: MRegsState -> FAST_REG_NO -> MRegsState
165 useMRegs :: MRegsState -> [RegNo] -> MRegsState
166 freeMReg :: MRegsState -> FAST_REG_NO -> MRegsState
167 freeMRegs :: MRegsState -> [RegNo] -> MRegsState
170 = MRs (mkBS is) (mkBS fs2) IF_ARCH_sparc((mkBS ds2),)
172 (is, fs) = partition (< INT_FLPT_CUTOFF) xs
173 #if sparc_TARGET_ARCH
174 (ss, ds) = partition (< SNGL_DBL_CUTOFF) fs
175 fs2 = map (subtract INT_FLPT_CUTOFF) ss
176 ds2 = map (subtract INT_FLPT_CUTOFF) (filter even ds)
178 fs2 = map (subtract INT_FLPT_CUTOFF) fs
181 ------------------------------------------------
182 #if sparc_TARGET_ARCH
183 possibleMRegs FloatRep (MRs _ ss _) = [ x + INT_FLPT_CUTOFF | x <- listBS ss]
184 possibleMRegs DoubleRep (MRs _ _ ds) = [ x + INT_FLPT_CUTOFF | x <- listBS ds]
185 possibleMRegs _ (MRs is _ _) = listBS is
187 possibleMRegs FloatRep (MRs _ fs) = [ x + INT_FLPT_CUTOFF | x <- listBS fs]
188 possibleMRegs DoubleRep (MRs _ fs) = [ x + INT_FLPT_CUTOFF | x <- listBS fs]
189 possibleMRegs _ (MRs is _) = listBS is
192 ------------------------------------------------
193 #if sparc_TARGET_ARCH
194 useMReg (MRs is ss ds) n
195 = if (n _LT_ ILIT(INT_FLPT_CUTOFF)) then
196 MRs (is `minusBS` unitBS IBOX(n)) ss ds
197 else if (n _LT_ ILIT(SNGL_DBL_CUTOFF)) then
198 MRs is (ss `minusBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF)))) ds
200 MRs is ss (ds `minusBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
202 useMReg (MRs is fs) n
203 = if (n _LT_ ILIT(INT_FLPT_CUTOFF))
204 then MRs (is `minusBS` unitBS IBOX(n)) fs
205 else MRs is (fs `minusBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
208 ------------------------------------------------
209 #if sparc_TARGET_ARCH
210 useMRegs (MRs is ss ds) xs
211 = MRs (is `minusBS` is2) (ss `minusBS` ss2) (ds `minusBS` ds2)
213 MRs is2 ss2 ds2 = mkMRegsState xs
215 useMRegs (MRs is fs) xs
216 = MRs (is `minusBS` is2) (fs `minusBS` fs2)
218 MRs is2 fs2 = mkMRegsState xs
221 ------------------------------------------------
222 #if sparc_TARGET_ARCH
223 freeMReg (MRs is ss ds) n
224 = if (n _LT_ ILIT(INT_FLPT_CUTOFF)) then
225 MRs (is `unionBS` unitBS IBOX(n)) ss ds
226 else if (n _LT_ ILIT(SNGL_DBL_CUTOFF)) then
227 MRs is (ss `unionBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF)))) ds
229 MRs is ss (ds `unionBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
231 freeMReg (MRs is fs) n
232 = if (n _LT_ ILIT(INT_FLPT_CUTOFF))
233 then MRs (is `unionBS` unitBS IBOX(n)) fs
234 else MRs is (fs `unionBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
237 ------------------------------------------------
238 #if sparc_TARGET_ARCH
239 freeMRegs (MRs is ss ds) xs
240 = MRs (is `unionBS` is2) (ss `unionBS` ss2) (ds `unionBS` ds2)
242 MRs is2 ss2 ds2 = mkMRegsState xs
244 freeMRegs (MRs is fs) xs
245 = MRs (is `unionBS` is2) (fs `unionBS` fs2)
247 MRs is2 fs2 = mkMRegsState xs
251 %************************************************************************
253 \subsection{@RegUsage@ type; @noUsage@, @endUsage@, @regUsage@ functions}
255 %************************************************************************
257 @regUsage@ returns the sets of src and destination registers used by a
258 particular instruction. Machine registers that are pre-allocated to
259 stgRegs are filtered out, because they are uninteresting from a
260 register allocation standpoint. (We wouldn't want them to end up on
263 An important point: The @regUsage@ function for a particular
264 assembly language must not refer to fixed registers, such as Hp, SpA,
265 etc. The source and destination MRegsStates should only refer to
266 dynamically allocated registers or static registers from the free
267 list. As far as we are concerned, the fixed registers simply don't
268 exist (for allocation purposes, anyway).
271 data RegUsage = RU RegSet RegSet
273 noUsage, endUsage :: RegUsage
274 noUsage = RU emptyRegSet emptyRegSet
275 endUsage = RU emptyRegSet freeRegSet
277 regUsage :: Instr -> RegUsage
279 #if alpha_TARGET_ARCH
281 regUsage instr = case instr of
282 LD B reg addr -> usage (regAddr addr, [reg, t9])
283 LD BU reg addr -> usage (regAddr addr, [reg, t9])
284 -- LD W reg addr -> usage (regAddr addr, [reg, t9]) : UNUSED
285 -- LD WU reg addr -> usage (regAddr addr, [reg, t9]) : UNUSED
286 LD sz reg addr -> usage (regAddr addr, [reg])
287 LDA reg addr -> usage (regAddr addr, [reg])
288 LDAH reg addr -> usage (regAddr addr, [reg])
289 LDGP reg addr -> usage (regAddr addr, [reg])
290 LDI sz reg imm -> usage ([], [reg])
291 ST B reg addr -> usage (reg : regAddr addr, [t9, t10])
292 -- ST W reg addr -> usage (reg : regAddr addr, [t9, t10]) : UNUSED
293 ST sz reg addr -> usage (reg : regAddr addr, [])
294 CLR reg -> usage ([], [reg])
295 ABS sz ri reg -> usage (regRI ri, [reg])
296 NEG sz ov ri reg -> usage (regRI ri, [reg])
297 ADD sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
298 SADD sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
299 SUB sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
300 SSUB sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
301 MUL sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
302 DIV sz un r1 ar r2 -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
303 REM sz un r1 ar r2 -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
304 NOT ri reg -> usage (regRI ri, [reg])
305 AND r1 ar r2 -> usage (r1 : regRI ar, [r2])
306 ANDNOT r1 ar r2 -> usage (r1 : regRI ar, [r2])
307 OR r1 ar r2 -> usage (r1 : regRI ar, [r2])
308 ORNOT r1 ar r2 -> usage (r1 : regRI ar, [r2])
309 XOR r1 ar r2 -> usage (r1 : regRI ar, [r2])
310 XORNOT r1 ar r2 -> usage (r1 : regRI ar, [r2])
311 SLL r1 ar r2 -> usage (r1 : regRI ar, [r2])
312 SRL r1 ar r2 -> usage (r1 : regRI ar, [r2])
313 SRA r1 ar r2 -> usage (r1 : regRI ar, [r2])
314 ZAP r1 ar r2 -> usage (r1 : regRI ar, [r2])
315 ZAPNOT r1 ar r2 -> usage (r1 : regRI ar, [r2])
316 CMP co r1 ar r2 -> usage (r1 : regRI ar, [r2])
317 FCLR reg -> usage ([], [reg])
318 FABS r1 r2 -> usage ([r1], [r2])
319 FNEG sz r1 r2 -> usage ([r1], [r2])
320 FADD sz r1 r2 r3 -> usage ([r1, r2], [r3])
321 FDIV sz r1 r2 r3 -> usage ([r1, r2], [r3])
322 FMUL sz r1 r2 r3 -> usage ([r1, r2], [r3])
323 FSUB sz r1 r2 r3 -> usage ([r1, r2], [r3])
324 CVTxy sz1 sz2 r1 r2 -> usage ([r1], [r2])
325 FCMP sz co r1 r2 r3 -> usage ([r1, r2], [r3])
326 FMOV r1 r2 -> usage ([r1], [r2])
329 -- We assume that all local jumps will be BI/BF/BR. JMP must be out-of-line.
330 BI cond reg lbl -> usage ([reg], [])
331 BF cond reg lbl -> usage ([reg], [])
332 JMP reg addr hint -> RU (mkRegSet (filter interesting (regAddr addr))) freeRegSet
334 BSR _ n -> RU (argRegSet n) callClobberedRegSet
335 JSR reg addr n -> RU (argRegSet n) callClobberedRegSet
340 usage (src, dst) = RU (mkRegSet (filter interesting src))
341 (mkRegSet (filter interesting dst))
343 interesting (FixedReg _) = False
346 regAddr (AddrReg r1) = [r1]
347 regAddr (AddrRegImm r1 _) = [r1]
348 regAddr (AddrImm _) = []
350 regRI (RIReg r) = [r]
353 #endif {- alpha_TARGET_ARCH -}
354 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
357 regUsage instr = case instr of
358 MOV sz src dst -> usage2 src dst
359 MOVZxL sz src dst -> usage2 src dst
360 MOVSxL sz src dst -> usage2 src dst
361 LEA sz src dst -> usage2 src dst
362 ADD sz src dst -> usage2s src dst
363 SUB sz src dst -> usage2s src dst
364 IMUL sz src dst -> usage2s src dst
365 IDIV sz src -> usage (eax:edx:opToReg src) [eax,edx]
366 AND sz src dst -> usage2s src dst
367 OR sz src dst -> usage2s src dst
368 XOR sz src dst -> usage2s src dst
369 NOT sz op -> usage1 op
370 NEGI sz op -> usage1 op
371 SHL sz imm dst -> usage1 dst
372 SAR sz imm dst -> usage1 dst
373 SHR sz imm dst -> usage1 dst
374 BT sz imm src -> usage (opToReg src) []
376 PUSH sz op -> usage (opToReg op) []
377 POP sz op -> usage [] (opToReg op)
378 TEST sz src dst -> usage (opToReg src ++ opToReg dst) []
379 CMP sz src dst -> usage (opToReg src ++ opToReg dst) []
380 SETCC cond op -> usage [] (opToReg op)
381 JXX cond lbl -> usage [] []
382 JMP op -> usage (opToReg op) freeRegs
383 CALL imm -> usage [] callClobberedRegs
384 CLTD -> usage [eax] [edx]
387 GMOV src dst -> usage [src] [dst]
388 GLD sz src dst -> usage (addrToRegs src) [dst]
389 GST sz src dst -> usage [src] (addrToRegs dst)
391 GFTOD src dst -> usage [src] [dst]
392 GFTOI src dst -> usage [src] [dst]
394 GDTOF src dst -> usage [src] [dst]
395 GDTOI src dst -> usage [src] [dst]
397 GITOF src dst -> usage [src] [dst]
398 GITOD src dst -> usage [src] [dst]
400 GADD sz s1 s2 dst -> usage [s1,s2] [dst]
401 GSUB sz s1 s2 dst -> usage [s1,s2] [dst]
402 GMUL sz s1 s2 dst -> usage [s1,s2] [dst]
403 GDIV sz s1 s2 dst -> usage [s1,s2] [dst]
405 GCMP sz src1 src2 -> usage [src1,src2] []
406 GABS sz src dst -> usage [src] [dst]
407 GNEG sz src dst -> usage [src] [dst]
408 GSQRT sz src dst -> usage [src] [dst]
409 GSIN sz src dst -> usage [src] [dst]
410 GCOS sz src dst -> usage [src] [dst]
411 GTAN sz src dst -> usage [src] [dst]
418 _ -> pprPanic "regUsage(x86)" empty
421 -- 2 operand form in which the second operand is purely a destination
422 usage2 :: Operand -> Operand -> RegUsage
423 usage2 op (OpReg reg) = usage (opToReg op) [reg]
424 usage2 op (OpAddr ea) = usage (opToReg op ++ addrToRegs ea) []
425 usage2 op (OpImm imm) = usage (opToReg op) []
427 -- 2 operand form in which the second operand is also an input
428 usage2s :: Operand -> Operand -> RegUsage
429 usage2s op (OpReg reg) = usage (opToReg op ++ [reg]) [reg]
430 usage2s op (OpAddr ea) = usage (opToReg op ++ addrToRegs ea) []
431 usage2s op (OpImm imm) = usage (opToReg op) []
433 -- 1 operand form in which the operand is both used and written
434 usage1 :: Operand -> RegUsage
435 usage1 (OpReg reg) = usage [reg] [reg]
436 usage1 (OpAddr ea) = usage (addrToRegs ea) []
438 allFPRegs = [fake0,fake1,fake2,fake3,fake4,fake5]
440 --callClobberedRegs = [ eax, ecx, edx ] -- according to gcc, anyway.
441 callClobberedRegs = [eax,fake0,fake1,fake2,fake3,fake4,fake5]
443 -- General purpose register collecting functions.
445 opToReg (OpReg reg) = [reg]
446 opToReg (OpImm imm) = []
447 opToReg (OpAddr ea) = addrToRegs ea
449 addrToRegs (AddrBaseIndex base index _) = baseToReg base ++ indexToReg index
450 where baseToReg Nothing = []
451 baseToReg (Just r) = [r]
452 indexToReg Nothing = []
453 indexToReg (Just (r,_)) = [r]
454 addrToRegs (ImmAddr _ _) = []
456 usage src dst = RU (mkRegSet (filter interesting src))
457 (mkRegSet (filter interesting dst))
459 interesting (FixedReg _) = False
463 -- Allow the spiller to decide whether or not it can use
464 -- %eax and %edx as spill temporaries.
465 hasFixedEAXorEDX instr = case instr of
470 #endif {- i386_TARGET_ARCH -}
471 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
472 #if sparc_TARGET_ARCH
474 regUsage instr = case instr of
475 LD sz addr reg -> usage (regAddr addr, [reg])
476 ST sz reg addr -> usage (reg : regAddr addr, [])
477 ADD x cc r1 ar r2 -> usage (r1 : regRI ar, [r2])
478 SUB x cc r1 ar r2 -> usage (r1 : regRI ar, [r2])
479 AND b r1 ar r2 -> usage (r1 : regRI ar, [r2])
480 ANDN b r1 ar r2 -> usage (r1 : regRI ar, [r2])
481 OR b r1 ar r2 -> usage (r1 : regRI ar, [r2])
482 ORN b r1 ar r2 -> usage (r1 : regRI ar, [r2])
483 XOR b r1 ar r2 -> usage (r1 : regRI ar, [r2])
484 XNOR b r1 ar r2 -> usage (r1 : regRI ar, [r2])
485 SLL r1 ar r2 -> usage (r1 : regRI ar, [r2])
486 SRL r1 ar r2 -> usage (r1 : regRI ar, [r2])
487 SRA r1 ar r2 -> usage (r1 : regRI ar, [r2])
488 SETHI imm reg -> usage ([], [reg])
489 FABS s r1 r2 -> usage ([r1], [r2])
490 FADD s r1 r2 r3 -> usage ([r1, r2], [r3])
491 FCMP e s r1 r2 -> usage ([r1, r2], [])
492 FDIV s r1 r2 r3 -> usage ([r1, r2], [r3])
493 FMOV s r1 r2 -> usage ([r1], [r2])
494 FMUL s r1 r2 r3 -> usage ([r1, r2], [r3])
495 FNEG s r1 r2 -> usage ([r1], [r2])
496 FSQRT s r1 r2 -> usage ([r1], [r2])
497 FSUB s r1 r2 r3 -> usage ([r1, r2], [r3])
498 FxTOy s1 s2 r1 r2 -> usage ([r1], [r2])
500 -- We assume that all local jumps will be BI/BF. JMP must be out-of-line.
501 JMP addr -> RU (mkRegSet (filter interesting (regAddr addr))) freeRegSet
503 CALL _ n True -> endUsage
504 CALL _ n False -> RU (argRegSet n) callClobberedRegSet
508 usage (src, dst) = RU (mkRegSet (filter interesting src))
509 (mkRegSet (filter interesting dst))
511 interesting (FixedReg _) = False
514 regAddr (AddrRegReg r1 r2) = [r1, r2]
515 regAddr (AddrRegImm r1 _) = [r1]
517 regRI (RIReg r) = [r]
520 #endif {- sparc_TARGET_ARCH -}
524 %************************************************************************
526 \subsection{Free, reserved, call-clobbered, and argument registers}
528 %************************************************************************
530 @freeRegs@ is the list of registers we can use in register allocation.
531 @freeReg@ (below) says if a particular register is free.
533 With a per-instruction clobber list, we might be able to get some of
534 these back, but it's probably not worth the hassle.
536 @callClobberedRegs@ ... the obvious.
538 @argRegs@: assuming a call with N arguments, what registers will be
539 used to hold arguments? (NB: it doesn't know whether the arguments
540 are integer or floating-point...)
542 findReservedRegs tells us which regs can be used as spill temporaries.
543 The list of instructions for which we are attempting allocation is
544 supplied. This is so that we can (at least for x86) examine it to
545 discover which registers are being used in a fixed way -- for example,
546 %eax and %edx are used by integer division, so they can't be used as
547 spill temporaries. However, most instruction lists don't do integer
548 division, so we don't want to rule them out altogether.
550 findReservedRegs returns not a list of spill temporaries, but a list
551 of list of them. This is so that the allocator can attempt allocating
552 with at first no spill temps, then if that fails, increasing numbers.
553 For x86 it is important that we minimise the number of regs reserved
554 as spill temporaries, since there are so few. For Alpha and Sparc
555 this isn't a concern; we just ignore the supplied code list and return
556 a singleton list which we know will satisfy all spill demands.
559 findReservedRegs :: [Instr] -> [[RegNo]]
560 findReservedRegs instrs
561 #if alpha_TARGET_ARCH
562 = --[[NCG_Reserved_I1, NCG_Reserved_I2,
563 -- NCG_Reserved_F1, NCG_Reserved_F2]]
564 error "findReservedRegs: alpha"
566 #if sparc_TARGET_ARCH
567 = --[[NCG_Reserved_I1, NCG_Reserved_I2,
568 -- NCG_Reserved_F1, NCG_Reserved_F2,
569 -- NCG_Reserved_D1, NCG_Reserved_D2]]
570 error "findReservedRegs: sparc"
573 -- Sigh. This is where it gets complicated.
574 = -- first of all, try without any at all.
575 map (map mappedRegNo) (
577 -- if that doesn't work, try one integer reg (which might fail)
578 -- and two float regs (which will always fix any float insns)
581 -- dire straits (but still correct): see if we can bag %eax and %edx
582 ++ if any hasFixedEAXorEDX instrs
584 else --[ [ecx,edx,fake4,fake5],
585 -- [ecx,edx,eax,fake4,fake5] ]
586 -- pro tem, don't use %eax until we institute a check that
587 -- instrs doesn't do a CALL insn, since that effectively
588 -- uses %eax in a fixed way
589 [ [ecx,edx,fake4,fake5] ]
595 %************************************************************************
597 \subsection{@RegLiveness@ type; @regLiveness@ function}
599 %************************************************************************
601 @regLiveness@ takes future liveness information and modifies it
602 according to the semantics of branches and labels. (An out-of-line
603 branch clobbers the liveness passed back by the following instruction;
604 a forward local branch passes back the liveness from the target label;
605 a conditional branch merges the liveness from the target and the
606 liveness from its successor; a label stashes away the current liveness
607 in the future liveness environment).
610 data RegLiveness = RL RegSet FutureLive
612 regLiveness :: Instr -> RegLiveness -> RegLiveness
614 regLiveness instr info@(RL live future@(FL all env))
617 = case (lookupFM env lbl) of
619 Nothing -> pprTrace "Missing" (pprCLabel_asm lbl <+> text "in future?")
622 case instr of -- the rest is machine-specific...
624 #if alpha_TARGET_ARCH
626 -- We assume that all local jumps will be BI/BF. JMP must be out-of-line.
628 BR (ImmCLbl lbl) -> RL (lookup lbl) future
629 BI _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
630 BF _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
631 JMP _ _ _ -> RL emptyRegSet future
632 BSR _ _ -> RL live future
633 JSR _ _ _ -> RL live future
634 LABEL lbl -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
637 #endif {- alpha_TARGET_ARCH -}
638 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
641 JXX _ lbl -> RL (lookup lbl `unionRegSets` live) future
642 JMP _ -> RL emptyRegSet future
643 CALL _ -> RL live future
644 LABEL lbl -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
647 #endif {- i386_TARGET_ARCH -}
648 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
649 #if sparc_TARGET_ARCH
651 -- We assume that all local jumps will be BI/BF. JMP must be out-of-line.
653 BI ALWAYS _ (ImmCLbl lbl) -> RL (lookup lbl) future
654 BI _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
655 BF ALWAYS _ (ImmCLbl lbl) -> RL (lookup lbl) future
656 BF _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
657 JMP _ -> RL emptyRegSet future
658 CALL _ i True -> RL emptyRegSet future
659 CALL _ i False -> RL live future
660 LABEL lbl -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
663 #endif {- sparc_TARGET_ARCH -}
666 %************************************************************************
668 \subsection{@patchRegs@ function}
670 %************************************************************************
672 @patchRegs@ takes an instruction (possibly with
673 MemoryReg/UnmappedReg registers) and changes all register references
674 according to the supplied environment.
677 patchRegs :: Instr -> (Reg -> Reg) -> Instr
679 #if alpha_TARGET_ARCH
681 patchRegs instr env = case instr of
682 LD sz reg addr -> LD sz (env reg) (fixAddr addr)
683 LDA reg addr -> LDA (env reg) (fixAddr addr)
684 LDAH reg addr -> LDAH (env reg) (fixAddr addr)
685 LDGP reg addr -> LDGP (env reg) (fixAddr addr)
686 LDI sz reg imm -> LDI sz (env reg) imm
687 ST sz reg addr -> ST sz (env reg) (fixAddr addr)
688 CLR reg -> CLR (env reg)
689 ABS sz ar reg -> ABS sz (fixRI ar) (env reg)
690 NEG sz ov ar reg -> NEG sz ov (fixRI ar) (env reg)
691 ADD sz ov r1 ar r2 -> ADD sz ov (env r1) (fixRI ar) (env r2)
692 SADD sz sc r1 ar r2 -> SADD sz sc (env r1) (fixRI ar) (env r2)
693 SUB sz ov r1 ar r2 -> SUB sz ov (env r1) (fixRI ar) (env r2)
694 SSUB sz sc r1 ar r2 -> SSUB sz sc (env r1) (fixRI ar) (env r2)
695 MUL sz ov r1 ar r2 -> MUL sz ov (env r1) (fixRI ar) (env r2)
696 DIV sz un r1 ar r2 -> DIV sz un (env r1) (fixRI ar) (env r2)
697 REM sz un r1 ar r2 -> REM sz un (env r1) (fixRI ar) (env r2)
698 NOT ar reg -> NOT (fixRI ar) (env reg)
699 AND r1 ar r2 -> AND (env r1) (fixRI ar) (env r2)
700 ANDNOT r1 ar r2 -> ANDNOT (env r1) (fixRI ar) (env r2)
701 OR r1 ar r2 -> OR (env r1) (fixRI ar) (env r2)
702 ORNOT r1 ar r2 -> ORNOT (env r1) (fixRI ar) (env r2)
703 XOR r1 ar r2 -> XOR (env r1) (fixRI ar) (env r2)
704 XORNOT r1 ar r2 -> XORNOT (env r1) (fixRI ar) (env r2)
705 SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
706 SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
707 SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
708 ZAP r1 ar r2 -> ZAP (env r1) (fixRI ar) (env r2)
709 ZAPNOT r1 ar r2 -> ZAPNOT (env r1) (fixRI ar) (env r2)
710 CMP co r1 ar r2 -> CMP co (env r1) (fixRI ar) (env r2)
711 FCLR reg -> FCLR (env reg)
712 FABS r1 r2 -> FABS (env r1) (env r2)
713 FNEG s r1 r2 -> FNEG s (env r1) (env r2)
714 FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
715 FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
716 FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
717 FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
718 CVTxy s1 s2 r1 r2 -> CVTxy s1 s2 (env r1) (env r2)
719 FCMP s co r1 r2 r3 -> FCMP s co (env r1) (env r2) (env r3)
720 FMOV r1 r2 -> FMOV (env r1) (env r2)
721 BI cond reg lbl -> BI cond (env reg) lbl
722 BF cond reg lbl -> BF cond (env reg) lbl
723 JMP reg addr hint -> JMP (env reg) (fixAddr addr) hint
724 JSR reg addr i -> JSR (env reg) (fixAddr addr) i
727 fixAddr (AddrReg r1) = AddrReg (env r1)
728 fixAddr (AddrRegImm r1 i) = AddrRegImm (env r1) i
729 fixAddr other = other
731 fixRI (RIReg r) = RIReg (env r)
734 #endif {- alpha_TARGET_ARCH -}
735 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
738 patchRegs instr env = case instr of
739 MOV sz src dst -> patch2 (MOV sz) src dst
740 MOVZxL sz src dst -> patch2 (MOVZxL sz) src dst
741 MOVSxL sz src dst -> patch2 (MOVSxL sz) src dst
742 LEA sz src dst -> patch2 (LEA sz) src dst
743 ADD sz src dst -> patch2 (ADD sz) src dst
744 SUB sz src dst -> patch2 (SUB sz) src dst
745 IMUL sz src dst -> patch2 (IMUL sz) src dst
746 IDIV sz src -> patch1 (IDIV sz) src
747 AND sz src dst -> patch2 (AND sz) src dst
748 OR sz src dst -> patch2 (OR sz) src dst
749 XOR sz src dst -> patch2 (XOR sz) src dst
750 NOT sz op -> patch1 (NOT sz) op
751 NEGI sz op -> patch1 (NEGI sz) op
752 SHL sz imm dst -> patch1 (SHL sz imm) dst
753 SAR sz imm dst -> patch1 (SAR sz imm) dst
754 SHR sz imm dst -> patch1 (SHR sz imm) dst
755 BT sz imm src -> patch1 (BT sz imm) src
756 TEST sz src dst -> patch2 (TEST sz) src dst
757 CMP sz src dst -> patch2 (CMP sz) src dst
758 PUSH sz op -> patch1 (PUSH sz) op
759 POP sz op -> patch1 (POP sz) op
760 SETCC cond op -> patch1 (SETCC cond) op
761 JMP op -> patch1 JMP op
763 GMOV src dst -> GMOV (env src) (env dst)
764 GLD sz src dst -> GLD sz (lookupAddr src) (env dst)
765 GST sz src dst -> GST sz (env src) (lookupAddr dst)
767 GFTOD src dst -> GFTOD (env src) (env dst)
768 GFTOI src dst -> GFTOI (env src) (env dst)
770 GDTOF src dst -> GDTOF (env src) (env dst)
771 GDTOI src dst -> GDTOI (env src) (env dst)
773 GITOF src dst -> GITOF (env src) (env dst)
774 GITOD src dst -> GITOD (env src) (env dst)
776 GADD sz s1 s2 dst -> GADD sz (env s1) (env s2) (env dst)
777 GSUB sz s1 s2 dst -> GSUB sz (env s1) (env s2) (env dst)
778 GMUL sz s1 s2 dst -> GMUL sz (env s1) (env s2) (env dst)
779 GDIV sz s1 s2 dst -> GDIV sz (env s1) (env s2) (env dst)
781 GCMP sz src1 src2 -> GCMP sz (env src1) (env src2)
782 GABS sz src dst -> GABS sz (env src) (env dst)
783 GNEG sz src dst -> GNEG sz (env src) (env dst)
784 GSQRT sz src dst -> GSQRT sz (env src) (env dst)
785 GSIN sz src dst -> GSIN sz (env src) (env dst)
786 GCOS sz src dst -> GCOS sz (env src) (env dst)
787 GTAN sz src dst -> GTAN sz (env src) (env dst)
797 _ -> pprPanic "patchInstr(x86)" empty
800 patch1 insn op = insn (patchOp op)
801 patch2 insn src dst = insn (patchOp src) (patchOp dst)
803 patchOp (OpReg reg) = OpReg (env reg)
804 patchOp (OpImm imm) = OpImm imm
805 patchOp (OpAddr ea) = OpAddr (lookupAddr ea)
807 lookupAddr (ImmAddr imm off) = ImmAddr imm off
808 lookupAddr (AddrBaseIndex base index disp)
809 = AddrBaseIndex (lookupBase base) (lookupIndex index) disp
811 lookupBase Nothing = Nothing
812 lookupBase (Just r) = Just (env r)
814 lookupIndex Nothing = Nothing
815 lookupIndex (Just (r,i)) = Just (env r, i)
817 #endif {- i386_TARGET_ARCH -}
818 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
819 #if sparc_TARGET_ARCH
821 patchRegs instr env = case instr of
822 LD sz addr reg -> LD sz (fixAddr addr) (env reg)
823 ST sz reg addr -> ST sz (env reg) (fixAddr addr)
824 ADD x cc r1 ar r2 -> ADD x cc (env r1) (fixRI ar) (env r2)
825 SUB x cc r1 ar r2 -> SUB x cc (env r1) (fixRI ar) (env r2)
826 AND b r1 ar r2 -> AND b (env r1) (fixRI ar) (env r2)
827 ANDN b r1 ar r2 -> ANDN b (env r1) (fixRI ar) (env r2)
828 OR b r1 ar r2 -> OR b (env r1) (fixRI ar) (env r2)
829 ORN b r1 ar r2 -> ORN b (env r1) (fixRI ar) (env r2)
830 XOR b r1 ar r2 -> XOR b (env r1) (fixRI ar) (env r2)
831 XNOR b r1 ar r2 -> XNOR b (env r1) (fixRI ar) (env r2)
832 SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
833 SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
834 SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
835 SETHI imm reg -> SETHI imm (env reg)
836 FABS s r1 r2 -> FABS s (env r1) (env r2)
837 FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
838 FCMP e s r1 r2 -> FCMP e s (env r1) (env r2)
839 FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
840 FMOV s r1 r2 -> FMOV s (env r1) (env r2)
841 FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
842 FNEG s r1 r2 -> FNEG s (env r1) (env r2)
843 FSQRT s r1 r2 -> FSQRT s (env r1) (env r2)
844 FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
845 FxTOy s1 s2 r1 r2 -> FxTOy s1 s2 (env r1) (env r2)
846 JMP addr -> JMP (fixAddr addr)
849 fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
850 fixAddr (AddrRegImm r1 i) = AddrRegImm (env r1) i
852 fixRI (RIReg r) = RIReg (env r)
855 #endif {- sparc_TARGET_ARCH -}
858 %************************************************************************
860 \subsection{@spillReg@ and @loadReg@ functions}
862 %************************************************************************
864 Spill to memory, and load it back...
866 JRS, 000122: on x86, don't spill directly above the stack pointer,
867 since some insn sequences (int <-> conversions, and eventually
868 StixInteger) use this as a temp location. Leave 8 words (ie, 64 bytes
869 for a 64-bit arch) of slop.
873 maxSpillSlots = (rESERVED_C_STACK_BYTES - 64) `div` 8
875 -- convert a spill slot number to a *byte* offset, with no sign:
876 -- decide on a per arch basis whether you are spilling above or below
877 -- the C stack pointer.
878 spillSlotToOffset :: Int -> Int
879 spillSlotToOffset slot
880 | slot >= 0 && slot < maxSpillSlots
883 = pprPanic "spillSlotToOffset:"
884 (text "invalid spill location: " <> int slot)
886 spillReg, loadReg :: Reg -> Reg -> InstrList
888 spillReg dyn (MemoryReg i pk)
889 = let sz = primRepToSize pk
890 off = spillSlotToOffset i
893 {-Alpha: spill below the stack pointer (?)-}
894 IF_ARCH_alpha( ST sz dyn (spRel (- (off `div` 8)))
896 {-I386: spill above stack pointer leaving 2 words/spill-}
897 ,IF_ARCH_i386 ( let off_w = off `div` 4
899 if pk == FloatRep || pk == DoubleRep
900 then GST DF dyn (spRel off_w)
901 else MOV sz (OpReg dyn) (OpAddr (spRel off_w))
903 {-SPARC: spill below frame pointer leaving 2 words/spill-}
904 ,IF_ARCH_sparc( ST sz dyn (fpRel (- (off `div` 4)))
908 loadReg (MemoryReg i pk) dyn
909 = let sz = primRepToSize pk
910 off = spillSlotToOffset i
913 IF_ARCH_alpha( LD sz dyn (spRel (- (off `div` 8)))
914 ,IF_ARCH_i386 ( let off_w = off `div` 4
916 if pk == FloatRep || pk == DoubleRep
917 then GLD DF (spRel off_w) dyn
918 else MOV sz (OpAddr (spRel off_w)) (OpReg dyn)
919 ,IF_ARCH_sparc( LD sz (fpRel (- (off `div` 4))) dyn