1 -----------------------------------------------------------------------------
3 -- Machine-dependent assembly language
5 -- (c) The University of Glasgow 1993-2004
7 -----------------------------------------------------------------------------
9 #include "HsVersions.h"
10 #include "nativeGen/NCG.h"
28 import Constants (rESERVED_C_STACK_BYTES)
36 --------------------------------------------------------------------------------
37 -- Size of a PPC memory address, in bytes.
43 -- | Instruction instance for powerpc
44 instance Instruction Instr where
45 regUsageOfInstr = ppc_regUsageOfInstr
46 patchRegsOfInstr = ppc_patchRegsOfInstr
47 isJumpishInstr = ppc_isJumpishInstr
48 jumpDestsOfInstr = ppc_jumpDestsOfInstr
49 patchJumpInstr = ppc_patchJumpInstr
50 mkSpillInstr = ppc_mkSpillInstr
51 mkLoadInstr = ppc_mkLoadInstr
52 takeDeltaInstr = ppc_takeDeltaInstr
53 isMetaInstr = ppc_isMetaInstr
54 mkRegRegMoveInstr = ppc_mkRegRegMoveInstr
55 takeRegRegMoveInstr = ppc_takeRegRegMoveInstr
56 mkJumpInstr = ppc_mkJumpInstr
59 -- -----------------------------------------------------------------------------
60 -- Machine's assembly language
62 -- We have a few common "instructions" (nearly all the pseudo-ops) but
63 -- mostly all of 'Instr' is machine-specific.
65 -- Register or immediate
74 -- some static data spat out during code
75 -- generation. Will be extracted before
77 | LDATA Section [CmmStatic]
79 -- start a new basic block. Useful during
80 -- codegen, removed later. Preceding
81 -- instruction should be a jump, as per the
82 -- invariants for a BasicBlock (see Cmm).
85 -- specify current stack offset for
86 -- benefit of subsequent passes
90 | LD Size Reg AddrMode -- Load size, dst, src
91 | LA Size Reg AddrMode -- Load arithmetic size, dst, src
92 | ST Size Reg AddrMode -- Store size, src, dst
93 | STU Size Reg AddrMode -- Store with Update size, src, dst
94 | LIS Reg Imm -- Load Immediate Shifted dst, src
95 | LI Reg Imm -- Load Immediate dst, src
96 | MR Reg Reg -- Move Register dst, src -- also for fmr
98 | CMP Size Reg RI --- size, src1, src2
99 | CMPL Size Reg RI --- size, src1, src2
102 | BCCFAR Cond BlockId
103 | JMP CLabel -- same as branch,
104 -- but with CLabel instead of block ID
106 | BCTR [BlockId] -- with list of local destinations
107 | BL CLabel [Reg] -- with list of argument regs
110 | ADD Reg Reg RI -- dst, src1, src2
111 | ADDC Reg Reg Reg -- (carrying) dst, src1, src2
112 | ADDE Reg Reg Reg -- (extend) dst, src1, src2
113 | ADDIS Reg Reg Imm -- Add Immediate Shifted dst, src1, src2
114 | SUBF Reg Reg Reg -- dst, src1, src2 ; dst = src2 - src1
119 | MULLW_MayOflo Reg Reg Reg
120 -- dst = 1 if src1 * src2 overflows
121 -- pseudo-instruction; pretty-printed as:
122 -- mullwo. dst, src1, src2
124 -- rlwinm dst, dst, 2, 31,31
126 | AND Reg Reg RI -- dst, src1, src2
127 | OR Reg Reg RI -- dst, src1, src2
128 | XOR Reg Reg RI -- dst, src1, src2
129 | XORIS Reg Reg Imm -- XOR Immediate Shifted dst, src1, src2
136 | SLW Reg Reg RI -- shift left word
137 | SRW Reg Reg RI -- shift right word
138 | SRAW Reg Reg RI -- shift right arithmetic word
140 -- Rotate Left Word Immediate then AND with Mask
141 | RLWINM Reg Reg Int Int Int
143 | FADD Size Reg Reg Reg
144 | FSUB Size Reg Reg Reg
145 | FMUL Size Reg Reg Reg
146 | FDIV Size Reg Reg Reg
147 | FNEG Reg Reg -- negate is the same for single and double prec.
151 | FCTIWZ Reg Reg -- convert to integer word
152 | FRSP Reg Reg -- reduce to single precision
153 -- (but destination is a FP register)
155 | CRNOR Int Int Int -- condition register nor
156 | MFCR Reg -- move from condition register
158 | MFLR Reg -- move from link register
159 | FETCHPC Reg -- pseudo-instruction:
160 -- bcl to next insn, mflr reg
162 | LWSYNC -- memory barrier
165 -- | Get the registers that are being used by this instruction.
166 -- regUsage doesn't need to do any trickery for jumps and such.
167 -- Just state precisely the regs read and written by that insn.
168 -- The consequences of control flow transfers, as far as register
169 -- allocation goes, are taken care of by the register allocator.
171 ppc_regUsageOfInstr :: Instr -> RegUsage
172 ppc_regUsageOfInstr instr
174 LD _ reg addr -> usage (regAddr addr, [reg])
175 LA _ reg addr -> usage (regAddr addr, [reg])
176 ST _ reg addr -> usage (reg : regAddr addr, [])
177 STU _ reg addr -> usage (reg : regAddr addr, [])
178 LIS reg _ -> usage ([], [reg])
179 LI reg _ -> usage ([], [reg])
180 MR reg1 reg2 -> usage ([reg2], [reg1])
181 CMP _ reg ri -> usage (reg : regRI ri,[])
182 CMPL _ reg ri -> usage (reg : regRI ri,[])
184 BCCFAR _ _ -> noUsage
185 MTCTR reg -> usage ([reg],[])
187 BL _ params -> usage (params, callClobberedRegs)
188 BCTRL params -> usage (params, callClobberedRegs)
189 ADD reg1 reg2 ri -> usage (reg2 : regRI ri, [reg1])
190 ADDC reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
191 ADDE reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
192 ADDIS reg1 reg2 _ -> usage ([reg2], [reg1])
193 SUBF reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
194 MULLW reg1 reg2 ri -> usage (reg2 : regRI ri, [reg1])
195 DIVW reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
196 DIVWU reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
197 MULLW_MayOflo reg1 reg2 reg3
198 -> usage ([reg2,reg3], [reg1])
199 AND reg1 reg2 ri -> usage (reg2 : regRI ri, [reg1])
200 OR reg1 reg2 ri -> usage (reg2 : regRI ri, [reg1])
201 XOR reg1 reg2 ri -> usage (reg2 : regRI ri, [reg1])
202 XORIS reg1 reg2 _ -> usage ([reg2], [reg1])
203 EXTS _ reg1 reg2 -> usage ([reg2], [reg1])
204 NEG reg1 reg2 -> usage ([reg2], [reg1])
205 NOT reg1 reg2 -> usage ([reg2], [reg1])
206 SLW reg1 reg2 ri -> usage (reg2 : regRI ri, [reg1])
207 SRW reg1 reg2 ri -> usage (reg2 : regRI ri, [reg1])
208 SRAW reg1 reg2 ri -> usage (reg2 : regRI ri, [reg1])
209 RLWINM reg1 reg2 _ _ _
210 -> usage ([reg2], [reg1])
211 FADD _ r1 r2 r3 -> usage ([r2,r3], [r1])
212 FSUB _ r1 r2 r3 -> usage ([r2,r3], [r1])
213 FMUL _ r1 r2 r3 -> usage ([r2,r3], [r1])
214 FDIV _ r1 r2 r3 -> usage ([r2,r3], [r1])
215 FNEG r1 r2 -> usage ([r2], [r1])
216 FCMP r1 r2 -> usage ([r1,r2], [])
217 FCTIWZ r1 r2 -> usage ([r2], [r1])
218 FRSP r1 r2 -> usage ([r2], [r1])
219 MFCR reg -> usage ([], [reg])
220 MFLR reg -> usage ([], [reg])
221 FETCHPC reg -> usage ([], [reg])
224 usage (src, dst) = RU (filter interesting src)
225 (filter interesting dst)
226 regAddr (AddrRegReg r1 r2) = [r1, r2]
227 regAddr (AddrRegImm r1 _) = [r1]
229 regRI (RIReg r) = [r]
232 interesting :: Reg -> Bool
233 interesting (VirtualRegI _) = True
234 interesting (VirtualRegHi _) = True
235 interesting (VirtualRegF _) = True
236 interesting (VirtualRegD _) = True
237 interesting (RealReg i) = isFastTrue (freeReg i)
242 -- | Apply a given mapping to all the register references in this
244 ppc_patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
245 ppc_patchRegsOfInstr instr env
247 LD sz reg addr -> LD sz (env reg) (fixAddr addr)
248 LA sz reg addr -> LA sz (env reg) (fixAddr addr)
249 ST sz reg addr -> ST sz (env reg) (fixAddr addr)
250 STU sz reg addr -> STU sz (env reg) (fixAddr addr)
251 LIS reg imm -> LIS (env reg) imm
252 LI reg imm -> LI (env reg) imm
253 MR reg1 reg2 -> MR (env reg1) (env reg2)
254 CMP sz reg ri -> CMP sz (env reg) (fixRI ri)
255 CMPL sz reg ri -> CMPL sz (env reg) (fixRI ri)
256 BCC cond lbl -> BCC cond lbl
257 BCCFAR cond lbl -> BCCFAR cond lbl
258 MTCTR reg -> MTCTR (env reg)
259 BCTR targets -> BCTR targets
260 BL imm argRegs -> BL imm argRegs -- argument regs
261 BCTRL argRegs -> BCTRL argRegs -- cannot be remapped
262 ADD reg1 reg2 ri -> ADD (env reg1) (env reg2) (fixRI ri)
263 ADDC reg1 reg2 reg3-> ADDC (env reg1) (env reg2) (env reg3)
264 ADDE reg1 reg2 reg3-> ADDE (env reg1) (env reg2) (env reg3)
265 ADDIS reg1 reg2 imm -> ADDIS (env reg1) (env reg2) imm
266 SUBF reg1 reg2 reg3-> SUBF (env reg1) (env reg2) (env reg3)
267 MULLW reg1 reg2 ri -> MULLW (env reg1) (env reg2) (fixRI ri)
268 DIVW reg1 reg2 reg3-> DIVW (env reg1) (env reg2) (env reg3)
269 DIVWU reg1 reg2 reg3-> DIVWU (env reg1) (env reg2) (env reg3)
270 MULLW_MayOflo reg1 reg2 reg3
271 -> MULLW_MayOflo (env reg1) (env reg2) (env reg3)
272 AND reg1 reg2 ri -> AND (env reg1) (env reg2) (fixRI ri)
273 OR reg1 reg2 ri -> OR (env reg1) (env reg2) (fixRI ri)
274 XOR reg1 reg2 ri -> XOR (env reg1) (env reg2) (fixRI ri)
275 XORIS reg1 reg2 imm -> XORIS (env reg1) (env reg2) imm
276 EXTS sz reg1 reg2 -> EXTS sz (env reg1) (env reg2)
277 NEG reg1 reg2 -> NEG (env reg1) (env reg2)
278 NOT reg1 reg2 -> NOT (env reg1) (env reg2)
279 SLW reg1 reg2 ri -> SLW (env reg1) (env reg2) (fixRI ri)
280 SRW reg1 reg2 ri -> SRW (env reg1) (env reg2) (fixRI ri)
281 SRAW reg1 reg2 ri -> SRAW (env reg1) (env reg2) (fixRI ri)
282 RLWINM reg1 reg2 sh mb me
283 -> RLWINM (env reg1) (env reg2) sh mb me
284 FADD sz r1 r2 r3 -> FADD sz (env r1) (env r2) (env r3)
285 FSUB sz r1 r2 r3 -> FSUB sz (env r1) (env r2) (env r3)
286 FMUL sz r1 r2 r3 -> FMUL sz (env r1) (env r2) (env r3)
287 FDIV sz r1 r2 r3 -> FDIV sz (env r1) (env r2) (env r3)
288 FNEG r1 r2 -> FNEG (env r1) (env r2)
289 FCMP r1 r2 -> FCMP (env r1) (env r2)
290 FCTIWZ r1 r2 -> FCTIWZ (env r1) (env r2)
291 FRSP r1 r2 -> FRSP (env r1) (env r2)
292 MFCR reg -> MFCR (env reg)
293 MFLR reg -> MFLR (env reg)
294 FETCHPC reg -> FETCHPC (env reg)
297 fixAddr (AddrRegReg r1 r2) = AddrRegReg (env r1) (env r2)
298 fixAddr (AddrRegImm r1 i) = AddrRegImm (env r1) i
300 fixRI (RIReg r) = RIReg (env r)
304 --------------------------------------------------------------------------------
305 -- | Checks whether this instruction is a jump/branch instruction.
306 -- One that can change the flow of control in a way that the
307 -- register allocator needs to worry about.
308 ppc_isJumpishInstr :: Instr -> Bool
309 ppc_isJumpishInstr instr
320 -- | Checks whether this instruction is a jump/branch instruction.
321 -- One that can change the flow of control in a way that the
322 -- register allocator needs to worry about.
323 ppc_jumpDestsOfInstr :: Instr -> [BlockId]
324 ppc_jumpDestsOfInstr insn
328 BCTR targets -> targets
332 -- | Change the destination of this jump instruction.
333 -- Used in the linear allocator when adding fixup blocks for join
335 ppc_patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
336 ppc_patchJumpInstr insn patchF
338 BCC cc id -> BCC cc (patchF id)
339 BCCFAR cc id -> BCCFAR cc (patchF id)
340 BCTR _ -> error "Cannot patch BCTR"
344 -- -----------------------------------------------------------------------------
346 -- | An instruction to spill a register into a spill slot.
348 :: Reg -- register to spill
349 -> Int -- current stack delta
350 -> Int -- spill slot to use
353 ppc_mkSpillInstr reg delta slot
354 = let off = spillSlotToOffset slot
356 let sz = case regClass reg of
359 _ -> panic "PPC.Instr.mkSpillInstr: no match"
360 in ST sz reg (AddrRegImm sp (ImmInt (off-delta)))
364 :: Reg -- register to load
365 -> Int -- current stack delta
366 -> Int -- spill slot to use
369 ppc_mkLoadInstr reg delta slot
370 = let off = spillSlotToOffset slot
372 let sz = case regClass reg of
375 _ -> panic "PPC.Instr.mkLoadInstr: no match"
376 in LD sz reg (AddrRegImm sp (ImmInt (off-delta)))
383 maxSpillSlots = ((rESERVED_C_STACK_BYTES - 64) `div` spillSlotSize) - 1
385 -- convert a spill slot number to a *byte* offset, with no sign:
386 -- decide on a per arch basis whether you are spilling above or below
387 -- the C stack pointer.
388 spillSlotToOffset :: Int -> Int
389 spillSlotToOffset slot
390 | slot >= 0 && slot < maxSpillSlots
391 = 64 + spillSlotSize * slot
393 = pprPanic "spillSlotToOffset:"
394 ( text "invalid spill location: " <> int slot
395 $$ text "maxSpillSlots: " <> int maxSpillSlots)
398 --------------------------------------------------------------------------------
399 -- | See if this instruction is telling us the current C stack delta
404 ppc_takeDeltaInstr instr
414 ppc_isMetaInstr instr
423 -- | Copy the value in a register to another one.
424 -- Must work for all register classes.
425 ppc_mkRegRegMoveInstr
430 ppc_mkRegRegMoveInstr src dst
434 -- | Make an unconditional jump instruction.
435 -- For architectures with branch delay slots, its ok to put
436 -- a NOP after the jump. Don't fill the delay slot with an
437 -- instruction that references regs or you'll confuse the
447 -- | Take the source and destination from this reg -> reg move instruction
448 -- or Nothing if it's not one
449 ppc_takeRegRegMoveInstr :: Instr -> Maybe (Reg,Reg)
450 ppc_takeRegRegMoveInstr (MR dst src) = Just (src,dst)
451 ppc_takeRegRegMoveInstr _ = Nothing