[project @ 1996-04-05 08:26:04 by partain]
[ghc-hetmet.git] / ghc / compiler / nativeGen / PprMach.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1996
3 %
4 \section[PprMach]{Pretty-printing assembly language}
5
6 We start with the @pprXXX@s with some cross-platform commonality
7 (e.g., @pprReg@); we conclude with the no-commonality monster,
8 @pprInstr@.
9
10 \begin{code}
11 #include "HsVersions.h"
12 #include "nativeGen/NCG.h"
13
14 module PprMach ( pprInstr ) where
15
16 import Ubiq{-uitious-}
17
18 import MachRegs         -- may differ per-platform
19 import MachMisc
20
21 import CLabel           ( pprCLabel_asm, externallyVisibleCLabel )
22 import CStrings         ( charToC )
23 import Maybes           ( maybeToBool )
24 import OrdList          ( OrdList )
25 import Stix             ( CodeSegment(..), StixTree )
26 import Unpretty         -- all of it
27 \end{code}
28
29 %************************************************************************
30 %*                                                                      *
31 \subsection{@pprReg@: print a @Reg@}
32 %*                                                                      *
33 %************************************************************************
34
35 For x86, the way we print a register name depends
36 on which bit of it we care about.  Yurgh.
37 \begin{code}
38 pprReg :: IF_ARCH_i386(Size ->,) Reg -> Unpretty
39
40 pprReg IF_ARCH_i386(s,) r
41   = case r of
42       FixedReg  i -> ppr_reg_no IF_ARCH_i386(s,) i
43       MappedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
44       other       -> uppStr (show other)   -- should only happen when debugging
45   where
46 #if alpha_TARGET_ARCH
47     ppr_reg_no :: FAST_REG_NO -> Unpretty
48     ppr_reg_no i = uppPStr
49       (case i of {
50         ILIT( 0) -> SLIT("$0");   ILIT( 1) -> SLIT("$1");
51         ILIT( 2) -> SLIT("$2");   ILIT( 3) -> SLIT("$3");
52         ILIT( 4) -> SLIT("$4");   ILIT( 5) -> SLIT("$5");
53         ILIT( 6) -> SLIT("$6");   ILIT( 7) -> SLIT("$7");
54         ILIT( 8) -> SLIT("$8");   ILIT( 9) -> SLIT("$9");
55         ILIT(10) -> SLIT("$10");  ILIT(11) -> SLIT("$11");
56         ILIT(12) -> SLIT("$12");  ILIT(13) -> SLIT("$13");
57         ILIT(14) -> SLIT("$14");  ILIT(15) -> SLIT("$15");
58         ILIT(16) -> SLIT("$16");  ILIT(17) -> SLIT("$17");
59         ILIT(18) -> SLIT("$18");  ILIT(19) -> SLIT("$19");
60         ILIT(20) -> SLIT("$20");  ILIT(21) -> SLIT("$21");
61         ILIT(22) -> SLIT("$22");  ILIT(23) -> SLIT("$23");
62         ILIT(24) -> SLIT("$24");  ILIT(25) -> SLIT("$25");
63         ILIT(26) -> SLIT("$26");  ILIT(27) -> SLIT("$27");
64         ILIT(28) -> SLIT("$28");  ILIT(29) -> SLIT("$29");
65         ILIT(30) -> SLIT("$30");  ILIT(31) -> SLIT("$31");
66         ILIT(32) -> SLIT("$f0");  ILIT(33) -> SLIT("$f1");
67         ILIT(34) -> SLIT("$f2");  ILIT(35) -> SLIT("$f3");
68         ILIT(36) -> SLIT("$f4");  ILIT(37) -> SLIT("$f5");
69         ILIT(38) -> SLIT("$f6");  ILIT(39) -> SLIT("$f7");
70         ILIT(40) -> SLIT("$f8");  ILIT(41) -> SLIT("$f9");
71         ILIT(42) -> SLIT("$f10"); ILIT(43) -> SLIT("$f11");
72         ILIT(44) -> SLIT("$f12"); ILIT(45) -> SLIT("$f13");
73         ILIT(46) -> SLIT("$f14"); ILIT(47) -> SLIT("$f15");
74         ILIT(48) -> SLIT("$f16"); ILIT(49) -> SLIT("$f17");
75         ILIT(50) -> SLIT("$f18"); ILIT(51) -> SLIT("$f19");
76         ILIT(52) -> SLIT("$f20"); ILIT(53) -> SLIT("$f21");
77         ILIT(54) -> SLIT("$f22"); ILIT(55) -> SLIT("$f23");
78         ILIT(56) -> SLIT("$f24"); ILIT(57) -> SLIT("$f25");
79         ILIT(58) -> SLIT("$f26"); ILIT(59) -> SLIT("$f27");
80         ILIT(60) -> SLIT("$f28"); ILIT(61) -> SLIT("$f29");
81         ILIT(62) -> SLIT("$f30"); ILIT(63) -> SLIT("$f31");
82         _ -> SLIT("very naughty alpha register")
83       })
84 #endif
85 #if i386_TARGET_ARCH
86     ppr_reg_no :: Size -> FAST_REG_NO -> Unpretty
87     ppr_reg_no B i = uppPStr
88       (case i of {
89         ILIT( 0) -> SLIT("%al");  ILIT( 1) -> SLIT("%bl");
90         ILIT( 2) -> SLIT("%cl");  ILIT( 3) -> SLIT("%dl");
91         _ -> SLIT("very naughty I386 byte register")
92       })
93
94     {- UNUSED:
95     ppr_reg_no HB i = uppPStr
96       (case i of {
97         ILIT( 0) -> SLIT("%ah");  ILIT( 1) -> SLIT("%bh");
98         ILIT( 2) -> SLIT("%ch");  ILIT( 3) -> SLIT("%dh");
99         _ -> SLIT("very naughty I386 high byte register")
100       })
101     -}
102
103 {- UNUSED:
104     ppr_reg_no S i = uppPStr
105       (case i of {
106         ILIT( 0) -> SLIT("%ax");  ILIT( 1) -> SLIT("%bx");
107         ILIT( 2) -> SLIT("%cx");  ILIT( 3) -> SLIT("%dx");
108         ILIT( 4) -> SLIT("%si");  ILIT( 5) -> SLIT("%di");
109         ILIT( 6) -> SLIT("%bp");  ILIT( 7) -> SLIT("%sp");
110         _ -> SLIT("very naughty I386 word register")
111       })
112 -}
113
114     ppr_reg_no L i = uppPStr
115       (case i of {
116         ILIT( 0) -> SLIT("%eax");  ILIT( 1) -> SLIT("%ebx");
117         ILIT( 2) -> SLIT("%ecx");  ILIT( 3) -> SLIT("%edx");
118         ILIT( 4) -> SLIT("%esi");  ILIT( 5) -> SLIT("%edi");
119         ILIT( 6) -> SLIT("%ebp");  ILIT( 7) -> SLIT("%esp");
120         _ -> SLIT("very naughty I386 double word register")
121       })
122
123     ppr_reg_no F i = uppPStr
124       (case i of {
125         --ToDo: rm these (???)
126         ILIT( 8) -> SLIT("%st(0)");  ILIT( 9) -> SLIT("%st(1)");
127         ILIT(10) -> SLIT("%st(2)");  ILIT(11) -> SLIT("%st(3)");
128         ILIT(12) -> SLIT("%st(4)");  ILIT(13) -> SLIT("%st(5)");
129         ILIT(14) -> SLIT("%st(6)");  ILIT(15) -> SLIT("%st(7)");
130         _ -> SLIT("very naughty I386 float register")
131       })
132
133     ppr_reg_no DF i = uppPStr
134       (case i of {
135         --ToDo: rm these (???)
136         ILIT( 8) -> SLIT("%st(0)");  ILIT( 9) -> SLIT("%st(1)");
137         ILIT(10) -> SLIT("%st(2)");  ILIT(11) -> SLIT("%st(3)");
138         ILIT(12) -> SLIT("%st(4)");  ILIT(13) -> SLIT("%st(5)");
139         ILIT(14) -> SLIT("%st(6)");  ILIT(15) -> SLIT("%st(7)");
140         _ -> SLIT("very naughty I386 float register")
141       })
142 #endif
143 #if sparc_TARGET_ARCH
144     ppr_reg_no :: FAST_REG_NO -> Unpretty
145     ppr_reg_no i = uppPStr
146       (case i of {
147         ILIT( 0) -> SLIT("%g0");  ILIT( 1) -> SLIT("%g1");
148         ILIT( 2) -> SLIT("%g2");  ILIT( 3) -> SLIT("%g3");
149         ILIT( 4) -> SLIT("%g4");  ILIT( 5) -> SLIT("%g5");
150         ILIT( 6) -> SLIT("%g6");  ILIT( 7) -> SLIT("%g7");
151         ILIT( 8) -> SLIT("%o0");  ILIT( 9) -> SLIT("%o1");
152         ILIT(10) -> SLIT("%o2");  ILIT(11) -> SLIT("%o3");
153         ILIT(12) -> SLIT("%o4");  ILIT(13) -> SLIT("%o5");
154         ILIT(14) -> SLIT("%o6");  ILIT(15) -> SLIT("%o7");
155         ILIT(16) -> SLIT("%l0");  ILIT(17) -> SLIT("%l1");
156         ILIT(18) -> SLIT("%l2");  ILIT(19) -> SLIT("%l3");
157         ILIT(20) -> SLIT("%l4");  ILIT(21) -> SLIT("%l5");
158         ILIT(22) -> SLIT("%l6");  ILIT(23) -> SLIT("%l7");
159         ILIT(24) -> SLIT("%i0");  ILIT(25) -> SLIT("%i1");
160         ILIT(26) -> SLIT("%i2");  ILIT(27) -> SLIT("%i3");
161         ILIT(28) -> SLIT("%i4");  ILIT(29) -> SLIT("%i5");
162         ILIT(30) -> SLIT("%i6");  ILIT(31) -> SLIT("%i7");
163         ILIT(32) -> SLIT("%f0");  ILIT(33) -> SLIT("%f1");
164         ILIT(34) -> SLIT("%f2");  ILIT(35) -> SLIT("%f3");
165         ILIT(36) -> SLIT("%f4");  ILIT(37) -> SLIT("%f5");
166         ILIT(38) -> SLIT("%f6");  ILIT(39) -> SLIT("%f7");
167         ILIT(40) -> SLIT("%f8");  ILIT(41) -> SLIT("%f9");
168         ILIT(42) -> SLIT("%f10"); ILIT(43) -> SLIT("%f11");
169         ILIT(44) -> SLIT("%f12"); ILIT(45) -> SLIT("%f13");
170         ILIT(46) -> SLIT("%f14"); ILIT(47) -> SLIT("%f15");
171         ILIT(48) -> SLIT("%f16"); ILIT(49) -> SLIT("%f17");
172         ILIT(50) -> SLIT("%f18"); ILIT(51) -> SLIT("%f19");
173         ILIT(52) -> SLIT("%f20"); ILIT(53) -> SLIT("%f21");
174         ILIT(54) -> SLIT("%f22"); ILIT(55) -> SLIT("%f23");
175         ILIT(56) -> SLIT("%f24"); ILIT(57) -> SLIT("%f25");
176         ILIT(58) -> SLIT("%f26"); ILIT(59) -> SLIT("%f27");
177         ILIT(60) -> SLIT("%f28"); ILIT(61) -> SLIT("%f29");
178         ILIT(62) -> SLIT("%f30"); ILIT(63) -> SLIT("%f31");
179         _ -> SLIT("very naughty sparc register")
180       })
181 #endif
182 \end{code}
183
184 %************************************************************************
185 %*                                                                      *
186 \subsection{@pprSize@: print a @Size@}
187 %*                                                                      *
188 %************************************************************************
189
190 \begin{code}
191 pprSize :: Size -> Unpretty
192
193 pprSize x = uppPStr (case x of
194 #if alpha_TARGET_ARCH
195          B  -> SLIT("b")
196          BU -> SLIT("bu")
197 --       W  -> SLIT("w") UNUSED
198 --       WU -> SLIT("wu") UNUSED
199 --       L  -> SLIT("l") UNUSED
200          Q  -> SLIT("q")
201 --       FF -> SLIT("f") UNUSED
202 --       DF -> SLIT("d") UNUSED
203 --       GF -> SLIT("g") UNUSED
204 --       SF -> SLIT("s") UNUSED
205          TF -> SLIT("t")
206 #endif
207 #if i386_TARGET_ARCH
208         B  -> SLIT("b")
209 --      HB -> SLIT("b") UNUSED
210 --      S  -> SLIT("w") UNUSED
211         L  -> SLIT("l")
212         F  -> SLIT("s")
213         DF -> SLIT("l")
214 #endif
215 #if sparc_TARGET_ARCH
216         B   -> SLIT("sb")
217 --      HW  -> SLIT("hw") UNUSED
218 --      BU  -> SLIT("ub") UNUSED
219 --      HWU -> SLIT("uhw") UNUSED
220         W   -> SLIT("")
221         F   -> SLIT("")
222 --      D   -> SLIT("d") UNUSED
223         DF  -> SLIT("d")
224 #endif
225     )
226 \end{code}
227
228 %************************************************************************
229 %*                                                                      *
230 \subsection{@pprCond@: print a @Cond@}
231 %*                                                                      *
232 %************************************************************************
233
234 \begin{code}
235 pprCond :: Cond -> Unpretty
236
237 pprCond c = uppPStr (case c of {
238 #if alpha_TARGET_ARCH
239         EQ  -> SLIT("eq");
240         LT  -> SLIT("lt");
241         LE  -> SLIT("le");
242         ULT -> SLIT("ult");
243         ULE -> SLIT("ule");
244         NE  -> SLIT("ne");
245         GT  -> SLIT("gt");
246         GE  -> SLIT("ge")
247 #endif
248 #if i386_TARGET_ARCH
249         GEU     -> SLIT("ae");  LU    -> SLIT("b");
250         EQ      -> SLIT("e");   GT    -> SLIT("g");
251         GE      -> SLIT("ge");  GU    -> SLIT("a");
252         LT      -> SLIT("l");   LE    -> SLIT("le");
253         LEU     -> SLIT("be");  NE    -> SLIT("ne");
254         NEG     -> SLIT("s");   POS   -> SLIT("ns");
255         ALWAYS  -> SLIT("mp")   -- hack
256 #endif
257 #if sparc_TARGET_ARCH
258         ALWAYS  -> SLIT("");    NEVER -> SLIT("n");
259         GEU     -> SLIT("geu"); LU    -> SLIT("lu");
260         EQ      -> SLIT("e");   GT    -> SLIT("g");
261         GE      -> SLIT("ge");  GU    -> SLIT("gu");
262         LT      -> SLIT("l");   LE    -> SLIT("le");
263         LEU     -> SLIT("leu"); NE    -> SLIT("ne");
264         NEG     -> SLIT("neg"); POS   -> SLIT("pos");
265         VC      -> SLIT("vc");  VS    -> SLIT("vs")
266 #endif
267     })
268 \end{code}
269
270 %************************************************************************
271 %*                                                                      *
272 \subsection{@pprImm@: print an @Imm@}
273 %*                                                                      *
274 %************************************************************************
275
276 \begin{code}
277 pprImm :: Imm -> Unpretty
278
279 pprImm (ImmInt i)     = uppInt i
280 pprImm (ImmInteger i) = uppInteger i
281 pprImm (ImmCLbl l)    = pprCLabel_asm l
282 pprImm (ImmLit s)     = s
283
284 pprImm (ImmLab s) | underscorePrefix = uppBeside (uppChar '_') s
285                   | otherwise        = s
286
287 #if sparc_TARGET_ARCH
288 pprImm (LO i)
289   = uppBesides [ pp_lo, pprImm i, uppRparen ]
290   where
291     pp_lo = uppPStr (_packCString (A# "%lo("#))
292
293 pprImm (HI i)
294   = uppBesides [ pp_hi, pprImm i, uppRparen ]
295   where
296     pp_hi = uppPStr (_packCString (A# "%hi("#))
297 #endif
298 \end{code}
299
300 %************************************************************************
301 %*                                                                      *
302 \subsection{@pprAddr@: print an @Addr@}
303 %*                                                                      *
304 %************************************************************************
305
306 \begin{code}
307 pprAddr :: Addr -> Unpretty
308
309 #if alpha_TARGET_ARCH
310 pprAddr (AddrReg r) = uppParens (pprReg r)
311 pprAddr (AddrImm i) = pprImm i
312 pprAddr (AddrRegImm r1 i)
313   = uppBeside (pprImm i) (uppParens (pprReg r1))
314 #endif
315
316 -------------------
317
318 #if i386_TARGET_ARCH
319 pprAddr (ImmAddr imm off)
320   = let
321         pp_imm = pprImm imm
322     in
323     if (off == 0) then
324         pp_imm
325     else if (off < 0) then
326         uppBeside pp_imm (uppInt off)
327     else
328         uppBesides [pp_imm, uppChar '+', uppInt off]
329
330 pprAddr (Addr base index displacement)
331   = let
332         pp_disp  = ppr_disp displacement
333         pp_off p = uppBeside pp_disp (uppParens p)
334         pp_reg r = pprReg L r
335     in
336     case (base,index) of
337       (Nothing, Nothing)    -> pp_disp
338       (Just b,  Nothing)    -> pp_off (pp_reg b)
339       (Nothing, Just (r,i)) -> pp_off (uppBesides [pp_reg r, uppComma, uppInt i])
340       (Just b,  Just (r,i)) -> pp_off (uppBesides [pp_reg b, uppComma, pp_reg r, uppComma, uppInt i])
341   where
342     ppr_disp (ImmInt 0) = uppNil
343     ppr_disp imm        = pprImm imm
344 #endif
345
346 -------------------
347
348 #if sparc_TARGET_ARCH
349 pprAddr (AddrRegReg r1 (FixedReg ILIT(0))) = pprReg r1
350
351 pprAddr (AddrRegReg r1 r2)
352   = uppBesides [ pprReg r1, uppChar '+', pprReg r2 ]
353
354 pprAddr (AddrRegImm r1 (ImmInt i))
355   | i == 0 = pprReg r1
356   | not (fits13Bits i) = largeOffsetError i
357   | otherwise = uppBesides [ pprReg r1, pp_sign, uppInt i ]
358   where
359     pp_sign = if i > 0 then uppChar '+' else uppNil
360
361 pprAddr (AddrRegImm r1 (ImmInteger i))
362   | i == 0 = pprReg r1
363   | not (fits13Bits i) = largeOffsetError i
364   | otherwise  = uppBesides [ pprReg r1, pp_sign, uppInteger i ]
365   where
366     pp_sign = if i > 0 then uppChar '+' else uppNil
367
368 pprAddr (AddrRegImm r1 imm)
369   = uppBesides [ pprReg r1, uppChar '+', pprImm imm ]
370 #endif
371 \end{code}
372
373 %************************************************************************
374 %*                                                                      *
375 \subsection{@pprInstr@: print an @Instr@}
376 %*                                                                      *
377 %************************************************************************
378
379 \begin{code}
380 pprInstr :: Instr -> Unpretty
381
382 pprInstr (COMMENT s) = uppBeside (uppPStr SLIT("\t# ")) (uppPStr s)
383
384 pprInstr (SEGMENT TextSegment)
385     = uppPStr
386          IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
387         ,IF_ARCH_sparc(SLIT("\t.text\n\t.align 4") {-word boundary-}
388         ,IF_ARCH_i386(SLIT(".text\n\t.align 2,0x90") {-needs per-OS variation!-}
389         ,)))
390
391 pprInstr (SEGMENT DataSegment)
392     = uppPStr
393          IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
394         ,IF_ARCH_sparc(SLIT("\t.data\n\t.align 8") {-<8 will break double constants -}
395         ,IF_ARCH_i386(SLIT(".data\n\t.align 2")
396         ,)))
397
398 pprInstr (LABEL clab)
399   = let
400         pp_lab = pprCLabel_asm clab
401     in
402     uppBesides [
403         if not (externallyVisibleCLabel clab) then
404             uppNil
405         else
406             uppBesides [uppPStr
407                          IF_ARCH_alpha(SLIT("\t.globl\t")
408                         ,IF_ARCH_i386(SLIT(".globl ")
409                         ,IF_ARCH_sparc(SLIT("\t.global\t")
410                         ,)))
411                         , pp_lab, uppChar '\n'],
412         pp_lab,
413         uppChar ':'
414     ]
415
416 pprInstr (ASCII False{-no backslash conversion-} str)
417   = uppBesides [ uppStr "\t.asciz \"", uppStr str, uppChar '"' ]
418
419 pprInstr (ASCII True str)
420   = uppBeside (uppStr "\t.ascii \"") (asciify str 60)
421   where
422     asciify :: String -> Int -> Unpretty
423
424     asciify [] _ = uppStr ("\\0\"")
425     asciify s     n | n <= 0 = uppBeside (uppStr "\"\n\t.ascii \"") (asciify s 60)
426     asciify ('\\':cs)      n = uppBeside (uppStr "\\\\") (asciify cs (n-1))
427     asciify ('\"':cs)      n = uppBeside (uppStr "\\\"") (asciify cs (n-1))
428     asciify (c:cs) n | isPrint c = uppBeside (uppChar c) (asciify cs (n-1))
429     asciify [c]            _ = uppBeside (uppStr (charToC c)) (uppStr ("\\0\""))
430     asciify (c:(cs@(d:_))) n
431       | isDigit d = uppBeside (uppStr (charToC c)) (asciify cs 0)
432       | otherwise = uppBeside (uppStr (charToC c)) (asciify cs (n-1))
433
434 pprInstr (DATA s xs)
435   = uppInterleave (uppChar '\n')
436                   [uppBeside (uppPStr pp_size) (pprImm x) | x <- xs]
437   where
438     pp_size = case s of
439 #if alpha_TARGET_ARCH
440             B  -> SLIT("\t.byte\t")
441             BU -> SLIT("\t.byte\t")
442 --UNUSED:   W  -> SLIT("\t.word\t")
443 --UNUSED:   WU -> SLIT("\t.word\t")
444 --UNUSED:   L  -> SLIT("\t.long\t")
445             Q  -> SLIT("\t.quad\t")
446 --UNUSED:   FF -> SLIT("\t.f_floating\t")
447 --UNUSED:   DF -> SLIT("\t.d_floating\t")
448 --UNUSED:   GF -> SLIT("\t.g_floating\t")
449 --UNUSED:   SF -> SLIT("\t.s_floating\t")
450             TF -> SLIT("\t.t_floating\t")
451 #endif
452 #if i386_TARGET_ARCH
453             B  -> SLIT("\t.byte\t")
454 --UNUSED:   HB -> SLIT("\t.byte\t")
455 --UNUSED:   S  -> SLIT("\t.word\t")
456             L  -> SLIT("\t.long\t")
457             F  -> SLIT("\t.long\t")
458             DF -> SLIT("\t.double\t")
459 #endif
460 #if sparc_TARGET_ARCH
461             B  -> SLIT("\t.byte\t")
462             BU -> SLIT("\t.byte\t")
463             W  -> SLIT("\t.word\t")
464             DF -> SLIT("\t.double\t")
465 #endif
466
467 -- fall through to rest of (machine-specific) pprInstr...
468 \end{code}
469
470 %************************************************************************
471 %*                                                                      *
472 \subsubsection{@pprInstr@ for an Alpha}
473 %*                                                                      *
474 %************************************************************************
475
476 \begin{code}
477 #if alpha_TARGET_ARCH
478
479 pprInstr (LD size reg addr)
480   = uppBesides [
481         uppPStr SLIT("\tld"),
482         pprSize size,
483         uppChar '\t',
484         pprReg reg,
485         uppComma,
486         pprAddr addr
487     ]
488
489 pprInstr (LDA reg addr)
490   = uppBesides [
491         uppPStr SLIT("\tlda\t"),
492         pprReg reg,
493         uppComma,
494         pprAddr addr
495     ]
496
497 pprInstr (LDAH reg addr)
498   = uppBesides [
499         uppPStr SLIT("\tldah\t"),
500         pprReg reg,
501         uppComma,
502         pprAddr addr
503     ]
504
505 pprInstr (LDGP reg addr)
506   = uppBesides [
507         uppPStr SLIT("\tldgp\t"),
508         pprReg reg,
509         uppComma,
510         pprAddr addr
511     ]
512
513 pprInstr (LDI size reg imm)
514   = uppBesides [
515         uppPStr SLIT("\tldi"),
516         pprSize size,
517         uppChar '\t',
518         pprReg reg,
519         uppComma,
520         pprImm imm
521     ]
522
523 pprInstr (ST size reg addr)
524   = uppBesides [
525         uppPStr SLIT("\tst"),
526         pprSize size,
527         uppChar '\t',
528         pprReg reg,
529         uppComma,
530         pprAddr addr
531     ]
532
533 pprInstr (CLR reg)
534   = uppBesides [
535         uppPStr SLIT("\tclr\t"),
536         pprReg reg
537     ]
538
539 pprInstr (ABS size ri reg)
540   = uppBesides [
541         uppPStr SLIT("\tabs"),
542         pprSize size,
543         uppChar '\t',
544         pprRI ri,
545         uppComma,
546         pprReg reg
547     ]
548
549 pprInstr (NEG size ov ri reg)
550   = uppBesides [
551         uppPStr SLIT("\tneg"),
552         pprSize size,
553         if ov then uppPStr SLIT("v\t") else uppChar '\t',
554         pprRI ri,
555         uppComma,
556         pprReg reg
557     ]
558
559 pprInstr (ADD size ov reg1 ri reg2)
560   = uppBesides [
561         uppPStr SLIT("\tadd"),
562         pprSize size,
563         if ov then uppPStr SLIT("v\t") else uppChar '\t',
564         pprReg reg1,
565         uppComma,
566         pprRI ri,
567         uppComma,
568         pprReg reg2
569     ]
570
571 pprInstr (SADD size scale reg1 ri reg2)
572   = uppBesides [
573         uppPStr (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
574         uppPStr SLIT("add"),
575         pprSize size,
576         uppChar '\t',
577         pprReg reg1,
578         uppComma,
579         pprRI ri,
580         uppComma,
581         pprReg reg2
582     ]
583
584 pprInstr (SUB size ov reg1 ri reg2)
585   = uppBesides [
586         uppPStr SLIT("\tsub"),
587         pprSize size,
588         if ov then uppPStr SLIT("v\t") else uppChar '\t',
589         pprReg reg1,
590         uppComma,
591         pprRI ri,
592         uppComma,
593         pprReg reg2
594     ]
595
596 pprInstr (SSUB size scale reg1 ri reg2)
597   = uppBesides [
598         uppPStr (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
599         uppPStr SLIT("sub"),
600         pprSize size,
601         uppChar '\t',
602         pprReg reg1,
603         uppComma,
604         pprRI ri,
605         uppComma,
606         pprReg reg2
607     ]
608
609 pprInstr (MUL size ov reg1 ri reg2)
610   = uppBesides [
611         uppPStr SLIT("\tmul"),
612         pprSize size,
613         if ov then uppPStr SLIT("v\t") else uppChar '\t',
614         pprReg reg1,
615         uppComma,
616         pprRI ri,
617         uppComma,
618         pprReg reg2
619     ]
620
621 pprInstr (DIV size uns reg1 ri reg2)
622   = uppBesides [
623         uppPStr SLIT("\tdiv"),
624         pprSize size,
625         if uns then uppPStr SLIT("u\t") else uppChar '\t',
626         pprReg reg1,
627         uppComma,
628         pprRI ri,
629         uppComma,
630         pprReg reg2
631     ]
632
633 pprInstr (REM size uns reg1 ri reg2)
634   = uppBesides [
635         uppPStr SLIT("\trem"),
636         pprSize size,
637         if uns then uppPStr SLIT("u\t") else uppChar '\t',
638         pprReg reg1,
639         uppComma,
640         pprRI ri,
641         uppComma,
642         pprReg reg2
643     ]
644
645 pprInstr (NOT ri reg)
646   = uppBesides [
647         uppPStr SLIT("\tnot"),
648         uppChar '\t',
649         pprRI ri,
650         uppComma,
651         pprReg reg
652     ]
653
654 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
655 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
656 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
657 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
658 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
659 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
660
661 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
662 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
663 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
664
665 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
666 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
667
668 pprInstr (NOP) = uppPStr SLIT("\tnop")
669
670 pprInstr (CMP cond reg1 ri reg2)
671   = uppBesides [
672         uppPStr SLIT("\tcmp"),
673         pprCond cond,
674         uppChar '\t',
675         pprReg reg1,
676         uppComma,
677         pprRI ri,
678         uppComma,
679         pprReg reg2
680     ]
681
682 pprInstr (FCLR reg)
683   = uppBesides [
684         uppPStr SLIT("\tfclr\t"),
685         pprReg reg
686     ]
687
688 pprInstr (FABS reg1 reg2)
689   = uppBesides [
690         uppPStr SLIT("\tfabs\t"),
691         pprReg reg1,
692         uppComma,
693         pprReg reg2
694     ]
695
696 pprInstr (FNEG size reg1 reg2)
697   = uppBesides [
698         uppPStr SLIT("\tneg"),
699         pprSize size,
700         uppChar '\t',
701         pprReg reg1,
702         uppComma,
703         pprReg reg2
704     ]
705
706 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
707 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
708 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
709 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
710
711 pprInstr (CVTxy size1 size2 reg1 reg2)
712   = uppBesides [
713         uppPStr SLIT("\tcvt"),
714         pprSize size1,
715         case size2 of {Q -> uppPStr SLIT("qc"); _ -> pprSize size2},
716         uppChar '\t',
717         pprReg reg1,
718         uppComma,
719         pprReg reg2
720     ]
721
722 pprInstr (FCMP size cond reg1 reg2 reg3)
723   = uppBesides [
724         uppPStr SLIT("\tcmp"),
725         pprSize size,
726         pprCond cond,
727         uppChar '\t',
728         pprReg reg1,
729         uppComma,
730         pprReg reg2,
731         uppComma,
732         pprReg reg3
733     ]
734
735 pprInstr (FMOV reg1 reg2)
736   = uppBesides [
737         uppPStr SLIT("\tfmov\t"),
738         pprReg reg1,
739         uppComma,
740         pprReg reg2
741     ]
742
743 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
744
745 pprInstr (BI NEVER reg lab) = uppNil
746
747 pprInstr (BI cond reg lab)
748   = uppBesides [
749         uppPStr SLIT("\tb"),
750         pprCond cond,
751         uppChar '\t',
752         pprReg reg,
753         uppComma,
754         pprImm lab
755     ]
756
757 pprInstr (BF cond reg lab)
758   = uppBesides [
759         uppPStr SLIT("\tfb"),
760         pprCond cond,
761         uppChar '\t',
762         pprReg reg,
763         uppComma,
764         pprImm lab
765     ]
766
767 pprInstr (BR lab)
768   = uppBeside (uppPStr SLIT("\tbr\t")) (pprImm lab)
769
770 pprInstr (JMP reg addr hint)
771   = uppBesides [
772         uppPStr SLIT("\tjmp\t"),
773         pprReg reg,
774         uppComma,
775         pprAddr addr,
776         uppComma,
777         uppInt hint
778     ]
779
780 pprInstr (BSR imm n)
781   = uppBeside (uppPStr SLIT("\tbsr\t")) (pprImm imm)
782
783 pprInstr (JSR reg addr n)
784   = uppBesides [
785         uppPStr SLIT("\tjsr\t"),
786         pprReg reg,
787         uppComma,
788         pprAddr addr
789     ]
790
791 pprInstr (FUNBEGIN clab)
792   = uppBesides [
793         if (externallyVisibleCLabel clab) then
794             uppBesides [uppPStr SLIT("\t.globl\t"), pp_lab, uppChar '\n']
795         else
796             uppNil,
797         uppPStr SLIT("\t.ent "),
798         pp_lab,
799         uppChar '\n',
800         pp_lab,
801         pp_ldgp,
802         pp_lab,
803         pp_frame
804     ]
805     where
806         pp_lab = pprCLabel_asm clab
807         pp_ldgp  = uppPStr (_packCString (A# ":\n\tldgp $29,0($27)\n"#))
808         pp_frame = uppPStr (_packCString (A# "..ng:\n\t.frame $30,4240,$26,0\n\t.prologue 1"#))
809
810 pprInstr (FUNEND clab)
811   = uppBeside (uppPStr SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
812 \end{code}
813
814 Continue with Alpha-only printing bits and bobs:
815 \begin{code}
816 pprRI :: RI -> Unpretty
817
818 pprRI (RIReg r) = pprReg r
819 pprRI (RIImm r) = pprImm r
820
821 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> Unpretty
822
823 pprRegRIReg name reg1 ri reg2
824   = uppBesides [
825         uppChar '\t',
826         uppPStr name,
827         uppChar '\t',
828         pprReg reg1,
829         uppComma,
830         pprRI ri,
831         uppComma,
832         pprReg reg2
833     ]
834
835 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Unpretty
836
837 pprSizeRegRegReg name size reg1 reg2 reg3
838   = uppBesides [
839         uppChar '\t',
840         uppPStr name,
841         pprSize size,
842         uppChar '\t',
843         pprReg reg1,
844         uppComma,
845         pprReg reg2,
846         uppComma,
847         pprReg reg3
848     ]
849
850 #endif {-alpha_TARGET_ARCH-}
851 \end{code}
852
853 %************************************************************************
854 %*                                                                      *
855 \subsubsection{@pprInstr@ for an I386}
856 %*                                                                      *
857 %************************************************************************
858
859 \begin{code}
860 #if i386_TARGET_ARCH
861
862 pprInstr (MOV size (OpReg src) (OpReg dst)) -- hack
863   | src == dst
864   = uppPStr SLIT("")
865 pprInstr (MOV size src dst)
866   = pprSizeOpOp SLIT("mov") size src dst
867 pprInstr (MOVZX size src dst) = pprSizeOpOpCoerce SLIT("movzx") L size src dst
868 pprInstr (MOVSX size src dst) = pprSizeOpOpCoerce SLIT("movxs") L size src dst
869
870 -- here we do some patching, since the physical registers are only set late
871 -- in the code generation.
872 pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
873   | reg1 == reg3
874   = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
875 pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
876   | reg2 == reg3
877   = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
878 pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
879   | reg1 == reg3
880   = pprInstr (ADD size (OpImm displ) dst)
881 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
882
883 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
884   = pprSizeOp SLIT("dec") size dst
885 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
886   = pprSizeOp SLIT("inc") size dst
887 pprInstr (ADD size src dst)
888   = pprSizeOpOp SLIT("add") size src dst
889 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
890 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
891 pprInstr (IDIV size op) = pprSizeOp SLIT("idiv") size op
892
893 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
894 pprInstr (OR  size src dst) = pprSizeOpOp SLIT("or")  size src dst
895 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor")  size src dst
896 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
897 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
898 pprInstr (SHL size imm dst) = pprSizeOpOp SLIT("shl")  size imm dst
899 pprInstr (SAR size imm dst) = pprSizeOpOp SLIT("sar")  size imm dst
900 pprInstr (SHR size imm dst) = pprSizeOpOp SLIT("shr")  size imm dst
901
902 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp")  size src dst
903 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test")  size src dst
904 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
905 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
906
907 pprInstr (NOP) = uppPStr SLIT("\tnop")
908 pprInstr (CLTD) = uppPStr SLIT("\tcltd")
909
910 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
911
912 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
913
914 pprInstr (JMP (OpImm imm)) = uppBeside (uppPStr SLIT("\tjmp ")) (pprImm imm)
915 pprInstr (JMP op) = uppBeside (uppPStr SLIT("\tjmp *")) (pprOperand L op)
916
917 pprInstr (CALL imm)
918   = uppBesides [ uppPStr SLIT("\tcall "), pprImm imm ]
919
920 pprInstr SAHF = uppPStr SLIT("\tsahf")
921 pprInstr FABS = uppPStr SLIT("\tfabs")
922
923 pprInstr (FADD sz src@(OpAddr _))
924   = uppBesides [uppPStr SLIT("\tfadd"), pprSize sz, uppSP, pprOperand sz src]
925 pprInstr (FADD sz src)
926   = uppPStr SLIT("\tfadd")
927 pprInstr FADDP
928   = uppPStr SLIT("\tfaddp")
929 pprInstr (FMUL sz src)
930   = uppBesides [uppPStr SLIT("\tfmul"), pprSize sz, uppSP, pprOperand sz src]
931 pprInstr FMULP
932   = uppPStr SLIT("\tfmulp")
933 pprInstr (FIADD size op) = pprSizeAddr SLIT("fiadd") size op
934 pprInstr FCHS = uppPStr SLIT("\tfchs")
935 pprInstr (FCOM size op) = pprSizeOp SLIT("fcom") size op
936 pprInstr FCOS = uppPStr SLIT("\tfcos")
937 pprInstr (FIDIV size op) = pprSizeAddr SLIT("fidiv") size op
938 pprInstr (FDIV sz src)
939   = uppBesides [uppPStr SLIT("\tfdiv"), pprSize sz, uppSP, pprOperand sz src]
940 pprInstr FDIVP
941   = uppPStr SLIT("\tfdivp")
942 pprInstr (FDIVR sz src)
943   = uppBesides [uppPStr SLIT("\tfdivr"), pprSize sz, uppSP, pprOperand sz src]
944 pprInstr FDIVRP
945   = uppPStr SLIT("\tfdivpr")
946 pprInstr (FIDIVR size op) = pprSizeAddr SLIT("fidivr") size op
947 pprInstr (FICOM size op) = pprSizeAddr SLIT("ficom") size op
948 pprInstr (FILD sz op reg) = pprSizeAddrReg SLIT("fild") sz op reg
949 pprInstr (FIST size op) = pprSizeAddr SLIT("fist") size op
950 pprInstr (FLD sz (OpImm (ImmCLbl src)))
951   = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppSP,pprCLabel_asm src]
952 pprInstr (FLD sz src)
953   = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppSP,pprOperand sz src]
954 pprInstr FLD1 = uppPStr SLIT("\tfld1")
955 pprInstr FLDZ = uppPStr SLIT("\tfldz")
956 pprInstr (FIMUL size op) = pprSizeAddr SLIT("fimul") size op
957 pprInstr FRNDINT = uppPStr SLIT("\tfrndint")
958 pprInstr FSIN = uppPStr SLIT("\tfsin")
959 pprInstr FSQRT = uppPStr SLIT("\tfsqrt")
960 pprInstr (FST sz dst)
961   = uppBesides [uppPStr SLIT("\tfst"), pprSize sz, uppSP, pprOperand sz dst]
962 pprInstr (FSTP sz dst)
963   = uppBesides [uppPStr SLIT("\tfstp"), pprSize sz, uppSP, pprOperand sz dst]
964 pprInstr (FISUB size op) = pprSizeAddr SLIT("fisub") size op
965 pprInstr (FSUB sz src)
966   = uppBesides [uppPStr SLIT("\tfsub"), pprSize sz, uppSP, pprOperand sz src]
967 pprInstr FSUBP
968   = uppPStr SLIT("\tfsubp")
969 pprInstr (FSUBR size src)
970   = pprSizeOp SLIT("fsubr") size src
971 pprInstr FSUBRP
972   = uppPStr SLIT("\tfsubpr")
973 pprInstr (FISUBR size op)
974   = pprSizeAddr SLIT("fisubr") size op
975 pprInstr FTST = uppPStr SLIT("\tftst")
976 pprInstr (FCOMP sz op)
977   = uppBesides [uppPStr SLIT("\tfcomp"), pprSize sz, uppSP, pprOperand sz op]
978 pprInstr FUCOMPP = uppPStr SLIT("\tfucompp")
979 pprInstr FXCH = uppPStr SLIT("\tfxch")
980 pprInstr FNSTSW = uppPStr SLIT("\tfnstsw %ax")
981 pprInstr FNOP = uppPStr SLIT("")
982 \end{code}
983
984 Continue with I386-only printing bits and bobs:
985 \begin{code}
986 pprDollImm :: Imm -> Unpretty
987
988 pprDollImm i     = uppBesides [ uppPStr SLIT("$"), pprImm i]
989
990 pprOperand :: Size -> Operand -> Unpretty
991 pprOperand s (OpReg r) = pprReg s r
992 pprOperand s (OpImm i) = pprDollImm i
993 pprOperand s (OpAddr ea) = pprAddr ea
994
995 pprSizeOp :: FAST_STRING -> Size -> Operand -> Unpretty
996 pprSizeOp name size op1
997   = uppBesides [
998         uppChar '\t',
999         uppPStr name,
1000         pprSize size,
1001         uppSP,
1002         pprOperand size op1
1003     ]
1004
1005 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Unpretty
1006 pprSizeOpOp name size op1 op2
1007   = uppBesides [
1008         uppChar '\t',
1009         uppPStr name,
1010         pprSize size,
1011         uppSP,
1012         pprOperand size op1,
1013         uppComma,
1014         pprOperand size op2
1015     ]
1016
1017 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> Unpretty
1018 pprSizeOpReg name size op1 reg
1019   = uppBesides [
1020         uppChar '\t',
1021         uppPStr name,
1022         pprSize size,
1023         uppSP,
1024         pprOperand size op1,
1025         uppComma,
1026         pprReg size reg
1027     ]
1028
1029 pprSizeAddr :: FAST_STRING -> Size -> Addr -> Unpretty
1030 pprSizeAddr name size op
1031   = uppBesides [
1032         uppChar '\t',
1033         uppPStr name,
1034         pprSize size,
1035         uppSP,
1036         pprAddr op
1037     ]
1038
1039 pprSizeAddrReg :: FAST_STRING -> Size -> Addr -> Reg -> Unpretty
1040 pprSizeAddrReg name size op dst
1041   = uppBesides [
1042         uppChar '\t',
1043         uppPStr name,
1044         pprSize size,
1045         uppSP,
1046         pprAddr op,
1047         uppComma,
1048         pprReg size dst
1049     ]
1050
1051 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Unpretty
1052 pprOpOp name size op1 op2
1053   = uppBesides [
1054         uppChar '\t',
1055         uppPStr name, uppSP,
1056         pprOperand size op1,
1057         uppComma,
1058         pprOperand size op2
1059     ]
1060
1061 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> Unpretty
1062 pprSizeOpOpCoerce name size1 size2 op1 op2
1063   = uppBesides [ uppChar '\t', uppPStr name, uppSP,
1064         pprOperand size1 op1,
1065         uppComma,
1066         pprOperand size2 op2
1067     ]
1068
1069 pprCondInstr :: FAST_STRING -> Cond -> Unpretty -> Unpretty
1070 pprCondInstr name cond arg
1071   = uppBesides [ uppChar '\t', uppPStr name, pprCond cond, uppSP, arg]
1072
1073 #endif {-i386_TARGET_ARCH-}
1074 \end{code}
1075
1076 %************************************************************************
1077 %*                                                                      *
1078 \subsubsection{@pprInstr@ for a SPARC}
1079 %*                                                                      *
1080 %************************************************************************
1081
1082 \begin{code}
1083 #if sparc_TARGET_ARCH
1084
1085 -- a clumsy hack for now, to handle possible double alignment problems
1086
1087 pprInstr (LD DF addr reg) | maybeToBool off_addr
1088   = uppBesides [
1089         pp_ld_lbracket,
1090         pprAddr addr,
1091         pp_rbracket_comma,
1092         pprReg reg,
1093
1094         uppChar '\n',
1095         pp_ld_lbracket,
1096         pprAddr addr2,
1097         pp_rbracket_comma,
1098         pprReg (fPair reg)
1099     ]
1100   where
1101     off_addr = addrOffset addr 4
1102     addr2 = case off_addr of Just x -> x
1103
1104 pprInstr (LD size addr reg)
1105   = uppBesides [
1106         uppPStr SLIT("\tld"),
1107         pprSize size,
1108         uppChar '\t',
1109         uppLbrack,
1110         pprAddr addr,
1111         pp_rbracket_comma,
1112         pprReg reg
1113     ]
1114
1115 -- The same clumsy hack as above
1116
1117 pprInstr (ST DF reg addr) | maybeToBool off_addr
1118   = uppBesides [
1119         uppPStr SLIT("\tst\t"),
1120         pprReg reg,
1121         pp_comma_lbracket,
1122         pprAddr addr,
1123
1124         uppPStr SLIT("]\n\tst\t"),
1125         pprReg (fPair reg),
1126         pp_comma_lbracket,
1127         pprAddr addr2,
1128         uppRbrack
1129     ]
1130   where
1131     off_addr = addrOffset addr 4
1132     addr2 = case off_addr of Just x -> x
1133
1134 pprInstr (ST size reg addr)
1135   = uppBesides [
1136         uppPStr SLIT("\tst"),
1137         pprSize size,
1138         uppChar '\t',
1139         pprReg reg,
1140         pp_comma_lbracket,
1141         pprAddr addr,
1142         uppRbrack
1143     ]
1144
1145 pprInstr (ADD x cc reg1 ri reg2)
1146   | not x && not cc && riZero ri
1147   = uppBesides [ uppPStr SLIT("\tmov\t"), pprReg reg1, uppComma, pprReg reg2 ]
1148   | otherwise
1149   = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1150
1151 pprInstr (SUB x cc reg1 ri reg2)
1152   | not x && cc && reg2 == g0
1153   = uppBesides [ uppPStr SLIT("\tcmp\t"), pprReg reg1, uppComma, pprRI ri ]
1154   | not x && not cc && riZero ri
1155   = uppBesides [ uppPStr SLIT("\tmov\t"), pprReg reg1, uppComma, pprReg reg2 ]
1156   | otherwise
1157   = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1158
1159 pprInstr (AND  b reg1 ri reg2) = pprRegRIReg SLIT("and")  b reg1 ri reg2
1160 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1161
1162 pprInstr (OR b reg1 ri reg2)
1163   | not b && reg1 == g0
1164   = uppBesides [ uppPStr SLIT("\tmov\t"), pprRI ri, uppComma, pprReg reg2 ]
1165   | otherwise
1166   = pprRegRIReg SLIT("or") b reg1 ri reg2
1167
1168 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1169
1170 pprInstr (XOR  b reg1 ri reg2) = pprRegRIReg SLIT("xor")  b reg1 ri reg2
1171 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1172
1173 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1174 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1175 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1176
1177 pprInstr (SETHI imm reg)
1178   = uppBesides [
1179         uppPStr SLIT("\tsethi\t"),
1180         pprImm imm,
1181         uppComma,
1182         pprReg reg
1183     ]
1184
1185 pprInstr NOP = uppPStr SLIT("\tnop")
1186
1187 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1188 pprInstr (FABS DF reg1 reg2)
1189   = uppBeside (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1190     (if (reg1 == reg2) then uppNil
1191      else uppBeside (uppChar '\n')
1192           (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1193
1194 pprInstr (FADD size reg1 reg2 reg3)
1195   = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1196 pprInstr (FCMP e size reg1 reg2)
1197   = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1198 pprInstr (FDIV size reg1 reg2 reg3)
1199   = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1200
1201 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1202 pprInstr (FMOV DF reg1 reg2)
1203   = uppBeside (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1204     (if (reg1 == reg2) then uppNil
1205      else uppBeside (uppChar '\n')
1206           (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1207
1208 pprInstr (FMUL size reg1 reg2 reg3)
1209   = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1210
1211 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1212 pprInstr (FNEG DF reg1 reg2)
1213   = uppBeside (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1214     (if (reg1 == reg2) then uppNil
1215      else uppBeside (uppChar '\n')
1216           (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1217
1218 pprInstr (FSQRT size reg1 reg2)     = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1219 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1220 pprInstr (FxTOy size1 size2 reg1 reg2)
1221   = uppBesides [
1222         uppPStr SLIT("\tf"),
1223         uppPStr
1224         (case size1 of
1225             W  -> SLIT("ito")
1226             F  -> SLIT("sto")
1227             DF -> SLIT("dto")),
1228         uppPStr
1229         (case size2 of
1230             W  -> SLIT("i\t")
1231             F  -> SLIT("s\t")
1232             DF -> SLIT("d\t")),
1233         pprReg reg1, uppComma, pprReg reg2
1234     ]
1235
1236
1237 pprInstr (BI cond b lab)
1238   = uppBesides [
1239         uppPStr SLIT("\tb"), pprCond cond,
1240         if b then pp_comma_a else uppNil,
1241         uppChar '\t',
1242         pprImm lab
1243     ]
1244
1245 pprInstr (BF cond b lab)
1246   = uppBesides [
1247         uppPStr SLIT("\tfb"), pprCond cond,
1248         if b then pp_comma_a else uppNil,
1249         uppChar '\t',
1250         pprImm lab
1251     ]
1252
1253 pprInstr (JMP addr) = uppBeside (uppPStr SLIT("\tjmp\t")) (pprAddr addr)
1254
1255 pprInstr (CALL imm n _)
1256   = uppBesides [ uppPStr SLIT("\tcall\t"), pprImm imm, uppComma, uppInt n ]
1257 \end{code}
1258
1259 Continue with SPARC-only printing bits and bobs:
1260 \begin{code}
1261 pprRI :: RI -> Unpretty
1262 pprRI (RIReg r) = pprReg r
1263 pprRI (RIImm r) = pprImm r
1264
1265 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Unpretty
1266 pprSizeRegReg name size reg1 reg2
1267   = uppBesides [
1268         uppChar '\t',
1269         uppPStr name,
1270         (case size of
1271             F  -> uppPStr SLIT("s\t")
1272             DF -> uppPStr SLIT("d\t")),
1273         pprReg reg1,
1274         uppComma,
1275         pprReg reg2
1276     ]
1277
1278 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Unpretty
1279 pprSizeRegRegReg name size reg1 reg2 reg3
1280   = uppBesides [
1281         uppChar '\t',
1282         uppPStr name,
1283         (case size of
1284             F  -> uppPStr SLIT("s\t")
1285             DF -> uppPStr SLIT("d\t")),
1286         pprReg reg1,
1287         uppComma,
1288         pprReg reg2,
1289         uppComma,
1290         pprReg reg3
1291     ]
1292
1293 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> Unpretty
1294 pprRegRIReg name b reg1 ri reg2
1295   = uppBesides [
1296         uppChar '\t',
1297         uppPStr name,
1298         if b then uppPStr SLIT("cc\t") else uppChar '\t',
1299         pprReg reg1,
1300         uppComma,
1301         pprRI ri,
1302         uppComma,
1303         pprReg reg2
1304     ]
1305
1306 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> Unpretty
1307 pprRIReg name b ri reg1
1308   = uppBesides [
1309         uppChar '\t',
1310         uppPStr name,
1311         if b then uppPStr SLIT("cc\t") else uppChar '\t',
1312         pprRI ri,
1313         uppComma,
1314         pprReg reg1
1315     ]
1316
1317 pp_ld_lbracket    = uppPStr (_packCString (A# "\tld\t["#))
1318 pp_rbracket_comma = uppPStr (_packCString (A# "],"#))
1319 pp_comma_lbracket = uppPStr (_packCString (A# ",["#))
1320 pp_comma_a        = uppPStr (_packCString (A# ",a"#))
1321
1322 #endif {-sparc_TARGET_ARCH-}
1323 \end{code}