2 % (c) The AQUA Project, Glasgow University, 1996-1998
4 \section[MachRegs]{Machine-specific info about registers}
6 Also includes stuff about immediate operands, which are
7 often/usually quite entangled with registers.
9 (Immediates could be untangled from registers at some cost in tangled
10 modules --- the pleasure has been foregone.)
13 #include "nativeGen/NCG.h"
17 RegClass(..), regClass,
18 VRegUnique(..), pprVRegUnique, getHiVRegFromLo,
19 Reg(..), isRealReg, isVirtualReg, getVRegUnique,
20 allocatableRegs, argRegs, allArgRegs, callClobberedRegs,
31 get_MagicId_reg_or_addr,
33 get_Regtable_addr_from_offset,
41 , gp, pv, ra, sp, t9, t10, t11, t12, v0, f0, zeroh
44 , eax, ebx, ecx, edx, esi, esp
45 , fake0, fake1, fake2, fake3, fake4, fake5
49 , fpRel, gReg, iReg, lReg, oReg, largeOffsetError
50 , fp, sp, g0, g1, g2, o0, o1, f0, f6, f8, f26, f27
55 #include "HsVersions.h"
57 import AbsCSyn ( MagicId(..) )
58 import CLabel ( CLabel, mkMainCapabilityLabel )
59 import MachOp ( MachOp(..) )
60 import PrimRep ( PrimRep(..), isFloatingRep )
61 import Stix ( StixExpr(..), StixReg(..),
62 getUniqueNat, returnNat, thenNat, NatM )
63 import Unique ( mkPseudoUnique2, Uniquable(..), Unique )
65 import Outputable ( Outputable(..), pprPanic, panic )
66 import qualified Outputable
70 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
75 | ImmInteger Integer -- Sigh.
76 | ImmCLbl CLabel -- AbstractC Label (with baggage)
77 | ImmLab Bool Doc -- Simple string label (underscore-able)
78 -- Bool==True ==> in a different DLL
79 | ImmLit Doc -- Simple string
84 | LO Imm -- Possible restrictions...
87 strImmLit s = ImmLit (text s)
90 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
101 = AddrBaseIndex Base Index Displacement
104 type Base = Maybe Reg
105 type Index = Maybe (Reg, Int) -- Int is 2, 4 or 8
106 type Displacement = Imm
109 #if sparc_TARGET_ARCH
114 addrOffset :: MachRegsAddr -> Int -> Maybe MachRegsAddr
118 #if alpha_TARGET_ARCH
119 _ -> panic "MachMisc.addrOffset not defined for Alpha"
122 ImmAddr i off0 -> Just (ImmAddr i (off0 + off))
123 AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
124 AddrBaseIndex r i (ImmInteger n)
125 -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
128 #if sparc_TARGET_ARCH
129 AddrRegImm r (ImmInt n)
130 | fits13Bits n2 -> Just (AddrRegImm r (ImmInt n2))
131 | otherwise -> Nothing
134 AddrRegImm r (ImmInteger n)
135 | fits13Bits n2 -> Just (AddrRegImm r (ImmInt (fromInteger n2)))
136 | otherwise -> Nothing
137 where n2 = n + toInteger off
139 AddrRegReg r (RealReg 0)
140 | fits13Bits off -> Just (AddrRegImm r (ImmInt off))
141 | otherwise -> Nothing
148 #if alpha_TARGET_ARCH
150 fits8Bits :: Integer -> Bool
151 fits8Bits i = i >= -256 && i < 256
155 #if sparc_TARGET_ARCH
157 {-# SPECIALIZE fits13Bits :: Int -> Bool, Integer -> Bool #-}
158 fits13Bits :: Integral a => a -> Bool
159 fits13Bits x = x >= -4096 && x < 4096
163 = error ("ERROR: SPARC native-code generator cannot handle large offset ("
164 ++show i++");\nprobably because of large constant data structures;" ++
165 "\nworkaround: use -fvia-C on this module.\n")
170 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
172 @stgReg@: we map STG registers onto appropriate Stix Trees. Either
173 they map to real machine registers or stored as offsets from BaseReg.
174 Given a MagicId, get_MagicId_reg_or_addr produces either the real
175 register it is in, on this platform, or a StixExpr denoting the
176 address in the register table holding it. get_MagicId_addr always
177 produces the register table address for it.
180 get_MagicId_reg_or_addr :: MagicId -> Either Reg StixExpr
181 get_MagicId_addr :: MagicId -> StixExpr
182 get_Regtable_addr_from_offset :: Int -> StixExpr
184 get_MagicId_reg_or_addr mid
185 = case magicIdRegMaybe mid of
187 Nothing -> Right (get_MagicId_addr mid)
189 get_MagicId_addr BaseReg
190 = -- This arch doesn't have BaseReg in a register, so we have to
191 -- use &MainRegTable.r instead.
192 StIndex PtrRep (StCLbl mkMainCapabilityLabel)
193 (StInt (toInteger OFFW_Capability_r))
195 = get_Regtable_addr_from_offset (baseRegOffset mid)
197 get_Regtable_addr_from_offset offset_in_words
198 = let ptr_to_RegTable
199 = case magicIdRegMaybe BaseReg of
201 -> -- This arch doesn't have BaseReg in a register, so we have to
202 -- use &MainRegTable.r instead.
203 StIndex PtrRep (StCLbl mkMainCapabilityLabel)
204 (StInt (toInteger OFFW_Capability_r))
206 -> -- It's in a reg, so leave it as it is
207 StReg (StixMagicId BaseReg)
209 StIndex PtrRep ptr_to_RegTable (StInt (toInteger offset_in_words))
212 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
214 @spRel@ gives us a stack relative addressing mode for volatile
215 temporaries and for excess call arguments. @fpRel@, where
216 applicable, is the same but for the frame pointer.
219 spRel :: Int -- desired stack offset in words, positive or negative
224 = AddrBaseIndex (Just esp) Nothing (ImmInt (n * BYTES_PER_WORD))
226 = AddrRegImm sp (ImmInt (n * BYTES_PER_WORD))
229 #if sparc_TARGET_ARCH
230 fpRel :: Int -> MachRegsAddr
231 -- Duznae work for offsets greater than 13 bits; we just hope for
234 = AddrRegImm fp (ImmInt (n * BYTES_PER_WORD))
238 %************************************************************************
240 \subsection[Reg]{Real registers}
242 %************************************************************************
244 RealRegs are machine regs which are available for allocation, in the
245 usual way. We know what class they are, because that's part of the
246 processor's architecture.
248 VirtualRegs are virtual registers. The register allocator will
249 eventually have to map them into RealRegs, or into spill slots.
250 VirtualRegs are allocated on the fly, usually to represent a single
251 value in the abstract assembly code (i.e. dynamic registers are
252 usually single assignment). With the new register allocator, the
253 single assignment restriction isn't necessary to get correct code,
254 although a better register allocation will result if single assignment
255 is used -- because the allocator maps a VirtualReg into a single
256 RealReg, even if the VirtualReg has multiple live ranges.
258 Virtual regs can be of either class, so that info is attached.
263 = VRegUniqueLo Unique -- lower part of a split quantity
264 | VRegUniqueHi Unique -- upper part thereof
267 instance Show VRegUnique where
268 show (VRegUniqueLo u) = show u
269 show (VRegUniqueHi u) = "_hi_" ++ show u
271 pprVRegUnique :: VRegUnique -> Outputable.SDoc
273 = Outputable.text . show
275 -- Determine the upper-half vreg for a 64-bit quantity on a 32-bit platform
276 -- when supplied with the vreg for the lower-half of the quantity.
277 getHiVRegFromLo (VirtualRegI (VRegUniqueLo u))
278 = VirtualRegI (VRegUniqueHi u)
279 getHiVRegFromLo other
280 = pprPanic "getHiVRegFromLo" (ppr other)
290 | VirtualRegI VRegUnique
291 | VirtualRegF VRegUnique
292 | VirtualRegD VRegUnique
294 unRealReg (RealReg i) = i
295 unRealReg vreg = pprPanic "unRealReg on VirtualReg" (ppr vreg)
297 getVRegUnique :: Reg -> VRegUnique
298 getVRegUnique (VirtualRegI vu) = vu
299 getVRegUnique (VirtualRegF vu) = vu
300 getVRegUnique (VirtualRegD vu) = vu
301 getVRegUnique rreg = pprPanic "getVRegUnique on RealReg" (ppr rreg)
303 mkVReg :: Unique -> PrimRep -> Reg
305 #if sparc_TARGET_ARCH
307 FloatRep -> VirtualRegF (VRegUniqueLo u)
308 DoubleRep -> VirtualRegD (VRegUniqueLo u)
309 other -> VirtualRegI (VRegUniqueLo u)
311 = if isFloatingRep pk then VirtualRegD (VRegUniqueLo u)
312 else VirtualRegI (VRegUniqueLo u)
315 isVirtualReg (RealReg _) = False
316 isVirtualReg (VirtualRegI _) = True
317 isVirtualReg (VirtualRegF _) = True
318 isVirtualReg (VirtualRegD _) = True
319 isRealReg = not . isVirtualReg
321 getNewRegNCG :: PrimRep -> NatM Reg
323 = getUniqueNat `thenNat` \ u -> returnNat (mkVReg u pk)
325 instance Eq Reg where
326 (==) (RealReg i1) (RealReg i2) = i1 == i2
327 (==) (VirtualRegI u1) (VirtualRegI u2) = u1 == u2
328 (==) (VirtualRegF u1) (VirtualRegF u2) = u1 == u2
329 (==) (VirtualRegD u1) (VirtualRegD u2) = u1 == u2
330 (==) reg1 reg2 = False
332 instance Ord Reg where
333 compare (RealReg i1) (RealReg i2) = compare i1 i2
334 compare (RealReg _) (VirtualRegI _) = LT
335 compare (RealReg _) (VirtualRegF _) = LT
336 compare (RealReg _) (VirtualRegD _) = LT
338 compare (VirtualRegI _) (RealReg _) = GT
339 compare (VirtualRegI u1) (VirtualRegI u2) = compare u1 u2
340 compare (VirtualRegI _) (VirtualRegF _) = LT
341 compare (VirtualRegI _) (VirtualRegD _) = LT
343 compare (VirtualRegF _) (RealReg _) = GT
344 compare (VirtualRegF _) (VirtualRegI _) = GT
345 compare (VirtualRegF u1) (VirtualRegF u2) = compare u1 u2
346 compare (VirtualRegF _) (VirtualRegD _) = LT
348 compare (VirtualRegD _) (RealReg _) = GT
349 compare (VirtualRegD _) (VirtualRegI _) = GT
350 compare (VirtualRegD _) (VirtualRegF _) = GT
351 compare (VirtualRegD u1) (VirtualRegD u2) = compare u1 u2
354 instance Show Reg where
355 show (RealReg i) = showReg i
356 show (VirtualRegI u) = "%vI_" ++ show u
357 show (VirtualRegF u) = "%vF_" ++ show u
358 show (VirtualRegD u) = "%vD_" ++ show u
360 instance Outputable Reg where
361 ppr r = Outputable.text (show r)
364 ** Machine-specific Reg stuff: **
366 The Alpha has 64 registers of interest; 32 integer registers and 32 floating
367 point registers. The mapping of STG registers to alpha machine registers
368 is defined in StgRegs.h. We are, of course, prepared for any eventuality.
370 #if alpha_TARGET_ARCH
374 v0, f0, ra, pv, gp, sp, zeroh :: Reg
376 f0 = realReg (fReg 0)
377 ra = FixedReg ILIT(26)
379 gp = FixedReg ILIT(29)
380 sp = FixedReg ILIT(30)
381 zeroh = FixedReg ILIT(31) -- "zero" is used in 1.3 (MonadZero method)
383 t9, t10, t11, t12 :: Reg
391 Intel x86 architecture:
392 - All registers except 7 (esp) are available for use.
393 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
394 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
395 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
396 - Registers 8-13 are fakes; we pretend x86 has 6 conventionally-addressable
397 fp registers, and 3-operand insns for them, and we translate this into
398 real stack-based x86 fp code after register allocation.
400 The fp registers are all Double registers; we don't have any RcFloat class
401 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
407 fake0, fake1, fake2, fake3, fake4, fake5,
408 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
424 regClass (RealReg i) = if i < 8 then RcInteger else RcDouble
425 regClass (VirtualRegI u) = RcInteger
426 regClass (VirtualRegD u) = RcDouble
427 regClass (VirtualRegF u) = pprPanic "regClass(x86):VirtualRegF"
428 (ppr (VirtualRegF u))
431 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
432 "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"]
434 showReg :: Int -> String
436 = if n >= 0 && n < 14
438 else "%unknown_x86_real_reg_" ++ show n
443 The SPARC has 64 registers of interest; 32 integer registers and 32
444 floating point registers. The mapping of STG registers to SPARC
445 machine registers is defined in StgRegs.h. We are, of course,
446 prepared for any eventuality.
448 The whole fp-register pairing thing on sparcs is a huge nuisance. See
449 fptools/ghc/includes/MachRegs.h for a description of what's going on
453 #if sparc_TARGET_ARCH
455 gReg,lReg,iReg,oReg,fReg :: Int -> Int
462 nCG_FirstFloatReg :: Int
463 nCG_FirstFloatReg = unRealReg NCG_FirstFloatReg
465 regClass (VirtualRegI u) = RcInteger
466 regClass (VirtualRegF u) = RcFloat
467 regClass (VirtualRegD u) = RcDouble
468 regClass (RealReg i) | i < 32 = RcInteger
469 | i < nCG_FirstFloatReg = RcDouble
470 | otherwise = RcFloat
472 showReg :: Int -> String
474 | n >= 0 && n < 8 = "%g" ++ show n
475 | n >= 8 && n < 16 = "%o" ++ show (n-8)
476 | n >= 16 && n < 24 = "%l" ++ show (n-16)
477 | n >= 24 && n < 32 = "%i" ++ show (n-24)
478 | n >= 32 && n < 64 = "%f" ++ show (n-32)
479 | otherwise = "%unknown_sparc_real_reg_" ++ show n
481 g0, g1, g2, fp, sp, o0, o1, f0, f1, f6, f8, f22, f26, f27 :: Reg
483 f6 = RealReg (fReg 6)
484 f8 = RealReg (fReg 8)
485 f22 = RealReg (fReg 22)
486 f26 = RealReg (fReg 26)
487 f27 = RealReg (fReg 27)
490 -- g0 is useful for codegen; is always zero, and writes to it vanish.
491 g0 = RealReg (gReg 0)
492 g1 = RealReg (gReg 1)
493 g2 = RealReg (gReg 2)
495 -- FP, SP, int and float return (from C) regs.
496 fp = RealReg (iReg 6)
497 sp = RealReg (oReg 6)
498 o0 = RealReg (oReg 0)
499 o1 = RealReg (oReg 1)
500 f0 = RealReg (fReg 0)
501 f1 = RealReg (fReg 1)
506 Redefine the literals used for machine-registers with non-numeric
507 names in the header files. Gag me with a spoon, eh?
509 #if alpha_TARGET_ARCH
559 #if sparc_TARGET_ARCH
630 baseRegOffset :: MagicId -> Int
632 baseRegOffset (VanillaReg _ 1#) = OFFSET_R1
633 baseRegOffset (VanillaReg _ 2#) = OFFSET_R2
634 baseRegOffset (VanillaReg _ 3#) = OFFSET_R3
635 baseRegOffset (VanillaReg _ 4#) = OFFSET_R4
636 baseRegOffset (VanillaReg _ 5#) = OFFSET_R5
637 baseRegOffset (VanillaReg _ 6#) = OFFSET_R6
638 baseRegOffset (VanillaReg _ 7#) = OFFSET_R7
639 baseRegOffset (VanillaReg _ 8#) = OFFSET_R8
640 baseRegOffset (VanillaReg _ 9#) = OFFSET_R9
641 baseRegOffset (VanillaReg _ 10#) = OFFSET_R10
642 baseRegOffset (FloatReg 1#) = OFFSET_F1
643 baseRegOffset (FloatReg 2#) = OFFSET_F2
644 baseRegOffset (FloatReg 3#) = OFFSET_F3
645 baseRegOffset (FloatReg 4#) = OFFSET_F4
646 baseRegOffset (DoubleReg 1#) = OFFSET_D1
647 baseRegOffset (DoubleReg 2#) = OFFSET_D2
648 baseRegOffset Sp = OFFSET_Sp
649 baseRegOffset Su = OFFSET_Su
650 baseRegOffset SpLim = OFFSET_SpLim
652 baseRegOffset (LongReg _ 1#) = OFFSET_L1
654 baseRegOffset Hp = OFFSET_Hp
655 baseRegOffset HpLim = OFFSET_HpLim
656 baseRegOffset CurrentTSO = OFFSET_CurrentTSO
657 baseRegOffset CurrentNursery = OFFSET_CurrentNursery
658 baseRegOffset HpAlloc = OFFSET_HpAlloc
660 baseRegOffset BaseReg = panic "baseRegOffset:BaseReg"
661 baseRegOffset CurCostCentre = panic "baseRegOffset:CurCostCentre"
662 baseRegOffset VoidReg = panic "baseRegOffset:VoidReg"
667 callerSaves :: MagicId -> Bool
669 #ifdef CALLER_SAVES_Base
670 callerSaves BaseReg = True
672 #ifdef CALLER_SAVES_R1
673 callerSaves (VanillaReg _ ILIT(1)) = True
675 #ifdef CALLER_SAVES_R2
676 callerSaves (VanillaReg _ ILIT(2)) = True
678 #ifdef CALLER_SAVES_R3
679 callerSaves (VanillaReg _ ILIT(3)) = True
681 #ifdef CALLER_SAVES_R4
682 callerSaves (VanillaReg _ ILIT(4)) = True
684 #ifdef CALLER_SAVES_R5
685 callerSaves (VanillaReg _ ILIT(5)) = True
687 #ifdef CALLER_SAVES_R6
688 callerSaves (VanillaReg _ ILIT(6)) = True
690 #ifdef CALLER_SAVES_R7
691 callerSaves (VanillaReg _ ILIT(7)) = True
693 #ifdef CALLER_SAVES_R8
694 callerSaves (VanillaReg _ ILIT(8)) = True
696 #ifdef CALLER_SAVES_F1
697 callerSaves (FloatReg 1#) = True
699 #ifdef CALLER_SAVES_F2
700 callerSaves (FloatReg 2#) = True
702 #ifdef CALLER_SAVES_F3
703 callerSaves (FloatReg 3#) = True
705 #ifdef CALLER_SAVES_F4
706 callerSaves (FloatReg 4#) = True
708 #ifdef CALLER_SAVES_D1
709 callerSaves (DoubleReg 1#) = True
711 #ifdef CALLER_SAVES_D2
712 callerSaves (DoubleReg 2#) = True
714 #ifdef CALLER_SAVES_L1
715 callerSaves (LongReg _ ILIT(1)) = True
717 #ifdef CALLER_SAVES_Sp
718 callerSaves Sp = True
720 #ifdef CALLER_SAVES_Su
721 callerSaves Su = True
723 #ifdef CALLER_SAVES_SpLim
724 callerSaves SpLim = True
726 #ifdef CALLER_SAVES_Hp
727 callerSaves Hp = True
729 #ifdef CALLER_SAVES_HpLim
730 callerSaves HpLim = True
732 #ifdef CALLER_SAVES_CurrentTSO
733 callerSaves CurrentTSO = True
735 #ifdef CALLER_SAVES_CurrentNursery
736 callerSaves CurrentNursery = True
738 callerSaves _ = False
742 magicIdRegMaybe :: MagicId -> Maybe Reg
745 magicIdRegMaybe BaseReg = Just (RealReg REG_Base)
748 magicIdRegMaybe (VanillaReg _ 1#) = Just (RealReg REG_R1)
751 magicIdRegMaybe (VanillaReg _ 2#) = Just (RealReg REG_R2)
754 magicIdRegMaybe (VanillaReg _ 3#) = Just (RealReg REG_R3)
757 magicIdRegMaybe (VanillaReg _ 4#) = Just (RealReg REG_R4)
760 magicIdRegMaybe (VanillaReg _ 5#) = Just (RealReg REG_R5)
763 magicIdRegMaybe (VanillaReg _ 6#) = Just (RealReg REG_R6)
766 magicIdRegMaybe (VanillaReg _ 7#) = Just (RealReg REG_R7)
769 magicIdRegMaybe (VanillaReg _ 8#) = Just (RealReg REG_R8)
772 magicIdRegMaybe (VanillaReg _ 9#) = Just (RealReg REG_R9)
775 magicIdRegMaybe (VanillaReg _ 10#) = Just (RealReg REG_R10)
778 magicIdRegMaybe (FloatReg 1#) = Just (RealReg REG_F1)
781 magicIdRegMaybe (FloatReg 2#) = Just (RealReg REG_F2)
784 magicIdRegMaybe (FloatReg 3#) = Just (RealReg REG_F3)
787 magicIdRegMaybe (FloatReg 4#) = Just (RealReg REG_F4)
790 magicIdRegMaybe (DoubleReg 1#) = Just (RealReg REG_D1)
793 magicIdRegMaybe (DoubleReg 2#) = Just (RealReg REG_D2)
796 magicIdRegMaybe Sp = Just (RealReg REG_Sp)
799 magicIdRegMaybe (LongReg _ ILIT(1)) = Just (RealReg REG_Lng1)
802 magicIdRegMaybe (LongReg _ ILIT(2)) = Just (RealReg REG_Lng2)
805 magicIdRegMaybe Su = Just (RealReg REG_Su)
808 magicIdRegMaybe SpLim = Just (RealReg REG_SpLim)
811 magicIdRegMaybe Hp = Just (RealReg REG_Hp)
814 magicIdRegMaybe HpLim = Just (RealReg REG_HpLim)
816 #ifdef REG_CurrentTSO
817 magicIdRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO)
819 #ifdef REG_CurrentNursery
820 magicIdRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery)
822 magicIdRegMaybe _ = Nothing
826 -------------------------------
827 -- allMachRegs is the complete set of machine regs.
828 allMachRegNos :: [Int]
830 = IF_ARCH_alpha( [0..63],
831 IF_ARCH_i386( [0..13],
832 IF_ARCH_sparc( ([0..31]
833 ++ [f0,f2 .. nCG_FirstFloatReg-1]
834 ++ [nCG_FirstFloatReg .. f31]),
836 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
837 -- i.e., these are the regs for which we are prepared to allow the
838 -- register allocator to attempt to map VRegs to.
839 allocatableRegs :: [Reg]
841 = let isFree i = isFastTrue (freeReg i)
842 in map RealReg (filter isFree allMachRegNos)
844 -------------------------------
845 -- these are the regs which we cannot assume stay alive over a
847 callClobberedRegs :: [Reg]
850 #if alpha_TARGET_ARCH
851 [0, 1, 2, 3, 4, 5, 6, 7, 8,
852 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
853 fReg 0, fReg 1, fReg 10, fReg 11, fReg 12, fReg 13, fReg 14, fReg 15,
854 fReg 16, fReg 17, fReg 18, fReg 19, fReg 20, fReg 21, fReg 22, fReg 23,
855 fReg 24, fReg 25, fReg 26, fReg 27, fReg 28, fReg 29, fReg 30]
856 #endif {- alpha_TARGET_ARCH -}
858 -- caller-saves registers
859 map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
860 #endif {- i386_TARGET_ARCH -}
861 #if sparc_TARGET_ARCH
864 [oReg i | i <- [0..5]] ++
865 [gReg i | i <- [1..7]] ++
866 [fReg i | i <- [0..31]] )
867 #endif {- sparc_TARGET_ARCH -}
869 -------------------------------
870 -- argRegs is the set of regs which are read for an n-argument call to C.
871 -- For archs which pass all args on the stack (x86), is empty.
872 -- Sparc passes up to the first 6 args in regs.
873 -- Dunno about Alpha.
874 argRegs :: Int -> [Reg]
877 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
880 #if alpha_TARGET_ARCH
882 argRegs 1 = freeMappedRegs [16, fReg 16]
883 argRegs 2 = freeMappedRegs [16, 17, fReg 16, fReg 17]
884 argRegs 3 = freeMappedRegs [16, 17, 18, fReg 16, fReg 17, fReg 18]
885 argRegs 4 = freeMappedRegs [16, 17, 18, 19, fReg 16, fReg 17, fReg 18, fReg 19]
886 argRegs 5 = freeMappedRegs [16, 17, 18, 19, 20, fReg 16, fReg 17, fReg 18, fReg 19, fReg 20]
887 argRegs 6 = freeMappedRegs [16, 17, 18, 19, 20, 21, fReg 16, fReg 17, fReg 18, fReg 19, fReg 20, fReg 21]
888 argRegs _ = panic "MachRegs.argRegs(alpha): don't know about >6 arguments!"
889 #endif {- alpha_TARGET_ARCH -}
891 #if sparc_TARGET_ARCH
893 argRegs 1 = map (RealReg . oReg) [0]
894 argRegs 2 = map (RealReg . oReg) [0,1]
895 argRegs 3 = map (RealReg . oReg) [0,1,2]
896 argRegs 4 = map (RealReg . oReg) [0,1,2,3]
897 argRegs 5 = map (RealReg . oReg) [0,1,2,3,4]
898 argRegs 6 = map (RealReg . oReg) [0,1,2,3,4,5]
899 argRegs _ = panic "MachRegs.argRegs(sparc): don't know about >6 arguments!"
900 #endif {- sparc_TARGET_ARCH -}
902 -------------------------------
903 -- all of the arg regs ??
904 #if alpha_TARGET_ARCH
905 allArgRegs :: [(Reg, Reg)]
906 allArgRegs = [(realReg i, realReg (fReg i)) | i <- [16..21]]
907 #endif {- alpha_TARGET_ARCH -}
909 #if sparc_TARGET_ARCH
911 allArgRegs = map RealReg [oReg i | i <- [0..5]]
912 #endif {- sparc_TARGET_ARCH -}
916 allArgRegs = panic "MachRegs.allArgRegs(x86): should not be used!"
921 freeReg :: Int -> FastBool
923 #if alpha_TARGET_ARCH
924 freeReg 26 = fastBool False -- return address (ra)
925 freeReg 28 = fastBool False -- reserved for the assembler (at)
926 freeReg 29 = fastBool False -- global pointer (gp)
927 freeReg 30 = fastBool False -- stack pointer (sp)
928 freeReg 31 = fastBool False -- always zero (zeroh)
929 freeReg 63 = fastBool False -- always zero (f31)
933 freeReg esp = fastBool False -- %esp is the C stack pointer
936 #if sparc_TARGET_ARCH
937 freeReg g0 = fastBool False -- %g0 is always 0.
938 freeReg g5 = fastBool False -- %g5 is reserved (ABI).
939 freeReg g6 = fastBool False -- %g6 is reserved (ABI).
940 freeReg g7 = fastBool False -- %g7 is reserved (ABI).
941 freeReg i6 = fastBool False -- %i6 is our frame pointer.
942 freeReg i7 = fastBool False -- %i7 tends to have ret-addr-ish things
943 freeReg o6 = fastBool False -- %o6 is our stack pointer.
944 freeReg o7 = fastBool False -- %o7 holds ret addrs (???)
945 freeReg f0 = fastBool False -- %f0/%f1 are the C fp return registers.
946 freeReg f1 = fastBool False
950 freeReg REG_Base = fastBool False
953 freeReg REG_R1 = fastBool False
956 freeReg REG_R2 = fastBool False
959 freeReg REG_R3 = fastBool False
962 freeReg REG_R4 = fastBool False
965 freeReg REG_R5 = fastBool False
968 freeReg REG_R6 = fastBool False
971 freeReg REG_R7 = fastBool False
974 freeReg REG_R8 = fastBool False
977 freeReg REG_F1 = fastBool False
980 freeReg REG_F2 = fastBool False
983 freeReg REG_F3 = fastBool False
986 freeReg REG_F4 = fastBool False
989 freeReg REG_D1 = fastBool False
992 freeReg REG_D2 = fastBool False
995 freeReg REG_Sp = fastBool False
998 freeReg REG_Su = fastBool False
1001 freeReg REG_SpLim = fastBool False
1004 freeReg REG_Hp = fastBool False
1007 freeReg REG_HpLim = fastBool False
1009 freeReg n = fastBool True