Merge in new code generator branch.
[ghc-hetmet.git] / compiler / nativeGen / SPARC / CodeGen / Gen64.hs
1
2 -- | Evaluation of 64 bit values on 32 bit platforms.
3 module SPARC.CodeGen.Gen64 (
4         assignMem_I64Code,
5         assignReg_I64Code,
6         iselExpr64
7 )
8
9 where
10
11 import {-# SOURCE #-} SPARC.CodeGen.Gen32
12 import SPARC.CodeGen.Base
13 import SPARC.CodeGen.Amode
14 import SPARC.Regs
15 import SPARC.AddrMode
16 import SPARC.Imm
17 import SPARC.Instr
18 import SPARC.Ppr()
19 import NCGMonad
20 import Instruction
21 import Size
22 import Reg
23
24 import OldCmm
25
26 import OrdList
27 import Outputable
28
29 -- | Code to assign a 64 bit value to memory.
30 assignMem_I64Code 
31         :: CmmExpr              -- ^ expr producing the desination address
32         -> CmmExpr              -- ^ expr producing the source value.
33         -> NatM InstrBlock
34
35 assignMem_I64Code addrTree valueTree 
36  = do
37      ChildCode64 vcode rlo      <- iselExpr64 valueTree  
38
39      (src, acode) <- getSomeReg addrTree
40      let 
41          rhi = getHiVRegFromLo rlo
42  
43          -- Big-endian store
44          mov_hi = ST II32 rhi (AddrRegImm src (ImmInt 0))
45          mov_lo = ST II32 rlo (AddrRegImm src (ImmInt 4))
46          
47          code   = vcode `appOL` acode `snocOL` mov_hi `snocOL` mov_lo
48
49 {-     pprTrace "assignMem_I64Code" 
50         (vcat   [ text "addrTree:  " <+> ppr addrTree
51                 , text "valueTree: " <+> ppr valueTree
52                 , text "vcode:"
53                 , vcat $ map ppr $ fromOL vcode 
54                 , text ""
55                 , text "acode:"
56                 , vcat $ map ppr $ fromOL acode ])
57        $ -}
58      return code
59
60
61 -- | Code to assign a 64 bit value to a register.
62 assignReg_I64Code 
63         :: CmmReg               -- ^ the destination register
64         -> CmmExpr              -- ^ expr producing the source value
65         -> NatM InstrBlock
66
67 assignReg_I64Code (CmmLocal (LocalReg u_dst pk)) valueTree 
68  = do
69      ChildCode64 vcode r_src_lo <- iselExpr64 valueTree    
70      let 
71          r_dst_lo = RegVirtual $ mkVirtualReg u_dst (cmmTypeSize pk)
72          r_dst_hi = getHiVRegFromLo r_dst_lo
73          r_src_hi = getHiVRegFromLo r_src_lo
74          mov_lo = mkMOV r_src_lo r_dst_lo
75          mov_hi = mkMOV r_src_hi r_dst_hi
76          mkMOV sreg dreg = OR False g0 (RIReg sreg) dreg
77
78      return (vcode `snocOL` mov_hi `snocOL` mov_lo)
79
80 assignReg_I64Code _ _
81    = panic "assignReg_I64Code(sparc): invalid lvalue"
82
83
84
85
86 -- | Get the value of an expression into a 64 bit register.
87
88 iselExpr64 :: CmmExpr -> NatM ChildCode64
89
90 -- Load a 64 bit word
91 iselExpr64 (CmmLoad addrTree ty) 
92  | isWord64 ty
93  = do   Amode amode addr_code   <- getAmode addrTree
94         let result
95
96                 | AddrRegReg r1 r2      <- amode
97                 = do    rlo     <- getNewRegNat II32
98                         tmp     <- getNewRegNat II32
99                         let rhi = getHiVRegFromLo rlo
100
101                         return  $ ChildCode64 
102                                 (        addr_code 
103                                 `appOL`  toOL
104                                          [ ADD False False r1 (RIReg r2) tmp
105                                          , LD II32 (AddrRegImm tmp (ImmInt 0)) rhi
106                                          , LD II32 (AddrRegImm tmp (ImmInt 4)) rlo ])
107                                 rlo
108
109                 | AddrRegImm r1 (ImmInt i) <- amode
110                 = do    rlo     <- getNewRegNat II32
111                         let rhi = getHiVRegFromLo rlo
112                         
113                         return  $ ChildCode64 
114                                 (        addr_code 
115                                 `appOL`  toOL
116                                          [ LD II32 (AddrRegImm r1 (ImmInt $ 0 + i)) rhi
117                                          , LD II32 (AddrRegImm r1 (ImmInt $ 4 + i)) rlo ])
118                                 rlo
119
120                 | otherwise
121                 = panic "SPARC.CodeGen.Gen64: no match"
122                 
123         result
124
125
126 -- Add a literal to a 64 bit integer
127 iselExpr64 (CmmMachOp (MO_Add _) [e1, CmmLit (CmmInt i _)]) 
128  = do   ChildCode64 code1 r1_lo <- iselExpr64 e1
129         let r1_hi       = getHiVRegFromLo r1_lo
130         
131         r_dst_lo        <- getNewRegNat II32
132         let r_dst_hi    =  getHiVRegFromLo r_dst_lo 
133         
134         let code =      code1
135                 `appOL` toOL
136                         [ ADD False True  r1_lo (RIImm (ImmInteger i)) r_dst_lo
137                         , ADD True  False r1_hi (RIReg g0)         r_dst_hi ]
138                         
139         return  $ ChildCode64 code r_dst_lo
140
141
142 -- Addition of II64
143 iselExpr64 (CmmMachOp (MO_Add _) [e1, e2])
144  = do   ChildCode64 code1 r1_lo <- iselExpr64 e1
145         let r1_hi       = getHiVRegFromLo r1_lo
146
147         ChildCode64 code2 r2_lo <- iselExpr64 e2
148         let r2_hi       = getHiVRegFromLo r2_lo
149         
150         r_dst_lo        <- getNewRegNat II32
151         let r_dst_hi    = getHiVRegFromLo r_dst_lo
152         
153         let code =      code1
154                 `appOL` code2
155                 `appOL` toOL
156                         [ ADD False True  r1_lo (RIReg r2_lo) r_dst_lo
157                         , ADD True  False r1_hi (RIReg r2_hi) r_dst_hi ]
158         
159         return  $ ChildCode64 code r_dst_lo
160
161
162 iselExpr64 (CmmReg (CmmLocal (LocalReg uq ty))) 
163  | isWord64 ty 
164  = do
165      r_dst_lo <-  getNewRegNat II32
166      let r_dst_hi = getHiVRegFromLo r_dst_lo
167          r_src_lo = RegVirtual $ mkVirtualReg uq II32
168          r_src_hi = getHiVRegFromLo r_src_lo
169          mov_lo = mkMOV r_src_lo r_dst_lo
170          mov_hi = mkMOV r_src_hi r_dst_hi
171          mkMOV sreg dreg = OR False g0 (RIReg sreg) dreg
172      return (
173             ChildCode64 (toOL [mov_hi, mov_lo]) r_dst_lo
174          )
175
176 -- Convert something into II64
177 iselExpr64 (CmmMachOp (MO_UU_Conv _ W64) [expr]) 
178  = do
179         r_dst_lo        <- getNewRegNat II32
180         let r_dst_hi    = getHiVRegFromLo r_dst_lo
181
182         -- compute expr and load it into r_dst_lo
183         (a_reg, a_code) <- getSomeReg expr
184
185         let code        = a_code
186                 `appOL` toOL
187                         [ mkRegRegMoveInstr g0    r_dst_hi      -- clear high 32 bits
188                         , mkRegRegMoveInstr a_reg r_dst_lo ]
189                         
190         return  $ ChildCode64 code r_dst_lo
191
192
193 iselExpr64 expr
194    = pprPanic "iselExpr64(sparc)" (ppr expr)
195
196
197