1 -----------------------------------------------------------------------------
3 -- Pretty-printing assembly language
5 -- (c) The University of Glasgow 1993-2005
7 -----------------------------------------------------------------------------
9 -- We start with the @pprXXX@s with some cross-platform commonality
10 -- (e.g., 'pprReg'); we conclude with the no-commonality monster,
13 #include "nativeGen/NCG.h"
16 pprNatCmmTop, pprBasicBlock,
17 pprInstr, pprSize, pprUserReg,
21 #include "HsVersions.h"
24 import MachOp ( MachRep(..), wordRep, isFloatingRep )
25 import MachRegs -- may differ per-platform
28 import CLabel ( CLabel, pprCLabel, externallyVisibleCLabel,
29 labelDynamic, mkAsmTempLabel, entryLblToInfoLbl )
30 #if HAVE_SUBSECTIONS_VIA_SYMBOLS
31 import CLabel ( mkDeadStripPreventer )
34 import Panic ( panic )
35 import Unique ( pprUnique )
38 import qualified Outputable
40 import StaticFlags ( opt_PIC, opt_Static )
42 #if __GLASGOW_HASKELL__ >= 504
44 import Data.Word ( Word8 )
50 import Char ( chr, ord )
52 #if powerpc_TARGET_ARCH
53 import DATA_WORD(Word32)
57 -- -----------------------------------------------------------------------------
58 -- Printing this stuff out
60 asmSDoc d = Outputable.withPprStyleDoc (
61 Outputable.mkCodeStyle Outputable.AsmStyle) d
62 pprCLabel_asm l = asmSDoc (pprCLabel l)
64 pprNatCmmTop :: NatCmmTop -> Doc
65 pprNatCmmTop (CmmData section dats) =
66 pprSectionHeader section $$ vcat (map pprData dats)
68 -- special case for split markers:
69 pprNatCmmTop (CmmProc [] lbl _ []) = pprLabel lbl
71 pprNatCmmTop (CmmProc info lbl params blocks) =
72 pprSectionHeader Text $$
75 #if HAVE_SUBSECTIONS_VIA_SYMBOLS
76 pprCLabel_asm (mkDeadStripPreventer $ entryLblToInfoLbl lbl)
79 vcat (map pprData info) $$
80 pprLabel (entryLblToInfoLbl lbl)
84 (BasicBlock _ instrs : rest) ->
85 (if null info then pprLabel lbl else empty) $$
86 -- the first block doesn't get a label:
87 vcat (map pprInstr instrs) $$
88 vcat (map pprBasicBlock rest)
90 #if HAVE_SUBSECTIONS_VIA_SYMBOLS
91 -- If we are using the .subsections_via_symbols directive
92 -- (available on recent versions of Darwin),
93 -- we have to make sure that there is some kind of reference
94 -- from the entry code to a label on the _top_ of of the info table,
95 -- so that the linker will not think it is unreferenced and dead-strip
96 -- it. That's why the label is called a DeadStripPreventer (_dsp).
99 <+> pprCLabel_asm (entryLblToInfoLbl lbl)
101 <+> pprCLabel_asm (mkDeadStripPreventer $ entryLblToInfoLbl lbl)
106 pprBasicBlock :: NatBasicBlock -> Doc
107 pprBasicBlock (BasicBlock (BlockId id) instrs) =
108 pprLabel (mkAsmTempLabel id) $$
109 vcat (map pprInstr instrs)
111 -- -----------------------------------------------------------------------------
112 -- pprReg: print a 'Reg'
114 -- For x86, the way we print a register name depends
115 -- on which bit of it we care about. Yurgh.
117 pprUserReg :: Reg -> Doc
118 pprUserReg = pprReg IF_ARCH_i386(I32,) IF_ARCH_x86_64(I64,)
120 pprReg :: IF_ARCH_i386(MachRep ->,) IF_ARCH_x86_64(MachRep ->,) Reg -> Doc
122 pprReg IF_ARCH_i386(s,) IF_ARCH_x86_64(s,) r
124 RealReg i -> ppr_reg_no IF_ARCH_i386(s,) IF_ARCH_x86_64(s,) i
125 VirtualRegI u -> text "%vI_" <> asmSDoc (pprUnique u)
126 VirtualRegHi u -> text "%vHi_" <> asmSDoc (pprUnique u)
127 VirtualRegF u -> text "%vF_" <> asmSDoc (pprUnique u)
128 VirtualRegD u -> text "%vD_" <> asmSDoc (pprUnique u)
130 #if alpha_TARGET_ARCH
131 ppr_reg_no :: Int -> Doc
134 0 -> SLIT("$0"); 1 -> SLIT("$1");
135 2 -> SLIT("$2"); 3 -> SLIT("$3");
136 4 -> SLIT("$4"); 5 -> SLIT("$5");
137 6 -> SLIT("$6"); 7 -> SLIT("$7");
138 8 -> SLIT("$8"); 9 -> SLIT("$9");
139 10 -> SLIT("$10"); 11 -> SLIT("$11");
140 12 -> SLIT("$12"); 13 -> SLIT("$13");
141 14 -> SLIT("$14"); 15 -> SLIT("$15");
142 16 -> SLIT("$16"); 17 -> SLIT("$17");
143 18 -> SLIT("$18"); 19 -> SLIT("$19");
144 20 -> SLIT("$20"); 21 -> SLIT("$21");
145 22 -> SLIT("$22"); 23 -> SLIT("$23");
146 24 -> SLIT("$24"); 25 -> SLIT("$25");
147 26 -> SLIT("$26"); 27 -> SLIT("$27");
148 28 -> SLIT("$28"); 29 -> SLIT("$29");
149 30 -> SLIT("$30"); 31 -> SLIT("$31");
150 32 -> SLIT("$f0"); 33 -> SLIT("$f1");
151 34 -> SLIT("$f2"); 35 -> SLIT("$f3");
152 36 -> SLIT("$f4"); 37 -> SLIT("$f5");
153 38 -> SLIT("$f6"); 39 -> SLIT("$f7");
154 40 -> SLIT("$f8"); 41 -> SLIT("$f9");
155 42 -> SLIT("$f10"); 43 -> SLIT("$f11");
156 44 -> SLIT("$f12"); 45 -> SLIT("$f13");
157 46 -> SLIT("$f14"); 47 -> SLIT("$f15");
158 48 -> SLIT("$f16"); 49 -> SLIT("$f17");
159 50 -> SLIT("$f18"); 51 -> SLIT("$f19");
160 52 -> SLIT("$f20"); 53 -> SLIT("$f21");
161 54 -> SLIT("$f22"); 55 -> SLIT("$f23");
162 56 -> SLIT("$f24"); 57 -> SLIT("$f25");
163 58 -> SLIT("$f26"); 59 -> SLIT("$f27");
164 60 -> SLIT("$f28"); 61 -> SLIT("$f29");
165 62 -> SLIT("$f30"); 63 -> SLIT("$f31");
166 _ -> SLIT("very naughty alpha register")
170 ppr_reg_no :: MachRep -> Int -> Doc
171 ppr_reg_no I8 = ppr_reg_byte
172 ppr_reg_no I16 = ppr_reg_word
173 ppr_reg_no _ = ppr_reg_long
175 ppr_reg_byte i = ptext
177 0 -> SLIT("%al"); 1 -> SLIT("%bl");
178 2 -> SLIT("%cl"); 3 -> SLIT("%dl");
179 _ -> SLIT("very naughty I386 byte register")
182 ppr_reg_word i = ptext
184 0 -> SLIT("%ax"); 1 -> SLIT("%bx");
185 2 -> SLIT("%cx"); 3 -> SLIT("%dx");
186 4 -> SLIT("%si"); 5 -> SLIT("%di");
187 6 -> SLIT("%bp"); 7 -> SLIT("%sp");
188 _ -> SLIT("very naughty I386 word register")
191 ppr_reg_long i = ptext
193 0 -> SLIT("%eax"); 1 -> SLIT("%ebx");
194 2 -> SLIT("%ecx"); 3 -> SLIT("%edx");
195 4 -> SLIT("%esi"); 5 -> SLIT("%edi");
196 6 -> SLIT("%ebp"); 7 -> SLIT("%esp");
197 8 -> SLIT("%fake0"); 9 -> SLIT("%fake1");
198 10 -> SLIT("%fake2"); 11 -> SLIT("%fake3");
199 12 -> SLIT("%fake4"); 13 -> SLIT("%fake5");
200 _ -> SLIT("very naughty I386 register")
204 #if x86_64_TARGET_ARCH
205 ppr_reg_no :: MachRep -> Int -> Doc
206 ppr_reg_no I8 = ppr_reg_byte
207 ppr_reg_no I16 = ppr_reg_word
208 ppr_reg_no I32 = ppr_reg_long
209 ppr_reg_no _ = ppr_reg_quad
211 ppr_reg_byte i = ptext
213 0 -> SLIT("%al"); 1 -> SLIT("%bl");
214 2 -> SLIT("%cl"); 3 -> SLIT("%dl");
215 4 -> SLIT("%sil"); 5 -> SLIT("%dil"); -- new 8-bit regs!
216 6 -> SLIT("%bpl"); 7 -> SLIT("%spl");
217 8 -> SLIT("%r8b"); 9 -> SLIT("%r9b");
218 10 -> SLIT("%r10b"); 11 -> SLIT("%r11b");
219 12 -> SLIT("%r12b"); 13 -> SLIT("%r13b");
220 14 -> SLIT("%r14b"); 15 -> SLIT("%r15b");
221 _ -> SLIT("very naughty x86_64 byte register")
224 ppr_reg_word i = ptext
226 0 -> SLIT("%ax"); 1 -> SLIT("%bx");
227 2 -> SLIT("%cx"); 3 -> SLIT("%dx");
228 4 -> SLIT("%si"); 5 -> SLIT("%di");
229 6 -> SLIT("%bp"); 7 -> SLIT("%sp");
230 8 -> SLIT("%r8w"); 9 -> SLIT("%r9w");
231 10 -> SLIT("%r10w"); 11 -> SLIT("%r11w");
232 12 -> SLIT("%r12w"); 13 -> SLIT("%r13w");
233 14 -> SLIT("%r14w"); 15 -> SLIT("%r15w");
234 _ -> SLIT("very naughty x86_64 word register")
237 ppr_reg_long i = ptext
239 0 -> SLIT("%eax"); 1 -> SLIT("%ebx");
240 2 -> SLIT("%ecx"); 3 -> SLIT("%edx");
241 4 -> SLIT("%esi"); 5 -> SLIT("%edi");
242 6 -> SLIT("%ebp"); 7 -> SLIT("%esp");
243 8 -> SLIT("%r8d"); 9 -> SLIT("%r9d");
244 10 -> SLIT("%r10d"); 11 -> SLIT("%r11d");
245 12 -> SLIT("%r12d"); 13 -> SLIT("%r13d");
246 14 -> SLIT("%r14d"); 15 -> SLIT("%r15d");
247 _ -> SLIT("very naughty x86_64 register")
250 ppr_reg_quad i = ptext
252 0 -> SLIT("%rax"); 1 -> SLIT("%rbx");
253 2 -> SLIT("%rcx"); 3 -> SLIT("%rdx");
254 4 -> SLIT("%rsi"); 5 -> SLIT("%rdi");
255 6 -> SLIT("%rbp"); 7 -> SLIT("%rsp");
256 8 -> SLIT("%r8"); 9 -> SLIT("%r9");
257 10 -> SLIT("%r10"); 11 -> SLIT("%r11");
258 12 -> SLIT("%r12"); 13 -> SLIT("%r13");
259 14 -> SLIT("%r14"); 15 -> SLIT("%r15");
260 16 -> SLIT("%xmm0"); 17 -> SLIT("%xmm1");
261 18 -> SLIT("%xmm2"); 19 -> SLIT("%xmm3");
262 20 -> SLIT("%xmm4"); 21 -> SLIT("%xmm5");
263 22 -> SLIT("%xmm6"); 23 -> SLIT("%xmm7");
264 24 -> SLIT("%xmm8"); 25 -> SLIT("%xmm9");
265 26 -> SLIT("%xmm10"); 27 -> SLIT("%xmm11");
266 28 -> SLIT("%xmm12"); 29 -> SLIT("%xmm13");
267 30 -> SLIT("%xmm14"); 31 -> SLIT("%xmm15");
268 _ -> SLIT("very naughty x86_64 register")
272 #if sparc_TARGET_ARCH
273 ppr_reg_no :: Int -> Doc
276 0 -> SLIT("%g0"); 1 -> SLIT("%g1");
277 2 -> SLIT("%g2"); 3 -> SLIT("%g3");
278 4 -> SLIT("%g4"); 5 -> SLIT("%g5");
279 6 -> SLIT("%g6"); 7 -> SLIT("%g7");
280 8 -> SLIT("%o0"); 9 -> SLIT("%o1");
281 10 -> SLIT("%o2"); 11 -> SLIT("%o3");
282 12 -> SLIT("%o4"); 13 -> SLIT("%o5");
283 14 -> SLIT("%o6"); 15 -> SLIT("%o7");
284 16 -> SLIT("%l0"); 17 -> SLIT("%l1");
285 18 -> SLIT("%l2"); 19 -> SLIT("%l3");
286 20 -> SLIT("%l4"); 21 -> SLIT("%l5");
287 22 -> SLIT("%l6"); 23 -> SLIT("%l7");
288 24 -> SLIT("%i0"); 25 -> SLIT("%i1");
289 26 -> SLIT("%i2"); 27 -> SLIT("%i3");
290 28 -> SLIT("%i4"); 29 -> SLIT("%i5");
291 30 -> SLIT("%i6"); 31 -> SLIT("%i7");
292 32 -> SLIT("%f0"); 33 -> SLIT("%f1");
293 34 -> SLIT("%f2"); 35 -> SLIT("%f3");
294 36 -> SLIT("%f4"); 37 -> SLIT("%f5");
295 38 -> SLIT("%f6"); 39 -> SLIT("%f7");
296 40 -> SLIT("%f8"); 41 -> SLIT("%f9");
297 42 -> SLIT("%f10"); 43 -> SLIT("%f11");
298 44 -> SLIT("%f12"); 45 -> SLIT("%f13");
299 46 -> SLIT("%f14"); 47 -> SLIT("%f15");
300 48 -> SLIT("%f16"); 49 -> SLIT("%f17");
301 50 -> SLIT("%f18"); 51 -> SLIT("%f19");
302 52 -> SLIT("%f20"); 53 -> SLIT("%f21");
303 54 -> SLIT("%f22"); 55 -> SLIT("%f23");
304 56 -> SLIT("%f24"); 57 -> SLIT("%f25");
305 58 -> SLIT("%f26"); 59 -> SLIT("%f27");
306 60 -> SLIT("%f28"); 61 -> SLIT("%f29");
307 62 -> SLIT("%f30"); 63 -> SLIT("%f31");
308 _ -> SLIT("very naughty sparc register")
311 #if powerpc_TARGET_ARCH
313 ppr_reg_no :: Int -> Doc
316 0 -> SLIT("r0"); 1 -> SLIT("r1");
317 2 -> SLIT("r2"); 3 -> SLIT("r3");
318 4 -> SLIT("r4"); 5 -> SLIT("r5");
319 6 -> SLIT("r6"); 7 -> SLIT("r7");
320 8 -> SLIT("r8"); 9 -> SLIT("r9");
321 10 -> SLIT("r10"); 11 -> SLIT("r11");
322 12 -> SLIT("r12"); 13 -> SLIT("r13");
323 14 -> SLIT("r14"); 15 -> SLIT("r15");
324 16 -> SLIT("r16"); 17 -> SLIT("r17");
325 18 -> SLIT("r18"); 19 -> SLIT("r19");
326 20 -> SLIT("r20"); 21 -> SLIT("r21");
327 22 -> SLIT("r22"); 23 -> SLIT("r23");
328 24 -> SLIT("r24"); 25 -> SLIT("r25");
329 26 -> SLIT("r26"); 27 -> SLIT("r27");
330 28 -> SLIT("r28"); 29 -> SLIT("r29");
331 30 -> SLIT("r30"); 31 -> SLIT("r31");
332 32 -> SLIT("f0"); 33 -> SLIT("f1");
333 34 -> SLIT("f2"); 35 -> SLIT("f3");
334 36 -> SLIT("f4"); 37 -> SLIT("f5");
335 38 -> SLIT("f6"); 39 -> SLIT("f7");
336 40 -> SLIT("f8"); 41 -> SLIT("f9");
337 42 -> SLIT("f10"); 43 -> SLIT("f11");
338 44 -> SLIT("f12"); 45 -> SLIT("f13");
339 46 -> SLIT("f14"); 47 -> SLIT("f15");
340 48 -> SLIT("f16"); 49 -> SLIT("f17");
341 50 -> SLIT("f18"); 51 -> SLIT("f19");
342 52 -> SLIT("f20"); 53 -> SLIT("f21");
343 54 -> SLIT("f22"); 55 -> SLIT("f23");
344 56 -> SLIT("f24"); 57 -> SLIT("f25");
345 58 -> SLIT("f26"); 59 -> SLIT("f27");
346 60 -> SLIT("f28"); 61 -> SLIT("f29");
347 62 -> SLIT("f30"); 63 -> SLIT("f31");
348 _ -> SLIT("very naughty powerpc register")
351 ppr_reg_no :: Int -> Doc
352 ppr_reg_no i | i <= 31 = int i -- GPRs
353 | i <= 63 = int (i-32) -- FPRs
354 | otherwise = ptext SLIT("very naughty powerpc register")
359 -- -----------------------------------------------------------------------------
360 -- pprSize: print a 'Size'
362 #if powerpc_TARGET_ARCH || i386_TARGET_ARCH || x86_64_TARGET_ARCH
363 pprSize :: MachRep -> Doc
365 pprSize :: Size -> Doc
368 pprSize x = ptext (case x of
369 #if alpha_TARGET_ARCH
372 -- W -> SLIT("w") UNUSED
373 -- Wu -> SLIT("wu") UNUSED
376 -- FF -> SLIT("f") UNUSED
377 -- DF -> SLIT("d") UNUSED
378 -- GF -> SLIT("g") UNUSED
379 -- SF -> SLIT("s") UNUSED
382 #if i386_TARGET_ARCH || x86_64_TARGET_ARCH
393 #if x86_64_TARGET_ARCH
394 F32 -> SLIT("ss") -- "scalar single-precision float" (SSE2)
395 F64 -> SLIT("sd") -- "scalar double-precision float" (SSE2)
397 #if sparc_TARGET_ARCH
406 pprStSize :: Size -> Doc
407 pprStSize x = ptext (case x of
416 #if powerpc_TARGET_ARCH
425 -- -----------------------------------------------------------------------------
426 -- pprCond: print a 'Cond'
428 pprCond :: Cond -> Doc
430 pprCond c = ptext (case c of {
431 #if alpha_TARGET_ARCH
441 #if i386_TARGET_ARCH || x86_64_TARGET_ARCH
442 GEU -> SLIT("ae"); LU -> SLIT("b");
443 EQQ -> SLIT("e"); GTT -> SLIT("g");
444 GE -> SLIT("ge"); GU -> SLIT("a");
445 LTT -> SLIT("l"); LE -> SLIT("le");
446 LEU -> SLIT("be"); NE -> SLIT("ne");
447 NEG -> SLIT("s"); POS -> SLIT("ns");
448 CARRY -> SLIT("c"); OFLO -> SLIT("o");
449 ALWAYS -> SLIT("mp") -- hack
451 #if sparc_TARGET_ARCH
452 ALWAYS -> SLIT(""); NEVER -> SLIT("n");
453 GEU -> SLIT("geu"); LU -> SLIT("lu");
454 EQQ -> SLIT("e"); GTT -> SLIT("g");
455 GE -> SLIT("ge"); GU -> SLIT("gu");
456 LTT -> SLIT("l"); LE -> SLIT("le");
457 LEU -> SLIT("leu"); NE -> SLIT("ne");
458 NEG -> SLIT("neg"); POS -> SLIT("pos");
459 VC -> SLIT("vc"); VS -> SLIT("vs")
461 #if powerpc_TARGET_ARCH
463 EQQ -> SLIT("eq"); NE -> SLIT("ne");
464 LTT -> SLIT("lt"); GE -> SLIT("ge");
465 GTT -> SLIT("gt"); LE -> SLIT("le");
466 LU -> SLIT("lt"); GEU -> SLIT("ge");
467 GU -> SLIT("gt"); LEU -> SLIT("le");
472 -- -----------------------------------------------------------------------------
473 -- pprImm: print an 'Imm'
477 pprImm (ImmInt i) = int i
478 pprImm (ImmInteger i) = integer i
479 pprImm (ImmCLbl l) = pprCLabel_asm l
480 pprImm (ImmIndex l i) = pprCLabel_asm l <> char '+' <> int i
481 pprImm (ImmLit s) = s
483 pprImm (ImmFloat _) = panic "pprImm:ImmFloat"
484 pprImm (ImmDouble _) = panic "pprImm:ImmDouble"
486 pprImm (ImmConstantSum a b) = pprImm a <> char '+' <> pprImm b
487 pprImm (ImmConstantDiff a b) = pprImm a <> char '-'
488 <> lparen <> pprImm b <> rparen
490 #if sparc_TARGET_ARCH
492 = hcat [ pp_lo, pprImm i, rparen ]
497 = hcat [ pp_hi, pprImm i, rparen ]
501 #if powerpc_TARGET_ARCH
504 = hcat [ pp_lo, pprImm i, rparen ]
509 = hcat [ pp_hi, pprImm i, rparen ]
514 = hcat [ pp_ha, pprImm i, rparen ]
520 = pprImm i <> text "@l"
523 = pprImm i <> text "@h"
526 = pprImm i <> text "@ha"
531 -- -----------------------------------------------------------------------------
532 -- @pprAddr: print an 'AddrMode'
534 pprAddr :: AddrMode -> Doc
536 #if alpha_TARGET_ARCH
537 pprAddr (AddrReg r) = parens (pprReg r)
538 pprAddr (AddrImm i) = pprImm i
539 pprAddr (AddrRegImm r1 i)
540 = (<>) (pprImm i) (parens (pprReg r1))
545 #if i386_TARGET_ARCH || x86_64_TARGET_ARCH
546 pprAddr (ImmAddr imm off)
547 = let pp_imm = pprImm imm
551 else if (off < 0) then
554 pp_imm <> char '+' <> int off
556 pprAddr (AddrBaseIndex base index displacement)
558 pp_disp = ppr_disp displacement
559 pp_off p = pp_disp <> char '(' <> p <> char ')'
560 pp_reg r = pprReg wordRep r
563 (Nothing, Nothing) -> pp_disp
564 (Just b, Nothing) -> pp_off (pp_reg b)
565 (Nothing, Just (r,i)) -> pp_off (comma <> pp_reg r <> comma <> int i)
566 (Just b, Just (r,i)) -> pp_off (pp_reg b <> comma <> pp_reg r
569 ppr_disp (ImmInt 0) = empty
570 ppr_disp imm = pprImm imm
575 #if sparc_TARGET_ARCH
576 pprAddr (AddrRegReg r1 (RealReg 0)) = pprReg r1
578 pprAddr (AddrRegReg r1 r2)
579 = hcat [ pprReg r1, char '+', pprReg r2 ]
581 pprAddr (AddrRegImm r1 (ImmInt i))
583 | not (fits13Bits i) = largeOffsetError i
584 | otherwise = hcat [ pprReg r1, pp_sign, int i ]
586 pp_sign = if i > 0 then char '+' else empty
588 pprAddr (AddrRegImm r1 (ImmInteger i))
590 | not (fits13Bits i) = largeOffsetError i
591 | otherwise = hcat [ pprReg r1, pp_sign, integer i ]
593 pp_sign = if i > 0 then char '+' else empty
595 pprAddr (AddrRegImm r1 imm)
596 = hcat [ pprReg r1, char '+', pprImm imm ]
601 #if powerpc_TARGET_ARCH
602 pprAddr (AddrRegReg r1 r2)
603 = pprReg r1 <+> ptext SLIT(", ") <+> pprReg r2
605 pprAddr (AddrRegImm r1 (ImmInt i)) = hcat [ int i, char '(', pprReg r1, char ')' ]
606 pprAddr (AddrRegImm r1 (ImmInteger i)) = hcat [ integer i, char '(', pprReg r1, char ')' ]
607 pprAddr (AddrRegImm r1 imm) = hcat [ pprImm imm, char '(', pprReg r1, char ')' ]
611 -- -----------------------------------------------------------------------------
612 -- pprData: print a 'CmmStatic'
614 pprSectionHeader Text
616 IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
617 ,IF_ARCH_sparc(SLIT(".text\n\t.align 4") {-word boundary-}
618 ,IF_ARCH_i386(SLIT(".text\n\t.align 4,0x90") {-needs per-OS variation!-}
619 ,IF_ARCH_x86_64(SLIT(".text\n\t.align 8") {-needs per-OS variation!-}
620 ,IF_ARCH_powerpc(SLIT(".text\n.align 2")
622 pprSectionHeader Data
624 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
625 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
626 ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
627 ,IF_ARCH_x86_64(SLIT(".data\n\t.align 8")
628 ,IF_ARCH_powerpc(SLIT(".data\n.align 2")
630 pprSectionHeader ReadOnlyData
632 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
633 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
634 ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
635 ,IF_ARCH_x86_64(SLIT(".section .rodata\n\t.align 8")
636 ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const\n.align 2"),
637 SLIT(".section .rodata\n\t.align 2"))
639 pprSectionHeader RelocatableReadOnlyData
641 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
642 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
643 ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
644 ,IF_ARCH_x86_64(SLIT(".section .rodata\n\t.align 8")
645 ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
646 SLIT(".data\n\t.align 2"))
648 pprSectionHeader UninitialisedData
650 IF_ARCH_alpha(SLIT("\t.bss\n\t.align 3")
651 ,IF_ARCH_sparc(SLIT(".bss\n\t.align 8") {-<8 will break double constants -}
652 ,IF_ARCH_i386(SLIT(".section .bss\n\t.align 4")
653 ,IF_ARCH_x86_64(SLIT(".section .bss\n\t.align 8")
654 ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
655 SLIT(".section .bss\n\t.align 2"))
657 pprSectionHeader ReadOnlyData16
659 IF_ARCH_alpha(SLIT("\t.data\n\t.align 4")
660 ,IF_ARCH_sparc(SLIT(".data\n\t.align 16")
661 ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 16")
662 ,IF_ARCH_x86_64(SLIT(".section .rodata.cst16\n\t.align 16")
663 ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const\n.align 4"),
664 SLIT(".section .rodata\n\t.align 4"))
667 pprSectionHeader (OtherSection sec)
668 = panic "PprMach.pprSectionHeader: unknown section"
670 pprData :: CmmStatic -> Doc
671 pprData (CmmAlign bytes) = pprAlign bytes
672 pprData (CmmDataLabel lbl) = pprLabel lbl
673 pprData (CmmString str) = pprASCII str
674 pprData (CmmUninitialised bytes) = ptext SLIT(".space ") <> int bytes
675 pprData (CmmStaticLit lit) = pprDataItem lit
677 pprGloblDecl :: CLabel -> Doc
679 | not (externallyVisibleCLabel lbl) = empty
680 | otherwise = ptext IF_ARCH_sparc(SLIT(".global "),
684 pprLabel :: CLabel -> Doc
685 pprLabel lbl = pprGloblDecl lbl $$ (pprCLabel_asm lbl <> char ':')
688 -- Assume we want to backslash-convert the string
690 = vcat (map do1 (str ++ [chr 0]))
693 do1 c = ptext SLIT("\t.byte\t0x") <> hshow (ord c)
696 hshow n | n >= 0 && n <= 255
697 = char (tab !! (n `div` 16)) <> char (tab !! (n `mod` 16))
698 tab = "0123456789ABCDEF"
701 IF_ARCH_alpha(ptextSLIT(".align ") <> int pow2,
702 IF_ARCH_i386(ptext SLIT(".align ") <> int bytes,
703 IF_ARCH_x86_64(ptext SLIT(".align ") <> int bytes,
704 IF_ARCH_sparc(ptext SLIT(".align ") <> int bytes,
705 IF_ARCH_powerpc(ptext SLIT(".align ") <> int pow2,)))))
709 log2 :: Int -> Int -- cache the common ones
714 log2 n = 1 + log2 (n `quot` 2)
717 pprDataItem :: CmmLit -> Doc
719 = vcat (ppr_item (cmmLitRep lit) lit)
723 -- These seem to be common:
724 ppr_item I8 x = [ptext SLIT("\t.byte\t") <> pprImm imm]
725 ppr_item I32 x = [ptext SLIT("\t.long\t") <> pprImm imm]
726 ppr_item F32 (CmmFloat r _)
727 = let bs = floatToBytes (fromRational r)
728 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
729 ppr_item F64 (CmmFloat r _)
730 = let bs = doubleToBytes (fromRational r)
731 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
733 #if sparc_TARGET_ARCH
734 -- copy n paste of x86 version
735 ppr_item I16 x = [ptext SLIT("\t.short\t") <> pprImm imm]
736 ppr_item I64 x = [ptext SLIT("\t.quad\t") <> pprImm imm]
738 #if i386_TARGET_ARCH || x86_64_TARGET_ARCH
739 ppr_item I16 x = [ptext SLIT("\t.word\t") <> pprImm imm]
742 ppr_item I64 x = [ptext SLIT("\t.quad\t") <> pprImm imm]
744 #if x86_64_TARGET_ARCH
745 -- x86_64: binutils can't handle the R_X86_64_PC64 relocation
746 -- type, which means we can't do pc-relative 64-bit addresses.
747 -- Fortunately we're assuming the small memory model, in which
748 -- all such offsets will fit into 32 bits, so we have to stick
749 -- to 32-bit offset fields and modify the RTS appropriately
750 -- (see InfoTables.h).
753 | isRelativeReloc x =
754 [ptext SLIT("\t.long\t") <> pprImm imm,
755 ptext SLIT("\t.long\t0")]
757 [ptext SLIT("\t.quad\t") <> pprImm imm]
759 isRelativeReloc (CmmLabelOff _ _) = True
760 isRelativeReloc (CmmLabelDiffOff _ _ _) = True
761 isRelativeReloc _ = False
763 #if powerpc_TARGET_ARCH
764 ppr_item I16 x = [ptext SLIT("\t.short\t") <> pprImm imm]
765 ppr_item I64 (CmmInt x _) =
766 [ptext SLIT("\t.long\t")
768 (fromIntegral (x `shiftR` 32) :: Word32)),
769 ptext SLIT("\t.long\t")
770 <> int (fromIntegral (fromIntegral x :: Word32))]
773 -- fall through to rest of (machine-specific) pprInstr...
775 -- -----------------------------------------------------------------------------
776 -- pprInstr: print an 'Instr'
778 pprInstr :: Instr -> Doc
780 --pprInstr (COMMENT s) = empty -- nuke 'em
782 = IF_ARCH_alpha( ((<>) (ptext SLIT("\t# ")) (ftext s))
783 ,IF_ARCH_sparc( ((<>) (ptext SLIT("! ")) (ftext s))
784 ,IF_ARCH_i386( ((<>) (ptext SLIT("# ")) (ftext s))
785 ,IF_ARCH_x86_64( ((<>) (ptext SLIT("# ")) (ftext s))
786 ,IF_ARCH_powerpc( IF_OS_linux(
787 ((<>) (ptext SLIT("# ")) (ftext s)),
788 ((<>) (ptext SLIT("; ")) (ftext s)))
792 = pprInstr (COMMENT (mkFastString ("\tdelta = " ++ show d)))
794 pprInstr (NEWBLOCK _)
795 = panic "PprMach.pprInstr: NEWBLOCK"
798 = panic "PprMach.pprInstr: LDATA"
800 -- -----------------------------------------------------------------------------
801 -- pprInstr for an Alpha
803 #if alpha_TARGET_ARCH
805 pprInstr (LD size reg addr)
815 pprInstr (LDA reg addr)
817 ptext SLIT("\tlda\t"),
823 pprInstr (LDAH reg addr)
825 ptext SLIT("\tldah\t"),
831 pprInstr (LDGP reg addr)
833 ptext SLIT("\tldgp\t"),
839 pprInstr (LDI size reg imm)
849 pprInstr (ST size reg addr)
861 ptext SLIT("\tclr\t"),
865 pprInstr (ABS size ri reg)
875 pprInstr (NEG size ov ri reg)
879 if ov then ptext SLIT("v\t") else char '\t',
885 pprInstr (ADD size ov reg1 ri reg2)
889 if ov then ptext SLIT("v\t") else char '\t',
897 pprInstr (SADD size scale reg1 ri reg2)
899 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
910 pprInstr (SUB size ov reg1 ri reg2)
914 if ov then ptext SLIT("v\t") else char '\t',
922 pprInstr (SSUB size scale reg1 ri reg2)
924 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
935 pprInstr (MUL size ov reg1 ri reg2)
939 if ov then ptext SLIT("v\t") else char '\t',
947 pprInstr (DIV size uns reg1 ri reg2)
951 if uns then ptext SLIT("u\t") else char '\t',
959 pprInstr (REM size uns reg1 ri reg2)
963 if uns then ptext SLIT("u\t") else char '\t',
971 pprInstr (NOT ri reg)
980 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
981 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
982 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
983 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
984 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
985 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
987 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
988 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
989 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
991 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
992 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
994 pprInstr (NOP) = ptext SLIT("\tnop")
996 pprInstr (CMP cond reg1 ri reg2)
1010 ptext SLIT("\tfclr\t"),
1014 pprInstr (FABS reg1 reg2)
1016 ptext SLIT("\tfabs\t"),
1022 pprInstr (FNEG size reg1 reg2)
1024 ptext SLIT("\tneg"),
1032 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
1033 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
1034 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
1035 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
1037 pprInstr (CVTxy size1 size2 reg1 reg2)
1039 ptext SLIT("\tcvt"),
1041 case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
1048 pprInstr (FCMP size cond reg1 reg2 reg3)
1050 ptext SLIT("\tcmp"),
1061 pprInstr (FMOV reg1 reg2)
1063 ptext SLIT("\tfmov\t"),
1069 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
1071 pprInstr (BI NEVER reg lab) = empty
1073 pprInstr (BI cond reg lab)
1083 pprInstr (BF cond reg lab)
1094 = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
1096 pprInstr (JMP reg addr hint)
1098 ptext SLIT("\tjmp\t"),
1106 pprInstr (BSR imm n)
1107 = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
1109 pprInstr (JSR reg addr n)
1111 ptext SLIT("\tjsr\t"),
1117 pprInstr (FUNBEGIN clab)
1119 if (externallyVisibleCLabel clab) then
1120 hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
1123 ptext SLIT("\t.ent "),
1132 pp_lab = pprCLabel_asm clab
1134 -- NEVER use commas within those string literals, cpp will ruin your day
1135 pp_ldgp = hcat [ ptext SLIT(":\n\tldgp $29"), char ',', ptext SLIT("0($27)\n") ]
1136 pp_frame = hcat [ ptext SLIT("..ng:\n\t.frame $30"), char ',',
1137 ptext SLIT("4240"), char ',',
1138 ptext SLIT("$26"), char ',',
1139 ptext SLIT("0\n\t.prologue 1") ]
1141 pprInstr (FUNEND clab)
1142 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
1145 Continue with Alpha-only printing bits and bobs:
1149 pprRI (RIReg r) = pprReg r
1150 pprRI (RIImm r) = pprImm r
1152 pprRegRIReg :: LitString -> Reg -> RI -> Reg -> Doc
1153 pprRegRIReg name reg1 ri reg2
1165 pprSizeRegRegReg :: LitString -> Size -> Reg -> Reg -> Reg -> Doc
1166 pprSizeRegRegReg name size reg1 reg2 reg3
1179 #endif /* alpha_TARGET_ARCH */
1182 -- -----------------------------------------------------------------------------
1183 -- pprInstr for an x86
1185 #if i386_TARGET_ARCH || x86_64_TARGET_ARCH
1187 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
1190 #if 0 /* #ifdef DEBUG */
1191 (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
1196 pprInstr (MOV size src dst)
1197 = pprSizeOpOp SLIT("mov") size src dst
1199 pprInstr (MOVZxL I32 src dst) = pprSizeOpOp SLIT("mov") I32 src dst
1200 -- 32-to-64 bit zero extension on x86_64 is accomplished by a simple
1201 -- movl. But we represent it as a MOVZxL instruction, because
1202 -- the reg alloc would tend to throw away a plain reg-to-reg
1203 -- move, and we still want it to do that.
1205 pprInstr (MOVZxL sizes src dst) = pprSizeOpOpCoerce SLIT("movz") sizes wordRep src dst
1206 pprInstr (MOVSxL sizes src dst) = pprSizeOpOpCoerce SLIT("movs") sizes wordRep src dst
1208 -- here we do some patching, since the physical registers are only set late
1209 -- in the code generation.
1210 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
1212 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
1213 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
1215 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
1216 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
1218 = pprInstr (ADD size (OpImm displ) dst)
1219 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
1221 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
1222 = pprSizeOp SLIT("dec") size dst
1223 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
1224 = pprSizeOp SLIT("inc") size dst
1225 pprInstr (ADD size src dst)
1226 = pprSizeOpOp SLIT("add") size src dst
1227 pprInstr (ADC size src dst)
1228 = pprSizeOpOp SLIT("adc") size src dst
1229 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
1230 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
1232 {- A hack. The Intel documentation says that "The two and three
1233 operand forms [of IMUL] may also be used with unsigned operands
1234 because the lower half of the product is the same regardless if
1235 (sic) the operands are signed or unsigned. The CF and OF flags,
1236 however, cannot be used to determine if the upper half of the
1237 result is non-zero." So there.
1239 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
1240 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
1242 pprInstr (XOR F32 src dst) = pprOpOp SLIT("xorps") F32 src dst
1243 pprInstr (XOR F64 src dst) = pprOpOp SLIT("xorpd") F64 src dst
1244 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
1246 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
1247 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
1249 pprInstr (SHL size src dst) = pprShift SLIT("shl") size src dst
1250 pprInstr (SAR size src dst) = pprShift SLIT("sar") size src dst
1251 pprInstr (SHR size src dst) = pprShift SLIT("shr") size src dst
1253 pprInstr (BT size imm src) = pprSizeImmOp SLIT("bt") size imm src
1255 pprInstr (CMP size src dst)
1256 | isFloatingRep size = pprSizeOpOp SLIT("ucomi") size src dst -- SSE2
1257 | otherwise = pprSizeOpOp SLIT("cmp") size src dst
1259 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
1260 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
1261 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
1263 -- both unused (SDM):
1264 -- pprInstr PUSHA = ptext SLIT("\tpushal")
1265 -- pprInstr POPA = ptext SLIT("\tpopal")
1267 pprInstr NOP = ptext SLIT("\tnop")
1268 pprInstr (CLTD I32) = ptext SLIT("\tcltd")
1269 pprInstr (CLTD I64) = ptext SLIT("\tcqto")
1271 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand I8 op)
1273 pprInstr (JXX cond (BlockId id))
1274 = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
1275 where lab = mkAsmTempLabel id
1277 pprInstr (JMP (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
1278 pprInstr (JMP op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand wordRep op)
1279 pprInstr (JMP_TBL op ids) = pprInstr (JMP op)
1280 pprInstr (CALL (Left imm)) = (<>) (ptext SLIT("\tcall ")) (pprImm imm)
1281 pprInstr (CALL (Right reg)) = (<>) (ptext SLIT("\tcall *")) (pprReg wordRep reg)
1283 pprInstr (IDIV sz op) = pprSizeOp SLIT("idiv") sz op
1284 pprInstr (DIV sz op) = pprSizeOp SLIT("div") sz op
1285 pprInstr (IMUL2 sz op) = pprSizeOp SLIT("imul") sz op
1287 #if x86_64_TARGET_ARCH
1288 pprInstr (MUL size op1 op2) = pprSizeOpOp SLIT("mul") size op1 op2
1290 pprInstr (FDIV size op1 op2) = pprSizeOpOp SLIT("div") size op1 op2
1292 pprInstr (CVTSS2SD from to) = pprRegReg SLIT("cvtss2sd") from to
1293 pprInstr (CVTSD2SS from to) = pprRegReg SLIT("cvtsd2ss") from to
1294 pprInstr (CVTSS2SI from to) = pprOpReg SLIT("cvtss2si") from to
1295 pprInstr (CVTSD2SI from to) = pprOpReg SLIT("cvtsd2si") from to
1296 pprInstr (CVTSI2SS from to) = pprOpReg SLIT("cvtsi2ss") from to
1297 pprInstr (CVTSI2SD from to) = pprOpReg SLIT("cvtsi2sd") from to
1300 pprInstr (FETCHGOT reg)
1301 = vcat [ ptext SLIT("\tcall 1f"),
1302 hcat [ ptext SLIT("1:\tpopl\t"), pprReg I32 reg ],
1303 hcat [ ptext SLIT("\taddl\t$_GLOBAL_OFFSET_TABLE_+(.-1b), "),
1309 -- -----------------------------------------------------------------------------
1310 -- i386 floating-point
1312 #if i386_TARGET_ARCH
1313 -- Simulating a flat register set on the x86 FP stack is tricky.
1314 -- you have to free %st(7) before pushing anything on the FP reg stack
1315 -- so as to preclude the possibility of a FP stack overflow exception.
1316 pprInstr g@(GMOV src dst)
1320 = pprG g (hcat [gtab, gpush src 0, gsemi, gpop dst 1])
1322 -- GLD sz addr dst ==> FFREE %st(7) ; FLDsz addr ; FSTP (dst+1)
1323 pprInstr g@(GLD sz addr dst)
1324 = pprG g (hcat [gtab, text "ffree %st(7) ; fld", pprSize sz, gsp,
1325 pprAddr addr, gsemi, gpop dst 1])
1327 -- GST sz src addr ==> FFREE %st(7) ; FLD dst ; FSTPsz addr
1328 pprInstr g@(GST sz src addr)
1329 = pprG g (hcat [gtab, gpush src 0, gsemi,
1330 text "fstp", pprSize sz, gsp, pprAddr addr])
1332 pprInstr g@(GLDZ dst)
1333 = pprG g (hcat [gtab, text "ffree %st(7) ; fldz ; ", gpop dst 1])
1334 pprInstr g@(GLD1 dst)
1335 = pprG g (hcat [gtab, text "ffree %st(7) ; fld1 ; ", gpop dst 1])
1337 pprInstr g@(GFTOI src dst)
1338 = pprInstr (GDTOI src dst)
1339 pprInstr g@(GDTOI src dst)
1340 = pprG g (hcat [gtab, text "subl $4, %esp ; ",
1341 gpush src 0, gsemi, text "fistpl 0(%esp) ; popl ",
1344 pprInstr g@(GITOF src dst)
1345 = pprInstr (GITOD src dst)
1346 pprInstr g@(GITOD src dst)
1347 = pprG g (hcat [gtab, text "pushl ", pprReg I32 src,
1348 text " ; ffree %st(7); fildl (%esp) ; ",
1349 gpop dst 1, text " ; addl $4,%esp"])
1351 {- Gruesome swamp follows. If you're unfortunate enough to have ventured
1352 this far into the jungle AND you give a Rat's Ass (tm) what's going
1353 on, here's the deal. Generate code to do a floating point comparison
1354 of src1 and src2, of kind cond, and set the Zero flag if true.
1356 The complications are to do with handling NaNs correctly. We want the
1357 property that if either argument is NaN, then the result of the
1358 comparison is False ... except if we're comparing for inequality,
1359 in which case the answer is True.
1361 Here's how the general (non-inequality) case works. As an
1362 example, consider generating the an equality test:
1364 pushl %eax -- we need to mess with this
1365 <get src1 to top of FPU stack>
1366 fcomp <src2 location in FPU stack> and pop pushed src1
1367 -- Result of comparison is in FPU Status Register bits
1369 fstsw %ax -- Move FPU Status Reg to %ax
1370 sahf -- move C3 C2 C0 from %ax to integer flag reg
1371 -- now the serious magic begins
1372 setpo %ah -- %ah = if comparable(neither arg was NaN) then 1 else 0
1373 sete %al -- %al = if arg1 == arg2 then 1 else 0
1374 andb %ah,%al -- %al &= %ah
1375 -- so %al == 1 iff (comparable && same); else it holds 0
1376 decb %al -- %al == 0, ZeroFlag=1 iff (comparable && same);
1377 else %al == 0xFF, ZeroFlag=0
1378 -- the zero flag is now set as we desire.
1381 The special case of inequality differs thusly:
1383 setpe %ah -- %ah = if incomparable(either arg was NaN) then 1 else 0
1384 setne %al -- %al = if arg1 /= arg2 then 1 else 0
1385 orb %ah,%al -- %al = if (incomparable || different) then 1 else 0
1386 decb %al -- if (incomparable || different) then (%al == 0, ZF=1)
1387 else (%al == 0xFF, ZF=0)
1389 pprInstr g@(GCMP cond src1 src2)
1390 | case cond of { NE -> True; other -> False }
1392 hcat [gtab, text "pushl %eax ; ",gpush src1 0],
1393 hcat [gtab, text "fcomp ", greg src2 1,
1394 text "; fstsw %ax ; sahf ; setpe %ah"],
1395 hcat [gtab, text "setne %al ; ",
1396 text "orb %ah,%al ; decb %al ; popl %eax"]
1400 hcat [gtab, text "pushl %eax ; ",gpush src1 0],
1401 hcat [gtab, text "fcomp ", greg src2 1,
1402 text "; fstsw %ax ; sahf ; setpo %ah"],
1403 hcat [gtab, text "set", pprCond (fix_FP_cond cond), text " %al ; ",
1404 text "andb %ah,%al ; decb %al ; popl %eax"]
1407 {- On the 486, the flags set by FP compare are the unsigned ones!
1408 (This looks like a HACK to me. WDP 96/03)
1410 fix_FP_cond :: Cond -> Cond
1411 fix_FP_cond GE = GEU
1412 fix_FP_cond GTT = GU
1413 fix_FP_cond LTT = LU
1414 fix_FP_cond LE = LEU
1415 fix_FP_cond EQQ = EQQ
1417 -- there should be no others
1420 pprInstr g@(GABS sz src dst)
1421 = pprG g (hcat [gtab, gpush src 0, text " ; fabs ; ", gpop dst 1])
1422 pprInstr g@(GNEG sz src dst)
1423 = pprG g (hcat [gtab, gpush src 0, text " ; fchs ; ", gpop dst 1])
1425 pprInstr g@(GSQRT sz src dst)
1426 = pprG g (hcat [gtab, gpush src 0, text " ; fsqrt"] $$
1427 hcat [gtab, gcoerceto sz, gpop dst 1])
1428 pprInstr g@(GSIN sz src dst)
1429 = pprG g (hcat [gtab, gpush src 0, text " ; fsin"] $$
1430 hcat [gtab, gcoerceto sz, gpop dst 1])
1431 pprInstr g@(GCOS sz src dst)
1432 = pprG g (hcat [gtab, gpush src 0, text " ; fcos"] $$
1433 hcat [gtab, gcoerceto sz, gpop dst 1])
1434 pprInstr g@(GTAN sz src dst)
1435 = pprG g (hcat [gtab, text "ffree %st(6) ; ",
1436 gpush src 0, text " ; fptan ; ",
1437 text " fstp %st(0)"] $$
1438 hcat [gtab, gcoerceto sz, gpop dst 1])
1440 -- In the translations for GADD, GMUL, GSUB and GDIV,
1441 -- the first two cases are mere optimisations. The otherwise clause
1442 -- generates correct code under all circumstances.
1444 pprInstr g@(GADD sz src1 src2 dst)
1446 = pprG g (text "\t#GADD-xxxcase1" $$
1447 hcat [gtab, gpush src2 0,
1448 text " ; faddp %st(0),", greg src1 1])
1450 = pprG g (text "\t#GADD-xxxcase2" $$
1451 hcat [gtab, gpush src1 0,
1452 text " ; faddp %st(0),", greg src2 1])
1454 = pprG g (hcat [gtab, gpush src1 0,
1455 text " ; fadd ", greg src2 1, text ",%st(0)",
1459 pprInstr g@(GMUL sz src1 src2 dst)
1461 = pprG g (text "\t#GMUL-xxxcase1" $$
1462 hcat [gtab, gpush src2 0,
1463 text " ; fmulp %st(0),", greg src1 1])
1465 = pprG g (text "\t#GMUL-xxxcase2" $$
1466 hcat [gtab, gpush src1 0,
1467 text " ; fmulp %st(0),", greg src2 1])
1469 = pprG g (hcat [gtab, gpush src1 0,
1470 text " ; fmul ", greg src2 1, text ",%st(0)",
1474 pprInstr g@(GSUB sz src1 src2 dst)
1476 = pprG g (text "\t#GSUB-xxxcase1" $$
1477 hcat [gtab, gpush src2 0,
1478 text " ; fsubrp %st(0),", greg src1 1])
1480 = pprG g (text "\t#GSUB-xxxcase2" $$
1481 hcat [gtab, gpush src1 0,
1482 text " ; fsubp %st(0),", greg src2 1])
1484 = pprG g (hcat [gtab, gpush src1 0,
1485 text " ; fsub ", greg src2 1, text ",%st(0)",
1489 pprInstr g@(GDIV sz src1 src2 dst)
1491 = pprG g (text "\t#GDIV-xxxcase1" $$
1492 hcat [gtab, gpush src2 0,
1493 text " ; fdivrp %st(0),", greg src1 1])
1495 = pprG g (text "\t#GDIV-xxxcase2" $$
1496 hcat [gtab, gpush src1 0,
1497 text " ; fdivp %st(0),", greg src2 1])
1499 = pprG g (hcat [gtab, gpush src1 0,
1500 text " ; fdiv ", greg src2 1, text ",%st(0)",
1505 = vcat [ ptext SLIT("\tffree %st(0) ;ffree %st(1) ;ffree %st(2) ;ffree %st(3)"),
1506 ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)")
1509 --------------------------
1511 -- coerce %st(0) to the specified size
1512 gcoerceto F64 = empty
1513 gcoerceto F32 = empty --text "subl $4,%esp ; fstps (%esp) ; flds (%esp) ; addl $4,%esp ; "
1516 = hcat [text "ffree %st(7) ; fld ", greg reg offset]
1518 = hcat [text "fstp ", greg reg offset]
1520 greg reg offset = text "%st(" <> int (gregno reg - 8+offset) <> char ')'
1525 gregno (RealReg i) = i
1526 gregno other = --pprPanic "gregno" (ppr other)
1527 999 -- bogus; only needed for debug printing
1529 pprG :: Instr -> Doc -> Doc
1531 = (char '#' <> pprGInstr fake) $$ actual
1533 pprGInstr (GMOV src dst) = pprSizeRegReg SLIT("gmov") F64 src dst
1534 pprGInstr (GLD sz src dst) = pprSizeAddrReg SLIT("gld") sz src dst
1535 pprGInstr (GST sz src dst) = pprSizeRegAddr SLIT("gst") sz src dst
1537 pprGInstr (GLDZ dst) = pprSizeReg SLIT("gldz") F64 dst
1538 pprGInstr (GLD1 dst) = pprSizeReg SLIT("gld1") F64 dst
1540 pprGInstr (GFTOI src dst) = pprSizeSizeRegReg SLIT("gftoi") F32 I32 src dst
1541 pprGInstr (GDTOI src dst) = pprSizeSizeRegReg SLIT("gdtoi") F64 I32 src dst
1543 pprGInstr (GITOF src dst) = pprSizeSizeRegReg SLIT("gitof") I32 F32 src dst
1544 pprGInstr (GITOD src dst) = pprSizeSizeRegReg SLIT("gitod") I32 F64 src dst
1546 pprGInstr (GCMP co src dst) = pprCondRegReg SLIT("gcmp_") F64 co src dst
1547 pprGInstr (GABS sz src dst) = pprSizeRegReg SLIT("gabs") sz src dst
1548 pprGInstr (GNEG sz src dst) = pprSizeRegReg SLIT("gneg") sz src dst
1549 pprGInstr (GSQRT sz src dst) = pprSizeRegReg SLIT("gsqrt") sz src dst
1550 pprGInstr (GSIN sz src dst) = pprSizeRegReg SLIT("gsin") sz src dst
1551 pprGInstr (GCOS sz src dst) = pprSizeRegReg SLIT("gcos") sz src dst
1552 pprGInstr (GTAN sz src dst) = pprSizeRegReg SLIT("gtan") sz src dst
1554 pprGInstr (GADD sz src1 src2 dst) = pprSizeRegRegReg SLIT("gadd") sz src1 src2 dst
1555 pprGInstr (GSUB sz src1 src2 dst) = pprSizeRegRegReg SLIT("gsub") sz src1 src2 dst
1556 pprGInstr (GMUL sz src1 src2 dst) = pprSizeRegRegReg SLIT("gmul") sz src1 src2 dst
1557 pprGInstr (GDIV sz src1 src2 dst) = pprSizeRegRegReg SLIT("gdiv") sz src1 src2 dst
1560 #if i386_TARGET_ARCH || x86_64_TARGET_ARCH
1562 -- Continue with I386-only printing bits and bobs:
1564 pprDollImm :: Imm -> Doc
1566 pprDollImm i = ptext SLIT("$") <> pprImm i
1568 pprOperand :: MachRep -> Operand -> Doc
1569 pprOperand s (OpReg r) = pprReg s r
1570 pprOperand s (OpImm i) = pprDollImm i
1571 pprOperand s (OpAddr ea) = pprAddr ea
1573 pprMnemonic_ :: LitString -> Doc
1575 char '\t' <> ptext name <> space
1577 pprMnemonic :: LitString -> MachRep -> Doc
1578 pprMnemonic name size =
1579 char '\t' <> ptext name <> pprSize size <> space
1581 pprSizeImmOp :: LitString -> MachRep -> Imm -> Operand -> Doc
1582 pprSizeImmOp name size imm op1
1584 pprMnemonic name size,
1591 pprSizeOp :: LitString -> MachRep -> Operand -> Doc
1592 pprSizeOp name size op1
1594 pprMnemonic name size,
1598 pprSizeOpOp :: LitString -> MachRep -> Operand -> Operand -> Doc
1599 pprSizeOpOp name size op1 op2
1601 pprMnemonic name size,
1602 pprOperand size op1,
1607 pprOpOp :: LitString -> MachRep -> Operand -> Operand -> Doc
1608 pprOpOp name size op1 op2
1611 pprOperand size op1,
1616 pprSizeReg :: LitString -> MachRep -> Reg -> Doc
1617 pprSizeReg name size reg1
1619 pprMnemonic name size,
1623 pprSizeRegReg :: LitString -> MachRep -> Reg -> Reg -> Doc
1624 pprSizeRegReg name size reg1 reg2
1626 pprMnemonic name size,
1632 pprRegReg :: LitString -> Reg -> Reg -> Doc
1633 pprRegReg name reg1 reg2
1636 pprReg wordRep reg1,
1641 pprOpReg :: LitString -> Operand -> Reg -> Doc
1642 pprOpReg name op1 reg2
1645 pprOperand wordRep op1,
1650 pprCondRegReg :: LitString -> MachRep -> Cond -> Reg -> Reg -> Doc
1651 pprCondRegReg name size cond reg1 reg2
1662 pprSizeSizeRegReg :: LitString -> MachRep -> MachRep -> Reg -> Reg -> Doc
1663 pprSizeSizeRegReg name size1 size2 reg1 reg2
1676 pprSizeRegRegReg :: LitString -> MachRep -> Reg -> Reg -> Reg -> Doc
1677 pprSizeRegRegReg name size reg1 reg2 reg3
1679 pprMnemonic name size,
1687 pprSizeAddrReg :: LitString -> MachRep -> AddrMode -> Reg -> Doc
1688 pprSizeAddrReg name size op dst
1690 pprMnemonic name size,
1696 pprSizeRegAddr :: LitString -> MachRep -> Reg -> AddrMode -> Doc
1697 pprSizeRegAddr name size src op
1699 pprMnemonic name size,
1705 pprShift :: LitString -> MachRep -> Operand -> Operand -> Doc
1706 pprShift name size src dest
1708 pprMnemonic name size,
1709 pprOperand I8 src, -- src is 8-bit sized
1711 pprOperand size dest
1714 pprSizeOpOpCoerce :: LitString -> MachRep -> MachRep -> Operand -> Operand -> Doc
1715 pprSizeOpOpCoerce name size1 size2 op1 op2
1716 = hcat [ char '\t', ptext name, pprSize size1, pprSize size2, space,
1717 pprOperand size1 op1,
1719 pprOperand size2 op2
1722 pprCondInstr :: LitString -> Cond -> Doc -> Doc
1723 pprCondInstr name cond arg
1724 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1726 #endif /* i386_TARGET_ARCH */
1729 -- ------------------------------------------------------------------------------- pprInstr for a SPARC
1731 #if sparc_TARGET_ARCH
1733 -- a clumsy hack for now, to handle possible double alignment problems
1735 -- even clumsier, to allow for RegReg regs that show when doing indexed
1736 -- reads (bytearrays).
1739 -- Translate to the following:
1742 -- ld [g1+4],%f(n+1)
1743 -- sub g1,g2,g1 -- to restore g1
1744 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1746 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1747 hcat [pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg],
1748 hcat [pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)],
1749 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1754 -- ld [addr+4],%f(n+1)
1755 pprInstr (LD DF addr reg) | isJust off_addr
1757 hcat [pp_ld_lbracket, pprAddr addr, pp_rbracket_comma, pprReg reg],
1758 hcat [pp_ld_lbracket, pprAddr addr2, pp_rbracket_comma,pprReg (fPair reg)]
1761 off_addr = addrOffset addr 4
1762 addr2 = case off_addr of Just x -> x
1765 pprInstr (LD size addr reg)
1776 -- The same clumsy hack as above
1778 -- Translate to the following:
1781 -- st %f(n+1),[g1+4]
1782 -- sub g1,g2,g1 -- to restore g1
1783 pprInstr (ST DF reg (AddrRegReg g1 g2))
1785 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1786 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1788 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1789 pprReg g1, ptext SLIT("+4]")],
1790 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1795 -- st %f(n+1),[addr+4]
1796 pprInstr (ST DF reg addr) | isJust off_addr
1798 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1799 pprAddr addr, rbrack],
1800 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1801 pprAddr addr2, rbrack]
1804 off_addr = addrOffset addr 4
1805 addr2 = case off_addr of Just x -> x
1807 -- no distinction is made between signed and unsigned bytes on stores for the
1808 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1809 -- so we call a special-purpose pprSize for ST..
1811 pprInstr (ST size reg addr)
1822 pprInstr (ADD x cc reg1 ri reg2)
1823 | not x && not cc && riZero ri
1824 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1826 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1828 pprInstr (SUB x cc reg1 ri reg2)
1829 | not x && cc && reg2 == g0
1830 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1831 | not x && not cc && riZero ri
1832 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1834 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1836 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1837 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1839 pprInstr (OR b reg1 ri reg2)
1840 | not b && reg1 == g0
1841 = let doit = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1843 RIReg rrr | rrr == reg2 -> empty
1846 = pprRegRIReg SLIT("or") b reg1 ri reg2
1848 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1850 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1851 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1853 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1854 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1855 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1857 pprInstr (RDY rd) = ptext SLIT("\trd\t%y,") <> pprReg rd
1858 pprInstr (SMUL b reg1 ri reg2) = pprRegRIReg SLIT("smul") b reg1 ri reg2
1859 pprInstr (UMUL b reg1 ri reg2) = pprRegRIReg SLIT("umul") b reg1 ri reg2
1861 pprInstr (SETHI imm reg)
1863 ptext SLIT("\tsethi\t"),
1869 pprInstr NOP = ptext SLIT("\tnop")
1871 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1872 pprInstr (FABS DF reg1 reg2)
1873 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1874 (if (reg1 == reg2) then empty
1875 else (<>) (char '\n')
1876 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1878 pprInstr (FADD size reg1 reg2 reg3)
1879 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1880 pprInstr (FCMP e size reg1 reg2)
1881 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1882 pprInstr (FDIV size reg1 reg2 reg3)
1883 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1885 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1886 pprInstr (FMOV DF reg1 reg2)
1887 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1888 (if (reg1 == reg2) then empty
1889 else (<>) (char '\n')
1890 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1892 pprInstr (FMUL size reg1 reg2 reg3)
1893 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1895 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1896 pprInstr (FNEG DF reg1 reg2)
1897 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1898 (if (reg1 == reg2) then empty
1899 else (<>) (char '\n')
1900 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1902 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1903 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1904 pprInstr (FxTOy size1 size2 reg1 reg2)
1917 pprReg reg1, comma, pprReg reg2
1921 pprInstr (BI cond b lab)
1923 ptext SLIT("\tb"), pprCond cond,
1924 if b then pp_comma_a else empty,
1929 pprInstr (BF cond b lab)
1931 ptext SLIT("\tfb"), pprCond cond,
1932 if b then pp_comma_a else empty,
1937 pprInstr (JMP dsts addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1939 pprInstr (CALL (Left imm) n _)
1940 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1941 pprInstr (CALL (Right reg) n _)
1942 = hcat [ ptext SLIT("\tcall\t"), pprReg reg, comma, int n ]
1945 Continue with SPARC-only printing bits and bobs:
1948 pprRI (RIReg r) = pprReg r
1949 pprRI (RIImm r) = pprImm r
1951 pprSizeRegReg :: LitString -> Size -> Reg -> Reg -> Doc
1952 pprSizeRegReg name size reg1 reg2
1957 F -> ptext SLIT("s\t")
1958 DF -> ptext SLIT("d\t")),
1964 pprSizeRegRegReg :: LitString -> Size -> Reg -> Reg -> Reg -> Doc
1965 pprSizeRegRegReg name size reg1 reg2 reg3
1970 F -> ptext SLIT("s\t")
1971 DF -> ptext SLIT("d\t")),
1979 pprRegRIReg :: LitString -> Bool -> Reg -> RI -> Reg -> Doc
1980 pprRegRIReg name b reg1 ri reg2
1984 if b then ptext SLIT("cc\t") else char '\t',
1992 pprRIReg :: LitString -> Bool -> RI -> Reg -> Doc
1993 pprRIReg name b ri reg1
1997 if b then ptext SLIT("cc\t") else char '\t',
2003 pp_ld_lbracket = ptext SLIT("\tld\t[")
2004 pp_rbracket_comma = text "],"
2005 pp_comma_lbracket = text ",["
2006 pp_comma_a = text ",a"
2008 #endif /* sparc_TARGET_ARCH */
2011 -- -----------------------------------------------------------------------------
2012 -- pprInstr for PowerPC
2014 #if powerpc_TARGET_ARCH
2015 pprInstr (LD sz reg addr) = hcat [
2024 case addr of AddrRegImm _ _ -> empty
2025 AddrRegReg _ _ -> char 'x',
2031 pprInstr (LA sz reg addr) = hcat [
2040 case addr of AddrRegImm _ _ -> empty
2041 AddrRegReg _ _ -> char 'x',
2047 pprInstr (ST sz reg addr) = hcat [
2051 case addr of AddrRegImm _ _ -> empty
2052 AddrRegReg _ _ -> char 'x',
2058 pprInstr (STU sz reg addr) = hcat [
2063 case addr of AddrRegImm _ _ -> empty
2064 AddrRegReg _ _ -> char 'x',
2069 pprInstr (LIS reg imm) = hcat [
2077 pprInstr (LI reg imm) = hcat [
2085 pprInstr (MR reg1 reg2)
2086 | reg1 == reg2 = empty
2087 | otherwise = hcat [
2089 case regClass reg1 of
2090 RcInteger -> ptext SLIT("mr")
2091 _ -> ptext SLIT("fmr"),
2097 pprInstr (CMP sz reg ri) = hcat [
2113 pprInstr (CMPL sz reg ri) = hcat [
2129 pprInstr (BCC cond (BlockId id)) = hcat [
2136 where lbl = mkAsmTempLabel id
2138 pprInstr (JMP lbl) = hcat [ -- an alias for b that takes a CLabel
2145 pprInstr (MTCTR reg) = hcat [
2147 ptext SLIT("mtctr"),
2151 pprInstr (BCTR _) = hcat [
2155 pprInstr (BL lbl _) = hcat [
2156 ptext SLIT("\tbl\t"),
2159 pprInstr (BCTRL _) = hcat [
2163 pprInstr (ADD reg1 reg2 ri) = pprLogic SLIT("add") reg1 reg2 ri
2164 pprInstr (ADDIS reg1 reg2 imm) = hcat [
2166 ptext SLIT("addis"),
2175 pprInstr (ADDC reg1 reg2 reg3) = pprLogic SLIT("addc") reg1 reg2 (RIReg reg3)
2176 pprInstr (ADDE reg1 reg2 reg3) = pprLogic SLIT("adde") reg1 reg2 (RIReg reg3)
2177 pprInstr (SUBF reg1 reg2 reg3) = pprLogic SLIT("subf") reg1 reg2 (RIReg reg3)
2178 pprInstr (MULLW reg1 reg2 ri@(RIReg _)) = pprLogic SLIT("mullw") reg1 reg2 ri
2179 pprInstr (MULLW reg1 reg2 ri@(RIImm _)) = pprLogic SLIT("mull") reg1 reg2 ri
2180 pprInstr (DIVW reg1 reg2 reg3) = pprLogic SLIT("divw") reg1 reg2 (RIReg reg3)
2181 pprInstr (DIVWU reg1 reg2 reg3) = pprLogic SLIT("divwu") reg1 reg2 (RIReg reg3)
2183 pprInstr (MULLW_MayOflo reg1 reg2 reg3) = vcat [
2184 hcat [ ptext SLIT("\tmullwo\t"), pprReg reg1, ptext SLIT(", "),
2185 pprReg reg2, ptext SLIT(", "),
2187 hcat [ ptext SLIT("\tmfxer\t"), pprReg reg1 ],
2188 hcat [ ptext SLIT("\trlwinm\t"), pprReg reg1, ptext SLIT(", "),
2189 pprReg reg1, ptext SLIT(", "),
2190 ptext SLIT("2, 31, 31") ]
2193 -- for some reason, "andi" doesn't exist.
2194 -- we'll use "andi." instead.
2195 pprInstr (AND reg1 reg2 (RIImm imm)) = hcat [
2197 ptext SLIT("andi."),
2205 pprInstr (AND reg1 reg2 ri) = pprLogic SLIT("and") reg1 reg2 ri
2207 pprInstr (OR reg1 reg2 ri) = pprLogic SLIT("or") reg1 reg2 ri
2208 pprInstr (XOR reg1 reg2 ri) = pprLogic SLIT("xor") reg1 reg2 ri
2210 pprInstr (XORIS reg1 reg2 imm) = hcat [
2212 ptext SLIT("xoris"),
2221 pprInstr (EXTS sz reg1 reg2) = hcat [
2231 pprInstr (NEG reg1 reg2) = pprUnary SLIT("neg") reg1 reg2
2232 pprInstr (NOT reg1 reg2) = pprUnary SLIT("not") reg1 reg2
2234 pprInstr (SLW reg1 reg2 ri) = pprLogic SLIT("slw") reg1 reg2 (limitShiftRI ri)
2235 pprInstr (SRW reg1 reg2 ri) = pprLogic SLIT("srw") reg1 reg2 (limitShiftRI ri)
2236 pprInstr (SRAW reg1 reg2 ri) = pprLogic SLIT("sraw") reg1 reg2 (limitShiftRI ri)
2237 pprInstr (RLWINM reg1 reg2 sh mb me) = hcat [
2238 ptext SLIT("\trlwinm\t"),
2250 pprInstr (FADD sz reg1 reg2 reg3) = pprBinaryF SLIT("fadd") sz reg1 reg2 reg3
2251 pprInstr (FSUB sz reg1 reg2 reg3) = pprBinaryF SLIT("fsub") sz reg1 reg2 reg3
2252 pprInstr (FMUL sz reg1 reg2 reg3) = pprBinaryF SLIT("fmul") sz reg1 reg2 reg3
2253 pprInstr (FDIV sz reg1 reg2 reg3) = pprBinaryF SLIT("fdiv") sz reg1 reg2 reg3
2254 pprInstr (FNEG reg1 reg2) = pprUnary SLIT("fneg") reg1 reg2
2256 pprInstr (FCMP reg1 reg2) = hcat [
2258 ptext SLIT("fcmpu\tcr0, "),
2259 -- Note: we're using fcmpu, not fcmpo
2260 -- The difference is with fcmpo, compare with NaN is an invalid operation.
2261 -- We don't handle invalid fp ops, so we don't care
2267 pprInstr (FCTIWZ reg1 reg2) = pprUnary SLIT("fctiwz") reg1 reg2
2268 pprInstr (FRSP reg1 reg2) = pprUnary SLIT("frsp") reg1 reg2
2270 pprInstr (CRNOR dst src1 src2) = hcat [
2271 ptext SLIT("\tcrnor\t"),
2279 pprInstr (MFCR reg) = hcat [
2286 pprInstr (MFLR reg) = hcat [
2293 pprInstr (FETCHPC reg) = vcat [
2294 ptext SLIT("\tbcl\t20,31,1f"),
2295 hcat [ ptext SLIT("1:\tmflr\t"), pprReg reg ]
2298 pprInstr _ = panic "pprInstr (ppc)"
2300 pprLogic op reg1 reg2 ri = hcat [
2305 RIImm _ -> char 'i',
2314 pprUnary op reg1 reg2 = hcat [
2323 pprBinaryF op sz reg1 reg2 reg3 = hcat [
2336 pprRI (RIReg r) = pprReg r
2337 pprRI (RIImm r) = pprImm r
2339 pprFSize F64 = empty
2340 pprFSize F32 = char 's'
2342 -- limit immediate argument for shift instruction to range 0..32
2343 -- (yes, the maximum is really 32, not 31)
2344 limitShiftRI :: RI -> RI
2345 limitShiftRI (RIImm (ImmInt i)) | i > 32 || i < 0 = RIImm (ImmInt 32)
2348 #endif /* powerpc_TARGET_ARCH */
2351 -- -----------------------------------------------------------------------------
2352 -- Converting floating-point literals to integrals for printing
2354 #if __GLASGOW_HASKELL__ >= 504
2355 newFloatArray :: (Int,Int) -> ST s (STUArray s Int Float)
2356 newFloatArray = newArray_
2358 newDoubleArray :: (Int,Int) -> ST s (STUArray s Int Double)
2359 newDoubleArray = newArray_
2361 castFloatToCharArray :: STUArray s Int Float -> ST s (STUArray s Int Word8)
2362 castFloatToCharArray = castSTUArray
2364 castDoubleToCharArray :: STUArray s Int Double -> ST s (STUArray s Int Word8)
2365 castDoubleToCharArray = castSTUArray
2367 writeFloatArray :: STUArray s Int Float -> Int -> Float -> ST s ()
2368 writeFloatArray = writeArray
2370 writeDoubleArray :: STUArray s Int Double -> Int -> Double -> ST s ()
2371 writeDoubleArray = writeArray
2373 readCharArray :: STUArray s Int Word8 -> Int -> ST s Char
2374 readCharArray arr i = do
2375 w <- readArray arr i
2376 return $! (chr (fromIntegral w))
2380 castFloatToCharArray :: MutableByteArray s t -> ST s (MutableByteArray s t)
2381 castFloatToCharArray = return
2383 castDoubleToCharArray :: MutableByteArray s t -> ST s (MutableByteArray s t)
2386 castDoubleToCharArray = return
2390 -- floatToBytes and doubleToBytes convert to the host's byte
2391 -- order. Providing that we're not cross-compiling for a
2392 -- target with the opposite endianness, this should work ok
2395 -- ToDo: this stuff is very similar to the shenanigans in PprAbs,
2396 -- could they be merged?
2398 floatToBytes :: Float -> [Int]
2401 arr <- newFloatArray ((0::Int),3)
2402 writeFloatArray arr 0 f
2403 arr <- castFloatToCharArray arr
2404 i0 <- readCharArray arr 0
2405 i1 <- readCharArray arr 1
2406 i2 <- readCharArray arr 2
2407 i3 <- readCharArray arr 3
2408 return (map ord [i0,i1,i2,i3])
2411 doubleToBytes :: Double -> [Int]
2414 arr <- newDoubleArray ((0::Int),7)
2415 writeDoubleArray arr 0 d
2416 arr <- castDoubleToCharArray arr
2417 i0 <- readCharArray arr 0
2418 i1 <- readCharArray arr 1
2419 i2 <- readCharArray arr 2
2420 i3 <- readCharArray arr 3
2421 i4 <- readCharArray arr 4
2422 i5 <- readCharArray arr 5
2423 i6 <- readCharArray arr 6
2424 i7 <- readCharArray arr 7
2425 return (map ord [i0,i1,i2,i3,i4,i5,i6,i7])