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