2 -- | Evaluation of 64 bit values on 32 bit platforms.
3 module SPARC.CodeGen.Gen64 (
11 import {-# SOURCE #-} SPARC.CodeGen.Gen32
12 import SPARC.CodeGen.Base
13 import SPARC.CodeGen.Amode
29 -- | Code to assign a 64 bit value to memory.
31 :: CmmExpr -- ^ expr producing the desination address
32 -> CmmExpr -- ^ expr producing the source value.
35 assignMem_I64Code addrTree valueTree
37 ChildCode64 vcode rlo <- iselExpr64 valueTree
39 (src, acode) <- getSomeReg addrTree
41 rhi = getHiVRegFromLo rlo
44 mov_hi = ST II32 rhi (AddrRegImm src (ImmInt 0))
45 mov_lo = ST II32 rlo (AddrRegImm src (ImmInt 4))
47 code = vcode `appOL` acode `snocOL` mov_hi `snocOL` mov_lo
49 {- pprTrace "assignMem_I64Code"
50 (vcat [ text "addrTree: " <+> ppr addrTree
51 , text "valueTree: " <+> ppr valueTree
53 , vcat $ map ppr $ fromOL vcode
56 , vcat $ map ppr $ fromOL acode ])
61 -- | Code to assign a 64 bit value to a register.
63 :: CmmReg -- ^ the destination register
64 -> CmmExpr -- ^ expr producing the source value
67 assignReg_I64Code (CmmLocal (LocalReg u_dst pk)) valueTree
69 ChildCode64 vcode r_src_lo <- iselExpr64 valueTree
71 r_dst_lo = mkVReg 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
78 return (vcode `snocOL` mov_hi `snocOL` mov_lo)
81 = panic "assignReg_I64Code(sparc): invalid lvalue"
86 -- | Get the value of an expression into a 64 bit register.
88 iselExpr64 :: CmmExpr -> NatM ChildCode64
91 iselExpr64 (CmmLoad addrTree ty)
93 = do Amode amode addr_code <- getAmode addrTree
96 | AddrRegReg r1 r2 <- amode
97 = do rlo <- getNewRegNat II32
98 tmp <- getNewRegNat II32
99 let rhi = getHiVRegFromLo rlo
104 [ ADD False False r1 (RIReg r2) tmp
105 , LD II32 (AddrRegImm tmp (ImmInt 0)) rhi
106 , LD II32 (AddrRegImm tmp (ImmInt 4)) rlo ])
109 | AddrRegImm r1 (ImmInt i) <- amode
110 = do rlo <- getNewRegNat II32
111 let rhi = getHiVRegFromLo rlo
116 [ LD II32 (AddrRegImm r1 (ImmInt $ 0 + i)) rhi
117 , LD II32 (AddrRegImm r1 (ImmInt $ 4 + i)) rlo ])
121 = panic "SPARC.CodeGen.Gen64: no match"
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
131 r_dst_lo <- getNewRegNat II32
132 let r_dst_hi = getHiVRegFromLo r_dst_lo
136 [ ADD False True r1_lo (RIImm (ImmInteger i)) r_dst_lo
137 , ADD True False r1_hi (RIReg g0) r_dst_hi ]
139 return $ ChildCode64 code r_dst_lo
143 iselExpr64 (CmmMachOp (MO_Add _) [e1, e2])
144 = do ChildCode64 code1 r1_lo <- iselExpr64 e1
145 let r1_hi = getHiVRegFromLo r1_lo
147 ChildCode64 code2 r2_lo <- iselExpr64 e2
148 let r2_hi = getHiVRegFromLo r2_lo
150 r_dst_lo <- getNewRegNat II32
151 let r_dst_hi = getHiVRegFromLo r_dst_lo
156 [ ADD False True r1_lo (RIReg r2_lo) r_dst_lo
157 , ADD True False r1_hi (RIReg r2_hi) r_dst_hi ]
159 return $ ChildCode64 code r_dst_lo
162 iselExpr64 (CmmReg (CmmLocal (LocalReg uq ty)))
165 r_dst_lo <- getNewRegNat II32
166 let r_dst_hi = getHiVRegFromLo r_dst_lo
167 r_src_lo = mkVReg 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
173 ChildCode64 (toOL [mov_hi, mov_lo]) r_dst_lo
176 -- Convert something into II64
177 iselExpr64 (CmmMachOp (MO_UU_Conv _ W64) [expr])
179 r_dst_lo <- getNewRegNat II32
180 let r_dst_hi = getHiVRegFromLo r_dst_lo
182 -- compute expr and load it into r_dst_lo
183 (a_reg, a_code) <- getSomeReg expr
187 [ mkRegRegMoveInstr g0 r_dst_hi -- clear high 32 bits
188 , mkRegRegMoveInstr a_reg r_dst_lo ]
190 return $ ChildCode64 code r_dst_lo
194 = pprPanic "iselExpr64(sparc)" (ppr expr)