2 % (c) The AQUA Project, Glasgow University, 1996
4 \section[RegAllocInfo]{Machine-specific info used for register allocation}
6 The (machine-independent) allocator itself is in @AsmRegAlloc@.
9 #include "HsVersions.h"
10 #include "nativeGen/NCG.h"
27 SYN_IE(RegAssignment),
54 #if __GLASGOW_HASKELL__ >= 202
61 IMPORT_1_3(List(partition))
65 import MachCode ( SYN_IE(InstrList) )
67 import AbsCSyn ( MagicId )
68 import BitSet ( unitBS, mkBS, minusBS, unionBS, listBS, BitSet )
69 import CLabel ( pprCLabel_asm, CLabel{-instance Ord-} )
70 import FiniteMap ( addToFM, lookupFM, FiniteMap )
71 import OrdList ( mkUnitList, OrdList )
72 import PrimRep ( PrimRep(..) )
73 import Stix ( StixTree, CodeSegment )
74 import UniqSet -- quite a bit of it
77 %************************************************************************
79 \subsection{Register allocation information}
81 %************************************************************************
84 type RegSet = UniqSet Reg
86 mkRegSet :: [Reg] -> RegSet
88 unionRegSets, minusRegSet :: RegSet -> RegSet -> RegSet
89 elementOfRegSet :: Reg -> RegSet -> Bool
90 isEmptyRegSet :: RegSet -> Bool
91 regSetToList :: RegSet -> [Reg]
94 emptyRegSet = emptyUniqSet
95 unionRegSets = unionUniqSets
96 minusRegSet = minusUniqSet
97 elementOfRegSet = elementOfUniqSet
98 isEmptyRegSet = isEmptyUniqSet
99 regSetToList = uniqSetToList
101 freeRegSet, callClobberedRegSet :: RegSet
102 argRegSet :: Int -> RegSet
104 freeRegSet = mkRegSet freeRegs
105 callClobberedRegSet = mkRegSet callClobberedRegs
106 argRegSet n = mkRegSet (argRegs n)
108 type RegAssignment = FiniteMap Reg Reg
109 type RegConflicts = FiniteMap Int RegSet
111 data FutureLive = FL RegSet (FiniteMap CLabel RegSet)
121 = RF RegSet -- in use
126 = RI RegSet -- in use
128 RegSet -- destinations
133 %************************************************************************
135 \subsection{Register allocation information}
137 %************************************************************************
139 COMMENT ON THE EXTRA BitSet FOR SPARC MRegsState: Getting the conflicts
140 right is a bit tedious for doubles. We'd have to add a conflict
141 function to the MachineRegisters class, and we'd have to put a PrimRep
142 in the MappedReg datatype, or use some kludge (e.g. register 64 + n is
143 really the same as 32 + n, except that it's used for a double, so it
144 also conflicts with 33 + n) to deal with it. It's just not worth the
145 bother, so we just partition the free floating point registers into
146 two sets: one for single precision and one for double precision. We
147 never seem to run out of floating point registers anyway.
151 = MRs BitSet -- integer registers
152 BitSet -- floating-point registers
153 IF_ARCH_sparc(BitSet,) -- double registers handled separately
157 #if alpha_TARGET_ARCH
158 # define INT_FLPT_CUTOFF 32
161 # define INT_FLPT_CUTOFF 8
163 #if sparc_TARGET_ARCH
164 # define INT_FLPT_CUTOFF 32
165 # define SNGL_DBL_CUTOFF 48
168 mkMRegsState :: [RegNo] -> MRegsState
169 possibleMRegs :: PrimRep -> MRegsState -> [RegNo]
170 useMReg :: MRegsState -> FAST_REG_NO -> MRegsState
171 useMRegs :: MRegsState -> [RegNo] -> MRegsState
172 freeMReg :: MRegsState -> FAST_REG_NO -> MRegsState
173 freeMRegs :: MRegsState -> [RegNo] -> MRegsState
176 = MRs (mkBS is) (mkBS fs2) IF_ARCH_sparc((mkBS ds2),)
178 (is, fs) = partition (< INT_FLPT_CUTOFF) xs
179 #if sparc_TARGET_ARCH
180 (ss, ds) = partition (< SNGL_DBL_CUTOFF) fs
181 fs2 = map (subtract INT_FLPT_CUTOFF) ss
182 ds2 = map (subtract INT_FLPT_CUTOFF) (filter even ds)
184 fs2 = map (subtract INT_FLPT_CUTOFF) fs
187 ------------------------------------------------
188 #if sparc_TARGET_ARCH
189 possibleMRegs FloatRep (MRs _ ss _) = [ x + INT_FLPT_CUTOFF | x <- listBS ss]
190 possibleMRegs DoubleRep (MRs _ _ ds) = [ x + INT_FLPT_CUTOFF | x <- listBS ds]
191 possibleMRegs _ (MRs is _ _) = listBS is
193 possibleMRegs FloatRep (MRs _ fs) = [ x + INT_FLPT_CUTOFF | x <- listBS fs]
194 possibleMRegs DoubleRep (MRs _ fs) = [ x + INT_FLPT_CUTOFF | x <- listBS fs]
195 possibleMRegs _ (MRs is _) = listBS is
198 ------------------------------------------------
199 #if sparc_TARGET_ARCH
200 useMReg (MRs is ss ds) n
201 = if (n _LT_ ILIT(INT_FLPT_CUTOFF)) then
202 MRs (is `minusBS` unitBS IBOX(n)) ss ds
203 else if (n _LT_ ILIT(SNGL_DBL_CUTOFF)) then
204 MRs is (ss `minusBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF)))) ds
206 MRs is ss (ds `minusBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
208 useMReg (MRs is fs) n
209 = if (n _LT_ ILIT(INT_FLPT_CUTOFF))
210 then MRs (is `minusBS` unitBS IBOX(n)) fs
211 else MRs is (fs `minusBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
214 ------------------------------------------------
215 #if sparc_TARGET_ARCH
216 useMRegs (MRs is ss ds) xs
217 = MRs (is `minusBS` is2) (ss `minusBS` ss2) (ds `minusBS` ds2)
219 MRs is2 ss2 ds2 = mkMRegsState xs
221 useMRegs (MRs is fs) xs
222 = MRs (is `minusBS` is2) (fs `minusBS` fs2)
224 MRs is2 fs2 = mkMRegsState xs
227 ------------------------------------------------
228 #if sparc_TARGET_ARCH
229 freeMReg (MRs is ss ds) n
230 = if (n _LT_ ILIT(INT_FLPT_CUTOFF)) then
231 MRs (is `unionBS` unitBS IBOX(n)) ss ds
232 else if (n _LT_ ILIT(SNGL_DBL_CUTOFF)) then
233 MRs is (ss `unionBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF)))) ds
235 MRs is ss (ds `unionBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
237 freeMReg (MRs is fs) n
238 = if (n _LT_ ILIT(INT_FLPT_CUTOFF))
239 then MRs (is `unionBS` unitBS IBOX(n)) fs
240 else MRs is (fs `unionBS` unitBS (IBOX(n _SUB_ ILIT(INT_FLPT_CUTOFF))))
243 ------------------------------------------------
244 #if sparc_TARGET_ARCH
245 freeMRegs (MRs is ss ds) xs
246 = MRs (is `unionBS` is2) (ss `unionBS` ss2) (ds `unionBS` ds2)
248 MRs is2 ss2 ds2 = mkMRegsState xs
250 freeMRegs (MRs is fs) xs
251 = MRs (is `unionBS` is2) (fs `unionBS` fs2)
253 MRs is2 fs2 = mkMRegsState xs
257 %************************************************************************
259 \subsection{@RegUsage@ type; @noUsage@, @endUsage@, @regUsage@ functions}
261 %************************************************************************
263 @regUsage@ returns the sets of src and destination registers used by a
264 particular instruction. Machine registers that are pre-allocated to
265 stgRegs are filtered out, because they are uninteresting from a
266 register allocation standpoint. (We wouldn't want them to end up on
269 An important point: The @regUsage@ function for a particular
270 assembly language must not refer to fixed registers, such as Hp, SpA,
271 etc. The source and destination MRegsStates should only refer to
272 dynamically allocated registers or static registers from the free
273 list. As far as we are concerned, the fixed registers simply don't
274 exist (for allocation purposes, anyway).
277 data RegUsage = RU RegSet RegSet
279 noUsage, endUsage :: RegUsage
280 noUsage = RU emptyRegSet emptyRegSet
281 endUsage = RU emptyRegSet freeRegSet
283 regUsage :: Instr -> RegUsage
285 #if alpha_TARGET_ARCH
287 regUsage instr = case instr of
288 LD B reg addr -> usage (regAddr addr, [reg, t9])
289 LD BU reg addr -> usage (regAddr addr, [reg, t9])
290 -- LD W reg addr -> usage (regAddr addr, [reg, t9]) : UNUSED
291 -- LD WU reg addr -> usage (regAddr addr, [reg, t9]) : UNUSED
292 LD sz reg addr -> usage (regAddr addr, [reg])
293 LDA reg addr -> usage (regAddr addr, [reg])
294 LDAH reg addr -> usage (regAddr addr, [reg])
295 LDGP reg addr -> usage (regAddr addr, [reg])
296 LDI sz reg imm -> usage ([], [reg])
297 ST B reg addr -> usage (reg : regAddr addr, [t9, t10])
298 -- ST W reg addr -> usage (reg : regAddr addr, [t9, t10]) : UNUSED
299 ST sz reg addr -> usage (reg : regAddr addr, [])
300 CLR reg -> usage ([], [reg])
301 ABS sz ri reg -> usage (regRI ri, [reg])
302 NEG sz ov ri reg -> usage (regRI ri, [reg])
303 ADD sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
304 SADD sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
305 SUB sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
306 SSUB sz sc r1 ar r2 -> usage (r1 : regRI ar, [r2])
307 MUL sz ov r1 ar r2 -> usage (r1 : regRI ar, [r2])
308 DIV sz un r1 ar r2 -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
309 REM sz un r1 ar r2 -> usage (r1 : regRI ar, [r2, t9, t10, t11, t12])
310 NOT ri reg -> usage (regRI ri, [reg])
311 AND r1 ar r2 -> usage (r1 : regRI ar, [r2])
312 ANDNOT r1 ar r2 -> usage (r1 : regRI ar, [r2])
313 OR r1 ar r2 -> usage (r1 : regRI ar, [r2])
314 ORNOT r1 ar r2 -> usage (r1 : regRI ar, [r2])
315 XOR r1 ar r2 -> usage (r1 : regRI ar, [r2])
316 XORNOT r1 ar r2 -> usage (r1 : regRI ar, [r2])
317 SLL r1 ar r2 -> usage (r1 : regRI ar, [r2])
318 SRL r1 ar r2 -> usage (r1 : regRI ar, [r2])
319 SRA r1 ar r2 -> usage (r1 : regRI ar, [r2])
320 ZAP r1 ar r2 -> usage (r1 : regRI ar, [r2])
321 ZAPNOT r1 ar r2 -> usage (r1 : regRI ar, [r2])
322 CMP co r1 ar r2 -> usage (r1 : regRI ar, [r2])
323 FCLR reg -> usage ([], [reg])
324 FABS r1 r2 -> usage ([r1], [r2])
325 FNEG sz r1 r2 -> usage ([r1], [r2])
326 FADD sz r1 r2 r3 -> usage ([r1, r2], [r3])
327 FDIV sz r1 r2 r3 -> usage ([r1, r2], [r3])
328 FMUL sz r1 r2 r3 -> usage ([r1, r2], [r3])
329 FSUB sz r1 r2 r3 -> usage ([r1, r2], [r3])
330 CVTxy sz1 sz2 r1 r2 -> usage ([r1], [r2])
331 FCMP sz co r1 r2 r3 -> usage ([r1, r2], [r3])
332 FMOV r1 r2 -> usage ([r1], [r2])
335 -- We assume that all local jumps will be BI/BF/BR. JMP must be out-of-line.
336 BI cond reg lbl -> usage ([reg], [])
337 BF cond reg lbl -> usage ([reg], [])
338 JMP reg addr hint -> RU (mkRegSet (filter interesting (regAddr addr))) freeRegSet
340 BSR _ n -> RU (argRegSet n) callClobberedRegSet
341 JSR reg addr n -> RU (argRegSet n) callClobberedRegSet
346 usage (src, dst) = RU (mkRegSet (filter interesting src))
347 (mkRegSet (filter interesting dst))
349 interesting (FixedReg _) = False
352 regAddr (AddrReg r1) = [r1]
353 regAddr (AddrRegImm r1 _) = [r1]
354 regAddr (AddrImm _) = []
356 regRI (RIReg r) = [r]
359 #endif {- alpha_TARGET_ARCH -}
360 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
363 regUsage instr = case instr of
364 MOV sz src dst -> usage2 src dst
365 MOVZX sz src dst -> usage2 src dst
366 MOVSX sz src dst -> usage2 src dst
367 LEA sz src dst -> usage2 src dst
368 ADD sz src dst -> usage2 src dst
369 SUB sz src dst -> usage2 src dst
370 IMUL sz src dst -> usage2 src dst
371 IDIV sz src -> usage (eax:edx:opToReg src) [eax,edx]
372 AND sz src dst -> usage2 src dst
373 OR sz src dst -> usage2 src dst
374 XOR sz src dst -> usage2 src dst
375 NOT sz op -> usage1 op
376 NEGI sz op -> usage1 op
377 SHL sz dst len -> usage2 dst len -- len is either an Imm or ecx.
378 SAR sz dst len -> usage2 dst len -- len is either an Imm or ecx.
379 SHR sz len dst -> usage2 dst len -- len is either an Imm or ecx.
380 PUSH sz op -> usage (opToReg op) []
381 POP sz op -> usage [] (opToReg op)
382 TEST sz src dst -> usage (opToReg src ++ opToReg dst) []
383 CMP sz src dst -> usage (opToReg src ++ opToReg dst) []
384 SETCC cond op -> usage [] (opToReg op)
385 JXX cond label -> usage [] []
386 JMP op -> usage (opToReg op) freeRegs
387 CALL imm -> usage [] callClobberedRegs
388 CLTD -> usage [eax] [edx]
390 SAHF -> usage [eax] []
391 FABS -> usage [st0] [st0]
392 FADD sz src -> usage (st0:opToReg src) [st0] -- allFPRegs
393 FADDP -> usage [st0,st1] [st0] -- allFPRegs
394 FIADD sz asrc -> usage (addrToRegs asrc) [st0]
395 FCHS -> usage [st0] [st0]
396 FCOM sz src -> usage (st0:opToReg src) []
397 FCOS -> usage [st0] [st0]
398 FDIV sz src -> usage (st0:opToReg src) [st0]
399 FDIVP -> usage [st0,st1] [st0]
400 FDIVRP -> usage [st0,st1] [st0]
401 FIDIV sz asrc -> usage (addrToRegs asrc) [st0]
402 FDIVR sz src -> usage (st0:opToReg src) [st0]
403 FIDIVR sz asrc -> usage (addrToRegs asrc) [st0]
404 FICOM sz asrc -> usage (addrToRegs asrc) []
405 FILD sz asrc dst -> usage (addrToRegs asrc) [dst] -- allFPRegs
406 FIST sz adst -> usage (st0:addrToRegs adst) []
407 FLD sz src -> usage (opToReg src) [st0] -- allFPRegs
408 FLD1 -> usage [] [st0] -- allFPRegs
409 FLDZ -> usage [] [st0] -- allFPRegs
410 FMUL sz src -> usage (st0:opToReg src) [st0]
411 FMULP -> usage [st0,st1] [st0]
412 FIMUL sz asrc -> usage (addrToRegs asrc) [st0]
413 FRNDINT -> usage [st0] [st0]
414 FSIN -> usage [st0] [st0]
415 FSQRT -> usage [st0] [st0]
416 FST sz (OpReg r) -> usage [st0] [r]
417 FST sz dst -> usage (st0:opToReg dst) []
418 FSTP sz (OpReg r) -> usage [st0] [r] -- allFPRegs
419 FSTP sz dst -> usage (st0:opToReg dst) [] -- allFPRegs
420 FSUB sz src -> usage (st0:opToReg src) [st0] -- allFPRegs
421 FSUBR sz src -> usage (st0:opToReg src) [st0] -- allFPRegs
422 FISUB sz asrc -> usage (addrToRegs asrc) [st0]
423 FSUBP -> usage [st0,st1] [st0] -- allFPRegs
424 FSUBRP -> usage [st0,st1] [st0] -- allFPRegs
425 FISUBR sz asrc -> usage (addrToRegs asrc) [st0]
426 FTST -> usage [st0] []
427 FCOMP sz op -> usage (st0:opToReg op) [st0] -- allFPRegs
428 FUCOMPP -> usage [st0, st1] [] -- allFPRegs
429 FXCH -> usage [st0, st1] [st0, st1]
430 FNSTSW -> usage [] [eax]
433 usage2 :: Operand -> Operand -> RegUsage
434 usage2 op (OpReg reg) = usage (opToReg op) [reg]
435 usage2 op (OpAddr ea) = usage (opToReg op ++ addrToRegs ea) []
436 usage2 op (OpImm imm) = usage (opToReg op) []
437 usage1 :: Operand -> RegUsage
438 usage1 (OpReg reg) = usage [reg] [reg]
439 usage1 (OpAddr ea) = usage (addrToRegs ea) []
440 allFPRegs = [st0,st1,st2,st3,st4,st5,st6,st7]
442 --callClobberedRegs = [ eax, ecx, edx ] -- according to gcc, anyway.
443 callClobberedRegs = [eax]
445 -- General purpose register collecting functions.
447 opToReg (OpReg reg) = [reg]
448 opToReg (OpImm imm) = []
449 opToReg (OpAddr ea) = addrToRegs ea
451 addrToRegs (Address base index _) = baseToReg base ++ indexToReg index
452 where baseToReg Nothing = []
453 baseToReg (Just r) = [r]
454 indexToReg Nothing = []
455 indexToReg (Just (r,_)) = [r]
456 addrToRegs (ImmAddr _ _) = []
458 usage src dst = RU (mkRegSet (filter interesting src))
459 (mkRegSet (filter interesting dst))
461 interesting (FixedReg _) = False
464 #endif {- i386_TARGET_ARCH -}
465 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
466 #if sparc_TARGET_ARCH
468 regUsage instr = case instr of
469 LD sz addr reg -> usage (regAddr addr, [reg])
470 ST sz reg addr -> usage (reg : regAddr addr, [])
471 ADD x cc r1 ar r2 -> usage (r1 : regRI ar, [r2])
472 SUB x cc r1 ar r2 -> usage (r1 : regRI ar, [r2])
473 AND b r1 ar r2 -> usage (r1 : regRI ar, [r2])
474 ANDN b r1 ar r2 -> usage (r1 : regRI ar, [r2])
475 OR b r1 ar r2 -> usage (r1 : regRI ar, [r2])
476 ORN b r1 ar r2 -> usage (r1 : regRI ar, [r2])
477 XOR b r1 ar r2 -> usage (r1 : regRI ar, [r2])
478 XNOR b r1 ar r2 -> usage (r1 : regRI ar, [r2])
479 SLL r1 ar r2 -> usage (r1 : regRI ar, [r2])
480 SRL r1 ar r2 -> usage (r1 : regRI ar, [r2])
481 SRA r1 ar r2 -> usage (r1 : regRI ar, [r2])
482 SETHI imm reg -> usage ([], [reg])
483 FABS s r1 r2 -> usage ([r1], [r2])
484 FADD s r1 r2 r3 -> usage ([r1, r2], [r3])
485 FCMP e s r1 r2 -> usage ([r1, r2], [])
486 FDIV s r1 r2 r3 -> usage ([r1, r2], [r3])
487 FMOV s r1 r2 -> usage ([r1], [r2])
488 FMUL s r1 r2 r3 -> usage ([r1, r2], [r3])
489 FNEG s r1 r2 -> usage ([r1], [r2])
490 FSQRT s r1 r2 -> usage ([r1], [r2])
491 FSUB s r1 r2 r3 -> usage ([r1, r2], [r3])
492 FxTOy s1 s2 r1 r2 -> usage ([r1], [r2])
494 -- We assume that all local jumps will be BI/BF. JMP must be out-of-line.
495 JMP addr -> RU (mkRegSet (filter interesting (regAddr addr))) freeRegSet
497 CALL _ n True -> endUsage
498 CALL _ n False -> RU (argRegSet n) callClobberedRegSet
502 usage (src, dst) = RU (mkRegSet (filter interesting src))
503 (mkRegSet (filter interesting dst))
505 interesting (FixedReg _) = False
508 regAddr (AddrRegReg r1 r2) = [r1, r2]
509 regAddr (AddrRegImm r1 _) = [r1]
511 regRI (RIReg r) = [r]
514 #endif {- sparc_TARGET_ARCH -}
517 %************************************************************************
519 \subsection{@RegLiveness@ type; @regLiveness@ function}
521 %************************************************************************
523 @regLiveness@ takes future liveness information and modifies it
524 according to the semantics of branches and labels. (An out-of-line
525 branch clobbers the liveness passed back by the following instruction;
526 a forward local branch passes back the liveness from the target label;
527 a conditional branch merges the liveness from the target and the
528 liveness from its successor; a label stashes away the current liveness
529 in the future liveness environment).
532 data RegLiveness = RL RegSet FutureLive
534 regLiveness :: Instr -> RegLiveness -> RegLiveness
536 regLiveness instr info@(RL live future@(FL all env))
539 = case (lookupFM env lbl) of
541 Nothing -> trace ("Missing " ++ (show (pprCLabel_asm lbl)) ++
542 " in future?") emptyRegSet
544 case instr of -- the rest is machine-specific...
546 #if alpha_TARGET_ARCH
548 -- We assume that all local jumps will be BI/BF. JMP must be out-of-line.
550 BR (ImmCLbl lbl) -> RL (lookup lbl) future
551 BI _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
552 BF _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
553 JMP _ _ _ -> RL emptyRegSet future
554 BSR _ _ -> RL live future
555 JSR _ _ _ -> RL live future
556 LABEL lbl -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
559 #endif {- alpha_TARGET_ARCH -}
560 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
563 JXX _ lbl -> RL (lookup lbl `unionRegSets` live) future
564 JMP _ -> RL emptyRegSet future
565 CALL _ -> RL live future
566 LABEL lbl -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
569 #endif {- i386_TARGET_ARCH -}
570 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
571 #if sparc_TARGET_ARCH
573 -- We assume that all local jumps will be BI/BF. JMP must be out-of-line.
575 BI ALWAYS _ (ImmCLbl lbl) -> RL (lookup lbl) future
576 BI _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
577 BF ALWAYS _ (ImmCLbl lbl) -> RL (lookup lbl) future
578 BF _ _ (ImmCLbl lbl) -> RL (lookup lbl `unionRegSets` live) future
579 JMP _ -> RL emptyRegSet future
580 CALL _ i True -> RL emptyRegSet future
581 CALL _ i False -> RL live future
582 LABEL lbl -> RL live (FL (all `unionRegSets` live) (addToFM env lbl live))
585 #endif {- sparc_TARGET_ARCH -}
588 %************************************************************************
590 \subsection{@patchRegs@ function}
592 %************************************************************************
594 @patchRegs@ takes an instruction (possibly with
595 MemoryReg/UnmappedReg registers) and changes all register references
596 according to the supplied environment.
599 patchRegs :: Instr -> (Reg -> Reg) -> Instr
601 #if alpha_TARGET_ARCH
603 patchRegs instr env = case instr of
604 LD sz reg addr -> LD sz (env reg) (fixAddr addr)
605 LDA reg addr -> LDA (env reg) (fixAddr addr)
606 LDAH reg addr -> LDAH (env reg) (fixAddr addr)
607 LDGP reg addr -> LDGP (env reg) (fixAddr addr)
608 LDI sz reg imm -> LDI sz (env reg) imm
609 ST sz reg addr -> ST sz (env reg) (fixAddr addr)
610 CLR reg -> CLR (env reg)
611 ABS sz ar reg -> ABS sz (fixRI ar) (env reg)
612 NEG sz ov ar reg -> NEG sz ov (fixRI ar) (env reg)
613 ADD sz ov r1 ar r2 -> ADD sz ov (env r1) (fixRI ar) (env r2)
614 SADD sz sc r1 ar r2 -> SADD sz sc (env r1) (fixRI ar) (env r2)
615 SUB sz ov r1 ar r2 -> SUB sz ov (env r1) (fixRI ar) (env r2)
616 SSUB sz sc r1 ar r2 -> SSUB sz sc (env r1) (fixRI ar) (env r2)
617 MUL sz ov r1 ar r2 -> MUL sz ov (env r1) (fixRI ar) (env r2)
618 DIV sz un r1 ar r2 -> DIV sz un (env r1) (fixRI ar) (env r2)
619 REM sz un r1 ar r2 -> REM sz un (env r1) (fixRI ar) (env r2)
620 NOT ar reg -> NOT (fixRI ar) (env reg)
621 AND r1 ar r2 -> AND (env r1) (fixRI ar) (env r2)
622 ANDNOT r1 ar r2 -> ANDNOT (env r1) (fixRI ar) (env r2)
623 OR r1 ar r2 -> OR (env r1) (fixRI ar) (env r2)
624 ORNOT r1 ar r2 -> ORNOT (env r1) (fixRI ar) (env r2)
625 XOR r1 ar r2 -> XOR (env r1) (fixRI ar) (env r2)
626 XORNOT r1 ar r2 -> XORNOT (env r1) (fixRI ar) (env r2)
627 SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
628 SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
629 SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
630 ZAP r1 ar r2 -> ZAP (env r1) (fixRI ar) (env r2)
631 ZAPNOT r1 ar r2 -> ZAPNOT (env r1) (fixRI ar) (env r2)
632 CMP co r1 ar r2 -> CMP co (env r1) (fixRI ar) (env r2)
633 FCLR reg -> FCLR (env reg)
634 FABS r1 r2 -> FABS (env r1) (env r2)
635 FNEG s r1 r2 -> FNEG s (env r1) (env r2)
636 FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
637 FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
638 FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
639 FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
640 CVTxy s1 s2 r1 r2 -> CVTxy s1 s2 (env r1) (env r2)
641 FCMP s co r1 r2 r3 -> FCMP s co (env r1) (env r2) (env r3)
642 FMOV r1 r2 -> FMOV (env r1) (env r2)
643 BI cond reg lbl -> BI cond (env reg) lbl
644 BF cond reg lbl -> BF cond (env reg) lbl
645 JMP reg addr hint -> JMP (env reg) (fixAddr addr) hint
646 JSR reg addr i -> JSR (env reg) (fixAddr addr) i
649 fixAddr (AddrReg r1) = AddrReg (env r1)
650 fixAddr (AddrRegImm r1 i) = AddrRegImm (env r1) i
651 fixAddr other = other
653 fixRI (RIReg r) = RIReg (env r)
656 #endif {- alpha_TARGET_ARCH -}
657 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
660 patchRegs instr env = case instr of
661 MOV sz src dst -> patch2 (MOV sz) src dst
662 MOVZX sz src dst -> patch2 (MOVZX sz) src dst
663 MOVSX sz src dst -> patch2 (MOVSX sz) src dst
664 LEA sz src dst -> patch2 (LEA sz) src dst
665 ADD sz src dst -> patch2 (ADD sz) src dst
666 SUB sz src dst -> patch2 (SUB sz) src dst
667 IMUL sz src dst -> patch2 (IMUL sz) src dst
668 IDIV sz src -> patch1 (IDIV sz) src
669 AND sz src dst -> patch2 (AND sz) src dst
670 OR sz src dst -> patch2 (OR sz) src dst
671 XOR sz src dst -> patch2 (XOR sz) src dst
672 NOT sz op -> patch1 (NOT sz) op
673 NEGI sz op -> patch1 (NEGI sz) op
674 SHL sz imm dst -> patch2 (SHL sz) imm dst
675 SAR sz imm dst -> patch2 (SAR sz) imm dst
676 SHR sz imm dst -> patch2 (SHR sz) imm dst
677 TEST sz src dst -> patch2 (TEST sz) src dst
678 CMP sz src dst -> patch2 (CMP sz) src dst
679 PUSH sz op -> patch1 (PUSH sz) op
680 POP sz op -> patch1 (POP sz) op
681 SETCC cond op -> patch1 (SETCC cond) op
682 JMP op -> patch1 JMP op
683 FADD sz src -> FADD sz (patchOp src)
684 FIADD sz asrc -> FIADD sz (lookupAddr asrc)
685 FCOM sz src -> patch1 (FCOM sz) src
686 FDIV sz src -> FDIV sz (patchOp src)
687 --FDIVP sz src -> FDIVP sz (patchOp src)
688 FIDIV sz asrc -> FIDIV sz (lookupAddr asrc)
689 FDIVR sz src -> FDIVR sz (patchOp src)
690 --FDIVRP sz src -> FDIVRP sz (patchOp src)
691 FIDIVR sz asrc -> FIDIVR sz (lookupAddr asrc)
692 FICOM sz asrc -> FICOM sz (lookupAddr asrc)
693 FILD sz asrc dst -> FILD sz (lookupAddr asrc) (env dst)
694 FIST sz adst -> FIST sz (lookupAddr adst)
695 FLD sz src -> patch1 (FLD sz) (patchOp src)
696 FMUL sz src -> FMUL sz (patchOp src)
697 --FMULP sz src -> FMULP sz (patchOp src)
698 FIMUL sz asrc -> FIMUL sz (lookupAddr asrc)
699 FST sz dst -> FST sz (patchOp dst)
700 FSTP sz dst -> FSTP sz (patchOp dst)
701 FSUB sz src -> FSUB sz (patchOp src)
702 --FSUBP sz src -> FSUBP sz (patchOp src)
703 FISUB sz asrc -> FISUB sz (lookupAddr asrc)
704 FSUBR sz src -> FSUBR sz (patchOp src)
705 --FSUBRP sz src -> FSUBRP sz (patchOp src)
706 FISUBR sz asrc -> FISUBR sz (lookupAddr asrc)
707 FCOMP sz src -> FCOMP sz (patchOp src)
710 patch1 insn op = insn (patchOp op)
711 patch2 insn src dst = insn (patchOp src) (patchOp dst)
713 patchOp (OpReg reg) = OpReg (env reg)
714 patchOp (OpImm imm) = OpImm imm
715 patchOp (OpAddr ea) = OpAddr (lookupAddr ea)
717 lookupAddr (ImmAddr imm off) = ImmAddr imm off
718 lookupAddr (Address base index disp)
719 = Address (lookupBase base) (lookupIndex index) disp
721 lookupBase Nothing = Nothing
722 lookupBase (Just r) = Just (env r)
724 lookupIndex Nothing = Nothing
725 lookupIndex (Just (r,i)) = Just (env r, i)
727 #endif {- i386_TARGET_ARCH -}
728 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
729 #if sparc_TARGET_ARCH
731 patchRegs instr env = case instr of
732 LD sz addr reg -> LD sz (fixAddr addr) (env reg)
733 ST sz reg addr -> ST sz (env reg) (fixAddr addr)
734 ADD x cc r1 ar r2 -> ADD x cc (env r1) (fixRI ar) (env r2)
735 SUB x cc r1 ar r2 -> SUB x cc (env r1) (fixRI ar) (env r2)
736 AND b r1 ar r2 -> AND b (env r1) (fixRI ar) (env r2)
737 ANDN b r1 ar r2 -> ANDN b (env r1) (fixRI ar) (env r2)
738 OR b r1 ar r2 -> OR b (env r1) (fixRI ar) (env r2)
739 ORN b r1 ar r2 -> ORN b (env r1) (fixRI ar) (env r2)
740 XOR b r1 ar r2 -> XOR b (env r1) (fixRI ar) (env r2)
741 XNOR b r1 ar r2 -> XNOR b (env r1) (fixRI ar) (env r2)
742 SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
743 SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
744 SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
745 SETHI imm reg -> SETHI imm (env reg)
746 FABS s r1 r2 -> FABS s (env r1) (env r2)
747 FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
748 FCMP e s r1 r2 -> FCMP e s (env r1) (env r2)
749 FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
750 FMOV s r1 r2 -> FMOV s (env r1) (env r2)
751 FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
752 FNEG s r1 r2 -> FNEG s (env r1) (env r2)
753 FSQRT s r1 r2 -> FSQRT s (env r1) (env r2)
754 FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
755 FxTOy s1 s2 r1 r2 -> FxTOy s1 s2 (env r1) (env r2)
756 JMP addr -> JMP (fixAddr addr)
759 fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
760 fixAddr (AddrRegImm r1 i) = AddrRegImm (env r1) i
762 fixRI (RIReg r) = RIReg (env r)
765 #endif {- sparc_TARGET_ARCH -}
768 %************************************************************************
770 \subsection{@spillReg@ and @loadReg@ functions}
772 %************************************************************************
774 Spill to memory, and load it back...
777 spillReg, loadReg :: Reg -> Reg -> InstrList
779 spillReg dyn (MemoryReg i pk)
781 sz = primRepToSize pk
784 {-Alpha: spill below the stack pointer (?)-}
785 IF_ARCH_alpha( ST sz dyn (spRel i)
787 {-I386: spill below stack pointer leaving 2 words/spill-}
788 ,IF_ARCH_i386 ( MOV sz (OpReg dyn) (OpAddr (spRel (-2 * i)))
790 {-SPARC: spill below frame pointer leaving 2 words/spill-}
791 ,IF_ARCH_sparc( ST sz dyn (fpRel (-2 * i))
795 ----------------------------
796 loadReg (MemoryReg i pk) dyn
798 sz = primRepToSize pk
801 IF_ARCH_alpha( LD sz dyn (spRel i)
802 ,IF_ARCH_i386 ( MOV sz (OpAddr (spRel (-2 * i))) (OpReg dyn)
803 ,IF_ARCH_sparc( LD sz (fpRel (-2 * i)) dyn