2 -----------------------------------------------------------------------------
4 -- Machine-specific parts of the register allocator
6 -- (c) The University of Glasgow 1996-2004
8 -----------------------------------------------------------------------------
10 module SPARC.RegInfo (
37 #include "nativeGen/NCG.h"
38 #include "HsVersions.h"
46 import Constants ( rESERVED_C_STACK_BYTES )
50 -- | Represents what regs are read and written to in an instruction.
53 = RU [Reg] -- regs read from
54 [Reg] -- regs written to
57 -- | No regs read or written to.
62 -- | regUsage returns the sets of src and destination registers used
63 -- by a particular instruction. Machine registers that are
64 -- pre-allocated to stgRegs are filtered out, because they are
65 -- uninteresting from a register allocation standpoint. (We wouldn't
66 -- want them to end up on the free list!) As far as we are concerned,
67 -- the fixed registers simply don't exist (for allocation purposes,
70 -- regUsage doesn't need to do any trickery for jumps and such. Just
71 -- state precisely the regs read and written by that insn. The
72 -- consequences of control flow transfers, as far as register
73 -- allocation goes, are taken care of by the register allocator.
75 regUsage :: Instr -> RegUsage
78 SPILL reg _ -> usage ([reg], [])
79 RELOAD _ reg -> usage ([], [reg])
81 LD _ addr reg -> usage (regAddr addr, [reg])
82 ST _ reg addr -> usage (reg : regAddr addr, [])
83 ADD _ _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
84 SUB _ _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
85 UMUL _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
86 SMUL _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
87 UDIV _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
88 SDIV _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
89 RDY rd -> usage ([], [rd])
90 WRY r1 r2 -> usage ([r1, r2], [])
91 AND _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
92 ANDN _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
93 OR _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
94 ORN _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
95 XOR _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
96 XNOR _ r1 ar r2 -> usage (r1 : regRI ar, [r2])
97 SLL r1 ar r2 -> usage (r1 : regRI ar, [r2])
98 SRL r1 ar r2 -> usage (r1 : regRI ar, [r2])
99 SRA r1 ar r2 -> usage (r1 : regRI ar, [r2])
100 SETHI _ reg -> usage ([], [reg])
101 FABS _ r1 r2 -> usage ([r1], [r2])
102 FADD _ r1 r2 r3 -> usage ([r1, r2], [r3])
103 FCMP _ _ r1 r2 -> usage ([r1, r2], [])
104 FDIV _ r1 r2 r3 -> usage ([r1, r2], [r3])
105 FMOV _ r1 r2 -> usage ([r1], [r2])
106 FMUL _ r1 r2 r3 -> usage ([r1, r2], [r3])
107 FNEG _ r1 r2 -> usage ([r1], [r2])
108 FSQRT _ r1 r2 -> usage ([r1], [r2])
109 FSUB _ r1 r2 r3 -> usage ([r1, r2], [r3])
110 FxTOy _ _ r1 r2 -> usage ([r1], [r2])
112 JMP addr -> usage (regAddr addr, [])
113 JMP_TBL addr _ -> usage (regAddr addr, [])
115 CALL (Left _ ) _ True -> noUsage
116 CALL (Left _ ) n False -> usage (argRegs n, callClobberedRegs)
117 CALL (Right reg) _ True -> usage ([reg], [])
118 CALL (Right reg) n False -> usage (reg : (argRegs n), callClobberedRegs)
123 = RU (filter interesting src) (filter interesting dst)
125 regAddr (AddrRegReg r1 r2) = [r1, r2]
126 regAddr (AddrRegImm r1 _) = [r1]
128 regRI (RIReg r) = [r]
132 -- | Interesting regs are virtuals, or ones that are allocatable
133 -- by the register allocator.
134 interesting :: Reg -> Bool
137 VirtualRegI _ -> True
138 VirtualRegHi _ -> True
139 VirtualRegF _ -> True
140 VirtualRegD _ -> True
141 RealReg i -> isFastTrue (freeReg i)
145 -- | Apply a given mapping to tall the register references in this instruction.
147 patchRegs :: Instr -> (Reg -> Reg) -> Instr
148 patchRegs instr env = case instr of
149 SPILL reg slot -> SPILL (env reg) slot
150 RELOAD slot reg -> RELOAD slot (env reg)
152 LD sz addr reg -> LD sz (fixAddr addr) (env reg)
153 ST sz reg addr -> ST sz (env reg) (fixAddr addr)
155 ADD x cc r1 ar r2 -> ADD x cc (env r1) (fixRI ar) (env r2)
156 SUB x cc r1 ar r2 -> SUB x cc (env r1) (fixRI ar) (env r2)
157 UMUL cc r1 ar r2 -> UMUL cc (env r1) (fixRI ar) (env r2)
158 SMUL cc r1 ar r2 -> SMUL cc (env r1) (fixRI ar) (env r2)
159 UDIV cc r1 ar r2 -> UDIV cc (env r1) (fixRI ar) (env r2)
160 SDIV cc r1 ar r2 -> SDIV cc (env r1) (fixRI ar) (env r2)
161 RDY rd -> RDY (env rd)
162 WRY r1 r2 -> WRY (env r1) (env r2)
163 AND b r1 ar r2 -> AND b (env r1) (fixRI ar) (env r2)
164 ANDN b r1 ar r2 -> ANDN b (env r1) (fixRI ar) (env r2)
165 OR b r1 ar r2 -> OR b (env r1) (fixRI ar) (env r2)
166 ORN b r1 ar r2 -> ORN b (env r1) (fixRI ar) (env r2)
167 XOR b r1 ar r2 -> XOR b (env r1) (fixRI ar) (env r2)
168 XNOR b r1 ar r2 -> XNOR b (env r1) (fixRI ar) (env r2)
169 SLL r1 ar r2 -> SLL (env r1) (fixRI ar) (env r2)
170 SRL r1 ar r2 -> SRL (env r1) (fixRI ar) (env r2)
171 SRA r1 ar r2 -> SRA (env r1) (fixRI ar) (env r2)
173 SETHI imm reg -> SETHI imm (env reg)
175 FABS s r1 r2 -> FABS s (env r1) (env r2)
176 FADD s r1 r2 r3 -> FADD s (env r1) (env r2) (env r3)
177 FCMP e s r1 r2 -> FCMP e s (env r1) (env r2)
178 FDIV s r1 r2 r3 -> FDIV s (env r1) (env r2) (env r3)
179 FMOV s r1 r2 -> FMOV s (env r1) (env r2)
180 FMUL s r1 r2 r3 -> FMUL s (env r1) (env r2) (env r3)
181 FNEG s r1 r2 -> FNEG s (env r1) (env r2)
182 FSQRT s r1 r2 -> FSQRT s (env r1) (env r2)
183 FSUB s r1 r2 r3 -> FSUB s (env r1) (env r2) (env r3)
184 FxTOy s1 s2 r1 r2 -> FxTOy s1 s2 (env r1) (env r2)
186 JMP addr -> JMP (fixAddr addr)
187 JMP_TBL addr ids -> JMP_TBL (fixAddr addr) ids
189 CALL (Left i) n t -> CALL (Left i) n t
190 CALL (Right r) n t -> CALL (Right (env r)) n t
194 fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
195 fixAddr (AddrRegImm r1 i) = AddrRegImm (env r1) i
197 fixRI (RIReg r) = RIReg (env r)
201 -- -----------------------------------------------------------------------------
202 -- Determine the possible destinations from the current instruction.
204 -- (we always assume that the next instruction is also a valid destination;
205 -- if this isn't the case then the jump should be at the end of the basic
208 jumpDests :: Instr -> [BlockId] -> [BlockId]
211 BI _ _ id -> id : acc
212 BF _ _ id -> id : acc
213 JMP_TBL _ ids -> ids ++ acc
217 -- | Check whether a particular instruction is a jump, branch or call instruction (jumpish)
218 -- We can't just use jumpDests above because the jump might take its arg,
219 -- so the instr won't contain a blockid.
221 isJumpish :: Instr -> Bool
232 -- | Change the destination of this jump instruction
233 -- Used in joinToTargets in the linear allocator, when emitting fixup code
235 patchJump :: Instr -> BlockId -> BlockId -> Instr
236 patchJump insn old new
239 | id == old -> BI cc annul new
242 | id == old -> BF cc annul new
249 data JumpDest = DestBlockId BlockId | DestImm Imm
251 canShortcut :: Instr -> Maybe JumpDest
252 canShortcut _ = Nothing
254 shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
255 shortcutJump _ other = other
259 -- | Make a spill instruction.
260 -- On SPARC we spill below frame pointer leaving 2 words/spill
262 :: Reg -- ^ register to spill
263 -> Int -- ^ current stack delta
264 -> Int -- ^ spill slot to use
267 mkSpillInstr reg _ slot
268 = let off = spillSlotToOffset slot
269 off_w = 1 + (off `div` 4)
270 sz = case regClass reg of
275 in ST sz reg (fpRel (negate off_w))
278 -- | Make a spill reload instruction.
280 :: Reg -- ^ register to load
281 -> Int -- ^ current stack delta
282 -> Int -- ^ spill slot to use
285 mkLoadInstr reg _ slot
286 = let off = spillSlotToOffset slot
287 off_w = 1 + (off `div` 4)
288 sz = case regClass reg of
293 in LD sz (fpRel (- off_w)) reg
296 -- | Make a reg-reg move instruction.
297 -- On SPARC v8 there are no instructions to move directly between
298 -- floating point and integer regs. If we need to do that then we
299 -- have to go via memory.
306 mkRegRegMoveInstr src dst
307 = case regClass src of
308 RcInteger -> ADD False False src (RIReg g0) dst
309 RcDouble -> FMOV FF64 src dst
310 RcFloat -> FMOV FF32 src dst
313 -- | Check whether an instruction represents a reg-reg move.
314 -- The register allocator attempts to eliminate reg->reg moves whenever it can,
315 -- by assigning the src and dest temporaries to the same real register.
317 isRegRegMove :: Instr -> Maybe (Reg,Reg)
320 ADD False False src (RIReg src2) dst
321 | g0 == src2 -> Just (src, dst)
323 FMOV FF64 src dst -> Just (src, dst)
324 FMOV FF32 src dst -> Just (src, dst)
328 -- | Make an unconditional branch instruction.
334 = [BI ALWAYS False id
335 , NOP] -- fill the branch delay slot.
338 -- | TODO: Why do we need 8 bytes per slot?? -BL 2009/02
343 -- | The maximum number of spill slots available on the C stack.
344 -- If we use up all of the slots, then we're screwed.
346 maxSpillSlots = ((rESERVED_C_STACK_BYTES - 64) `div` spillSlotSize) - 1
349 -- | Convert a spill slot number to a *byte* offset, with no sign.
351 spillSlotToOffset :: Int -> Int
352 spillSlotToOffset slot
353 | slot >= 0 && slot < maxSpillSlots
354 = 64 + spillSlotSize * slot
357 = pprPanic "spillSlotToOffset:"
358 ( text "invalid spill location: " <> int slot
359 $$ text "maxSpillSlots: " <> int maxSpillSlots)