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 CStrings ( charToC )
22 import Maybes ( maybeToBool )
23 import Stix ( CodeSegment(..), StixTree(..) )
24 import Char ( isPrint, isDigit )
29 import Char ( chr, ord )
32 %************************************************************************
34 \subsection{@pprReg@: print a @Reg@}
36 %************************************************************************
38 For x86, the way we print a register name depends
39 on which bit of it we care about. Yurgh.
41 pprUserReg:: Reg -> SDoc
42 pprUserReg = pprReg IF_ARCH_i386(L,)
45 pprReg :: IF_ARCH_i386(Size ->,) Reg -> SDoc
47 pprReg IF_ARCH_i386(s,) r
49 RealReg (I# i) -> ppr_reg_no IF_ARCH_i386(s,) i
50 VirtualRegI u -> text "%vI_" <> ppr u
51 VirtualRegF u -> text "%vF_" <> ppr u
54 ppr_reg_no :: FAST_REG_NO -> SDoc
57 ILIT( 0) -> SLIT("$0"); ILIT( 1) -> SLIT("$1");
58 ILIT( 2) -> SLIT("$2"); ILIT( 3) -> SLIT("$3");
59 ILIT( 4) -> SLIT("$4"); ILIT( 5) -> SLIT("$5");
60 ILIT( 6) -> SLIT("$6"); ILIT( 7) -> SLIT("$7");
61 ILIT( 8) -> SLIT("$8"); ILIT( 9) -> SLIT("$9");
62 ILIT(10) -> SLIT("$10"); ILIT(11) -> SLIT("$11");
63 ILIT(12) -> SLIT("$12"); ILIT(13) -> SLIT("$13");
64 ILIT(14) -> SLIT("$14"); ILIT(15) -> SLIT("$15");
65 ILIT(16) -> SLIT("$16"); ILIT(17) -> SLIT("$17");
66 ILIT(18) -> SLIT("$18"); ILIT(19) -> SLIT("$19");
67 ILIT(20) -> SLIT("$20"); ILIT(21) -> SLIT("$21");
68 ILIT(22) -> SLIT("$22"); ILIT(23) -> SLIT("$23");
69 ILIT(24) -> SLIT("$24"); ILIT(25) -> SLIT("$25");
70 ILIT(26) -> SLIT("$26"); ILIT(27) -> SLIT("$27");
71 ILIT(28) -> SLIT("$28"); ILIT(29) -> SLIT("$29");
72 ILIT(30) -> SLIT("$30"); ILIT(31) -> SLIT("$31");
73 ILIT(32) -> SLIT("$f0"); ILIT(33) -> SLIT("$f1");
74 ILIT(34) -> SLIT("$f2"); ILIT(35) -> SLIT("$f3");
75 ILIT(36) -> SLIT("$f4"); ILIT(37) -> SLIT("$f5");
76 ILIT(38) -> SLIT("$f6"); ILIT(39) -> SLIT("$f7");
77 ILIT(40) -> SLIT("$f8"); ILIT(41) -> SLIT("$f9");
78 ILIT(42) -> SLIT("$f10"); ILIT(43) -> SLIT("$f11");
79 ILIT(44) -> SLIT("$f12"); ILIT(45) -> SLIT("$f13");
80 ILIT(46) -> SLIT("$f14"); ILIT(47) -> SLIT("$f15");
81 ILIT(48) -> SLIT("$f16"); ILIT(49) -> SLIT("$f17");
82 ILIT(50) -> SLIT("$f18"); ILIT(51) -> SLIT("$f19");
83 ILIT(52) -> SLIT("$f20"); ILIT(53) -> SLIT("$f21");
84 ILIT(54) -> SLIT("$f22"); ILIT(55) -> SLIT("$f23");
85 ILIT(56) -> SLIT("$f24"); ILIT(57) -> SLIT("$f25");
86 ILIT(58) -> SLIT("$f26"); ILIT(59) -> SLIT("$f27");
87 ILIT(60) -> SLIT("$f28"); ILIT(61) -> SLIT("$f29");
88 ILIT(62) -> SLIT("$f30"); ILIT(63) -> SLIT("$f31");
89 _ -> SLIT("very naughty alpha register")
93 ppr_reg_no :: Size -> FAST_REG_NO -> SDoc
96 ILIT( 0) -> SLIT("%al"); ILIT( 1) -> SLIT("%bl");
97 ILIT( 2) -> SLIT("%cl"); ILIT( 3) -> SLIT("%dl");
98 _ -> SLIT("very naughty I386 byte register")
101 ppr_reg_no _ i = ptext
103 ILIT( 0) -> SLIT("%eax"); ILIT( 1) -> SLIT("%ebx");
104 ILIT( 2) -> SLIT("%ecx"); ILIT( 3) -> SLIT("%edx");
105 ILIT( 4) -> SLIT("%esi"); ILIT( 5) -> SLIT("%edi");
106 ILIT( 6) -> SLIT("%ebp"); ILIT( 7) -> SLIT("%esp");
107 ILIT( 8) -> SLIT("%fake0"); ILIT( 9) -> SLIT("%fake1");
108 ILIT(10) -> SLIT("%fake2"); ILIT(11) -> SLIT("%fake3");
109 ILIT(12) -> SLIT("%fake4"); ILIT(13) -> SLIT("%fake5");
110 _ -> SLIT("very naughty I386 register")
113 #if sparc_TARGET_ARCH
114 ppr_reg_no :: FAST_REG_NO -> SDoc
117 ILIT( 0) -> SLIT("%g0"); ILIT( 1) -> SLIT("%g1");
118 ILIT( 2) -> SLIT("%g2"); ILIT( 3) -> SLIT("%g3");
119 ILIT( 4) -> SLIT("%g4"); ILIT( 5) -> SLIT("%g5");
120 ILIT( 6) -> SLIT("%g6"); ILIT( 7) -> SLIT("%g7");
121 ILIT( 8) -> SLIT("%o0"); ILIT( 9) -> SLIT("%o1");
122 ILIT(10) -> SLIT("%o2"); ILIT(11) -> SLIT("%o3");
123 ILIT(12) -> SLIT("%o4"); ILIT(13) -> SLIT("%o5");
124 ILIT(14) -> SLIT("%o6"); ILIT(15) -> SLIT("%o7");
125 ILIT(16) -> SLIT("%l0"); ILIT(17) -> SLIT("%l1");
126 ILIT(18) -> SLIT("%l2"); ILIT(19) -> SLIT("%l3");
127 ILIT(20) -> SLIT("%l4"); ILIT(21) -> SLIT("%l5");
128 ILIT(22) -> SLIT("%l6"); ILIT(23) -> SLIT("%l7");
129 ILIT(24) -> SLIT("%i0"); ILIT(25) -> SLIT("%i1");
130 ILIT(26) -> SLIT("%i2"); ILIT(27) -> SLIT("%i3");
131 ILIT(28) -> SLIT("%i4"); ILIT(29) -> SLIT("%i5");
132 ILIT(30) -> SLIT("%i6"); ILIT(31) -> SLIT("%i7");
133 ILIT(32) -> SLIT("%f0"); ILIT(33) -> SLIT("%f1");
134 ILIT(34) -> SLIT("%f2"); ILIT(35) -> SLIT("%f3");
135 ILIT(36) -> SLIT("%f4"); ILIT(37) -> SLIT("%f5");
136 ILIT(38) -> SLIT("%f6"); ILIT(39) -> SLIT("%f7");
137 ILIT(40) -> SLIT("%f8"); ILIT(41) -> SLIT("%f9");
138 ILIT(42) -> SLIT("%f10"); ILIT(43) -> SLIT("%f11");
139 ILIT(44) -> SLIT("%f12"); ILIT(45) -> SLIT("%f13");
140 ILIT(46) -> SLIT("%f14"); ILIT(47) -> SLIT("%f15");
141 ILIT(48) -> SLIT("%f16"); ILIT(49) -> SLIT("%f17");
142 ILIT(50) -> SLIT("%f18"); ILIT(51) -> SLIT("%f19");
143 ILIT(52) -> SLIT("%f20"); ILIT(53) -> SLIT("%f21");
144 ILIT(54) -> SLIT("%f22"); ILIT(55) -> SLIT("%f23");
145 ILIT(56) -> SLIT("%f24"); ILIT(57) -> SLIT("%f25");
146 ILIT(58) -> SLIT("%f26"); ILIT(59) -> SLIT("%f27");
147 ILIT(60) -> SLIT("%f28"); ILIT(61) -> SLIT("%f29");
148 ILIT(62) -> SLIT("%f30"); ILIT(63) -> SLIT("%f31");
149 _ -> SLIT("very naughty sparc register")
154 %************************************************************************
156 \subsection{@pprSize@: print a @Size@}
158 %************************************************************************
161 pprSize :: Size -> SDoc
163 pprSize x = ptext (case x of
164 #if alpha_TARGET_ARCH
167 -- W -> SLIT("w") UNUSED
168 -- WU -> SLIT("wu") UNUSED
169 -- L -> SLIT("l") UNUSED
171 -- FF -> SLIT("f") UNUSED
172 -- DF -> SLIT("d") UNUSED
173 -- GF -> SLIT("g") UNUSED
174 -- SF -> SLIT("s") UNUSED
179 -- HB -> SLIT("b") UNUSED
180 -- S -> SLIT("w") UNUSED
186 #if sparc_TARGET_ARCH
189 -- HW -> SLIT("hw") UNUSED
190 -- HWU -> SLIT("uhw") UNUSED
193 -- D -> SLIT("d") UNUSED
196 pprStSize :: Size -> SDoc
197 pprStSize x = ptext (case x of
200 -- HW -> SLIT("hw") UNUSED
201 -- HWU -> SLIT("uhw") UNUSED
204 -- D -> SLIT("d") UNUSED
210 %************************************************************************
212 \subsection{@pprCond@: print a @Cond@}
214 %************************************************************************
217 pprCond :: Cond -> SDoc
219 pprCond c = ptext (case c of {
220 #if alpha_TARGET_ARCH
231 GEU -> SLIT("ae"); LU -> SLIT("b");
232 EQQ -> SLIT("e"); GTT -> SLIT("g");
233 GE -> SLIT("ge"); GU -> SLIT("a");
234 LTT -> SLIT("l"); LE -> SLIT("le");
235 LEU -> SLIT("be"); NE -> SLIT("ne");
236 NEG -> SLIT("s"); POS -> SLIT("ns");
237 ALWAYS -> SLIT("mp") -- hack
239 #if sparc_TARGET_ARCH
240 ALWAYS -> SLIT(""); NEVER -> SLIT("n");
241 GEU -> SLIT("geu"); LU -> SLIT("lu");
242 EQQ -> SLIT("e"); GTT -> SLIT("g");
243 GE -> SLIT("ge"); GU -> SLIT("gu");
244 LTT -> SLIT("l"); LE -> SLIT("le");
245 LEU -> SLIT("leu"); NE -> SLIT("ne");
246 NEG -> SLIT("neg"); POS -> SLIT("pos");
247 VC -> SLIT("vc"); VS -> SLIT("vs")
252 %************************************************************************
254 \subsection{@pprImm@: print an @Imm@}
256 %************************************************************************
259 pprImm :: Imm -> SDoc
261 pprImm (ImmInt i) = int i
262 pprImm (ImmInteger i) = integer i
263 pprImm (ImmCLbl l) = (if labelDynamic l then text "__imp_" else empty)
265 pprImm (ImmIndex l i) = (if labelDynamic l then text "__imp_" else empty)
266 <> pprCLabel_asm l <> char '+' <> int i
267 pprImm (ImmLit s) = s
269 pprImm (ImmLab dll s) = (if underscorePrefix then char '_' else empty)
270 <> (if dll then text "_imp__" else empty)
273 #if sparc_TARGET_ARCH
275 = hcat [ pp_lo, pprImm i, rparen ]
280 = hcat [ pp_hi, pprImm i, rparen ]
286 %************************************************************************
288 \subsection{@pprAddr@: print an @Addr@}
290 %************************************************************************
293 pprAddr :: MachRegsAddr -> SDoc
295 #if alpha_TARGET_ARCH
296 pprAddr (AddrReg r) = parens (pprReg r)
297 pprAddr (AddrImm i) = pprImm i
298 pprAddr (AddrRegImm r1 i)
299 = (<>) (pprImm i) (parens (pprReg r1))
305 pprAddr (ImmAddr imm off)
306 = let pp_imm = pprImm imm
310 else if (off < 0) then
313 pp_imm <> char '+' <> int off
315 pprAddr (AddrBaseIndex base index displacement)
317 pp_disp = ppr_disp displacement
318 pp_off p = pp_disp <> char '(' <> p <> char ')'
319 pp_reg r = pprReg L r
322 (Nothing, Nothing) -> pp_disp
323 (Just b, Nothing) -> pp_off (pp_reg b)
324 (Nothing, Just (r,i)) -> pp_off (pp_reg r <> comma <> int i)
325 (Just b, Just (r,i)) -> pp_off (pp_reg b <> comma <> pp_reg r
328 ppr_disp (ImmInt 0) = empty
329 ppr_disp imm = pprImm imm
334 #if sparc_TARGET_ARCH
335 pprAddr (AddrRegReg r1 (RealReg 0)) = pprReg r1
337 pprAddr (AddrRegReg r1 r2)
338 = hcat [ pprReg r1, char '+', pprReg r2 ]
340 pprAddr (AddrRegImm r1 (ImmInt i))
342 | not (fits13Bits i) = largeOffsetError i
343 | otherwise = hcat [ pprReg r1, pp_sign, int i ]
345 pp_sign = if i > 0 then char '+' else empty
347 pprAddr (AddrRegImm r1 (ImmInteger i))
349 | not (fits13Bits i) = largeOffsetError i
350 | otherwise = hcat [ pprReg r1, pp_sign, integer i ]
352 pp_sign = if i > 0 then char '+' else empty
354 pprAddr (AddrRegImm r1 imm)
355 = hcat [ pprReg r1, char '+', pprImm imm ]
359 %************************************************************************
361 \subsection{@pprInstr@: print an @Instr@}
363 %************************************************************************
366 pprInstr :: Instr -> SDoc
368 --pprInstr (COMMENT s) = empty -- nuke 'em
370 = IF_ARCH_alpha( ((<>) (ptext SLIT("\t# ")) (ptext s))
371 ,IF_ARCH_sparc( ((<>) (ptext SLIT("! ")) (ptext s))
372 ,IF_ARCH_i386( ((<>) (ptext SLIT("# ")) (ptext s))
376 = pprInstr (COMMENT (_PK_ ("\tdelta = " ++ show d)))
378 pprInstr (SEGMENT TextSegment)
379 = IF_ARCH_alpha(ptext SLIT("\t.text\n\t.align 3") {-word boundary-}
380 ,IF_ARCH_sparc(ptext SLIT(".text\n\t.align 4") {-word boundary-}
381 ,IF_ARCH_i386((text ".text\n\t.align 4,0x90") {-needs per-OS variation!-}
384 pprInstr (SEGMENT DataSegment)
386 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
387 ,IF_ARCH_sparc(SLIT(".data\n\t.align 8") {-<8 will break double constants -}
388 ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
391 pprInstr (LABEL clab)
393 pp_lab = pprCLabel_asm clab
396 if not (externallyVisibleCLabel clab) then
400 IF_ARCH_alpha(SLIT("\t.globl\t")
401 ,IF_ARCH_i386(SLIT(".globl ")
402 ,IF_ARCH_sparc(SLIT(".global\t")
404 , pp_lab, char '\n'],
409 pprInstr (ASCII False{-no backslash conversion-} str)
410 = hcat [ ptext SLIT("\t.asciz "), char '\"', text str, char '"' ]
412 pprInstr (ASCII True str)
414 -- The Solaris assembler doesn't understand \x escapes in
418 asciify :: String -> SDoc
419 asciify "" = text "\t.ascii \"\\0\""
421 = let fst = take 16 str
423 this = text ("\t.ascii \""
424 ++ concat (map asciify_char fst)
426 in this $$ asciify rest
427 asciify_char :: Char -> String
428 asciify_char c = '\\' : 'x' : hshow (ord c)
430 = vcat (map do1 (str ++ [chr 0]))
433 do1 c = text "\t.byte\t0x" <> text (hshow (ord c))
435 hshow :: Int -> String
436 hshow n | n >= 0 && n <= 255
437 = [ tab !! (n `div` 16), tab !! (n `mod` 16)]
438 tab = "0123456789ABCDEF"
442 = vcat (concatMap (ppr_item s) xs)
445 #if alpha_TARGET_ARCH
446 ppr_item = error "ppr_item on Alpha"
448 #if sparc_TARGET_ARCH
449 -- copy n paste of x86 version
450 ppr_item B x = [text "\t.byte\t" <> pprImm x]
451 ppr_item W x = [text "\t.long\t" <> pprImm x]
452 ppr_item F (ImmFloat r)
453 = let bs = floatToBytes (fromRational r)
454 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
455 ppr_item DF (ImmDouble r)
456 = let bs = doubleToBytes (fromRational r)
457 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
460 ppr_item B x = [text "\t.byte\t" <> pprImm x]
461 ppr_item L x = [text "\t.long\t" <> pprImm x]
462 ppr_item F (ImmFloat r)
463 = let bs = floatToBytes (fromRational r)
464 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
465 ppr_item DF (ImmDouble r)
466 = let bs = doubleToBytes (fromRational r)
467 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
470 -- floatToBytes and doubleToBytes convert to the host's byte
471 -- order. Providing that we're not cross-compiling for a
472 -- target with the opposite endianness, this should work ok
474 floatToBytes :: Float -> [Int]
477 arr <- newFloatArray ((0::Int),3)
478 writeFloatArray arr 0 f
479 i0 <- readCharArray arr 0
480 i1 <- readCharArray arr 1
481 i2 <- readCharArray arr 2
482 i3 <- readCharArray arr 3
483 return (map ord [i0,i1,i2,i3])
486 doubleToBytes :: Double -> [Int]
489 arr <- newDoubleArray ((0::Int),7)
490 writeDoubleArray arr 0 d
491 i0 <- readCharArray arr 0
492 i1 <- readCharArray arr 1
493 i2 <- readCharArray arr 2
494 i3 <- readCharArray arr 3
495 i4 <- readCharArray arr 4
496 i5 <- readCharArray arr 5
497 i6 <- readCharArray arr 6
498 i7 <- readCharArray arr 7
499 return (map ord [i0,i1,i2,i3,i4,i5,i6,i7])
502 -- fall through to rest of (machine-specific) pprInstr...
505 %************************************************************************
507 \subsubsection{@pprInstr@ for an Alpha}
509 %************************************************************************
512 #if alpha_TARGET_ARCH
514 pprInstr (LD size reg addr)
524 pprInstr (LDA reg addr)
526 ptext SLIT("\tlda\t"),
532 pprInstr (LDAH reg addr)
534 ptext SLIT("\tldah\t"),
540 pprInstr (LDGP reg addr)
542 ptext SLIT("\tldgp\t"),
548 pprInstr (LDI size reg imm)
558 pprInstr (ST size reg addr)
570 ptext SLIT("\tclr\t"),
574 pprInstr (ABS size ri reg)
584 pprInstr (NEG size ov ri reg)
588 if ov then ptext SLIT("v\t") else char '\t',
594 pprInstr (ADD size ov reg1 ri reg2)
598 if ov then ptext SLIT("v\t") else char '\t',
606 pprInstr (SADD size scale reg1 ri reg2)
608 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
619 pprInstr (SUB size ov reg1 ri reg2)
623 if ov then ptext SLIT("v\t") else char '\t',
631 pprInstr (SSUB size scale reg1 ri reg2)
633 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
644 pprInstr (MUL size ov reg1 ri reg2)
648 if ov then ptext SLIT("v\t") else char '\t',
656 pprInstr (DIV size uns reg1 ri reg2)
660 if uns then ptext SLIT("u\t") else char '\t',
668 pprInstr (REM size uns reg1 ri reg2)
672 if uns then ptext SLIT("u\t") else char '\t',
680 pprInstr (NOT ri reg)
689 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
690 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
691 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
692 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
693 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
694 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
696 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
697 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
698 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
700 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
701 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
703 pprInstr (NOP) = ptext SLIT("\tnop")
705 pprInstr (CMP cond reg1 ri reg2)
719 ptext SLIT("\tfclr\t"),
723 pprInstr (FABS reg1 reg2)
725 ptext SLIT("\tfabs\t"),
731 pprInstr (FNEG size reg1 reg2)
741 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
742 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
743 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
744 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
746 pprInstr (CVTxy size1 size2 reg1 reg2)
750 case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
757 pprInstr (FCMP size cond reg1 reg2 reg3)
770 pprInstr (FMOV reg1 reg2)
772 ptext SLIT("\tfmov\t"),
778 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
780 pprInstr (BI NEVER reg lab) = empty
782 pprInstr (BI cond reg lab)
792 pprInstr (BF cond reg lab)
803 = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
805 pprInstr (JMP reg addr hint)
807 ptext SLIT("\tjmp\t"),
816 = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
818 pprInstr (JSR reg addr n)
820 ptext SLIT("\tjsr\t"),
826 pprInstr (FUNBEGIN clab)
828 if (externallyVisibleCLabel clab) then
829 hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
832 ptext SLIT("\t.ent "),
841 pp_lab = pprCLabel_asm clab
843 -- NEVER use commas within those string literals, cpp will ruin your day
844 pp_ldgp = hcat [ ptext SLIT(":\n\tldgp $29"), char ',', ptext SLIT("0($27)\n") ]
845 pp_frame = hcat [ ptext SLIT("..ng:\n\t.frame $30"), char ',',
846 ptext SLIT("4240"), char ',',
847 ptext SLIT("$26"), char ',',
848 ptext SLIT("0\n\t.prologue 1") ]
850 pprInstr (FUNEND clab)
851 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
854 Continue with Alpha-only printing bits and bobs:
858 pprRI (RIReg r) = pprReg r
859 pprRI (RIImm r) = pprImm r
861 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> SDoc
863 pprRegRIReg name reg1 ri reg2
875 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
877 pprSizeRegRegReg name size reg1 reg2 reg3
890 #endif {-alpha_TARGET_ARCH-}
893 %************************************************************************
895 \subsubsection{@pprInstr@ for an I386}
897 %************************************************************************
902 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
905 #if 0 /* #ifdef DEBUG */
906 (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
910 pprInstr (MOV size src dst)
911 = pprSizeOpOp SLIT("mov") size src dst
912 pprInstr (MOVZxL sizes src dst) = pprSizeOpOpCoerce SLIT("movz") sizes L src dst
913 pprInstr (MOVSxL sizes src dst) = pprSizeOpOpCoerce SLIT("movs") sizes L src dst
915 -- here we do some patching, since the physical registers are only set late
916 -- in the code generation.
917 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
919 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
920 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
922 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
923 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
925 = pprInstr (ADD size (OpImm displ) dst)
926 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
928 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
929 = pprSizeOp SLIT("dec") size dst
930 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
931 = pprSizeOp SLIT("inc") size dst
932 pprInstr (ADD size src dst)
933 = pprSizeOpOp SLIT("add") size src dst
934 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
935 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
936 pprInstr (IDIV size op) = pprSizeOp SLIT("idiv") size op
938 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
939 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
940 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
941 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
942 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
944 pprInstr (SHL size imm dst) = pprSizeImmOp SLIT("shl") size imm dst
945 pprInstr (SAR size imm dst) = pprSizeImmOp SLIT("sar") size imm dst
946 pprInstr (SHR size imm dst) = pprSizeImmOp SLIT("shr") size imm dst
947 pprInstr (BT size imm src) = pprSizeImmOp SLIT("bt") size imm src
949 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
950 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
951 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
952 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
953 pprInstr PUSHA = ptext SLIT("\tpushal")
954 pprInstr POPA = ptext SLIT("\tpopal")
956 pprInstr (NOP) = ptext SLIT("\tnop")
957 pprInstr (CLTD) = ptext SLIT("\tcltd")
959 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
961 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
963 pprInstr (JMP (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
964 pprInstr (JMP op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand L op)
966 = (<>) (ptext SLIT("\tcall ")) (pprImm imm)
969 -- Simulating a flat register set on the x86 FP stack is tricky.
970 -- you have to free %st(7) before pushing anything on the FP reg stack
971 -- so as to preclude the possibility of a FP stack overflow exception.
972 pprInstr g@(GMOV src dst)
976 = pprG g (hcat [gtab, gpush src 0, gsemi, gpop dst 1])
978 -- GLD sz addr dst ==> FFREE %st(7) ; FLDsz addr ; FSTP (dst+1)
979 pprInstr g@(GLD sz addr dst)
980 = pprG g (hcat [gtab, text "ffree %st(7) ; fld", pprSize sz, gsp,
981 pprAddr addr, gsemi, gpop dst 1])
983 -- GST sz src addr ==> FFREE %st(7) ; FLD dst ; FSTPsz addr
984 pprInstr g@(GST sz src addr)
985 = pprG g (hcat [gtab, gpush src 0, gsemi,
986 text "fstp", pprSize sz, gsp, pprAddr addr])
988 pprInstr g@(GLDZ dst)
989 = pprG g (hcat [gtab, text "ffree %st(7) ; fldz ; ", gpop dst 1])
990 pprInstr g@(GLD1 dst)
991 = pprG g (hcat [gtab, text "ffree %st(7) ; fld1 ; ", gpop dst 1])
993 pprInstr g@(GFTOD src dst)
995 pprInstr g@(GFTOI src dst)
998 pprInstr g@(GDTOF src dst)
1000 pprInstr g@(GDTOI src dst)
1003 pprInstr g@(GITOF src dst)
1004 = pprInstr (GITOD src dst)
1005 pprInstr g@(GITOD src dst)
1006 = pprG g (hcat [gtab, text "pushl ", pprReg L src,
1007 text " ; ffree %st(7); fildl (%esp) ; ",
1008 gpop dst 1, text " ; addl $4,%esp"])
1010 pprInstr g@(GCMP sz src1 src2)
1011 = pprG g (hcat [gtab, text "pushl %eax ; ",gpush src1 0]
1013 hcat [gtab, text "fcomp ", greg src2 1,
1014 text "; fstsw %ax ; sahf ; popl %eax"])
1016 pprInstr g@(GABS sz src dst)
1017 = pprG g (hcat [gtab, gpush src 0, text " ; fabs ; ", gpop dst 1])
1018 pprInstr g@(GNEG sz src dst)
1019 = pprG g (hcat [gtab, gpush src 0, text " ; fchs ; ", gpop dst 1])
1021 pprInstr g@(GSQRT sz src dst)
1022 = pprG g (hcat [gtab, gpush src 0, text " ; fsqrt"] $$
1023 hcat [gtab, gcoerceto sz, gpop dst 1])
1024 pprInstr g@(GSIN sz src dst)
1025 = pprG g (hcat [gtab, gpush src 0, text " ; fsin"] $$
1026 hcat [gtab, gcoerceto sz, gpop dst 1])
1027 pprInstr g@(GCOS sz src dst)
1028 = pprG g (hcat [gtab, gpush src 0, text " ; fcos"] $$
1029 hcat [gtab, gcoerceto sz, gpop dst 1])
1030 pprInstr g@(GTAN sz src dst)
1031 = pprG g (hcat [gtab, text "ffree %st(6) ; ",
1032 gpush src 0, text " ; fptan ; ",
1033 text " fstp %st(0)"] $$
1034 hcat [gtab, gcoerceto sz, gpop dst 1])
1036 -- In the translations for GADD, GMUL, GSUB and GDIV,
1037 -- the first two cases are mere optimisations. The otherwise clause
1038 -- generates correct code under all circumstances.
1040 pprInstr g@(GADD sz src1 src2 dst)
1042 = pprG g (text "\t#GADD-xxxcase1" $$
1043 hcat [gtab, gpush src2 0,
1044 text " ; faddp %st(0),", greg src1 1])
1046 = pprG g (text "\t#GADD-xxxcase2" $$
1047 hcat [gtab, gpush src1 0,
1048 text " ; faddp %st(0),", greg src2 1])
1050 = pprG g (hcat [gtab, gpush src1 0,
1051 text " ; fadd ", greg src2 1, text ",%st(0)",
1055 pprInstr g@(GMUL sz src1 src2 dst)
1057 = pprG g (text "\t#GMUL-xxxcase1" $$
1058 hcat [gtab, gpush src2 0,
1059 text " ; fmulp %st(0),", greg src1 1])
1061 = pprG g (text "\t#GMUL-xxxcase2" $$
1062 hcat [gtab, gpush src1 0,
1063 text " ; fmulp %st(0),", greg src2 1])
1065 = pprG g (hcat [gtab, gpush src1 0,
1066 text " ; fmul ", greg src2 1, text ",%st(0)",
1070 pprInstr g@(GSUB sz src1 src2 dst)
1072 = pprG g (text "\t#GSUB-xxxcase1" $$
1073 hcat [gtab, gpush src2 0,
1074 text " ; fsubrp %st(0),", greg src1 1])
1076 = pprG g (text "\t#GSUB-xxxcase2" $$
1077 hcat [gtab, gpush src1 0,
1078 text " ; fsubp %st(0),", greg src2 1])
1080 = pprG g (hcat [gtab, gpush src1 0,
1081 text " ; fsub ", greg src2 1, text ",%st(0)",
1085 pprInstr g@(GDIV sz src1 src2 dst)
1087 = pprG g (text "\t#GDIV-xxxcase1" $$
1088 hcat [gtab, gpush src2 0,
1089 text " ; fdivrp %st(0),", greg src1 1])
1091 = pprG g (text "\t#GDIV-xxxcase2" $$
1092 hcat [gtab, gpush src1 0,
1093 text " ; fdivp %st(0),", greg src2 1])
1095 = pprG g (hcat [gtab, gpush src1 0,
1096 text " ; fdiv ", greg src2 1, text ",%st(0)",
1101 = vcat [ ptext SLIT("\tffree %st(0) ;ffree %st(1) ;ffree %st(2) ;ffree %st(3)"),
1102 ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)")
1105 --------------------------
1107 -- coerce %st(0) to the specified size
1108 gcoerceto DF = empty
1109 gcoerceto F = text "subl $4,%esp ; fstps (%esp) ; flds (%esp) ; addl $4,%esp ; "
1112 = hcat [text "ffree %st(7) ; fld ", greg reg offset]
1114 = hcat [text "fstp ", greg reg offset]
1116 bogus = text "\tbogus"
1117 greg reg offset = text "%st(" <> int (gregno reg - 8+offset) <> char ')'
1122 gregno (RealReg i) = i
1123 gregno other = --pprPanic "gregno" (ppr other)
1124 999 -- bogus; only needed for debug printing
1126 pprG :: Instr -> SDoc -> SDoc
1128 = (char '#' <> pprGInstr fake) $$ actual
1130 pprGInstr (GMOV src dst) = pprSizeRegReg SLIT("gmov") DF src dst
1131 pprGInstr (GLD sz src dst) = pprSizeAddrReg SLIT("gld") sz src dst
1132 pprGInstr (GST sz src dst) = pprSizeRegAddr SLIT("gst") sz src dst
1134 pprGInstr (GLDZ dst) = pprSizeReg SLIT("gldz") DF dst
1135 pprGInstr (GLD1 dst) = pprSizeReg SLIT("gld1") DF dst
1137 pprGInstr (GFTOD src dst) = pprSizeSizeRegReg SLIT("gftod") F DF src dst
1138 pprGInstr (GFTOI src dst) = pprSizeSizeRegReg SLIT("gftoi") F L src dst
1140 pprGInstr (GDTOF src dst) = pprSizeSizeRegReg SLIT("gdtof") DF F src dst
1141 pprGInstr (GDTOI src dst) = pprSizeSizeRegReg SLIT("gdtoi") DF L src dst
1143 pprGInstr (GITOF src dst) = pprSizeSizeRegReg SLIT("gitof") L F src dst
1144 pprGInstr (GITOD src dst) = pprSizeSizeRegReg SLIT("gitod") L DF src dst
1146 pprGInstr (GCMP sz src dst) = pprSizeRegReg SLIT("gcmp") sz src dst
1147 pprGInstr (GABS sz src dst) = pprSizeRegReg SLIT("gabs") sz src dst
1148 pprGInstr (GNEG sz src dst) = pprSizeRegReg SLIT("gneg") sz src dst
1149 pprGInstr (GSQRT sz src dst) = pprSizeRegReg SLIT("gsqrt") sz src dst
1150 pprGInstr (GSIN sz src dst) = pprSizeRegReg SLIT("gsin") sz src dst
1151 pprGInstr (GCOS sz src dst) = pprSizeRegReg SLIT("gcos") sz src dst
1152 pprGInstr (GTAN sz src dst) = pprSizeRegReg SLIT("gtan") sz src dst
1154 pprGInstr (GADD sz src1 src2 dst) = pprSizeRegRegReg SLIT("gadd") sz src1 src2 dst
1155 pprGInstr (GSUB sz src1 src2 dst) = pprSizeRegRegReg SLIT("gsub") sz src1 src2 dst
1156 pprGInstr (GMUL sz src1 src2 dst) = pprSizeRegRegReg SLIT("gmul") sz src1 src2 dst
1157 pprGInstr (GDIV sz src1 src2 dst) = pprSizeRegRegReg SLIT("gdiv") sz src1 src2 dst
1160 Continue with I386-only printing bits and bobs:
1162 pprDollImm :: Imm -> SDoc
1164 pprDollImm i = ptext SLIT("$") <> pprImm i
1166 pprOperand :: Size -> Operand -> SDoc
1167 pprOperand s (OpReg r) = pprReg s r
1168 pprOperand s (OpImm i) = pprDollImm i
1169 pprOperand s (OpAddr ea) = pprAddr ea
1171 pprSizeImmOp :: FAST_STRING -> Size -> Imm -> Operand -> SDoc
1172 pprSizeImmOp name size imm op1
1184 pprSizeOp :: FAST_STRING -> Size -> Operand -> SDoc
1185 pprSizeOp name size op1
1194 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1195 pprSizeOpOp name size op1 op2
1201 pprOperand size op1,
1206 pprSizeByteOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1207 pprSizeByteOpOp name size op1 op2
1218 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> SDoc
1219 pprSizeOpReg name size op1 reg
1225 pprOperand size op1,
1230 pprSizeReg :: FAST_STRING -> Size -> Reg -> SDoc
1231 pprSizeReg name size reg1
1240 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1241 pprSizeRegReg name size reg1 reg2
1252 pprSizeSizeRegReg :: FAST_STRING -> Size -> Size -> Reg -> Reg -> SDoc
1253 pprSizeSizeRegReg name size1 size2 reg1 reg2
1265 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1266 pprSizeRegRegReg name size reg1 reg2 reg3
1279 pprSizeAddr :: FAST_STRING -> Size -> MachRegsAddr -> SDoc
1280 pprSizeAddr name size op
1289 pprSizeAddrReg :: FAST_STRING -> Size -> MachRegsAddr -> Reg -> SDoc
1290 pprSizeAddrReg name size op dst
1301 pprSizeRegAddr :: FAST_STRING -> Size -> Reg -> MachRegsAddr -> SDoc
1302 pprSizeRegAddr name size src op
1313 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1314 pprOpOp name size op1 op2
1318 pprOperand size op1,
1323 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> SDoc
1324 pprSizeOpOpCoerce name size1 size2 op1 op2
1325 = hcat [ char '\t', ptext name, pprSize size1, pprSize size2, space,
1326 pprOperand size1 op1,
1328 pprOperand size2 op2
1331 pprCondInstr :: FAST_STRING -> Cond -> SDoc -> SDoc
1332 pprCondInstr name cond arg
1333 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1335 #endif {-i386_TARGET_ARCH-}
1338 %************************************************************************
1340 \subsubsection{@pprInstr@ for a SPARC}
1342 %************************************************************************
1345 #if sparc_TARGET_ARCH
1347 -- a clumsy hack for now, to handle possible double alignment problems
1349 -- even clumsier, to allow for RegReg regs that show when doing indexed
1350 -- reads (bytearrays).
1353 -- Translate to the following:
1356 -- ld [g1+4],%f(n+1)
1357 -- sub g1,g2,g1 -- to restore g1
1358 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1360 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1361 hcat [pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg],
1362 hcat [pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)],
1363 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1368 -- ld [addr+4],%f(n+1)
1369 pprInstr (LD DF addr reg) | maybeToBool off_addr
1371 hcat [pp_ld_lbracket, pprAddr addr, pp_rbracket_comma, pprReg reg],
1372 hcat [pp_ld_lbracket, pprAddr addr2, pp_rbracket_comma,pprReg (fPair reg)]
1375 off_addr = addrOffset addr 4
1376 addr2 = case off_addr of Just x -> x
1379 pprInstr (LD size addr reg)
1390 -- The same clumsy hack as above
1392 -- Translate to the following:
1395 -- st %f(n+1),[g1+4]
1396 -- sub g1,g2,g1 -- to restore g1
1397 pprInstr (ST DF reg (AddrRegReg g1 g2))
1399 hcat [ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1],
1400 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1402 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1403 pprReg g1, ptext SLIT("+4]")],
1404 hcat [ptext SLIT("\tsub\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1]
1409 -- st %f(n+1),[addr+4]
1410 pprInstr (ST DF reg addr) | maybeToBool off_addr
1412 hcat [ptext SLIT("\tst\t"), pprReg reg, pp_comma_lbracket,
1413 pprAddr addr, rbrack],
1414 hcat [ptext SLIT("\tst\t"), pprReg (fPair reg), pp_comma_lbracket,
1415 pprAddr addr2, rbrack]
1418 off_addr = addrOffset addr 4
1419 addr2 = case off_addr of Just x -> x
1421 -- no distinction is made between signed and unsigned bytes on stores for the
1422 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1423 -- so we call a special-purpose pprSize for ST..
1425 pprInstr (ST size reg addr)
1436 pprInstr (ADD x cc reg1 ri reg2)
1437 | not x && not cc && riZero ri
1438 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1440 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1442 pprInstr (SUB x cc reg1 ri reg2)
1443 | not x && cc && reg2 == g0
1444 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1445 | not x && not cc && riZero ri
1446 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1448 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1450 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1451 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1453 pprInstr (OR b reg1 ri reg2)
1454 | not b && reg1 == g0
1455 = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1457 = pprRegRIReg SLIT("or") b reg1 ri reg2
1459 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1461 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1462 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1464 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1465 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1466 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1468 pprInstr (SETHI imm reg)
1470 ptext SLIT("\tsethi\t"),
1476 pprInstr NOP = ptext SLIT("\tnop")
1478 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1479 pprInstr (FABS DF reg1 reg2)
1480 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1481 (if (reg1 == reg2) then empty
1482 else (<>) (char '\n')
1483 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1485 pprInstr (FADD size reg1 reg2 reg3)
1486 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1487 pprInstr (FCMP e size reg1 reg2)
1488 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1489 pprInstr (FDIV size reg1 reg2 reg3)
1490 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1492 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1493 pprInstr (FMOV DF reg1 reg2)
1494 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1495 (if (reg1 == reg2) then empty
1496 else (<>) (char '\n')
1497 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1499 pprInstr (FMUL size reg1 reg2 reg3)
1500 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1502 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1503 pprInstr (FNEG DF reg1 reg2)
1504 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1505 (if (reg1 == reg2) then empty
1506 else (<>) (char '\n')
1507 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1509 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1510 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1511 pprInstr (FxTOy size1 size2 reg1 reg2)
1524 pprReg reg1, comma, pprReg reg2
1528 pprInstr (BI cond b lab)
1530 ptext SLIT("\tb"), pprCond cond,
1531 if b then pp_comma_a else empty,
1536 pprInstr (BF cond b lab)
1538 ptext SLIT("\tfb"), pprCond cond,
1539 if b then pp_comma_a else empty,
1544 pprInstr (JMP addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1546 pprInstr (CALL imm n _)
1547 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1550 Continue with SPARC-only printing bits and bobs:
1553 pprRI (RIReg r) = pprReg r
1554 pprRI (RIImm r) = pprImm r
1556 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1557 pprSizeRegReg name size reg1 reg2
1562 F -> ptext SLIT("s\t")
1563 DF -> ptext SLIT("d\t")),
1569 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1570 pprSizeRegRegReg name size reg1 reg2 reg3
1575 F -> ptext SLIT("s\t")
1576 DF -> ptext SLIT("d\t")),
1584 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> SDoc
1585 pprRegRIReg name b reg1 ri reg2
1589 if b then ptext SLIT("cc\t") else char '\t',
1597 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> SDoc
1598 pprRIReg name b ri reg1
1602 if b then ptext SLIT("cc\t") else char '\t',
1608 pp_ld_lbracket = ptext SLIT("\tld\t[")
1609 pp_rbracket_comma = text "],"
1610 pp_comma_lbracket = text ",["
1611 pp_comma_a = text ",a"
1613 #endif {-sparc_TARGET_ARCH-}