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