2 % (c) The AQUA Project, Glasgow University, 1996-1998
4 \section[PprMach]{Pretty-printing assembly language}
6 We start with the @pprXXX@s with some cross-platform commonality
7 (e.g., @pprReg@); we conclude with the no-commonality monster,
11 #include "nativeGen/NCG.h"
13 module PprMach ( pprInstr, pprSize, pprUserReg ) where
15 #include "HsVersions.h"
17 import MachRegs -- may differ per-platform
20 import CLabel ( pprCLabel_asm, externallyVisibleCLabel )
21 import CStrings ( charToC )
22 import Maybes ( maybeToBool )
23 import Stix ( CodeSegment(..), StixTree(..) )
24 import Char ( isPrint, isDigit )
32 %************************************************************************
34 \subsection{@pprReg@: print a @Reg@}
36 %************************************************************************
38 For x86, the way we print a register name depends
39 on which bit of it we care about. Yurgh.
41 pprUserReg:: Reg -> SDoc
42 pprUserReg = pprReg IF_ARCH_i386(L,)
45 pprReg :: IF_ARCH_i386(Size ->,) Reg -> SDoc
47 pprReg IF_ARCH_i386(s,) r
49 FixedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
50 MappedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
51 other -> text (show other) -- should only happen when debugging
54 ppr_reg_no :: FAST_REG_NO -> SDoc
57 ILIT( 0) -> SLIT("$0"); ILIT( 1) -> SLIT("$1");
58 ILIT( 2) -> SLIT("$2"); ILIT( 3) -> SLIT("$3");
59 ILIT( 4) -> SLIT("$4"); ILIT( 5) -> SLIT("$5");
60 ILIT( 6) -> SLIT("$6"); ILIT( 7) -> SLIT("$7");
61 ILIT( 8) -> SLIT("$8"); ILIT( 9) -> SLIT("$9");
62 ILIT(10) -> SLIT("$10"); ILIT(11) -> SLIT("$11");
63 ILIT(12) -> SLIT("$12"); ILIT(13) -> SLIT("$13");
64 ILIT(14) -> SLIT("$14"); ILIT(15) -> SLIT("$15");
65 ILIT(16) -> SLIT("$16"); ILIT(17) -> SLIT("$17");
66 ILIT(18) -> SLIT("$18"); ILIT(19) -> SLIT("$19");
67 ILIT(20) -> SLIT("$20"); ILIT(21) -> SLIT("$21");
68 ILIT(22) -> SLIT("$22"); ILIT(23) -> SLIT("$23");
69 ILIT(24) -> SLIT("$24"); ILIT(25) -> SLIT("$25");
70 ILIT(26) -> SLIT("$26"); ILIT(27) -> SLIT("$27");
71 ILIT(28) -> SLIT("$28"); ILIT(29) -> SLIT("$29");
72 ILIT(30) -> SLIT("$30"); ILIT(31) -> SLIT("$31");
73 ILIT(32) -> SLIT("$f0"); ILIT(33) -> SLIT("$f1");
74 ILIT(34) -> SLIT("$f2"); ILIT(35) -> SLIT("$f3");
75 ILIT(36) -> SLIT("$f4"); ILIT(37) -> SLIT("$f5");
76 ILIT(38) -> SLIT("$f6"); ILIT(39) -> SLIT("$f7");
77 ILIT(40) -> SLIT("$f8"); ILIT(41) -> SLIT("$f9");
78 ILIT(42) -> SLIT("$f10"); ILIT(43) -> SLIT("$f11");
79 ILIT(44) -> SLIT("$f12"); ILIT(45) -> SLIT("$f13");
80 ILIT(46) -> SLIT("$f14"); ILIT(47) -> SLIT("$f15");
81 ILIT(48) -> SLIT("$f16"); ILIT(49) -> SLIT("$f17");
82 ILIT(50) -> SLIT("$f18"); ILIT(51) -> SLIT("$f19");
83 ILIT(52) -> SLIT("$f20"); ILIT(53) -> SLIT("$f21");
84 ILIT(54) -> SLIT("$f22"); ILIT(55) -> SLIT("$f23");
85 ILIT(56) -> SLIT("$f24"); ILIT(57) -> SLIT("$f25");
86 ILIT(58) -> SLIT("$f26"); ILIT(59) -> SLIT("$f27");
87 ILIT(60) -> SLIT("$f28"); ILIT(61) -> SLIT("$f29");
88 ILIT(62) -> SLIT("$f30"); ILIT(63) -> SLIT("$f31");
89 _ -> SLIT("very naughty alpha register")
93 ppr_reg_no :: Size -> FAST_REG_NO -> SDoc
94 ppr_reg_no B i = ptext
96 ILIT( 0) -> SLIT("%al"); ILIT( 1) -> SLIT("%bl");
97 ILIT( 2) -> SLIT("%cl"); ILIT( 3) -> SLIT("%dl");
98 _ -> SLIT("very naughty I386 byte register")
101 ppr_reg_no _ i = ptext
103 ILIT( 0) -> SLIT("%eax"); ILIT( 1) -> SLIT("%ebx");
104 ILIT( 2) -> SLIT("%ecx"); ILIT( 3) -> SLIT("%edx");
105 ILIT( 4) -> SLIT("%esi"); ILIT( 5) -> SLIT("%edi");
106 ILIT( 6) -> SLIT("%ebp"); ILIT( 7) -> SLIT("%esp");
107 ILIT( 8) -> SLIT("%fake0"); ILIT( 9) -> SLIT("%fake1");
108 ILIT(10) -> SLIT("%fake2"); ILIT(11) -> SLIT("%fake3");
109 ILIT(12) -> SLIT("%fake4"); ILIT(13) -> SLIT("%fake5");
110 _ -> SLIT("very naughty I386 register")
113 #if sparc_TARGET_ARCH
114 ppr_reg_no :: FAST_REG_NO -> SDoc
117 ILIT( 0) -> SLIT("%g0"); ILIT( 1) -> SLIT("%g1");
118 ILIT( 2) -> SLIT("%g2"); ILIT( 3) -> SLIT("%g3");
119 ILIT( 4) -> SLIT("%g4"); ILIT( 5) -> SLIT("%g5");
120 ILIT( 6) -> SLIT("%g6"); ILIT( 7) -> SLIT("%g7");
121 ILIT( 8) -> SLIT("%o0"); ILIT( 9) -> SLIT("%o1");
122 ILIT(10) -> SLIT("%o2"); ILIT(11) -> SLIT("%o3");
123 ILIT(12) -> SLIT("%o4"); ILIT(13) -> SLIT("%o5");
124 ILIT(14) -> SLIT("%o6"); ILIT(15) -> SLIT("%o7");
125 ILIT(16) -> SLIT("%l0"); ILIT(17) -> SLIT("%l1");
126 ILIT(18) -> SLIT("%l2"); ILIT(19) -> SLIT("%l3");
127 ILIT(20) -> SLIT("%l4"); ILIT(21) -> SLIT("%l5");
128 ILIT(22) -> SLIT("%l6"); ILIT(23) -> SLIT("%l7");
129 ILIT(24) -> SLIT("%i0"); ILIT(25) -> SLIT("%i1");
130 ILIT(26) -> SLIT("%i2"); ILIT(27) -> SLIT("%i3");
131 ILIT(28) -> SLIT("%i4"); ILIT(29) -> SLIT("%i5");
132 ILIT(30) -> SLIT("%i6"); ILIT(31) -> SLIT("%i7");
133 ILIT(32) -> SLIT("%f0"); ILIT(33) -> SLIT("%f1");
134 ILIT(34) -> SLIT("%f2"); ILIT(35) -> SLIT("%f3");
135 ILIT(36) -> SLIT("%f4"); ILIT(37) -> SLIT("%f5");
136 ILIT(38) -> SLIT("%f6"); ILIT(39) -> SLIT("%f7");
137 ILIT(40) -> SLIT("%f8"); ILIT(41) -> SLIT("%f9");
138 ILIT(42) -> SLIT("%f10"); ILIT(43) -> SLIT("%f11");
139 ILIT(44) -> SLIT("%f12"); ILIT(45) -> SLIT("%f13");
140 ILIT(46) -> SLIT("%f14"); ILIT(47) -> SLIT("%f15");
141 ILIT(48) -> SLIT("%f16"); ILIT(49) -> SLIT("%f17");
142 ILIT(50) -> SLIT("%f18"); ILIT(51) -> SLIT("%f19");
143 ILIT(52) -> SLIT("%f20"); ILIT(53) -> SLIT("%f21");
144 ILIT(54) -> SLIT("%f22"); ILIT(55) -> SLIT("%f23");
145 ILIT(56) -> SLIT("%f24"); ILIT(57) -> SLIT("%f25");
146 ILIT(58) -> SLIT("%f26"); ILIT(59) -> SLIT("%f27");
147 ILIT(60) -> SLIT("%f28"); ILIT(61) -> SLIT("%f29");
148 ILIT(62) -> SLIT("%f30"); ILIT(63) -> SLIT("%f31");
149 _ -> SLIT("very naughty sparc register")
154 %************************************************************************
156 \subsection{@pprSize@: print a @Size@}
158 %************************************************************************
161 pprSize :: Size -> SDoc
163 pprSize x = ptext (case x of
164 #if alpha_TARGET_ARCH
167 -- W -> SLIT("w") UNUSED
168 -- WU -> SLIT("wu") UNUSED
169 -- L -> SLIT("l") UNUSED
171 -- FF -> SLIT("f") UNUSED
172 -- DF -> SLIT("d") UNUSED
173 -- GF -> SLIT("g") UNUSED
174 -- SF -> SLIT("s") UNUSED
179 -- HB -> SLIT("b") UNUSED
180 -- S -> SLIT("w") UNUSED
186 #if sparc_TARGET_ARCH
189 -- HW -> SLIT("hw") UNUSED
190 -- HWU -> SLIT("uhw") UNUSED
193 -- D -> SLIT("d") UNUSED
196 pprStSize :: Size -> SDoc
197 pprStSize x = ptext (case x of
200 -- HW -> SLIT("hw") UNUSED
201 -- HWU -> SLIT("uhw") UNUSED
204 -- D -> SLIT("d") UNUSED
210 %************************************************************************
212 \subsection{@pprCond@: print a @Cond@}
214 %************************************************************************
217 pprCond :: Cond -> SDoc
219 pprCond c = ptext (case c of {
220 #if alpha_TARGET_ARCH
231 GEU -> SLIT("ae"); LU -> SLIT("b");
232 EQQ -> SLIT("e"); GTT -> SLIT("g");
233 GE -> SLIT("ge"); GU -> SLIT("a");
234 LTT -> SLIT("l"); LE -> SLIT("le");
235 LEU -> SLIT("be"); NE -> SLIT("ne");
236 NEG -> SLIT("s"); POS -> SLIT("ns");
237 ALWAYS -> SLIT("mp") -- hack
239 #if sparc_TARGET_ARCH
240 ALWAYS -> SLIT(""); NEVER -> SLIT("n");
241 GEU -> SLIT("geu"); LU -> SLIT("lu");
242 EQQ -> SLIT("e"); GTT -> SLIT("g");
243 GE -> SLIT("ge"); GU -> SLIT("gu");
244 LTT -> SLIT("l"); LE -> SLIT("le");
245 LEU -> SLIT("leu"); NE -> SLIT("ne");
246 NEG -> SLIT("neg"); POS -> SLIT("pos");
247 VC -> SLIT("vc"); VS -> SLIT("vs")
252 %************************************************************************
254 \subsection{@pprImm@: print an @Imm@}
256 %************************************************************************
259 pprImm :: Imm -> SDoc
261 pprImm (ImmInt i) = int i
262 pprImm (ImmInteger i) = integer i
263 pprImm (ImmCLbl l) = pprCLabel_asm l
264 pprImm (ImmIndex l i) = pprCLabel_asm l <> char '+' <> int i
265 pprImm (ImmLit s) = s
267 pprImm (ImmLab s) | underscorePrefix = (<>) (char '_') s
270 #if sparc_TARGET_ARCH
272 = hcat [ pp_lo, pprImm i, rparen ]
277 = hcat [ pp_hi, pprImm i, rparen ]
283 %************************************************************************
285 \subsection{@pprAddr@: print an @Addr@}
287 %************************************************************************
290 pprAddr :: MachRegsAddr -> SDoc
292 #if alpha_TARGET_ARCH
293 pprAddr (AddrReg r) = parens (pprReg r)
294 pprAddr (AddrImm i) = pprImm i
295 pprAddr (AddrRegImm r1 i)
296 = (<>) (pprImm i) (parens (pprReg r1))
302 pprAddr (ImmAddr imm off)
303 = let pp_imm = pprImm imm
307 else if (off < 0) then
310 pp_imm <> char '+' <> int off
312 pprAddr (AddrBaseIndex base index displacement)
314 pp_disp = ppr_disp displacement
315 pp_off p = pp_disp <> char '(' <> p <> char ')'
316 pp_reg r = pprReg L r
319 (Nothing, Nothing) -> pp_disp
320 (Just b, Nothing) -> pp_off (pp_reg b)
321 (Nothing, Just (r,i)) -> pp_off (pp_reg r <> comma <> int i)
322 (Just b, Just (r,i)) -> pp_off (pp_reg b <> comma <> pp_reg r
325 ppr_disp (ImmInt 0) = empty
326 ppr_disp imm = pprImm imm
331 #if sparc_TARGET_ARCH
332 pprAddr (AddrRegReg r1 (FixedReg ILIT(0))) = pprReg r1
334 pprAddr (AddrRegReg r1 r2)
335 = hcat [ pprReg r1, char '+', pprReg r2 ]
337 pprAddr (AddrRegImm r1 (ImmInt i))
339 | not (fits13Bits i) = largeOffsetError i
340 | otherwise = hcat [ pprReg r1, pp_sign, int i ]
342 pp_sign = if i > 0 then char '+' else empty
344 pprAddr (AddrRegImm r1 (ImmInteger i))
346 | not (fits13Bits i) = largeOffsetError i
347 | otherwise = hcat [ pprReg r1, pp_sign, integer i ]
349 pp_sign = if i > 0 then char '+' else empty
351 pprAddr (AddrRegImm r1 imm)
352 = hcat [ pprReg r1, char '+', pprImm imm ]
356 %************************************************************************
358 \subsection{@pprInstr@: print an @Instr@}
360 %************************************************************************
363 pprInstr :: Instr -> SDoc
365 --pprInstr (COMMENT s) = empty -- nuke 'em
367 = IF_ARCH_alpha( ((<>) (ptext SLIT("\t# ")) (ptext s))
368 ,IF_ARCH_sparc( ((<>) (ptext SLIT("! ")) (ptext s))
369 ,IF_ARCH_i386( ((<>) (ptext SLIT("# ")) (ptext s))
373 = pprInstr (COMMENT (_PK_ ("\tdelta = " ++ show d)))
375 pprInstr (SEGMENT TextSegment)
376 = IF_ARCH_alpha(ptext SLIT("\t.text\n\t.align 3") {-word boundary-}
377 ,IF_ARCH_sparc(ptext SLIT("\t.text\n\t.align 4") {-word boundary-}
378 ,IF_ARCH_i386((text ".text\n\t.align 4,0x90") {-needs per-OS variation!-}
381 pprInstr (SEGMENT DataSegment)
383 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
384 ,IF_ARCH_sparc(SLIT("\t.data\n\t.align 8") {-<8 will break double constants -}
385 ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
388 pprInstr (LABEL clab)
390 pp_lab = pprCLabel_asm clab
393 if not (externallyVisibleCLabel clab) then
397 IF_ARCH_alpha(SLIT("\t.globl\t")
398 ,IF_ARCH_i386(SLIT(".globl ")
399 ,IF_ARCH_sparc(SLIT("\t.global\t")
401 , pp_lab, char '\n'],
406 pprInstr (ASCII False{-no backslash conversion-} str)
407 = hcat [ ptext SLIT("\t.asciz "), char '\"', text str, char '"' ]
409 pprInstr (ASCII True str)
410 = --(<>) (text "\t.ascii \"") (asciify 60 str)
413 asciify :: String -> SDoc
414 asciify "" = text "\t.ascii \"\\0\""
416 = let fst = take 16 str
418 this = text ("\t.ascii \""
419 ++ concat (map asciify_char fst)
421 in this $$ asciify rest
422 asciify_char :: Char -> String
423 asciify_char c = '\\' : 'x' : hshow (ord c)
425 hshow :: Int -> String
426 hshow n | n >= 0 && n <= 255
427 = [ tab !! (n `div` 16), tab !! (n `mod` 16)]
428 tab = "0123456789abcdef"
431 asciify :: String -> Int -> SDoc
432 asciify [] _ = text "\\0\""
433 asciify s n | n <= 0 = (<>) (text "\"\n\t.ascii \"") (asciify s 60)
434 asciify ('\\':cs) n = (<>) (text "\\\\") (asciify cs (n-1))
435 asciify ('\"':cs) n = (<>) (text "\\\"") (asciify cs (n-1))
436 asciify (c:cs) n | isPrint c = (<>) (char c) (asciify cs (n-1))
437 asciify [c] _ = (<>) (text (charToC c)) (text ("\\0\"")){-"-}
438 asciify (c:(cs@(d:_))) n
439 | isDigit d = (<>) (text (charToC c)) (asciify cs 0)
440 | otherwise = (<>) (text (charToC c)) (asciify cs (n-1))
441 asciify [] _ = text "\\0\
446 = vcat [(<>) (ptext pp_size) (pprImm x) | x <- xs]
449 #if alpha_TARGET_ARCH
450 B -> SLIT("\t.byte\t")
451 BU -> SLIT("\t.byte\t")
452 Q -> SLIT("\t.quad\t")
453 TF -> SLIT("\t.t_floating\t")
456 B -> SLIT("\t.byte\t")
457 L -> SLIT("\t.long\t")
458 F -> SLIT("\t.float\t")
459 DF -> SLIT("\t.double\t")
461 #if sparc_TARGET_ARCH
462 B -> SLIT("\t.byte\t")
463 BU -> SLIT("\t.byte\t")
464 W -> SLIT("\t.word\t")
465 DF -> SLIT("\t.double\t")
471 = vcat (concatMap (ppr_item s) xs)
473 #if alpha_TARGET_ARCH
474 ppr_item = error "ppr_item on Alpha"
476 This needs to be fixed.
477 B -> SLIT("\t.byte\t")
478 BU -> SLIT("\t.byte\t")
479 Q -> SLIT("\t.quad\t")
480 TF -> SLIT("\t.t_floating\t")
483 #if sparc_TARGET_ARCH
484 ppr_item = error "ppr_item on Sparc"
486 This needs to be fixed.
487 B -> SLIT("\t.byte\t")
488 BU -> SLIT("\t.byte\t")
489 W -> SLIT("\t.word\t")
490 DF -> SLIT("\t.double\t")
494 ppr_item B x = [text "\t.byte\t" <> pprImm x]
495 ppr_item L x = [text "\t.long\t" <> pprImm x]
496 ppr_item F (ImmDouble r)
497 = let bs = floatToBytes (fromRational r)
498 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
499 ppr_item DF (ImmDouble r)
500 = let bs = doubleToBytes (fromRational r)
501 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
503 floatToBytes :: Float -> [Int]
506 arr <- newFloatArray ((0::Int),3)
507 writeFloatArray arr 0 f
508 i0 <- readCharArray arr 0
509 i1 <- readCharArray arr 1
510 i2 <- readCharArray arr 2
511 i3 <- readCharArray arr 3
512 return (map ord [i0,i1,i2,i3])
515 doubleToBytes :: Double -> [Int]
518 arr <- newDoubleArray ((0::Int),7)
519 writeDoubleArray arr 0 d
520 i0 <- readCharArray arr 0
521 i1 <- readCharArray arr 1
522 i2 <- readCharArray arr 2
523 i3 <- readCharArray arr 3
524 i4 <- readCharArray arr 4
525 i5 <- readCharArray arr 5
526 i6 <- readCharArray arr 6
527 i7 <- readCharArray arr 7
528 return (map ord [i0,i1,i2,i3,i4,i5,i6,i7])
533 -- fall through to rest of (machine-specific) pprInstr...
536 %************************************************************************
538 \subsubsection{@pprInstr@ for an Alpha}
540 %************************************************************************
543 #if alpha_TARGET_ARCH
545 pprInstr (LD size reg addr)
555 pprInstr (LDA reg addr)
557 ptext SLIT("\tlda\t"),
563 pprInstr (LDAH reg addr)
565 ptext SLIT("\tldah\t"),
571 pprInstr (LDGP reg addr)
573 ptext SLIT("\tldgp\t"),
579 pprInstr (LDI size reg imm)
589 pprInstr (ST size reg addr)
601 ptext SLIT("\tclr\t"),
605 pprInstr (ABS size ri reg)
615 pprInstr (NEG size ov ri reg)
619 if ov then ptext SLIT("v\t") else char '\t',
625 pprInstr (ADD size ov reg1 ri reg2)
629 if ov then ptext SLIT("v\t") else char '\t',
637 pprInstr (SADD size scale reg1 ri reg2)
639 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
650 pprInstr (SUB size ov reg1 ri reg2)
654 if ov then ptext SLIT("v\t") else char '\t',
662 pprInstr (SSUB size scale reg1 ri reg2)
664 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
675 pprInstr (MUL size ov reg1 ri reg2)
679 if ov then ptext SLIT("v\t") else char '\t',
687 pprInstr (DIV size uns reg1 ri reg2)
691 if uns then ptext SLIT("u\t") else char '\t',
699 pprInstr (REM size uns reg1 ri reg2)
703 if uns then ptext SLIT("u\t") else char '\t',
711 pprInstr (NOT ri reg)
720 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
721 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
722 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
723 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
724 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
725 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
727 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
728 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
729 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
731 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
732 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
734 pprInstr (NOP) = ptext SLIT("\tnop")
736 pprInstr (CMP cond reg1 ri reg2)
750 ptext SLIT("\tfclr\t"),
754 pprInstr (FABS reg1 reg2)
756 ptext SLIT("\tfabs\t"),
762 pprInstr (FNEG size reg1 reg2)
772 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
773 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
774 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
775 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
777 pprInstr (CVTxy size1 size2 reg1 reg2)
781 case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
788 pprInstr (FCMP size cond reg1 reg2 reg3)
801 pprInstr (FMOV reg1 reg2)
803 ptext SLIT("\tfmov\t"),
809 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
811 pprInstr (BI NEVER reg lab) = empty
813 pprInstr (BI cond reg lab)
823 pprInstr (BF cond reg lab)
834 = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
836 pprInstr (JMP reg addr hint)
838 ptext SLIT("\tjmp\t"),
847 = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
849 pprInstr (JSR reg addr n)
851 ptext SLIT("\tjsr\t"),
857 pprInstr (FUNBEGIN clab)
859 if (externallyVisibleCLabel clab) then
860 hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
863 ptext SLIT("\t.ent "),
872 pp_lab = pprCLabel_asm clab
874 -- NEVER use commas within those string literals, cpp will ruin your day
875 pp_ldgp = hcat [ ptext SLIT(":\n\tldgp $29"), char ',', ptext SLIT("0($27)\n") ]
876 pp_frame = hcat [ ptext SLIT("..ng:\n\t.frame $30"), char ',',
877 ptext SLIT("4240"), char ',',
878 ptext SLIT("$26"), char ',',
879 ptext SLIT("0\n\t.prologue 1") ]
881 pprInstr (FUNEND clab)
882 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
885 Continue with Alpha-only printing bits and bobs:
889 pprRI (RIReg r) = pprReg r
890 pprRI (RIImm r) = pprImm r
892 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> SDoc
894 pprRegRIReg name reg1 ri reg2
906 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
908 pprSizeRegRegReg name size reg1 reg2 reg3
921 #endif {-alpha_TARGET_ARCH-}
924 %************************************************************************
926 \subsubsection{@pprInstr@ for an I386}
928 %************************************************************************
933 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
937 (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
941 pprInstr (MOV size src dst)
942 = pprSizeOpOp SLIT("mov") size src dst
943 pprInstr (MOVZxL sizes src dst) = pprSizeOpOpCoerce SLIT("movz") sizes L src dst
944 pprInstr (MOVSxL sizes src dst) = pprSizeOpOpCoerce SLIT("movs") sizes L src dst
946 -- here we do some patching, since the physical registers are only set late
947 -- in the code generation.
948 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
950 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
951 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
953 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
954 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
956 = pprInstr (ADD size (OpImm displ) dst)
957 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
959 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
960 = pprSizeOp SLIT("dec") size dst
961 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
962 = pprSizeOp SLIT("inc") size dst
963 pprInstr (ADD size src dst)
964 = pprSizeOpOp SLIT("add") size src dst
965 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
966 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
967 pprInstr (IDIV size op) = pprSizeOp SLIT("idiv") size op
969 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
970 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
971 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
972 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
973 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
975 pprInstr (SHL size imm dst) = pprSizeImmOp SLIT("shl") size imm dst
976 pprInstr (SAR size imm dst) = pprSizeImmOp SLIT("sar") size imm dst
977 pprInstr (SHR size imm dst) = pprSizeImmOp SLIT("shr") size imm dst
978 pprInstr (BT size imm src) = pprSizeImmOp SLIT("bt") size imm src
980 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
981 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
982 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
983 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
984 pprInstr PUSHA = ptext SLIT("\tpushal")
985 pprInstr POPA = ptext SLIT("\tpopal")
987 pprInstr (NOP) = ptext SLIT("\tnop")
988 pprInstr (CLTD) = ptext SLIT("\tcltd")
990 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
992 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
994 pprInstr (JMP (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
995 pprInstr (JMP op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand L op)
997 = (<>) (ptext SLIT("\tcall ")) (pprImm imm)
1000 -- Simulating a flat register set on the x86 FP stack is tricky.
1001 -- you have to free %st(7) before pushing anything on the FP reg stack
1002 -- so as to preclude the possibility of a FP stack overflow exception.
1003 pprInstr g@(GMOV src dst)
1007 = pprG g (hcat [gtab, gpush src 0, gsemi, gpop dst 1])
1009 -- GLD sz addr dst ==> FFREE %st(7) ; FLDsz addr ; FSTP (dst+1)
1010 pprInstr g@(GLD sz addr dst)
1011 = pprG g (hcat [gtab, text "ffree %st(7) ; fld", pprSize sz, gsp,
1012 pprAddr addr, gsemi, gpop dst 1])
1014 -- GST sz src addr ==> FFREE %st(7) ; FLD dst ; FSTPsz addr
1015 pprInstr g@(GST sz src addr)
1016 = pprG g (hcat [gtab, gpush src 0, gsemi,
1017 text "fstp", pprSize sz, gsp, pprAddr addr])
1019 pprInstr g@(GLDZ dst)
1020 = pprG g (hcat [gtab, text "ffree %st(7) ; fldz ; ", gpop dst 1])
1021 pprInstr g@(GLD1 dst)
1022 = pprG g (hcat [gtab, text "ffree %st(7) ; fld1 ; ", gpop dst 1])
1024 pprInstr g@(GFTOD src dst)
1026 pprInstr g@(GFTOI src dst)
1029 pprInstr g@(GDTOF src dst)
1031 pprInstr g@(GDTOI src dst)
1034 pprInstr g@(GITOF src dst)
1035 = pprInstr (GITOD src dst)
1036 pprInstr g@(GITOD src dst)
1037 = pprG g (hcat [gtab, text "pushl ", pprReg L src,
1038 text " ; ffree %st(7); fildl (%esp) ; ",
1039 gpop dst 1, text " ; addl $4,%esp"])
1041 pprInstr g@(GCMP sz src1 src2)
1042 = pprG g (hcat [gtab, text "pushl %eax ; ",
1043 gpush src2 0, gsemi, gpush src1 1]
1045 hcat [gtab, text "fcompp ; fstsw %ax ; sahf ; popl %eax"])
1047 pprInstr g@(GABS sz src dst)
1048 = pprG g (hcat [gtab, gpush src 0, text " ; fabs ; ", gpop dst 1])
1049 pprInstr g@(GNEG sz src dst)
1050 = pprG g (hcat [gtab, gpush src 0, text " ; fchs ; ", gpop dst 1])
1052 pprInstr g@(GSQRT sz src dst)
1053 = pprG g (hcat [gtab, gpush src 0, text " ; fsqrt"] $$
1054 hcat [gtab, gcoerceto sz, gpop dst 1])
1055 pprInstr g@(GSIN sz src dst)
1056 = pprG g (hcat [gtab, gpush src 0, text " ; fsin"] $$
1057 hcat [gtab, gcoerceto sz, gpop dst 1])
1058 pprInstr g@(GCOS sz src dst)
1059 = pprG g (hcat [gtab, gpush src 0, text " ; fcos"] $$
1060 hcat [gtab, gcoerceto sz, gpop dst 1])
1061 pprInstr g@(GTAN sz src dst)
1062 = pprG g (hcat [gtab, text "ffree %st(6) ; ",
1063 gpush src 0, text " ; fptan ; ",
1064 text " fstp %st(0)"] $$
1065 hcat [gtab, gcoerceto sz, gpop dst 1])
1067 pprInstr g@(GADD sz src1 src2 dst)
1068 = pprG g (hcat [gtab, gpush src1 0,
1069 text " ; fadd ", greg src2 1, text ",%st(0)",
1071 pprInstr g@(GSUB sz src1 src2 dst)
1072 = pprG g (hcat [gtab, gpush src1 0,
1073 text " ; fsub ", greg src2 1, text ",%st(0)",
1075 pprInstr g@(GMUL sz src1 src2 dst)
1076 = pprG g (hcat [gtab, gpush src1 0,
1077 text " ; fmul ", greg src2 1, text ",%st(0)",
1079 pprInstr g@(GDIV sz src1 src2 dst)
1080 = pprG g (hcat [gtab, gpush src1 0,
1081 text " ; fdiv ", greg src2 1, text ",%st(0)",
1085 = vcat [ ptext SLIT("\tffree %st(0) ;ffree %st(1) ;ffree %st(2) ;ffree %st(3)"),
1086 ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)")
1089 --------------------------
1091 -- coerce %st(0) to the specified size
1092 gcoerceto DF = empty
1093 gcoerceto F = text "subl $4,%esp ; fstps (%esp) ; flds (%esp) ; addl $4,%esp ; "
1096 = hcat [text "ffree %st(7) ; fld ", greg reg offset]
1098 = hcat [text "fstp ", greg reg offset]
1100 bogus = text "\tbogus"
1101 greg reg offset = text "%st(" <> int (gregno reg - 8+offset) <> char ')'
1105 gregno (FixedReg i) = I# i
1106 gregno (MappedReg i) = I# i
1107 gregno other = pprPanic "gregno" (text (show other))
1109 pprG :: Instr -> SDoc -> SDoc
1111 = (char '#' <> pprGInstr fake) $$ actual
1113 pprGInstr (GMOV src dst) = pprSizeRegReg SLIT("gmov") DF src dst
1114 pprGInstr (GLD sz src dst) = pprSizeAddrReg SLIT("gld") sz src dst
1115 pprGInstr (GST sz src dst) = pprSizeRegAddr SLIT("gst") sz src dst
1117 pprGInstr (GLDZ dst) = pprSizeReg SLIT("gldz") DF dst
1118 pprGInstr (GLD1 dst) = pprSizeReg SLIT("gld1") DF dst
1120 pprGInstr (GFTOD src dst) = pprSizeSizeRegReg SLIT("gftod") F DF src dst
1121 pprGInstr (GFTOI src dst) = pprSizeSizeRegReg SLIT("gftoi") F L src dst
1123 pprGInstr (GDTOF src dst) = pprSizeSizeRegReg SLIT("gdtof") DF F src dst
1124 pprGInstr (GDTOI src dst) = pprSizeSizeRegReg SLIT("gdtoi") DF L src dst
1126 pprGInstr (GITOF src dst) = pprSizeSizeRegReg SLIT("gitof") L F src dst
1127 pprGInstr (GITOD src dst) = pprSizeSizeRegReg SLIT("gitod") L DF src dst
1129 pprGInstr (GCMP sz src dst) = pprSizeRegReg SLIT("gcmp") sz src dst
1130 pprGInstr (GABS sz src dst) = pprSizeRegReg SLIT("gabs") sz src dst
1131 pprGInstr (GNEG sz src dst) = pprSizeRegReg SLIT("gneg") sz src dst
1132 pprGInstr (GSQRT sz src dst) = pprSizeRegReg SLIT("gsqrt") sz src dst
1133 pprGInstr (GSIN sz src dst) = pprSizeRegReg SLIT("gsin") sz src dst
1134 pprGInstr (GCOS sz src dst) = pprSizeRegReg SLIT("gcos") sz src dst
1135 pprGInstr (GTAN sz src dst) = pprSizeRegReg SLIT("gtan") sz src dst
1137 pprGInstr (GADD sz src1 src2 dst) = pprSizeRegRegReg SLIT("gadd") sz src1 src2 dst
1138 pprGInstr (GSUB sz src1 src2 dst) = pprSizeRegRegReg SLIT("gsub") sz src1 src2 dst
1139 pprGInstr (GMUL sz src1 src2 dst) = pprSizeRegRegReg SLIT("gmul") sz src1 src2 dst
1140 pprGInstr (GDIV sz src1 src2 dst) = pprSizeRegRegReg SLIT("gdiv") sz src1 src2 dst
1143 Continue with I386-only printing bits and bobs:
1145 pprDollImm :: Imm -> SDoc
1147 pprDollImm i = ptext SLIT("$") <> pprImm i
1149 pprOperand :: Size -> Operand -> SDoc
1150 pprOperand s (OpReg r) = pprReg s r
1151 pprOperand s (OpImm i) = pprDollImm i
1152 pprOperand s (OpAddr ea) = pprAddr ea
1154 pprSizeImmOp :: FAST_STRING -> Size -> Imm -> Operand -> SDoc
1155 pprSizeImmOp name size imm op1
1167 pprSizeOp :: FAST_STRING -> Size -> Operand -> SDoc
1168 pprSizeOp name size op1
1177 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1178 pprSizeOpOp name size op1 op2
1184 pprOperand size op1,
1189 pprSizeByteOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1190 pprSizeByteOpOp name size op1 op2
1201 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> SDoc
1202 pprSizeOpReg name size op1 reg
1208 pprOperand size op1,
1213 pprSizeReg :: FAST_STRING -> Size -> Reg -> SDoc
1214 pprSizeReg name size reg1
1223 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1224 pprSizeRegReg name size reg1 reg2
1235 pprSizeSizeRegReg :: FAST_STRING -> Size -> Size -> Reg -> Reg -> SDoc
1236 pprSizeSizeRegReg name size1 size2 reg1 reg2
1248 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1249 pprSizeRegRegReg name size reg1 reg2 reg3
1262 pprSizeAddr :: FAST_STRING -> Size -> MachRegsAddr -> SDoc
1263 pprSizeAddr name size op
1272 pprSizeAddrReg :: FAST_STRING -> Size -> MachRegsAddr -> Reg -> SDoc
1273 pprSizeAddrReg name size op dst
1284 pprSizeRegAddr :: FAST_STRING -> Size -> Reg -> MachRegsAddr -> SDoc
1285 pprSizeRegAddr name size src op
1296 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1297 pprOpOp name size op1 op2
1301 pprOperand size op1,
1306 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> SDoc
1307 pprSizeOpOpCoerce name size1 size2 op1 op2
1308 = hcat [ char '\t', ptext name, pprSize size1, pprSize size2, space,
1309 pprOperand size1 op1,
1311 pprOperand size2 op2
1314 pprCondInstr :: FAST_STRING -> Cond -> SDoc -> SDoc
1315 pprCondInstr name cond arg
1316 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1318 #endif {-i386_TARGET_ARCH-}
1321 %************************************************************************
1323 \subsubsection{@pprInstr@ for a SPARC}
1325 %************************************************************************
1328 #if sparc_TARGET_ARCH
1330 -- a clumsy hack for now, to handle possible double alignment problems
1332 -- even clumsier, to allow for RegReg regs that show when doing indexed
1333 -- reads (bytearrays).
1335 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1337 ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1, char '\n',
1338 pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg, char '\n',
1339 pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)
1342 pprInstr (LD DF addr reg) | maybeToBool off_addr
1356 off_addr = addrOffset addr 4
1357 addr2 = case off_addr of Just x -> x
1359 pprInstr (LD size addr reg)
1370 -- The same clumsy hack as above
1372 pprInstr (ST DF reg (AddrRegReg g1 g2))
1374 ptext SLIT("\tadd\t"),
1375 pprReg g1,comma,pprReg g2,comma,pprReg g1, char '\n',
1376 ptext SLIT("\tst\t"),
1377 pprReg reg, pp_comma_lbracket, pprReg g1,
1378 ptext SLIT("]\n\tst\t"),
1379 pprReg (fPair reg), pp_comma_lbracket, pprReg g1, ptext SLIT("+4]")
1382 pprInstr (ST DF reg addr) | maybeToBool off_addr
1384 ptext SLIT("\tst\t"),
1385 pprReg reg, pp_comma_lbracket, pprAddr addr,
1387 ptext SLIT("]\n\tst\t"),
1388 pprReg (fPair reg), pp_comma_lbracket,
1389 pprAddr addr2, rbrack
1392 off_addr = addrOffset addr 4
1393 addr2 = case off_addr of Just x -> x
1395 -- no distinction is made between signed and unsigned bytes on stores for the
1396 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1397 -- so we call a special-purpose pprSize for ST..
1399 pprInstr (ST size reg addr)
1410 pprInstr (ADD x cc reg1 ri reg2)
1411 | not x && not cc && riZero ri
1412 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1414 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1416 pprInstr (SUB x cc reg1 ri reg2)
1417 | not x && cc && reg2 == g0
1418 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1419 | not x && not cc && riZero ri
1420 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1422 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1424 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1425 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1427 pprInstr (OR b reg1 ri reg2)
1428 | not b && reg1 == g0
1429 = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1431 = pprRegRIReg SLIT("or") b reg1 ri reg2
1433 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1435 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1436 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1438 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1439 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1440 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1442 pprInstr (SETHI imm reg)
1444 ptext SLIT("\tsethi\t"),
1450 pprInstr NOP = ptext SLIT("\tnop")
1452 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1453 pprInstr (FABS DF reg1 reg2)
1454 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1455 (if (reg1 == reg2) then empty
1456 else (<>) (char '\n')
1457 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1459 pprInstr (FADD size reg1 reg2 reg3)
1460 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1461 pprInstr (FCMP e size reg1 reg2)
1462 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1463 pprInstr (FDIV size reg1 reg2 reg3)
1464 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1466 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1467 pprInstr (FMOV DF reg1 reg2)
1468 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1469 (if (reg1 == reg2) then empty
1470 else (<>) (char '\n')
1471 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1473 pprInstr (FMUL size reg1 reg2 reg3)
1474 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1476 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1477 pprInstr (FNEG DF reg1 reg2)
1478 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1479 (if (reg1 == reg2) then empty
1480 else (<>) (char '\n')
1481 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1483 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1484 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1485 pprInstr (FxTOy size1 size2 reg1 reg2)
1498 pprReg reg1, comma, pprReg reg2
1502 pprInstr (BI cond b lab)
1504 ptext SLIT("\tb"), pprCond cond,
1505 if b then pp_comma_a else empty,
1510 pprInstr (BF cond b lab)
1512 ptext SLIT("\tfb"), pprCond cond,
1513 if b then pp_comma_a else empty,
1518 pprInstr (JMP addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1520 pprInstr (CALL imm n _)
1521 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1524 Continue with SPARC-only printing bits and bobs:
1527 pprRI (RIReg r) = pprReg r
1528 pprRI (RIImm r) = pprImm r
1530 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1531 pprSizeRegReg name size reg1 reg2
1536 F -> ptext SLIT("s\t")
1537 DF -> ptext SLIT("d\t")),
1543 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1544 pprSizeRegRegReg name size reg1 reg2 reg3
1549 F -> ptext SLIT("s\t")
1550 DF -> ptext SLIT("d\t")),
1558 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> SDoc
1559 pprRegRIReg name b reg1 ri reg2
1563 if b then ptext SLIT("cc\t") else char '\t',
1571 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> SDoc
1572 pprRIReg name b ri reg1
1576 if b then ptext SLIT("cc\t") else char '\t',
1582 pp_ld_lbracket = ptext SLIT("\tld\t[")
1583 pp_rbracket_comma = text "],"
1584 pp_comma_lbracket = text ",["
1585 pp_comma_a = text ",a"
1587 #endif {-sparc_TARGET_ARCH-}