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