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, externallyVisibleCLabel, labelDynamic )
21 import Stix ( CodeSegment(..) )
22 import Unique ( pprUnique )
23 import Panic ( panic )
25 import qualified Outputable
29 import Char ( chr, ord )
30 import Maybe ( isJust )
32 asmSDoc d = Outputable.withPprStyleDoc (
33 Outputable.mkCodeStyle Outputable.AsmStyle) d
34 pprCLabel_asm l = asmSDoc (pprCLabel l)
37 %************************************************************************
39 \subsection{@pprReg@: print a @Reg@}
41 %************************************************************************
43 For x86, the way we print a register name depends
44 on which bit of it we care about. Yurgh.
46 pprUserReg :: Reg -> Doc
47 pprUserReg = pprReg IF_ARCH_i386(L,)
49 pprReg :: IF_ARCH_i386(Size ->,) Reg -> Doc
51 pprReg IF_ARCH_i386(s,) r
53 RealReg i -> ppr_reg_no IF_ARCH_i386(s,) i
54 VirtualRegI u -> text "%vI_" <> asmSDoc (pprUnique u)
55 VirtualRegF u -> text "%vF_" <> asmSDoc (pprUnique u)
58 ppr_reg_no :: Int -> Doc
61 0 -> SLIT("$0"); 1 -> SLIT("$1");
62 2 -> SLIT("$2"); 3 -> SLIT("$3");
63 4 -> SLIT("$4"); 5 -> SLIT("$5");
64 6 -> SLIT("$6"); 7 -> SLIT("$7");
65 8 -> SLIT("$8"); 9 -> SLIT("$9");
66 10 -> SLIT("$10"); 11 -> SLIT("$11");
67 12 -> SLIT("$12"); 13 -> SLIT("$13");
68 14 -> SLIT("$14"); 15 -> SLIT("$15");
69 16 -> SLIT("$16"); 17 -> SLIT("$17");
70 18 -> SLIT("$18"); 19 -> SLIT("$19");
71 20 -> SLIT("$20"); 21 -> SLIT("$21");
72 22 -> SLIT("$22"); 23 -> SLIT("$23");
73 24 -> SLIT("$24"); 25 -> SLIT("$25");
74 26 -> SLIT("$26"); 27 -> SLIT("$27");
75 28 -> SLIT("$28"); 29 -> SLIT("$29");
76 30 -> SLIT("$30"); 31 -> SLIT("$31");
77 32 -> SLIT("$f0"); 33 -> SLIT("$f1");
78 34 -> SLIT("$f2"); 35 -> SLIT("$f3");
79 36 -> SLIT("$f4"); 37 -> SLIT("$f5");
80 38 -> SLIT("$f6"); 39 -> SLIT("$f7");
81 40 -> SLIT("$f8"); 41 -> SLIT("$f9");
82 42 -> SLIT("$f10"); 43 -> SLIT("$f11");
83 44 -> SLIT("$f12"); 45 -> SLIT("$f13");
84 46 -> SLIT("$f14"); 47 -> SLIT("$f15");
85 48 -> SLIT("$f16"); 49 -> SLIT("$f17");
86 50 -> SLIT("$f18"); 51 -> SLIT("$f19");
87 52 -> SLIT("$f20"); 53 -> SLIT("$f21");
88 54 -> SLIT("$f22"); 55 -> SLIT("$f23");
89 56 -> SLIT("$f24"); 57 -> SLIT("$f25");
90 58 -> SLIT("$f26"); 59 -> SLIT("$f27");
91 60 -> SLIT("$f28"); 61 -> SLIT("$f29");
92 62 -> SLIT("$f30"); 63 -> SLIT("$f31");
93 _ -> SLIT("very naughty alpha register")
97 ppr_reg_no :: Size -> Int -> Doc
98 ppr_reg_no B = ppr_reg_byte
99 ppr_reg_no Bu = ppr_reg_byte
100 ppr_reg_no W = ppr_reg_word
101 ppr_reg_no Wu = ppr_reg_word
102 ppr_reg_no _ = ppr_reg_long
104 ppr_reg_byte i = ptext
106 0 -> SLIT("%al"); 1 -> SLIT("%bl");
107 2 -> SLIT("%cl"); 3 -> SLIT("%dl");
108 _ -> SLIT("very naughty I386 byte register")
111 ppr_reg_word i = ptext
113 0 -> SLIT("%ax"); 1 -> SLIT("%bx");
114 2 -> SLIT("%cx"); 3 -> SLIT("%dx");
115 4 -> SLIT("%si"); 5 -> SLIT("%di");
116 6 -> SLIT("%bp"); 7 -> SLIT("%sp");
117 _ -> SLIT("very naughty I386 word register")
120 ppr_reg_long i = ptext
122 0 -> SLIT("%eax"); 1 -> SLIT("%ebx");
123 2 -> SLIT("%ecx"); 3 -> SLIT("%edx");
124 4 -> SLIT("%esi"); 5 -> SLIT("%edi");
125 6 -> SLIT("%ebp"); 7 -> SLIT("%esp");
126 8 -> SLIT("%fake0"); 9 -> SLIT("%fake1");
127 10 -> SLIT("%fake2"); 11 -> SLIT("%fake3");
128 12 -> SLIT("%fake4"); 13 -> SLIT("%fake5");
129 _ -> SLIT("very naughty I386 register")
132 #if sparc_TARGET_ARCH
133 ppr_reg_no :: Int -> Doc
136 0 -> SLIT("%g0"); 1 -> SLIT("%g1");
137 2 -> SLIT("%g2"); 3 -> SLIT("%g3");
138 4 -> SLIT("%g4"); 5 -> SLIT("%g5");
139 6 -> SLIT("%g6"); 7 -> SLIT("%g7");
140 8 -> SLIT("%o0"); 9 -> SLIT("%o1");
141 10 -> SLIT("%o2"); 11 -> SLIT("%o3");
142 12 -> SLIT("%o4"); 13 -> SLIT("%o5");
143 14 -> SLIT("%o6"); 15 -> SLIT("%o7");
144 16 -> SLIT("%l0"); 17 -> SLIT("%l1");
145 18 -> SLIT("%l2"); 19 -> SLIT("%l3");
146 20 -> SLIT("%l4"); 21 -> SLIT("%l5");
147 22 -> SLIT("%l6"); 23 -> SLIT("%l7");
148 24 -> SLIT("%i0"); 25 -> SLIT("%i1");
149 26 -> SLIT("%i2"); 27 -> SLIT("%i3");
150 28 -> SLIT("%i4"); 29 -> SLIT("%i5");
151 30 -> SLIT("%i6"); 31 -> SLIT("%i7");
152 32 -> SLIT("%f0"); 33 -> SLIT("%f1");
153 34 -> SLIT("%f2"); 35 -> SLIT("%f3");
154 36 -> SLIT("%f4"); 37 -> SLIT("%f5");
155 38 -> SLIT("%f6"); 39 -> SLIT("%f7");
156 40 -> SLIT("%f8"); 41 -> SLIT("%f9");
157 42 -> SLIT("%f10"); 43 -> SLIT("%f11");
158 44 -> SLIT("%f12"); 45 -> SLIT("%f13");
159 46 -> SLIT("%f14"); 47 -> SLIT("%f15");
160 48 -> SLIT("%f16"); 49 -> SLIT("%f17");
161 50 -> SLIT("%f18"); 51 -> SLIT("%f19");
162 52 -> SLIT("%f20"); 53 -> SLIT("%f21");
163 54 -> SLIT("%f22"); 55 -> SLIT("%f23");
164 56 -> SLIT("%f24"); 57 -> SLIT("%f25");
165 58 -> SLIT("%f26"); 59 -> SLIT("%f27");
166 60 -> SLIT("%f28"); 61 -> SLIT("%f29");
167 62 -> SLIT("%f30"); 63 -> SLIT("%f31");
168 _ -> SLIT("very naughty sparc register")
173 %************************************************************************
175 \subsection{@pprSize@: print a @Size@}
177 %************************************************************************
180 pprSize :: Size -> Doc
182 pprSize x = ptext (case x of
183 #if alpha_TARGET_ARCH
186 -- W -> SLIT("w") UNUSED
187 -- Wu -> SLIT("wu") UNUSED
190 -- FF -> SLIT("f") UNUSED
191 -- DF -> SLIT("d") UNUSED
192 -- GF -> SLIT("g") UNUSED
193 -- SF -> SLIT("s") UNUSED
207 #if sparc_TARGET_ARCH
214 pprStSize :: Size -> Doc
215 pprStSize x = ptext (case x of
225 %************************************************************************
227 \subsection{@pprCond@: print a @Cond@}
229 %************************************************************************
232 pprCond :: Cond -> Doc
234 pprCond c = ptext (case c of {
235 #if alpha_TARGET_ARCH
246 GEU -> SLIT("ae"); LU -> SLIT("b");
247 EQQ -> SLIT("e"); GTT -> SLIT("g");
248 GE -> SLIT("ge"); GU -> SLIT("a");
249 LTT -> SLIT("l"); LE -> SLIT("le");
250 LEU -> SLIT("be"); NE -> SLIT("ne");
251 NEG -> SLIT("s"); POS -> SLIT("ns");
252 ALWAYS -> SLIT("mp") -- hack
254 #if sparc_TARGET_ARCH
255 ALWAYS -> SLIT(""); NEVER -> SLIT("n");
256 GEU -> SLIT("geu"); LU -> SLIT("lu");
257 EQQ -> SLIT("e"); GTT -> SLIT("g");
258 GE -> SLIT("ge"); GU -> SLIT("gu");
259 LTT -> SLIT("l"); LE -> SLIT("le");
260 LEU -> SLIT("leu"); NE -> SLIT("ne");
261 NEG -> SLIT("neg"); POS -> SLIT("pos");
262 VC -> SLIT("vc"); VS -> SLIT("vs")
267 %************************************************************************
269 \subsection{@pprImm@: print an @Imm@}
271 %************************************************************************
276 pprImm (ImmInt i) = int i
277 pprImm (ImmInteger i) = integer i
278 pprImm (ImmCLbl l) = (if labelDynamic l then text "__imp_" else empty)
280 pprImm (ImmIndex l i) = (if labelDynamic l then text "__imp_" else empty)
281 <> pprCLabel_asm l <> char '+' <> int i
282 pprImm (ImmLit s) = s
284 pprImm (ImmLab dll s) = (if underscorePrefix then char '_' else empty)
285 <> (if dll then text "_imp__" else empty)
288 #if sparc_TARGET_ARCH
290 = hcat [ pp_lo, pprImm i, rparen ]
295 = hcat [ pp_hi, pprImm i, rparen ]
301 %************************************************************************
303 \subsection{@pprAddr@: print an @Addr@}
305 %************************************************************************
308 pprAddr :: MachRegsAddr -> Doc
310 #if alpha_TARGET_ARCH
311 pprAddr (AddrReg r) = parens (pprReg r)
312 pprAddr (AddrImm i) = pprImm i
313 pprAddr (AddrRegImm r1 i)
314 = (<>) (pprImm i) (parens (pprReg r1))
320 pprAddr (ImmAddr imm off)
321 = let pp_imm = pprImm imm
325 else if (off < 0) then
328 pp_imm <> char '+' <> int off
330 pprAddr (AddrBaseIndex base index displacement)
332 pp_disp = ppr_disp displacement
333 pp_off p = pp_disp <> char '(' <> p <> char ')'
334 pp_reg r = pprReg L r
337 (Nothing, Nothing) -> pp_disp
338 (Just b, Nothing) -> pp_off (pp_reg b)
339 (Nothing, Just (r,i)) -> pp_off (pp_reg r <> comma <> int i)
340 (Just b, Just (r,i)) -> pp_off (pp_reg b <> comma <> pp_reg r
343 ppr_disp (ImmInt 0) = empty
344 ppr_disp imm = pprImm imm
349 #if sparc_TARGET_ARCH
350 pprAddr (AddrRegReg r1 (RealReg 0)) = pprReg r1
352 pprAddr (AddrRegReg r1 r2)
353 = hcat [ pprReg r1, char '+', pprReg r2 ]
355 pprAddr (AddrRegImm r1 (ImmInt i))
357 | not (fits13Bits i) = largeOffsetError i
358 | otherwise = hcat [ pprReg r1, pp_sign, int i ]
360 pp_sign = if i > 0 then char '+' else empty
362 pprAddr (AddrRegImm r1 (ImmInteger i))
364 | not (fits13Bits i) = largeOffsetError i
365 | otherwise = hcat [ pprReg r1, pp_sign, integer i ]
367 pp_sign = if i > 0 then char '+' else empty
369 pprAddr (AddrRegImm r1 imm)
370 = hcat [ pprReg r1, char '+', pprImm imm ]
374 %************************************************************************
376 \subsection{@pprInstr@: print an @Instr@}
378 %************************************************************************
381 pprInstr :: Instr -> Doc
383 --pprInstr (COMMENT s) = empty -- nuke 'em
385 = IF_ARCH_alpha( ((<>) (ptext SLIT("\t# ")) (ptext s))
386 ,IF_ARCH_sparc( ((<>) (ptext SLIT("! ")) (ptext s))
387 ,IF_ARCH_i386( ((<>) (ptext SLIT("# ")) (ptext s))
391 = pprInstr (COMMENT (_PK_ ("\tdelta = " ++ show d)))
393 pprInstr (SEGMENT TextSegment)
394 = IF_ARCH_alpha(ptext SLIT("\t.text\n\t.align 3") {-word boundary-}
395 ,IF_ARCH_sparc(ptext SLIT(".text\n\t.align 4") {-word boundary-}
396 ,IF_ARCH_i386((text ".text\n\t.align 4,0x90") {-needs per-OS variation!-}
399 pprInstr (SEGMENT DataSegment)
401 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
402 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
403 ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
406 pprInstr (SEGMENT RoDataSegment)
408 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
409 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
410 ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
413 pprInstr (LABEL clab)
415 pp_lab = pprCLabel_asm clab
418 if not (externallyVisibleCLabel clab) then
422 IF_ARCH_alpha(SLIT("\t.globl\t")
423 ,IF_ARCH_i386(SLIT(".globl ")
424 ,IF_ARCH_sparc(SLIT(".global\t")
426 , pp_lab, char '\n'],
431 pprInstr (ASCII False{-no backslash conversion-} str)
432 = hcat [ ptext SLIT("\t.asciz "), char '\"', text str, char '"' ]
434 pprInstr (ASCII True str)
435 = vcat (map do1 (str ++ [chr 0]))
438 do1 c = ptext SLIT("\t.byte\t0x") <> hshow (ord c)
441 hshow n | n >= 0 && n <= 255
442 = char (tab !! (n `div` 16)) <> char (tab !! (n `mod` 16))
443 tab = "0123456789ABCDEF"
447 = vcat (concatMap (ppr_item s) xs)
450 #if alpha_TARGET_ARCH
451 ppr_item = error "ppr_item on Alpha"
453 #if sparc_TARGET_ARCH
454 -- copy n paste of x86 version
455 ppr_item B x = [ptext SLIT("\t.byte\t") <> pprImm x]
456 ppr_item W x = [ptext SLIT("\t.long\t") <> pprImm x]
457 ppr_item F (ImmFloat r)
458 = let bs = floatToBytes (fromRational r)
459 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
460 ppr_item DF (ImmDouble r)
461 = let bs = doubleToBytes (fromRational r)
462 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
465 ppr_item B x = [ptext SLIT("\t.byte\t") <> pprImm x]
466 ppr_item L x = [ptext SLIT("\t.long\t") <> pprImm x]
467 ppr_item F (ImmFloat r)
468 = let bs = floatToBytes (fromRational r)
469 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
470 ppr_item DF (ImmDouble r)
471 = let bs = doubleToBytes (fromRational r)
472 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
475 -- floatToBytes and doubleToBytes convert to the host's byte
476 -- order. Providing that we're not cross-compiling for a
477 -- target with the opposite endianness, this should work ok
479 floatToBytes :: Float -> [Int]
482 arr <- newFloatArray ((0::Int),3)
483 writeFloatArray arr 0 f
484 i0 <- readCharArray arr 0
485 i1 <- readCharArray arr 1
486 i2 <- readCharArray arr 2
487 i3 <- readCharArray arr 3
488 return (map ord [i0,i1,i2,i3])
491 doubleToBytes :: Double -> [Int]
494 arr <- newDoubleArray ((0::Int),7)
495 writeDoubleArray arr 0 d
496 i0 <- readCharArray arr 0
497 i1 <- readCharArray arr 1
498 i2 <- readCharArray arr 2
499 i3 <- readCharArray arr 3
500 i4 <- readCharArray arr 4
501 i5 <- readCharArray arr 5
502 i6 <- readCharArray arr 6
503 i7 <- readCharArray arr 7
504 return (map ord [i0,i1,i2,i3,i4,i5,i6,i7])
507 -- fall through to rest of (machine-specific) pprInstr...
510 %************************************************************************
512 \subsubsection{@pprInstr@ for an Alpha}
514 %************************************************************************
517 #if alpha_TARGET_ARCH
519 pprInstr (LD size reg addr)
529 pprInstr (LDA reg addr)
531 ptext SLIT("\tlda\t"),
537 pprInstr (LDAH reg addr)
539 ptext SLIT("\tldah\t"),
545 pprInstr (LDGP reg addr)
547 ptext SLIT("\tldgp\t"),
553 pprInstr (LDI size reg imm)
563 pprInstr (ST size reg addr)
575 ptext SLIT("\tclr\t"),
579 pprInstr (ABS size ri reg)
589 pprInstr (NEG size ov ri reg)
593 if ov then ptext SLIT("v\t") else char '\t',
599 pprInstr (ADD size ov reg1 ri reg2)
603 if ov then ptext SLIT("v\t") else char '\t',
611 pprInstr (SADD size scale reg1 ri reg2)
613 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
624 pprInstr (SUB size ov reg1 ri reg2)
628 if ov then ptext SLIT("v\t") else char '\t',
636 pprInstr (SSUB size scale reg1 ri reg2)
638 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
649 pprInstr (MUL size ov reg1 ri reg2)
653 if ov then ptext SLIT("v\t") else char '\t',
661 pprInstr (DIV size uns reg1 ri reg2)
665 if uns then ptext SLIT("u\t") else char '\t',
673 pprInstr (REM size uns reg1 ri reg2)
677 if uns then ptext SLIT("u\t") else char '\t',
685 pprInstr (NOT ri reg)
694 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
695 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
696 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
697 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
698 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
699 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
701 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
702 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
703 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
705 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
706 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
708 pprInstr (NOP) = ptext SLIT("\tnop")
710 pprInstr (CMP cond reg1 ri reg2)
724 ptext SLIT("\tfclr\t"),
728 pprInstr (FABS reg1 reg2)
730 ptext SLIT("\tfabs\t"),
736 pprInstr (FNEG size reg1 reg2)
746 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
747 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
748 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
749 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
751 pprInstr (CVTxy size1 size2 reg1 reg2)
755 case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
762 pprInstr (FCMP size cond reg1 reg2 reg3)
775 pprInstr (FMOV reg1 reg2)
777 ptext SLIT("\tfmov\t"),
783 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
785 pprInstr (BI NEVER reg lab) = empty
787 pprInstr (BI cond reg lab)
797 pprInstr (BF cond reg lab)
808 = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
810 pprInstr (JMP reg addr hint)
812 ptext SLIT("\tjmp\t"),
821 = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
823 pprInstr (JSR reg addr n)
825 ptext SLIT("\tjsr\t"),
831 pprInstr (FUNBEGIN clab)
833 if (externallyVisibleCLabel clab) then
834 hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
837 ptext SLIT("\t.ent "),
846 pp_lab = pprCLabel_asm clab
848 -- NEVER use commas within those string literals, cpp will ruin your day
849 pp_ldgp = hcat [ ptext SLIT(":\n\tldgp $29"), char ',', ptext SLIT("0($27)\n") ]
850 pp_frame = hcat [ ptext SLIT("..ng:\n\t.frame $30"), char ',',
851 ptext SLIT("4240"), char ',',
852 ptext SLIT("$26"), char ',',
853 ptext SLIT("0\n\t.prologue 1") ]
855 pprInstr (FUNEND clab)
856 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
859 Continue with Alpha-only printing bits and bobs:
863 pprRI (RIReg r) = pprReg r
864 pprRI (RIImm r) = pprImm r
866 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> Doc
868 pprRegRIReg name reg1 ri reg2
880 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Doc
882 pprSizeRegRegReg name size reg1 reg2 reg3
895 #endif {-alpha_TARGET_ARCH-}
898 %************************************************************************
900 \subsubsection{@pprInstr@ for an I386}
902 %************************************************************************
907 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
910 #if 0 /* #ifdef DEBUG */
911 (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
915 pprInstr (MOV size src dst)
916 = pprSizeOpOp SLIT("mov") size src dst
917 pprInstr (MOVZxL sizes src dst) = pprSizeOpOpCoerce SLIT("movz") sizes L src dst
918 pprInstr (MOVSxL sizes src dst) = pprSizeOpOpCoerce SLIT("movs") sizes L src dst
920 -- here we do some patching, since the physical registers are only set late
921 -- in the code generation.
922 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
924 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
925 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
927 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
928 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
930 = pprInstr (ADD size (OpImm displ) dst)
931 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
933 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
934 = pprSizeOp SLIT("dec") size dst
935 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
936 = pprSizeOp SLIT("inc") size dst
937 pprInstr (ADD size src dst)
938 = pprSizeOpOp SLIT("add") size src dst
939 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
940 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
942 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
943 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
944 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
945 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
946 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
948 pprInstr (SHL size imm dst) = pprSizeImmOp SLIT("shl") size imm dst
949 pprInstr (SAR size imm dst) = pprSizeImmOp SLIT("sar") size imm dst
950 pprInstr (SHR size imm dst) = pprSizeImmOp SLIT("shr") size imm dst
951 pprInstr (BT size imm src) = pprSizeImmOp SLIT("bt") size imm src
953 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
954 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
955 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
956 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
957 pprInstr PUSHA = ptext SLIT("\tpushal")
958 pprInstr POPA = ptext SLIT("\tpopal")
960 pprInstr (NOP) = ptext SLIT("\tnop")
961 pprInstr (CLTD) = ptext SLIT("\tcltd")
963 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
965 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
967 pprInstr (JMP dsts (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
968 pprInstr (JMP dsts op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand L op)
969 pprInstr (CALL imm) = (<>) (ptext SLIT("\tcall ")) (pprImm imm)
971 pprInstr (IQUOT sz src dst) = pprInstr_quotRem True sz src dst
972 pprInstr (IREM sz src dst) = pprInstr_quotRem False sz src dst
974 -- Simulating a flat register set on the x86 FP stack is tricky.
975 -- you have to free %st(7) before pushing anything on the FP reg stack
976 -- so as to preclude the possibility of a FP stack overflow exception.
977 pprInstr g@(GMOV src dst)
981 = pprG g (hcat [gtab, gpush src 0, gsemi, gpop dst 1])
983 -- GLD sz addr dst ==> FFREE %st(7) ; FLDsz addr ; FSTP (dst+1)
984 pprInstr g@(GLD sz addr dst)
985 = pprG g (hcat [gtab, text "ffree %st(7) ; fld", pprSize sz, gsp,
986 pprAddr addr, gsemi, gpop dst 1])
988 -- GST sz src addr ==> FFREE %st(7) ; FLD dst ; FSTPsz addr
989 pprInstr g@(GST sz src addr)
990 = pprG g (hcat [gtab, gpush src 0, gsemi,
991 text "fstp", pprSize sz, gsp, pprAddr addr])
993 pprInstr g@(GLDZ dst)
994 = pprG g (hcat [gtab, text "ffree %st(7) ; fldz ; ", gpop dst 1])
995 pprInstr g@(GLD1 dst)
996 = pprG g (hcat [gtab, text "ffree %st(7) ; fld1 ; ", gpop dst 1])
998 pprInstr g@(GFTOD src dst)
1000 pprInstr g@(GFTOI src dst)
1003 pprInstr g@(GDTOF src dst)
1005 pprInstr g@(GDTOI src dst)
1008 pprInstr g@(GITOF src dst)
1009 = pprInstr (GITOD src dst)
1010 pprInstr g@(GITOD src dst)
1011 = pprG g (hcat [gtab, text "pushl ", pprReg L src,
1012 text " ; ffree %st(7); fildl (%esp) ; ",
1013 gpop dst 1, text " ; addl $4,%esp"])
1015 pprInstr g@(GCMP sz src1 src2)
1016 = pprG g (hcat [gtab, text "pushl %eax ; ",gpush src1 0]
1018 hcat [gtab, text "fcomp ", greg src2 1,
1019 text "; fstsw %ax ; sahf ; popl %eax"])
1021 pprInstr g@(GABS sz src dst)
1022 = pprG g (hcat [gtab, gpush src 0, text " ; fabs ; ", gpop dst 1])
1023 pprInstr g@(GNEG sz src dst)
1024 = pprG g (hcat [gtab, gpush src 0, text " ; fchs ; ", gpop dst 1])
1026 pprInstr g@(GSQRT sz src dst)
1027 = pprG g (hcat [gtab, gpush src 0, text " ; fsqrt"] $$
1028 hcat [gtab, gcoerceto sz, gpop dst 1])
1029 pprInstr g@(GSIN sz src dst)
1030 = pprG g (hcat [gtab, gpush src 0, text " ; fsin"] $$
1031 hcat [gtab, gcoerceto sz, gpop dst 1])
1032 pprInstr g@(GCOS sz src dst)
1033 = pprG g (hcat [gtab, gpush src 0, text " ; fcos"] $$
1034 hcat [gtab, gcoerceto sz, gpop dst 1])
1035 pprInstr g@(GTAN sz src dst)
1036 = pprG g (hcat [gtab, text "ffree %st(6) ; ",
1037 gpush src 0, text " ; fptan ; ",
1038 text " fstp %st(0)"] $$
1039 hcat [gtab, gcoerceto sz, gpop dst 1])
1041 -- In the translations for GADD, GMUL, GSUB and GDIV,
1042 -- the first two cases are mere optimisations. The otherwise clause
1043 -- generates correct code under all circumstances.
1045 pprInstr g@(GADD sz src1 src2 dst)
1047 = pprG g (text "\t#GADD-xxxcase1" $$
1048 hcat [gtab, gpush src2 0,
1049 text " ; faddp %st(0),", greg src1 1])
1051 = pprG g (text "\t#GADD-xxxcase2" $$
1052 hcat [gtab, gpush src1 0,
1053 text " ; faddp %st(0),", greg src2 1])
1055 = pprG g (hcat [gtab, gpush src1 0,
1056 text " ; fadd ", greg src2 1, text ",%st(0)",
1060 pprInstr g@(GMUL sz src1 src2 dst)
1062 = pprG g (text "\t#GMUL-xxxcase1" $$
1063 hcat [gtab, gpush src2 0,
1064 text " ; fmulp %st(0),", greg src1 1])
1066 = pprG g (text "\t#GMUL-xxxcase2" $$
1067 hcat [gtab, gpush src1 0,
1068 text " ; fmulp %st(0),", greg src2 1])
1070 = pprG g (hcat [gtab, gpush src1 0,
1071 text " ; fmul ", greg src2 1, text ",%st(0)",
1075 pprInstr g@(GSUB sz src1 src2 dst)
1077 = pprG g (text "\t#GSUB-xxxcase1" $$
1078 hcat [gtab, gpush src2 0,
1079 text " ; fsubrp %st(0),", greg src1 1])
1081 = pprG g (text "\t#GSUB-xxxcase2" $$
1082 hcat [gtab, gpush src1 0,
1083 text " ; fsubp %st(0),", greg src2 1])
1085 = pprG g (hcat [gtab, gpush src1 0,
1086 text " ; fsub ", greg src2 1, text ",%st(0)",
1090 pprInstr g@(GDIV sz src1 src2 dst)
1092 = pprG g (text "\t#GDIV-xxxcase1" $$
1093 hcat [gtab, gpush src2 0,
1094 text " ; fdivrp %st(0),", greg src1 1])
1096 = pprG g (text "\t#GDIV-xxxcase2" $$
1097 hcat [gtab, gpush src1 0,
1098 text " ; fdivp %st(0),", greg src2 1])
1100 = pprG g (hcat [gtab, gpush src1 0,
1101 text " ; fdiv ", greg src2 1, text ",%st(0)",
1106 = vcat [ ptext SLIT("\tffree %st(0) ;ffree %st(1) ;ffree %st(2) ;ffree %st(3)"),
1107 ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)")
1111 pprInstr_quotRem isQuot sz src dst
1112 | case sz of L -> False; _ -> True
1113 = panic "pprInstr_quotRem: dunno how to do non-32bit operands"
1116 (text "\t# BEGIN " <> fakeInsn),
1117 (text "\tpushl $0; pushl %eax; pushl %edx; pushl " <> pprOperand sz src),
1118 (text "\tmovl " <> pprOperand sz dst <> text ",%eax; xorl %edx,%edx; cltd"),
1119 (text "\tdivl 0(%esp); movl " <> text resReg <> text ",12(%esp)"),
1120 (text "\tpopl %edx; popl %edx; popl %eax; popl " <> pprOperand sz dst),
1121 (text "\t# END " <> fakeInsn)
1124 resReg = if isQuot then "%eax" else "%edx"
1125 opStr = if isQuot then "IQUOT" else "IREM"
1126 fakeInsn = text opStr <+> pprOperand sz src <> char ',' <+> pprOperand sz dst
1128 --------------------------
1130 -- coerce %st(0) to the specified size
1131 gcoerceto DF = empty
1132 gcoerceto F = text "subl $4,%esp ; fstps (%esp) ; flds (%esp) ; addl $4,%esp ; "
1135 = hcat [text "ffree %st(7) ; fld ", greg reg offset]
1137 = hcat [text "fstp ", greg reg offset]
1139 bogus = text "\tbogus"
1140 greg reg offset = text "%st(" <> int (gregno reg - 8+offset) <> char ')'
1145 gregno (RealReg i) = i
1146 gregno other = --pprPanic "gregno" (ppr other)
1147 999 -- bogus; only needed for debug printing
1149 pprG :: Instr -> Doc -> Doc
1151 = (char '#' <> pprGInstr fake) $$ actual
1153 pprGInstr (GMOV src dst) = pprSizeRegReg SLIT("gmov") DF src dst
1154 pprGInstr (GLD sz src dst) = pprSizeAddrReg SLIT("gld") sz src dst
1155 pprGInstr (GST sz src dst) = pprSizeRegAddr SLIT("gst") sz src dst
1157 pprGInstr (GLDZ dst) = pprSizeReg SLIT("gldz") DF dst
1158 pprGInstr (GLD1 dst) = pprSizeReg SLIT("gld1") DF dst
1160 pprGInstr (GFTOD src dst) = pprSizeSizeRegReg SLIT("gftod") F DF src dst
1161 pprGInstr (GFTOI src dst) = pprSizeSizeRegReg SLIT("gftoi") F L src dst
1163 pprGInstr (GDTOF src dst) = pprSizeSizeRegReg SLIT("gdtof") DF F src dst
1164 pprGInstr (GDTOI src dst) = pprSizeSizeRegReg SLIT("gdtoi") DF L src dst
1166 pprGInstr (GITOF src dst) = pprSizeSizeRegReg SLIT("gitof") L F src dst
1167 pprGInstr (GITOD src dst) = pprSizeSizeRegReg SLIT("gitod") L DF src dst
1169 pprGInstr (GCMP sz src dst) = pprSizeRegReg SLIT("gcmp") sz src dst
1170 pprGInstr (GABS sz src dst) = pprSizeRegReg SLIT("gabs") sz src dst
1171 pprGInstr (GNEG sz src dst) = pprSizeRegReg SLIT("gneg") sz src dst
1172 pprGInstr (GSQRT sz src dst) = pprSizeRegReg SLIT("gsqrt") sz src dst
1173 pprGInstr (GSIN sz src dst) = pprSizeRegReg SLIT("gsin") sz src dst
1174 pprGInstr (GCOS sz src dst) = pprSizeRegReg SLIT("gcos") sz src dst
1175 pprGInstr (GTAN sz src dst) = pprSizeRegReg SLIT("gtan") sz src dst
1177 pprGInstr (GADD sz src1 src2 dst) = pprSizeRegRegReg SLIT("gadd") sz src1 src2 dst
1178 pprGInstr (GSUB sz src1 src2 dst) = pprSizeRegRegReg SLIT("gsub") sz src1 src2 dst
1179 pprGInstr (GMUL sz src1 src2 dst) = pprSizeRegRegReg SLIT("gmul") sz src1 src2 dst
1180 pprGInstr (GDIV sz src1 src2 dst) = pprSizeRegRegReg SLIT("gdiv") sz src1 src2 dst
1183 Continue with I386-only printing bits and bobs:
1185 pprDollImm :: Imm -> Doc
1187 pprDollImm i = ptext SLIT("$") <> pprImm i
1189 pprOperand :: Size -> Operand -> Doc
1190 pprOperand s (OpReg r) = pprReg s r
1191 pprOperand s (OpImm i) = pprDollImm i
1192 pprOperand s (OpAddr ea) = pprAddr ea
1194 pprSizeImmOp :: FAST_STRING -> Size -> Imm -> Operand -> Doc
1195 pprSizeImmOp name size imm op1
1207 pprSizeOp :: FAST_STRING -> Size -> Operand -> Doc
1208 pprSizeOp name size op1
1217 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Doc
1218 pprSizeOpOp name size op1 op2
1224 pprOperand size op1,
1229 pprSizeByteOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Doc
1230 pprSizeByteOpOp name size op1 op2
1241 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> Doc
1242 pprSizeOpReg name size op1 reg
1248 pprOperand size op1,
1253 pprSizeReg :: FAST_STRING -> Size -> Reg -> Doc
1254 pprSizeReg name size reg1
1263 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Doc
1264 pprSizeRegReg name size reg1 reg2
1275 pprSizeSizeRegReg :: FAST_STRING -> Size -> Size -> Reg -> Reg -> Doc
1276 pprSizeSizeRegReg name size1 size2 reg1 reg2
1288 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Doc
1289 pprSizeRegRegReg name size reg1 reg2 reg3
1302 pprSizeAddr :: FAST_STRING -> Size -> MachRegsAddr -> Doc
1303 pprSizeAddr name size op
1312 pprSizeAddrReg :: FAST_STRING -> Size -> MachRegsAddr -> Reg -> Doc
1313 pprSizeAddrReg name size op dst
1324 pprSizeRegAddr :: FAST_STRING -> Size -> Reg -> MachRegsAddr -> Doc
1325 pprSizeRegAddr name size src op
1336 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Doc
1337 pprOpOp name size op1 op2
1341 pprOperand size op1,
1346 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> Doc
1347 pprSizeOpOpCoerce name size1 size2 op1 op2
1348 = hcat [ char '\t', ptext name, pprSize size1, pprSize size2, space,
1349 pprOperand size1 op1,
1351 pprOperand size2 op2
1354 pprCondInstr :: FAST_STRING -> Cond -> Doc -> Doc
1355 pprCondInstr name cond arg
1356 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1358 #endif {-i386_TARGET_ARCH-}
1361 %************************************************************************
1363 \subsubsection{@pprInstr@ for a SPARC}
1365 %************************************************************************
1368 #if sparc_TARGET_ARCH
1370 -- a clumsy hack for now, to handle possible double alignment problems
1372 -- even clumsier, to allow for RegReg regs that show when doing indexed
1373 -- reads (bytearrays).
1376 -- Translate to the following:
1379 -- ld [g1+4],%f(n+1)
1380 -- sub g1,g2,g1 -- to restore g1
1381 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1383 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1384 hcat [pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg],
1385 hcat [pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)],
1386 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1391 -- ld [addr+4],%f(n+1)
1392 pprInstr (LD DF addr reg) | isJust off_addr
1394 hcat [pp_ld_lbracket, pprAddr addr, pp_rbracket_comma, pprReg reg],
1395 hcat [pp_ld_lbracket, pprAddr addr2, pp_rbracket_comma,pprReg (fPair reg)]
1398 off_addr = addrOffset addr 4
1399 addr2 = case off_addr of Just x -> x
1402 pprInstr (LD size addr reg)
1413 -- The same clumsy hack as above
1415 -- Translate to the following:
1418 -- st %f(n+1),[g1+4]
1419 -- sub g1,g2,g1 -- to restore g1
1420 pprInstr (ST DF reg (AddrRegReg g1 g2))
1422 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1423 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1425 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1426 pprReg g1, ptext SLIT("+4]")],
1427 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1432 -- st %f(n+1),[addr+4]
1433 pprInstr (ST DF reg addr) | isJust off_addr
1435 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1436 pprAddr addr, rbrack],
1437 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1438 pprAddr addr2, rbrack]
1441 off_addr = addrOffset addr 4
1442 addr2 = case off_addr of Just x -> x
1444 -- no distinction is made between signed and unsigned bytes on stores for the
1445 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1446 -- so we call a special-purpose pprSize for ST..
1448 pprInstr (ST size reg addr)
1459 pprInstr (ADD x cc reg1 ri reg2)
1460 | not x && not cc && riZero ri
1461 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1463 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1465 pprInstr (SUB x cc reg1 ri reg2)
1466 | not x && cc && reg2 == g0
1467 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1468 | not x && not cc && riZero ri
1469 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1471 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1473 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1474 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1476 pprInstr (OR b reg1 ri reg2)
1477 | not b && reg1 == g0
1478 = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1480 = pprRegRIReg SLIT("or") b reg1 ri reg2
1482 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1484 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1485 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1487 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1488 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1489 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1491 pprInstr (SETHI imm reg)
1493 ptext SLIT("\tsethi\t"),
1499 pprInstr NOP = ptext SLIT("\tnop")
1501 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1502 pprInstr (FABS DF reg1 reg2)
1503 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1504 (if (reg1 == reg2) then empty
1505 else (<>) (char '\n')
1506 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1508 pprInstr (FADD size reg1 reg2 reg3)
1509 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1510 pprInstr (FCMP e size reg1 reg2)
1511 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1512 pprInstr (FDIV size reg1 reg2 reg3)
1513 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1515 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1516 pprInstr (FMOV DF reg1 reg2)
1517 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1518 (if (reg1 == reg2) then empty
1519 else (<>) (char '\n')
1520 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1522 pprInstr (FMUL size reg1 reg2 reg3)
1523 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1525 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1526 pprInstr (FNEG DF reg1 reg2)
1527 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1528 (if (reg1 == reg2) then empty
1529 else (<>) (char '\n')
1530 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1532 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1533 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1534 pprInstr (FxTOy size1 size2 reg1 reg2)
1547 pprReg reg1, comma, pprReg reg2
1551 pprInstr (BI cond b lab)
1553 ptext SLIT("\tb"), pprCond cond,
1554 if b then pp_comma_a else empty,
1559 pprInstr (BF cond b lab)
1561 ptext SLIT("\tfb"), pprCond cond,
1562 if b then pp_comma_a else empty,
1567 pprInstr (JMP dsts addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1569 pprInstr (CALL imm n _)
1570 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1573 Continue with SPARC-only printing bits and bobs:
1576 pprRI (RIReg r) = pprReg r
1577 pprRI (RIImm r) = pprImm r
1579 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Doc
1580 pprSizeRegReg name size reg1 reg2
1585 F -> ptext SLIT("s\t")
1586 DF -> ptext SLIT("d\t")),
1592 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Doc
1593 pprSizeRegRegReg name size reg1 reg2 reg3
1598 F -> ptext SLIT("s\t")
1599 DF -> ptext SLIT("d\t")),
1607 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> Doc
1608 pprRegRIReg name b reg1 ri reg2
1612 if b then ptext SLIT("cc\t") else char '\t',
1620 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> Doc
1621 pprRIReg name b ri reg1
1625 if b then ptext SLIT("cc\t") else char '\t',
1631 pp_ld_lbracket = ptext SLIT("\tld\t[")
1632 pp_rbracket_comma = text "],"
1633 pp_comma_lbracket = text ",["
1634 pp_comma_a = text ",a"
1636 #endif {-sparc_TARGET_ARCH-}