2 % (c) The AQUA Project, Glasgow University, 1996
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 "HsVersions.h"
12 #include "nativeGen/NCG.h"
14 module PprMach ( pprInstr ) where
16 IMPORT_1_3(Char(isPrint,isDigit))
17 #if __GLASGOW_HASKELL__ == 201
18 import qualified GHCbase(Addr(..)) -- to see innards
20 #elif __GLASGOW_HASKELL__ >= 202
21 import qualified GlaExts (Addr(..))
22 import GlaExts hiding (Addr(..))
29 import MachRegs -- may differ per-platform
32 import AbsCSyn ( MagicId )
33 import CLabel ( pprCLabel_asm, externallyVisibleCLabel )
34 import CStrings ( charToC )
35 import Maybes ( maybeToBool )
36 import OrdList ( OrdList )
37 import Stix ( CodeSegment(..), StixTree )
38 import Pretty -- all of it
40 #if __GLASGOW_HASKELL__ == 201
41 a_HASH x = GHCbase.A# x
42 pACK_STR x = packCString x
43 #elif __GLASGOW_HASKELL__ >= 202
44 a_HASH x = GlaExts.A# x
45 pACK_STR x = mkFastCharString x
48 pACK_STR x = mkFastCharString x --_packCString x
52 %************************************************************************
54 \subsection{@pprReg@: print a @Reg@}
56 %************************************************************************
58 For x86, the way we print a register name depends
59 on which bit of it we care about. Yurgh.
61 pprReg :: IF_ARCH_i386(Size ->,) Reg -> Doc
63 pprReg IF_ARCH_i386(s,) r
65 FixedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
66 MappedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
67 other -> text (show other) -- should only happen when debugging
70 ppr_reg_no :: FAST_REG_NO -> Doc
73 ILIT( 0) -> SLIT("$0"); ILIT( 1) -> SLIT("$1");
74 ILIT( 2) -> SLIT("$2"); ILIT( 3) -> SLIT("$3");
75 ILIT( 4) -> SLIT("$4"); ILIT( 5) -> SLIT("$5");
76 ILIT( 6) -> SLIT("$6"); ILIT( 7) -> SLIT("$7");
77 ILIT( 8) -> SLIT("$8"); ILIT( 9) -> SLIT("$9");
78 ILIT(10) -> SLIT("$10"); ILIT(11) -> SLIT("$11");
79 ILIT(12) -> SLIT("$12"); ILIT(13) -> SLIT("$13");
80 ILIT(14) -> SLIT("$14"); ILIT(15) -> SLIT("$15");
81 ILIT(16) -> SLIT("$16"); ILIT(17) -> SLIT("$17");
82 ILIT(18) -> SLIT("$18"); ILIT(19) -> SLIT("$19");
83 ILIT(20) -> SLIT("$20"); ILIT(21) -> SLIT("$21");
84 ILIT(22) -> SLIT("$22"); ILIT(23) -> SLIT("$23");
85 ILIT(24) -> SLIT("$24"); ILIT(25) -> SLIT("$25");
86 ILIT(26) -> SLIT("$26"); ILIT(27) -> SLIT("$27");
87 ILIT(28) -> SLIT("$28"); ILIT(29) -> SLIT("$29");
88 ILIT(30) -> SLIT("$30"); ILIT(31) -> SLIT("$31");
89 ILIT(32) -> SLIT("$f0"); ILIT(33) -> SLIT("$f1");
90 ILIT(34) -> SLIT("$f2"); ILIT(35) -> SLIT("$f3");
91 ILIT(36) -> SLIT("$f4"); ILIT(37) -> SLIT("$f5");
92 ILIT(38) -> SLIT("$f6"); ILIT(39) -> SLIT("$f7");
93 ILIT(40) -> SLIT("$f8"); ILIT(41) -> SLIT("$f9");
94 ILIT(42) -> SLIT("$f10"); ILIT(43) -> SLIT("$f11");
95 ILIT(44) -> SLIT("$f12"); ILIT(45) -> SLIT("$f13");
96 ILIT(46) -> SLIT("$f14"); ILIT(47) -> SLIT("$f15");
97 ILIT(48) -> SLIT("$f16"); ILIT(49) -> SLIT("$f17");
98 ILIT(50) -> SLIT("$f18"); ILIT(51) -> SLIT("$f19");
99 ILIT(52) -> SLIT("$f20"); ILIT(53) -> SLIT("$f21");
100 ILIT(54) -> SLIT("$f22"); ILIT(55) -> SLIT("$f23");
101 ILIT(56) -> SLIT("$f24"); ILIT(57) -> SLIT("$f25");
102 ILIT(58) -> SLIT("$f26"); ILIT(59) -> SLIT("$f27");
103 ILIT(60) -> SLIT("$f28"); ILIT(61) -> SLIT("$f29");
104 ILIT(62) -> SLIT("$f30"); ILIT(63) -> SLIT("$f31");
105 _ -> SLIT("very naughty alpha register")
109 ppr_reg_no :: Size -> FAST_REG_NO -> Doc
110 ppr_reg_no B i = ptext
112 ILIT( 0) -> SLIT("%al"); ILIT( 1) -> SLIT("%bl");
113 ILIT( 2) -> SLIT("%cl"); ILIT( 3) -> SLIT("%dl");
114 _ -> SLIT("very naughty I386 byte register")
118 ppr_reg_no HB i = ptext
120 ILIT( 0) -> SLIT("%ah"); ILIT( 1) -> SLIT("%bh");
121 ILIT( 2) -> SLIT("%ch"); ILIT( 3) -> SLIT("%dh");
122 _ -> SLIT("very naughty I386 high byte register")
127 ppr_reg_no S i = ptext
129 ILIT( 0) -> SLIT("%ax"); ILIT( 1) -> SLIT("%bx");
130 ILIT( 2) -> SLIT("%cx"); ILIT( 3) -> SLIT("%dx");
131 ILIT( 4) -> SLIT("%si"); ILIT( 5) -> SLIT("%di");
132 ILIT( 6) -> SLIT("%bp"); ILIT( 7) -> SLIT("%sp");
133 _ -> SLIT("very naughty I386 word register")
137 ppr_reg_no L i = ptext
139 ILIT( 0) -> SLIT("%eax"); ILIT( 1) -> SLIT("%ebx");
140 ILIT( 2) -> SLIT("%ecx"); ILIT( 3) -> SLIT("%edx");
141 ILIT( 4) -> SLIT("%esi"); ILIT( 5) -> SLIT("%edi");
142 ILIT( 6) -> SLIT("%ebp"); ILIT( 7) -> SLIT("%esp");
143 _ -> SLIT("very naughty I386 double word register")
146 ppr_reg_no F i = ptext
148 --ToDo: rm these (???)
149 ILIT( 8) -> SLIT("%st(0)"); ILIT( 9) -> SLIT("%st(1)");
150 ILIT(10) -> SLIT("%st(2)"); ILIT(11) -> SLIT("%st(3)");
151 ILIT(12) -> SLIT("%st(4)"); ILIT(13) -> SLIT("%st(5)");
152 ILIT(14) -> SLIT("%st(6)"); ILIT(15) -> SLIT("%st(7)");
153 _ -> SLIT("very naughty I386 float register")
156 ppr_reg_no DF i = ptext
158 --ToDo: rm these (???)
159 ILIT( 8) -> SLIT("%st(0)"); ILIT( 9) -> SLIT("%st(1)");
160 ILIT(10) -> SLIT("%st(2)"); ILIT(11) -> SLIT("%st(3)");
161 ILIT(12) -> SLIT("%st(4)"); ILIT(13) -> SLIT("%st(5)");
162 ILIT(14) -> SLIT("%st(6)"); ILIT(15) -> SLIT("%st(7)");
163 _ -> SLIT("very naughty I386 float register")
166 #if sparc_TARGET_ARCH
167 ppr_reg_no :: FAST_REG_NO -> Doc
170 ILIT( 0) -> SLIT("%g0"); ILIT( 1) -> SLIT("%g1");
171 ILIT( 2) -> SLIT("%g2"); ILIT( 3) -> SLIT("%g3");
172 ILIT( 4) -> SLIT("%g4"); ILIT( 5) -> SLIT("%g5");
173 ILIT( 6) -> SLIT("%g6"); ILIT( 7) -> SLIT("%g7");
174 ILIT( 8) -> SLIT("%o0"); ILIT( 9) -> SLIT("%o1");
175 ILIT(10) -> SLIT("%o2"); ILIT(11) -> SLIT("%o3");
176 ILIT(12) -> SLIT("%o4"); ILIT(13) -> SLIT("%o5");
177 ILIT(14) -> SLIT("%o6"); ILIT(15) -> SLIT("%o7");
178 ILIT(16) -> SLIT("%l0"); ILIT(17) -> SLIT("%l1");
179 ILIT(18) -> SLIT("%l2"); ILIT(19) -> SLIT("%l3");
180 ILIT(20) -> SLIT("%l4"); ILIT(21) -> SLIT("%l5");
181 ILIT(22) -> SLIT("%l6"); ILIT(23) -> SLIT("%l7");
182 ILIT(24) -> SLIT("%i0"); ILIT(25) -> SLIT("%i1");
183 ILIT(26) -> SLIT("%i2"); ILIT(27) -> SLIT("%i3");
184 ILIT(28) -> SLIT("%i4"); ILIT(29) -> SLIT("%i5");
185 ILIT(30) -> SLIT("%i6"); ILIT(31) -> SLIT("%i7");
186 ILIT(32) -> SLIT("%f0"); ILIT(33) -> SLIT("%f1");
187 ILIT(34) -> SLIT("%f2"); ILIT(35) -> SLIT("%f3");
188 ILIT(36) -> SLIT("%f4"); ILIT(37) -> SLIT("%f5");
189 ILIT(38) -> SLIT("%f6"); ILIT(39) -> SLIT("%f7");
190 ILIT(40) -> SLIT("%f8"); ILIT(41) -> SLIT("%f9");
191 ILIT(42) -> SLIT("%f10"); ILIT(43) -> SLIT("%f11");
192 ILIT(44) -> SLIT("%f12"); ILIT(45) -> SLIT("%f13");
193 ILIT(46) -> SLIT("%f14"); ILIT(47) -> SLIT("%f15");
194 ILIT(48) -> SLIT("%f16"); ILIT(49) -> SLIT("%f17");
195 ILIT(50) -> SLIT("%f18"); ILIT(51) -> SLIT("%f19");
196 ILIT(52) -> SLIT("%f20"); ILIT(53) -> SLIT("%f21");
197 ILIT(54) -> SLIT("%f22"); ILIT(55) -> SLIT("%f23");
198 ILIT(56) -> SLIT("%f24"); ILIT(57) -> SLIT("%f25");
199 ILIT(58) -> SLIT("%f26"); ILIT(59) -> SLIT("%f27");
200 ILIT(60) -> SLIT("%f28"); ILIT(61) -> SLIT("%f29");
201 ILIT(62) -> SLIT("%f30"); ILIT(63) -> SLIT("%f31");
202 _ -> SLIT("very naughty sparc register")
207 %************************************************************************
209 \subsection{@pprSize@: print a @Size@}
211 %************************************************************************
214 pprSize :: Size -> Doc
216 pprSize x = ptext (case x of
217 #if alpha_TARGET_ARCH
220 -- W -> SLIT("w") UNUSED
221 -- WU -> SLIT("wu") UNUSED
222 -- L -> SLIT("l") UNUSED
224 -- FF -> SLIT("f") UNUSED
225 -- DF -> SLIT("d") UNUSED
226 -- GF -> SLIT("g") UNUSED
227 -- SF -> SLIT("s") UNUSED
232 -- HB -> SLIT("b") UNUSED
233 -- S -> SLIT("w") UNUSED
238 #if sparc_TARGET_ARCH
241 -- HW -> SLIT("hw") UNUSED
242 -- HWU -> SLIT("uhw") UNUSED
245 -- D -> SLIT("d") UNUSED
248 pprStSize :: Size -> Doc
249 pprStSize x = ptext (case x of
252 -- HW -> SLIT("hw") UNUSED
253 -- HWU -> SLIT("uhw") UNUSED
256 -- D -> SLIT("d") UNUSED
262 %************************************************************************
264 \subsection{@pprCond@: print a @Cond@}
266 %************************************************************************
269 pprCond :: Cond -> Doc
271 pprCond c = ptext (case c of {
272 #if alpha_TARGET_ARCH
283 GEU -> SLIT("ae"); LU -> SLIT("b");
284 EQQ -> SLIT("e"); GTT -> SLIT("g");
285 GE -> SLIT("ge"); GU -> SLIT("a");
286 LTT -> SLIT("l"); LE -> SLIT("le");
287 LEU -> SLIT("be"); NE -> SLIT("ne");
288 NEG -> SLIT("s"); POS -> SLIT("ns");
289 ALWAYS -> SLIT("mp") -- hack
291 #if sparc_TARGET_ARCH
292 ALWAYS -> SLIT(""); NEVER -> SLIT("n");
293 GEU -> SLIT("geu"); LU -> SLIT("lu");
294 EQQ -> SLIT("e"); GTT -> SLIT("g");
295 GE -> SLIT("ge"); GU -> SLIT("gu");
296 LTT -> SLIT("l"); LE -> SLIT("le");
297 LEU -> SLIT("leu"); NE -> SLIT("ne");
298 NEG -> SLIT("neg"); POS -> SLIT("pos");
299 VC -> SLIT("vc"); VS -> SLIT("vs")
304 %************************************************************************
306 \subsection{@pprImm@: print an @Imm@}
308 %************************************************************************
313 pprImm (ImmInt i) = int i
314 pprImm (ImmInteger i) = integer i
315 pprImm (ImmCLbl l) = pprCLabel_asm l
316 pprImm (ImmLit s) = s
318 pprImm (ImmLab s) | underscorePrefix = (<>) (char '_') s
321 #if sparc_TARGET_ARCH
323 = hcat [ pp_lo, pprImm i, rparen ]
325 pp_lo = ptext (pACK_STR (a_HASH "%lo("#))
328 = hcat [ pp_hi, pprImm i, rparen ]
330 pp_hi = ptext (pACK_STR (a_HASH "%hi("#))
334 %************************************************************************
336 \subsection{@pprAddr@: print an @Addr@}
338 %************************************************************************
341 pprAddr :: Addr -> Doc
343 #if alpha_TARGET_ARCH
344 pprAddr (AddrReg r) = parens (pprReg r)
345 pprAddr (AddrImm i) = pprImm i
346 pprAddr (AddrRegImm r1 i)
347 = (<>) (pprImm i) (parens (pprReg r1))
353 pprAddr (ImmAddr imm off)
359 else if (off < 0) then
360 (<>) pp_imm (int off)
362 hcat [pp_imm, char '+', int off]
364 pprAddr (Addr base index displacement)
366 pp_disp = ppr_disp displacement
367 pp_off p = (<>) pp_disp (parens p)
368 pp_reg r = pprReg L r
371 (Nothing, Nothing) -> pp_disp
372 (Just b, Nothing) -> pp_off (pp_reg b)
373 (Nothing, Just (r,i)) -> pp_off (hcat [pp_reg r, comma, int i])
374 (Just b, Just (r,i)) -> pp_off (hcat [pp_reg b, comma, pp_reg r, comma, int i])
376 ppr_disp (ImmInt 0) = empty
377 ppr_disp imm = pprImm imm
382 #if sparc_TARGET_ARCH
383 pprAddr (AddrRegReg r1 (FixedReg ILIT(0))) = pprReg r1
385 pprAddr (AddrRegReg r1 r2)
386 = hcat [ pprReg r1, char '+', pprReg r2 ]
388 pprAddr (AddrRegImm r1 (ImmInt i))
390 | not (fits13Bits i) = largeOffsetError i
391 | otherwise = hcat [ pprReg r1, pp_sign, int i ]
393 pp_sign = if i > 0 then char '+' else empty
395 pprAddr (AddrRegImm r1 (ImmInteger i))
397 | not (fits13Bits i) = largeOffsetError i
398 | otherwise = hcat [ pprReg r1, pp_sign, integer i ]
400 pp_sign = if i > 0 then char '+' else empty
402 pprAddr (AddrRegImm r1 imm)
403 = hcat [ pprReg r1, char '+', pprImm imm ]
407 %************************************************************************
409 \subsection{@pprInstr@: print an @Instr@}
411 %************************************************************************
414 pprInstr :: Instr -> Doc
416 pprInstr (COMMENT s) = empty -- nuke 'em
417 --alpha: = (<>) (ptext SLIT("\t# ")) (ptext s)
418 --i386 : = (<>) (ptext SLIT("# ")) (ptext s)
419 --sparc: = (<>) (ptext SLIT("! ")) (ptext s)
421 pprInstr (SEGMENT TextSegment)
423 IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
424 ,IF_ARCH_sparc(SLIT("\t.text\n\t.align 4") {-word boundary-}
425 ,IF_ARCH_i386((_PK_ ".text\n\t.align 2\x2c\&0x90") {-needs per-OS variation!-}
428 pprInstr (SEGMENT DataSegment)
430 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
431 ,IF_ARCH_sparc(SLIT("\t.data\n\t.align 8") {-<8 will break double constants -}
432 ,IF_ARCH_i386(SLIT(".data\n\t.align 2")
435 pprInstr (LABEL clab)
437 pp_lab = pprCLabel_asm clab
440 if not (externallyVisibleCLabel clab) then
444 IF_ARCH_alpha(SLIT("\t.globl\t")
445 ,IF_ARCH_i386(SLIT(".globl ")
446 ,IF_ARCH_sparc(SLIT("\t.global\t")
448 , pp_lab, char '\n'],
453 pprInstr (ASCII False{-no backslash conversion-} str)
454 = hcat [ ptext SLIT("\t.asciz "), char '\"', text str, char '"' ]
456 pprInstr (ASCII True str)
457 = (<>) (text "\t.ascii \"") (asciify str 60)
459 asciify :: String -> Int -> Doc
461 asciify [] _ = text "\\0\""
462 asciify s n | n <= 0 = (<>) (text "\"\n\t.ascii \"") (asciify s 60)
463 asciify ('\\':cs) n = (<>) (text "\\\\") (asciify cs (n-1))
464 asciify ('\"':cs) n = (<>) (text "\\\"") (asciify cs (n-1))
465 asciify (c:cs) n | isPrint c = (<>) (char c) (asciify cs (n-1))
466 asciify [c] _ = (<>) (text (charToC c)) (text ("\\0\""))
467 asciify (c:(cs@(d:_))) n
468 | isDigit d = (<>) (text (charToC c)) (asciify cs 0)
469 | otherwise = (<>) (text (charToC c)) (asciify cs (n-1))
472 = vcat [(<>) (ptext pp_size) (pprImm x) | x <- xs]
475 #if alpha_TARGET_ARCH
476 B -> SLIT("\t.byte\t")
477 BU -> SLIT("\t.byte\t")
478 --UNUSED: W -> SLIT("\t.word\t")
479 --UNUSED: WU -> SLIT("\t.word\t")
480 --UNUSED: L -> SLIT("\t.long\t")
481 Q -> SLIT("\t.quad\t")
482 --UNUSED: FF -> SLIT("\t.f_floating\t")
483 --UNUSED: DF -> SLIT("\t.d_floating\t")
484 --UNUSED: GF -> SLIT("\t.g_floating\t")
485 --UNUSED: SF -> SLIT("\t.s_floating\t")
486 TF -> SLIT("\t.t_floating\t")
489 B -> SLIT("\t.byte\t")
490 --UNUSED: HB -> SLIT("\t.byte\t")
491 --UNUSED: S -> SLIT("\t.word\t")
492 L -> SLIT("\t.long\t")
493 F -> SLIT("\t.long\t")
494 DF -> SLIT("\t.double\t")
496 #if sparc_TARGET_ARCH
497 B -> SLIT("\t.byte\t")
498 BU -> SLIT("\t.byte\t")
499 W -> SLIT("\t.word\t")
500 DF -> SLIT("\t.double\t")
503 -- fall through to rest of (machine-specific) pprInstr...
506 %************************************************************************
508 \subsubsection{@pprInstr@ for an Alpha}
510 %************************************************************************
513 #if alpha_TARGET_ARCH
515 pprInstr (LD size reg addr)
525 pprInstr (LDA reg addr)
527 ptext SLIT("\tlda\t"),
533 pprInstr (LDAH reg addr)
535 ptext SLIT("\tldah\t"),
541 pprInstr (LDGP reg addr)
543 ptext SLIT("\tldgp\t"),
549 pprInstr (LDI size reg imm)
559 pprInstr (ST size reg addr)
571 ptext SLIT("\tclr\t"),
575 pprInstr (ABS size ri reg)
585 pprInstr (NEG size ov ri reg)
589 if ov then ptext SLIT("v\t") else char '\t',
595 pprInstr (ADD size ov reg1 ri reg2)
599 if ov then ptext SLIT("v\t") else char '\t',
607 pprInstr (SADD size scale reg1 ri reg2)
609 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
620 pprInstr (SUB size ov reg1 ri reg2)
624 if ov then ptext SLIT("v\t") else char '\t',
632 pprInstr (SSUB size scale reg1 ri reg2)
634 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
645 pprInstr (MUL size ov reg1 ri reg2)
649 if ov then ptext SLIT("v\t") else char '\t',
657 pprInstr (DIV size uns reg1 ri reg2)
661 if uns then ptext SLIT("u\t") else char '\t',
669 pprInstr (REM size uns reg1 ri reg2)
673 if uns then ptext SLIT("u\t") else char '\t',
681 pprInstr (NOT ri reg)
690 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
691 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
692 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
693 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
694 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
695 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
697 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
698 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
699 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
701 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
702 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
704 pprInstr (NOP) = ptext SLIT("\tnop")
706 pprInstr (CMP cond reg1 ri reg2)
720 ptext SLIT("\tfclr\t"),
724 pprInstr (FABS reg1 reg2)
726 ptext SLIT("\tfabs\t"),
732 pprInstr (FNEG size reg1 reg2)
742 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
743 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
744 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
745 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
747 pprInstr (CVTxy size1 size2 reg1 reg2)
751 case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
758 pprInstr (FCMP size cond reg1 reg2 reg3)
771 pprInstr (FMOV reg1 reg2)
773 ptext SLIT("\tfmov\t"),
779 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
781 pprInstr (BI NEVER reg lab) = empty
783 pprInstr (BI cond reg lab)
793 pprInstr (BF cond reg lab)
804 = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
806 pprInstr (JMP reg addr hint)
808 ptext SLIT("\tjmp\t"),
817 = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
819 pprInstr (JSR reg addr n)
821 ptext SLIT("\tjsr\t"),
827 pprInstr (FUNBEGIN clab)
829 if (externallyVisibleCLabel clab) then
830 hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
833 ptext SLIT("\t.ent "),
842 pp_lab = pprCLabel_asm clab
844 pp_ldgp = ptext (pACK_STR (a_HASH ":\n\tldgp $29,0($27)\n"#))
845 pp_frame = ptext (pACK_STR (a_HASH "..ng:\n\t.frame $30,4240,$26,0\n\t.prologue 1"#))
847 pprInstr (FUNEND clab)
848 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
851 Continue with Alpha-only printing bits and bobs:
855 pprRI (RIReg r) = pprReg r
856 pprRI (RIImm r) = pprImm r
858 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> Doc
860 pprRegRIReg name reg1 ri reg2
872 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Doc
874 pprSizeRegRegReg name size reg1 reg2 reg3
887 #endif {-alpha_TARGET_ARCH-}
890 %************************************************************************
892 \subsubsection{@pprInstr@ for an I386}
894 %************************************************************************
899 pprInstr (MOV size (OpReg src) (OpReg dst)) -- hack
902 pprInstr (MOV size src dst)
903 = pprSizeOpOp SLIT("mov") size src dst
904 pprInstr (MOVZX size src dst) = pprSizeOpOpCoerce SLIT("movzx") L size src dst
905 pprInstr (MOVSX size src dst) = pprSizeOpOpCoerce SLIT("movxs") L size src dst
907 -- here we do some patching, since the physical registers are only set late
908 -- in the code generation.
909 pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
911 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
912 pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
914 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
915 pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
917 = pprInstr (ADD size (OpImm displ) dst)
918 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
920 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
921 = pprSizeOp SLIT("dec") size dst
922 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
923 = pprSizeOp SLIT("inc") size dst
924 pprInstr (ADD size src dst)
925 = pprSizeOpOp SLIT("add") size src dst
926 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
927 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
928 pprInstr (IDIV size op) = pprSizeOp SLIT("idiv") size op
930 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
931 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
932 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
933 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
934 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
935 pprInstr (SHL size imm dst) = pprSizeOpOp SLIT("shl") size imm dst
936 pprInstr (SAR size imm dst) = pprSizeOpOp SLIT("sar") size imm dst
937 pprInstr (SHR size imm dst) = pprSizeOpOp SLIT("shr") size imm dst
939 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
940 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
941 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
942 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
944 pprInstr (NOP) = ptext SLIT("\tnop")
945 pprInstr (CLTD) = ptext SLIT("\tcltd")
947 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
949 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
951 pprInstr (JMP (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
952 pprInstr (JMP op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand L op)
955 = hcat [ ptext SLIT("\tcall "), pprImm imm ]
957 pprInstr SAHF = ptext SLIT("\tsahf")
958 pprInstr FABS = ptext SLIT("\tfabs")
960 pprInstr (FADD sz src@(OpAddr _))
961 = hcat [ptext SLIT("\tfadd"), pprSize sz, space, pprOperand sz src]
962 pprInstr (FADD sz src)
963 = ptext SLIT("\tfadd")
965 = ptext SLIT("\tfaddp")
966 pprInstr (FMUL sz src)
967 = hcat [ptext SLIT("\tfmul"), pprSize sz, space, pprOperand sz src]
969 = ptext SLIT("\tfmulp")
970 pprInstr (FIADD size op) = pprSizeAddr SLIT("fiadd") size op
971 pprInstr FCHS = ptext SLIT("\tfchs")
972 pprInstr (FCOM size op) = pprSizeOp SLIT("fcom") size op
973 pprInstr FCOS = ptext SLIT("\tfcos")
974 pprInstr (FIDIV size op) = pprSizeAddr SLIT("fidiv") size op
975 pprInstr (FDIV sz src)
976 = hcat [ptext SLIT("\tfdiv"), pprSize sz, space, pprOperand sz src]
978 = ptext SLIT("\tfdivp")
979 pprInstr (FDIVR sz src)
980 = hcat [ptext SLIT("\tfdivr"), pprSize sz, space, pprOperand sz src]
982 = ptext SLIT("\tfdivpr")
983 pprInstr (FIDIVR size op) = pprSizeAddr SLIT("fidivr") size op
984 pprInstr (FICOM size op) = pprSizeAddr SLIT("ficom") size op
985 pprInstr (FILD sz op reg) = pprSizeAddrReg SLIT("fild") sz op reg
986 pprInstr (FIST size op) = pprSizeAddr SLIT("fist") size op
987 pprInstr (FLD sz (OpImm (ImmCLbl src)))
988 = hcat [ptext SLIT("\tfld"),pprSize sz,space,pprCLabel_asm src]
989 pprInstr (FLD sz src)
990 = hcat [ptext SLIT("\tfld"),pprSize sz,space,pprOperand sz src]
991 pprInstr FLD1 = ptext SLIT("\tfld1")
992 pprInstr FLDZ = ptext SLIT("\tfldz")
993 pprInstr (FIMUL size op) = pprSizeAddr SLIT("fimul") size op
994 pprInstr FRNDINT = ptext SLIT("\tfrndint")
995 pprInstr FSIN = ptext SLIT("\tfsin")
996 pprInstr FSQRT = ptext SLIT("\tfsqrt")
997 pprInstr (FST sz dst)
998 = hcat [ptext SLIT("\tfst"), pprSize sz, space, pprOperand sz dst]
999 pprInstr (FSTP sz dst)
1000 = hcat [ptext SLIT("\tfstp"), pprSize sz, space, pprOperand sz dst]
1001 pprInstr (FISUB size op) = pprSizeAddr SLIT("fisub") size op
1002 pprInstr (FSUB sz src)
1003 = hcat [ptext SLIT("\tfsub"), pprSize sz, space, pprOperand sz src]
1005 = ptext SLIT("\tfsubp")
1006 pprInstr (FSUBR size src)
1007 = pprSizeOp SLIT("fsubr") size src
1009 = ptext SLIT("\tfsubpr")
1010 pprInstr (FISUBR size op)
1011 = pprSizeAddr SLIT("fisubr") size op
1012 pprInstr FTST = ptext SLIT("\tftst")
1013 pprInstr (FCOMP sz op)
1014 = hcat [ptext SLIT("\tfcomp"), pprSize sz, space, pprOperand sz op]
1015 pprInstr FUCOMPP = ptext SLIT("\tfucompp")
1016 pprInstr FXCH = ptext SLIT("\tfxch")
1017 pprInstr FNSTSW = ptext SLIT("\tfnstsw %ax")
1018 pprInstr FNOP = ptext SLIT("")
1021 Continue with I386-only printing bits and bobs:
1023 pprDollImm :: Imm -> Doc
1025 pprDollImm i = hcat [ ptext SLIT("$"), pprImm i]
1027 pprOperand :: Size -> Operand -> Doc
1028 pprOperand s (OpReg r) = pprReg s r
1029 pprOperand s (OpImm i) = pprDollImm i
1030 pprOperand s (OpAddr ea) = pprAddr ea
1032 pprSizeOp :: FAST_STRING -> Size -> Operand -> Doc
1033 pprSizeOp name size op1
1042 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Doc
1043 pprSizeOpOp name size op1 op2
1049 pprOperand size op1,
1054 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> Doc
1055 pprSizeOpReg name size op1 reg
1061 pprOperand size op1,
1066 pprSizeAddr :: FAST_STRING -> Size -> Addr -> Doc
1067 pprSizeAddr name size op
1076 pprSizeAddrReg :: FAST_STRING -> Size -> Addr -> Reg -> Doc
1077 pprSizeAddrReg name size op dst
1088 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Doc
1089 pprOpOp name size op1 op2
1093 pprOperand size op1,
1098 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> Doc
1099 pprSizeOpOpCoerce name size1 size2 op1 op2
1100 = hcat [ char '\t', ptext name, space,
1101 pprOperand size1 op1,
1103 pprOperand size2 op2
1106 pprCondInstr :: FAST_STRING -> Cond -> Doc -> Doc
1107 pprCondInstr name cond arg
1108 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1110 #endif {-i386_TARGET_ARCH-}
1113 %************************************************************************
1115 \subsubsection{@pprInstr@ for a SPARC}
1117 %************************************************************************
1120 #if sparc_TARGET_ARCH
1122 -- a clumsy hack for now, to handle possible double alignment problems
1124 -- even clumsier, to allow for RegReg regs that show when doing indexed
1125 -- reads (bytearrays).
1127 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1129 ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1, char '\n',
1130 pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg, char '\n',
1131 pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)
1134 pprInstr (LD DF addr reg) | maybeToBool off_addr
1148 off_addr = addrOffset addr 4
1149 addr2 = case off_addr of Just x -> x
1151 pprInstr (LD size addr reg)
1162 -- The same clumsy hack as above
1164 pprInstr (ST DF reg (AddrRegReg g1 g2))
1166 ptext SLIT("\tadd\t"),
1167 pprReg g1,comma,pprReg g2,comma,pprReg g1, char '\n',
1168 ptext SLIT("\tst\t"),
1169 pprReg reg, pp_comma_lbracket, pprReg g1,
1170 ptext SLIT("]\n\tst\t"),
1171 pprReg (fPair reg), pp_comma_lbracket, pprReg g1, ptext SLIT("+4]")
1174 pprInstr (ST DF reg addr) | maybeToBool off_addr
1176 ptext SLIT("\tst\t"),
1177 pprReg reg, pp_comma_lbracket, pprAddr addr,
1179 ptext SLIT("]\n\tst\t"),
1180 pprReg (fPair reg), pp_comma_lbracket,
1181 pprAddr addr2, rbrack
1184 off_addr = addrOffset addr 4
1185 addr2 = case off_addr of Just x -> x
1187 -- no distinction is made between signed and unsigned bytes on stores for the
1188 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1189 -- so we call a special-purpose pprSize for ST..
1191 pprInstr (ST size reg addr)
1202 pprInstr (ADD x cc reg1 ri reg2)
1203 | not x && not cc && riZero ri
1204 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1206 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1208 pprInstr (SUB x cc reg1 ri reg2)
1209 | not x && cc && reg2 == g0
1210 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1211 | not x && not cc && riZero ri
1212 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1214 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1216 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1217 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1219 pprInstr (OR b reg1 ri reg2)
1220 | not b && reg1 == g0
1221 = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1223 = pprRegRIReg SLIT("or") b reg1 ri reg2
1225 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1227 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1228 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1230 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1231 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1232 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1234 pprInstr (SETHI imm reg)
1236 ptext SLIT("\tsethi\t"),
1242 pprInstr NOP = ptext SLIT("\tnop")
1244 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1245 pprInstr (FABS DF reg1 reg2)
1246 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1247 (if (reg1 == reg2) then empty
1248 else (<>) (char '\n')
1249 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1251 pprInstr (FADD size reg1 reg2 reg3)
1252 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1253 pprInstr (FCMP e size reg1 reg2)
1254 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1255 pprInstr (FDIV size reg1 reg2 reg3)
1256 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1258 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1259 pprInstr (FMOV DF reg1 reg2)
1260 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1261 (if (reg1 == reg2) then empty
1262 else (<>) (char '\n')
1263 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1265 pprInstr (FMUL size reg1 reg2 reg3)
1266 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1268 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1269 pprInstr (FNEG DF reg1 reg2)
1270 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1271 (if (reg1 == reg2) then empty
1272 else (<>) (char '\n')
1273 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1275 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1276 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1277 pprInstr (FxTOy size1 size2 reg1 reg2)
1290 pprReg reg1, comma, pprReg reg2
1294 pprInstr (BI cond b lab)
1296 ptext SLIT("\tb"), pprCond cond,
1297 if b then pp_comma_a else empty,
1302 pprInstr (BF cond b lab)
1304 ptext SLIT("\tfb"), pprCond cond,
1305 if b then pp_comma_a else empty,
1310 pprInstr (JMP addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1312 pprInstr (CALL imm n _)
1313 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1316 Continue with SPARC-only printing bits and bobs:
1319 pprRI (RIReg r) = pprReg r
1320 pprRI (RIImm r) = pprImm r
1322 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Doc
1323 pprSizeRegReg name size reg1 reg2
1328 F -> ptext SLIT("s\t")
1329 DF -> ptext SLIT("d\t")),
1335 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Doc
1336 pprSizeRegRegReg name size reg1 reg2 reg3
1341 F -> ptext SLIT("s\t")
1342 DF -> ptext SLIT("d\t")),
1350 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> Doc
1351 pprRegRIReg name b reg1 ri reg2
1355 if b then ptext SLIT("cc\t") else char '\t',
1363 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> Doc
1364 pprRIReg name b ri reg1
1368 if b then ptext SLIT("cc\t") else char '\t',
1374 pp_ld_lbracket = ptext (pACK_STR (a_HASH "\tld\t["#))
1375 pp_rbracket_comma = ptext (pACK_STR (a_HASH "],"#))
1376 pp_comma_lbracket = ptext (pACK_STR (a_HASH ",["#))
1377 pp_comma_a = ptext (pACK_STR (a_HASH ",a"#))
1379 #endif {-sparc_TARGET_ARCH-}