[project @ 2004-10-07 15:54:03 by wolfgang]
[ghc-hetmet.git] / ghc / compiler / nativeGen / PprMach.hs
1 -----------------------------------------------------------------------------
2 --
3 -- Pretty-printing assembly language
4 --
5         -- (c) The University of Glasgow 1993-2004
6         --
7 -----------------------------------------------------------------------------
8
9 -- We start with the @pprXXX@s with some cross-platform commonality
10 -- (e.g., 'pprReg'); we conclude with the no-commonality monster,
11 -- 'pprInstr'.
12
13 #include "nativeGen/NCG.h"
14
15 module PprMach ( 
16         pprNatCmmTop, pprBasicBlock,
17         pprInstr, pprSize, pprUserReg,
18   ) where
19
20
21 #include "HsVersions.h"
22
23 import Cmm
24 import MachOp           ( MachRep(..) )
25 import MachRegs         -- may differ per-platform
26 import MachInstrs
27
28 import CLabel           ( CLabel, pprCLabel, externallyVisibleCLabel,
29                           labelDynamic, mkAsmTempLabel, entryLblToInfoLbl )
30
31 import Panic            ( panic )
32 import Unique           ( pprUnique )
33 import Pretty
34 import FastString
35 import qualified Outputable
36
37 import CmdLineOpts      ( opt_PIC )
38
39 #if __GLASGOW_HASKELL__ >= 504
40 import Data.Array.ST
41 import Data.Word        ( Word8 )
42 #else
43 import MutableArray
44 #endif
45
46 import MONAD_ST
47 import Char             ( chr, ord )
48
49 #if powerpc_TARGET_ARCH
50 import DATA_WORD(Word32)
51 import DATA_BITS
52 #endif
53
54 -- -----------------------------------------------------------------------------
55 -- Printing this stuff out
56
57 asmSDoc d = Outputable.withPprStyleDoc (
58               Outputable.mkCodeStyle Outputable.AsmStyle) d
59 pprCLabel_asm l = asmSDoc (pprCLabel l)
60
61 pprNatCmmTop :: NatCmmTop -> Doc
62 pprNatCmmTop (CmmData section dats) = 
63   pprSectionHeader section $$ vcat (map pprData dats)
64
65  -- special case for split markers:
66 pprNatCmmTop (CmmProc [] lbl _ []) = pprLabel lbl
67
68 pprNatCmmTop (CmmProc info lbl params blocks) = 
69   pprSectionHeader Text $$
70   (if not (null info)
71         then vcat (map pprData info) 
72                 $$ pprLabel (entryLblToInfoLbl lbl)
73         else empty) $$
74   (case blocks of
75         [] -> empty
76         (BasicBlock _ instrs : rest) -> 
77                 (if null info then pprLabel lbl else empty) $$
78                 -- the first block doesn't get a label:
79                 vcat (map pprInstr instrs) $$
80                 vcat (map pprBasicBlock rest))
81
82
83 pprBasicBlock :: NatBasicBlock -> Doc
84 pprBasicBlock (BasicBlock (BlockId id) instrs) =
85   pprLabel (mkAsmTempLabel id) $$
86   vcat (map pprInstr instrs)
87
88 -- -----------------------------------------------------------------------------
89 -- pprReg: print a 'Reg'
90
91 -- For x86, the way we print a register name depends
92 -- on which bit of it we care about.  Yurgh.
93
94 pprUserReg :: Reg -> Doc
95 pprUserReg = pprReg IF_ARCH_i386(I32,)
96
97 pprReg :: IF_ARCH_i386(MachRep ->,) Reg -> Doc
98
99 pprReg IF_ARCH_i386(s,) r
100   = case r of
101       RealReg i      -> ppr_reg_no IF_ARCH_i386(s,) i
102       VirtualRegI  u  -> text "%vI_" <> asmSDoc (pprUnique u)
103       VirtualRegHi u  -> text "%vHi_" <> asmSDoc (pprUnique u)
104       VirtualRegF  u  -> text "%vF_" <> asmSDoc (pprUnique u)
105       VirtualRegD  u  -> text "%vD_" <> asmSDoc (pprUnique u)
106   where
107 #if alpha_TARGET_ARCH
108     ppr_reg_no :: Int -> Doc
109     ppr_reg_no i = ptext
110       (case i of {
111          0 -> SLIT("$0");    1 -> SLIT("$1");
112          2 -> SLIT("$2");    3 -> SLIT("$3");
113          4 -> SLIT("$4");    5 -> SLIT("$5");
114          6 -> SLIT("$6");    7 -> SLIT("$7");
115          8 -> SLIT("$8");    9 -> SLIT("$9");
116         10 -> SLIT("$10");  11 -> SLIT("$11");
117         12 -> SLIT("$12");  13 -> SLIT("$13");
118         14 -> SLIT("$14");  15 -> SLIT("$15");
119         16 -> SLIT("$16");  17 -> SLIT("$17");
120         18 -> SLIT("$18");  19 -> SLIT("$19");
121         20 -> SLIT("$20");  21 -> SLIT("$21");
122         22 -> SLIT("$22");  23 -> SLIT("$23");
123         24 -> SLIT("$24");  25 -> SLIT("$25");
124         26 -> SLIT("$26");  27 -> SLIT("$27");
125         28 -> SLIT("$28");  29 -> SLIT("$29");
126         30 -> SLIT("$30");  31 -> SLIT("$31");
127         32 -> SLIT("$f0");  33 -> SLIT("$f1");
128         34 -> SLIT("$f2");  35 -> SLIT("$f3");
129         36 -> SLIT("$f4");  37 -> SLIT("$f5");
130         38 -> SLIT("$f6");  39 -> SLIT("$f7");
131         40 -> SLIT("$f8");  41 -> SLIT("$f9");
132         42 -> SLIT("$f10"); 43 -> SLIT("$f11");
133         44 -> SLIT("$f12"); 45 -> SLIT("$f13");
134         46 -> SLIT("$f14"); 47 -> SLIT("$f15");
135         48 -> SLIT("$f16"); 49 -> SLIT("$f17");
136         50 -> SLIT("$f18"); 51 -> SLIT("$f19");
137         52 -> SLIT("$f20"); 53 -> SLIT("$f21");
138         54 -> SLIT("$f22"); 55 -> SLIT("$f23");
139         56 -> SLIT("$f24"); 57 -> SLIT("$f25");
140         58 -> SLIT("$f26"); 59 -> SLIT("$f27");
141         60 -> SLIT("$f28"); 61 -> SLIT("$f29");
142         62 -> SLIT("$f30"); 63 -> SLIT("$f31");
143         _  -> SLIT("very naughty alpha register")
144       })
145 #endif
146 #if i386_TARGET_ARCH
147     ppr_reg_no :: MachRep -> Int -> Doc
148     ppr_reg_no I8   = ppr_reg_byte
149     ppr_reg_no I16  = ppr_reg_word
150     ppr_reg_no _    = ppr_reg_long
151
152     ppr_reg_byte i = ptext
153       (case i of {
154          0 -> SLIT("%al");     1 -> SLIT("%bl");
155          2 -> SLIT("%cl");     3 -> SLIT("%dl");
156         _  -> SLIT("very naughty I386 byte register")
157       })
158
159     ppr_reg_word i = ptext
160       (case i of {
161          0 -> SLIT("%ax");     1 -> SLIT("%bx");
162          2 -> SLIT("%cx");     3 -> SLIT("%dx");
163          4 -> SLIT("%si");     5 -> SLIT("%di");
164          6 -> SLIT("%bp");     7 -> SLIT("%sp");
165         _  -> SLIT("very naughty I386 word register")
166       })
167
168     ppr_reg_long i = ptext
169       (case i of {
170          0 -> SLIT("%eax");    1 -> SLIT("%ebx");
171          2 -> SLIT("%ecx");    3 -> SLIT("%edx");
172          4 -> SLIT("%esi");    5 -> SLIT("%edi");
173          6 -> SLIT("%ebp");    7 -> SLIT("%esp");
174          8 -> SLIT("%fake0");  9 -> SLIT("%fake1");
175         10 -> SLIT("%fake2"); 11 -> SLIT("%fake3");
176         12 -> SLIT("%fake4"); 13 -> SLIT("%fake5");
177         _  -> SLIT("very naughty I386 register")
178       })
179 #endif
180 #if sparc_TARGET_ARCH
181     ppr_reg_no :: Int -> Doc
182     ppr_reg_no i = ptext
183       (case i of {
184          0 -> SLIT("%g0");   1 -> SLIT("%g1");
185          2 -> SLIT("%g2");   3 -> SLIT("%g3");
186          4 -> SLIT("%g4");   5 -> SLIT("%g5");
187          6 -> SLIT("%g6");   7 -> SLIT("%g7");
188          8 -> SLIT("%o0");   9 -> SLIT("%o1");
189         10 -> SLIT("%o2");  11 -> SLIT("%o3");
190         12 -> SLIT("%o4");  13 -> SLIT("%o5");
191         14 -> SLIT("%o6");  15 -> SLIT("%o7");
192         16 -> SLIT("%l0");  17 -> SLIT("%l1");
193         18 -> SLIT("%l2");  19 -> SLIT("%l3");
194         20 -> SLIT("%l4");  21 -> SLIT("%l5");
195         22 -> SLIT("%l6");  23 -> SLIT("%l7");
196         24 -> SLIT("%i0");  25 -> SLIT("%i1");
197         26 -> SLIT("%i2");  27 -> SLIT("%i3");
198         28 -> SLIT("%i4");  29 -> SLIT("%i5");
199         30 -> SLIT("%i6");  31 -> SLIT("%i7");
200         32 -> SLIT("%f0");  33 -> SLIT("%f1");
201         34 -> SLIT("%f2");  35 -> SLIT("%f3");
202         36 -> SLIT("%f4");  37 -> SLIT("%f5");
203         38 -> SLIT("%f6");  39 -> SLIT("%f7");
204         40 -> SLIT("%f8");  41 -> SLIT("%f9");
205         42 -> SLIT("%f10"); 43 -> SLIT("%f11");
206         44 -> SLIT("%f12"); 45 -> SLIT("%f13");
207         46 -> SLIT("%f14"); 47 -> SLIT("%f15");
208         48 -> SLIT("%f16"); 49 -> SLIT("%f17");
209         50 -> SLIT("%f18"); 51 -> SLIT("%f19");
210         52 -> SLIT("%f20"); 53 -> SLIT("%f21");
211         54 -> SLIT("%f22"); 55 -> SLIT("%f23");
212         56 -> SLIT("%f24"); 57 -> SLIT("%f25");
213         58 -> SLIT("%f26"); 59 -> SLIT("%f27");
214         60 -> SLIT("%f28"); 61 -> SLIT("%f29");
215         62 -> SLIT("%f30"); 63 -> SLIT("%f31");
216         _  -> SLIT("very naughty sparc register")
217       })
218 #endif
219 #if powerpc_TARGET_ARCH
220 #if darwin_TARGET_OS
221     ppr_reg_no :: Int -> Doc
222     ppr_reg_no i = ptext
223       (case i of {
224          0 -> SLIT("r0");   1 -> SLIT("r1");
225          2 -> SLIT("r2");   3 -> SLIT("r3");
226          4 -> SLIT("r4");   5 -> SLIT("r5");
227          6 -> SLIT("r6");   7 -> SLIT("r7");
228          8 -> SLIT("r8");   9 -> SLIT("r9");
229         10 -> SLIT("r10");  11 -> SLIT("r11");
230         12 -> SLIT("r12");  13 -> SLIT("r13");
231         14 -> SLIT("r14");  15 -> SLIT("r15");
232         16 -> SLIT("r16");  17 -> SLIT("r17");
233         18 -> SLIT("r18");  19 -> SLIT("r19");
234         20 -> SLIT("r20");  21 -> SLIT("r21");
235         22 -> SLIT("r22");  23 -> SLIT("r23");
236         24 -> SLIT("r24");  25 -> SLIT("r25");
237         26 -> SLIT("r26");  27 -> SLIT("r27");
238         28 -> SLIT("r28");  29 -> SLIT("r29");
239         30 -> SLIT("r30");  31 -> SLIT("r31");
240         32 -> SLIT("f0");  33 -> SLIT("f1");
241         34 -> SLIT("f2");  35 -> SLIT("f3");
242         36 -> SLIT("f4");  37 -> SLIT("f5");
243         38 -> SLIT("f6");  39 -> SLIT("f7");
244         40 -> SLIT("f8");  41 -> SLIT("f9");
245         42 -> SLIT("f10"); 43 -> SLIT("f11");
246         44 -> SLIT("f12"); 45 -> SLIT("f13");
247         46 -> SLIT("f14"); 47 -> SLIT("f15");
248         48 -> SLIT("f16"); 49 -> SLIT("f17");
249         50 -> SLIT("f18"); 51 -> SLIT("f19");
250         52 -> SLIT("f20"); 53 -> SLIT("f21");
251         54 -> SLIT("f22"); 55 -> SLIT("f23");
252         56 -> SLIT("f24"); 57 -> SLIT("f25");
253         58 -> SLIT("f26"); 59 -> SLIT("f27");
254         60 -> SLIT("f28"); 61 -> SLIT("f29");
255         62 -> SLIT("f30"); 63 -> SLIT("f31");
256         _  -> SLIT("very naughty powerpc register")
257       })
258 #else
259     ppr_reg_no :: Int -> Doc
260     ppr_reg_no i | i <= 31 = int i      -- GPRs
261                  | i <= 63 = int (i-32) -- FPRs
262                  | otherwise = ptext SLIT("very naughty powerpc register")
263 #endif
264 #endif
265
266
267 -- -----------------------------------------------------------------------------
268 -- pprSize: print a 'Size'
269
270 #if powerpc_TARGET_ARCH || i386_TARGET_ARCH
271 pprSize :: MachRep -> Doc
272 #else
273 pprSize :: Size -> Doc
274 #endif
275
276 pprSize x = ptext (case x of
277 #if alpha_TARGET_ARCH
278          B  -> SLIT("b")
279          Bu -> SLIT("bu")
280 --       W  -> SLIT("w") UNUSED
281 --       Wu -> SLIT("wu") UNUSED
282          L  -> SLIT("l")
283          Q  -> SLIT("q")
284 --       FF -> SLIT("f") UNUSED
285 --       DF -> SLIT("d") UNUSED
286 --       GF -> SLIT("g") UNUSED
287 --       SF -> SLIT("s") UNUSED
288          TF -> SLIT("t")
289 #endif
290 #if i386_TARGET_ARCH
291         I8   -> SLIT("b")
292         I16  -> SLIT("w")
293         I32  -> SLIT("l")
294         F32  -> SLIT("s")
295         F64  -> SLIT("l")
296         F80  -> SLIT("t")
297 #endif
298 #if sparc_TARGET_ARCH
299         B   -> SLIT("sb")
300         Bu  -> SLIT("ub")
301         H   -> SLIT("sh")
302         Hu  -> SLIT("uh")
303         W   -> SLIT("")
304         F   -> SLIT("")
305         DF  -> SLIT("d")
306     )
307 pprStSize :: Size -> Doc
308 pprStSize x = ptext (case x of
309         B   -> SLIT("b")
310         Bu  -> SLIT("b")
311         H   -> SLIT("h")
312         Hu  -> SLIT("h")
313         W   -> SLIT("")
314         F   -> SLIT("")
315         DF  -> SLIT("d")
316 #endif
317 #if powerpc_TARGET_ARCH
318         I8   -> SLIT("b")
319         I16  -> SLIT("h")
320         I32  -> SLIT("w")
321         F32  -> SLIT("fs")
322         F64  -> SLIT("fd")
323 #endif
324     )
325
326 -- -----------------------------------------------------------------------------
327 -- pprCond: print a 'Cond'
328
329 pprCond :: Cond -> Doc
330
331 pprCond c = ptext (case c of {
332 #if alpha_TARGET_ARCH
333         EQQ  -> SLIT("eq");
334         LTT  -> SLIT("lt");
335         LE  -> SLIT("le");
336         ULT -> SLIT("ult");
337         ULE -> SLIT("ule");
338         NE  -> SLIT("ne");
339         GTT  -> SLIT("gt");
340         GE  -> SLIT("ge")
341 #endif
342 #if i386_TARGET_ARCH
343         GEU     -> SLIT("ae");  LU    -> SLIT("b");
344         EQQ     -> SLIT("e");   GTT    -> SLIT("g");
345         GE      -> SLIT("ge");  GU    -> SLIT("a");
346         LTT     -> SLIT("l");   LE    -> SLIT("le");
347         LEU     -> SLIT("be");  NE    -> SLIT("ne");
348         NEG     -> SLIT("s");   POS   -> SLIT("ns");
349         CARRY   -> SLIT("c");   OFLO  -> SLIT("o");
350         ALWAYS  -> SLIT("mp")   -- hack
351 #endif
352 #if sparc_TARGET_ARCH
353         ALWAYS  -> SLIT("");    NEVER -> SLIT("n");
354         GEU     -> SLIT("geu"); LU    -> SLIT("lu");
355         EQQ     -> SLIT("e");   GTT   -> SLIT("g");
356         GE      -> SLIT("ge");  GU    -> SLIT("gu");
357         LTT     -> SLIT("l");   LE    -> SLIT("le");
358         LEU     -> SLIT("leu"); NE    -> SLIT("ne");
359         NEG     -> SLIT("neg"); POS   -> SLIT("pos");
360         VC      -> SLIT("vc");  VS    -> SLIT("vs")
361 #endif
362 #if powerpc_TARGET_ARCH
363         ALWAYS  -> SLIT("");
364         EQQ     -> SLIT("eq");  NE    -> SLIT("ne");
365         LTT     -> SLIT("lt");  GE    -> SLIT("ge");
366         GTT     -> SLIT("gt");  LE    -> SLIT("le");
367         LU      -> SLIT("lt");  GEU   -> SLIT("ge");
368         GU      -> SLIT("gt");  LEU   -> SLIT("le");
369 #endif
370     })
371
372
373 -- -----------------------------------------------------------------------------
374 -- pprImm: print an 'Imm'
375
376 pprImm :: Imm -> Doc
377
378 pprImm (ImmInt i)     = int i
379 pprImm (ImmInteger i) = integer i
380 pprImm (ImmCLbl l)    = pprCLabel_asm l
381 pprImm (ImmIndex l i) = pprCLabel_asm l <> char '+' <> int i
382 pprImm (ImmLit s)     = s
383
384 pprImm (ImmFloat _) = panic "pprImm:ImmFloat"
385 pprImm (ImmDouble _) = panic "pprImm:ImmDouble"
386
387 pprImm (ImmConstantSum a b) = pprImm a <> char '+' <> pprImm b
388 pprImm (ImmConstantDiff a b) = pprImm a <> char '-'
389                             <> lparen <> pprImm b <> rparen
390
391 #if sparc_TARGET_ARCH
392 pprImm (LO i)
393   = hcat [ pp_lo, pprImm i, rparen ]
394   where
395     pp_lo = text "%lo("
396
397 pprImm (HI i)
398   = hcat [ pp_hi, pprImm i, rparen ]
399   where
400     pp_hi = text "%hi("
401 #endif
402 #if powerpc_TARGET_ARCH
403 #if darwin_TARGET_OS
404 pprImm (LO i)
405   = hcat [ pp_lo, pprImm i, rparen ]
406   where
407     pp_lo = text "lo16("
408
409 pprImm (HI i)
410   = hcat [ pp_hi, pprImm i, rparen ]
411   where
412     pp_hi = text "hi16("
413
414 pprImm (HA i)
415   = hcat [ pp_ha, pprImm i, rparen ]
416   where
417     pp_ha = text "ha16("
418     
419 #else
420 pprImm (LO i)
421   = pprImm i <> text "@l"
422
423 pprImm (HI i)
424   = pprImm i <> text "@h"
425
426 pprImm (HA i)
427   = pprImm i <> text "@ha"
428 #endif
429 #endif
430
431
432 -- -----------------------------------------------------------------------------
433 -- @pprAddr: print an 'AddrMode'
434
435 pprAddr :: AddrMode -> Doc
436
437 #if alpha_TARGET_ARCH
438 pprAddr (AddrReg r) = parens (pprReg r)
439 pprAddr (AddrImm i) = pprImm i
440 pprAddr (AddrRegImm r1 i)
441   = (<>) (pprImm i) (parens (pprReg r1))
442 #endif
443
444 -------------------
445
446 #if i386_TARGET_ARCH
447 pprAddr (ImmAddr imm off)
448   = let pp_imm = pprImm imm
449     in
450     if (off == 0) then
451         pp_imm
452     else if (off < 0) then
453         pp_imm <> int off
454     else
455         pp_imm <> char '+' <> int off
456
457 pprAddr (AddrBaseIndex base index displacement)
458   = let
459         pp_disp  = ppr_disp displacement
460         pp_off p = pp_disp <> char '(' <> p <> char ')'
461         pp_reg r = pprReg I32 r
462     in
463     case (base,index) of
464       (Nothing, Nothing)    -> pp_disp
465       (Just b,  Nothing)    -> pp_off (pp_reg b)
466       (Nothing, Just (r,i)) -> pp_off (comma <> pp_reg r <> comma <> int i)
467       (Just b,  Just (r,i)) -> pp_off (pp_reg b <> comma <> pp_reg r 
468                                        <> comma <> int i)
469   where
470     ppr_disp (ImmInt 0) = empty
471     ppr_disp imm        = pprImm imm
472 #endif
473
474 -------------------
475
476 #if sparc_TARGET_ARCH
477 pprAddr (AddrRegReg r1 (RealReg 0)) = pprReg r1
478
479 pprAddr (AddrRegReg r1 r2)
480   = hcat [ pprReg r1, char '+', pprReg r2 ]
481
482 pprAddr (AddrRegImm r1 (ImmInt i))
483   | i == 0 = pprReg r1
484   | not (fits13Bits i) = largeOffsetError i
485   | otherwise = hcat [ pprReg r1, pp_sign, int i ]
486   where
487     pp_sign = if i > 0 then char '+' else empty
488
489 pprAddr (AddrRegImm r1 (ImmInteger i))
490   | i == 0 = pprReg r1
491   | not (fits13Bits i) = largeOffsetError i
492   | otherwise  = hcat [ pprReg r1, pp_sign, integer i ]
493   where
494     pp_sign = if i > 0 then char '+' else empty
495
496 pprAddr (AddrRegImm r1 imm)
497   = hcat [ pprReg r1, char '+', pprImm imm ]
498 #endif
499
500 -------------------
501
502 #if powerpc_TARGET_ARCH
503 pprAddr (AddrRegReg r1 r2)
504   = pprReg r1 <+> ptext SLIT(", ") <+> pprReg r2
505
506 pprAddr (AddrRegImm r1 (ImmInt i)) = hcat [ int i, char '(', pprReg r1, char ')' ]
507 pprAddr (AddrRegImm r1 (ImmInteger i)) = hcat [ integer i, char '(', pprReg r1, char ')' ]
508 pprAddr (AddrRegImm r1 imm) = hcat [ pprImm imm, char '(', pprReg r1, char ')' ]
509 #endif
510
511
512 -- -----------------------------------------------------------------------------
513 -- pprData: print a 'CmmStatic'
514
515 pprSectionHeader Text
516     = ptext
517         IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
518        ,IF_ARCH_sparc(SLIT(".text\n\t.align 4") {-word boundary-}
519        ,IF_ARCH_i386(SLIT(".text\n\t.align 4,0x90") {-needs per-OS variation!-}
520        ,IF_ARCH_powerpc(SLIT(".text\n.align 2")
521        ,))))
522 pprSectionHeader Data
523     = ptext
524          IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
525         ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
526         ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
527         ,IF_ARCH_powerpc(SLIT(".data\n.align 2")
528         ,))))
529 pprSectionHeader ReadOnlyData
530     = ptext
531          IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
532         ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
533         ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
534         ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
535                                       SLIT(".section .rodata\n\t.align 2"))
536         ,))))
537 pprSectionHeader UninitialisedData
538     = ptext
539          IF_ARCH_alpha(SLIT("\t.bss\n\t.align 3")
540         ,IF_ARCH_sparc(SLIT(".bss\n\t.align 8") {-<8 will break double constants -}
541         ,IF_ARCH_i386(SLIT(".section .bss\n\t.align 4")
542         ,IF_ARCH_powerpc(IF_OS_darwin(SLIT(".const_data\n.align 2"),
543                                       SLIT(".section .bss\n\t.align 2"))
544         ,))))
545 pprSectionHeader (OtherSection sec)
546     = panic "PprMach.pprSectionHeader: unknown section"
547
548 pprData :: CmmStatic -> Doc
549 pprData (CmmAlign bytes)         = pprAlign bytes
550 pprData (CmmDataLabel lbl)       = pprLabel lbl
551 pprData (CmmString str)          = pprASCII str
552 pprData (CmmUninitialised bytes) = ptext SLIT(".space ") <> int bytes
553 pprData (CmmStaticLit lit)       = pprDataItem lit
554
555 pprGloblDecl :: CLabel -> Doc
556 pprGloblDecl lbl
557   | not (externallyVisibleCLabel lbl) = empty
558   | otherwise = ptext IF_ARCH_alpha(SLIT(".globl ")
559                         ,IF_ARCH_i386(SLIT(".globl ")
560                         ,IF_ARCH_sparc(SLIT(".global ")
561                         ,IF_ARCH_powerpc(SLIT(".globl ")
562                         ,)))) <>
563                 pprCLabel_asm lbl
564
565 pprLabel :: CLabel -> Doc
566 pprLabel lbl = pprGloblDecl lbl $$ (pprCLabel_asm lbl <> char ':')
567
568
569 -- Assume we want to backslash-convert the string
570 pprASCII str
571   = vcat (map do1 (str ++ [chr 0]))
572     where
573        do1 :: Char -> Doc
574        do1 c = ptext SLIT("\t.byte\t0x") <> hshow (ord c)
575
576        hshow :: Int -> Doc
577        hshow n | n >= 0 && n <= 255
578                = char (tab !! (n `div` 16)) <> char (tab !! (n `mod` 16))
579        tab = "0123456789ABCDEF"
580
581 pprAlign bytes =
582         IF_ARCH_alpha(ptextSLIT(".align ") <> int pow2,
583         IF_ARCH_i386(ptext SLIT(".align ") <> int bytes,
584         IF_ARCH_sparc(ptext SLIT(".align ") <> int bytes,
585         IF_ARCH_powerpc(ptext SLIT(".align ") <> int pow2,))))
586   where
587         pow2 = log2 bytes
588         
589         log2 :: Int -> Int  -- cache the common ones
590         log2 1 = 0 
591         log2 2 = 1
592         log2 4 = 2
593         log2 8 = 3
594         log2 n = 1 + log2 (n `quot` 2)
595
596
597 pprDataItem :: CmmLit -> Doc
598 pprDataItem lit
599   = vcat (ppr_item (cmmLitRep lit) lit)
600     where
601         imm = litToImm lit
602
603         -- These seem to be common:
604         ppr_item I8   x = [ptext SLIT("\t.byte\t") <> pprImm imm]
605         ppr_item I32  x = [ptext SLIT("\t.long\t") <> pprImm imm]
606         ppr_item F32  (CmmFloat r _)
607            = let bs = floatToBytes (fromRational r)
608              in  map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
609         ppr_item F64 (CmmFloat r _)
610            = let bs = doubleToBytes (fromRational r)
611              in  map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
612
613 #if sparc_TARGET_ARCH
614         -- copy n paste of x86 version
615         ppr_item I16  x = [ptext SLIT("\t.short\t") <> pprImm imm]
616         ppr_item I64  x = [ptext SLIT("\t.quad\t") <> pprImm imm]
617 #endif
618 #if i386_TARGET_ARCH
619         ppr_item I16  x = [ptext SLIT("\t.word\t") <> pprImm imm]
620         ppr_item I64  x = [ptext SLIT("\t.quad\t") <> pprImm imm]
621 #endif
622 #if powerpc_TARGET_ARCH
623         ppr_item I16 x = [ptext SLIT("\t.short\t") <> pprImm imm]
624         ppr_item I64 (CmmInt x _)  =
625                 [ptext SLIT("\t.long\t")
626                     <> int (fromIntegral 
627                         (fromIntegral (x `shiftR` 32) :: Word32)),
628                  ptext SLIT("\t.long\t")
629                     <> int (fromIntegral (fromIntegral x :: Word32))]
630 #endif
631
632 -- fall through to rest of (machine-specific) pprInstr...
633
634 -- -----------------------------------------------------------------------------
635 -- pprInstr: print an 'Instr'
636
637 pprInstr :: Instr -> Doc
638
639 --pprInstr (COMMENT s) = empty -- nuke 'em
640 pprInstr (COMMENT s)
641    =  IF_ARCH_alpha( ((<>) (ptext SLIT("\t# ")) (ftext s))
642      ,IF_ARCH_sparc( ((<>) (ptext SLIT("! "))   (ftext s))
643      ,IF_ARCH_i386( ((<>) (ptext SLIT("# "))   (ftext s))
644      ,IF_ARCH_powerpc( IF_OS_linux(
645         ((<>) (ptext SLIT("# ")) (ftext s)),
646         ((<>) (ptext SLIT("; ")) (ftext s)))
647      ,))))
648
649 pprInstr (DELTA d)
650    = pprInstr (COMMENT (mkFastString ("\tdelta = " ++ show d)))
651
652 pprInstr (NEWBLOCK _)
653    = panic "PprMach.pprInstr: NEWBLOCK"
654
655 pprInstr (LDATA _ _)
656    = panic "PprMach.pprInstr: LDATA"
657
658 -- -----------------------------------------------------------------------------
659 -- pprInstr for an Alpha
660
661 #if alpha_TARGET_ARCH
662
663 pprInstr (LD size reg addr)
664   = hcat [
665         ptext SLIT("\tld"),
666         pprSize size,
667         char '\t',
668         pprReg reg,
669         comma,
670         pprAddr addr
671     ]
672
673 pprInstr (LDA reg addr)
674   = hcat [
675         ptext SLIT("\tlda\t"),
676         pprReg reg,
677         comma,
678         pprAddr addr
679     ]
680
681 pprInstr (LDAH reg addr)
682   = hcat [
683         ptext SLIT("\tldah\t"),
684         pprReg reg,
685         comma,
686         pprAddr addr
687     ]
688
689 pprInstr (LDGP reg addr)
690   = hcat [
691         ptext SLIT("\tldgp\t"),
692         pprReg reg,
693         comma,
694         pprAddr addr
695     ]
696
697 pprInstr (LDI size reg imm)
698   = hcat [
699         ptext SLIT("\tldi"),
700         pprSize size,
701         char '\t',
702         pprReg reg,
703         comma,
704         pprImm imm
705     ]
706
707 pprInstr (ST size reg addr)
708   = hcat [
709         ptext SLIT("\tst"),
710         pprSize size,
711         char '\t',
712         pprReg reg,
713         comma,
714         pprAddr addr
715     ]
716
717 pprInstr (CLR reg)
718   = hcat [
719         ptext SLIT("\tclr\t"),
720         pprReg reg
721     ]
722
723 pprInstr (ABS size ri reg)
724   = hcat [
725         ptext SLIT("\tabs"),
726         pprSize size,
727         char '\t',
728         pprRI ri,
729         comma,
730         pprReg reg
731     ]
732
733 pprInstr (NEG size ov ri reg)
734   = hcat [
735         ptext SLIT("\tneg"),
736         pprSize size,
737         if ov then ptext SLIT("v\t") else char '\t',
738         pprRI ri,
739         comma,
740         pprReg reg
741     ]
742
743 pprInstr (ADD size ov reg1 ri reg2)
744   = hcat [
745         ptext SLIT("\tadd"),
746         pprSize size,
747         if ov then ptext SLIT("v\t") else char '\t',
748         pprReg reg1,
749         comma,
750         pprRI ri,
751         comma,
752         pprReg reg2
753     ]
754
755 pprInstr (SADD size scale reg1 ri reg2)
756   = hcat [
757         ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
758         ptext SLIT("add"),
759         pprSize size,
760         char '\t',
761         pprReg reg1,
762         comma,
763         pprRI ri,
764         comma,
765         pprReg reg2
766     ]
767
768 pprInstr (SUB size ov reg1 ri reg2)
769   = hcat [
770         ptext SLIT("\tsub"),
771         pprSize size,
772         if ov then ptext SLIT("v\t") else char '\t',
773         pprReg reg1,
774         comma,
775         pprRI ri,
776         comma,
777         pprReg reg2
778     ]
779
780 pprInstr (SSUB size scale reg1 ri reg2)
781   = hcat [
782         ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
783         ptext SLIT("sub"),
784         pprSize size,
785         char '\t',
786         pprReg reg1,
787         comma,
788         pprRI ri,
789         comma,
790         pprReg reg2
791     ]
792
793 pprInstr (MUL size ov reg1 ri reg2)
794   = hcat [
795         ptext SLIT("\tmul"),
796         pprSize size,
797         if ov then ptext SLIT("v\t") else char '\t',
798         pprReg reg1,
799         comma,
800         pprRI ri,
801         comma,
802         pprReg reg2
803     ]
804
805 pprInstr (DIV size uns reg1 ri reg2)
806   = hcat [
807         ptext SLIT("\tdiv"),
808         pprSize size,
809         if uns then ptext SLIT("u\t") else char '\t',
810         pprReg reg1,
811         comma,
812         pprRI ri,
813         comma,
814         pprReg reg2
815     ]
816
817 pprInstr (REM size uns reg1 ri reg2)
818   = hcat [
819         ptext SLIT("\trem"),
820         pprSize size,
821         if uns then ptext SLIT("u\t") else char '\t',
822         pprReg reg1,
823         comma,
824         pprRI ri,
825         comma,
826         pprReg reg2
827     ]
828
829 pprInstr (NOT ri reg)
830   = hcat [
831         ptext SLIT("\tnot"),
832         char '\t',
833         pprRI ri,
834         comma,
835         pprReg reg
836     ]
837
838 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
839 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
840 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
841 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
842 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
843 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
844
845 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
846 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
847 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
848
849 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
850 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
851
852 pprInstr (NOP) = ptext SLIT("\tnop")
853
854 pprInstr (CMP cond reg1 ri reg2)
855   = hcat [
856         ptext SLIT("\tcmp"),
857         pprCond cond,
858         char '\t',
859         pprReg reg1,
860         comma,
861         pprRI ri,
862         comma,
863         pprReg reg2
864     ]
865
866 pprInstr (FCLR reg)
867   = hcat [
868         ptext SLIT("\tfclr\t"),
869         pprReg reg
870     ]
871
872 pprInstr (FABS reg1 reg2)
873   = hcat [
874         ptext SLIT("\tfabs\t"),
875         pprReg reg1,
876         comma,
877         pprReg reg2
878     ]
879
880 pprInstr (FNEG size reg1 reg2)
881   = hcat [
882         ptext SLIT("\tneg"),
883         pprSize size,
884         char '\t',
885         pprReg reg1,
886         comma,
887         pprReg reg2
888     ]
889
890 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
891 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
892 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
893 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
894
895 pprInstr (CVTxy size1 size2 reg1 reg2)
896   = hcat [
897         ptext SLIT("\tcvt"),
898         pprSize size1,
899         case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
900         char '\t',
901         pprReg reg1,
902         comma,
903         pprReg reg2
904     ]
905
906 pprInstr (FCMP size cond reg1 reg2 reg3)
907   = hcat [
908         ptext SLIT("\tcmp"),
909         pprSize size,
910         pprCond cond,
911         char '\t',
912         pprReg reg1,
913         comma,
914         pprReg reg2,
915         comma,
916         pprReg reg3
917     ]
918
919 pprInstr (FMOV reg1 reg2)
920   = hcat [
921         ptext SLIT("\tfmov\t"),
922         pprReg reg1,
923         comma,
924         pprReg reg2
925     ]
926
927 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
928
929 pprInstr (BI NEVER reg lab) = empty
930
931 pprInstr (BI cond reg lab)
932   = hcat [
933         ptext SLIT("\tb"),
934         pprCond cond,
935         char '\t',
936         pprReg reg,
937         comma,
938         pprImm lab
939     ]
940
941 pprInstr (BF cond reg lab)
942   = hcat [
943         ptext SLIT("\tfb"),
944         pprCond cond,
945         char '\t',
946         pprReg reg,
947         comma,
948         pprImm lab
949     ]
950
951 pprInstr (BR lab)
952   = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
953
954 pprInstr (JMP reg addr hint)
955   = hcat [
956         ptext SLIT("\tjmp\t"),
957         pprReg reg,
958         comma,
959         pprAddr addr,
960         comma,
961         int hint
962     ]
963
964 pprInstr (BSR imm n)
965   = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
966
967 pprInstr (JSR reg addr n)
968   = hcat [
969         ptext SLIT("\tjsr\t"),
970         pprReg reg,
971         comma,
972         pprAddr addr
973     ]
974
975 pprInstr (FUNBEGIN clab)
976   = hcat [
977         if (externallyVisibleCLabel clab) then
978             hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
979         else
980             empty,
981         ptext SLIT("\t.ent "),
982         pp_lab,
983         char '\n',
984         pp_lab,
985         pp_ldgp,
986         pp_lab,
987         pp_frame
988     ]
989     where
990         pp_lab = pprCLabel_asm clab
991
992         -- NEVER use commas within those string literals, cpp will ruin your day
993         pp_ldgp  = hcat [ ptext SLIT(":\n\tldgp $29"), char ',', ptext SLIT("0($27)\n") ]
994         pp_frame = hcat [ ptext SLIT("..ng:\n\t.frame $30"), char ',',
995                           ptext SLIT("4240"), char ',',
996                           ptext SLIT("$26"), char ',',
997                           ptext SLIT("0\n\t.prologue 1") ]
998
999 pprInstr (FUNEND clab)
1000   = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
1001 \end{code}
1002
1003 Continue with Alpha-only printing bits and bobs:
1004 \begin{code}
1005 pprRI :: RI -> Doc
1006
1007 pprRI (RIReg r) = pprReg r
1008 pprRI (RIImm r) = pprImm r
1009
1010 pprRegRIReg :: LitString -> Reg -> RI -> Reg -> Doc
1011 pprRegRIReg name reg1 ri reg2
1012   = hcat [
1013         char '\t',
1014         ptext name,
1015         char '\t',
1016         pprReg reg1,
1017         comma,
1018         pprRI ri,
1019         comma,
1020         pprReg reg2
1021     ]
1022
1023 pprSizeRegRegReg :: LitString -> Size -> Reg -> Reg -> Reg -> Doc
1024 pprSizeRegRegReg name size reg1 reg2 reg3
1025   = hcat [
1026         char '\t',
1027         ptext name,
1028         pprSize size,
1029         char '\t',
1030         pprReg reg1,
1031         comma,
1032         pprReg reg2,
1033         comma,
1034         pprReg reg3
1035     ]
1036
1037 #endif /* alpha_TARGET_ARCH */
1038
1039
1040 -- -----------------------------------------------------------------------------
1041 -- pprInstr for an x86
1042
1043 #if i386_TARGET_ARCH
1044
1045 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
1046   | src == dst
1047   =
1048 #if 0 /* #ifdef DEBUG */
1049     (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
1050 #else
1051     empty
1052 #endif
1053 pprInstr (MOV size src dst)
1054   = pprSizeOpOp SLIT("mov") size src dst
1055 pprInstr (MOVZxL sizes src dst) = pprSizeOpOpCoerce SLIT("movz") sizes I32 src dst
1056 pprInstr (MOVSxL sizes src dst) = pprSizeOpOpCoerce SLIT("movs") sizes I32 src dst
1057
1058 -- here we do some patching, since the physical registers are only set late
1059 -- in the code generation.
1060 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
1061   | reg1 == reg3
1062   = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
1063 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
1064   | reg2 == reg3
1065   = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
1066 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
1067   | reg1 == reg3
1068   = pprInstr (ADD size (OpImm displ) dst)
1069 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
1070
1071 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
1072   = pprSizeOp SLIT("dec") size dst
1073 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
1074   = pprSizeOp SLIT("inc") size dst
1075 pprInstr (ADD size src dst)
1076   = pprSizeOpOp SLIT("add") size src dst
1077 pprInstr (ADC size src dst)
1078   = pprSizeOpOp SLIT("adc") size src dst
1079 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
1080 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
1081
1082 {- A hack.  The Intel documentation says that "The two and three
1083    operand forms [of IMUL] may also be used with unsigned operands
1084    because the lower half of the product is the same regardless if
1085    (sic) the operands are signed or unsigned.  The CF and OF flags,
1086    however, cannot be used to determine if the upper half of the
1087    result is non-zero."  So there.  
1088 -} 
1089 pprInstr (MUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
1090
1091 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
1092 pprInstr (OR  size src dst) = pprSizeOpOp SLIT("or")  size src dst
1093 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor")  size src dst
1094 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
1095 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
1096
1097 pprInstr (SHL size src dst) = pprShift SLIT("shl") size src dst
1098 pprInstr (SAR size src dst) = pprShift SLIT("sar") size src dst
1099 pprInstr (SHR size src dst) = pprShift SLIT("shr") size src dst
1100
1101 pprInstr (BT  size imm src) = pprSizeImmOp SLIT("bt") size imm src
1102
1103 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp")  size src dst
1104 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test")  size src dst
1105 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
1106 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
1107
1108 -- both unused (SDM):
1109 -- pprInstr PUSHA = ptext SLIT("\tpushal")
1110 -- pprInstr POPA = ptext SLIT("\tpopal")
1111
1112 pprInstr NOP = ptext SLIT("\tnop")
1113 pprInstr CLTD = ptext SLIT("\tcltd")
1114
1115 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand I8 op)
1116
1117 pprInstr (JXX cond (BlockId id)) 
1118   = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
1119   where lab = mkAsmTempLabel id
1120
1121 pprInstr (JMP (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
1122 pprInstr (JMP op)          = (<>) (ptext SLIT("\tjmp *")) (pprOperand I32 op)
1123 pprInstr (JMP_TBL op ids)  = pprInstr (JMP op)
1124 pprInstr (CALL (Left imm))      = (<>) (ptext SLIT("\tcall ")) (pprImm imm)
1125 pprInstr (CALL (Right reg))     = (<>) (ptext SLIT("\tcall *")) (pprReg I32 reg)
1126
1127 pprInstr (IDIV sz op)   = pprSizeOp SLIT("idiv") sz op
1128 pprInstr (DIV sz op)    = pprSizeOp SLIT("div")  sz op
1129
1130 pprInstr (IMUL64 sd_hi sd_lo) = pprInstr_imul64 sd_hi sd_lo
1131
1132
1133 -- Simulating a flat register set on the x86 FP stack is tricky.
1134 -- you have to free %st(7) before pushing anything on the FP reg stack
1135 -- so as to preclude the possibility of a FP stack overflow exception.
1136 pprInstr g@(GMOV src dst)
1137    | src == dst
1138    = empty
1139    | otherwise 
1140    = pprG g (hcat [gtab, gpush src 0, gsemi, gpop dst 1])
1141
1142 -- GLD sz addr dst ==> FFREE %st(7) ; FLDsz addr ; FSTP (dst+1)
1143 pprInstr g@(GLD sz addr dst)
1144  = pprG g (hcat [gtab, text "ffree %st(7) ; fld", pprSize sz, gsp, 
1145                  pprAddr addr, gsemi, gpop dst 1])
1146
1147 -- GST sz src addr ==> FFREE %st(7) ; FLD dst ; FSTPsz addr
1148 pprInstr g@(GST sz src addr)
1149  = pprG g (hcat [gtab, gpush src 0, gsemi, 
1150                  text "fstp", pprSize sz, gsp, pprAddr addr])
1151
1152 pprInstr g@(GLDZ dst)
1153  = pprG g (hcat [gtab, text "ffree %st(7) ; fldz ; ", gpop dst 1])
1154 pprInstr g@(GLD1 dst)
1155  = pprG g (hcat [gtab, text "ffree %st(7) ; fld1 ; ", gpop dst 1])
1156
1157 pprInstr g@(GFTOI src dst) 
1158    = pprInstr (GDTOI src dst)
1159 pprInstr g@(GDTOI src dst) 
1160    = pprG g (hcat [gtab, text "subl $4, %esp ; ", 
1161                    gpush src 0, gsemi, text "fistpl 0(%esp) ; popl ", 
1162                    pprReg I32 dst])
1163
1164 pprInstr g@(GITOF src dst) 
1165    = pprInstr (GITOD src dst)
1166 pprInstr g@(GITOD src dst) 
1167    = pprG g (hcat [gtab, text "pushl ", pprReg I32 src, 
1168                    text " ; ffree %st(7); fildl (%esp) ; ",
1169                    gpop dst 1, text " ; addl $4,%esp"])
1170
1171 {- Gruesome swamp follows.  If you're unfortunate enough to have ventured
1172    this far into the jungle AND you give a Rat's Ass (tm) what's going
1173    on, here's the deal.  Generate code to do a floating point comparison
1174    of src1 and src2, of kind cond, and set the Zero flag if true.
1175
1176    The complications are to do with handling NaNs correctly.  We want the
1177    property that if either argument is NaN, then the result of the
1178    comparison is False ... except if we're comparing for inequality,
1179    in which case the answer is True.
1180
1181    Here's how the general (non-inequality) case works.  As an
1182    example, consider generating the an equality test:
1183
1184      pushl %eax         -- we need to mess with this
1185      <get src1 to top of FPU stack>
1186      fcomp <src2 location in FPU stack> and pop pushed src1
1187                 -- Result of comparison is in FPU Status Register bits
1188                 -- C3 C2 and C0
1189      fstsw %ax  -- Move FPU Status Reg to %ax
1190      sahf       -- move C3 C2 C0 from %ax to integer flag reg
1191      -- now the serious magic begins
1192      setpo %ah     -- %ah = if comparable(neither arg was NaN) then 1 else 0
1193      sete  %al     -- %al = if arg1 == arg2 then 1 else 0
1194      andb %ah,%al  -- %al &= %ah
1195                    -- so %al == 1 iff (comparable && same); else it holds 0
1196      decb %al      -- %al == 0, ZeroFlag=1  iff (comparable && same); 
1197                       else %al == 0xFF, ZeroFlag=0
1198      -- the zero flag is now set as we desire.
1199      popl %eax
1200
1201    The special case of inequality differs thusly:
1202
1203      setpe %ah     -- %ah = if incomparable(either arg was NaN) then 1 else 0
1204      setne %al     -- %al = if arg1 /= arg2 then 1 else 0
1205      orb %ah,%al   -- %al = if (incomparable || different) then 1 else 0
1206      decb %al      -- if (incomparable || different) then (%al == 0, ZF=1)
1207                                                      else (%al == 0xFF, ZF=0)
1208 -}
1209 pprInstr g@(GCMP cond src1 src2) 
1210    | case cond of { NE -> True; other -> False }
1211    = pprG g (vcat [
1212         hcat [gtab, text "pushl %eax ; ",gpush src1 0],
1213         hcat [gtab, text "fcomp ", greg src2 1, 
1214                     text "; fstsw %ax ; sahf ;  setpe %ah"],
1215         hcat [gtab, text "setne %al ;  ",
1216               text "orb %ah,%al ;  decb %al ;  popl %eax"]
1217     ])
1218    | otherwise
1219    = pprG g (vcat [
1220         hcat [gtab, text "pushl %eax ; ",gpush src1 0],
1221         hcat [gtab, text "fcomp ", greg src2 1, 
1222                     text "; fstsw %ax ; sahf ;  setpo %ah"],
1223         hcat [gtab, text "set", pprCond (fix_FP_cond cond), text " %al ;  ",
1224               text "andb %ah,%al ;  decb %al ;  popl %eax"]
1225     ])
1226     where
1227         {- On the 486, the flags set by FP compare are the unsigned ones!
1228            (This looks like a HACK to me.  WDP 96/03)
1229         -}
1230         fix_FP_cond :: Cond -> Cond
1231         fix_FP_cond GE   = GEU
1232         fix_FP_cond GTT  = GU
1233         fix_FP_cond LTT  = LU
1234         fix_FP_cond LE   = LEU
1235         fix_FP_cond EQQ  = EQQ
1236         fix_FP_cond NE   = NE
1237         -- there should be no others
1238
1239
1240 pprInstr g@(GABS sz src dst)
1241    = pprG g (hcat [gtab, gpush src 0, text " ; fabs ; ", gpop dst 1])
1242 pprInstr g@(GNEG sz src dst)
1243    = pprG g (hcat [gtab, gpush src 0, text " ; fchs ; ", gpop dst 1])
1244
1245 pprInstr g@(GSQRT sz src dst)
1246    = pprG g (hcat [gtab, gpush src 0, text " ; fsqrt"] $$ 
1247              hcat [gtab, gcoerceto sz, gpop dst 1])
1248 pprInstr g@(GSIN sz src dst)
1249    = pprG g (hcat [gtab, gpush src 0, text " ; fsin"] $$ 
1250              hcat [gtab, gcoerceto sz, gpop dst 1])
1251 pprInstr g@(GCOS sz src dst)
1252    = pprG g (hcat [gtab, gpush src 0, text " ; fcos"] $$ 
1253              hcat [gtab, gcoerceto sz, gpop dst 1])
1254 pprInstr g@(GTAN sz src dst)
1255    = pprG g (hcat [gtab, text "ffree %st(6) ; ",
1256                    gpush src 0, text " ; fptan ; ", 
1257                    text " fstp %st(0)"] $$
1258              hcat [gtab, gcoerceto sz, gpop dst 1])
1259
1260 -- In the translations for GADD, GMUL, GSUB and GDIV,
1261 -- the first two cases are mere optimisations.  The otherwise clause
1262 -- generates correct code under all circumstances.
1263
1264 pprInstr g@(GADD sz src1 src2 dst)
1265    | src1 == dst
1266    = pprG g (text "\t#GADD-xxxcase1" $$ 
1267              hcat [gtab, gpush src2 0,
1268                    text " ; faddp %st(0),", greg src1 1])
1269    | src2 == dst
1270    = pprG g (text "\t#GADD-xxxcase2" $$ 
1271              hcat [gtab, gpush src1 0,
1272                    text " ; faddp %st(0),", greg src2 1])
1273    | otherwise
1274    = pprG g (hcat [gtab, gpush src1 0, 
1275                    text " ; fadd ", greg src2 1, text ",%st(0)",
1276                    gsemi, gpop dst 1])
1277
1278
1279 pprInstr g@(GMUL sz src1 src2 dst)
1280    | src1 == dst
1281    = pprG g (text "\t#GMUL-xxxcase1" $$ 
1282              hcat [gtab, gpush src2 0,
1283                    text " ; fmulp %st(0),", greg src1 1])
1284    | src2 == dst
1285    = pprG g (text "\t#GMUL-xxxcase2" $$ 
1286              hcat [gtab, gpush src1 0,
1287                    text " ; fmulp %st(0),", greg src2 1])
1288    | otherwise
1289    = pprG g (hcat [gtab, gpush src1 0, 
1290                    text " ; fmul ", greg src2 1, text ",%st(0)",
1291                    gsemi, gpop dst 1])
1292
1293
1294 pprInstr g@(GSUB sz src1 src2 dst)
1295    | src1 == dst
1296    = pprG g (text "\t#GSUB-xxxcase1" $$ 
1297              hcat [gtab, gpush src2 0,
1298                    text " ; fsubrp %st(0),", greg src1 1])
1299    | src2 == dst
1300    = pprG g (text "\t#GSUB-xxxcase2" $$ 
1301              hcat [gtab, gpush src1 0,
1302                    text " ; fsubp %st(0),", greg src2 1])
1303    | otherwise
1304    = pprG g (hcat [gtab, gpush src1 0, 
1305                    text " ; fsub ", greg src2 1, text ",%st(0)",
1306                    gsemi, gpop dst 1])
1307
1308
1309 pprInstr g@(GDIV sz src1 src2 dst)
1310    | src1 == dst
1311    = pprG g (text "\t#GDIV-xxxcase1" $$ 
1312              hcat [gtab, gpush src2 0,
1313                    text " ; fdivrp %st(0),", greg src1 1])
1314    | src2 == dst
1315    = pprG g (text "\t#GDIV-xxxcase2" $$ 
1316              hcat [gtab, gpush src1 0,
1317                    text " ; fdivp %st(0),", greg src2 1])
1318    | otherwise
1319    = pprG g (hcat [gtab, gpush src1 0, 
1320                    text " ; fdiv ", greg src2 1, text ",%st(0)",
1321                    gsemi, gpop dst 1])
1322
1323
1324 pprInstr GFREE 
1325    = vcat [ ptext SLIT("\tffree %st(0) ;ffree %st(1) ;ffree %st(2) ;ffree %st(3)"),
1326             ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)") 
1327           ]
1328
1329
1330 -- Emit code to make hi_reg:lo_reg be the 64-bit product of hi_reg and lo_reg
1331 pprInstr_imul64 hi_reg lo_reg
1332    = let fakeInsn = text "imul64" <+> pp_hi_reg <> comma <+> pp_lo_reg
1333          pp_hi_reg = pprReg I32 hi_reg
1334          pp_lo_reg = pprReg I32 lo_reg
1335      in     
1336          vcat [
1337             text "\t# BEGIN " <> fakeInsn,
1338             text "\tpushl" <+> pp_hi_reg <> text" ;  pushl" <+> pp_lo_reg,
1339             text "\tpushl %eax ; pushl %edx",
1340             text "\tmovl 12(%esp), %eax ; imull 8(%esp)",
1341             text "\tmovl %edx, 12(%esp) ; movl %eax, 8(%esp)",
1342             text "\tpopl %edx ; popl %eax",
1343             text "\tpopl" <+> pp_lo_reg <> text " ;  popl" <+> pp_hi_reg,
1344             text "\t# END   " <> fakeInsn
1345          ]
1346
1347
1348 --------------------------
1349
1350 -- coerce %st(0) to the specified size
1351 gcoerceto F64 = empty
1352 gcoerceto F32 = empty --text "subl $4,%esp ; fstps (%esp) ; flds (%esp) ; addl $4,%esp ; "
1353
1354 gpush reg offset
1355    = hcat [text "ffree %st(7) ; fld ", greg reg offset]
1356 gpop reg offset
1357    = hcat [text "fstp ", greg reg offset]
1358
1359 greg reg offset = text "%st(" <> int (gregno reg - 8+offset) <> char ')'
1360 gsemi = text " ; "
1361 gtab  = char '\t'
1362 gsp   = char ' '
1363
1364 gregno (RealReg i) = i
1365 gregno other       = --pprPanic "gregno" (ppr other)
1366                      999   -- bogus; only needed for debug printing
1367
1368 pprG :: Instr -> Doc -> Doc
1369 pprG fake actual
1370    = (char '#' <> pprGInstr fake) $$ actual
1371
1372 pprGInstr (GMOV src dst)   = pprSizeRegReg SLIT("gmov") F64 src dst
1373 pprGInstr (GLD sz src dst) = pprSizeAddrReg SLIT("gld") sz src dst
1374 pprGInstr (GST sz src dst) = pprSizeRegAddr SLIT("gst") sz src dst
1375
1376 pprGInstr (GLDZ dst) = pprSizeReg SLIT("gldz") F64 dst
1377 pprGInstr (GLD1 dst) = pprSizeReg SLIT("gld1") F64 dst
1378
1379 pprGInstr (GFTOI src dst) = pprSizeSizeRegReg SLIT("gftoi") F32 I32  src dst
1380 pprGInstr (GDTOI src dst) = pprSizeSizeRegReg SLIT("gdtoi") F64 I32 src dst
1381
1382 pprGInstr (GITOF src dst) = pprSizeSizeRegReg SLIT("gitof") I32 F32  src dst
1383 pprGInstr (GITOD src dst) = pprSizeSizeRegReg SLIT("gitod") I32 F64 src dst
1384
1385 pprGInstr (GCMP co src dst) = pprCondRegReg SLIT("gcmp_") F64 co src dst
1386 pprGInstr (GABS sz src dst) = pprSizeRegReg SLIT("gabs") sz src dst
1387 pprGInstr (GNEG sz src dst) = pprSizeRegReg SLIT("gneg") sz src dst
1388 pprGInstr (GSQRT sz src dst) = pprSizeRegReg SLIT("gsqrt") sz src dst
1389 pprGInstr (GSIN sz src dst) = pprSizeRegReg SLIT("gsin") sz src dst
1390 pprGInstr (GCOS sz src dst) = pprSizeRegReg SLIT("gcos") sz src dst
1391 pprGInstr (GTAN sz src dst) = pprSizeRegReg SLIT("gtan") sz src dst
1392
1393 pprGInstr (GADD sz src1 src2 dst) = pprSizeRegRegReg SLIT("gadd") sz src1 src2 dst
1394 pprGInstr (GSUB sz src1 src2 dst) = pprSizeRegRegReg SLIT("gsub") sz src1 src2 dst
1395 pprGInstr (GMUL sz src1 src2 dst) = pprSizeRegRegReg SLIT("gmul") sz src1 src2 dst
1396 pprGInstr (GDIV sz src1 src2 dst) = pprSizeRegRegReg SLIT("gdiv") sz src1 src2 dst
1397
1398 -- Continue with I386-only printing bits and bobs:
1399
1400 pprDollImm :: Imm -> Doc
1401
1402 pprDollImm i =  ptext SLIT("$") <> pprImm i
1403
1404 pprOperand :: MachRep -> Operand -> Doc
1405 pprOperand s (OpReg r)   = pprReg s r
1406 pprOperand s (OpImm i)   = pprDollImm i
1407 pprOperand s (OpAddr ea) = pprAddr ea
1408
1409 pprMnemonic  :: LitString -> MachRep -> Doc
1410 pprMnemonic name size = 
1411    char '\t' <> ptext name <> pprSize size <> space
1412
1413 pprSizeImmOp :: LitString -> MachRep -> Imm -> Operand -> Doc
1414 pprSizeImmOp name size imm op1
1415   = hcat [
1416         pprMnemonic name size,
1417         char '$',
1418         pprImm imm,
1419         comma,
1420         pprOperand size op1
1421     ]
1422         
1423 pprSizeOp :: LitString -> MachRep -> Operand -> Doc
1424 pprSizeOp name size op1
1425   = hcat [
1426         pprMnemonic name size,
1427         pprOperand size op1
1428     ]
1429
1430 pprSizeOpOp :: LitString -> MachRep -> Operand -> Operand -> Doc
1431 pprSizeOpOp name size op1 op2
1432   = hcat [
1433         pprMnemonic name size,
1434         pprOperand size op1,
1435         comma,
1436         pprOperand size op2
1437     ]
1438
1439 pprSizeReg :: LitString -> MachRep -> Reg -> Doc
1440 pprSizeReg name size reg1
1441   = hcat [
1442         pprMnemonic name size,
1443         pprReg size reg1
1444     ]
1445
1446 pprSizeRegReg :: LitString -> MachRep -> Reg -> Reg -> Doc
1447 pprSizeRegReg name size reg1 reg2
1448   = hcat [
1449         pprMnemonic name size,
1450         pprReg size reg1,
1451         comma,
1452         pprReg size reg2
1453     ]
1454
1455 pprCondRegReg :: LitString -> MachRep -> Cond -> Reg -> Reg -> Doc
1456 pprCondRegReg name size cond reg1 reg2
1457   = hcat [
1458         char '\t',
1459         ptext name,
1460         pprCond cond,
1461         space,
1462         pprReg size reg1,
1463         comma,
1464         pprReg size reg2
1465     ]
1466
1467 pprSizeSizeRegReg :: LitString -> MachRep -> MachRep -> Reg -> Reg -> Doc
1468 pprSizeSizeRegReg name size1 size2 reg1 reg2
1469   = hcat [
1470         char '\t',
1471         ptext name,
1472         pprSize size1,
1473         pprSize size2,
1474         space,
1475         pprReg size1 reg1,
1476
1477         comma,
1478         pprReg size2 reg2
1479     ]
1480
1481 pprSizeRegRegReg :: LitString -> MachRep -> Reg -> Reg -> Reg -> Doc
1482 pprSizeRegRegReg name size reg1 reg2 reg3
1483   = hcat [
1484         pprMnemonic name size,
1485         pprReg size reg1,
1486         comma,
1487         pprReg size reg2,
1488         comma,
1489         pprReg size reg3
1490     ]
1491
1492 pprSizeAddrReg :: LitString -> MachRep -> AddrMode -> Reg -> Doc
1493 pprSizeAddrReg name size op dst
1494   = hcat [
1495         pprMnemonic name size,
1496         pprAddr op,
1497         comma,
1498         pprReg size dst
1499     ]
1500
1501 pprSizeRegAddr :: LitString -> MachRep -> Reg -> AddrMode -> Doc
1502 pprSizeRegAddr name size src op
1503   = hcat [
1504         pprMnemonic name size,
1505         pprReg size src,
1506         comma,
1507         pprAddr op
1508     ]
1509
1510 pprShift :: LitString -> MachRep -> Operand -> Operand -> Doc
1511 pprShift name size src dest
1512   = hcat [
1513         pprMnemonic name size,
1514         pprOperand I8 src,  -- src is 8-bit sized
1515         comma,
1516         pprOperand size dest
1517     ]
1518
1519 pprSizeOpOpCoerce :: LitString -> MachRep -> MachRep -> Operand -> Operand -> Doc
1520 pprSizeOpOpCoerce name size1 size2 op1 op2
1521   = hcat [ char '\t', ptext name, pprSize size1, pprSize size2, space,
1522         pprOperand size1 op1,
1523         comma,
1524         pprOperand size2 op2
1525     ]
1526
1527 pprCondInstr :: LitString -> Cond -> Doc -> Doc
1528 pprCondInstr name cond arg
1529   = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1530
1531 #endif /* i386_TARGET_ARCH */
1532
1533
1534 -- ------------------------------------------------------------------------------- pprInstr for a SPARC
1535
1536 #if sparc_TARGET_ARCH
1537
1538 -- a clumsy hack for now, to handle possible double alignment problems
1539
1540 -- even clumsier, to allow for RegReg regs that show when doing indexed
1541 -- reads (bytearrays).
1542 --
1543
1544 -- Translate to the following:
1545 --    add g1,g2,g1
1546 --    ld  [g1],%fn
1547 --    ld  [g1+4],%f(n+1)
1548 --    sub g1,g2,g1           -- to restore g1
1549 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1550   = vcat [
1551        hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1552        hcat [pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg],
1553        hcat [pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)],
1554        hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1555     ]
1556
1557 -- Translate to
1558 --    ld  [addr],%fn
1559 --    ld  [addr+4],%f(n+1)
1560 pprInstr (LD DF addr reg) | isJust off_addr
1561   = vcat [
1562        hcat [pp_ld_lbracket, pprAddr addr, pp_rbracket_comma, pprReg reg],
1563        hcat [pp_ld_lbracket, pprAddr addr2, pp_rbracket_comma,pprReg (fPair reg)]
1564     ]
1565   where
1566     off_addr = addrOffset addr 4
1567     addr2 = case off_addr of Just x -> x
1568
1569
1570 pprInstr (LD size addr reg)
1571   = hcat [
1572        ptext SLIT("\tld"),
1573        pprSize size,
1574        char '\t',
1575        lbrack,
1576        pprAddr addr,
1577        pp_rbracket_comma,
1578        pprReg reg
1579     ]
1580
1581 -- The same clumsy hack as above
1582
1583 -- Translate to the following:
1584 --    add g1,g2,g1
1585 --    st  %fn,[g1]
1586 --    st  %f(n+1),[g1+4]
1587 --    sub g1,g2,g1           -- to restore g1
1588 pprInstr (ST DF reg (AddrRegReg g1 g2))
1589  = vcat [
1590        hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1591        hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket, 
1592              pprReg g1, rbrack],
1593        hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1594              pprReg g1, ptext SLIT("+4]")],
1595        hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1596     ]
1597
1598 -- Translate to
1599 --    st  %fn,[addr]
1600 --    st  %f(n+1),[addr+4]
1601 pprInstr (ST DF reg addr) | isJust off_addr 
1602  = vcat [
1603       hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket, 
1604             pprAddr addr, rbrack],
1605       hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1606             pprAddr addr2, rbrack]
1607     ]
1608   where
1609     off_addr = addrOffset addr 4
1610     addr2 = case off_addr of Just x -> x
1611
1612 -- no distinction is made between signed and unsigned bytes on stores for the
1613 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1614 -- so we call a special-purpose pprSize for ST..
1615
1616 pprInstr (ST size reg addr)
1617   = hcat [
1618        ptext SLIT("\tst"),
1619        pprStSize size,
1620        char '\t',
1621        pprReg reg,
1622        pp_comma_lbracket,
1623        pprAddr addr,
1624        rbrack
1625     ]
1626
1627 pprInstr (ADD x cc reg1 ri reg2)
1628   | not x && not cc && riZero ri
1629   = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1630   | otherwise
1631   = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1632
1633 pprInstr (SUB x cc reg1 ri reg2)
1634   | not x && cc && reg2 == g0
1635   = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1636   | not x && not cc && riZero ri
1637   = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1638   | otherwise
1639   = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1640
1641 pprInstr (AND  b reg1 ri reg2) = pprRegRIReg SLIT("and")  b reg1 ri reg2
1642 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1643
1644 pprInstr (OR b reg1 ri reg2)
1645   | not b && reg1 == g0
1646   = let doit = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1647     in  case ri of
1648            RIReg rrr | rrr == reg2 -> empty
1649            other                   -> doit
1650   | otherwise
1651   = pprRegRIReg SLIT("or") b reg1 ri reg2
1652
1653 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1654
1655 pprInstr (XOR  b reg1 ri reg2) = pprRegRIReg SLIT("xor")  b reg1 ri reg2
1656 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1657
1658 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1659 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1660 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1661
1662 pprInstr (RDY rd) = ptext SLIT("\trd\t%y,") <> pprReg rd
1663 pprInstr (SMUL b reg1 ri reg2) = pprRegRIReg SLIT("smul")  b reg1 ri reg2
1664 pprInstr (UMUL b reg1 ri reg2) = pprRegRIReg SLIT("umul")  b reg1 ri reg2
1665
1666 pprInstr (SETHI imm reg)
1667   = hcat [
1668         ptext SLIT("\tsethi\t"),
1669         pprImm imm,
1670         comma,
1671         pprReg reg
1672     ]
1673
1674 pprInstr NOP = ptext SLIT("\tnop")
1675
1676 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1677 pprInstr (FABS DF reg1 reg2)
1678   = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1679     (if (reg1 == reg2) then empty
1680      else (<>) (char '\n')
1681           (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1682
1683 pprInstr (FADD size reg1 reg2 reg3)
1684   = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1685 pprInstr (FCMP e size reg1 reg2)
1686   = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1687 pprInstr (FDIV size reg1 reg2 reg3)
1688   = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1689
1690 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1691 pprInstr (FMOV DF reg1 reg2)
1692   = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1693     (if (reg1 == reg2) then empty
1694      else (<>) (char '\n')
1695           (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1696
1697 pprInstr (FMUL size reg1 reg2 reg3)
1698   = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1699
1700 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1701 pprInstr (FNEG DF reg1 reg2)
1702   = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1703     (if (reg1 == reg2) then empty
1704      else (<>) (char '\n')
1705           (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1706
1707 pprInstr (FSQRT size reg1 reg2)     = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1708 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1709 pprInstr (FxTOy size1 size2 reg1 reg2)
1710   = hcat [
1711         ptext SLIT("\tf"),
1712         ptext
1713         (case size1 of
1714             W  -> SLIT("ito")
1715             F  -> SLIT("sto")
1716             DF -> SLIT("dto")),
1717         ptext
1718         (case size2 of
1719             W  -> SLIT("i\t")
1720             F  -> SLIT("s\t")
1721             DF -> SLIT("d\t")),
1722         pprReg reg1, comma, pprReg reg2
1723     ]
1724
1725
1726 pprInstr (BI cond b lab)
1727   = hcat [
1728         ptext SLIT("\tb"), pprCond cond,
1729         if b then pp_comma_a else empty,
1730         char '\t',
1731         pprImm lab
1732     ]
1733
1734 pprInstr (BF cond b lab)
1735   = hcat [
1736         ptext SLIT("\tfb"), pprCond cond,
1737         if b then pp_comma_a else empty,
1738         char '\t',
1739         pprImm lab
1740     ]
1741
1742 pprInstr (JMP dsts addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1743
1744 pprInstr (CALL (Left imm) n _)
1745   = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1746 pprInstr (CALL (Right reg) n _)
1747   = hcat [ ptext SLIT("\tcall\t"), pprReg reg, comma, int n ]
1748 \end{code}
1749
1750 Continue with SPARC-only printing bits and bobs:
1751 \begin{code}
1752 pprRI :: RI -> Doc
1753 pprRI (RIReg r) = pprReg r
1754 pprRI (RIImm r) = pprImm r
1755
1756 pprSizeRegReg :: LitString -> Size -> Reg -> Reg -> Doc
1757 pprSizeRegReg name size reg1 reg2
1758   = hcat [
1759         char '\t',
1760         ptext name,
1761         (case size of
1762             F  -> ptext SLIT("s\t")
1763             DF -> ptext SLIT("d\t")),
1764         pprReg reg1,
1765         comma,
1766         pprReg reg2
1767     ]
1768
1769 pprSizeRegRegReg :: LitString -> Size -> Reg -> Reg -> Reg -> Doc
1770 pprSizeRegRegReg name size reg1 reg2 reg3
1771   = hcat [
1772         char '\t',
1773         ptext name,
1774         (case size of
1775             F  -> ptext SLIT("s\t")
1776             DF -> ptext SLIT("d\t")),
1777         pprReg reg1,
1778         comma,
1779         pprReg reg2,
1780         comma,
1781         pprReg reg3
1782     ]
1783
1784 pprRegRIReg :: LitString -> Bool -> Reg -> RI -> Reg -> Doc
1785 pprRegRIReg name b reg1 ri reg2
1786   = hcat [
1787         char '\t',
1788         ptext name,
1789         if b then ptext SLIT("cc\t") else char '\t',
1790         pprReg reg1,
1791         comma,
1792         pprRI ri,
1793         comma,
1794         pprReg reg2
1795     ]
1796
1797 pprRIReg :: LitString -> Bool -> RI -> Reg -> Doc
1798 pprRIReg name b ri reg1
1799   = hcat [
1800         char '\t',
1801         ptext name,
1802         if b then ptext SLIT("cc\t") else char '\t',
1803         pprRI ri,
1804         comma,
1805         pprReg reg1
1806     ]
1807
1808 pp_ld_lbracket    = ptext SLIT("\tld\t[")
1809 pp_rbracket_comma = text "],"
1810 pp_comma_lbracket = text ",["
1811 pp_comma_a        = text ",a"
1812
1813 #endif /* sparc_TARGET_ARCH */
1814
1815
1816 -- -----------------------------------------------------------------------------
1817 -- pprInstr for PowerPC
1818
1819 #if powerpc_TARGET_ARCH
1820 pprInstr (LD sz reg addr) = hcat [
1821         char '\t',
1822         ptext SLIT("l"),
1823         ptext (case sz of
1824             I8  -> SLIT("bz")
1825             I16 -> SLIT("hz")
1826             I32 -> SLIT("wz")
1827             F32 -> SLIT("fs")
1828             F64 -> SLIT("fd")),
1829         case addr of AddrRegImm _ _ -> empty
1830                      AddrRegReg _ _ -> char 'x',
1831         char '\t',
1832         pprReg reg,
1833         ptext SLIT(", "),
1834         pprAddr addr
1835     ]
1836 pprInstr (LA sz reg addr) = hcat [
1837         char '\t',
1838         ptext SLIT("l"),
1839         ptext (case sz of
1840             I8  -> SLIT("ba")
1841             I16 -> SLIT("ha")
1842             I32 -> SLIT("wa")
1843             F32 -> SLIT("fs")
1844             F64 -> SLIT("fd")),
1845         case addr of AddrRegImm _ _ -> empty
1846                      AddrRegReg _ _ -> char 'x',
1847         char '\t',
1848         pprReg reg,
1849         ptext SLIT(", "),
1850         pprAddr addr
1851     ]
1852 pprInstr (ST sz reg addr) = hcat [
1853         char '\t',
1854         ptext SLIT("st"),
1855         pprSize sz,
1856         case addr of AddrRegImm _ _ -> empty
1857                      AddrRegReg _ _ -> char 'x',
1858         char '\t',
1859         pprReg reg,
1860         ptext SLIT(", "),
1861         pprAddr addr
1862     ]
1863 pprInstr (STU sz reg addr) = hcat [
1864         char '\t',
1865         ptext SLIT("st"),
1866         pprSize sz,
1867         ptext SLIT("u\t"),
1868         case addr of AddrRegImm _ _ -> empty
1869                      AddrRegReg _ _ -> char 'x',
1870         pprReg reg,
1871         ptext SLIT(", "),
1872         pprAddr addr
1873     ]
1874 pprInstr (LIS reg imm) = hcat [
1875         char '\t',
1876         ptext SLIT("lis"),
1877         char '\t',
1878         pprReg reg,
1879         ptext SLIT(", "),
1880         pprImm imm
1881     ]
1882 pprInstr (LI reg imm) = hcat [
1883         char '\t',
1884         ptext SLIT("li"),
1885         char '\t',
1886         pprReg reg,
1887         ptext SLIT(", "),
1888         pprImm imm
1889     ]
1890 pprInstr (MR reg1 reg2) 
1891     | reg1 == reg2 = empty
1892     | otherwise = hcat [
1893         char '\t',
1894         case regClass reg1 of
1895             RcInteger -> ptext SLIT("mr")
1896             _ -> ptext SLIT("fmr"),
1897         char '\t',
1898         pprReg reg1,
1899         ptext SLIT(", "),
1900         pprReg reg2
1901     ]
1902 pprInstr (CMP sz reg ri) = hcat [
1903         char '\t',
1904         op,
1905         char '\t',
1906         pprReg reg,
1907         ptext SLIT(", "),
1908         pprRI ri
1909     ]
1910     where
1911         op = hcat [
1912                 ptext SLIT("cmp"),
1913                 pprSize sz,
1914                 case ri of
1915                     RIReg _ -> empty
1916                     RIImm _ -> char 'i'
1917             ]
1918 pprInstr (CMPL sz reg ri) = hcat [
1919         char '\t',
1920         op,
1921         char '\t',
1922         pprReg reg,
1923         ptext SLIT(", "),
1924         pprRI ri
1925     ]
1926     where
1927         op = hcat [
1928                 ptext SLIT("cmpl"),
1929                 pprSize sz,
1930                 case ri of
1931                     RIReg _ -> empty
1932                     RIImm _ -> char 'i'
1933             ]
1934 pprInstr (BCC cond (BlockId id)) = hcat [
1935         char '\t',
1936         ptext SLIT("b"),
1937         pprCond cond,
1938         char '\t',
1939         pprCLabel_asm lbl
1940     ]
1941     where lbl = mkAsmTempLabel id
1942
1943 pprInstr (JMP lbl) = hcat [ -- an alias for b that takes a CLabel
1944         char '\t',
1945         ptext SLIT("b"),
1946         char '\t',
1947         pprCLabel_asm lbl
1948     ]
1949
1950 pprInstr (MTCTR reg) = hcat [
1951         char '\t',
1952         ptext SLIT("mtctr"),
1953         char '\t',
1954         pprReg reg
1955     ]
1956 pprInstr (BCTR _) = hcat [
1957         char '\t',
1958         ptext SLIT("bctr")
1959     ]
1960 pprInstr (BL lbl _) = hcat [
1961         ptext SLIT("\tbl\t"),
1962         pprCLabel_asm lbl
1963     ]
1964 pprInstr (BCTRL _) = hcat [
1965         char '\t',
1966         ptext SLIT("bctrl")
1967     ]
1968 pprInstr (ADD reg1 reg2 ri) = pprLogic SLIT("add") reg1 reg2 ri
1969 pprInstr (ADDIS reg1 reg2 imm) = hcat [
1970         char '\t',
1971         ptext SLIT("addis"),
1972         char '\t',
1973         pprReg reg1,
1974         ptext SLIT(", "),
1975         pprReg reg2,
1976         ptext SLIT(", "),
1977         pprImm imm
1978     ]
1979
1980 pprInstr (ADDC reg1 reg2 reg3) = pprLogic SLIT("addc") reg1 reg2 (RIReg reg3)
1981 pprInstr (ADDE reg1 reg2 reg3) = pprLogic SLIT("adde") reg1 reg2 (RIReg reg3)
1982 pprInstr (SUBF reg1 reg2 reg3) = pprLogic SLIT("subf") reg1 reg2 (RIReg reg3)
1983 pprInstr (MULLW reg1 reg2 ri@(RIReg _)) = pprLogic SLIT("mullw") reg1 reg2 ri
1984 pprInstr (MULLW reg1 reg2 ri@(RIImm _)) = pprLogic SLIT("mull") reg1 reg2 ri
1985 pprInstr (DIVW reg1 reg2 reg3) = pprLogic SLIT("divw") reg1 reg2 (RIReg reg3)
1986 pprInstr (DIVWU reg1 reg2 reg3) = pprLogic SLIT("divwu") reg1 reg2 (RIReg reg3)
1987
1988 pprInstr (MULLW_MayOflo reg1 reg2 reg3) = vcat [
1989          hcat [ ptext SLIT("\tmullwo\t"), pprReg reg1, ptext SLIT(", "),
1990                                           pprReg reg2, ptext SLIT(", "),
1991                                           pprReg reg3 ],
1992          hcat [ ptext SLIT("\tmfxer\t"),  pprReg reg1 ],
1993          hcat [ ptext SLIT("\trlwinm\t"), pprReg reg1, ptext SLIT(", "),
1994                                           pprReg reg1, ptext SLIT(", "),
1995                                           ptext SLIT("2, 31, 31") ]
1996     ]
1997
1998         -- for some reason, "andi" doesn't exist.
1999         -- we'll use "andi." instead.
2000 pprInstr (AND reg1 reg2 (RIImm imm)) = hcat [
2001         char '\t',
2002         ptext SLIT("andi."),
2003         char '\t',
2004         pprReg reg1,
2005         ptext SLIT(", "),
2006         pprReg reg2,
2007         ptext SLIT(", "),
2008         pprImm imm
2009     ]
2010 pprInstr (AND reg1 reg2 ri) = pprLogic SLIT("and") reg1 reg2 ri
2011
2012 pprInstr (OR reg1 reg2 ri) = pprLogic SLIT("or") reg1 reg2 ri
2013 pprInstr (XOR reg1 reg2 ri) = pprLogic SLIT("xor") reg1 reg2 ri
2014
2015 pprInstr (XORIS reg1 reg2 imm) = hcat [
2016         char '\t',
2017         ptext SLIT("xoris"),
2018         char '\t',
2019         pprReg reg1,
2020         ptext SLIT(", "),
2021         pprReg reg2,
2022         ptext SLIT(", "),
2023         pprImm imm
2024     ]
2025
2026 pprInstr (EXTS sz reg1 reg2) = hcat [
2027         char '\t',
2028         ptext SLIT("exts"),
2029         pprSize sz,
2030         char '\t',
2031         pprReg reg1,
2032         ptext SLIT(", "),
2033         pprReg reg2
2034     ]
2035
2036 pprInstr (NEG reg1 reg2) = pprUnary SLIT("neg") reg1 reg2
2037 pprInstr (NOT reg1 reg2) = pprUnary SLIT("not") reg1 reg2
2038
2039 pprInstr (SLW reg1 reg2 ri) = pprLogic SLIT("slw") reg1 reg2 (limitShiftRI ri)
2040 pprInstr (SRW reg1 reg2 ri) = pprLogic SLIT("srw") reg1 reg2 (limitShiftRI ri)
2041 pprInstr (SRAW reg1 reg2 ri) = pprLogic SLIT("sraw") reg1 reg2 (limitShiftRI ri)
2042 pprInstr (RLWINM reg1 reg2 sh mb me) = hcat [
2043         ptext SLIT("\trlwinm\t"),
2044         pprReg reg1,
2045         ptext SLIT(", "),
2046         pprReg reg2,
2047         ptext SLIT(", "),
2048         int sh,
2049         ptext SLIT(", "),
2050         int mb,
2051         ptext SLIT(", "),
2052         int me
2053     ]
2054     
2055 pprInstr (FADD sz reg1 reg2 reg3) = pprBinaryF SLIT("fadd") sz reg1 reg2 reg3
2056 pprInstr (FSUB sz reg1 reg2 reg3) = pprBinaryF SLIT("fsub") sz reg1 reg2 reg3
2057 pprInstr (FMUL sz reg1 reg2 reg3) = pprBinaryF SLIT("fmul") sz reg1 reg2 reg3
2058 pprInstr (FDIV sz reg1 reg2 reg3) = pprBinaryF SLIT("fdiv") sz reg1 reg2 reg3
2059 pprInstr (FNEG reg1 reg2) = pprUnary SLIT("fneg") reg1 reg2
2060
2061 pprInstr (FCMP reg1 reg2) = hcat [
2062         char '\t',
2063         ptext SLIT("fcmpu\tcr0, "),
2064             -- Note: we're using fcmpu, not fcmpo
2065             -- The difference is with fcmpo, compare with NaN is an invalid operation.
2066             -- We don't handle invalid fp ops, so we don't care
2067         pprReg reg1,
2068         ptext SLIT(", "),
2069         pprReg reg2
2070     ]
2071
2072 pprInstr (FCTIWZ reg1 reg2) = pprUnary SLIT("fctiwz") reg1 reg2
2073 pprInstr (FRSP reg1 reg2) = pprUnary SLIT("frsp") reg1 reg2
2074
2075 pprInstr (CRNOR dst src1 src2) = hcat [
2076         ptext SLIT("\tcrnor\t"),
2077         int dst,
2078         ptext SLIT(", "),
2079         int src1,
2080         ptext SLIT(", "),
2081         int src2
2082     ]
2083
2084 pprInstr (MFCR reg) = hcat [
2085         char '\t',
2086         ptext SLIT("mfcr"),
2087         char '\t',
2088         pprReg reg
2089     ]
2090
2091 pprInstr (MFLR reg) = hcat [
2092         char '\t',
2093         ptext SLIT("mflr"),
2094         char '\t',
2095         pprReg reg
2096     ]
2097
2098 pprInstr (FETCHPC reg) = vcat [
2099         ptext SLIT("\tbcl\t20,31,1f"),
2100         hcat [ ptext SLIT("1:\tmflr\t"), pprReg reg ]
2101     ]
2102
2103 pprInstr _ = panic "pprInstr (ppc)"
2104
2105 pprLogic op reg1 reg2 ri = hcat [
2106         char '\t',
2107         ptext op,
2108         case ri of
2109             RIReg _ -> empty
2110             RIImm _ -> char 'i',
2111         char '\t',
2112         pprReg reg1,
2113         ptext SLIT(", "),
2114         pprReg reg2,
2115         ptext SLIT(", "),
2116         pprRI ri
2117     ]
2118     
2119 pprUnary op reg1 reg2 = hcat [
2120         char '\t',
2121         ptext op,
2122         char '\t',
2123         pprReg reg1,
2124         ptext SLIT(", "),
2125         pprReg reg2
2126     ]
2127     
2128 pprBinaryF op sz reg1 reg2 reg3 = hcat [
2129         char '\t',
2130         ptext op,
2131         pprFSize sz,
2132         char '\t',
2133         pprReg reg1,
2134         ptext SLIT(", "),
2135         pprReg reg2,
2136         ptext SLIT(", "),
2137         pprReg reg3
2138     ]
2139     
2140 pprRI :: RI -> Doc
2141 pprRI (RIReg r) = pprReg r
2142 pprRI (RIImm r) = pprImm r
2143
2144 pprFSize F64 = empty
2145 pprFSize F32 = char 's'
2146
2147     -- limit immediate argument for shift instruction to range 0..32
2148     -- (yes, the maximum is really 32, not 31)
2149 limitShiftRI :: RI -> RI
2150 limitShiftRI (RIImm (ImmInt i)) | i > 32 || i < 0 = RIImm (ImmInt 32)
2151 limitShiftRI x = x
2152
2153 #endif /* powerpc_TARGET_ARCH */
2154
2155
2156 -- -----------------------------------------------------------------------------
2157 -- Converting floating-point literals to integrals for printing
2158
2159 #if __GLASGOW_HASKELL__ >= 504
2160 newFloatArray :: (Int,Int) -> ST s (STUArray s Int Float)
2161 newFloatArray = newArray_
2162
2163 newDoubleArray :: (Int,Int) -> ST s (STUArray s Int Double)
2164 newDoubleArray = newArray_
2165
2166 castFloatToCharArray :: STUArray s Int Float -> ST s (STUArray s Int Word8)
2167 castFloatToCharArray = castSTUArray
2168
2169 castDoubleToCharArray :: STUArray s Int Double -> ST s (STUArray s Int Word8)
2170 castDoubleToCharArray = castSTUArray
2171
2172 writeFloatArray :: STUArray s Int Float -> Int -> Float -> ST s ()
2173 writeFloatArray = writeArray
2174
2175 writeDoubleArray :: STUArray s Int Double -> Int -> Double -> ST s ()
2176 writeDoubleArray = writeArray
2177
2178 readCharArray :: STUArray s Int Word8 -> Int -> ST s Char
2179 readCharArray arr i = do 
2180   w <- readArray arr i
2181   return $! (chr (fromIntegral w))
2182
2183 #else
2184
2185 castFloatToCharArray :: MutableByteArray s t -> ST s (MutableByteArray s t)
2186 castFloatToCharArray = return
2187
2188 castDoubleToCharArray :: MutableByteArray s t -> ST s (MutableByteArray s t)
2189
2190
2191 castDoubleToCharArray = return
2192
2193 #endif
2194
2195 -- floatToBytes and doubleToBytes convert to the host's byte
2196 -- order.  Providing that we're not cross-compiling for a 
2197 -- target with the opposite endianness, this should work ok
2198 -- on all targets.
2199
2200 -- ToDo: this stuff is very similar to the shenanigans in PprAbs,
2201 -- could they be merged?
2202
2203 floatToBytes :: Float -> [Int]
2204 floatToBytes f
2205    = runST (do
2206         arr <- newFloatArray ((0::Int),3)
2207         writeFloatArray arr 0 f
2208         arr <- castFloatToCharArray arr
2209         i0 <- readCharArray arr 0
2210         i1 <- readCharArray arr 1
2211         i2 <- readCharArray arr 2
2212         i3 <- readCharArray arr 3
2213         return (map ord [i0,i1,i2,i3])
2214      )
2215
2216 doubleToBytes :: Double -> [Int]
2217 doubleToBytes d
2218    = runST (do
2219         arr <- newDoubleArray ((0::Int),7)
2220         writeDoubleArray arr 0 d
2221         arr <- castDoubleToCharArray arr
2222         i0 <- readCharArray arr 0
2223         i1 <- readCharArray arr 1
2224         i2 <- readCharArray arr 2
2225         i3 <- readCharArray arr 3
2226         i4 <- readCharArray arr 4
2227         i5 <- readCharArray arr 5
2228         i6 <- readCharArray arr 6
2229         i7 <- readCharArray arr 7
2230         return (map ord [i0,i1,i2,i3,i4,i5,i6,i7])
2231      )