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