1 -----------------------------------------------------------------------------
3 -- Machine-dependent assembly language
5 -- (c) The University of Glasgow 1993-2004
7 -----------------------------------------------------------------------------
9 #include "HsVersions.h"
10 #include "nativeGen/NCG.h"
30 import Constants (rESERVED_C_STACK_BYTES )
37 -- | Register or immediate
43 -- | instance for sparc instruction set
44 instance Instruction Instr where
45 regUsageOfInstr = sparc_regUsageOfInstr
46 patchRegsOfInstr = sparc_patchRegsOfInstr
47 isJumpishInstr = sparc_isJumpishInstr
48 jumpDestsOfInstr = sparc_jumpDestsOfInstr
49 patchJumpInstr = sparc_patchJumpInstr
50 mkSpillInstr = sparc_mkSpillInstr
51 mkLoadInstr = sparc_mkLoadInstr
52 takeDeltaInstr = sparc_takeDeltaInstr
53 isMetaInstr = sparc_isMetaInstr
54 mkRegRegMoveInstr = sparc_mkRegRegMoveInstr
55 takeRegRegMoveInstr = sparc_takeRegRegMoveInstr
56 mkJumpInstr = sparc_mkJumpInstr
59 -- | SPARC instruction set.
60 -- Not complete. This is only the ones we need.
64 -- meta ops --------------------------------------------------
68 -- some static data spat out during code generation.
69 -- Will be extracted before pretty-printing.
70 | LDATA Section [CmmStatic]
72 -- Start a new basic block. Useful during codegen, removed later.
73 -- Preceding instruction should be a jump, as per the invariants
74 -- for a BasicBlock (see Cmm).
77 -- specify current stack offset for benefit of subsequent passes.
80 -- real instrs -----------------------------------------------
82 | LD Size AddrMode Reg -- size, src, dst
83 | ST Size Reg AddrMode -- size, src, dst
86 | ADD Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
87 | SUB Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
89 | UMUL Bool Reg RI Reg -- cc?, src1, src2, dst
90 | SMUL Bool Reg RI Reg -- cc?, src1, src2, dst
93 -- The SPARC divide instructions perform 64bit by 32bit division
94 -- The Y register is xored into the first operand.
96 -- On _some implementations_ the Y register is overwritten by
97 -- the remainder, so we have to make sure it is 0 each time.
99 -- dst <- ((Y `shiftL` 32) `or` src1) `div` src2
100 | UDIV Bool Reg RI Reg -- cc?, src1, src2, dst
101 | SDIV Bool Reg RI Reg -- cc?, src1, src2, dst
103 | RDY Reg -- move contents of Y register to reg
104 | WRY Reg Reg -- Y <- src1 `xor` src2
107 | AND Bool Reg RI Reg -- cc?, src1, src2, dst
108 | ANDN Bool Reg RI Reg -- cc?, src1, src2, dst
109 | OR Bool Reg RI Reg -- cc?, src1, src2, dst
110 | ORN Bool Reg RI Reg -- cc?, src1, src2, dst
111 | XOR Bool Reg RI Reg -- cc?, src1, src2, dst
112 | XNOR Bool Reg RI Reg -- cc?, src1, src2, dst
113 | SLL Reg RI Reg -- src1, src2, dst
114 | SRL Reg RI Reg -- src1, src2, dst
115 | SRA Reg RI Reg -- src1, src2, dst
118 | SETHI Imm Reg -- src, dst
121 -- Implemented by the assembler as SETHI 0, %g0, but worth an alias
125 -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single
126 -- instructions right up until we spit them out.
128 | FABS Size Reg Reg -- src dst
129 | FADD Size Reg Reg Reg -- src1, src2, dst
130 | FCMP Bool Size Reg Reg -- exception?, src1, src2, dst
131 | FDIV Size Reg Reg Reg -- src1, src2, dst
132 | FMOV Size Reg Reg -- src, dst
133 | FMUL Size Reg Reg Reg -- src1, src2, dst
134 | FNEG Size Reg Reg -- src, dst
135 | FSQRT Size Reg Reg -- src, dst
136 | FSUB Size Reg Reg Reg -- src1, src2, dst
137 | FxTOy Size Size Reg Reg -- src, dst
140 | BI Cond Bool BlockId -- cond, annul?, target
141 | BF Cond Bool BlockId -- cond, annul?, target
143 | JMP AddrMode -- target
145 -- With a tabled jump we know all the possible destinations.
146 -- We also need this info so we can work out what regs are live across the jump.
148 | JMP_TBL AddrMode [BlockId]
150 | CALL (Either Imm Reg) Int Bool -- target, args, terminal
153 -- | regUsage returns the sets of src and destination registers used
154 -- by a particular instruction. Machine registers that are
155 -- pre-allocated to stgRegs are filtered out, because they are
156 -- uninteresting from a register allocation standpoint. (We wouldn't
157 -- want them to end up on the free list!) As far as we are concerned,
158 -- the fixed registers simply don't exist (for allocation purposes,
161 -- regUsage doesn't need to do any trickery for jumps and such. Just
162 -- state precisely the regs read and written by that insn. The
163 -- consequences of control flow transfers, as far as register
164 -- allocation goes, are taken care of by the register allocator.
166 sparc_regUsageOfInstr :: Instr -> RegUsage
167 sparc_regUsageOfInstr instr
169 LD _ addr reg -> usage (regAddr addr, [reg])
170 ST _ reg addr -> usage (reg : regAddr addr, [])
171 ADD _ _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
172 SUB _ _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
173 UMUL _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
174 SMUL _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
175 UDIV _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
176 SDIV _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
177 RDY rd -> usage ([], [rd])
178 WRY r1 r2 -> usage ([r1, r2], [])
179 AND _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
180 ANDN _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
181 OR _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
182 ORN _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
183 XOR _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
184 XNOR _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
185 SLL r1 ar r2 -> usage (r1 : regRI ar, [r2])
186 SRL r1 ar r2 -> usage (r1 : regRI ar, [r2])
187 SRA r1 ar r2 -> usage (r1 : regRI ar, [r2])
188 SETHI _ reg -> usage ([], [reg])
189 FABS _ r1 r2 -> usage ([r1], [r2])
190 FADD _ r1 r2 r3 -> usage ([r1, r2], [r3])
191 FCMP _ _ r1 r2 -> usage ([r1, r2], [])
192 FDIV _ r1 r2 r3 -> usage ([r1, r2], [r3])
193 FMOV _ r1 r2 -> usage ([r1], [r2])
194 FMUL _ r1 r2 r3 -> usage ([r1, r2], [r3])
195 FNEG _ r1 r2 -> usage ([r1], [r2])
196 FSQRT _ r1 r2 -> usage ([r1], [r2])
197 FSUB _ r1 r2 r3 -> usage ([r1, r2], [r3])
198 FxTOy _ _ r1 r2 -> usage ([r1], [r2])
200 JMP addr -> usage (regAddr addr, [])
201 JMP_TBL addr _ -> usage (regAddr addr, [])
203 CALL (Left _ ) _ True -> noUsage
204 CALL (Left _ ) n False -> usage (argRegs n, callClobberedRegs)
205 CALL (Right reg) _ True -> usage ([reg], [])
206 CALL (Right reg) n False -> usage (reg : (argRegs n), callClobberedRegs)
211 = RU (filter interesting src) (filter interesting dst)
213 regAddr (AddrRegReg r1 r2) = [r1, r2]
214 regAddr (AddrRegImm r1 _) = [r1]
216 regRI (RIReg r) = [r]
220 -- | Interesting regs are virtuals, or ones that are allocatable
221 -- by the register allocator.
222 interesting :: Reg -> Bool
225 VirtualRegI _ -> True
226 VirtualRegHi _ -> True
227 VirtualRegF _ -> True
228 VirtualRegD _ -> True
229 RealReg i -> isFastTrue (freeReg i)
233 -- | Apply a given mapping to tall the register references in this instruction.
234 sparc_patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
235 sparc_patchRegsOfInstr instr env = case instr of
236 LD sz addr reg -> LD sz (fixAddr addr) (env reg)
237 ST sz reg addr -> ST sz (env reg) (fixAddr addr)
239 ADD x cc r1 ar r2 -> ADD x cc (env r1) (fixRI ar) (env r2)
240 SUB x cc r1 ar r2 -> SUB x cc (env r1) (fixRI ar) (env r2)
241 UMUL cc r1 ar r2 -> UMUL cc (env r1) (fixRI ar) (env r2)
242 SMUL cc r1 ar r2 -> SMUL cc (env r1) (fixRI ar) (env r2)
243 UDIV cc r1 ar r2 -> UDIV cc (env r1) (fixRI ar) (env r2)
244 SDIV cc r1 ar r2 -> SDIV cc (env r1) (fixRI ar) (env r2)
245 RDY rd -> RDY (env rd)
246 WRY r1 r2 -> WRY (env r1) (env r2)
247 AND b r1 ar r2 -> AND b (env r1) (fixRI ar) (env r2)
248 ANDN b r1 ar r2 -> ANDN b (env r1) (fixRI ar) (env r2)
249 OR b r1 ar r2 -> OR b (env r1) (fixRI ar) (env r2)
250 ORN b r1 ar r2 -> ORN b (env r1) (fixRI ar) (env r2)
251 XOR b r1 ar r2 -> XOR b (env r1) (fixRI ar) (env r2)
252 XNOR b r1 ar r2 -> XNOR b (env r1) (fixRI ar) (env r2)
253 SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
254 SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
255 SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
257 SETHI imm reg -> SETHI imm (env reg)
259 FABS s r1 r2 -> FABS s (env r1) (env r2)
260 FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
261 FCMP e s r1 r2 -> FCMP e s (env r1) (env r2)
262 FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
263 FMOV s r1 r2 -> FMOV s (env r1) (env r2)
264 FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
265 FNEG s r1 r2 -> FNEG s (env r1) (env r2)
266 FSQRT s r1 r2 -> FSQRT s (env r1) (env r2)
267 FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
268 FxTOy s1 s2 r1 r2 -> FxTOy s1 s2 (env r1) (env r2)
270 JMP addr -> JMP (fixAddr addr)
271 JMP_TBL addr ids -> JMP_TBL (fixAddr addr) ids
273 CALL (Left i) n t -> CALL (Left i) n t
274 CALL (Right r) n t -> CALL (Right (env r)) n t
278 fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
279 fixAddr (AddrRegImm r1 i) = AddrRegImm (env r1) i
281 fixRI (RIReg r) = RIReg (env r)
285 --------------------------------------------------------------------------------
286 sparc_isJumpishInstr :: Instr -> Bool
287 sparc_isJumpishInstr instr
296 sparc_jumpDestsOfInstr :: Instr -> [BlockId]
297 sparc_jumpDestsOfInstr insn
305 sparc_patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
306 sparc_patchJumpInstr insn patchF
308 BI cc annul id -> BI cc annul (patchF id)
309 BF cc annul id -> BF cc annul (patchF id)
313 --------------------------------------------------------------------------------
314 -- | Make a spill instruction.
315 -- On SPARC we spill below frame pointer leaving 2 words/spill
317 :: Reg -- ^ register to spill
318 -> Int -- ^ current stack delta
319 -> Int -- ^ spill slot to use
322 sparc_mkSpillInstr reg _ slot
323 = let off = spillSlotToOffset slot
324 off_w = 1 + (off `div` 4)
325 sz = case regClass reg of
330 in ST sz reg (fpRel (negate off_w))
333 -- | Make a spill reload instruction.
335 :: Reg -- ^ register to load
336 -> Int -- ^ current stack delta
337 -> Int -- ^ spill slot to use
340 sparc_mkLoadInstr reg _ slot
341 = let off = spillSlotToOffset slot
342 off_w = 1 + (off `div` 4)
343 sz = case regClass reg of
348 in LD sz (fpRel (- off_w)) reg
350 -- | Convert a spill slot number to a *byte* offset, with no sign.
352 spillSlotToOffset :: Int -> Int
353 spillSlotToOffset slot
354 | slot >= 0 && slot < maxSpillSlots
355 = 64 + spillSlotSize * slot
358 = pprPanic "spillSlotToOffset:"
359 ( text "invalid spill location: " <> int slot
360 $$ text "maxSpillSlots: " <> int maxSpillSlots)
363 -- | We need 8 bytes because our largest registers are 64 bit.
368 -- | The maximum number of spill slots available on the C stack.
369 -- If we use up all of the slots, then we're screwed.
371 maxSpillSlots = ((rESERVED_C_STACK_BYTES - 64) `div` spillSlotSize) - 1
374 --------------------------------------------------------------------------------
375 -- | See if this instruction is telling us the current C stack delta
380 sparc_takeDeltaInstr instr
390 sparc_isMetaInstr instr
399 -- | Make a reg-reg move instruction.
400 -- On SPARC v8 there are no instructions to move directly between
401 -- floating point and integer regs. If we need to do that then we
402 -- have to go via memory.
404 sparc_mkRegRegMoveInstr
409 sparc_mkRegRegMoveInstr src dst
410 = case regClass src of
411 RcInteger -> ADD False False src (RIReg g0) dst
412 RcDouble -> FMOV FF64 src dst
413 RcFloat -> FMOV FF32 src dst
416 -- | Check whether an instruction represents a reg-reg move.
417 -- The register allocator attempts to eliminate reg->reg moves whenever it can,
418 -- by assigning the src and dest temporaries to the same real register.
420 sparc_takeRegRegMoveInstr :: Instr -> Maybe (Reg,Reg)
421 sparc_takeRegRegMoveInstr instr
423 ADD False False src (RIReg src2) dst
424 | g0 == src2 -> Just (src, dst)
426 FMOV FF64 src dst -> Just (src, dst)
427 FMOV FF32 src dst -> Just (src, dst)
431 -- | Make an unconditional branch instruction.
437 = [BI ALWAYS False id
438 , NOP] -- fill the branch delay slot.