Add new LLVM code generator to GHC. (Version 2)
[ghc-hetmet.git] / compiler / nativeGen / SPARC / CodeGen / Base.hs
1
2 module SPARC.CodeGen.Base (
3         InstrBlock,
4         CondCode(..),
5         ChildCode64(..),
6         Amode(..),
7
8         Register(..),
9         setSizeOfRegister,
10         
11         getRegisterReg,
12         mangleIndexTree
13 )
14
15 where
16
17 import SPARC.Instr
18 import SPARC.Cond
19 import SPARC.AddrMode
20 import SPARC.Regs
21 import SPARC.RegPlate
22 import Size
23 import Reg
24
25 import Cmm
26
27 import Outputable
28 import OrdList
29
30 --------------------------------------------------------------------------------
31 -- | 'InstrBlock's are the insn sequences generated by the insn selectors.
32 --      They are really trees of insns to facilitate fast appending, where a
33 --      left-to-right traversal yields the insns in the correct order.
34 --
35 type InstrBlock 
36         = OrdList Instr
37
38
39 -- | Condition codes passed up the tree.
40 --
41 data CondCode   
42         = CondCode Bool Cond InstrBlock
43
44
45 -- | a.k.a "Register64"
46 --      Reg is the lower 32-bit temporary which contains the result. 
47 --      Use getHiVRegFromLo to find the other VRegUnique.  
48 --
49 --      Rules of this simplified insn selection game are therefore that
50 --      the returned Reg may be modified
51 --
52 data ChildCode64        
53    = ChildCode64 
54         InstrBlock
55         Reg             
56
57
58 -- | Holds code that references a memory address.
59 data Amode 
60         = Amode 
61                 -- the AddrMode we can use in the instruction 
62                 --      that does the real load\/store.
63                 AddrMode        
64
65                 -- other setup code we have to run first before we can use the
66                 --      above AddrMode.
67                 InstrBlock      
68
69
70
71 --------------------------------------------------------------------------------
72 -- | Code to produce a result into a register.
73 --      If the result must go in a specific register, it comes out as Fixed.
74 --      Otherwise, the parent can decide which register to put it in.
75 --
76 data Register
77         = Fixed Size Reg InstrBlock
78         | Any   Size (Reg -> InstrBlock)
79
80
81 -- | Change the size field in a Register.
82 setSizeOfRegister
83         :: Register -> Size -> Register
84
85 setSizeOfRegister reg size
86  = case reg of
87         Fixed _ reg code        -> Fixed size reg code
88         Any _ codefn            -> Any   size codefn
89
90
91 --------------------------------------------------------------------------------
92 -- | Grab the Reg for a CmmReg
93 getRegisterReg :: CmmReg -> Reg
94
95 getRegisterReg (CmmLocal (LocalReg u pk))
96         = RegVirtual $ mkVirtualReg u (cmmTypeSize pk)
97
98 getRegisterReg (CmmGlobal mid)
99   = case globalRegMaybe mid of
100         Just reg -> RegReal reg
101         Nothing  -> pprPanic
102                         "SPARC.CodeGen.Base.getRegisterReg: global is in memory"
103                         (ppr $ CmmGlobal mid)
104
105
106 -- Expand CmmRegOff.  ToDo: should we do it this way around, or convert
107 -- CmmExprs into CmmRegOff?
108 mangleIndexTree :: CmmExpr -> CmmExpr
109
110 mangleIndexTree (CmmRegOff reg off)
111         = CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)]
112         where width = typeWidth (cmmRegType reg)
113
114 mangleIndexTree _
115         = panic "SPARC.CodeGen.Base.mangleIndexTree: no match"
116
117
118
119