--- TODO: Not sure about these BL 2009/01/10
--- Used for NCG spill tmps? what is this?
-
-{-
-freeReg g1 = fastBool False -- %g1 is used for NCG spill tmp
-freeReg g2 = fastBool False
-freeReg f6 = fastBool False
-freeReg f8 = fastBool False
-freeReg f26 = fastBool False
-freeReg f27 = fastBool False
--}
-
-#ifdef REG_Base
-freeReg REG_Base = fastBool False
-#endif
-#ifdef REG_R1
-freeReg REG_R1 = fastBool False
-#endif
-#ifdef REG_R2
-freeReg REG_R2 = fastBool False
-#endif
-#ifdef REG_R3
-freeReg REG_R3 = fastBool False
-#endif
-#ifdef REG_R4
-freeReg REG_R4 = fastBool False
-#endif
-#ifdef REG_R5
-freeReg REG_R5 = fastBool False
-#endif
-#ifdef REG_R6
-freeReg REG_R6 = fastBool False
-#endif
-#ifdef REG_R7
-freeReg REG_R7 = fastBool False
-#endif
-#ifdef REG_R8
-freeReg REG_R8 = fastBool False
-#endif
-#ifdef REG_F1
-freeReg REG_F1 = fastBool False
-#endif
-#ifdef REG_F2
-freeReg REG_F2 = fastBool False
-#endif
-#ifdef REG_F3
-freeReg REG_F3 = fastBool False
-#endif
-#ifdef REG_F4
-freeReg REG_F4 = fastBool False
-#endif
-#ifdef REG_D1
-freeReg REG_D1 = fastBool False
-#endif
-#ifdef REG_D2
-freeReg REG_D2 = fastBool False
-#endif
-#ifdef REG_Sp
-freeReg REG_Sp = fastBool False
-#endif
-#ifdef REG_Su
-freeReg REG_Su = fastBool False
-#endif
-#ifdef REG_SpLim
-freeReg REG_SpLim = fastBool False
-#endif
-#ifdef REG_Hp
-freeReg REG_Hp = fastBool False
-#endif
-#ifdef REG_HpLim
-freeReg REG_HpLim = fastBool False
-#endif
-freeReg _ = fastBool True
-
-
-
--- | Returns 'Nothing' if this global register is not stored
--- in a real machine register, otherwise returns @'Just' reg@, where
--- reg is the machine register it is stored in.
-
-globalRegMaybe :: GlobalReg -> Maybe Reg
-
-#ifdef REG_Base
-globalRegMaybe BaseReg = Just (RealReg REG_Base)
-#endif
-#ifdef REG_R1
-globalRegMaybe (VanillaReg 1 _) = Just (RealReg REG_R1)
-#endif
-#ifdef REG_R2
-globalRegMaybe (VanillaReg 2 _) = Just (RealReg REG_R2)
-#endif
-#ifdef REG_R3
-globalRegMaybe (VanillaReg 3 _) = Just (RealReg REG_R3)
-#endif
-#ifdef REG_R4
-globalRegMaybe (VanillaReg 4 _) = Just (RealReg REG_R4)
-#endif
-#ifdef REG_R5
-globalRegMaybe (VanillaReg 5 _) = Just (RealReg REG_R5)
-#endif
-#ifdef REG_R6
-globalRegMaybe (VanillaReg 6 _) = Just (RealReg REG_R6)
-#endif
-#ifdef REG_R7
-globalRegMaybe (VanillaReg 7 _) = Just (RealReg REG_R7)
-#endif
-#ifdef REG_R8
-globalRegMaybe (VanillaReg 8 _) = Just (RealReg REG_R8)
-#endif
-#ifdef REG_R9
-globalRegMaybe (VanillaReg 9 _) = Just (RealReg REG_R9)
-#endif
-#ifdef REG_R10
-globalRegMaybe (VanillaReg 10 _) = Just (RealReg REG_R10)
-#endif
-#ifdef REG_F1
-globalRegMaybe (FloatReg 1) = Just (RealReg REG_F1)
-#endif
-#ifdef REG_F2
-globalRegMaybe (FloatReg 2) = Just (RealReg REG_F2)
-#endif
-#ifdef REG_F3
-globalRegMaybe (FloatReg 3) = Just (RealReg REG_F3)
-#endif
-#ifdef REG_F4
-globalRegMaybe (FloatReg 4) = Just (RealReg REG_F4)
-#endif
-#ifdef REG_D1
-globalRegMaybe (DoubleReg 1) = Just (RealReg REG_D1)
-#endif
-#ifdef REG_D2
-globalRegMaybe (DoubleReg 2) = Just (RealReg REG_D2)
-#endif
-#ifdef REG_Sp
-globalRegMaybe Sp = Just (RealReg REG_Sp)
-#endif
-#ifdef REG_Lng1
-globalRegMaybe (LongReg 1) = Just (RealReg REG_Lng1)
-#endif
-#ifdef REG_Lng2
-globalRegMaybe (LongReg 2) = Just (RealReg REG_Lng2)
-#endif
-#ifdef REG_SpLim
-globalRegMaybe SpLim = Just (RealReg REG_SpLim)
-#endif
-#ifdef REG_Hp
-globalRegMaybe Hp = Just (RealReg REG_Hp)
-#endif
-#ifdef REG_HpLim
-globalRegMaybe HpLim = Just (RealReg REG_HpLim)
-#endif
-#ifdef REG_CurrentTSO
-globalRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO)
-#endif
-#ifdef REG_CurrentNursery
-globalRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery)
-#endif
-globalRegMaybe _ = Nothing
+-- | Check whether a machine register is free for allocation.
+-- This needs to match the info in includes/MachRegs.h otherwise modules
+-- compiled with the NCG won't be compatible with via-C ones.
+--
+freeReg :: RegNo -> FastBool
+freeReg regno
+ = case regno of
+ -- %g0(r0) is always 0.
+ 0 -> fastBool False
+
+ -- %g1(r1) - %g4(r4) are allocable -----------------
+
+ -- %g5(r5) - %g7(r7)
+ -- are reserved for the OS
+ 5 -> fastBool False
+ 6 -> fastBool False
+ 7 -> fastBool False
+
+ -- %o0(r8) - %o5(r13) are allocable ----------------
+
+ -- %o6(r14)
+ -- is the C stack pointer
+ 14 -> fastBool False
+
+ -- %o7(r15)
+ -- holds C return addresses (???)
+ 15 -> fastBool False
+
+ -- %l0(r16) is allocable ---------------------------
+
+ -- %l1(r17) - %l5(r21)
+ -- are STG regs R1 - R5
+ 17 -> fastBool False
+ 18 -> fastBool False
+ 19 -> fastBool False
+ 20 -> fastBool False
+ 21 -> fastBool False
+
+ -- %l6(r22) - %l7(r23) are allocable --------------
+
+ -- %i0(r24) - %i5(r29)
+ -- are STG regs Sp, Base, SpLim, Hp, HpLim, R6
+ 24 -> fastBool False
+ 25 -> fastBool False
+ 26 -> fastBool False
+ 27 -> fastBool False
+ 28 -> fastBool False
+ 29 -> fastBool False
+
+ -- %i6(r30)
+ -- is the C frame pointer
+ 30 -> fastBool False
+
+ -- %i7(r31)
+ -- is used for C return addresses
+ 31 -> fastBool False
+
+ -- %f0(r32) - %f1(r33)
+ -- are C fp return registers
+ 32 -> fastBool False
+ 33 -> fastBool False
+
+ -- %f2(r34) - %f5(r37)
+ -- are STG regs D1 - D2
+ 34 -> fastBool False
+ 35 -> fastBool False
+ 36 -> fastBool False
+ 37 -> fastBool False
+
+ -- %f22(r54) - %f25(r57)
+ -- are STG regs F1 - F4
+ 54 -> fastBool False
+ 55 -> fastBool False
+ 56 -> fastBool False
+ 57 -> fastBool False
+
+ -- regs not matched above are allocable.
+ _ -> fastBool True
+
+
+-- allocatableRegs is allMachRegNos with the fixed-use regs removed.
+-- i.e., these are the regs for which we are prepared to allow the
+-- register allocator to attempt to map VRegs to.
+allocatableRegs :: [RegNo]
+allocatableRegs
+ = let isFree i = isFastTrue (freeReg i)
+ in filter isFree allMachRegNos
+
+
+-- | Returns Just the real register that a global register is stored in.
+-- Returns Nothing if the global has no real register, and is stored
+-- in the in-memory register table instead.
+--
+globalRegMaybe :: GlobalReg -> Maybe Reg
+globalRegMaybe gg
+ = case gg of
+ -- Argument and return regs
+ VanillaReg 1 _ -> Just (RealReg 17) -- %l1
+ VanillaReg 2 _ -> Just (RealReg 18) -- %l2
+ VanillaReg 3 _ -> Just (RealReg 19) -- %l3
+ VanillaReg 4 _ -> Just (RealReg 20) -- %l4
+ VanillaReg 5 _ -> Just (RealReg 21) -- %l5
+ VanillaReg 6 _ -> Just (RealReg 29) -- %i5
+
+ FloatReg 1 -> Just (RealReg 54) -- %f22
+ FloatReg 2 -> Just (RealReg 55) -- %f23
+ FloatReg 3 -> Just (RealReg 56) -- %f24
+ FloatReg 4 -> Just (RealReg 57) -- %f25
+
+ DoubleReg 1 -> Just (RealReg 34) -- %f2
+ DoubleReg 2 -> Just (RealReg 36) -- %f4
+
+ -- STG Regs
+ Sp -> Just (RealReg 24) -- %i0
+ SpLim -> Just (RealReg 26) -- %i2
+ Hp -> Just (RealReg 27) -- %i3
+ HpLim -> Just (RealReg 28) -- %i4
+
+ BaseReg -> Just (RealReg 25) -- %i1
+
+ _ -> Nothing
+
+
+-- We map STG registers onto appropriate CmmExprs. Either they map
+-- to real machine registers or stored as offsets from BaseReg. Given
+-- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
+-- register it is in, on this platform, or a CmmExpr denoting the
+-- address in the register table holding it.
+-- (See also get_GlobalReg_addr in CgUtils.)
+
+get_GlobalReg_reg_or_addr :: GlobalReg -> Either Reg CmmExpr
+get_GlobalReg_reg_or_addr mid
+ = case globalRegMaybe mid of
+ Just rr -> Left rr
+ Nothing -> Right (get_GlobalReg_addr mid)