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
28 -- | Code to assign a 64 bit value to memory.
30 :: CmmExpr -- ^ expr producing the desination address
31 -> CmmExpr -- ^ expr producing the source value.
34 assignMem_I64Code addrTree valueTree
36 ChildCode64 vcode rlo <- iselExpr64 valueTree
38 (src, code) <- getSomeReg addrTree
40 rhi = getHiVRegFromLo rlo
43 mov_hi = ST II32 rhi (AddrRegImm src (ImmInt 0))
44 mov_lo = ST II32 rlo (AddrRegImm src (ImmInt 4))
46 return (vcode `appOL` code `snocOL` mov_hi `snocOL` mov_lo)
49 -- | Code to assign a 64 bit value to a register.
51 :: CmmReg -- ^ the destination register
52 -> CmmExpr -- ^ expr producing the source value
55 assignReg_I64Code (CmmLocal (LocalReg u_dst pk)) valueTree
57 ChildCode64 vcode r_src_lo <- iselExpr64 valueTree
59 r_dst_lo = mkVReg u_dst (cmmTypeSize pk)
60 r_dst_hi = getHiVRegFromLo r_dst_lo
61 r_src_hi = getHiVRegFromLo r_src_lo
62 mov_lo = mkMOV r_src_lo r_dst_lo
63 mov_hi = mkMOV r_src_hi r_dst_hi
64 mkMOV sreg dreg = OR False g0 (RIReg sreg) dreg
66 return (vcode `snocOL` mov_hi `snocOL` mov_lo)
69 = panic "assignReg_I64Code(sparc): invalid lvalue"
74 -- | Get the value of an expression into a 64 bit register.
76 iselExpr64 :: CmmExpr -> NatM ChildCode64
79 iselExpr64 (CmmLoad addrTree ty)
81 = do Amode amode addr_code <- getAmode addrTree
84 | AddrRegReg r1 r2 <- amode
85 = do rlo <- getNewRegNat II32
86 tmp <- getNewRegNat II32
87 let rhi = getHiVRegFromLo rlo
92 [ ADD False False r1 (RIReg r2) tmp
93 , LD II32 (AddrRegImm tmp (ImmInt 0)) rhi
94 , LD II32 (AddrRegImm tmp (ImmInt 4)) rlo ])
97 | AddrRegImm r1 (ImmInt i) <- amode
98 = do rlo <- getNewRegNat II32
99 let rhi = getHiVRegFromLo rlo
104 [ LD II32 (AddrRegImm r1 (ImmInt $ 0 + i)) rhi
105 , LD II32 (AddrRegImm r1 (ImmInt $ 4 + i)) rlo ])
109 = panic "SPARC.CodeGen.Gen64: no match"
114 -- Add a literal to a 64 bit integer
115 iselExpr64 (CmmMachOp (MO_Add _) [e1, CmmLit (CmmInt i _)])
116 = do ChildCode64 _ r1_lo <- iselExpr64 e1
117 let r1_hi = getHiVRegFromLo r1_lo
119 r_dst_lo <- getNewRegNat II32
120 let r_dst_hi = getHiVRegFromLo r_dst_lo
124 [ ADD False False r1_lo (RIImm (ImmInteger i)) r_dst_lo
125 , ADD True False r1_hi (RIReg g0) r_dst_hi ])
130 iselExpr64 (CmmMachOp (MO_Add _) [e1, e2])
131 = do ChildCode64 code1 r1_lo <- iselExpr64 e1
132 let r1_hi = getHiVRegFromLo r1_lo
134 ChildCode64 code2 r2_lo <- iselExpr64 e2
135 let r2_hi = getHiVRegFromLo r2_lo
137 r_dst_lo <- getNewRegNat II32
138 let r_dst_hi = getHiVRegFromLo r_dst_lo
143 [ ADD False False r1_lo (RIReg r2_lo) r_dst_lo
144 , ADD True False r1_hi (RIReg r2_hi) r_dst_hi ]
146 return $ ChildCode64 code r_dst_lo
149 iselExpr64 (CmmReg (CmmLocal (LocalReg uq ty)))
152 r_dst_lo <- getNewRegNat II32
153 let r_dst_hi = getHiVRegFromLo r_dst_lo
154 r_src_lo = mkVReg uq II32
155 r_src_hi = getHiVRegFromLo r_src_lo
156 mov_lo = mkMOV r_src_lo r_dst_lo
157 mov_hi = mkMOV r_src_hi r_dst_hi
158 mkMOV sreg dreg = OR False g0 (RIReg sreg) dreg
160 ChildCode64 (toOL [mov_hi, mov_lo]) r_dst_lo
163 -- Convert something into II64
164 iselExpr64 (CmmMachOp (MO_UU_Conv _ W64) [expr])
166 r_dst_lo <- getNewRegNat II32
167 let r_dst_hi = getHiVRegFromLo r_dst_lo
169 -- compute expr and load it into r_dst_lo
170 (a_reg, a_code) <- getSomeReg expr
174 [ mkRegRegMoveInstr g0 r_dst_hi -- clear high 32 bits
175 , mkRegRegMoveInstr a_reg r_dst_lo ]
177 return $ ChildCode64 code r_dst_lo
181 = pprPanic "iselExpr64(sparc)" (ppr expr)