Commit 6254fd4a authored by sewardj's avatar sewardj
Browse files

[project @ 2000-07-11 15:26:33 by sewardj]

Fix up the sparc native code generator.  Mostly dull stuff.  Notable
changes:

* Cleaned up ccall mechanism for sparc somewhat.

* Rearranged assignment of sparc floating point registers (includes/MachRegs.h)
  so the NCG's register allocator can handle the double-single pairing
  issue without modification.  Split VirtualRegF into VirtualRegF and
  VirtualRegD, and split RcFloating into RcFloat and RcDouble.  Net effect
  is that there are now three register classes -- int, float and double,
  and we pretend that sparc has some float and some double real regs.

* (A fix for all platforms): propagate MachFloats through as StFloats,
  not StDoubles.  Amazingly, until now literal floats had been converted
  to and treated as doubles, including in ccalls.
parent ee7aa7a6
......@@ -216,9 +216,16 @@ Here we handle top-level things, like @CCodeBlock@s and
= returnUs (\xs -> table ++ xs)
where
table = StData PtrRep [StCLbl (infoTableLabelFromCI cl_info)] :
map (\amode -> StData (getAmodeRep amode) [a2stix amode]) amodes ++
map do_one_amode amodes ++
[StData PtrRep (padding_wds ++ static_link)]
do_one_amode amode
= StData (promote_to_word (getAmodeRep amode)) [a2stix amode]
-- We need to promote any item smaller than a word to a word
promote_to_word CharRep = WordRep
promote_to_word other = other
-- always at least one padding word: this is the static link field
-- for the garbage collector.
padding_wds = if closureUpdReqd cl_info then
......
......@@ -95,7 +95,7 @@ nativeCodeGen absC us
insn_sdoc = my_vcat insn_sdocs
stix_sdoc = vcat stix_sdocs
# if NCG_DEBUG
# if 1 /* ifdef NCG_DEBUG */
my_trace m x = trace m x
my_vcat sds = vcat (intersperse (char ' '
$$ ptext SLIT("# ___ncg_debug_marker")
......
......@@ -59,11 +59,13 @@ runRegAllocate
-> [Instr]
runRegAllocate regs find_reserve_regs instrs
= case simpleAlloc of
= --trace ("runRegAllocate: " ++ show regs) (
case simpleAlloc of
Just simple -> --trace "SIMPLE"
simple
Nothing -> --trace "GENERAL"
(tryGeneral reserves)
--)
where
tryGeneral []
= error "nativeGen: spilling failed. Workaround: compile with -fvia-C.\n"
......@@ -137,7 +139,8 @@ doSimpleAlloc available_real_regs instrs
(i2:ris_done) is
where
isFloatingOrReal reg
= isRealReg reg || regClass reg == RcFloating
= isRealReg reg || regClass reg == RcFloat
|| regClass reg == RcDouble
rds_l = regSetToList rds
wrs_l = regSetToList wrs
......@@ -222,7 +225,7 @@ doGeneralAlloc all_regs reserve_regs instrs
++ " using "
++ showSDoc (hsep (map ppr reserve_regs))
# ifdef NCG_DEBUG
# if 1 /* ifdef DEBUG */
maybetrace msg x = trace msg x
# else
maybetrace msg x = x
......
......@@ -95,6 +95,7 @@ stmt2Instrs stmt = case stmt of
getData (StInt i) = returnNat (nilOL, ImmInteger i)
getData (StDouble d) = returnNat (nilOL, ImmDouble d)
getData (StFloat d) = returnNat (nilOL, ImmFloat d)
getData (StCLbl l) = returnNat (nilOL, ImmCLbl l)
getData (StString s) =
getNatLabelNCG `thenNat` \ lbl ->
......@@ -128,6 +129,7 @@ derefDLL tree
StInd pk addr -> StInd pk (qq addr)
StCall who cc pk args -> StCall who cc pk (map qq args)
StInt _ -> t
StFloat _ -> t
StDouble _ -> t
StString _ -> t
StReg _ -> t
......@@ -898,6 +900,19 @@ getRegister leaf
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if sparc_TARGET_ARCH
getRegister (StFloat d)
= getNatLabelNCG `thenNat` \ lbl ->
getNewRegNCG PtrRep `thenNat` \ tmp ->
let code dst = toOL [
SEGMENT DataSegment,
LABEL lbl,
DATA F [ImmFloat d],
SEGMENT TextSegment,
SETHI (HI (ImmCLbl lbl)) tmp,
LD F (AddrRegImm tmp (LO (ImmCLbl lbl))) dst]
in
returnNat (Any FloatRep code)
getRegister (StDouble d)
= getNatLabelNCG `thenNat` \ lbl ->
getNewRegNCG PtrRep `thenNat` \ tmp ->
......@@ -911,33 +926,42 @@ getRegister (StDouble d)
in
returnNat (Any DoubleRep code)
-- The 6-word scratch area is immediately below the frame pointer.
-- Below that is the spill area.
getRegister (StScratchWord i)
| i >= 0 && i < 6
= let j = i+1
code dst = unitOL (fpRelEA j dst)
in
returnNat (Any PtrRep code)
getRegister (StPrim primop [x]) -- unary PrimOps
= case primop of
IntNegOp -> trivialUCode (SUB False False g0) x
NotOp -> trivialUCode (XNOR False g0) x
FloatNegOp -> trivialUFCode FloatRep (FNEG F) x
IntNegOp -> trivialUCode (SUB False False g0) x
NotOp -> trivialUCode (XNOR False g0) x
DoubleNegOp -> trivialUFCode DoubleRep (FNEG DF) x
FloatNegOp -> trivialUFCode FloatRep (FNEG F) x
DoubleNegOp -> trivialUFCode DoubleRep (FNEG DF) x
Double2FloatOp -> trivialUFCode FloatRep (FxTOy DF F) x
Float2DoubleOp -> trivialUFCode DoubleRep (FxTOy F DF) x
OrdOp -> coerceIntCode IntRep x
ChrOp -> chrCode x
OrdOp -> coerceIntCode IntRep x
ChrOp -> chrCode x
Float2IntOp -> coerceFP2Int x
Int2FloatOp -> coerceInt2FP FloatRep x
Double2IntOp -> coerceFP2Int x
Int2DoubleOp -> coerceInt2FP DoubleRep x
Float2IntOp -> coerceFP2Int x
Int2FloatOp -> coerceInt2FP FloatRep x
Double2IntOp -> coerceFP2Int x
Int2DoubleOp -> coerceInt2FP DoubleRep x
other_op ->
let
fixed_x = if is_float_op -- promote to double
then StPrim Float2DoubleOp [x]
else x
fixed_x = if is_float_op -- promote to double
then StPrim Float2DoubleOp [x]
else x
in
getRegister (StCall fn cCallConv DoubleRep [x])
getRegister (StCall fn cCallConv DoubleRep [fixed_x])
where
(is_float_op, fn)
= case primop of
......@@ -959,7 +983,7 @@ getRegister (StPrim primop [x]) -- unary PrimOps
DoubleExpOp -> (False, SLIT("exp"))
DoubleLogOp -> (False, SLIT("log"))
DoubleSqrtOp -> (True, SLIT("sqrt"))
DoubleSqrtOp -> (False, SLIT("sqrt"))
DoubleSinOp -> (False, SLIT("sin"))
DoubleCosOp -> (False, SLIT("cos"))
......@@ -972,7 +996,10 @@ getRegister (StPrim primop [x]) -- unary PrimOps
DoubleSinhOp -> (False, SLIT("sinh"))
DoubleCoshOp -> (False, SLIT("cosh"))
DoubleTanhOp -> (False, SLIT("tanh"))
_ -> panic ("Monadic PrimOp not handled: " ++ show primop)
other
-> pprPanic "getRegister(sparc,monadicprimop)"
(pprStixTree (StPrim primop [x]))
getRegister (StPrim primop [x, y]) -- dyadic PrimOps
= case primop of
......@@ -1046,10 +1073,16 @@ getRegister (StPrim primop [x, y]) -- dyadic PrimOps
ISraOp -> trivialCode SRA x y --was: panic "SparcGen:isra"
ISrlOp -> trivialCode SRL x y --was: panic "SparcGen:isrl"
FloatPowerOp -> getRegister (StCall SLIT("pow") cCallConv DoubleRep [promote x, promote y])
FloatPowerOp -> getRegister (StCall SLIT("pow") cCallConv DoubleRep
[promote x, promote y])
where promote x = StPrim Float2DoubleOp [x]
DoublePowerOp -> getRegister (StCall SLIT("pow") cCallConv DoubleRep [x, y])
-- _ -> panic "Prim op " ++ (showPrimOp primop) ++ " not handled!"
DoublePowerOp -> getRegister (StCall SLIT("pow") cCallConv DoubleRep
[x, y])
other
-> pprPanic "getRegister(sparc,dyadic primop)"
(pprStixTree (StPrim primop [x, y]))
where
imul_div fn x y = getRegister (StCall fn cCallConv IntRep [x, y])
......@@ -1079,6 +1112,8 @@ getRegister leaf
OR False dst (RIImm (LO imm__2)) dst]
in
returnNat (Any PtrRep code)
| otherwise
= pprPanic "getRegister(sparc)" (pprStixTree leaf)
where
imm = maybeImm leaf
imm__2 = case imm of Just x -> x
......@@ -2394,21 +2429,27 @@ genCCall fn cconv kind args
#endif {- i386_TARGET_ARCH -}
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if sparc_TARGET_ARCH
-- Implement this! It should be im MachRegs.lhs, not here.
allArgRegs :: [Reg]
allArgRegs = error "nativeGen(sparc): allArgRegs"
genCCall fn cconv kind args
= mapAccumLNat get_arg (allArgRegs, eXTRA_STK_ARGS_HERE) args
`thenNat` \ ((unused,_), argCode) ->
let
nRegs = length allArgRegs - length unused
call = CALL fn__2 nRegs False
call = unitOL (CALL fn__2 nRegs False)
code = concatOL argCode
in
returnNat (code `snocOL` call `snocOL` NOP)
-- 3 because in the worst case, %o0 .. %o5 will only use up 3 args
(move_sp_down, move_sp_up)
= let nn = length args - 3
in if nn <= 0
then (nilOL, nilOL)
else (unitOL (moveSp (-(2*nn))), unitOL (moveSp (2*nn)))
in
returnNat (move_sp_down `appOL`
code `appOL`
call `appOL`
unitOL NOP `appOL`
move_sp_up)
where
-- function names that begin with '.' are assumed to be special
-- internally generated names like '.mul,' which don't get an
......@@ -2429,6 +2470,9 @@ genCCall fn cconv kind args
offset to use for overflowing arguments. This way,
@get_arg@ can be applied to all of a call's arguments using
@mapAccumL@.
If we have to put args on the stack, move %o6==%sp down by
8 x the number of args, to ensure there's enough space.
-}
get_arg
:: ([Reg],Int) -- Argument registers and stack offset (accumulator)
......@@ -2453,23 +2497,27 @@ genCCall fn cconv kind args
case dsts of
[] -> ( ([], offset + 1),
code `snocOL`
-- conveniently put the second part in the right stack
-- location, and load the first part into %o5
ST DF src (spRel (offset - 1)) `snocOL`
LD W (spRel (offset - 1)) dst
-- put the second part in the right stack
-- and load the first part into %o5
FMOV DF src f0 `snocOL`
ST F f0 (spRel offset) `snocOL`
LD W (spRel offset) dst `snocOL`
ST F (fPair f0) (spRel offset)
)
(dst__2:dsts__2)
-> ( (dsts__2, offset),
code `snocOL`
ST DF src (spRel (-2)) `snocOL`
LD W (spRel (-2)) dst `snocOL`
LD W (spRel (-1)) dst__2
code `snocOL`
FMOV DF src f0 `snocOL`
ST F f0 (spRel 16) `snocOL`
LD W (spRel 16) dst `snocOL`
ST F (fPair f0) (spRel 16) `snocOL`
LD W (spRel 16) dst__2
)
FloatRep
-> ( (dsts, offset),
code `snocOL`
ST F src (spRel (-2)) `snocOL`
LD W (spRel (-2)) dst
ST F src (spRel 16) `snocOL`
LD W (spRel 16) dst
)
_ -> ( (dsts, offset),
if isFixed register
......
......@@ -31,7 +31,7 @@ module MachMisc (
#if i386_TARGET_ARCH
#endif
#if sparc_TARGET_ARCH
RI(..), riZero
RI(..), riZero, fpRelEA, moveSp, fPair
#endif
) where
......@@ -45,6 +45,9 @@ import Literal ( mkMachInt, Literal(..) )
import MachRegs ( stgReg, callerSaves, RegLoc(..),
Imm(..), Reg(..),
MachRegsAddr(..)
# if sparc_TARGET_ARCH
,fp, sp
# endif
)
import PrimRep ( PrimRep(..) )
import SMRep ( SMRep(..) )
......@@ -52,7 +55,7 @@ import Stix ( StixTree(..), StixReg(..), CodeSegment )
import Panic ( panic )
import Char ( isDigit )
import GlaExts ( word2Int#, int2Word#, shiftRL#, and#, (/=#) )
import Outputable ( text )
import Outputable ( text, pprPanic, ppr )
import IOExts ( trace )
\end{code}
......@@ -639,5 +642,21 @@ riZero (RIImm (ImmInteger 0)) = True
riZero (RIReg (RealReg 0)) = True
riZero _ = False
-- Calculate the effective address which would be used by the
-- corresponding fpRel sequence. fpRel is in MachRegs.lhs,
-- alas -- can't have fpRelEA here because of module dependencies.
fpRelEA :: Int -> Reg -> Instr
fpRelEA n dst
= ADD False False fp (RIImm (ImmInt (n * BYTES_PER_WORD))) dst
-- Code to shift the stack pointer by n words.
moveSp :: Int -> Instr
moveSp n
= ADD False False sp (RIImm (ImmInt (n * BYTES_PER_WORD))) sp
-- Produce the second-half-of-a-double register given the first half.
fPair :: Reg -> Reg
fPair (RealReg n) | n >= 32 && n `mod` 2 == 0 = RealReg (n+1)
fPair other = pprPanic "fPair(sparc NCG)" (ppr other)
#endif {- sparc_TARGET_ARCH -}
\end{code}
......@@ -16,7 +16,7 @@ module MachRegs (
RegClass(..), regClass,
Reg(..), isRealReg, isVirtualReg,
allocatableRegs,
allocatableRegs, argRegs, allArgRegs, callClobberedRegs,
Imm(..),
MachRegsAddr(..),
......@@ -47,7 +47,7 @@ module MachRegs (
#if sparc_TARGET_ARCH
, fits13Bits
, fpRel, gReg, iReg, lReg, oReg, largeOffsetError
, fp, g0, o0, f0
, fp, sp, g0, g1, g2, o0, f0, f6, f8, f26, f27
#endif
) where
......@@ -76,6 +76,7 @@ data Imm
-- Bool==True ==> in a different DLL
| ImmLit SDoc -- Simple string
| ImmIndex CLabel Int
| ImmFloat Rational
| ImmDouble Rational
IF_ARCH_sparc(
| LO Imm -- Possible restrictions...
......@@ -150,13 +151,8 @@ fits8Bits i = i >= -256 && i < 256
#endif
#if sparc_TARGET_ARCH
{-# SPECIALIZE
fits13Bits :: Int -> Bool
#-}
{-# SPECIALIZE
fits13Bits :: Integer -> Bool
#-}
{-# SPECIALIZE fits13Bits :: Int -> Bool, Integer -> Bool #-}
fits13Bits :: Integral a => a -> Bool
fits13Bits x = x >= -4096 && x < 4096
......@@ -261,50 +257,74 @@ Virtual regs can be of either class, so that info is attached.
data RegClass
= RcInteger
| RcFloating
| RcFloat
| RcDouble
deriving Eq
data Reg
= RealReg Int
| VirtualRegI Unique
| VirtualRegF Unique
| VirtualRegD Unique
unRealReg (RealReg i) = i
unRealReg vreg = pprPanic "unRealReg on VirtualReg" (ppr vreg)
mkVReg :: Unique -> PrimRep -> Reg
mkVReg u pk
= if isFloatingRep pk then VirtualRegF u else VirtualRegI u
#if sparc_TARGET_ARCH
= case pk of
FloatRep -> VirtualRegF u
DoubleRep -> VirtualRegD u
other -> VirtualRegI u
#else
= if isFloatingRep pk then VirtualRegD u else VirtualRegI u
#endif
isVirtualReg (RealReg _) = False
isVirtualReg (VirtualRegI _) = True
isVirtualReg (VirtualRegF _) = True
isVirtualReg (VirtualRegD _) = True
isRealReg = not . isVirtualReg
getNewRegNCG :: PrimRep -> NatM Reg
getNewRegNCG pk
= if isFloatingRep pk
then getUniqueNat `thenNat` \ u -> returnNat (VirtualRegF u)
else getUniqueNat `thenNat` \ u -> returnNat (VirtualRegI u)
= getUniqueNat `thenNat` \ u -> returnNat (mkVReg u pk)
instance Eq Reg where
(==) (RealReg i1) (RealReg i2) = i1 == i2
(==) (VirtualRegI u1) (VirtualRegI u2) = u1 == u2
(==) (VirtualRegF u1) (VirtualRegF u2) = u1 == u2
(==) (VirtualRegD u1) (VirtualRegD u2) = u1 == u2
(==) reg1 reg2 = False
instance Ord Reg where
compare (RealReg i1) (RealReg i2) = compare i1 i2
compare (RealReg _) (VirtualRegI _) = LT
compare (RealReg _) (VirtualRegF _) = LT
compare (RealReg _) (VirtualRegD _) = LT
compare (VirtualRegI _) (RealReg _) = GT
compare (VirtualRegI u1) (VirtualRegI u2) = compare u1 u2
compare (VirtualRegI _) (VirtualRegF _) = LT
compare (VirtualRegI _) (VirtualRegD _) = LT
compare (VirtualRegF _) (RealReg _) = GT
compare (VirtualRegF _) (VirtualRegI _) = GT
compare (VirtualRegF u1) (VirtualRegF u2) = compare u1 u2
compare (VirtualRegF _) (VirtualRegD _) = LT
compare (VirtualRegD _) (RealReg _) = GT
compare (VirtualRegD _) (VirtualRegI _) = GT
compare (VirtualRegD _) (VirtualRegF _) = GT
compare (VirtualRegD u1) (VirtualRegD u2) = compare u1 u2
instance Show Reg where
showsPrec _ (RealReg i) = showString (showReg i)
showsPrec _ (VirtualRegI u) = showString "%vI_" . shows u
showsPrec _ (VirtualRegF u) = showString "%vF_" . shows u
showsPrec _ (VirtualRegD u) = showString "%vD_" . shows u
instance Outputable Reg where
ppr r = text (show r)
......@@ -313,6 +333,7 @@ instance Uniquable Reg where
getUnique (RealReg i) = mkPseudoUnique2 i
getUnique (VirtualRegI u) = u
getUnique (VirtualRegF u) = u
getUnique (VirtualRegD u) = u
\end{code}
** Machine-specific Reg stuff: **
......@@ -371,9 +392,10 @@ fake3 = RealReg 11
fake4 = RealReg 12
fake5 = RealReg 13
regClass (RealReg i) = if i < 8 then RcInteger else RcFloating
regClass (RealReg i) = if i < 8 then RcInteger else RcDouble
regClass (VirtualRegI u) = RcInteger
regClass (VirtualRegF u) = RcFloating
regClass (VirtualRegF u) = RcFloat
regClass (VirtualRegD u) = RcDouble
regNames
= ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
......@@ -391,9 +413,11 @@ showReg n
The SPARC has 64 registers of interest; 32 integer registers and 32
floating point registers. The mapping of STG registers to SPARC
machine registers is defined in StgRegs.h. We are, of course,
prepared for any eventuality. When (if?) the sparc nativegen is
ever revived, we should just treat it as if it has 16 floating
regs, and use them in pairs.
prepared for any eventuality.
The whole fp-register pairing thing on sparcs is a huge nuisance. See
fptools/ghc/includes/MachRegs.h for a description of what's going on
here.
\begin{code}
#if sparc_TARGET_ARCH
......@@ -405,24 +429,45 @@ lReg x = (16 + x)
iReg x = (24 + x)
fReg x = (32 + x)
-- CHECK THIS
regClass (RealReg i) = if i < 32 then RcInteger else RcFloating
nCG_FirstFloatReg :: Int
nCG_FirstFloatReg = unRealReg NCG_FirstFloatReg
regClass (VirtualRegI u) = RcInteger
regClass (VirtualRegF u) = RcFloating
regClass (VirtualRegF u) = RcFloat
regClass (VirtualRegD u) = RcDouble
regClass (RealReg i) | i < 32 = RcInteger
| i < nCG_FirstFloatReg = RcDouble
| otherwise = RcFloat
-- FIX THIS
showReg :: Int -> String
showReg n
= if n >= 0 && n < 64
then "%sparc_real_reg_" ++ show n
else "%unknown_sparc_real_reg_" ++ show n
| n >= 0 && n < 8 = "%g" ++ show n
| n >= 8 && n < 16 = "%o" ++ show (n-8)
| n >= 16 && n < 24 = "%l" ++ show (n-16)
| n >= 24 && n < 32 = "%i" ++ show (n-24)
| n >= 32 && n < 64 = "%f" ++ show (n-32)
| otherwise = "%unknown_sparc_real_reg_" ++ show n
g0, g1, g2, fp, sp, o0, f0, f1, f6, f8, f22, f26, f27 :: Reg
f6 = RealReg (fReg 6)
f8 = RealReg (fReg 8)
f22 = RealReg (fReg 22)
f26 = RealReg (fReg 26)
f27 = RealReg (fReg 27)
g0, fp, sp, o0, f0 :: Reg
g0 = RealReg (gReg 0)
fp = RealReg (iReg 6)
sp = RealReg (oReg 6)
o0 = RealReg (oReg 0)
f0 = RealReg (fReg 0)
-- g0 is useful for codegen; is always zero, and writes to it vanish.
g0 = RealReg (gReg 0)
g1 = RealReg (gReg 1)
g2 = RealReg (gReg 2)
-- FP, SP, int and float return (from C) regs.
fp = RealReg (iReg 6)
sp = RealReg (oReg 6)
o0 = RealReg (oReg 0)
f0 = RealReg (fReg 0)
f1 = RealReg (fReg 1)
#endif
\end{code}
......@@ -513,16 +558,17 @@ names in the header files. Gag me with a spoon, eh?
#define i5 29
#define i6 30
#define i7 31
#define f0 32
#define f1 33
#define f2 34
#define f3 35
#define f4 36
#define f5 37
#define f6 38
#define f7 39
#define f8 40
#define f9 41
#define f0 32
#define f1 33
#define f2 34
#define f3 35
#define f4 36
#define f5 37
#define f6 38
#define f7 39
#define f8 40
#define f9 41
#define f10 42
#define f11 43
#define f12 44
......@@ -545,6 +591,7 @@ names in the header files. Gag me with a spoon, eh?
#define f29 61
#define f30 62
#define f31 63
#endif
\end{code}
......@@ -748,19 +795,15 @@ magicIdRegMaybe _ = Nothing
\begin{code}
-------------------------------
#if 0
freeRegs :: [Reg]
freeRegs
= freeMappedRegs IF_ARCH_alpha( [0..63],
IF_ARCH_i386( [0..13],
IF_ARCH_sparc( [0..63],)))
#endif
-- allMachRegs is the complete set of machine regs.
allMachRegNos :: [Int]
allMachRegNos
= IF_ARCH_alpha( [0..63],
IF_ARCH_i386( [0..13],
IF_ARCH_sparc( [0..63],)))
IF_ARCH_sparc( ([0..31]
++ [f0,f2 .. nCG_FirstFloatReg-1]
++ [nCG_FirstFloatReg .. f31]),
)))
-- allocatableRegs is allMachRegNos with the fixed-use regs removed.
allocatableRegs :: [Reg]
allocatableRegs
......@@ -769,10 +812,9 @@ allocatableRegs
-------------------------------
#if 0
callClobberedRegs :: [Reg]
callClobberedRegs
= freeMappedRegs
=
#if alpha_TARGET_ARCH
[0, 1, 2, 3, 4, 5, 6, 7, 8,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
......@@ -781,58 +823,67 @@ callClobberedRegs
fReg 24, fReg 25, fReg 26, fReg 27, fReg 28, fReg 29, fReg 30]
#endif {- alpha_TARGET_ARCH -}
#if i386_TARGET_ARCH
[{-none-}]
-- caller-saves registers
[eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
#endif {- i386_TARGET_ARCH -}
#if sparc_TARGET_ARCH
( oReg 7 :
[oReg i | i <- [0..5]] ++
[gReg i | i <- [1..7]] ++
[fReg i | i <- [0..31]] )
map RealReg
( oReg 7 :
[oReg i | i <- [0..5]] ++
[gReg i | i <- [1..7]] ++
[fReg i | i <- [0..31]] )
#endif {- sparc_TARGET_ARCH -}
#endif
-------------------------------
#if 0
-- argRegs is the set of regs which are read for an n-argument call to C.
-- For archs which pass all args on the stack (x86), is empty.
-- Sparc passes up to the first 6 args in regs.
-- Dunno about Alpha.
argRegs :: Int -> [Reg]
argRegs 0 = []
#if i386_TARGET_ARCH
argRegs _ = panic "MachRegs.argRegs: doesn't work on I386"