2 % (c) The AQUA Project, Glasgow University, 1994-1995
4 \section[I386Desc]{The I386 Machine Description}
7 #include "HsVersions.h"
12 -- and assorted nonsense referenced by the class methods
14 PprStyle, SMRep, MagicId, RegLoc, StixTree, PrimKind, SwitchResult
19 import AbsPrel ( PrimOp(..)
20 IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
21 IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
23 import AsmRegAlloc ( Reg, MachineCode(..), MachineRegisters(..),
24 RegLiveness(..), RegUsage(..), FutureLive(..)
26 import CLabelInfo ( CLabel )
27 import CmdLineOpts ( GlobalSwitch(..), stringSwitchSet, switchIsOn, SwitchResult(..) )
28 import HeapOffs ( hpRelToInt )
30 import Maybes ( Maybe(..) )
33 import PrimKind ( PrimKind(..) )
34 import SMRep ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
36 import I386Gen ( i386CodeGen )
46 Header sizes depend only on command-line options, not on the target
47 architecture. (I think.)
51 fhs :: (GlobalSwitch -> SwitchResult) -> Int
53 fhs switches = 1 + profFHS + ageFHS
55 profFHS = if switchIsOn switches SccProfilingOn then 1 else 0
56 ageFHS = if switchIsOn switches SccProfilingOn then 1 else 0
58 vhs :: (GlobalSwitch -> SwitchResult) -> SMRep -> Int
60 vhs switches sm = case sm of
62 SpecialisedRep _ _ _ _ -> 0
65 MuTupleRep _ -> 2 {- (1 + GC_MUT_RESERVED_WORDS) -}
69 PhantomRep -> panic "vhs:phantom"
73 Here we map STG registers onto appropriate Stix Trees. First, we
74 handle the two constants, @STK_STUB_closure@ and @vtbl_StdUpdFrame@.
75 The rest are either in real machine registers or stored as offsets
80 i386Reg :: (GlobalSwitch -> SwitchResult) -> MagicId -> RegLoc
84 Just reg -> Save nonReg
85 Nothing -> Always nonReg
86 where nonReg = case x of
87 StkStubReg -> sStLitLbl SLIT("STK_STUB_closure")
88 StdUpdRetVecReg -> sStLitLbl SLIT("vtbl_StdUpdFrame")
89 BaseReg -> sStLitLbl SLIT("MainRegTable")
90 --Hp -> StInd PtrKind (sStLitLbl SLIT("StorageMgrInfo"))
91 --HpLim -> StInd PtrKind (sStLitLbl SLIT("StorageMgrInfo+4"))
92 TagReg -> StInd IntKind (StPrim IntSubOp [infoptr, StInt (1*4)])
94 r2 = VanillaReg PtrKind ILIT(2)
95 infoptr = case i386Reg switches r2 of
97 Save _ -> StReg (StixMagicId r2)
98 _ -> StInd (kindFromMagicId x)
99 (StPrim IntAddOp [baseLoc, StInt (toInteger (offset*4))])
100 baseLoc = case stgRegMap BaseReg of
101 Just _ -> StReg (StixMagicId BaseReg)
102 Nothing -> sStLitLbl SLIT("MainRegTable")
103 offset = baseRegOffset x
111 size pk = case kindToSize pk of
112 {B -> 1; S -> 2; L -> 4; F -> 4; D -> 8 }
116 Now the volatile saves and restores. We add the basic guys to the list of ``user''
117 registers provided. Note that there are more basic registers on the restore list,
118 because some are reloaded from constants.
122 vsaves switches vols =
123 map save ((filter callerSaves) ([BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg{-,ActivityReg-}] ++ vols))
125 save x = StAssign (kindFromMagicId x) loc reg
126 where reg = StReg (StixMagicId x)
127 loc = case i386Reg switches x of
129 Always loc -> panic "vsaves"
131 vrests switches vols =
132 map restore ((filter callerSaves)
133 ([BaseReg,SpA,SuA,SpB,SuB,Hp,HpLim,RetReg{-,ActivityReg-},StkStubReg,StdUpdRetVecReg] ++ vols))
135 restore x = StAssign (kindFromMagicId x) reg loc
136 where reg = StReg (StixMagicId x)
137 loc = case i386Reg switches x of
139 Always loc -> panic "vrests"
143 Static closure sizes.
147 charLikeSize, intLikeSize :: Target -> Int
149 charLikeSize target =
150 size PtrKind * (fixedHeaderSize target + varHeaderSize target charLikeRep + 1)
151 where charLikeRep = SpecialisedRep CharLikeRep 0 1 SMNormalForm
154 size PtrKind * (fixedHeaderSize target + varHeaderSize target intLikeRep + 1)
155 where intLikeRep = SpecialisedRep IntLikeRep 0 1 SMNormalForm
157 mhs, dhs :: (GlobalSwitch -> SwitchResult) -> StixTree
159 mhs switches = StInt (toInteger words)
161 words = fhs switches + vhs switches (MuTupleRep 0)
163 dhs switches = StInt (toInteger words)
165 words = fhs switches + vhs switches (DataRep 0)
169 Setting up a i386 target.
173 -> (GlobalSwitch -> SwitchResult)
175 (PprStyle -> [[StixTree]] -> SUniqSM Unpretty), -- codeGen
177 (String -> String)) -- fmtAsmLbl
179 mkI386 decentOS switches =
180 let fhs' = fhs switches
182 i386Reg' = i386Reg switches
183 vsaves' = vsaves switches
184 vrests' = vrests switches
185 hprel = hpRelToInt target
186 as = amodeCode target
187 as' = amodeCode' target
188 csz = charLikeSize target
189 isz = intLikeSize target
192 ps = genPrimCode target
193 mc = genMacroCode target
194 hc = doHeapCheck --UNUSED NOW: target
195 target = mkTarget {-switches-} fhs' vhs' i386Reg' {-id-} size
197 (vsaves', vrests', csz, isz, mhs', dhs', ps, mc, hc)
198 {-i386CodeGen decentOS id-}
200 (target, i386CodeGen, decentOS, id)