never executed always true always false
1
2
3 -----------------------------------------------------------------------------
4 --
5 -- Machine-dependent assembly language
6 --
7 -- (c) The University of Glasgow 1993-2004
8 --
9 -----------------------------------------------------------------------------
10 module GHC.CmmToAsm.SPARC.Instr
11 ( Instr(..)
12 , RI(..)
13 , riZero
14 , fpRelEA
15 , moveSp
16 , isUnconditionalJump
17 , maxSpillSlots
18 , patchRegsOfInstr
19 , patchJumpInstr
20 , mkRegRegMoveInstr
21 , mkLoadInstr
22 , mkSpillInstr
23 , mkJumpInstr
24 , takeDeltaInstr
25 , isMetaInstr
26 , isJumpishInstr
27 , jumpDestsOfInstr
28 , takeRegRegMoveInstr
29 , regUsageOfInstr
30 )
31 where
32
33 import GHC.Prelude
34 import GHC.Platform
35
36 import GHC.CmmToAsm.SPARC.Stack
37 import GHC.CmmToAsm.SPARC.Imm
38 import GHC.CmmToAsm.SPARC.AddrMode
39 import GHC.CmmToAsm.SPARC.Cond
40 import GHC.CmmToAsm.SPARC.Regs
41 import GHC.CmmToAsm.SPARC.Base
42 import GHC.CmmToAsm.Reg.Target
43 import GHC.CmmToAsm.Format
44 import GHC.CmmToAsm.Config
45 import GHC.CmmToAsm.Instr (RegUsage(..), noUsage)
46
47 import GHC.Platform.Reg.Class
48 import GHC.Platform.Reg
49 import GHC.Platform.Regs
50
51 import GHC.Cmm.CLabel
52 import GHC.Cmm.BlockId
53 import GHC.Cmm
54 import GHC.Utils.Outputable
55 import GHC.Utils.Panic
56
57
58 -- | Register or immediate
59 data RI
60 = RIReg Reg
61 | RIImm Imm
62
63 -- | Check if a RI represents a zero value.
64 -- - a literal zero
65 -- - register %g0, which is always zero.
66 --
67 riZero :: RI -> Bool
68 riZero (RIImm (ImmInt 0)) = True
69 riZero (RIImm (ImmInteger 0)) = True
70 riZero (RIReg (RegReal (RealRegSingle 0))) = True
71 riZero _ = False
72
73
74 -- | Calculate the effective address which would be used by the
75 -- corresponding fpRel sequence.
76 fpRelEA :: Int -> Reg -> Instr
77 fpRelEA n dst
78 = ADD False False fp (RIImm (ImmInt (n * wordLength))) dst
79
80
81 -- | Code to shift the stack pointer by n words.
82 moveSp :: Int -> Instr
83 moveSp n
84 = ADD False False sp (RIImm (ImmInt (n * wordLength))) sp
85
86 -- | An instruction that will cause the one after it never to be exectuted
87 isUnconditionalJump :: Instr -> Bool
88 isUnconditionalJump ii
89 = case ii of
90 CALL{} -> True
91 JMP{} -> True
92 JMP_TBL{} -> True
93 BI ALWAYS _ _ -> True
94 BF ALWAYS _ _ -> True
95 _ -> False
96
97
98 -- | SPARC instruction set.
99 -- Not complete. This is only the ones we need.
100 --
101 data Instr
102
103 -- meta ops --------------------------------------------------
104 -- comment pseudo-op
105 = COMMENT SDoc
106
107 -- some static data spat out during code generation.
108 -- Will be extracted before pretty-printing.
109 | LDATA Section RawCmmStatics
110
111 -- Start a new basic block. Useful during codegen, removed later.
112 -- Preceding instruction should be a jump, as per the invariants
113 -- for a BasicBlock (see Cmm).
114 | NEWBLOCK BlockId
115
116 -- specify current stack offset for benefit of subsequent passes.
117 | DELTA Int
118
119 -- real instrs -----------------------------------------------
120 -- Loads and stores.
121 | LD Format AddrMode Reg -- format, src, dst
122 | ST Format Reg AddrMode -- format, src, dst
123
124 -- Int Arithmetic.
125 -- x: add/sub with carry bit.
126 -- In SPARC V9 addx and friends were renamed addc.
127 --
128 -- cc: modify condition codes
129 --
130 | ADD Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
131 | SUB Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
132
133 | UMUL Bool Reg RI Reg -- cc?, src1, src2, dst
134 | SMUL Bool Reg RI Reg -- cc?, src1, src2, dst
135
136
137 -- The SPARC divide instructions perform 64bit by 32bit division
138 -- The Y register is xored into the first operand.
139
140 -- On _some implementations_ the Y register is overwritten by
141 -- the remainder, so we have to make sure it is 0 each time.
142
143 -- dst <- ((Y `shiftL` 32) `or` src1) `div` src2
144 | UDIV Bool Reg RI Reg -- cc?, src1, src2, dst
145 | SDIV Bool Reg RI Reg -- cc?, src1, src2, dst
146
147 | RDY Reg -- move contents of Y register to reg
148 | WRY Reg Reg -- Y <- src1 `xor` src2
149
150 -- Logic operations.
151 | AND Bool Reg RI Reg -- cc?, src1, src2, dst
152 | ANDN Bool Reg RI Reg -- cc?, src1, src2, dst
153 | OR Bool Reg RI Reg -- cc?, src1, src2, dst
154 | ORN Bool Reg RI Reg -- cc?, src1, src2, dst
155 | XOR Bool Reg RI Reg -- cc?, src1, src2, dst
156 | XNOR Bool Reg RI Reg -- cc?, src1, src2, dst
157 | SLL Reg RI Reg -- src1, src2, dst
158 | SRL Reg RI Reg -- src1, src2, dst
159 | SRA Reg RI Reg -- src1, src2, dst
160
161 -- Load immediates.
162 | SETHI Imm Reg -- src, dst
163
164 -- Do nothing.
165 -- Implemented by the assembler as SETHI 0, %g0, but worth an alias
166 | NOP
167
168 -- Float Arithmetic.
169 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single
170 -- instructions right up until we spit them out.
171 --
172 | FABS Format Reg Reg -- src dst
173 | FADD Format Reg Reg Reg -- src1, src2, dst
174 | FCMP Bool Format Reg Reg -- exception?, src1, src2, dst
175 | FDIV Format Reg Reg Reg -- src1, src2, dst
176 | FMOV Format Reg Reg -- src, dst
177 | FMUL Format Reg Reg Reg -- src1, src2, dst
178 | FNEG Format Reg Reg -- src, dst
179 | FSQRT Format Reg Reg -- src, dst
180 | FSUB Format Reg Reg Reg -- src1, src2, dst
181 | FxTOy Format Format Reg Reg -- src, dst
182
183 -- Jumping around.
184 | BI Cond Bool BlockId -- cond, annul?, target
185 | BF Cond Bool BlockId -- cond, annul?, target
186
187 | JMP AddrMode -- target
188
189 -- With a tabled jump we know all the possible destinations.
190 -- We also need this info so we can work out what regs are live across the jump.
191 --
192 | JMP_TBL AddrMode [Maybe BlockId] CLabel
193
194 | CALL (Either Imm Reg) Int Bool -- target, args, terminal
195
196
197 -- | regUsage returns the sets of src and destination registers used
198 -- by a particular instruction. Machine registers that are
199 -- pre-allocated to stgRegs are filtered out, because they are
200 -- uninteresting from a register allocation standpoint. (We wouldn't
201 -- want them to end up on the free list!) As far as we are concerned,
202 -- the fixed registers simply don't exist (for allocation purposes,
203 -- anyway).
204
205 -- regUsage doesn't need to do any trickery for jumps and such. Just
206 -- state precisely the regs read and written by that insn. The
207 -- consequences of control flow transfers, as far as register
208 -- allocation goes, are taken care of by the register allocator.
209 --
210 regUsageOfInstr :: Platform -> Instr -> RegUsage
211 regUsageOfInstr platform instr
212 = case instr of
213 LD _ addr reg -> usage (regAddr addr, [reg])
214 ST _ reg addr -> usage (reg : regAddr addr, [])
215 ADD _ _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
216 SUB _ _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
217 UMUL _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
218 SMUL _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
219 UDIV _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
220 SDIV _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
221 RDY rd -> usage ([], [rd])
222 WRY r1 r2 -> usage ([r1, r2], [])
223 AND _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
224 ANDN _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
225 OR _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
226 ORN _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
227 XOR _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
228 XNOR _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
229 SLL r1 ar r2 -> usage (r1 : regRI ar, [r2])
230 SRL r1 ar r2 -> usage (r1 : regRI ar, [r2])
231 SRA r1 ar r2 -> usage (r1 : regRI ar, [r2])
232 SETHI _ reg -> usage ([], [reg])
233 FABS _ r1 r2 -> usage ([r1], [r2])
234 FADD _ r1 r2 r3 -> usage ([r1, r2], [r3])
235 FCMP _ _ r1 r2 -> usage ([r1, r2], [])
236 FDIV _ r1 r2 r3 -> usage ([r1, r2], [r3])
237 FMOV _ r1 r2 -> usage ([r1], [r2])
238 FMUL _ r1 r2 r3 -> usage ([r1, r2], [r3])
239 FNEG _ r1 r2 -> usage ([r1], [r2])
240 FSQRT _ r1 r2 -> usage ([r1], [r2])
241 FSUB _ r1 r2 r3 -> usage ([r1, r2], [r3])
242 FxTOy _ _ r1 r2 -> usage ([r1], [r2])
243
244 JMP addr -> usage (regAddr addr, [])
245 JMP_TBL addr _ _ -> usage (regAddr addr, [])
246
247 CALL (Left _ ) _ True -> noUsage
248 CALL (Left _ ) n False -> usage (argRegs n, callClobberedRegs)
249 CALL (Right reg) _ True -> usage ([reg], [])
250 CALL (Right reg) n False -> usage (reg : (argRegs n), callClobberedRegs)
251 _ -> noUsage
252
253 where
254 usage (src, dst)
255 = RU (filter (interesting platform) src)
256 (filter (interesting platform) dst)
257
258 regAddr (AddrRegReg r1 r2) = [r1, r2]
259 regAddr (AddrRegImm r1 _) = [r1]
260
261 regRI (RIReg r) = [r]
262 regRI _ = []
263
264
265 -- | Interesting regs are virtuals, or ones that are allocatable
266 -- by the register allocator.
267 interesting :: Platform -> Reg -> Bool
268 interesting platform reg
269 = case reg of
270 RegVirtual _ -> True
271 RegReal (RealRegSingle r1) -> freeReg platform r1
272 RegReal (RealRegPair r1 _) -> freeReg platform r1
273
274
275
276 -- | Apply a given mapping to tall the register references in this instruction.
277 patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
278 patchRegsOfInstr instr env = case instr of
279 LD fmt addr reg -> LD fmt (fixAddr addr) (env reg)
280 ST fmt reg addr -> ST fmt (env reg) (fixAddr addr)
281
282 ADD x cc r1 ar r2 -> ADD x cc (env r1) (fixRI ar) (env r2)
283 SUB x cc r1 ar r2 -> SUB x cc (env r1) (fixRI ar) (env r2)
284 UMUL cc r1 ar r2 -> UMUL cc (env r1) (fixRI ar) (env r2)
285 SMUL cc r1 ar r2 -> SMUL cc (env r1) (fixRI ar) (env r2)
286 UDIV cc r1 ar r2 -> UDIV cc (env r1) (fixRI ar) (env r2)
287 SDIV cc r1 ar r2 -> SDIV cc (env r1) (fixRI ar) (env r2)
288 RDY rd -> RDY (env rd)
289 WRY r1 r2 -> WRY (env r1) (env r2)
290 AND b r1 ar r2 -> AND b (env r1) (fixRI ar) (env r2)
291 ANDN b r1 ar r2 -> ANDN b (env r1) (fixRI ar) (env r2)
292 OR b r1 ar r2 -> OR b (env r1) (fixRI ar) (env r2)
293 ORN b r1 ar r2 -> ORN b (env r1) (fixRI ar) (env r2)
294 XOR b r1 ar r2 -> XOR b (env r1) (fixRI ar) (env r2)
295 XNOR b r1 ar r2 -> XNOR b (env r1) (fixRI ar) (env r2)
296 SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
297 SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
298 SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
299
300 SETHI imm reg -> SETHI imm (env reg)
301
302 FABS s r1 r2 -> FABS s (env r1) (env r2)
303 FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
304 FCMP e s r1 r2 -> FCMP e s (env r1) (env r2)
305 FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
306 FMOV s r1 r2 -> FMOV s (env r1) (env r2)
307 FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
308 FNEG s r1 r2 -> FNEG s (env r1) (env r2)
309 FSQRT s r1 r2 -> FSQRT s (env r1) (env r2)
310 FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
311 FxTOy s1 s2 r1 r2 -> FxTOy s1 s2 (env r1) (env r2)
312
313 JMP addr -> JMP (fixAddr addr)
314 JMP_TBL addr ids l -> JMP_TBL (fixAddr addr) ids l
315
316 CALL (Left i) n t -> CALL (Left i) n t
317 CALL (Right r) n t -> CALL (Right (env r)) n t
318 _ -> instr
319
320 where
321 fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
322 fixAddr (AddrRegImm r1 i) = AddrRegImm (env r1) i
323
324 fixRI (RIReg r) = RIReg (env r)
325 fixRI other = other
326
327
328 --------------------------------------------------------------------------------
329 isJumpishInstr :: Instr -> Bool
330 isJumpishInstr instr
331 = case instr of
332 BI{} -> True
333 BF{} -> True
334 JMP{} -> True
335 JMP_TBL{} -> True
336 CALL{} -> True
337 _ -> False
338
339 jumpDestsOfInstr :: Instr -> [BlockId]
340 jumpDestsOfInstr insn
341 = case insn of
342 BI _ _ id -> [id]
343 BF _ _ id -> [id]
344 JMP_TBL _ ids _ -> [id | Just id <- ids]
345 _ -> []
346
347
348 patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
349 patchJumpInstr insn patchF
350 = case insn of
351 BI cc annul id -> BI cc annul (patchF id)
352 BF cc annul id -> BF cc annul (patchF id)
353 JMP_TBL n ids l -> JMP_TBL n (map (fmap patchF) ids) l
354 _ -> insn
355
356
357 --------------------------------------------------------------------------------
358 -- | Make a spill instruction.
359 -- On SPARC we spill below frame pointer leaving 2 words/spill
360 mkSpillInstr
361 :: NCGConfig
362 -> Reg -- ^ register to spill
363 -> Int -- ^ current stack delta
364 -> Int -- ^ spill slot to use
365 -> [Instr]
366
367 mkSpillInstr config reg _ slot
368 = let platform = ncgPlatform config
369 off = spillSlotToOffset config slot
370 off_w = 1 + (off `div` 4)
371 fmt = case targetClassOfReg platform reg of
372 RcInteger -> II32
373 RcFloat -> FF32
374 RcDouble -> FF64
375
376 in [ST fmt reg (fpRel (negate off_w))]
377
378
379 -- | Make a spill reload instruction.
380 mkLoadInstr
381 :: NCGConfig
382 -> Reg -- ^ register to load into
383 -> Int -- ^ current stack delta
384 -> Int -- ^ spill slot to use
385 -> [Instr]
386
387 mkLoadInstr config reg _ slot
388 = let platform = ncgPlatform config
389 off = spillSlotToOffset config slot
390 off_w = 1 + (off `div` 4)
391 fmt = case targetClassOfReg platform reg of
392 RcInteger -> II32
393 RcFloat -> FF32
394 RcDouble -> FF64
395
396 in [LD fmt (fpRel (- off_w)) reg]
397
398
399 --------------------------------------------------------------------------------
400 -- | See if this instruction is telling us the current C stack delta
401 takeDeltaInstr
402 :: Instr
403 -> Maybe Int
404
405 takeDeltaInstr instr
406 = case instr of
407 DELTA i -> Just i
408 _ -> Nothing
409
410
411 isMetaInstr
412 :: Instr
413 -> Bool
414
415 isMetaInstr instr
416 = case instr of
417 COMMENT{} -> True
418 LDATA{} -> True
419 NEWBLOCK{} -> True
420 DELTA{} -> True
421 _ -> False
422
423
424 -- | Make a reg-reg move instruction.
425 -- On SPARC v8 there are no instructions to move directly between
426 -- floating point and integer regs. If we need to do that then we
427 -- have to go via memory.
428 --
429 mkRegRegMoveInstr
430 :: Platform
431 -> Reg
432 -> Reg
433 -> Instr
434
435 mkRegRegMoveInstr platform src dst
436 | srcClass <- targetClassOfReg platform src
437 , dstClass <- targetClassOfReg platform dst
438 , srcClass == dstClass
439 = case srcClass of
440 RcInteger -> ADD False False src (RIReg g0) dst
441 RcDouble -> FMOV FF64 src dst
442 RcFloat -> FMOV FF32 src dst
443
444 | otherwise
445 = panic "SPARC.Instr.mkRegRegMoveInstr: classes of src and dest not the same"
446
447
448 -- | Check whether an instruction represents a reg-reg move.
449 -- The register allocator attempts to eliminate reg->reg moves whenever it can,
450 -- by assigning the src and dest temporaries to the same real register.
451 --
452 takeRegRegMoveInstr :: Instr -> Maybe (Reg,Reg)
453 takeRegRegMoveInstr instr
454 = case instr of
455 ADD False False src (RIReg src2) dst
456 | g0 == src2 -> Just (src, dst)
457
458 FMOV FF64 src dst -> Just (src, dst)
459 FMOV FF32 src dst -> Just (src, dst)
460 _ -> Nothing
461
462
463 -- | Make an unconditional branch instruction.
464 mkJumpInstr
465 :: BlockId
466 -> [Instr]
467
468 mkJumpInstr id
469 = [BI ALWAYS False id
470 , NOP] -- fill the branch delay slot.