diff options
author | Ben.Lippmeier@anu.edu.au <unknown> | 2009-02-15 05:51:58 +0000 |
---|---|---|
committer | Ben.Lippmeier@anu.edu.au <unknown> | 2009-02-15 05:51:58 +0000 |
commit | b04a210e26ca57242fd052f2aa91011a80b76299 (patch) | |
tree | 6f26993cc3ef37f4555087bd80da4195edcda4ed /compiler/nativeGen/PPC/Regs.hs | |
parent | 77ed23d51b968505b3ad8541c075657ae94f0ea3 (diff) | |
download | haskell-b04a210e26ca57242fd052f2aa91011a80b76299.tar.gz |
NCG: Split up the native code generator into arch specific modules
- nativeGen/Instruction defines a type class for a generic
instruction set. Each of the instruction sets we have,
X86, PPC and SPARC are instances of it.
- The register alloctors use this type class when they need
info about a certain register or instruction, such as
regUsage, mkSpillInstr, mkJumpInstr, patchRegs..
- nativeGen/Platform defines some data types enumerating
the architectures and operating systems supported by the
native code generator.
- DynFlags now keeps track of the current build platform, and
the PositionIndependentCode module uses this to decide what
to do instead of relying of #ifdefs.
- It's not totally retargetable yet. Some info info about the
build target is still hardwired, but I've tried to contain
most of it to a single module, TargetRegs.
- Moved the SPILL and RELOAD instructions into LiveInstr.
- Reg and RegClass now have their own modules, and are shared
across all architectures.
Diffstat (limited to 'compiler/nativeGen/PPC/Regs.hs')
-rw-r--r-- | compiler/nativeGen/PPC/Regs.hs | 102 |
1 files changed, 31 insertions, 71 deletions
diff --git a/compiler/nativeGen/PPC/Regs.hs b/compiler/nativeGen/PPC/Regs.hs index d6993b210b..80c68dd096 100644 --- a/compiler/nativeGen/PPC/Regs.hs +++ b/compiler/nativeGen/PPC/Regs.hs @@ -5,16 +5,6 @@ -- ----------------------------------------------------------------------------- module PPC.Regs ( - -- sizes - Size(..), - intSize, - floatSize, - isFloatSize, - wordSize, - cmmTypeSize, - sizeToWidth, - mkVReg, - -- immediates Imm(..), strImmLit, @@ -42,7 +32,10 @@ module PPC.Regs ( -- horrow show freeReg, - globalRegMaybe + globalRegMaybe, + get_GlobalReg_reg_or_addr, + allocatableRegs + ) where @@ -51,78 +44,22 @@ where #include "HsVersions.h" #include "../includes/MachRegs.h" -import RegsBase +import Reg +import RegClass +import CgUtils ( get_GlobalReg_addr ) import BlockId import Cmm import CLabel ( CLabel ) import Pretty import Outputable ( Outputable(..), pprPanic, panic ) import qualified Outputable -import Unique import Constants import FastBool import Data.Word ( Word8, Word16, Word32 ) import Data.Int ( Int8, Int16, Int32 ) --- sizes ----------------------------------------------------------------------- --- For these three, the "size" also gives the int/float --- distinction, because the instructions for int/float --- differ only in their suffices -data Size - = II8 | II16 | II32 | II64 | FF32 | FF64 | FF80 - deriving Eq - -intSize, floatSize :: Width -> Size -intSize W8 = II8 -intSize W16 = II16 -intSize W32 = II32 -intSize W64 = II64 -intSize other = pprPanic "MachInstrs.intSize" (ppr other) - -floatSize W32 = FF32 -floatSize W64 = FF64 -floatSize other = pprPanic "MachInstrs.intSize" (ppr other) - - -isFloatSize :: Size -> Bool -isFloatSize FF32 = True -isFloatSize FF64 = True -isFloatSize FF80 = True -isFloatSize _ = False - - -wordSize :: Size -wordSize = intSize wordWidth - - -cmmTypeSize :: CmmType -> Size -cmmTypeSize ty - | isFloatType ty = floatSize (typeWidth ty) - | otherwise = intSize (typeWidth ty) - - -sizeToWidth :: Size -> Width -sizeToWidth II8 = W8 -sizeToWidth II16 = W16 -sizeToWidth II32 = W32 -sizeToWidth II64 = W64 -sizeToWidth FF32 = W32 -sizeToWidth FF64 = W64 -sizeToWidth _ = panic "MachInstrs.sizeToWidth" - - -mkVReg :: Unique -> Size -> Reg -mkVReg u size - | not (isFloatSize size) = VirtualRegI u - | otherwise - = case size of - FF32 -> VirtualRegD u - FF64 -> VirtualRegD u - _ -> panic "mkVReg" - - -- immediates ------------------------------------------------------------------ data Imm @@ -490,7 +427,7 @@ freeReg REG_Hp = fastBool False #ifdef REG_HpLim freeReg REG_HpLim = fastBool False #endif -freeReg n = fastBool True +freeReg _ = fastBool True -- | Returns 'Nothing' if this global register is not stored @@ -582,3 +519,26 @@ freeReg _ = 0# globalRegMaybe _ = panic "PPC.Regs.globalRegMaybe: not defined" #endif /* powerpc_TARGET_ARCH */ + + +-- 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) + + +-- 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 |