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
182 #if sparc_TARGET_ARCH
189 pprStSize :: Size -> SDoc
190 pprStSize x = ptext (case x of
200 %************************************************************************
202 \subsection{@pprCond@: print a @Cond@}
204 %************************************************************************
207 pprCond :: Cond -> SDoc
209 pprCond c = ptext (case c of {
210 #if alpha_TARGET_ARCH
221 GEU -> SLIT("ae"); LU -> SLIT("b");
222 EQQ -> SLIT("e"); GTT -> SLIT("g");
223 GE -> SLIT("ge"); GU -> SLIT("a");
224 LTT -> SLIT("l"); LE -> SLIT("le");
225 LEU -> SLIT("be"); NE -> SLIT("ne");
226 NEG -> SLIT("s"); POS -> SLIT("ns");
227 ALWAYS -> SLIT("mp") -- hack
229 #if sparc_TARGET_ARCH
230 ALWAYS -> SLIT(""); NEVER -> SLIT("n");
231 GEU -> SLIT("geu"); LU -> SLIT("lu");
232 EQQ -> SLIT("e"); GTT -> SLIT("g");
233 GE -> SLIT("ge"); GU -> SLIT("gu");
234 LTT -> SLIT("l"); LE -> SLIT("le");
235 LEU -> SLIT("leu"); NE -> SLIT("ne");
236 NEG -> SLIT("neg"); POS -> SLIT("pos");
237 VC -> SLIT("vc"); VS -> SLIT("vs")
242 %************************************************************************
244 \subsection{@pprImm@: print an @Imm@}
246 %************************************************************************
249 pprImm :: Imm -> SDoc
251 pprImm (ImmInt i) = int i
252 pprImm (ImmInteger i) = integer i
253 pprImm (ImmCLbl l) = (if labelDynamic l then text "__imp_" else empty)
255 pprImm (ImmIndex l i) = (if labelDynamic l then text "__imp_" else empty)
256 <> pprCLabel_asm l <> char '+' <> int i
257 pprImm (ImmLit s) = s
259 pprImm (ImmLab dll s) = (if underscorePrefix then char '_' else empty)
260 <> (if dll then text "_imp__" else empty)
263 #if sparc_TARGET_ARCH
265 = hcat [ pp_lo, pprImm i, rparen ]
270 = hcat [ pp_hi, pprImm i, rparen ]
276 %************************************************************************
278 \subsection{@pprAddr@: print an @Addr@}
280 %************************************************************************
283 pprAddr :: MachRegsAddr -> SDoc
285 #if alpha_TARGET_ARCH
286 pprAddr (AddrReg r) = parens (pprReg r)
287 pprAddr (AddrImm i) = pprImm i
288 pprAddr (AddrRegImm r1 i)
289 = (<>) (pprImm i) (parens (pprReg r1))
295 pprAddr (ImmAddr imm off)
296 = let pp_imm = pprImm imm
300 else if (off < 0) then
303 pp_imm <> char '+' <> int off
305 pprAddr (AddrBaseIndex base index displacement)
307 pp_disp = ppr_disp displacement
308 pp_off p = pp_disp <> char '(' <> p <> char ')'
309 pp_reg r = pprReg L r
312 (Nothing, Nothing) -> pp_disp
313 (Just b, Nothing) -> pp_off (pp_reg b)
314 (Nothing, Just (r,i)) -> pp_off (pp_reg r <> comma <> int i)
315 (Just b, Just (r,i)) -> pp_off (pp_reg b <> comma <> pp_reg r
318 ppr_disp (ImmInt 0) = empty
319 ppr_disp imm = pprImm imm
324 #if sparc_TARGET_ARCH
325 pprAddr (AddrRegReg r1 (RealReg 0)) = pprReg r1
327 pprAddr (AddrRegReg r1 r2)
328 = hcat [ pprReg r1, char '+', pprReg r2 ]
330 pprAddr (AddrRegImm r1 (ImmInt i))
332 | not (fits13Bits i) = largeOffsetError i
333 | otherwise = hcat [ pprReg r1, pp_sign, int i ]
335 pp_sign = if i > 0 then char '+' else empty
337 pprAddr (AddrRegImm r1 (ImmInteger i))
339 | not (fits13Bits i) = largeOffsetError i
340 | otherwise = hcat [ pprReg r1, pp_sign, integer i ]
342 pp_sign = if i > 0 then char '+' else empty
344 pprAddr (AddrRegImm r1 imm)
345 = hcat [ pprReg r1, char '+', pprImm imm ]
349 %************************************************************************
351 \subsection{@pprInstr@: print an @Instr@}
353 %************************************************************************
356 pprInstr :: Instr -> SDoc
358 --pprInstr (COMMENT s) = empty -- nuke 'em
360 = IF_ARCH_alpha( ((<>) (ptext SLIT("\t# ")) (ptext s))
361 ,IF_ARCH_sparc( ((<>) (ptext SLIT("! ")) (ptext s))
362 ,IF_ARCH_i386( ((<>) (ptext SLIT("# ")) (ptext s))
366 = pprInstr (COMMENT (_PK_ ("\tdelta = " ++ show d)))
368 pprInstr (SEGMENT TextSegment)
369 = IF_ARCH_alpha(ptext SLIT("\t.text\n\t.align 3") {-word boundary-}
370 ,IF_ARCH_sparc(ptext SLIT(".text\n\t.align 4") {-word boundary-}
371 ,IF_ARCH_i386((text ".text\n\t.align 4,0x90") {-needs per-OS variation!-}
374 pprInstr (SEGMENT DataSegment)
376 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
377 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
378 ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
381 pprInstr (SEGMENT RoDataSegment)
383 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
384 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
385 ,IF_ARCH_i386(SLIT(".section .rodata\n\t.align 4")
388 pprInstr (LABEL clab)
390 pp_lab = pprCLabel_asm clab
393 if not (externallyVisibleCLabel clab) then
397 IF_ARCH_alpha(SLIT("\t.globl\t")
398 ,IF_ARCH_i386(SLIT(".globl ")
399 ,IF_ARCH_sparc(SLIT(".global\t")
401 , pp_lab, char '\n'],
406 pprInstr (ASCII False{-no backslash conversion-} str)
407 = hcat [ ptext SLIT("\t.asciz "), char '\"', text str, char '"' ]
409 pprInstr (ASCII True str)
410 = vcat (map do1 (str ++ [chr 0]))
413 do1 c = ptext SLIT("\t.byte\t0x") <> hshow (ord c)
416 hshow n | n >= 0 && n <= 255
417 = char (tab !! (n `div` 16)) <> char (tab !! (n `mod` 16))
418 tab = "0123456789ABCDEF"
422 = vcat (concatMap (ppr_item s) xs)
425 #if alpha_TARGET_ARCH
426 ppr_item = error "ppr_item on Alpha"
428 #if sparc_TARGET_ARCH
429 -- copy n paste of x86 version
430 ppr_item B x = [ptext SLIT("\t.byte\t") <> pprImm x]
431 ppr_item W x = [ptext SLIT("\t.long\t") <> pprImm x]
432 ppr_item F (ImmFloat r)
433 = let bs = floatToBytes (fromRational r)
434 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
435 ppr_item DF (ImmDouble r)
436 = let bs = doubleToBytes (fromRational r)
437 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
440 ppr_item B x = [ptext SLIT("\t.byte\t") <> pprImm x]
441 ppr_item L x = [ptext SLIT("\t.long\t") <> pprImm x]
442 ppr_item F (ImmFloat r)
443 = let bs = floatToBytes (fromRational r)
444 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
445 ppr_item DF (ImmDouble r)
446 = let bs = doubleToBytes (fromRational r)
447 in map (\b -> ptext SLIT("\t.byte\t") <> pprImm (ImmInt b)) bs
450 -- floatToBytes and doubleToBytes convert to the host's byte
451 -- order. Providing that we're not cross-compiling for a
452 -- target with the opposite endianness, this should work ok
454 floatToBytes :: Float -> [Int]
457 arr <- newFloatArray ((0::Int),3)
458 writeFloatArray arr 0 f
459 i0 <- readCharArray arr 0
460 i1 <- readCharArray arr 1
461 i2 <- readCharArray arr 2
462 i3 <- readCharArray arr 3
463 return (map ord [i0,i1,i2,i3])
466 doubleToBytes :: Double -> [Int]
469 arr <- newDoubleArray ((0::Int),7)
470 writeDoubleArray arr 0 d
471 i0 <- readCharArray arr 0
472 i1 <- readCharArray arr 1
473 i2 <- readCharArray arr 2
474 i3 <- readCharArray arr 3
475 i4 <- readCharArray arr 4
476 i5 <- readCharArray arr 5
477 i6 <- readCharArray arr 6
478 i7 <- readCharArray arr 7
479 return (map ord [i0,i1,i2,i3,i4,i5,i6,i7])
482 -- fall through to rest of (machine-specific) pprInstr...
485 %************************************************************************
487 \subsubsection{@pprInstr@ for an Alpha}
489 %************************************************************************
492 #if alpha_TARGET_ARCH
494 pprInstr (LD size reg addr)
504 pprInstr (LDA reg addr)
506 ptext SLIT("\tlda\t"),
512 pprInstr (LDAH reg addr)
514 ptext SLIT("\tldah\t"),
520 pprInstr (LDGP reg addr)
522 ptext SLIT("\tldgp\t"),
528 pprInstr (LDI size reg imm)
538 pprInstr (ST size reg addr)
550 ptext SLIT("\tclr\t"),
554 pprInstr (ABS size ri reg)
564 pprInstr (NEG size ov ri reg)
568 if ov then ptext SLIT("v\t") else char '\t',
574 pprInstr (ADD size ov reg1 ri reg2)
578 if ov then ptext SLIT("v\t") else char '\t',
586 pprInstr (SADD size scale reg1 ri reg2)
588 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
599 pprInstr (SUB size ov reg1 ri reg2)
603 if ov then ptext SLIT("v\t") else char '\t',
611 pprInstr (SSUB size scale reg1 ri reg2)
613 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
624 pprInstr (MUL size ov reg1 ri reg2)
628 if ov then ptext SLIT("v\t") else char '\t',
636 pprInstr (DIV size uns reg1 ri reg2)
640 if uns then ptext SLIT("u\t") else char '\t',
648 pprInstr (REM size uns reg1 ri reg2)
652 if uns then ptext SLIT("u\t") else char '\t',
660 pprInstr (NOT ri reg)
669 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
670 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
671 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
672 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
673 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
674 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
676 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
677 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
678 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
680 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
681 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
683 pprInstr (NOP) = ptext SLIT("\tnop")
685 pprInstr (CMP cond reg1 ri reg2)
699 ptext SLIT("\tfclr\t"),
703 pprInstr (FABS reg1 reg2)
705 ptext SLIT("\tfabs\t"),
711 pprInstr (FNEG size reg1 reg2)
721 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
722 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
723 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
724 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
726 pprInstr (CVTxy size1 size2 reg1 reg2)
730 case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
737 pprInstr (FCMP size cond reg1 reg2 reg3)
750 pprInstr (FMOV reg1 reg2)
752 ptext SLIT("\tfmov\t"),
758 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
760 pprInstr (BI NEVER reg lab) = empty
762 pprInstr (BI cond reg lab)
772 pprInstr (BF cond reg lab)
783 = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
785 pprInstr (JMP reg addr hint)
787 ptext SLIT("\tjmp\t"),
796 = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
798 pprInstr (JSR reg addr n)
800 ptext SLIT("\tjsr\t"),
806 pprInstr (FUNBEGIN clab)
808 if (externallyVisibleCLabel clab) then
809 hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
812 ptext SLIT("\t.ent "),
821 pp_lab = pprCLabel_asm clab
823 -- NEVER use commas within those string literals, cpp will ruin your day
824 pp_ldgp = hcat [ ptext SLIT(":\n\tldgp $29"), char ',', ptext SLIT("0($27)\n") ]
825 pp_frame = hcat [ ptext SLIT("..ng:\n\t.frame $30"), char ',',
826 ptext SLIT("4240"), char ',',
827 ptext SLIT("$26"), char ',',
828 ptext SLIT("0\n\t.prologue 1") ]
830 pprInstr (FUNEND clab)
831 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
834 Continue with Alpha-only printing bits and bobs:
838 pprRI (RIReg r) = pprReg r
839 pprRI (RIImm r) = pprImm r
841 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> SDoc
843 pprRegRIReg name reg1 ri reg2
855 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
857 pprSizeRegRegReg name size reg1 reg2 reg3
870 #endif {-alpha_TARGET_ARCH-}
873 %************************************************************************
875 \subsubsection{@pprInstr@ for an I386}
877 %************************************************************************
882 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
885 #if 0 /* #ifdef DEBUG */
886 (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
890 pprInstr (MOV size src dst)
891 = pprSizeOpOp SLIT("mov") size src dst
892 pprInstr (MOVZxL sizes src dst) = pprSizeOpOpCoerce SLIT("movz") sizes L src dst
893 pprInstr (MOVSxL sizes src dst) = pprSizeOpOpCoerce SLIT("movs") sizes L src dst
895 -- here we do some patching, since the physical registers are only set late
896 -- in the code generation.
897 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
899 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
900 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
902 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
903 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
905 = pprInstr (ADD size (OpImm displ) dst)
906 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
908 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
909 = pprSizeOp SLIT("dec") size dst
910 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
911 = pprSizeOp SLIT("inc") size dst
912 pprInstr (ADD size src dst)
913 = pprSizeOpOp SLIT("add") size src dst
914 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
915 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
917 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
918 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
919 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
920 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
921 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
923 pprInstr (SHL size imm dst) = pprSizeImmOp SLIT("shl") size imm dst
924 pprInstr (SAR size imm dst) = pprSizeImmOp SLIT("sar") size imm dst
925 pprInstr (SHR size imm dst) = pprSizeImmOp SLIT("shr") size imm dst
926 pprInstr (BT size imm src) = pprSizeImmOp SLIT("bt") size imm src
928 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
929 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
930 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
931 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
932 pprInstr PUSHA = ptext SLIT("\tpushal")
933 pprInstr POPA = ptext SLIT("\tpopal")
935 pprInstr (NOP) = ptext SLIT("\tnop")
936 pprInstr (CLTD) = ptext SLIT("\tcltd")
938 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
940 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
942 pprInstr (JMP dsts (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
943 pprInstr (JMP dsts op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand L op)
944 pprInstr (CALL imm) = (<>) (ptext SLIT("\tcall ")) (pprImm imm)
946 pprInstr (IQUOT sz src dst) = pprInstr_quotRem True sz src dst
947 pprInstr (IREM sz src dst) = pprInstr_quotRem False sz src dst
949 -- Simulating a flat register set on the x86 FP stack is tricky.
950 -- you have to free %st(7) before pushing anything on the FP reg stack
951 -- so as to preclude the possibility of a FP stack overflow exception.
952 pprInstr g@(GMOV src dst)
956 = pprG g (hcat [gtab, gpush src 0, gsemi, gpop dst 1])
958 -- GLD sz addr dst ==> FFREE %st(7) ; FLDsz addr ; FSTP (dst+1)
959 pprInstr g@(GLD sz addr dst)
960 = pprG g (hcat [gtab, text "ffree %st(7) ; fld", pprSize sz, gsp,
961 pprAddr addr, gsemi, gpop dst 1])
963 -- GST sz src addr ==> FFREE %st(7) ; FLD dst ; FSTPsz addr
964 pprInstr g@(GST sz src addr)
965 = pprG g (hcat [gtab, gpush src 0, gsemi,
966 text "fstp", pprSize sz, gsp, pprAddr addr])
968 pprInstr g@(GLDZ dst)
969 = pprG g (hcat [gtab, text "ffree %st(7) ; fldz ; ", gpop dst 1])
970 pprInstr g@(GLD1 dst)
971 = pprG g (hcat [gtab, text "ffree %st(7) ; fld1 ; ", gpop dst 1])
973 pprInstr g@(GFTOD src dst)
975 pprInstr g@(GFTOI src dst)
978 pprInstr g@(GDTOF src dst)
980 pprInstr g@(GDTOI src dst)
983 pprInstr g@(GITOF src dst)
984 = pprInstr (GITOD src dst)
985 pprInstr g@(GITOD src dst)
986 = pprG g (hcat [gtab, text "pushl ", pprReg L src,
987 text " ; ffree %st(7); fildl (%esp) ; ",
988 gpop dst 1, text " ; addl $4,%esp"])
990 pprInstr g@(GCMP sz src1 src2)
991 = pprG g (hcat [gtab, text "pushl %eax ; ",gpush src1 0]
993 hcat [gtab, text "fcomp ", greg src2 1,
994 text "; fstsw %ax ; sahf ; popl %eax"])
996 pprInstr g@(GABS sz src dst)
997 = pprG g (hcat [gtab, gpush src 0, text " ; fabs ; ", gpop dst 1])
998 pprInstr g@(GNEG sz src dst)
999 = pprG g (hcat [gtab, gpush src 0, text " ; fchs ; ", gpop dst 1])
1001 pprInstr g@(GSQRT sz src dst)
1002 = pprG g (hcat [gtab, gpush src 0, text " ; fsqrt"] $$
1003 hcat [gtab, gcoerceto sz, gpop dst 1])
1004 pprInstr g@(GSIN sz src dst)
1005 = pprG g (hcat [gtab, gpush src 0, text " ; fsin"] $$
1006 hcat [gtab, gcoerceto sz, gpop dst 1])
1007 pprInstr g@(GCOS sz src dst)
1008 = pprG g (hcat [gtab, gpush src 0, text " ; fcos"] $$
1009 hcat [gtab, gcoerceto sz, gpop dst 1])
1010 pprInstr g@(GTAN sz src dst)
1011 = pprG g (hcat [gtab, text "ffree %st(6) ; ",
1012 gpush src 0, text " ; fptan ; ",
1013 text " fstp %st(0)"] $$
1014 hcat [gtab, gcoerceto sz, gpop dst 1])
1016 -- In the translations for GADD, GMUL, GSUB and GDIV,
1017 -- the first two cases are mere optimisations. The otherwise clause
1018 -- generates correct code under all circumstances.
1020 pprInstr g@(GADD sz src1 src2 dst)
1022 = pprG g (text "\t#GADD-xxxcase1" $$
1023 hcat [gtab, gpush src2 0,
1024 text " ; faddp %st(0),", greg src1 1])
1026 = pprG g (text "\t#GADD-xxxcase2" $$
1027 hcat [gtab, gpush src1 0,
1028 text " ; faddp %st(0),", greg src2 1])
1030 = pprG g (hcat [gtab, gpush src1 0,
1031 text " ; fadd ", greg src2 1, text ",%st(0)",
1035 pprInstr g@(GMUL sz src1 src2 dst)
1037 = pprG g (text "\t#GMUL-xxxcase1" $$
1038 hcat [gtab, gpush src2 0,
1039 text " ; fmulp %st(0),", greg src1 1])
1041 = pprG g (text "\t#GMUL-xxxcase2" $$
1042 hcat [gtab, gpush src1 0,
1043 text " ; fmulp %st(0),", greg src2 1])
1045 = pprG g (hcat [gtab, gpush src1 0,
1046 text " ; fmul ", greg src2 1, text ",%st(0)",
1050 pprInstr g@(GSUB sz src1 src2 dst)
1052 = pprG g (text "\t#GSUB-xxxcase1" $$
1053 hcat [gtab, gpush src2 0,
1054 text " ; fsubrp %st(0),", greg src1 1])
1056 = pprG g (text "\t#GSUB-xxxcase2" $$
1057 hcat [gtab, gpush src1 0,
1058 text " ; fsubp %st(0),", greg src2 1])
1060 = pprG g (hcat [gtab, gpush src1 0,
1061 text " ; fsub ", greg src2 1, text ",%st(0)",
1065 pprInstr g@(GDIV sz src1 src2 dst)
1067 = pprG g (text "\t#GDIV-xxxcase1" $$
1068 hcat [gtab, gpush src2 0,
1069 text " ; fdivrp %st(0),", greg src1 1])
1071 = pprG g (text "\t#GDIV-xxxcase2" $$
1072 hcat [gtab, gpush src1 0,
1073 text " ; fdivp %st(0),", greg src2 1])
1075 = pprG g (hcat [gtab, gpush src1 0,
1076 text " ; fdiv ", greg src2 1, text ",%st(0)",
1081 = vcat [ ptext SLIT("\tffree %st(0) ;ffree %st(1) ;ffree %st(2) ;ffree %st(3)"),
1082 ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)")
1086 pprInstr_quotRem isQuot sz src dst
1087 | case sz of L -> False; _ -> True
1088 = panic "pprInstr_quotRem: dunno how to do non-32bit operands"
1091 (text "\t# BEGIN " <> fakeInsn),
1092 (text "\tpushl $0; pushl %eax; pushl %edx; pushl " <> pprOperand sz src),
1093 (text "\tmovl " <> pprOperand sz dst <> text ",%eax; xorl %edx,%edx; cltd"),
1094 (text "\tdivl 0(%esp); movl " <> text resReg <> text ",12(%esp)"),
1095 (text "\tpopl %edx; popl %edx; popl %eax; popl " <> pprOperand sz dst),
1096 (text "\t# END " <> fakeInsn)
1099 resReg = if isQuot then "%eax" else "%edx"
1100 opStr = if isQuot then "IQUOT" else "IREM"
1101 fakeInsn = text opStr <+> pprOperand sz src <> char ',' <+> pprOperand sz dst
1103 --------------------------
1105 -- coerce %st(0) to the specified size
1106 gcoerceto DF = empty
1107 gcoerceto F = text "subl $4,%esp ; fstps (%esp) ; flds (%esp) ; addl $4,%esp ; "
1110 = hcat [text "ffree %st(7) ; fld ", greg reg offset]
1112 = hcat [text "fstp ", greg reg offset]
1114 bogus = text "\tbogus"
1115 greg reg offset = text "%st(" <> int (gregno reg - 8+offset) <> char ')'
1120 gregno (RealReg i) = i
1121 gregno other = --pprPanic "gregno" (ppr other)
1122 999 -- bogus; only needed for debug printing
1124 pprG :: Instr -> SDoc -> SDoc
1126 = (char '#' <> pprGInstr fake) $$ actual
1128 pprGInstr (GMOV src dst) = pprSizeRegReg SLIT("gmov") DF src dst
1129 pprGInstr (GLD sz src dst) = pprSizeAddrReg SLIT("gld") sz src dst
1130 pprGInstr (GST sz src dst) = pprSizeRegAddr SLIT("gst") sz src dst
1132 pprGInstr (GLDZ dst) = pprSizeReg SLIT("gldz") DF dst
1133 pprGInstr (GLD1 dst) = pprSizeReg SLIT("gld1") DF dst
1135 pprGInstr (GFTOD src dst) = pprSizeSizeRegReg SLIT("gftod") F DF src dst
1136 pprGInstr (GFTOI src dst) = pprSizeSizeRegReg SLIT("gftoi") F L src dst
1138 pprGInstr (GDTOF src dst) = pprSizeSizeRegReg SLIT("gdtof") DF F src dst
1139 pprGInstr (GDTOI src dst) = pprSizeSizeRegReg SLIT("gdtoi") DF L src dst
1141 pprGInstr (GITOF src dst) = pprSizeSizeRegReg SLIT("gitof") L F src dst
1142 pprGInstr (GITOD src dst) = pprSizeSizeRegReg SLIT("gitod") L DF src dst
1144 pprGInstr (GCMP sz src dst) = pprSizeRegReg SLIT("gcmp") sz src dst
1145 pprGInstr (GABS sz src dst) = pprSizeRegReg SLIT("gabs") sz src dst
1146 pprGInstr (GNEG sz src dst) = pprSizeRegReg SLIT("gneg") sz src dst
1147 pprGInstr (GSQRT sz src dst) = pprSizeRegReg SLIT("gsqrt") sz src dst
1148 pprGInstr (GSIN sz src dst) = pprSizeRegReg SLIT("gsin") sz src dst
1149 pprGInstr (GCOS sz src dst) = pprSizeRegReg SLIT("gcos") sz src dst
1150 pprGInstr (GTAN sz src dst) = pprSizeRegReg SLIT("gtan") sz src dst
1152 pprGInstr (GADD sz src1 src2 dst) = pprSizeRegRegReg SLIT("gadd") sz src1 src2 dst
1153 pprGInstr (GSUB sz src1 src2 dst) = pprSizeRegRegReg SLIT("gsub") sz src1 src2 dst
1154 pprGInstr (GMUL sz src1 src2 dst) = pprSizeRegRegReg SLIT("gmul") sz src1 src2 dst
1155 pprGInstr (GDIV sz src1 src2 dst) = pprSizeRegRegReg SLIT("gdiv") sz src1 src2 dst
1158 Continue with I386-only printing bits and bobs:
1160 pprDollImm :: Imm -> SDoc
1162 pprDollImm i = ptext SLIT("$") <> pprImm i
1164 pprOperand :: Size -> Operand -> SDoc
1165 pprOperand s (OpReg r) = pprReg s r
1166 pprOperand s (OpImm i) = pprDollImm i
1167 pprOperand s (OpAddr ea) = pprAddr ea
1169 pprSizeImmOp :: FAST_STRING -> Size -> Imm -> Operand -> SDoc
1170 pprSizeImmOp name size imm op1
1182 pprSizeOp :: FAST_STRING -> Size -> Operand -> SDoc
1183 pprSizeOp name size op1
1192 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1193 pprSizeOpOp name size op1 op2
1199 pprOperand size op1,
1204 pprSizeByteOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1205 pprSizeByteOpOp name size op1 op2
1216 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> SDoc
1217 pprSizeOpReg name size op1 reg
1223 pprOperand size op1,
1228 pprSizeReg :: FAST_STRING -> Size -> Reg -> SDoc
1229 pprSizeReg name size reg1
1238 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1239 pprSizeRegReg name size reg1 reg2
1250 pprSizeSizeRegReg :: FAST_STRING -> Size -> Size -> Reg -> Reg -> SDoc
1251 pprSizeSizeRegReg name size1 size2 reg1 reg2
1263 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1264 pprSizeRegRegReg name size reg1 reg2 reg3
1277 pprSizeAddr :: FAST_STRING -> Size -> MachRegsAddr -> SDoc
1278 pprSizeAddr name size op
1287 pprSizeAddrReg :: FAST_STRING -> Size -> MachRegsAddr -> Reg -> SDoc
1288 pprSizeAddrReg name size op dst
1299 pprSizeRegAddr :: FAST_STRING -> Size -> Reg -> MachRegsAddr -> SDoc
1300 pprSizeRegAddr name size src op
1311 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1312 pprOpOp name size op1 op2
1316 pprOperand size op1,
1321 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> SDoc
1322 pprSizeOpOpCoerce name size1 size2 op1 op2
1323 = hcat [ char '\t', ptext name, pprSize size1, pprSize size2, space,
1324 pprOperand size1 op1,
1326 pprOperand size2 op2
1329 pprCondInstr :: FAST_STRING -> Cond -> SDoc -> SDoc
1330 pprCondInstr name cond arg
1331 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1333 #endif {-i386_TARGET_ARCH-}
1336 %************************************************************************
1338 \subsubsection{@pprInstr@ for a SPARC}
1340 %************************************************************************
1343 #if sparc_TARGET_ARCH
1345 -- a clumsy hack for now, to handle possible double alignment problems
1347 -- even clumsier, to allow for RegReg regs that show when doing indexed
1348 -- reads (bytearrays).
1351 -- Translate to the following:
1354 -- ld [g1+4],%f(n+1)
1355 -- sub g1,g2,g1 -- to restore g1
1356 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1358 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1359 hcat [pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg],
1360 hcat [pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)],
1361 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1366 -- ld [addr+4],%f(n+1)
1367 pprInstr (LD DF addr reg) | isJust off_addr
1369 hcat [pp_ld_lbracket, pprAddr addr, pp_rbracket_comma, pprReg reg],
1370 hcat [pp_ld_lbracket, pprAddr addr2, pp_rbracket_comma,pprReg (fPair reg)]
1373 off_addr = addrOffset addr 4
1374 addr2 = case off_addr of Just x -> x
1377 pprInstr (LD size addr reg)
1388 -- The same clumsy hack as above
1390 -- Translate to the following:
1393 -- st %f(n+1),[g1+4]
1394 -- sub g1,g2,g1 -- to restore g1
1395 pprInstr (ST DF reg (AddrRegReg g1 g2))
1397 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1398 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1400 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1401 pprReg g1, ptext SLIT("+4]")],
1402 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1407 -- st %f(n+1),[addr+4]
1408 pprInstr (ST DF reg addr) | isJust off_addr
1410 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1411 pprAddr addr, rbrack],
1412 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1413 pprAddr addr2, rbrack]
1416 off_addr = addrOffset addr 4
1417 addr2 = case off_addr of Just x -> x
1419 -- no distinction is made between signed and unsigned bytes on stores for the
1420 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1421 -- so we call a special-purpose pprSize for ST..
1423 pprInstr (ST size reg addr)
1434 pprInstr (ADD x cc reg1 ri reg2)
1435 | not x && not cc && riZero ri
1436 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1438 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1440 pprInstr (SUB x cc reg1 ri reg2)
1441 | not x && cc && reg2 == g0
1442 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1443 | not x && not cc && riZero ri
1444 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1446 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1448 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1449 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1451 pprInstr (OR b reg1 ri reg2)
1452 | not b && reg1 == g0
1453 = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1455 = pprRegRIReg SLIT("or") b reg1 ri reg2
1457 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1459 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1460 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1462 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1463 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1464 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1466 pprInstr (SETHI imm reg)
1468 ptext SLIT("\tsethi\t"),
1474 pprInstr NOP = ptext SLIT("\tnop")
1476 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1477 pprInstr (FABS DF reg1 reg2)
1478 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1479 (if (reg1 == reg2) then empty
1480 else (<>) (char '\n')
1481 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1483 pprInstr (FADD size reg1 reg2 reg3)
1484 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1485 pprInstr (FCMP e size reg1 reg2)
1486 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1487 pprInstr (FDIV size reg1 reg2 reg3)
1488 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1490 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1491 pprInstr (FMOV DF reg1 reg2)
1492 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1493 (if (reg1 == reg2) then empty
1494 else (<>) (char '\n')
1495 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1497 pprInstr (FMUL size reg1 reg2 reg3)
1498 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1500 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1501 pprInstr (FNEG DF reg1 reg2)
1502 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1503 (if (reg1 == reg2) then empty
1504 else (<>) (char '\n')
1505 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1507 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1508 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1509 pprInstr (FxTOy size1 size2 reg1 reg2)
1522 pprReg reg1, comma, pprReg reg2
1526 pprInstr (BI cond b lab)
1528 ptext SLIT("\tb"), pprCond cond,
1529 if b then pp_comma_a else empty,
1534 pprInstr (BF cond b lab)
1536 ptext SLIT("\tfb"), pprCond cond,
1537 if b then pp_comma_a else empty,
1542 pprInstr (JMP dsts addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1544 pprInstr (CALL imm n _)
1545 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1548 Continue with SPARC-only printing bits and bobs:
1551 pprRI (RIReg r) = pprReg r
1552 pprRI (RIImm r) = pprImm r
1554 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1555 pprSizeRegReg name size reg1 reg2
1560 F -> ptext SLIT("s\t")
1561 DF -> ptext SLIT("d\t")),
1567 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1568 pprSizeRegRegReg name size reg1 reg2 reg3
1573 F -> ptext SLIT("s\t")
1574 DF -> ptext SLIT("d\t")),
1582 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> SDoc
1583 pprRegRIReg name b reg1 ri reg2
1587 if b then ptext SLIT("cc\t") else char '\t',
1595 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> SDoc
1596 pprRIReg name b ri reg1
1600 if b then ptext SLIT("cc\t") else char '\t',
1606 pp_ld_lbracket = ptext SLIT("\tld\t[")
1607 pp_rbracket_comma = text "],"
1608 pp_comma_lbracket = text ",["
1609 pp_comma_a = text ",a"
1611 #endif {-sparc_TARGET_ARCH-}