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 "nativeGen/NCG.h"
13 module PprMach ( pprInstr ) where
15 #include "HsVersions.h"
17 import MachRegs -- may differ per-platform
20 import AbsCSyn ( MagicId )
21 import CLabel ( pprCLabel_asm, externallyVisibleCLabel )
22 import CStrings ( charToC )
23 import Maybes ( maybeToBool )
24 import OrdList ( OrdList )
25 import Stix ( CodeSegment(..), StixTree )
26 import Char ( isPrint, isDigit )
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 pprReg :: IF_ARCH_i386(Size ->,) Reg -> SDoc
41 pprReg IF_ARCH_i386(s,) r
43 FixedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
44 MappedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
45 other -> text (show other) -- should only happen when debugging
48 ppr_reg_no :: FAST_REG_NO -> SDoc
51 ILIT( 0) -> SLIT("$0"); ILIT( 1) -> SLIT("$1");
52 ILIT( 2) -> SLIT("$2"); ILIT( 3) -> SLIT("$3");
53 ILIT( 4) -> SLIT("$4"); ILIT( 5) -> SLIT("$5");
54 ILIT( 6) -> SLIT("$6"); ILIT( 7) -> SLIT("$7");
55 ILIT( 8) -> SLIT("$8"); ILIT( 9) -> SLIT("$9");
56 ILIT(10) -> SLIT("$10"); ILIT(11) -> SLIT("$11");
57 ILIT(12) -> SLIT("$12"); ILIT(13) -> SLIT("$13");
58 ILIT(14) -> SLIT("$14"); ILIT(15) -> SLIT("$15");
59 ILIT(16) -> SLIT("$16"); ILIT(17) -> SLIT("$17");
60 ILIT(18) -> SLIT("$18"); ILIT(19) -> SLIT("$19");
61 ILIT(20) -> SLIT("$20"); ILIT(21) -> SLIT("$21");
62 ILIT(22) -> SLIT("$22"); ILIT(23) -> SLIT("$23");
63 ILIT(24) -> SLIT("$24"); ILIT(25) -> SLIT("$25");
64 ILIT(26) -> SLIT("$26"); ILIT(27) -> SLIT("$27");
65 ILIT(28) -> SLIT("$28"); ILIT(29) -> SLIT("$29");
66 ILIT(30) -> SLIT("$30"); ILIT(31) -> SLIT("$31");
67 ILIT(32) -> SLIT("$f0"); ILIT(33) -> SLIT("$f1");
68 ILIT(34) -> SLIT("$f2"); ILIT(35) -> SLIT("$f3");
69 ILIT(36) -> SLIT("$f4"); ILIT(37) -> SLIT("$f5");
70 ILIT(38) -> SLIT("$f6"); ILIT(39) -> SLIT("$f7");
71 ILIT(40) -> SLIT("$f8"); ILIT(41) -> SLIT("$f9");
72 ILIT(42) -> SLIT("$f10"); ILIT(43) -> SLIT("$f11");
73 ILIT(44) -> SLIT("$f12"); ILIT(45) -> SLIT("$f13");
74 ILIT(46) -> SLIT("$f14"); ILIT(47) -> SLIT("$f15");
75 ILIT(48) -> SLIT("$f16"); ILIT(49) -> SLIT("$f17");
76 ILIT(50) -> SLIT("$f18"); ILIT(51) -> SLIT("$f19");
77 ILIT(52) -> SLIT("$f20"); ILIT(53) -> SLIT("$f21");
78 ILIT(54) -> SLIT("$f22"); ILIT(55) -> SLIT("$f23");
79 ILIT(56) -> SLIT("$f24"); ILIT(57) -> SLIT("$f25");
80 ILIT(58) -> SLIT("$f26"); ILIT(59) -> SLIT("$f27");
81 ILIT(60) -> SLIT("$f28"); ILIT(61) -> SLIT("$f29");
82 ILIT(62) -> SLIT("$f30"); ILIT(63) -> SLIT("$f31");
83 _ -> SLIT("very naughty alpha register")
87 ppr_reg_no :: Size -> FAST_REG_NO -> SDoc
88 ppr_reg_no B i = ptext
90 ILIT( 0) -> SLIT("%al"); ILIT( 1) -> SLIT("%bl");
91 ILIT( 2) -> SLIT("%cl"); ILIT( 3) -> SLIT("%dl");
92 _ -> SLIT("very naughty I386 byte register")
96 ppr_reg_no HB i = ptext
98 ILIT( 0) -> SLIT("%ah"); ILIT( 1) -> SLIT("%bh");
99 ILIT( 2) -> SLIT("%ch"); ILIT( 3) -> SLIT("%dh");
100 _ -> SLIT("very naughty I386 high byte register")
105 ppr_reg_no S i = ptext
107 ILIT( 0) -> SLIT("%ax"); ILIT( 1) -> SLIT("%bx");
108 ILIT( 2) -> SLIT("%cx"); ILIT( 3) -> SLIT("%dx");
109 ILIT( 4) -> SLIT("%si"); ILIT( 5) -> SLIT("%di");
110 ILIT( 6) -> SLIT("%bp"); ILIT( 7) -> SLIT("%sp");
111 _ -> SLIT("very naughty I386 word register")
115 ppr_reg_no L i = ptext
117 ILIT( 0) -> SLIT("%eax"); ILIT( 1) -> SLIT("%ebx");
118 ILIT( 2) -> SLIT("%ecx"); ILIT( 3) -> SLIT("%edx");
119 ILIT( 4) -> SLIT("%esi"); ILIT( 5) -> SLIT("%edi");
120 ILIT( 6) -> SLIT("%ebp"); ILIT( 7) -> SLIT("%esp");
121 _ -> SLIT("very naughty I386 double word register")
124 ppr_reg_no F i = ptext
126 --ToDo: rm these (???)
127 ILIT( 8) -> SLIT("%st(0)"); ILIT( 9) -> SLIT("%st(1)");
128 ILIT(10) -> SLIT("%st(2)"); ILIT(11) -> SLIT("%st(3)");
129 ILIT(12) -> SLIT("%st(4)"); ILIT(13) -> SLIT("%st(5)");
130 ILIT(14) -> SLIT("%st(6)"); ILIT(15) -> SLIT("%st(7)");
131 _ -> SLIT("very naughty I386 float register")
134 ppr_reg_no DF i = ptext
136 --ToDo: rm these (???)
137 ILIT( 8) -> SLIT("%st(0)"); ILIT( 9) -> SLIT("%st(1)");
138 ILIT(10) -> SLIT("%st(2)"); ILIT(11) -> SLIT("%st(3)");
139 ILIT(12) -> SLIT("%st(4)"); ILIT(13) -> SLIT("%st(5)");
140 ILIT(14) -> SLIT("%st(6)"); ILIT(15) -> SLIT("%st(7)");
141 _ -> SLIT("very naughty I386 float register")
144 #if sparc_TARGET_ARCH
145 ppr_reg_no :: FAST_REG_NO -> SDoc
148 ILIT( 0) -> SLIT("%g0"); ILIT( 1) -> SLIT("%g1");
149 ILIT( 2) -> SLIT("%g2"); ILIT( 3) -> SLIT("%g3");
150 ILIT( 4) -> SLIT("%g4"); ILIT( 5) -> SLIT("%g5");
151 ILIT( 6) -> SLIT("%g6"); ILIT( 7) -> SLIT("%g7");
152 ILIT( 8) -> SLIT("%o0"); ILIT( 9) -> SLIT("%o1");
153 ILIT(10) -> SLIT("%o2"); ILIT(11) -> SLIT("%o3");
154 ILIT(12) -> SLIT("%o4"); ILIT(13) -> SLIT("%o5");
155 ILIT(14) -> SLIT("%o6"); ILIT(15) -> SLIT("%o7");
156 ILIT(16) -> SLIT("%l0"); ILIT(17) -> SLIT("%l1");
157 ILIT(18) -> SLIT("%l2"); ILIT(19) -> SLIT("%l3");
158 ILIT(20) -> SLIT("%l4"); ILIT(21) -> SLIT("%l5");
159 ILIT(22) -> SLIT("%l6"); ILIT(23) -> SLIT("%l7");
160 ILIT(24) -> SLIT("%i0"); ILIT(25) -> SLIT("%i1");
161 ILIT(26) -> SLIT("%i2"); ILIT(27) -> SLIT("%i3");
162 ILIT(28) -> SLIT("%i4"); ILIT(29) -> SLIT("%i5");
163 ILIT(30) -> SLIT("%i6"); ILIT(31) -> SLIT("%i7");
164 ILIT(32) -> SLIT("%f0"); ILIT(33) -> SLIT("%f1");
165 ILIT(34) -> SLIT("%f2"); ILIT(35) -> SLIT("%f3");
166 ILIT(36) -> SLIT("%f4"); ILIT(37) -> SLIT("%f5");
167 ILIT(38) -> SLIT("%f6"); ILIT(39) -> SLIT("%f7");
168 ILIT(40) -> SLIT("%f8"); ILIT(41) -> SLIT("%f9");
169 ILIT(42) -> SLIT("%f10"); ILIT(43) -> SLIT("%f11");
170 ILIT(44) -> SLIT("%f12"); ILIT(45) -> SLIT("%f13");
171 ILIT(46) -> SLIT("%f14"); ILIT(47) -> SLIT("%f15");
172 ILIT(48) -> SLIT("%f16"); ILIT(49) -> SLIT("%f17");
173 ILIT(50) -> SLIT("%f18"); ILIT(51) -> SLIT("%f19");
174 ILIT(52) -> SLIT("%f20"); ILIT(53) -> SLIT("%f21");
175 ILIT(54) -> SLIT("%f22"); ILIT(55) -> SLIT("%f23");
176 ILIT(56) -> SLIT("%f24"); ILIT(57) -> SLIT("%f25");
177 ILIT(58) -> SLIT("%f26"); ILIT(59) -> SLIT("%f27");
178 ILIT(60) -> SLIT("%f28"); ILIT(61) -> SLIT("%f29");
179 ILIT(62) -> SLIT("%f30"); ILIT(63) -> SLIT("%f31");
180 _ -> SLIT("very naughty sparc register")
185 %************************************************************************
187 \subsection{@pprSize@: print a @Size@}
189 %************************************************************************
192 pprSize :: Size -> SDoc
194 pprSize x = ptext (case x of
195 #if alpha_TARGET_ARCH
198 -- W -> SLIT("w") UNUSED
199 -- WU -> SLIT("wu") UNUSED
200 -- L -> SLIT("l") UNUSED
202 -- FF -> SLIT("f") UNUSED
203 -- DF -> SLIT("d") UNUSED
204 -- GF -> SLIT("g") UNUSED
205 -- SF -> SLIT("s") UNUSED
210 -- HB -> SLIT("b") UNUSED
211 -- S -> SLIT("w") UNUSED
216 #if sparc_TARGET_ARCH
219 -- HW -> SLIT("hw") UNUSED
220 -- HWU -> SLIT("uhw") UNUSED
223 -- D -> SLIT("d") UNUSED
226 pprStSize :: Size -> SDoc
227 pprStSize x = ptext (case x of
230 -- HW -> SLIT("hw") UNUSED
231 -- HWU -> SLIT("uhw") UNUSED
234 -- D -> SLIT("d") UNUSED
240 %************************************************************************
242 \subsection{@pprCond@: print a @Cond@}
244 %************************************************************************
247 pprCond :: Cond -> SDoc
249 pprCond c = ptext (case c of {
250 #if alpha_TARGET_ARCH
261 GEU -> SLIT("ae"); LU -> SLIT("b");
262 EQQ -> SLIT("e"); GTT -> SLIT("g");
263 GE -> SLIT("ge"); GU -> SLIT("a");
264 LTT -> SLIT("l"); LE -> SLIT("le");
265 LEU -> SLIT("be"); NE -> SLIT("ne");
266 NEG -> SLIT("s"); POS -> SLIT("ns");
267 ALWAYS -> SLIT("mp") -- hack
269 #if sparc_TARGET_ARCH
270 ALWAYS -> SLIT(""); NEVER -> SLIT("n");
271 GEU -> SLIT("geu"); LU -> SLIT("lu");
272 EQQ -> SLIT("e"); GTT -> SLIT("g");
273 GE -> SLIT("ge"); GU -> SLIT("gu");
274 LTT -> SLIT("l"); LE -> SLIT("le");
275 LEU -> SLIT("leu"); NE -> SLIT("ne");
276 NEG -> SLIT("neg"); POS -> SLIT("pos");
277 VC -> SLIT("vc"); VS -> SLIT("vs")
282 %************************************************************************
284 \subsection{@pprImm@: print an @Imm@}
286 %************************************************************************
289 pprImm :: Imm -> SDoc
291 pprImm (ImmInt i) = int i
292 pprImm (ImmInteger i) = integer i
293 pprImm (ImmCLbl l) = pprCLabel_asm l
294 pprImm (ImmLit s) = s
296 pprImm (ImmLab s) | underscorePrefix = (<>) (char '_') s
299 #if sparc_TARGET_ARCH
301 = hcat [ pp_lo, pprImm i, rparen ]
306 = hcat [ pp_hi, pprImm i, rparen ]
312 %************************************************************************
314 \subsection{@pprAddr@: print an @Addr@}
316 %************************************************************************
319 pprAddr :: MachRegsAddr -> SDoc
321 #if alpha_TARGET_ARCH
322 pprAddr (AddrReg r) = parens (pprReg r)
323 pprAddr (AddrImm i) = pprImm i
324 pprAddr (AddrRegImm r1 i)
325 = (<>) (pprImm i) (parens (pprReg r1))
331 pprAddr (ImmAddr imm off)
337 else if (off < 0) then
338 (<>) pp_imm (int off)
340 hcat [pp_imm, char '+', int off]
342 pprAddr (AddrBaseIndex base index displacement)
344 pp_disp = ppr_disp displacement
345 pp_off p = (<>) pp_disp (parens p)
346 pp_reg r = pprReg L r
349 (Nothing, Nothing) -> pp_disp
350 (Just b, Nothing) -> pp_off (pp_reg b)
351 (Nothing, Just (r,i)) -> pp_off (hcat [pp_reg r, comma, int i])
352 (Just b, Just (r,i)) -> pp_off (hcat [pp_reg b, comma, pp_reg r, comma, int i])
354 ppr_disp (ImmInt 0) = empty
355 ppr_disp imm = pprImm imm
360 #if sparc_TARGET_ARCH
361 pprAddr (AddrRegReg r1 (FixedReg ILIT(0))) = pprReg r1
363 pprAddr (AddrRegReg r1 r2)
364 = hcat [ pprReg r1, char '+', pprReg r2 ]
366 pprAddr (AddrRegImm r1 (ImmInt i))
368 | not (fits13Bits i) = largeOffsetError i
369 | otherwise = hcat [ pprReg r1, pp_sign, int i ]
371 pp_sign = if i > 0 then char '+' else empty
373 pprAddr (AddrRegImm r1 (ImmInteger i))
375 | not (fits13Bits i) = largeOffsetError i
376 | otherwise = hcat [ pprReg r1, pp_sign, integer i ]
378 pp_sign = if i > 0 then char '+' else empty
380 pprAddr (AddrRegImm r1 imm)
381 = hcat [ pprReg r1, char '+', pprImm imm ]
385 %************************************************************************
387 \subsection{@pprInstr@: print an @Instr@}
389 %************************************************************************
392 pprInstr :: Instr -> SDoc
394 --pprInstr (COMMENT s) = (<>) (ptext SLIT("# ")) (ptext s)
395 pprInstr (COMMENT s) = empty -- nuke 'em
396 --alpha: = (<>) (ptext SLIT("\t# ")) (ptext s)
397 --i386 : = (<>) (ptext SLIT("# ")) (ptext s)
398 --sparc: = (<>) (ptext SLIT("! ")) (ptext s)
400 pprInstr (SEGMENT TextSegment)
402 IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
403 ,IF_ARCH_sparc(SLIT("\t.text\n\t.align 4") {-word boundary-}
404 ,IF_ARCH_i386((_PK_ ".text\n\t.align 2\x2c\&0x90") {-needs per-OS variation!-}
407 pprInstr (SEGMENT DataSegment)
409 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
410 ,IF_ARCH_sparc(SLIT("\t.data\n\t.align 8") {-<8 will break double constants -}
411 ,IF_ARCH_i386(SLIT(".data\n\t.align 2")
414 pprInstr (LABEL clab)
416 pp_lab = pprCLabel_asm clab
419 if not (externallyVisibleCLabel clab) then
423 IF_ARCH_alpha(SLIT("\t.globl\t")
424 ,IF_ARCH_i386(SLIT(".globl ")
425 ,IF_ARCH_sparc(SLIT("\t.global\t")
427 , pp_lab, char '\n'],
432 pprInstr (ASCII False{-no backslash conversion-} str)
433 = hcat [ ptext SLIT("\t.asciz "), char '\"', text str, char '"' ]
435 pprInstr (ASCII True str)
436 = (<>) (text "\t.ascii \"") (asciify str 60)
438 asciify :: String -> Int -> SDoc
440 asciify [] _ = text "\\0\""
441 asciify s n | n <= 0 = (<>) (text "\"\n\t.ascii \"") (asciify s 60)
442 asciify ('\\':cs) n = (<>) (text "\\\\") (asciify cs (n-1))
443 asciify ('\"':cs) n = (<>) (text "\\\"") (asciify cs (n-1))
444 asciify (c:cs) n | isPrint c = (<>) (char c) (asciify cs (n-1))
445 asciify [c] _ = (<>) (text (charToC c)) (text ("\\0\"")){-"-}
446 asciify (c:(cs@(d:_))) n
447 | isDigit d = (<>) (text (charToC c)) (asciify cs 0)
448 | otherwise = (<>) (text (charToC c)) (asciify cs (n-1))
451 = vcat [(<>) (ptext pp_size) (pprImm x) | x <- xs]
454 #if alpha_TARGET_ARCH
455 B -> SLIT("\t.byte\t")
456 BU -> SLIT("\t.byte\t")
457 --UNUSED: W -> SLIT("\t.word\t")
458 --UNUSED: WU -> SLIT("\t.word\t")
459 --UNUSED: L -> SLIT("\t.long\t")
460 Q -> SLIT("\t.quad\t")
461 --UNUSED: FF -> SLIT("\t.f_floating\t")
462 --UNUSED: DF -> SLIT("\t.d_floating\t")
463 --UNUSED: GF -> SLIT("\t.g_floating\t")
464 --UNUSED: SF -> SLIT("\t.s_floating\t")
465 TF -> SLIT("\t.t_floating\t")
468 B -> SLIT("\t.byte\t")
469 --UNUSED: HB -> SLIT("\t.byte\t")
470 --UNUSED: S -> SLIT("\t.word\t")
471 L -> SLIT("\t.long\t")
472 F -> SLIT("\t.long\t")
473 DF -> SLIT("\t.double\t")
475 #if sparc_TARGET_ARCH
476 B -> SLIT("\t.byte\t")
477 BU -> SLIT("\t.byte\t")
478 W -> SLIT("\t.word\t")
479 DF -> SLIT("\t.double\t")
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 pp_ldgp = ptext SLIT(":\n\tldgp $29,0($27)\n")
824 pp_frame = ptext SLIT("..ng:\n\t.frame $30,4240,$26,0\n\t.prologue 1")
826 pprInstr (FUNEND clab)
827 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
830 Continue with Alpha-only printing bits and bobs:
834 pprRI (RIReg r) = pprReg r
835 pprRI (RIImm r) = pprImm r
837 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> SDoc
839 pprRegRIReg name reg1 ri reg2
851 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
853 pprSizeRegRegReg name size reg1 reg2 reg3
866 #endif {-alpha_TARGET_ARCH-}
869 %************************************************************************
871 \subsubsection{@pprInstr@ for an I386}
873 %************************************************************************
878 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
882 (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
886 pprInstr (MOV size src dst)
887 = pprSizeOpOp SLIT("mov") size src dst
888 pprInstr (MOVZX size src dst) = pprSizeOpOpCoerce SLIT("movzx") L size src dst
889 pprInstr (MOVSX size src dst) = pprSizeOpOpCoerce SLIT("movxs") L size src dst
891 -- here we do some patching, since the physical registers are only set late
892 -- in the code generation.
893 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
895 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
896 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
898 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
899 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
901 = pprInstr (ADD size (OpImm displ) dst)
902 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
904 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
905 = pprSizeOp SLIT("dec") size dst
906 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
907 = pprSizeOp SLIT("inc") size dst
908 pprInstr (ADD size src dst)
909 = pprSizeOpOp SLIT("add") size src dst
910 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
911 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
912 pprInstr (IDIV size op) = pprSizeOp SLIT("idiv") size op
914 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
915 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
916 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
917 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
918 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
920 pprInstr (SHL size imm dst) = pprSizeByteOpOp SLIT("shl") size imm dst
921 pprInstr (SAR size imm dst) = pprSizeByteOpOp SLIT("sar") size imm dst
922 pprInstr (SHR size imm dst) = pprSizeByteOpOp SLIT("shr") size imm dst
924 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
925 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
926 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
927 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
929 pprInstr (NOP) = ptext SLIT("\tnop")
930 pprInstr (CLTD) = ptext SLIT("\tcltd")
932 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
934 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
936 pprInstr (JMP (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
937 pprInstr (JMP op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand L op)
940 = hcat [ ptext SLIT("\tcall "), pprImm imm ]
942 pprInstr SAHF = ptext SLIT("\tsahf")
943 pprInstr FABS = ptext SLIT("\tfabs")
945 pprInstr (FADD sz src@(OpAddr _))
946 = hcat [ptext SLIT("\tfadd"), pprSize sz, space, pprOperand sz src]
947 pprInstr (FADD sz src)
948 = ptext SLIT("\tfadd")
950 = ptext SLIT("\tfaddp")
951 pprInstr (FMUL sz src)
952 = hcat [ptext SLIT("\tfmul"), pprSize sz, space, pprOperand sz src]
954 = ptext SLIT("\tfmulp")
955 pprInstr (FIADD size op) = pprSizeAddr SLIT("fiadd") size op
956 pprInstr FCHS = ptext SLIT("\tfchs")
957 pprInstr (FCOM size op) = pprSizeOp SLIT("fcom") size op
958 pprInstr FCOS = ptext SLIT("\tfcos")
959 pprInstr (FIDIV size op) = pprSizeAddr SLIT("fidiv") size op
960 pprInstr (FDIV sz src)
961 = hcat [ptext SLIT("\tfdiv"), pprSize sz, space, pprOperand sz src]
963 = ptext SLIT("\tfdivp")
964 pprInstr (FDIVR sz src)
965 = hcat [ptext SLIT("\tfdivr"), pprSize sz, space, pprOperand sz src]
967 = ptext SLIT("\tfdivpr")
968 pprInstr (FIDIVR size op) = pprSizeAddr SLIT("fidivr") size op
969 pprInstr (FICOM size op) = pprSizeAddr SLIT("ficom") size op
970 pprInstr (FILD sz op reg) = pprSizeAddrReg SLIT("fild") sz op reg
971 pprInstr (FIST size op) = pprSizeAddr SLIT("fist") size op
972 pprInstr (FLD sz (OpImm (ImmCLbl src)))
973 = hcat [ptext SLIT("\tfld"),pprSize sz,space,pprCLabel_asm src]
974 pprInstr (FLD sz src)
975 = hcat [ptext SLIT("\tfld"),pprSize sz,space,pprOperand sz src]
976 pprInstr FLD1 = ptext SLIT("\tfld1")
977 pprInstr FLDZ = ptext SLIT("\tfldz")
978 pprInstr (FIMUL size op) = pprSizeAddr SLIT("fimul") size op
979 pprInstr FRNDINT = ptext SLIT("\tfrndint")
980 pprInstr FSIN = ptext SLIT("\tfsin")
981 pprInstr FSQRT = ptext SLIT("\tfsqrt")
982 pprInstr (FST sz dst)
983 = hcat [ptext SLIT("\tfst"), pprSize sz, space, pprOperand sz dst]
984 pprInstr (FSTP sz dst)
985 = hcat [ptext SLIT("\tfstp"), pprSize sz, space, pprOperand sz dst]
986 pprInstr (FISUB size op) = pprSizeAddr SLIT("fisub") size op
987 pprInstr (FSUB sz src)
988 = hcat [ptext SLIT("\tfsub"), pprSize sz, space, pprOperand sz src]
990 = ptext SLIT("\tfsubp")
991 pprInstr (FSUBR size src)
992 = pprSizeOp SLIT("fsubr") size src
994 = ptext SLIT("\tfsubpr")
995 pprInstr (FISUBR size op)
996 = pprSizeAddr SLIT("fisubr") size op
997 pprInstr FTST = ptext SLIT("\tftst")
998 pprInstr (FCOMP sz op)
999 = hcat [ptext SLIT("\tfcomp"), pprSize sz, space, pprOperand sz op]
1000 pprInstr FUCOMPP = ptext SLIT("\tfucompp")
1001 pprInstr FXCH = ptext SLIT("\tfxch")
1002 pprInstr FNSTSW = ptext SLIT("\tfnstsw %ax")
1003 pprInstr FNOP = ptext SLIT("")
1006 Continue with I386-only printing bits and bobs:
1008 pprDollImm :: Imm -> SDoc
1010 pprDollImm i = hcat [ ptext SLIT("$"), pprImm i]
1012 pprOperand :: Size -> Operand -> SDoc
1013 pprOperand s (OpReg r) = pprReg s r
1014 pprOperand s (OpImm i) = pprDollImm i
1015 pprOperand s (OpAddr ea) = pprAddr ea
1017 pprSizeOp :: FAST_STRING -> Size -> Operand -> SDoc
1018 pprSizeOp name size op1
1027 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1028 pprSizeOpOp name size op1 op2
1034 pprOperand size op1,
1039 pprSizeByteOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1040 pprSizeByteOpOp name size op1 op2
1051 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> SDoc
1052 pprSizeOpReg name size op1 reg
1058 pprOperand size op1,
1063 pprSizeAddr :: FAST_STRING -> Size -> MachRegsAddr -> SDoc
1064 pprSizeAddr name size op
1073 pprSizeAddrReg :: FAST_STRING -> Size -> MachRegsAddr -> Reg -> SDoc
1074 pprSizeAddrReg name size op dst
1085 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1086 pprOpOp name size op1 op2
1090 pprOperand size op1,
1095 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> SDoc
1096 pprSizeOpOpCoerce name size1 size2 op1 op2
1097 = hcat [ char '\t', ptext name, space,
1098 pprOperand size1 op1,
1100 pprOperand size2 op2
1103 pprCondInstr :: FAST_STRING -> Cond -> SDoc -> SDoc
1104 pprCondInstr name cond arg
1105 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1107 #endif {-i386_TARGET_ARCH-}
1110 %************************************************************************
1112 \subsubsection{@pprInstr@ for a SPARC}
1114 %************************************************************************
1117 #if sparc_TARGET_ARCH
1119 -- a clumsy hack for now, to handle possible double alignment problems
1121 -- even clumsier, to allow for RegReg regs that show when doing indexed
1122 -- reads (bytearrays).
1124 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1126 ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1, char '\n',
1127 pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg, char '\n',
1128 pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)
1131 pprInstr (LD DF addr reg) | maybeToBool off_addr
1145 off_addr = addrOffset addr 4
1146 addr2 = case off_addr of Just x -> x
1148 pprInstr (LD size addr reg)
1159 -- The same clumsy hack as above
1161 pprInstr (ST DF reg (AddrRegReg g1 g2))
1163 ptext SLIT("\tadd\t"),
1164 pprReg g1,comma,pprReg g2,comma,pprReg g1, char '\n',
1165 ptext SLIT("\tst\t"),
1166 pprReg reg, pp_comma_lbracket, pprReg g1,
1167 ptext SLIT("]\n\tst\t"),
1168 pprReg (fPair reg), pp_comma_lbracket, pprReg g1, ptext SLIT("+4]")
1171 pprInstr (ST DF reg addr) | maybeToBool off_addr
1173 ptext SLIT("\tst\t"),
1174 pprReg reg, pp_comma_lbracket, pprAddr addr,
1176 ptext SLIT("]\n\tst\t"),
1177 pprReg (fPair reg), pp_comma_lbracket,
1178 pprAddr addr2, rbrack
1181 off_addr = addrOffset addr 4
1182 addr2 = case off_addr of Just x -> x
1184 -- no distinction is made between signed and unsigned bytes on stores for the
1185 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1186 -- so we call a special-purpose pprSize for ST..
1188 pprInstr (ST size reg addr)
1199 pprInstr (ADD x cc reg1 ri reg2)
1200 | not x && not cc && riZero ri
1201 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1203 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1205 pprInstr (SUB x cc reg1 ri reg2)
1206 | not x && cc && reg2 == g0
1207 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1208 | not x && not cc && riZero ri
1209 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1211 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1213 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1214 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1216 pprInstr (OR b reg1 ri reg2)
1217 | not b && reg1 == g0
1218 = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1220 = pprRegRIReg SLIT("or") b reg1 ri reg2
1222 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1224 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1225 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1227 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1228 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1229 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1231 pprInstr (SETHI imm reg)
1233 ptext SLIT("\tsethi\t"),
1239 pprInstr NOP = ptext SLIT("\tnop")
1241 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1242 pprInstr (FABS DF reg1 reg2)
1243 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1244 (if (reg1 == reg2) then empty
1245 else (<>) (char '\n')
1246 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1248 pprInstr (FADD size reg1 reg2 reg3)
1249 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1250 pprInstr (FCMP e size reg1 reg2)
1251 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1252 pprInstr (FDIV size reg1 reg2 reg3)
1253 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1255 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1256 pprInstr (FMOV DF reg1 reg2)
1257 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1258 (if (reg1 == reg2) then empty
1259 else (<>) (char '\n')
1260 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1262 pprInstr (FMUL size reg1 reg2 reg3)
1263 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1265 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1266 pprInstr (FNEG DF reg1 reg2)
1267 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1268 (if (reg1 == reg2) then empty
1269 else (<>) (char '\n')
1270 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1272 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1273 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1274 pprInstr (FxTOy size1 size2 reg1 reg2)
1287 pprReg reg1, comma, pprReg reg2
1291 pprInstr (BI cond b lab)
1293 ptext SLIT("\tb"), pprCond cond,
1294 if b then pp_comma_a else empty,
1299 pprInstr (BF cond b lab)
1301 ptext SLIT("\tfb"), pprCond cond,
1302 if b then pp_comma_a else empty,
1307 pprInstr (JMP addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1309 pprInstr (CALL imm n _)
1310 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1313 Continue with SPARC-only printing bits and bobs:
1316 pprRI (RIReg r) = pprReg r
1317 pprRI (RIImm r) = pprImm r
1319 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1320 pprSizeRegReg name size reg1 reg2
1325 F -> ptext SLIT("s\t")
1326 DF -> ptext SLIT("d\t")),
1332 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1333 pprSizeRegRegReg name size reg1 reg2 reg3
1338 F -> ptext SLIT("s\t")
1339 DF -> ptext SLIT("d\t")),
1347 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> SDoc
1348 pprRegRIReg name b reg1 ri reg2
1352 if b then ptext SLIT("cc\t") else char '\t',
1360 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> SDoc
1361 pprRIReg name b ri reg1
1365 if b then ptext SLIT("cc\t") else char '\t',
1371 pp_ld_lbracket = ptext SLIT("\tld\t[")
1372 pp_rbracket_comma = text "],"
1373 pp_comma_lbracket = text ",["
1374 pp_comma_a = text ",a"
1376 #endif {-sparc_TARGET_ARCH-}