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, labelDynamic )
21 import Stix ( CodeSegment(..) )
26 import Char ( chr, ord )
27 import Maybe ( isJust )
30 %************************************************************************
32 \subsection{@pprReg@: print a @Reg@}
34 %************************************************************************
36 For x86, the way we print a register name depends
37 on which bit of it we care about. Yurgh.
39 pprUserReg:: Reg -> SDoc
40 pprUserReg = pprReg IF_ARCH_i386(L,)
43 pprReg :: IF_ARCH_i386(Size ->,) Reg -> SDoc
45 pprReg IF_ARCH_i386(s,) r
47 RealReg i -> ppr_reg_no IF_ARCH_i386(s,) i
48 VirtualRegI u -> text "%vI_" <> ppr u
49 VirtualRegF u -> text "%vF_" <> ppr u
52 ppr_reg_no :: Int -> SDoc
55 0 -> SLIT("$0"); 1 -> SLIT("$1");
56 2 -> SLIT("$2"); 3 -> SLIT("$3");
57 4 -> SLIT("$4"); 5 -> SLIT("$5");
58 6 -> SLIT("$6"); 7 -> SLIT("$7");
59 8 -> SLIT("$8"); 9 -> SLIT("$9");
60 10 -> SLIT("$10"); 11 -> SLIT("$11");
61 12 -> SLIT("$12"); 13 -> SLIT("$13");
62 14 -> SLIT("$14"); 15 -> SLIT("$15");
63 16 -> SLIT("$16"); 17 -> SLIT("$17");
64 18 -> SLIT("$18"); 19 -> SLIT("$19");
65 20 -> SLIT("$20"); 21 -> SLIT("$21");
66 22 -> SLIT("$22"); 23 -> SLIT("$23");
67 24 -> SLIT("$24"); 25 -> SLIT("$25");
68 26 -> SLIT("$26"); 27 -> SLIT("$27");
69 28 -> SLIT("$28"); 29 -> SLIT("$29");
70 30 -> SLIT("$30"); 31 -> SLIT("$31");
71 32 -> SLIT("$f0"); 33 -> SLIT("$f1");
72 34 -> SLIT("$f2"); 35 -> SLIT("$f3");
73 36 -> SLIT("$f4"); 37 -> SLIT("$f5");
74 38 -> SLIT("$f6"); 39 -> SLIT("$f7");
75 40 -> SLIT("$f8"); 41 -> SLIT("$f9");
76 42 -> SLIT("$f10"); 43 -> SLIT("$f11");
77 44 -> SLIT("$f12"); 45 -> SLIT("$f13");
78 46 -> SLIT("$f14"); 47 -> SLIT("$f15");
79 48 -> SLIT("$f16"); 49 -> SLIT("$f17");
80 50 -> SLIT("$f18"); 51 -> SLIT("$f19");
81 52 -> SLIT("$f20"); 53 -> SLIT("$f21");
82 54 -> SLIT("$f22"); 55 -> SLIT("$f23");
83 56 -> SLIT("$f24"); 57 -> SLIT("$f25");
84 58 -> SLIT("$f26"); 59 -> SLIT("$f27");
85 60 -> SLIT("$f28"); 61 -> SLIT("$f29");
86 62 -> SLIT("$f30"); 63 -> SLIT("$f31");
87 _ -> SLIT("very naughty alpha register")
91 ppr_reg_no :: Size -> Int -> SDoc
94 0 -> SLIT("%al"); 1 -> SLIT("%bl");
95 2 -> SLIT("%cl"); 3 -> SLIT("%dl");
96 _ -> SLIT("very naughty I386 byte register")
99 ppr_reg_no _ i = ptext
101 0 -> SLIT("%eax"); 1 -> SLIT("%ebx");
102 2 -> SLIT("%ecx"); 3 -> SLIT("%edx");
103 4 -> SLIT("%esi"); 5 -> SLIT("%edi");
104 6 -> SLIT("%ebp"); 7 -> SLIT("%esp");
105 8 -> SLIT("%fake0"); 9 -> SLIT("%fake1");
106 10 -> SLIT("%fake2"); 11 -> SLIT("%fake3");
107 12 -> SLIT("%fake4"); 13 -> SLIT("%fake5");
108 _ -> SLIT("very naughty I386 register")
111 #if sparc_TARGET_ARCH
112 ppr_reg_no :: Int -> SDoc
115 0 -> SLIT("%g0"); 1 -> SLIT("%g1");
116 2 -> SLIT("%g2"); 3 -> SLIT("%g3");
117 4 -> SLIT("%g4"); 5 -> SLIT("%g5");
118 6 -> SLIT("%g6"); 7 -> SLIT("%g7");
119 8 -> SLIT("%o0"); 9 -> SLIT("%o1");
120 10 -> SLIT("%o2"); 11 -> SLIT("%o3");
121 12 -> SLIT("%o4"); 13 -> SLIT("%o5");
122 14 -> SLIT("%o6"); 15 -> SLIT("%o7");
123 16 -> SLIT("%l0"); 17 -> SLIT("%l1");
124 18 -> SLIT("%l2"); 19 -> SLIT("%l3");
125 20 -> SLIT("%l4"); 21 -> SLIT("%l5");
126 22 -> SLIT("%l6"); 23 -> SLIT("%l7");
127 24 -> SLIT("%i0"); 25 -> SLIT("%i1");
128 26 -> SLIT("%i2"); 27 -> SLIT("%i3");
129 28 -> SLIT("%i4"); 29 -> SLIT("%i5");
130 30 -> SLIT("%i6"); 31 -> SLIT("%i7");
131 32 -> SLIT("%f0"); 33 -> SLIT("%f1");
132 34 -> SLIT("%f2"); 35 -> SLIT("%f3");
133 36 -> SLIT("%f4"); 37 -> SLIT("%f5");
134 38 -> SLIT("%f6"); 39 -> SLIT("%f7");
135 40 -> SLIT("%f8"); 41 -> SLIT("%f9");
136 42 -> SLIT("%f10"); 43 -> SLIT("%f11");
137 44 -> SLIT("%f12"); 45 -> SLIT("%f13");
138 46 -> SLIT("%f14"); 47 -> SLIT("%f15");
139 48 -> SLIT("%f16"); 49 -> SLIT("%f17");
140 50 -> SLIT("%f18"); 51 -> SLIT("%f19");
141 52 -> SLIT("%f20"); 53 -> SLIT("%f21");
142 54 -> SLIT("%f22"); 55 -> SLIT("%f23");
143 56 -> SLIT("%f24"); 57 -> SLIT("%f25");
144 58 -> SLIT("%f26"); 59 -> SLIT("%f27");
145 60 -> SLIT("%f28"); 61 -> SLIT("%f29");
146 62 -> SLIT("%f30"); 63 -> SLIT("%f31");
147 _ -> SLIT("very naughty sparc register")
152 %************************************************************************
154 \subsection{@pprSize@: print a @Size@}
156 %************************************************************************
159 pprSize :: Size -> SDoc
161 pprSize x = ptext (case x of
162 #if alpha_TARGET_ARCH
165 -- W -> SLIT("w") UNUSED
166 -- WU -> SLIT("wu") UNUSED
169 -- FF -> SLIT("f") UNUSED
170 -- DF -> SLIT("d") UNUSED
171 -- GF -> SLIT("g") UNUSED
172 -- SF -> SLIT("s") UNUSED
177 -- HB -> SLIT("b") UNUSED
178 -- S -> SLIT("w") UNUSED
184 #if sparc_TARGET_ARCH
187 -- HW -> SLIT("hw") UNUSED
188 -- HWU -> SLIT("uhw") UNUSED
191 -- D -> SLIT("d") UNUSED
194 pprStSize :: Size -> SDoc
195 pprStSize x = ptext (case x of
198 -- HW -> SLIT("hw") UNUSED
199 -- HWU -> SLIT("uhw") UNUSED
202 -- D -> SLIT("d") UNUSED
208 %************************************************************************
210 \subsection{@pprCond@: print a @Cond@}
212 %************************************************************************
215 pprCond :: Cond -> SDoc
217 pprCond c = ptext (case c of {
218 #if alpha_TARGET_ARCH
229 GEU -> SLIT("ae"); LU -> SLIT("b");
230 EQQ -> SLIT("e"); GTT -> SLIT("g");
231 GE -> SLIT("ge"); GU -> SLIT("a");
232 LTT -> SLIT("l"); LE -> SLIT("le");
233 LEU -> SLIT("be"); NE -> SLIT("ne");
234 NEG -> SLIT("s"); POS -> SLIT("ns");
235 ALWAYS -> SLIT("mp") -- hack
237 #if sparc_TARGET_ARCH
238 ALWAYS -> SLIT(""); NEVER -> SLIT("n");
239 GEU -> SLIT("geu"); LU -> SLIT("lu");
240 EQQ -> SLIT("e"); GTT -> SLIT("g");
241 GE -> SLIT("ge"); GU -> SLIT("gu");
242 LTT -> SLIT("l"); LE -> SLIT("le");
243 LEU -> SLIT("leu"); NE -> SLIT("ne");
244 NEG -> SLIT("neg"); POS -> SLIT("pos");
245 VC -> SLIT("vc"); VS -> SLIT("vs")
250 %************************************************************************
252 \subsection{@pprImm@: print an @Imm@}
254 %************************************************************************
257 pprImm :: Imm -> SDoc
259 pprImm (ImmInt i) = int i
260 pprImm (ImmInteger i) = integer i
261 pprImm (ImmCLbl l) = (if labelDynamic l then text "__imp_" else empty)
263 pprImm (ImmIndex l i) = (if labelDynamic l then text "__imp_" else empty)
264 <> pprCLabel_asm l <> char '+' <> int i
265 pprImm (ImmLit s) = s
267 pprImm (ImmLab dll s) = (if underscorePrefix then char '_' else empty)
268 <> (if dll then text "_imp__" else empty)
271 #if sparc_TARGET_ARCH
273 = hcat [ pp_lo, pprImm i, rparen ]
278 = hcat [ pp_hi, pprImm i, rparen ]
284 %************************************************************************
286 \subsection{@pprAddr@: print an @Addr@}
288 %************************************************************************
291 pprAddr :: MachRegsAddr -> SDoc
293 #if alpha_TARGET_ARCH
294 pprAddr (AddrReg r) = parens (pprReg r)
295 pprAddr (AddrImm i) = pprImm i
296 pprAddr (AddrRegImm r1 i)
297 = (<>) (pprImm i) (parens (pprReg r1))
303 pprAddr (ImmAddr imm off)
304 = let pp_imm = pprImm imm
308 else if (off < 0) then
311 pp_imm <> char '+' <> int off
313 pprAddr (AddrBaseIndex base index displacement)
315 pp_disp = ppr_disp displacement
316 pp_off p = pp_disp <> char '(' <> p <> char ')'
317 pp_reg r = pprReg L r
320 (Nothing, Nothing) -> pp_disp
321 (Just b, Nothing) -> pp_off (pp_reg b)
322 (Nothing, Just (r,i)) -> pp_off (pp_reg r <> comma <> int i)
323 (Just b, Just (r,i)) -> pp_off (pp_reg b <> comma <> pp_reg r
326 ppr_disp (ImmInt 0) = empty
327 ppr_disp imm = pprImm imm
332 #if sparc_TARGET_ARCH
333 pprAddr (AddrRegReg r1 (RealReg 0)) = pprReg r1
335 pprAddr (AddrRegReg r1 r2)
336 = hcat [ pprReg r1, char '+', pprReg r2 ]
338 pprAddr (AddrRegImm r1 (ImmInt i))
340 | not (fits13Bits i) = largeOffsetError i
341 | otherwise = hcat [ pprReg r1, pp_sign, int i ]
343 pp_sign = if i > 0 then char '+' else empty
345 pprAddr (AddrRegImm r1 (ImmInteger i))
347 | not (fits13Bits i) = largeOffsetError i
348 | otherwise = hcat [ pprReg r1, pp_sign, integer i ]
350 pp_sign = if i > 0 then char '+' else empty
352 pprAddr (AddrRegImm r1 imm)
353 = hcat [ pprReg r1, char '+', pprImm imm ]
357 %************************************************************************
359 \subsection{@pprInstr@: print an @Instr@}
361 %************************************************************************
364 pprInstr :: Instr -> SDoc
366 --pprInstr (COMMENT s) = empty -- nuke 'em
368 = IF_ARCH_alpha( ((<>) (ptext SLIT("\t# ")) (ptext s))
369 ,IF_ARCH_sparc( ((<>) (ptext SLIT("! ")) (ptext s))
370 ,IF_ARCH_i386( ((<>) (ptext SLIT("# ")) (ptext s))
374 = pprInstr (COMMENT (_PK_ ("\tdelta = " ++ show d)))
376 pprInstr (SEGMENT TextSegment)
377 = IF_ARCH_alpha(ptext SLIT("\t.text\n\t.align 3") {-word boundary-}
378 ,IF_ARCH_sparc(ptext SLIT(".text\n\t.align 4") {-word boundary-}
379 ,IF_ARCH_i386((text ".text\n\t.align 4,0x90") {-needs per-OS variation!-}
382 pprInstr (SEGMENT DataSegment)
384 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
385 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
386 ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
389 pprInstr (SEGMENT RoDataSegment)
391 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
392 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
393 ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
396 pprInstr (LABEL clab)
398 pp_lab = pprCLabel_asm clab
401 if not (externallyVisibleCLabel clab) then
405 IF_ARCH_alpha(SLIT("\t.globl\t")
406 ,IF_ARCH_i386(SLIT(".globl ")
407 ,IF_ARCH_sparc(SLIT(".global\t")
409 , pp_lab, char '\n'],
414 pprInstr (ASCII False{-no backslash conversion-} str)
415 = hcat [ ptext SLIT("\t.asciz "), char '\"', text str, char '"' ]
417 pprInstr (ASCII True str)
418 = vcat (map do1 (str ++ [chr 0]))
421 do1 c = ptext SLIT("\t.byte\t0x") <> hshow (ord c)
424 hshow n | n >= 0 && n <= 255
425 = char (tab !! (n `div` 16)) <> char (tab !! (n `mod` 16))
426 tab = "0123456789ABCDEF"
430 = vcat (concatMap (ppr_item s) xs)
433 #if alpha_TARGET_ARCH
434 ppr_item = error "ppr_item on Alpha"
436 #if sparc_TARGET_ARCH
437 -- copy n paste of x86 version
438 ppr_item B x = [ptext SLIT("\t.byte\t") <> pprImm x]
439 ppr_item W x = [ptext SLIT("\t.long\t") <> pprImm x]
440 ppr_item F (ImmFloat r)
441 = let bs = floatToBytes (fromRational r)
442 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
443 ppr_item DF (ImmDouble r)
444 = let bs = doubleToBytes (fromRational r)
445 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
448 ppr_item B x = [ptext SLIT("\t.byte\t") <> pprImm x]
449 ppr_item L x = [ptext SLIT("\t.long\t") <> pprImm x]
450 ppr_item F (ImmFloat r)
451 = let bs = floatToBytes (fromRational r)
452 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
453 ppr_item DF (ImmDouble r)
454 = let bs = doubleToBytes (fromRational r)
455 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
458 -- floatToBytes and doubleToBytes convert to the host's byte
459 -- order. Providing that we're not cross-compiling for a
460 -- target with the opposite endianness, this should work ok
462 floatToBytes :: Float -> [Int]
465 arr <- newFloatArray ((0::Int),3)
466 writeFloatArray arr 0 f
467 i0 <- readCharArray arr 0
468 i1 <- readCharArray arr 1
469 i2 <- readCharArray arr 2
470 i3 <- readCharArray arr 3
471 return (map ord [i0,i1,i2,i3])
474 doubleToBytes :: Double -> [Int]
477 arr <- newDoubleArray ((0::Int),7)
478 writeDoubleArray arr 0 d
479 i0 <- readCharArray arr 0
480 i1 <- readCharArray arr 1
481 i2 <- readCharArray arr 2
482 i3 <- readCharArray arr 3
483 i4 <- readCharArray arr 4
484 i5 <- readCharArray arr 5
485 i6 <- readCharArray arr 6
486 i7 <- readCharArray arr 7
487 return (map ord [i0,i1,i2,i3,i4,i5,i6,i7])
490 -- fall through to rest of (machine-specific) pprInstr...
493 %************************************************************************
495 \subsubsection{@pprInstr@ for an Alpha}
497 %************************************************************************
500 #if alpha_TARGET_ARCH
502 pprInstr (LD size reg addr)
512 pprInstr (LDA reg addr)
514 ptext SLIT("\tlda\t"),
520 pprInstr (LDAH reg addr)
522 ptext SLIT("\tldah\t"),
528 pprInstr (LDGP reg addr)
530 ptext SLIT("\tldgp\t"),
536 pprInstr (LDI size reg imm)
546 pprInstr (ST size reg addr)
558 ptext SLIT("\tclr\t"),
562 pprInstr (ABS size ri reg)
572 pprInstr (NEG size ov ri reg)
576 if ov then ptext SLIT("v\t") else char '\t',
582 pprInstr (ADD size ov reg1 ri reg2)
586 if ov then ptext SLIT("v\t") else char '\t',
594 pprInstr (SADD size scale reg1 ri reg2)
596 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
607 pprInstr (SUB size ov reg1 ri reg2)
611 if ov then ptext SLIT("v\t") else char '\t',
619 pprInstr (SSUB size scale reg1 ri reg2)
621 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
632 pprInstr (MUL size ov reg1 ri reg2)
636 if ov then ptext SLIT("v\t") else char '\t',
644 pprInstr (DIV size uns reg1 ri reg2)
648 if uns then ptext SLIT("u\t") else char '\t',
656 pprInstr (REM size uns reg1 ri reg2)
660 if uns then ptext SLIT("u\t") else char '\t',
668 pprInstr (NOT ri reg)
677 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
678 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
679 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
680 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
681 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
682 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
684 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
685 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
686 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
688 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
689 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
691 pprInstr (NOP) = ptext SLIT("\tnop")
693 pprInstr (CMP cond reg1 ri reg2)
707 ptext SLIT("\tfclr\t"),
711 pprInstr (FABS reg1 reg2)
713 ptext SLIT("\tfabs\t"),
719 pprInstr (FNEG size reg1 reg2)
729 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
730 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
731 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
732 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
734 pprInstr (CVTxy size1 size2 reg1 reg2)
738 case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
745 pprInstr (FCMP size cond reg1 reg2 reg3)
758 pprInstr (FMOV reg1 reg2)
760 ptext SLIT("\tfmov\t"),
766 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
768 pprInstr (BI NEVER reg lab) = empty
770 pprInstr (BI cond reg lab)
780 pprInstr (BF cond reg lab)
791 = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
793 pprInstr (JMP reg addr hint)
795 ptext SLIT("\tjmp\t"),
804 = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
806 pprInstr (JSR reg addr n)
808 ptext SLIT("\tjsr\t"),
814 pprInstr (FUNBEGIN clab)
816 if (externallyVisibleCLabel clab) then
817 hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
820 ptext SLIT("\t.ent "),
829 pp_lab = pprCLabel_asm clab
831 -- NEVER use commas within those string literals, cpp will ruin your day
832 pp_ldgp = hcat [ ptext SLIT(":\n\tldgp $29"), char ',', ptext SLIT("0($27)\n") ]
833 pp_frame = hcat [ ptext SLIT("..ng:\n\t.frame $30"), char ',',
834 ptext SLIT("4240"), char ',',
835 ptext SLIT("$26"), char ',',
836 ptext SLIT("0\n\t.prologue 1") ]
838 pprInstr (FUNEND clab)
839 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
842 Continue with Alpha-only printing bits and bobs:
846 pprRI (RIReg r) = pprReg r
847 pprRI (RIImm r) = pprImm r
849 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> SDoc
851 pprRegRIReg name reg1 ri reg2
863 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
865 pprSizeRegRegReg name size reg1 reg2 reg3
878 #endif {-alpha_TARGET_ARCH-}
881 %************************************************************************
883 \subsubsection{@pprInstr@ for an I386}
885 %************************************************************************
890 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
893 #if 0 /* #ifdef DEBUG */
894 (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
898 pprInstr (MOV size src dst)
899 = pprSizeOpOp SLIT("mov") size src dst
900 pprInstr (MOVZxL sizes src dst) = pprSizeOpOpCoerce SLIT("movz") sizes L src dst
901 pprInstr (MOVSxL sizes src dst) = pprSizeOpOpCoerce SLIT("movs") sizes L src dst
903 -- here we do some patching, since the physical registers are only set late
904 -- in the code generation.
905 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
907 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
908 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
910 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
911 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
913 = pprInstr (ADD size (OpImm displ) dst)
914 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
916 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
917 = pprSizeOp SLIT("dec") size dst
918 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
919 = pprSizeOp SLIT("inc") size dst
920 pprInstr (ADD size src dst)
921 = pprSizeOpOp SLIT("add") size src dst
922 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
923 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
925 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
926 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
927 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
928 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
929 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
931 pprInstr (SHL size imm dst) = pprSizeImmOp SLIT("shl") size imm dst
932 pprInstr (SAR size imm dst) = pprSizeImmOp SLIT("sar") size imm dst
933 pprInstr (SHR size imm dst) = pprSizeImmOp SLIT("shr") size imm dst
934 pprInstr (BT size imm src) = pprSizeImmOp SLIT("bt") size imm src
936 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
937 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
938 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
939 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
940 pprInstr PUSHA = ptext SLIT("\tpushal")
941 pprInstr POPA = ptext SLIT("\tpopal")
943 pprInstr (NOP) = ptext SLIT("\tnop")
944 pprInstr (CLTD) = ptext SLIT("\tcltd")
946 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
948 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
950 pprInstr (JMP dsts (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
951 pprInstr (JMP dsts op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand L op)
952 pprInstr (CALL imm) = (<>) (ptext SLIT("\tcall ")) (pprImm imm)
954 pprInstr (IQUOT sz src dst) = pprInstr_quotRem True sz src dst
955 pprInstr (IREM sz src dst) = pprInstr_quotRem False sz src dst
957 -- Simulating a flat register set on the x86 FP stack is tricky.
958 -- you have to free %st(7) before pushing anything on the FP reg stack
959 -- so as to preclude the possibility of a FP stack overflow exception.
960 pprInstr g@(GMOV src dst)
964 = pprG g (hcat [gtab, gpush src 0, gsemi, gpop dst 1])
966 -- GLD sz addr dst ==> FFREE %st(7) ; FLDsz addr ; FSTP (dst+1)
967 pprInstr g@(GLD sz addr dst)
968 = pprG g (hcat [gtab, text "ffree %st(7) ; fld", pprSize sz, gsp,
969 pprAddr addr, gsemi, gpop dst 1])
971 -- GST sz src addr ==> FFREE %st(7) ; FLD dst ; FSTPsz addr
972 pprInstr g@(GST sz src addr)
973 = pprG g (hcat [gtab, gpush src 0, gsemi,
974 text "fstp", pprSize sz, gsp, pprAddr addr])
976 pprInstr g@(GLDZ dst)
977 = pprG g (hcat [gtab, text "ffree %st(7) ; fldz ; ", gpop dst 1])
978 pprInstr g@(GLD1 dst)
979 = pprG g (hcat [gtab, text "ffree %st(7) ; fld1 ; ", gpop dst 1])
981 pprInstr g@(GFTOD src dst)
983 pprInstr g@(GFTOI src dst)
986 pprInstr g@(GDTOF src dst)
988 pprInstr g@(GDTOI src dst)
991 pprInstr g@(GITOF src dst)
992 = pprInstr (GITOD src dst)
993 pprInstr g@(GITOD src dst)
994 = pprG g (hcat [gtab, text "pushl ", pprReg L src,
995 text " ; ffree %st(7); fildl (%esp) ; ",
996 gpop dst 1, text " ; addl $4,%esp"])
998 pprInstr g@(GCMP sz src1 src2)
999 = pprG g (hcat [gtab, text "pushl %eax ; ",gpush src1 0]
1001 hcat [gtab, text "fcomp ", greg src2 1,
1002 text "; fstsw %ax ; sahf ; popl %eax"])
1004 pprInstr g@(GABS sz src dst)
1005 = pprG g (hcat [gtab, gpush src 0, text " ; fabs ; ", gpop dst 1])
1006 pprInstr g@(GNEG sz src dst)
1007 = pprG g (hcat [gtab, gpush src 0, text " ; fchs ; ", gpop dst 1])
1009 pprInstr g@(GSQRT sz src dst)
1010 = pprG g (hcat [gtab, gpush src 0, text " ; fsqrt"] $$
1011 hcat [gtab, gcoerceto sz, gpop dst 1])
1012 pprInstr g@(GSIN sz src dst)
1013 = pprG g (hcat [gtab, gpush src 0, text " ; fsin"] $$
1014 hcat [gtab, gcoerceto sz, gpop dst 1])
1015 pprInstr g@(GCOS sz src dst)
1016 = pprG g (hcat [gtab, gpush src 0, text " ; fcos"] $$
1017 hcat [gtab, gcoerceto sz, gpop dst 1])
1018 pprInstr g@(GTAN sz src dst)
1019 = pprG g (hcat [gtab, text "ffree %st(6) ; ",
1020 gpush src 0, text " ; fptan ; ",
1021 text " fstp %st(0)"] $$
1022 hcat [gtab, gcoerceto sz, gpop dst 1])
1024 -- In the translations for GADD, GMUL, GSUB and GDIV,
1025 -- the first two cases are mere optimisations. The otherwise clause
1026 -- generates correct code under all circumstances.
1028 pprInstr g@(GADD sz src1 src2 dst)
1030 = pprG g (text "\t#GADD-xxxcase1" $$
1031 hcat [gtab, gpush src2 0,
1032 text " ; faddp %st(0),", greg src1 1])
1034 = pprG g (text "\t#GADD-xxxcase2" $$
1035 hcat [gtab, gpush src1 0,
1036 text " ; faddp %st(0),", greg src2 1])
1038 = pprG g (hcat [gtab, gpush src1 0,
1039 text " ; fadd ", greg src2 1, text ",%st(0)",
1043 pprInstr g@(GMUL sz src1 src2 dst)
1045 = pprG g (text "\t#GMUL-xxxcase1" $$
1046 hcat [gtab, gpush src2 0,
1047 text " ; fmulp %st(0),", greg src1 1])
1049 = pprG g (text "\t#GMUL-xxxcase2" $$
1050 hcat [gtab, gpush src1 0,
1051 text " ; fmulp %st(0),", greg src2 1])
1053 = pprG g (hcat [gtab, gpush src1 0,
1054 text " ; fmul ", greg src2 1, text ",%st(0)",
1058 pprInstr g@(GSUB sz src1 src2 dst)
1060 = pprG g (text "\t#GSUB-xxxcase1" $$
1061 hcat [gtab, gpush src2 0,
1062 text " ; fsubrp %st(0),", greg src1 1])
1064 = pprG g (text "\t#GSUB-xxxcase2" $$
1065 hcat [gtab, gpush src1 0,
1066 text " ; fsubp %st(0),", greg src2 1])
1068 = pprG g (hcat [gtab, gpush src1 0,
1069 text " ; fsub ", greg src2 1, text ",%st(0)",
1073 pprInstr g@(GDIV sz src1 src2 dst)
1075 = pprG g (text "\t#GDIV-xxxcase1" $$
1076 hcat [gtab, gpush src2 0,
1077 text " ; fdivrp %st(0),", greg src1 1])
1079 = pprG g (text "\t#GDIV-xxxcase2" $$
1080 hcat [gtab, gpush src1 0,
1081 text " ; fdivp %st(0),", greg src2 1])
1083 = pprG g (hcat [gtab, gpush src1 0,
1084 text " ; fdiv ", greg src2 1, text ",%st(0)",
1089 = vcat [ ptext SLIT("\tffree %st(0) ;ffree %st(1) ;ffree %st(2) ;ffree %st(3)"),
1090 ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)")
1094 pprInstr_quotRem isQuot sz src dst
1095 | case sz of L -> False; _ -> True
1096 = panic "pprInstr_quotRem: dunno how to do non-32bit operands"
1099 (text "\t# BEGIN " <> fakeInsn),
1100 (text "\tpushl $0; pushl %eax; pushl %edx; pushl " <> pprOperand sz src),
1101 (text "\tmovl " <> pprOperand sz dst <> text ",%eax; xorl %edx,%edx; cltd"),
1102 (text "\tdivl 0(%esp); movl " <> text resReg <> text ",12(%esp)"),
1103 (text "\tpopl %edx; popl %edx; popl %eax; popl " <> pprOperand sz dst),
1104 (text "\t# END " <> fakeInsn)
1107 resReg = if isQuot then "%eax" else "%edx"
1108 opStr = if isQuot then "IQUOT" else "IREM"
1109 fakeInsn = text opStr <+> pprOperand sz src <> char ',' <+> pprOperand sz dst
1111 --------------------------
1113 -- coerce %st(0) to the specified size
1114 gcoerceto DF = empty
1115 gcoerceto F = text "subl $4,%esp ; fstps (%esp) ; flds (%esp) ; addl $4,%esp ; "
1118 = hcat [text "ffree %st(7) ; fld ", greg reg offset]
1120 = hcat [text "fstp ", greg reg offset]
1122 bogus = text "\tbogus"
1123 greg reg offset = text "%st(" <> int (gregno reg - 8+offset) <> char ')'
1128 gregno (RealReg i) = i
1129 gregno other = --pprPanic "gregno" (ppr other)
1130 999 -- bogus; only needed for debug printing
1132 pprG :: Instr -> SDoc -> SDoc
1134 = (char '#' <> pprGInstr fake) $$ actual
1136 pprGInstr (GMOV src dst) = pprSizeRegReg SLIT("gmov") DF src dst
1137 pprGInstr (GLD sz src dst) = pprSizeAddrReg SLIT("gld") sz src dst
1138 pprGInstr (GST sz src dst) = pprSizeRegAddr SLIT("gst") sz src dst
1140 pprGInstr (GLDZ dst) = pprSizeReg SLIT("gldz") DF dst
1141 pprGInstr (GLD1 dst) = pprSizeReg SLIT("gld1") DF dst
1143 pprGInstr (GFTOD src dst) = pprSizeSizeRegReg SLIT("gftod") F DF src dst
1144 pprGInstr (GFTOI src dst) = pprSizeSizeRegReg SLIT("gftoi") F L src dst
1146 pprGInstr (GDTOF src dst) = pprSizeSizeRegReg SLIT("gdtof") DF F src dst
1147 pprGInstr (GDTOI src dst) = pprSizeSizeRegReg SLIT("gdtoi") DF L src dst
1149 pprGInstr (GITOF src dst) = pprSizeSizeRegReg SLIT("gitof") L F src dst
1150 pprGInstr (GITOD src dst) = pprSizeSizeRegReg SLIT("gitod") L DF src dst
1152 pprGInstr (GCMP sz src dst) = pprSizeRegReg SLIT("gcmp") sz src dst
1153 pprGInstr (GABS sz src dst) = pprSizeRegReg SLIT("gabs") sz src dst
1154 pprGInstr (GNEG sz src dst) = pprSizeRegReg SLIT("gneg") sz src dst
1155 pprGInstr (GSQRT sz src dst) = pprSizeRegReg SLIT("gsqrt") sz src dst
1156 pprGInstr (GSIN sz src dst) = pprSizeRegReg SLIT("gsin") sz src dst
1157 pprGInstr (GCOS sz src dst) = pprSizeRegReg SLIT("gcos") sz src dst
1158 pprGInstr (GTAN sz src dst) = pprSizeRegReg SLIT("gtan") sz src dst
1160 pprGInstr (GADD sz src1 src2 dst) = pprSizeRegRegReg SLIT("gadd") sz src1 src2 dst
1161 pprGInstr (GSUB sz src1 src2 dst) = pprSizeRegRegReg SLIT("gsub") sz src1 src2 dst
1162 pprGInstr (GMUL sz src1 src2 dst) = pprSizeRegRegReg SLIT("gmul") sz src1 src2 dst
1163 pprGInstr (GDIV sz src1 src2 dst) = pprSizeRegRegReg SLIT("gdiv") sz src1 src2 dst
1166 Continue with I386-only printing bits and bobs:
1168 pprDollImm :: Imm -> SDoc
1170 pprDollImm i = ptext SLIT("$") <> pprImm i
1172 pprOperand :: Size -> Operand -> SDoc
1173 pprOperand s (OpReg r) = pprReg s r
1174 pprOperand s (OpImm i) = pprDollImm i
1175 pprOperand s (OpAddr ea) = pprAddr ea
1177 pprSizeImmOp :: FAST_STRING -> Size -> Imm -> Operand -> SDoc
1178 pprSizeImmOp name size imm op1
1190 pprSizeOp :: FAST_STRING -> Size -> Operand -> SDoc
1191 pprSizeOp name size op1
1200 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1201 pprSizeOpOp name size op1 op2
1207 pprOperand size op1,
1212 pprSizeByteOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1213 pprSizeByteOpOp name size op1 op2
1224 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> SDoc
1225 pprSizeOpReg name size op1 reg
1231 pprOperand size op1,
1236 pprSizeReg :: FAST_STRING -> Size -> Reg -> SDoc
1237 pprSizeReg name size reg1
1246 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1247 pprSizeRegReg name size reg1 reg2
1258 pprSizeSizeRegReg :: FAST_STRING -> Size -> Size -> Reg -> Reg -> SDoc
1259 pprSizeSizeRegReg name size1 size2 reg1 reg2
1271 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1272 pprSizeRegRegReg name size reg1 reg2 reg3
1285 pprSizeAddr :: FAST_STRING -> Size -> MachRegsAddr -> SDoc
1286 pprSizeAddr name size op
1295 pprSizeAddrReg :: FAST_STRING -> Size -> MachRegsAddr -> Reg -> SDoc
1296 pprSizeAddrReg name size op dst
1307 pprSizeRegAddr :: FAST_STRING -> Size -> Reg -> MachRegsAddr -> SDoc
1308 pprSizeRegAddr name size src op
1319 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1320 pprOpOp name size op1 op2
1324 pprOperand size op1,
1329 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> SDoc
1330 pprSizeOpOpCoerce name size1 size2 op1 op2
1331 = hcat [ char '\t', ptext name, pprSize size1, pprSize size2, space,
1332 pprOperand size1 op1,
1334 pprOperand size2 op2
1337 pprCondInstr :: FAST_STRING -> Cond -> SDoc -> SDoc
1338 pprCondInstr name cond arg
1339 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1341 #endif {-i386_TARGET_ARCH-}
1344 %************************************************************************
1346 \subsubsection{@pprInstr@ for a SPARC}
1348 %************************************************************************
1351 #if sparc_TARGET_ARCH
1353 -- a clumsy hack for now, to handle possible double alignment problems
1355 -- even clumsier, to allow for RegReg regs that show when doing indexed
1356 -- reads (bytearrays).
1359 -- Translate to the following:
1362 -- ld [g1+4],%f(n+1)
1363 -- sub g1,g2,g1 -- to restore g1
1364 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1366 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1367 hcat [pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg],
1368 hcat [pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)],
1369 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1374 -- ld [addr+4],%f(n+1)
1375 pprInstr (LD DF addr reg) | isJust off_addr
1377 hcat [pp_ld_lbracket, pprAddr addr, pp_rbracket_comma, pprReg reg],
1378 hcat [pp_ld_lbracket, pprAddr addr2, pp_rbracket_comma,pprReg (fPair reg)]
1381 off_addr = addrOffset addr 4
1382 addr2 = case off_addr of Just x -> x
1385 pprInstr (LD size addr reg)
1396 -- The same clumsy hack as above
1398 -- Translate to the following:
1401 -- st %f(n+1),[g1+4]
1402 -- sub g1,g2,g1 -- to restore g1
1403 pprInstr (ST DF reg (AddrRegReg g1 g2))
1405 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1406 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1408 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1409 pprReg g1, ptext SLIT("+4]")],
1410 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1415 -- st %f(n+1),[addr+4]
1416 pprInstr (ST DF reg addr) | isJust off_addr
1418 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1419 pprAddr addr, rbrack],
1420 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1421 pprAddr addr2, rbrack]
1424 off_addr = addrOffset addr 4
1425 addr2 = case off_addr of Just x -> x
1427 -- no distinction is made between signed and unsigned bytes on stores for the
1428 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1429 -- so we call a special-purpose pprSize for ST..
1431 pprInstr (ST size reg addr)
1442 pprInstr (ADD x cc reg1 ri reg2)
1443 | not x && not cc && riZero ri
1444 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1446 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1448 pprInstr (SUB x cc reg1 ri reg2)
1449 | not x && cc && reg2 == g0
1450 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1451 | not x && not cc && riZero ri
1452 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1454 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1456 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1457 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1459 pprInstr (OR b reg1 ri reg2)
1460 | not b && reg1 == g0
1461 = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1463 = pprRegRIReg SLIT("or") b reg1 ri reg2
1465 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1467 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1468 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1470 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1471 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1472 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1474 pprInstr (SETHI imm reg)
1476 ptext SLIT("\tsethi\t"),
1482 pprInstr NOP = ptext SLIT("\tnop")
1484 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1485 pprInstr (FABS DF reg1 reg2)
1486 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1487 (if (reg1 == reg2) then empty
1488 else (<>) (char '\n')
1489 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1491 pprInstr (FADD size reg1 reg2 reg3)
1492 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1493 pprInstr (FCMP e size reg1 reg2)
1494 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1495 pprInstr (FDIV size reg1 reg2 reg3)
1496 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1498 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1499 pprInstr (FMOV DF reg1 reg2)
1500 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1501 (if (reg1 == reg2) then empty
1502 else (<>) (char '\n')
1503 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1505 pprInstr (FMUL size reg1 reg2 reg3)
1506 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1508 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1509 pprInstr (FNEG DF reg1 reg2)
1510 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1511 (if (reg1 == reg2) then empty
1512 else (<>) (char '\n')
1513 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1515 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1516 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1517 pprInstr (FxTOy size1 size2 reg1 reg2)
1530 pprReg reg1, comma, pprReg reg2
1534 pprInstr (BI cond b lab)
1536 ptext SLIT("\tb"), pprCond cond,
1537 if b then pp_comma_a else empty,
1542 pprInstr (BF cond b lab)
1544 ptext SLIT("\tfb"), pprCond cond,
1545 if b then pp_comma_a else empty,
1550 pprInstr (JMP dsts addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1552 pprInstr (CALL imm n _)
1553 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1556 Continue with SPARC-only printing bits and bobs:
1559 pprRI (RIReg r) = pprReg r
1560 pprRI (RIImm r) = pprImm r
1562 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1563 pprSizeRegReg name size reg1 reg2
1568 F -> ptext SLIT("s\t")
1569 DF -> ptext SLIT("d\t")),
1575 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1576 pprSizeRegRegReg name size reg1 reg2 reg3
1581 F -> ptext SLIT("s\t")
1582 DF -> ptext SLIT("d\t")),
1590 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> SDoc
1591 pprRegRIReg name b reg1 ri reg2
1595 if b then ptext SLIT("cc\t") else char '\t',
1603 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> SDoc
1604 pprRIReg name b ri reg1
1608 if b then ptext SLIT("cc\t") else char '\t',
1614 pp_ld_lbracket = ptext SLIT("\tld\t[")
1615 pp_rbracket_comma = text "],"
1616 pp_comma_lbracket = text ",["
1617 pp_comma_a = text ",a"
1619 #endif {-sparc_TARGET_ARCH-}