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
18 import MachRegs -- may differ per-platform
21 import AbsCSyn ( MagicId )
22 import CLabel ( pprCLabel_asm, externallyVisibleCLabel )
23 import CStrings ( charToC )
24 import Maybes ( maybeToBool )
25 import OrdList ( OrdList )
26 import Stix ( CodeSegment(..), StixTree )
27 import Unpretty -- all of it
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 -> Unpretty
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 -> uppStr (show other) -- should only happen when debugging
48 ppr_reg_no :: FAST_REG_NO -> Unpretty
49 ppr_reg_no i = uppPStr
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 -> Unpretty
88 ppr_reg_no B i = uppPStr
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 = uppPStr
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 = uppPStr
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 = uppPStr
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 = uppPStr
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 = uppPStr
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 -> Unpretty
146 ppr_reg_no i = uppPStr
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 -> Unpretty
194 pprSize x = uppPStr (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
229 %************************************************************************
231 \subsection{@pprCond@: print a @Cond@}
233 %************************************************************************
236 pprCond :: Cond -> Unpretty
238 pprCond c = uppPStr (case c of {
239 #if alpha_TARGET_ARCH
250 GEU -> SLIT("ae"); LU -> SLIT("b");
251 EQ -> SLIT("e"); GT -> SLIT("g");
252 GE -> SLIT("ge"); GU -> SLIT("a");
253 LT -> SLIT("l"); LE -> SLIT("le");
254 LEU -> SLIT("be"); NE -> SLIT("ne");
255 NEG -> SLIT("s"); POS -> SLIT("ns");
256 ALWAYS -> SLIT("mp") -- hack
258 #if sparc_TARGET_ARCH
259 ALWAYS -> SLIT(""); NEVER -> SLIT("n");
260 GEU -> SLIT("geu"); LU -> SLIT("lu");
261 EQ -> SLIT("e"); GT -> SLIT("g");
262 GE -> SLIT("ge"); GU -> SLIT("gu");
263 LT -> SLIT("l"); LE -> SLIT("le");
264 LEU -> SLIT("leu"); NE -> SLIT("ne");
265 NEG -> SLIT("neg"); POS -> SLIT("pos");
266 VC -> SLIT("vc"); VS -> SLIT("vs")
271 %************************************************************************
273 \subsection{@pprImm@: print an @Imm@}
275 %************************************************************************
278 pprImm :: Imm -> Unpretty
280 pprImm (ImmInt i) = uppInt i
281 pprImm (ImmInteger i) = uppInteger i
282 pprImm (ImmCLbl l) = pprCLabel_asm l
283 pprImm (ImmLit s) = s
285 pprImm (ImmLab s) | underscorePrefix = uppBeside (uppChar '_') s
288 #if sparc_TARGET_ARCH
290 = uppBesides [ pp_lo, pprImm i, uppRparen ]
292 pp_lo = uppPStr (_packCString (A# "%lo("#))
295 = uppBesides [ pp_hi, pprImm i, uppRparen ]
297 pp_hi = uppPStr (_packCString (A# "%hi("#))
301 %************************************************************************
303 \subsection{@pprAddr@: print an @Addr@}
305 %************************************************************************
308 pprAddr :: Addr -> Unpretty
310 #if alpha_TARGET_ARCH
311 pprAddr (AddrReg r) = uppParens (pprReg r)
312 pprAddr (AddrImm i) = pprImm i
313 pprAddr (AddrRegImm r1 i)
314 = uppBeside (pprImm i) (uppParens (pprReg r1))
320 pprAddr (ImmAddr imm off)
326 else if (off < 0) then
327 uppBeside pp_imm (uppInt off)
329 uppBesides [pp_imm, uppChar '+', uppInt off]
331 pprAddr (Addr base index displacement)
333 pp_disp = ppr_disp displacement
334 pp_off p = uppBeside pp_disp (uppParens p)
335 pp_reg r = pprReg L r
338 (Nothing, Nothing) -> pp_disp
339 (Just b, Nothing) -> pp_off (pp_reg b)
340 (Nothing, Just (r,i)) -> pp_off (uppBesides [pp_reg r, uppComma, uppInt i])
341 (Just b, Just (r,i)) -> pp_off (uppBesides [pp_reg b, uppComma, pp_reg r, uppComma, uppInt i])
343 ppr_disp (ImmInt 0) = uppNil
344 ppr_disp imm = pprImm imm
349 #if sparc_TARGET_ARCH
350 pprAddr (AddrRegReg r1 (FixedReg ILIT(0))) = pprReg r1
352 pprAddr (AddrRegReg r1 r2)
353 = uppBesides [ pprReg r1, uppChar '+', pprReg r2 ]
355 pprAddr (AddrRegImm r1 (ImmInt i))
357 | not (fits13Bits i) = largeOffsetError i
358 | otherwise = uppBesides [ pprReg r1, pp_sign, uppInt i ]
360 pp_sign = if i > 0 then uppChar '+' else uppNil
362 pprAddr (AddrRegImm r1 (ImmInteger i))
364 | not (fits13Bits i) = largeOffsetError i
365 | otherwise = uppBesides [ pprReg r1, pp_sign, uppInteger i ]
367 pp_sign = if i > 0 then uppChar '+' else uppNil
369 pprAddr (AddrRegImm r1 imm)
370 = uppBesides [ pprReg r1, uppChar '+', pprImm imm ]
374 %************************************************************************
376 \subsection{@pprInstr@: print an @Instr@}
378 %************************************************************************
381 pprInstr :: Instr -> Unpretty
383 pprInstr (COMMENT s) = uppNil -- nuke 'em
384 --alpha: = uppBeside (uppPStr SLIT("\t# ")) (uppPStr s)
385 --i386 : = uppBeside (uppPStr SLIT("# ")) (uppPStr s)
386 --sparc: = uppBeside (uppPStr SLIT("! ")) (uppPStr s)
388 pprInstr (SEGMENT TextSegment)
390 IF_ARCH_alpha(SLIT("\t.text\n\t.align 3") {-word boundary-}
391 ,IF_ARCH_sparc(SLIT("\t.text\n\t.align 4") {-word boundary-}
392 ,IF_ARCH_i386(SLIT(".text\n\t.align 2,0x90") {-needs per-OS variation!-}
395 pprInstr (SEGMENT DataSegment)
397 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
398 ,IF_ARCH_sparc(SLIT("\t.data\n\t.align 8") {-<8 will break double constants -}
399 ,IF_ARCH_i386(SLIT(".data\n\t.align 2")
402 pprInstr (LABEL clab)
404 pp_lab = pprCLabel_asm clab
407 if not (externallyVisibleCLabel clab) then
411 IF_ARCH_alpha(SLIT("\t.globl\t")
412 ,IF_ARCH_i386(SLIT(".globl ")
413 ,IF_ARCH_sparc(SLIT("\t.global\t")
415 , pp_lab, uppChar '\n'],
420 pprInstr (ASCII False{-no backslash conversion-} str)
421 = uppBesides [ uppStr "\t.asciz \"", uppStr str, uppChar '"' ]
423 pprInstr (ASCII True str)
424 = uppBeside (uppStr "\t.ascii \"") (asciify str 60)
426 asciify :: String -> Int -> Unpretty
428 asciify [] _ = uppStr ("\\0\"")
429 asciify s n | n <= 0 = uppBeside (uppStr "\"\n\t.ascii \"") (asciify s 60)
430 asciify ('\\':cs) n = uppBeside (uppStr "\\\\") (asciify cs (n-1))
431 asciify ('\"':cs) n = uppBeside (uppStr "\\\"") (asciify cs (n-1))
432 asciify (c:cs) n | isPrint c = uppBeside (uppChar c) (asciify cs (n-1))
433 asciify [c] _ = uppBeside (uppStr (charToC c)) (uppStr ("\\0\""))
434 asciify (c:(cs@(d:_))) n
435 | isDigit d = uppBeside (uppStr (charToC c)) (asciify cs 0)
436 | otherwise = uppBeside (uppStr (charToC c)) (asciify cs (n-1))
439 = uppInterleave (uppChar '\n')
440 [uppBeside (uppPStr pp_size) (pprImm x) | x <- xs]
443 #if alpha_TARGET_ARCH
444 B -> SLIT("\t.byte\t")
445 BU -> SLIT("\t.byte\t")
446 --UNUSED: W -> SLIT("\t.word\t")
447 --UNUSED: WU -> SLIT("\t.word\t")
448 --UNUSED: L -> SLIT("\t.long\t")
449 Q -> SLIT("\t.quad\t")
450 --UNUSED: FF -> SLIT("\t.f_floating\t")
451 --UNUSED: DF -> SLIT("\t.d_floating\t")
452 --UNUSED: GF -> SLIT("\t.g_floating\t")
453 --UNUSED: SF -> SLIT("\t.s_floating\t")
454 TF -> SLIT("\t.t_floating\t")
457 B -> SLIT("\t.byte\t")
458 --UNUSED: HB -> SLIT("\t.byte\t")
459 --UNUSED: S -> SLIT("\t.word\t")
460 L -> SLIT("\t.long\t")
461 F -> SLIT("\t.long\t")
462 DF -> SLIT("\t.double\t")
464 #if sparc_TARGET_ARCH
465 B -> SLIT("\t.byte\t")
466 BU -> SLIT("\t.byte\t")
467 W -> SLIT("\t.word\t")
468 DF -> SLIT("\t.double\t")
471 -- fall through to rest of (machine-specific) pprInstr...
474 %************************************************************************
476 \subsubsection{@pprInstr@ for an Alpha}
478 %************************************************************************
481 #if alpha_TARGET_ARCH
483 pprInstr (LD size reg addr)
485 uppPStr SLIT("\tld"),
493 pprInstr (LDA reg addr)
495 uppPStr SLIT("\tlda\t"),
501 pprInstr (LDAH reg addr)
503 uppPStr SLIT("\tldah\t"),
509 pprInstr (LDGP reg addr)
511 uppPStr SLIT("\tldgp\t"),
517 pprInstr (LDI size reg imm)
519 uppPStr SLIT("\tldi"),
527 pprInstr (ST size reg addr)
529 uppPStr SLIT("\tst"),
539 uppPStr SLIT("\tclr\t"),
543 pprInstr (ABS size ri reg)
545 uppPStr SLIT("\tabs"),
553 pprInstr (NEG size ov ri reg)
555 uppPStr SLIT("\tneg"),
557 if ov then uppPStr SLIT("v\t") else uppChar '\t',
563 pprInstr (ADD size ov reg1 ri reg2)
565 uppPStr SLIT("\tadd"),
567 if ov then uppPStr SLIT("v\t") else uppChar '\t',
575 pprInstr (SADD size scale reg1 ri reg2)
577 uppPStr (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
588 pprInstr (SUB size ov reg1 ri reg2)
590 uppPStr SLIT("\tsub"),
592 if ov then uppPStr SLIT("v\t") else uppChar '\t',
600 pprInstr (SSUB size scale reg1 ri reg2)
602 uppPStr (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
613 pprInstr (MUL size ov reg1 ri reg2)
615 uppPStr SLIT("\tmul"),
617 if ov then uppPStr SLIT("v\t") else uppChar '\t',
625 pprInstr (DIV size uns reg1 ri reg2)
627 uppPStr SLIT("\tdiv"),
629 if uns then uppPStr SLIT("u\t") else uppChar '\t',
637 pprInstr (REM size uns reg1 ri reg2)
639 uppPStr SLIT("\trem"),
641 if uns then uppPStr SLIT("u\t") else uppChar '\t',
649 pprInstr (NOT ri reg)
651 uppPStr SLIT("\tnot"),
658 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
659 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
660 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
661 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
662 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
663 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
665 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
666 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
667 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
669 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
670 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
672 pprInstr (NOP) = uppPStr SLIT("\tnop")
674 pprInstr (CMP cond reg1 ri reg2)
676 uppPStr SLIT("\tcmp"),
688 uppPStr SLIT("\tfclr\t"),
692 pprInstr (FABS reg1 reg2)
694 uppPStr SLIT("\tfabs\t"),
700 pprInstr (FNEG size reg1 reg2)
702 uppPStr SLIT("\tneg"),
710 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
711 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
712 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
713 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
715 pprInstr (CVTxy size1 size2 reg1 reg2)
717 uppPStr SLIT("\tcvt"),
719 case size2 of {Q -> uppPStr SLIT("qc"); _ -> pprSize size2},
726 pprInstr (FCMP size cond reg1 reg2 reg3)
728 uppPStr SLIT("\tcmp"),
739 pprInstr (FMOV reg1 reg2)
741 uppPStr SLIT("\tfmov\t"),
747 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
749 pprInstr (BI NEVER reg lab) = uppNil
751 pprInstr (BI cond reg lab)
761 pprInstr (BF cond reg lab)
763 uppPStr SLIT("\tfb"),
772 = uppBeside (uppPStr SLIT("\tbr\t")) (pprImm lab)
774 pprInstr (JMP reg addr hint)
776 uppPStr SLIT("\tjmp\t"),
785 = uppBeside (uppPStr SLIT("\tbsr\t")) (pprImm imm)
787 pprInstr (JSR reg addr n)
789 uppPStr SLIT("\tjsr\t"),
795 pprInstr (FUNBEGIN clab)
797 if (externallyVisibleCLabel clab) then
798 uppBesides [uppPStr SLIT("\t.globl\t"), pp_lab, uppChar '\n']
801 uppPStr SLIT("\t.ent "),
810 pp_lab = pprCLabel_asm clab
811 pp_ldgp = uppPStr (_packCString (A# ":\n\tldgp $29,0($27)\n"#))
812 pp_frame = uppPStr (_packCString (A# "..ng:\n\t.frame $30,4240,$26,0\n\t.prologue 1"#))
814 pprInstr (FUNEND clab)
815 = uppBeside (uppPStr SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
818 Continue with Alpha-only printing bits and bobs:
820 pprRI :: RI -> Unpretty
822 pprRI (RIReg r) = pprReg r
823 pprRI (RIImm r) = pprImm r
825 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> Unpretty
827 pprRegRIReg name reg1 ri reg2
839 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Unpretty
841 pprSizeRegRegReg name size reg1 reg2 reg3
854 #endif {-alpha_TARGET_ARCH-}
857 %************************************************************************
859 \subsubsection{@pprInstr@ for an I386}
861 %************************************************************************
866 pprInstr (MOV size (OpReg src) (OpReg dst)) -- hack
869 pprInstr (MOV size src dst)
870 = pprSizeOpOp SLIT("mov") size src dst
871 pprInstr (MOVZX size src dst) = pprSizeOpOpCoerce SLIT("movzx") L size src dst
872 pprInstr (MOVSX size src dst) = pprSizeOpOpCoerce SLIT("movxs") L size src dst
874 -- here we do some patching, since the physical registers are only set late
875 -- in the code generation.
876 pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
878 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
879 pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
881 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
882 pprInstr (LEA size (OpAddr (Addr src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
884 = pprInstr (ADD size (OpImm displ) dst)
885 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
887 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
888 = pprSizeOp SLIT("dec") size dst
889 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
890 = pprSizeOp SLIT("inc") size dst
891 pprInstr (ADD size src dst)
892 = pprSizeOpOp SLIT("add") size src dst
893 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
894 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
895 pprInstr (IDIV size op) = pprSizeOp SLIT("idiv") size op
897 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
898 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
899 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
900 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
901 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
902 pprInstr (SHL size imm dst) = pprSizeOpOp SLIT("shl") size imm dst
903 pprInstr (SAR size imm dst) = pprSizeOpOp SLIT("sar") size imm dst
904 pprInstr (SHR size imm dst) = pprSizeOpOp SLIT("shr") size imm dst
906 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
907 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
908 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
909 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
911 pprInstr (NOP) = uppPStr SLIT("\tnop")
912 pprInstr (CLTD) = uppPStr SLIT("\tcltd")
914 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
916 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
918 pprInstr (JMP (OpImm imm)) = uppBeside (uppPStr SLIT("\tjmp ")) (pprImm imm)
919 pprInstr (JMP op) = uppBeside (uppPStr SLIT("\tjmp *")) (pprOperand L op)
922 = uppBesides [ uppPStr SLIT("\tcall "), pprImm imm ]
924 pprInstr SAHF = uppPStr SLIT("\tsahf")
925 pprInstr FABS = uppPStr SLIT("\tfabs")
927 pprInstr (FADD sz src@(OpAddr _))
928 = uppBesides [uppPStr SLIT("\tfadd"), pprSize sz, uppSP, pprOperand sz src]
929 pprInstr (FADD sz src)
930 = uppPStr SLIT("\tfadd")
932 = uppPStr SLIT("\tfaddp")
933 pprInstr (FMUL sz src)
934 = uppBesides [uppPStr SLIT("\tfmul"), pprSize sz, uppSP, pprOperand sz src]
936 = uppPStr SLIT("\tfmulp")
937 pprInstr (FIADD size op) = pprSizeAddr SLIT("fiadd") size op
938 pprInstr FCHS = uppPStr SLIT("\tfchs")
939 pprInstr (FCOM size op) = pprSizeOp SLIT("fcom") size op
940 pprInstr FCOS = uppPStr SLIT("\tfcos")
941 pprInstr (FIDIV size op) = pprSizeAddr SLIT("fidiv") size op
942 pprInstr (FDIV sz src)
943 = uppBesides [uppPStr SLIT("\tfdiv"), pprSize sz, uppSP, pprOperand sz src]
945 = uppPStr SLIT("\tfdivp")
946 pprInstr (FDIVR sz src)
947 = uppBesides [uppPStr SLIT("\tfdivr"), pprSize sz, uppSP, pprOperand sz src]
949 = uppPStr SLIT("\tfdivpr")
950 pprInstr (FIDIVR size op) = pprSizeAddr SLIT("fidivr") size op
951 pprInstr (FICOM size op) = pprSizeAddr SLIT("ficom") size op
952 pprInstr (FILD sz op reg) = pprSizeAddrReg SLIT("fild") sz op reg
953 pprInstr (FIST size op) = pprSizeAddr SLIT("fist") size op
954 pprInstr (FLD sz (OpImm (ImmCLbl src)))
955 = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppSP,pprCLabel_asm src]
956 pprInstr (FLD sz src)
957 = uppBesides [uppPStr SLIT("\tfld"),pprSize sz,uppSP,pprOperand sz src]
958 pprInstr FLD1 = uppPStr SLIT("\tfld1")
959 pprInstr FLDZ = uppPStr SLIT("\tfldz")
960 pprInstr (FIMUL size op) = pprSizeAddr SLIT("fimul") size op
961 pprInstr FRNDINT = uppPStr SLIT("\tfrndint")
962 pprInstr FSIN = uppPStr SLIT("\tfsin")
963 pprInstr FSQRT = uppPStr SLIT("\tfsqrt")
964 pprInstr (FST sz dst)
965 = uppBesides [uppPStr SLIT("\tfst"), pprSize sz, uppSP, pprOperand sz dst]
966 pprInstr (FSTP sz dst)
967 = uppBesides [uppPStr SLIT("\tfstp"), pprSize sz, uppSP, pprOperand sz dst]
968 pprInstr (FISUB size op) = pprSizeAddr SLIT("fisub") size op
969 pprInstr (FSUB sz src)
970 = uppBesides [uppPStr SLIT("\tfsub"), pprSize sz, uppSP, pprOperand sz src]
972 = uppPStr SLIT("\tfsubp")
973 pprInstr (FSUBR size src)
974 = pprSizeOp SLIT("fsubr") size src
976 = uppPStr SLIT("\tfsubpr")
977 pprInstr (FISUBR size op)
978 = pprSizeAddr SLIT("fisubr") size op
979 pprInstr FTST = uppPStr SLIT("\tftst")
980 pprInstr (FCOMP sz op)
981 = uppBesides [uppPStr SLIT("\tfcomp"), pprSize sz, uppSP, pprOperand sz op]
982 pprInstr FUCOMPP = uppPStr SLIT("\tfucompp")
983 pprInstr FXCH = uppPStr SLIT("\tfxch")
984 pprInstr FNSTSW = uppPStr SLIT("\tfnstsw %ax")
985 pprInstr FNOP = uppPStr SLIT("")
988 Continue with I386-only printing bits and bobs:
990 pprDollImm :: Imm -> Unpretty
992 pprDollImm i = uppBesides [ uppPStr SLIT("$"), pprImm i]
994 pprOperand :: Size -> Operand -> Unpretty
995 pprOperand s (OpReg r) = pprReg s r
996 pprOperand s (OpImm i) = pprDollImm i
997 pprOperand s (OpAddr ea) = pprAddr ea
999 pprSizeOp :: FAST_STRING -> Size -> Operand -> Unpretty
1000 pprSizeOp name size op1
1009 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Unpretty
1010 pprSizeOpOp name size op1 op2
1016 pprOperand size op1,
1021 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> Unpretty
1022 pprSizeOpReg name size op1 reg
1028 pprOperand size op1,
1033 pprSizeAddr :: FAST_STRING -> Size -> Addr -> Unpretty
1034 pprSizeAddr name size op
1043 pprSizeAddrReg :: FAST_STRING -> Size -> Addr -> Reg -> Unpretty
1044 pprSizeAddrReg name size op dst
1055 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> Unpretty
1056 pprOpOp name size op1 op2
1059 uppPStr name, uppSP,
1060 pprOperand size op1,
1065 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> Unpretty
1066 pprSizeOpOpCoerce name size1 size2 op1 op2
1067 = uppBesides [ uppChar '\t', uppPStr name, uppSP,
1068 pprOperand size1 op1,
1070 pprOperand size2 op2
1073 pprCondInstr :: FAST_STRING -> Cond -> Unpretty -> Unpretty
1074 pprCondInstr name cond arg
1075 = uppBesides [ uppChar '\t', uppPStr name, pprCond cond, uppSP, arg]
1077 #endif {-i386_TARGET_ARCH-}
1080 %************************************************************************
1082 \subsubsection{@pprInstr@ for a SPARC}
1084 %************************************************************************
1087 #if sparc_TARGET_ARCH
1089 -- a clumsy hack for now, to handle possible double alignment problems
1091 pprInstr (LD DF addr reg) | maybeToBool off_addr
1105 off_addr = addrOffset addr 4
1106 addr2 = case off_addr of Just x -> x
1108 pprInstr (LD size addr reg)
1110 uppPStr SLIT("\tld"),
1119 -- The same clumsy hack as above
1121 pprInstr (ST DF reg addr) | maybeToBool off_addr
1123 uppPStr SLIT("\tst\t"),
1128 uppPStr SLIT("]\n\tst\t"),
1135 off_addr = addrOffset addr 4
1136 addr2 = case off_addr of Just x -> x
1138 pprInstr (ST size reg addr)
1140 uppPStr SLIT("\tst"),
1149 pprInstr (ADD x cc reg1 ri reg2)
1150 | not x && not cc && riZero ri
1151 = uppBesides [ uppPStr SLIT("\tmov\t"), pprReg reg1, uppComma, pprReg reg2 ]
1153 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1155 pprInstr (SUB x cc reg1 ri reg2)
1156 | not x && cc && reg2 == g0
1157 = uppBesides [ uppPStr SLIT("\tcmp\t"), pprReg reg1, uppComma, pprRI ri ]
1158 | not x && not cc && riZero ri
1159 = uppBesides [ uppPStr SLIT("\tmov\t"), pprReg reg1, uppComma, pprReg reg2 ]
1161 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1163 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1164 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1166 pprInstr (OR b reg1 ri reg2)
1167 | not b && reg1 == g0
1168 = uppBesides [ uppPStr SLIT("\tmov\t"), pprRI ri, uppComma, pprReg reg2 ]
1170 = pprRegRIReg SLIT("or") b reg1 ri reg2
1172 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1174 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1175 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1177 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1178 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1179 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1181 pprInstr (SETHI imm reg)
1183 uppPStr SLIT("\tsethi\t"),
1189 pprInstr NOP = uppPStr SLIT("\tnop")
1191 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1192 pprInstr (FABS DF reg1 reg2)
1193 = uppBeside (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1194 (if (reg1 == reg2) then uppNil
1195 else uppBeside (uppChar '\n')
1196 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1198 pprInstr (FADD size reg1 reg2 reg3)
1199 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1200 pprInstr (FCMP e size reg1 reg2)
1201 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1202 pprInstr (FDIV size reg1 reg2 reg3)
1203 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1205 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1206 pprInstr (FMOV DF reg1 reg2)
1207 = uppBeside (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1208 (if (reg1 == reg2) then uppNil
1209 else uppBeside (uppChar '\n')
1210 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1212 pprInstr (FMUL size reg1 reg2 reg3)
1213 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1215 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1216 pprInstr (FNEG DF reg1 reg2)
1217 = uppBeside (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1218 (if (reg1 == reg2) then uppNil
1219 else uppBeside (uppChar '\n')
1220 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1222 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1223 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1224 pprInstr (FxTOy size1 size2 reg1 reg2)
1226 uppPStr SLIT("\tf"),
1237 pprReg reg1, uppComma, pprReg reg2
1241 pprInstr (BI cond b lab)
1243 uppPStr SLIT("\tb"), pprCond cond,
1244 if b then pp_comma_a else uppNil,
1249 pprInstr (BF cond b lab)
1251 uppPStr SLIT("\tfb"), pprCond cond,
1252 if b then pp_comma_a else uppNil,
1257 pprInstr (JMP addr) = uppBeside (uppPStr SLIT("\tjmp\t")) (pprAddr addr)
1259 pprInstr (CALL imm n _)
1260 = uppBesides [ uppPStr SLIT("\tcall\t"), pprImm imm, uppComma, uppInt n ]
1263 Continue with SPARC-only printing bits and bobs:
1265 pprRI :: RI -> Unpretty
1266 pprRI (RIReg r) = pprReg r
1267 pprRI (RIImm r) = pprImm r
1269 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Unpretty
1270 pprSizeRegReg name size reg1 reg2
1275 F -> uppPStr SLIT("s\t")
1276 DF -> uppPStr SLIT("d\t")),
1282 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> Unpretty
1283 pprSizeRegRegReg name size reg1 reg2 reg3
1288 F -> uppPStr SLIT("s\t")
1289 DF -> uppPStr SLIT("d\t")),
1297 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> Unpretty
1298 pprRegRIReg name b reg1 ri reg2
1302 if b then uppPStr SLIT("cc\t") else uppChar '\t',
1310 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> Unpretty
1311 pprRIReg name b ri reg1
1315 if b then uppPStr SLIT("cc\t") else uppChar '\t',
1321 pp_ld_lbracket = uppPStr (_packCString (A# "\tld\t["#))
1322 pp_rbracket_comma = uppPStr (_packCString (A# "],"#))
1323 pp_comma_lbracket = uppPStr (_packCString (A# ",["#))
1324 pp_comma_a = uppPStr (_packCString (A# ",a"#))
1326 #endif {-sparc_TARGET_ARCH-}