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 (LABEL clab)
391 pp_lab = pprCLabel_asm clab
394 if not (externallyVisibleCLabel clab) then
398 IF_ARCH_alpha(SLIT("\t.globl\t")
399 ,IF_ARCH_i386(SLIT(".globl ")
400 ,IF_ARCH_sparc(SLIT(".global\t")
402 , pp_lab, char '\n'],
407 pprInstr (ASCII False{-no backslash conversion-} str)
408 = hcat [ ptext SLIT("\t.asciz "), char '\"', text str, char '"' ]
410 pprInstr (ASCII True str)
412 -- The Solaris assembler doesn't understand \x escapes in
416 asciify :: String -> SDoc
417 asciify "" = text "\t.ascii \"\\0\""
419 = let fst = take 16 str
421 this = text ("\t.ascii \""
422 ++ concat (map asciify_char fst)
424 in this $$ asciify rest
425 asciify_char :: Char -> String
426 asciify_char c = '\\' : 'x' : hshow (ord c)
428 = vcat (map do1 (str ++ [chr 0]))
431 do1 c = text "\t.byte\t0x" <> text (hshow (ord c))
433 hshow :: Int -> String
434 hshow n | n >= 0 && n <= 255
435 = [ tab !! (n `div` 16), tab !! (n `mod` 16)]
436 tab = "0123456789ABCDEF"
440 = vcat (concatMap (ppr_item s) xs)
443 #if alpha_TARGET_ARCH
444 ppr_item = error "ppr_item on Alpha"
446 #if sparc_TARGET_ARCH
447 -- copy n paste of x86 version
448 ppr_item B x = [text "\t.byte\t" <> pprImm x]
449 ppr_item W x = [text "\t.long\t" <> pprImm x]
450 ppr_item F (ImmFloat r)
451 = let bs = floatToBytes (fromRational r)
452 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
453 ppr_item DF (ImmDouble r)
454 = let bs = doubleToBytes (fromRational r)
455 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
458 ppr_item B x = [text "\t.byte\t" <> pprImm x]
459 ppr_item L x = [text "\t.long\t" <> pprImm x]
460 ppr_item F (ImmFloat r)
461 = let bs = floatToBytes (fromRational r)
462 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
463 ppr_item DF (ImmDouble r)
464 = let bs = doubleToBytes (fromRational r)
465 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
468 -- floatToBytes and doubleToBytes convert to the host's byte
469 -- order. Providing that we're not cross-compiling for a
470 -- target with the opposite endianness, this should work ok
472 floatToBytes :: Float -> [Int]
475 arr <- newFloatArray ((0::Int),3)
476 writeFloatArray arr 0 f
477 i0 <- readCharArray arr 0
478 i1 <- readCharArray arr 1
479 i2 <- readCharArray arr 2
480 i3 <- readCharArray arr 3
481 return (map ord [i0,i1,i2,i3])
484 doubleToBytes :: Double -> [Int]
487 arr <- newDoubleArray ((0::Int),7)
488 writeDoubleArray arr 0 d
489 i0 <- readCharArray arr 0
490 i1 <- readCharArray arr 1
491 i2 <- readCharArray arr 2
492 i3 <- readCharArray arr 3
493 i4 <- readCharArray arr 4
494 i5 <- readCharArray arr 5
495 i6 <- readCharArray arr 6
496 i7 <- readCharArray arr 7
497 return (map ord [i0,i1,i2,i3,i4,i5,i6,i7])
500 -- fall through to rest of (machine-specific) pprInstr...
503 %************************************************************************
505 \subsubsection{@pprInstr@ for an Alpha}
507 %************************************************************************
510 #if alpha_TARGET_ARCH
512 pprInstr (LD size reg addr)
522 pprInstr (LDA reg addr)
524 ptext SLIT("\tlda\t"),
530 pprInstr (LDAH reg addr)
532 ptext SLIT("\tldah\t"),
538 pprInstr (LDGP reg addr)
540 ptext SLIT("\tldgp\t"),
546 pprInstr (LDI size reg imm)
556 pprInstr (ST size reg addr)
568 ptext SLIT("\tclr\t"),
572 pprInstr (ABS size ri reg)
582 pprInstr (NEG size ov ri reg)
586 if ov then ptext SLIT("v\t") else char '\t',
592 pprInstr (ADD size ov reg1 ri reg2)
596 if ov then ptext SLIT("v\t") else char '\t',
604 pprInstr (SADD size scale reg1 ri reg2)
606 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
617 pprInstr (SUB size ov reg1 ri reg2)
621 if ov then ptext SLIT("v\t") else char '\t',
629 pprInstr (SSUB size scale reg1 ri reg2)
631 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
642 pprInstr (MUL size ov reg1 ri reg2)
646 if ov then ptext SLIT("v\t") else char '\t',
654 pprInstr (DIV size uns reg1 ri reg2)
658 if uns then ptext SLIT("u\t") else char '\t',
666 pprInstr (REM size uns reg1 ri reg2)
670 if uns then ptext SLIT("u\t") else char '\t',
678 pprInstr (NOT ri reg)
687 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
688 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
689 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
690 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
691 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
692 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
694 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
695 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
696 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
698 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
699 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
701 pprInstr (NOP) = ptext SLIT("\tnop")
703 pprInstr (CMP cond reg1 ri reg2)
717 ptext SLIT("\tfclr\t"),
721 pprInstr (FABS reg1 reg2)
723 ptext SLIT("\tfabs\t"),
729 pprInstr (FNEG size reg1 reg2)
739 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
740 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
741 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
742 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
744 pprInstr (CVTxy size1 size2 reg1 reg2)
748 case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
755 pprInstr (FCMP size cond reg1 reg2 reg3)
768 pprInstr (FMOV reg1 reg2)
770 ptext SLIT("\tfmov\t"),
776 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
778 pprInstr (BI NEVER reg lab) = empty
780 pprInstr (BI cond reg lab)
790 pprInstr (BF cond reg lab)
801 = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
803 pprInstr (JMP reg addr hint)
805 ptext SLIT("\tjmp\t"),
814 = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
816 pprInstr (JSR reg addr n)
818 ptext SLIT("\tjsr\t"),
824 pprInstr (FUNBEGIN clab)
826 if (externallyVisibleCLabel clab) then
827 hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
830 ptext SLIT("\t.ent "),
839 pp_lab = pprCLabel_asm clab
841 -- NEVER use commas within those string literals, cpp will ruin your day
842 pp_ldgp = hcat [ ptext SLIT(":\n\tldgp $29"), char ',', ptext SLIT("0($27)\n") ]
843 pp_frame = hcat [ ptext SLIT("..ng:\n\t.frame $30"), char ',',
844 ptext SLIT("4240"), char ',',
845 ptext SLIT("$26"), char ',',
846 ptext SLIT("0\n\t.prologue 1") ]
848 pprInstr (FUNEND clab)
849 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
852 Continue with Alpha-only printing bits and bobs:
856 pprRI (RIReg r) = pprReg r
857 pprRI (RIImm r) = pprImm r
859 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> SDoc
861 pprRegRIReg name reg1 ri reg2
873 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
875 pprSizeRegRegReg name size reg1 reg2 reg3
888 #endif {-alpha_TARGET_ARCH-}
891 %************************************************************************
893 \subsubsection{@pprInstr@ for an I386}
895 %************************************************************************
900 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
903 #if 0 /* #ifdef DEBUG */
904 (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
908 pprInstr (MOV size src dst)
909 = pprSizeOpOp SLIT("mov") size src dst
910 pprInstr (MOVZxL sizes src dst) = pprSizeOpOpCoerce SLIT("movz") sizes L src dst
911 pprInstr (MOVSxL sizes src dst) = pprSizeOpOpCoerce SLIT("movs") sizes L src dst
913 -- here we do some patching, since the physical registers are only set late
914 -- in the code generation.
915 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
917 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
918 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
920 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
921 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
923 = pprInstr (ADD size (OpImm displ) dst)
924 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
926 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
927 = pprSizeOp SLIT("dec") size dst
928 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
929 = pprSizeOp SLIT("inc") size dst
930 pprInstr (ADD size src dst)
931 = pprSizeOpOp SLIT("add") size src dst
932 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
933 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
935 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
936 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
937 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
938 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
939 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
941 pprInstr (SHL size imm dst) = pprSizeImmOp SLIT("shl") size imm dst
942 pprInstr (SAR size imm dst) = pprSizeImmOp SLIT("sar") size imm dst
943 pprInstr (SHR size imm dst) = pprSizeImmOp SLIT("shr") size imm dst
944 pprInstr (BT size imm src) = pprSizeImmOp SLIT("bt") size imm src
946 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
947 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
948 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
949 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
950 pprInstr PUSHA = ptext SLIT("\tpushal")
951 pprInstr POPA = ptext SLIT("\tpopal")
953 pprInstr (NOP) = ptext SLIT("\tnop")
954 pprInstr (CLTD) = ptext SLIT("\tcltd")
956 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
958 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
960 pprInstr (JMP dsts (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
961 pprInstr (JMP dsts op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand L op)
962 pprInstr (CALL imm) = (<>) (ptext SLIT("\tcall ")) (pprImm imm)
964 pprInstr (IQUOT sz src dst) = pprInstr_quotRem True sz src dst
965 pprInstr (IREM sz src dst) = pprInstr_quotRem False sz src dst
967 -- Simulating a flat register set on the x86 FP stack is tricky.
968 -- you have to free %st(7) before pushing anything on the FP reg stack
969 -- so as to preclude the possibility of a FP stack overflow exception.
970 pprInstr g@(GMOV src dst)
974 = pprG g (hcat [gtab, gpush src 0, gsemi, gpop dst 1])
976 -- GLD sz addr dst ==> FFREE %st(7) ; FLDsz addr ; FSTP (dst+1)
977 pprInstr g@(GLD sz addr dst)
978 = pprG g (hcat [gtab, text "ffree %st(7) ; fld", pprSize sz, gsp,
979 pprAddr addr, gsemi, gpop dst 1])
981 -- GST sz src addr ==> FFREE %st(7) ; FLD dst ; FSTPsz addr
982 pprInstr g@(GST sz src addr)
983 = pprG g (hcat [gtab, gpush src 0, gsemi,
984 text "fstp", pprSize sz, gsp, pprAddr addr])
986 pprInstr g@(GLDZ dst)
987 = pprG g (hcat [gtab, text "ffree %st(7) ; fldz ; ", gpop dst 1])
988 pprInstr g@(GLD1 dst)
989 = pprG g (hcat [gtab, text "ffree %st(7) ; fld1 ; ", gpop dst 1])
991 pprInstr g@(GFTOD src dst)
993 pprInstr g@(GFTOI src dst)
996 pprInstr g@(GDTOF src dst)
998 pprInstr g@(GDTOI src dst)
1001 pprInstr g@(GITOF src dst)
1002 = pprInstr (GITOD src dst)
1003 pprInstr g@(GITOD src dst)
1004 = pprG g (hcat [gtab, text "pushl ", pprReg L src,
1005 text " ; ffree %st(7); fildl (%esp) ; ",
1006 gpop dst 1, text " ; addl $4,%esp"])
1008 pprInstr g@(GCMP sz src1 src2)
1009 = pprG g (hcat [gtab, text "pushl %eax ; ",gpush src1 0]
1011 hcat [gtab, text "fcomp ", greg src2 1,
1012 text "; fstsw %ax ; sahf ; popl %eax"])
1014 pprInstr g@(GABS sz src dst)
1015 = pprG g (hcat [gtab, gpush src 0, text " ; fabs ; ", gpop dst 1])
1016 pprInstr g@(GNEG sz src dst)
1017 = pprG g (hcat [gtab, gpush src 0, text " ; fchs ; ", gpop dst 1])
1019 pprInstr g@(GSQRT sz src dst)
1020 = pprG g (hcat [gtab, gpush src 0, text " ; fsqrt"] $$
1021 hcat [gtab, gcoerceto sz, gpop dst 1])
1022 pprInstr g@(GSIN sz src dst)
1023 = pprG g (hcat [gtab, gpush src 0, text " ; fsin"] $$
1024 hcat [gtab, gcoerceto sz, gpop dst 1])
1025 pprInstr g@(GCOS sz src dst)
1026 = pprG g (hcat [gtab, gpush src 0, text " ; fcos"] $$
1027 hcat [gtab, gcoerceto sz, gpop dst 1])
1028 pprInstr g@(GTAN sz src dst)
1029 = pprG g (hcat [gtab, text "ffree %st(6) ; ",
1030 gpush src 0, text " ; fptan ; ",
1031 text " fstp %st(0)"] $$
1032 hcat [gtab, gcoerceto sz, gpop dst 1])
1034 -- In the translations for GADD, GMUL, GSUB and GDIV,
1035 -- the first two cases are mere optimisations. The otherwise clause
1036 -- generates correct code under all circumstances.
1038 pprInstr g@(GADD sz src1 src2 dst)
1040 = pprG g (text "\t#GADD-xxxcase1" $$
1041 hcat [gtab, gpush src2 0,
1042 text " ; faddp %st(0),", greg src1 1])
1044 = pprG g (text "\t#GADD-xxxcase2" $$
1045 hcat [gtab, gpush src1 0,
1046 text " ; faddp %st(0),", greg src2 1])
1048 = pprG g (hcat [gtab, gpush src1 0,
1049 text " ; fadd ", greg src2 1, text ",%st(0)",
1053 pprInstr g@(GMUL sz src1 src2 dst)
1055 = pprG g (text "\t#GMUL-xxxcase1" $$
1056 hcat [gtab, gpush src2 0,
1057 text " ; fmulp %st(0),", greg src1 1])
1059 = pprG g (text "\t#GMUL-xxxcase2" $$
1060 hcat [gtab, gpush src1 0,
1061 text " ; fmulp %st(0),", greg src2 1])
1063 = pprG g (hcat [gtab, gpush src1 0,
1064 text " ; fmul ", greg src2 1, text ",%st(0)",
1068 pprInstr g@(GSUB sz src1 src2 dst)
1070 = pprG g (text "\t#GSUB-xxxcase1" $$
1071 hcat [gtab, gpush src2 0,
1072 text " ; fsubrp %st(0),", greg src1 1])
1074 = pprG g (text "\t#GSUB-xxxcase2" $$
1075 hcat [gtab, gpush src1 0,
1076 text " ; fsubp %st(0),", greg src2 1])
1078 = pprG g (hcat [gtab, gpush src1 0,
1079 text " ; fsub ", greg src2 1, text ",%st(0)",
1083 pprInstr g@(GDIV sz src1 src2 dst)
1085 = pprG g (text "\t#GDIV-xxxcase1" $$
1086 hcat [gtab, gpush src2 0,
1087 text " ; fdivrp %st(0),", greg src1 1])
1089 = pprG g (text "\t#GDIV-xxxcase2" $$
1090 hcat [gtab, gpush src1 0,
1091 text " ; fdivp %st(0),", greg src2 1])
1093 = pprG g (hcat [gtab, gpush src1 0,
1094 text " ; fdiv ", greg src2 1, text ",%st(0)",
1099 = vcat [ ptext SLIT("\tffree %st(0) ;ffree %st(1) ;ffree %st(2) ;ffree %st(3)"),
1100 ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)")
1104 pprInstr_quotRem isQuot sz src dst
1105 | case sz of L -> False; _ -> True
1106 = panic "pprInstr_quotRem: dunno how to do non-32bit operands"
1109 (text "\t# BEGIN " <> fakeInsn),
1110 (text "\tpushl $0; pushl %eax; pushl %edx; pushl " <> pprOperand sz src),
1111 (text "\tmovl " <> pprOperand sz dst <> text ",%eax; xorl %edx,%edx; cltd"),
1112 (text "\tdivl 0(%esp); movl " <> text resReg <> text ",12(%esp)"),
1113 (text "\tpopl %edx; popl %edx; popl %eax; popl " <> pprOperand sz dst),
1114 (text "\t# END " <> fakeInsn)
1117 resReg = if isQuot then "%eax" else "%edx"
1118 opStr = if isQuot then "IQUOT" else "IREM"
1119 fakeInsn = text opStr <+> pprOperand sz src <> char ',' <+> pprOperand sz dst
1121 --------------------------
1123 -- coerce %st(0) to the specified size
1124 gcoerceto DF = empty
1125 gcoerceto F = text "subl $4,%esp ; fstps (%esp) ; flds (%esp) ; addl $4,%esp ; "
1128 = hcat [text "ffree %st(7) ; fld ", greg reg offset]
1130 = hcat [text "fstp ", greg reg offset]
1132 bogus = text "\tbogus"
1133 greg reg offset = text "%st(" <> int (gregno reg - 8+offset) <> char ')'
1138 gregno (RealReg i) = i
1139 gregno other = --pprPanic "gregno" (ppr other)
1140 999 -- bogus; only needed for debug printing
1142 pprG :: Instr -> SDoc -> SDoc
1144 = (char '#' <> pprGInstr fake) $$ actual
1146 pprGInstr (GMOV src dst) = pprSizeRegReg SLIT("gmov") DF src dst
1147 pprGInstr (GLD sz src dst) = pprSizeAddrReg SLIT("gld") sz src dst
1148 pprGInstr (GST sz src dst) = pprSizeRegAddr SLIT("gst") sz src dst
1150 pprGInstr (GLDZ dst) = pprSizeReg SLIT("gldz") DF dst
1151 pprGInstr (GLD1 dst) = pprSizeReg SLIT("gld1") DF dst
1153 pprGInstr (GFTOD src dst) = pprSizeSizeRegReg SLIT("gftod") F DF src dst
1154 pprGInstr (GFTOI src dst) = pprSizeSizeRegReg SLIT("gftoi") F L src dst
1156 pprGInstr (GDTOF src dst) = pprSizeSizeRegReg SLIT("gdtof") DF F src dst
1157 pprGInstr (GDTOI src dst) = pprSizeSizeRegReg SLIT("gdtoi") DF L src dst
1159 pprGInstr (GITOF src dst) = pprSizeSizeRegReg SLIT("gitof") L F src dst
1160 pprGInstr (GITOD src dst) = pprSizeSizeRegReg SLIT("gitod") L DF src dst
1162 pprGInstr (GCMP sz src dst) = pprSizeRegReg SLIT("gcmp") sz src dst
1163 pprGInstr (GABS sz src dst) = pprSizeRegReg SLIT("gabs") sz src dst
1164 pprGInstr (GNEG sz src dst) = pprSizeRegReg SLIT("gneg") sz src dst
1165 pprGInstr (GSQRT sz src dst) = pprSizeRegReg SLIT("gsqrt") sz src dst
1166 pprGInstr (GSIN sz src dst) = pprSizeRegReg SLIT("gsin") sz src dst
1167 pprGInstr (GCOS sz src dst) = pprSizeRegReg SLIT("gcos") sz src dst
1168 pprGInstr (GTAN sz src dst) = pprSizeRegReg SLIT("gtan") sz src dst
1170 pprGInstr (GADD sz src1 src2 dst) = pprSizeRegRegReg SLIT("gadd") sz src1 src2 dst
1171 pprGInstr (GSUB sz src1 src2 dst) = pprSizeRegRegReg SLIT("gsub") sz src1 src2 dst
1172 pprGInstr (GMUL sz src1 src2 dst) = pprSizeRegRegReg SLIT("gmul") sz src1 src2 dst
1173 pprGInstr (GDIV sz src1 src2 dst) = pprSizeRegRegReg SLIT("gdiv") sz src1 src2 dst
1176 Continue with I386-only printing bits and bobs:
1178 pprDollImm :: Imm -> SDoc
1180 pprDollImm i = ptext SLIT("$") <> pprImm i
1182 pprOperand :: Size -> Operand -> SDoc
1183 pprOperand s (OpReg r) = pprReg s r
1184 pprOperand s (OpImm i) = pprDollImm i
1185 pprOperand s (OpAddr ea) = pprAddr ea
1187 pprSizeImmOp :: FAST_STRING -> Size -> Imm -> Operand -> SDoc
1188 pprSizeImmOp name size imm op1
1200 pprSizeOp :: FAST_STRING -> Size -> Operand -> SDoc
1201 pprSizeOp name size op1
1210 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1211 pprSizeOpOp name size op1 op2
1217 pprOperand size op1,
1222 pprSizeByteOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1223 pprSizeByteOpOp name size op1 op2
1234 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> SDoc
1235 pprSizeOpReg name size op1 reg
1241 pprOperand size op1,
1246 pprSizeReg :: FAST_STRING -> Size -> Reg -> SDoc
1247 pprSizeReg name size reg1
1256 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1257 pprSizeRegReg name size reg1 reg2
1268 pprSizeSizeRegReg :: FAST_STRING -> Size -> Size -> Reg -> Reg -> SDoc
1269 pprSizeSizeRegReg name size1 size2 reg1 reg2
1281 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1282 pprSizeRegRegReg name size reg1 reg2 reg3
1295 pprSizeAddr :: FAST_STRING -> Size -> MachRegsAddr -> SDoc
1296 pprSizeAddr name size op
1305 pprSizeAddrReg :: FAST_STRING -> Size -> MachRegsAddr -> Reg -> SDoc
1306 pprSizeAddrReg name size op dst
1317 pprSizeRegAddr :: FAST_STRING -> Size -> Reg -> MachRegsAddr -> SDoc
1318 pprSizeRegAddr name size src op
1329 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1330 pprOpOp name size op1 op2
1334 pprOperand size op1,
1339 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> SDoc
1340 pprSizeOpOpCoerce name size1 size2 op1 op2
1341 = hcat [ char '\t', ptext name, pprSize size1, pprSize size2, space,
1342 pprOperand size1 op1,
1344 pprOperand size2 op2
1347 pprCondInstr :: FAST_STRING -> Cond -> SDoc -> SDoc
1348 pprCondInstr name cond arg
1349 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1351 #endif {-i386_TARGET_ARCH-}
1354 %************************************************************************
1356 \subsubsection{@pprInstr@ for a SPARC}
1358 %************************************************************************
1361 #if sparc_TARGET_ARCH
1363 -- a clumsy hack for now, to handle possible double alignment problems
1365 -- even clumsier, to allow for RegReg regs that show when doing indexed
1366 -- reads (bytearrays).
1369 -- Translate to the following:
1372 -- ld [g1+4],%f(n+1)
1373 -- sub g1,g2,g1 -- to restore g1
1374 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1376 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1377 hcat [pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg],
1378 hcat [pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)],
1379 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1384 -- ld [addr+4],%f(n+1)
1385 pprInstr (LD DF addr reg) | isJust off_addr
1387 hcat [pp_ld_lbracket, pprAddr addr, pp_rbracket_comma, pprReg reg],
1388 hcat [pp_ld_lbracket, pprAddr addr2, pp_rbracket_comma,pprReg (fPair reg)]
1391 off_addr = addrOffset addr 4
1392 addr2 = case off_addr of Just x -> x
1395 pprInstr (LD size addr reg)
1406 -- The same clumsy hack as above
1408 -- Translate to the following:
1411 -- st %f(n+1),[g1+4]
1412 -- sub g1,g2,g1 -- to restore g1
1413 pprInstr (ST DF reg (AddrRegReg g1 g2))
1415 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1416 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1418 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1419 pprReg g1, ptext SLIT("+4]")],
1420 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1425 -- st %f(n+1),[addr+4]
1426 pprInstr (ST DF reg addr) | isJust off_addr
1428 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1429 pprAddr addr, rbrack],
1430 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1431 pprAddr addr2, rbrack]
1434 off_addr = addrOffset addr 4
1435 addr2 = case off_addr of Just x -> x
1437 -- no distinction is made between signed and unsigned bytes on stores for the
1438 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1439 -- so we call a special-purpose pprSize for ST..
1441 pprInstr (ST size reg addr)
1452 pprInstr (ADD x cc reg1 ri reg2)
1453 | not x && not cc && riZero ri
1454 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1456 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1458 pprInstr (SUB x cc reg1 ri reg2)
1459 | not x && cc && reg2 == g0
1460 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1461 | not x && not cc && riZero ri
1462 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1464 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1466 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1467 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1469 pprInstr (OR b reg1 ri reg2)
1470 | not b && reg1 == g0
1471 = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1473 = pprRegRIReg SLIT("or") b reg1 ri reg2
1475 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1477 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1478 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1480 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1481 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1482 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1484 pprInstr (SETHI imm reg)
1486 ptext SLIT("\tsethi\t"),
1492 pprInstr NOP = ptext SLIT("\tnop")
1494 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1495 pprInstr (FABS DF reg1 reg2)
1496 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1497 (if (reg1 == reg2) then empty
1498 else (<>) (char '\n')
1499 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1501 pprInstr (FADD size reg1 reg2 reg3)
1502 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1503 pprInstr (FCMP e size reg1 reg2)
1504 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1505 pprInstr (FDIV size reg1 reg2 reg3)
1506 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1508 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1509 pprInstr (FMOV DF reg1 reg2)
1510 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1511 (if (reg1 == reg2) then empty
1512 else (<>) (char '\n')
1513 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1515 pprInstr (FMUL size reg1 reg2 reg3)
1516 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1518 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1519 pprInstr (FNEG DF reg1 reg2)
1520 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1521 (if (reg1 == reg2) then empty
1522 else (<>) (char '\n')
1523 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1525 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1526 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1527 pprInstr (FxTOy size1 size2 reg1 reg2)
1540 pprReg reg1, comma, pprReg reg2
1544 pprInstr (BI cond b lab)
1546 ptext SLIT("\tb"), pprCond cond,
1547 if b then pp_comma_a else empty,
1552 pprInstr (BF cond b lab)
1554 ptext SLIT("\tfb"), pprCond cond,
1555 if b then pp_comma_a else empty,
1560 pprInstr (JMP dsts addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1562 pprInstr (CALL imm n _)
1563 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1566 Continue with SPARC-only printing bits and bobs:
1569 pprRI (RIReg r) = pprReg r
1570 pprRI (RIImm r) = pprImm r
1572 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1573 pprSizeRegReg name size reg1 reg2
1578 F -> ptext SLIT("s\t")
1579 DF -> ptext SLIT("d\t")),
1585 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1586 pprSizeRegRegReg name size reg1 reg2 reg3
1591 F -> ptext SLIT("s\t")
1592 DF -> ptext SLIT("d\t")),
1600 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> SDoc
1601 pprRegRIReg name b reg1 ri reg2
1605 if b then ptext SLIT("cc\t") else char '\t',
1613 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> SDoc
1614 pprRIReg name b ri reg1
1618 if b then ptext SLIT("cc\t") else char '\t',
1624 pp_ld_lbracket = ptext SLIT("\tld\t[")
1625 pp_rbracket_comma = text "],"
1626 pp_comma_lbracket = text ",["
1627 pp_comma_a = text ",a"
1629 #endif {-sparc_TARGET_ARCH-}