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