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 )
21 import CStrings ( charToC )
22 import Maybes ( maybeToBool )
23 import Stix ( CodeSegment(..), StixTree(..) )
24 import Char ( isPrint, isDigit )
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 FixedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
50 MappedReg i -> ppr_reg_no IF_ARCH_i386(s,) i
51 other -> text (show other) -- should only happen when debugging
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
94 ppr_reg_no B i = ptext
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) = pprCLabel_asm l
264 pprImm (ImmIndex l i) = pprCLabel_asm l <> char '+' <> int i
265 pprImm (ImmLit s) = s
267 pprImm (ImmLab s) | underscorePrefix = (<>) (char '_') s
270 #if sparc_TARGET_ARCH
272 = hcat [ pp_lo, pprImm i, rparen ]
277 = hcat [ pp_hi, pprImm i, rparen ]
283 %************************************************************************
285 \subsection{@pprAddr@: print an @Addr@}
287 %************************************************************************
290 pprAddr :: MachRegsAddr -> SDoc
292 #if alpha_TARGET_ARCH
293 pprAddr (AddrReg r) = parens (pprReg r)
294 pprAddr (AddrImm i) = pprImm i
295 pprAddr (AddrRegImm r1 i)
296 = (<>) (pprImm i) (parens (pprReg r1))
302 pprAddr (ImmAddr imm off)
303 = let pp_imm = pprImm imm
307 else if (off < 0) then
310 pp_imm <> char '+' <> int off
312 pprAddr (AddrBaseIndex base index displacement)
314 pp_disp = ppr_disp displacement
315 pp_off p = pp_disp <> char '(' <> p <> char ')'
316 pp_reg r = pprReg L r
319 (Nothing, Nothing) -> pp_disp
320 (Just b, Nothing) -> pp_off (pp_reg b)
321 (Nothing, Just (r,i)) -> pp_off (pp_reg r <> comma <> int i)
322 (Just b, Just (r,i)) -> pp_off (pp_reg b <> comma <> pp_reg r
325 ppr_disp (ImmInt 0) = empty
326 ppr_disp imm = pprImm imm
331 #if sparc_TARGET_ARCH
332 pprAddr (AddrRegReg r1 (FixedReg ILIT(0))) = pprReg r1
334 pprAddr (AddrRegReg r1 r2)
335 = hcat [ pprReg r1, char '+', pprReg r2 ]
337 pprAddr (AddrRegImm r1 (ImmInt i))
339 | not (fits13Bits i) = largeOffsetError i
340 | otherwise = hcat [ pprReg r1, pp_sign, int i ]
342 pp_sign = if i > 0 then char '+' else empty
344 pprAddr (AddrRegImm r1 (ImmInteger i))
346 | not (fits13Bits i) = largeOffsetError i
347 | otherwise = hcat [ pprReg r1, pp_sign, integer i ]
349 pp_sign = if i > 0 then char '+' else empty
351 pprAddr (AddrRegImm r1 imm)
352 = hcat [ pprReg r1, char '+', pprImm imm ]
356 %************************************************************************
358 \subsection{@pprInstr@: print an @Instr@}
360 %************************************************************************
363 pprInstr :: Instr -> SDoc
365 --pprInstr (COMMENT s) = empty -- nuke 'em
367 = IF_ARCH_alpha( ((<>) (ptext SLIT("\t# ")) (ptext s))
368 ,IF_ARCH_sparc( ((<>) (ptext SLIT("! ")) (ptext s))
369 ,IF_ARCH_i386( ((<>) (ptext SLIT("# ")) (ptext s))
373 = pprInstr (COMMENT (_PK_ ("\tdelta = " ++ show d)))
375 pprInstr (SEGMENT TextSegment)
376 = IF_ARCH_alpha(ptext SLIT("\t.text\n\t.align 3") {-word boundary-}
377 ,IF_ARCH_sparc(ptext SLIT("\t.text\n\t.align 4") {-word boundary-}
378 ,IF_ARCH_i386((text ".text\n\t.align 4,0x90") {-needs per-OS variation!-}
381 pprInstr (SEGMENT DataSegment)
383 IF_ARCH_alpha(SLIT("\t.data\n\t.align 3")
384 ,IF_ARCH_sparc(SLIT("\t.data\n\t.align 8") {-<8 will break double constants -}
385 ,IF_ARCH_i386(SLIT(".data\n\t.align 4")
388 pprInstr (LABEL clab)
390 pp_lab = pprCLabel_asm clab
393 if not (externallyVisibleCLabel clab) then
397 IF_ARCH_alpha(SLIT("\t.globl\t")
398 ,IF_ARCH_i386(SLIT(".globl ")
399 ,IF_ARCH_sparc(SLIT("\t.global\t")
401 , pp_lab, char '\n'],
406 pprInstr (ASCII False{-no backslash conversion-} str)
407 = hcat [ ptext SLIT("\t.asciz "), char '\"', text str, char '"' ]
409 pprInstr (ASCII True str)
410 = (<>) (text "\t.ascii \"") (asciify str 60)
412 asciify :: String -> Int -> SDoc
414 asciify [] _ = text "\\0\""
415 asciify s n | n <= 0 = (<>) (text "\"\n\t.ascii \"") (asciify s 60)
416 asciify ('\\':cs) n = (<>) (text "\\\\") (asciify cs (n-1))
417 asciify ('\"':cs) n = (<>) (text "\\\"") (asciify cs (n-1))
418 asciify (c:cs) n | isPrint c = (<>) (char c) (asciify cs (n-1))
419 asciify [c] _ = (<>) (text (charToC c)) (text ("\\0\"")){-"-}
420 asciify (c:(cs@(d:_))) n
421 | isDigit d = (<>) (text (charToC c)) (asciify cs 0)
422 | otherwise = (<>) (text (charToC c)) (asciify cs (n-1))
426 = vcat [(<>) (ptext pp_size) (pprImm x) | x <- xs]
429 #if alpha_TARGET_ARCH
430 B -> SLIT("\t.byte\t")
431 BU -> SLIT("\t.byte\t")
432 Q -> SLIT("\t.quad\t")
433 TF -> SLIT("\t.t_floating\t")
436 B -> SLIT("\t.byte\t")
437 L -> SLIT("\t.long\t")
438 F -> SLIT("\t.float\t")
439 DF -> SLIT("\t.double\t")
441 #if sparc_TARGET_ARCH
442 B -> SLIT("\t.byte\t")
443 BU -> SLIT("\t.byte\t")
444 W -> SLIT("\t.word\t")
445 DF -> SLIT("\t.double\t")
451 = vcat (concatMap (ppr_item s) xs)
453 #if alpha_TARGET_ARCH
454 ppr_item = error "ppr_item on Alpha"
456 This needs to be fixed.
457 B -> SLIT("\t.byte\t")
458 BU -> SLIT("\t.byte\t")
459 Q -> SLIT("\t.quad\t")
460 TF -> SLIT("\t.t_floating\t")
463 #if sparc_TARGET_ARCH
464 ppr_item = error "ppr_item on Sparc"
466 This needs to be fixed.
467 B -> SLIT("\t.byte\t")
468 BU -> SLIT("\t.byte\t")
469 W -> SLIT("\t.word\t")
470 DF -> SLIT("\t.double\t")
474 ppr_item B x = [text "\t.byte\t" <> pprImm x]
475 ppr_item L x = [text "\t.long\t" <> pprImm x]
476 ppr_item F (ImmDouble r)
477 = let bs = floatToBytes (fromRational r)
478 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
479 ppr_item DF (ImmDouble r)
480 = let bs = doubleToBytes (fromRational r)
481 in map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
483 floatToBytes :: Float -> [Int]
486 arr <- newFloatArray ((0::Int),3)
487 writeFloatArray arr 0 f
488 i0 <- readCharArray arr 0
489 i1 <- readCharArray arr 1
490 i2 <- readCharArray arr 2
491 i3 <- readCharArray arr 3
492 return (map ord [i0,i1,i2,i3])
495 doubleToBytes :: Double -> [Int]
498 arr <- newDoubleArray ((0::Int),7)
499 writeDoubleArray arr 0 d
500 i0 <- readCharArray arr 0
501 i1 <- readCharArray arr 1
502 i2 <- readCharArray arr 2
503 i3 <- readCharArray arr 3
504 i4 <- readCharArray arr 4
505 i5 <- readCharArray arr 5
506 i6 <- readCharArray arr 6
507 i7 <- readCharArray arr 7
508 return (map ord [i0,i1,i2,i3,i4,i5,i6,i7])
513 -- fall through to rest of (machine-specific) pprInstr...
516 %************************************************************************
518 \subsubsection{@pprInstr@ for an Alpha}
520 %************************************************************************
523 #if alpha_TARGET_ARCH
525 pprInstr (LD size reg addr)
535 pprInstr (LDA reg addr)
537 ptext SLIT("\tlda\t"),
543 pprInstr (LDAH reg addr)
545 ptext SLIT("\tldah\t"),
551 pprInstr (LDGP reg addr)
553 ptext SLIT("\tldgp\t"),
559 pprInstr (LDI size reg imm)
569 pprInstr (ST size reg addr)
581 ptext SLIT("\tclr\t"),
585 pprInstr (ABS size ri reg)
595 pprInstr (NEG size ov ri reg)
599 if ov then ptext SLIT("v\t") else char '\t',
605 pprInstr (ADD size ov reg1 ri reg2)
609 if ov then ptext SLIT("v\t") else char '\t',
617 pprInstr (SADD size scale reg1 ri reg2)
619 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
630 pprInstr (SUB size ov reg1 ri reg2)
634 if ov then ptext SLIT("v\t") else char '\t',
642 pprInstr (SSUB size scale reg1 ri reg2)
644 ptext (case scale of {{-UNUSED:L -> SLIT("\ts4");-} Q -> SLIT("\ts8")}),
655 pprInstr (MUL size ov reg1 ri reg2)
659 if ov then ptext SLIT("v\t") else char '\t',
667 pprInstr (DIV size uns reg1 ri reg2)
671 if uns then ptext SLIT("u\t") else char '\t',
679 pprInstr (REM size uns reg1 ri reg2)
683 if uns then ptext SLIT("u\t") else char '\t',
691 pprInstr (NOT ri reg)
700 pprInstr (AND reg1 ri reg2) = pprRegRIReg SLIT("and") reg1 ri reg2
701 pprInstr (ANDNOT reg1 ri reg2) = pprRegRIReg SLIT("andnot") reg1 ri reg2
702 pprInstr (OR reg1 ri reg2) = pprRegRIReg SLIT("or") reg1 ri reg2
703 pprInstr (ORNOT reg1 ri reg2) = pprRegRIReg SLIT("ornot") reg1 ri reg2
704 pprInstr (XOR reg1 ri reg2) = pprRegRIReg SLIT("xor") reg1 ri reg2
705 pprInstr (XORNOT reg1 ri reg2) = pprRegRIReg SLIT("xornot") reg1 ri reg2
707 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") reg1 ri reg2
708 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") reg1 ri reg2
709 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") reg1 ri reg2
711 pprInstr (ZAP reg1 ri reg2) = pprRegRIReg SLIT("zap") reg1 ri reg2
712 pprInstr (ZAPNOT reg1 ri reg2) = pprRegRIReg SLIT("zapnot") reg1 ri reg2
714 pprInstr (NOP) = ptext SLIT("\tnop")
716 pprInstr (CMP cond reg1 ri reg2)
730 ptext SLIT("\tfclr\t"),
734 pprInstr (FABS reg1 reg2)
736 ptext SLIT("\tfabs\t"),
742 pprInstr (FNEG size reg1 reg2)
752 pprInstr (FADD size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("add") size reg1 reg2 reg3
753 pprInstr (FDIV size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("div") size reg1 reg2 reg3
754 pprInstr (FMUL size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("mul") size reg1 reg2 reg3
755 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("sub") size reg1 reg2 reg3
757 pprInstr (CVTxy size1 size2 reg1 reg2)
761 case size2 of {Q -> ptext SLIT("qc"); _ -> pprSize size2},
768 pprInstr (FCMP size cond reg1 reg2 reg3)
781 pprInstr (FMOV reg1 reg2)
783 ptext SLIT("\tfmov\t"),
789 pprInstr (BI ALWAYS reg lab) = pprInstr (BR lab)
791 pprInstr (BI NEVER reg lab) = empty
793 pprInstr (BI cond reg lab)
803 pprInstr (BF cond reg lab)
814 = (<>) (ptext SLIT("\tbr\t")) (pprImm lab)
816 pprInstr (JMP reg addr hint)
818 ptext SLIT("\tjmp\t"),
827 = (<>) (ptext SLIT("\tbsr\t")) (pprImm imm)
829 pprInstr (JSR reg addr n)
831 ptext SLIT("\tjsr\t"),
837 pprInstr (FUNBEGIN clab)
839 if (externallyVisibleCLabel clab) then
840 hcat [ptext SLIT("\t.globl\t"), pp_lab, char '\n']
843 ptext SLIT("\t.ent "),
852 pp_lab = pprCLabel_asm clab
854 -- NEVER use commas within those string literals, cpp will ruin your day
855 pp_ldgp = hcat [ ptext SLIT(":\n\tldgp $29"), char ',', ptext SLIT("0($27)\n") ]
856 pp_frame = hcat [ ptext SLIT("..ng:\n\t.frame $30"), char ',',
857 ptext SLIT("4240"), char ',',
858 ptext SLIT("$26"), char ',',
859 ptext SLIT("0\n\t.prologue 1") ]
861 pprInstr (FUNEND clab)
862 = (<>) (ptext SLIT("\t.align 4\n\t.end ")) (pprCLabel_asm clab)
865 Continue with Alpha-only printing bits and bobs:
869 pprRI (RIReg r) = pprReg r
870 pprRI (RIImm r) = pprImm r
872 pprRegRIReg :: FAST_STRING -> Reg -> RI -> Reg -> SDoc
874 pprRegRIReg name reg1 ri reg2
886 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
888 pprSizeRegRegReg name size reg1 reg2 reg3
901 #endif {-alpha_TARGET_ARCH-}
904 %************************************************************************
906 \subsubsection{@pprInstr@ for an I386}
908 %************************************************************************
913 pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
917 (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
921 pprInstr (MOV size src dst)
922 = pprSizeOpOp SLIT("mov") size src dst
923 pprInstr (MOVZxL sizes src dst) = pprSizeOpOpCoerce SLIT("movz") sizes L src dst
924 pprInstr (MOVSxL sizes src dst) = pprSizeOpOpCoerce SLIT("movs") sizes L src dst
926 -- here we do some patching, since the physical registers are only set late
927 -- in the code generation.
928 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
930 = pprSizeOpOp SLIT("add") size (OpReg reg2) dst
931 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) (Just (reg2,1)) (ImmInt 0))) dst@(OpReg reg3))
933 = pprSizeOpOp SLIT("add") size (OpReg reg1) dst
934 pprInstr (LEA size (OpAddr (AddrBaseIndex src1@(Just reg1) Nothing displ)) dst@(OpReg reg3))
936 = pprInstr (ADD size (OpImm displ) dst)
937 pprInstr (LEA size src dst) = pprSizeOpOp SLIT("lea") size src dst
939 pprInstr (ADD size (OpImm (ImmInt (-1))) dst)
940 = pprSizeOp SLIT("dec") size dst
941 pprInstr (ADD size (OpImm (ImmInt 1)) dst)
942 = pprSizeOp SLIT("inc") size dst
943 pprInstr (ADD size src dst)
944 = pprSizeOpOp SLIT("add") size src dst
945 pprInstr (SUB size src dst) = pprSizeOpOp SLIT("sub") size src dst
946 pprInstr (IMUL size op1 op2) = pprSizeOpOp SLIT("imul") size op1 op2
947 pprInstr (IDIV size op) = pprSizeOp SLIT("idiv") size op
949 pprInstr (AND size src dst) = pprSizeOpOp SLIT("and") size src dst
950 pprInstr (OR size src dst) = pprSizeOpOp SLIT("or") size src dst
951 pprInstr (XOR size src dst) = pprSizeOpOp SLIT("xor") size src dst
952 pprInstr (NOT size op) = pprSizeOp SLIT("not") size op
953 pprInstr (NEGI size op) = pprSizeOp SLIT("neg") size op
955 pprInstr (SHL size imm dst) = pprSizeImmOp SLIT("shl") size imm dst
956 pprInstr (SAR size imm dst) = pprSizeImmOp SLIT("sar") size imm dst
957 pprInstr (SHR size imm dst) = pprSizeImmOp SLIT("shr") size imm dst
958 pprInstr (BT size imm src) = pprSizeImmOp SLIT("bt") size imm src
960 pprInstr (CMP size src dst) = pprSizeOpOp SLIT("cmp") size src dst
961 pprInstr (TEST size src dst) = pprSizeOpOp SLIT("test") size src dst
962 pprInstr (PUSH size op) = pprSizeOp SLIT("push") size op
963 pprInstr (POP size op) = pprSizeOp SLIT("pop") size op
964 pprInstr PUSHA = ptext SLIT("\tpushal")
965 pprInstr POPA = ptext SLIT("\tpopal")
967 pprInstr (NOP) = ptext SLIT("\tnop")
968 pprInstr (CLTD) = ptext SLIT("\tcltd")
970 pprInstr (SETCC cond op) = pprCondInstr SLIT("set") cond (pprOperand B op)
972 pprInstr (JXX cond lab) = pprCondInstr SLIT("j") cond (pprCLabel_asm lab)
974 pprInstr (JMP (OpImm imm)) = (<>) (ptext SLIT("\tjmp ")) (pprImm imm)
975 pprInstr (JMP op) = (<>) (ptext SLIT("\tjmp *")) (pprOperand L op)
977 = (<>) (ptext SLIT("\tcall ")) (pprImm imm)
980 -- Simulating a flat register set on the x86 FP stack is tricky.
981 -- you have to free %st(7) before pushing anything on the FP reg stack
982 -- so as to preclude the possibility of a FP stack overflow exception.
983 pprInstr g@(GMOV src dst)
987 = pprG g (hcat [gtab, gpush src 0, gsemi, gpop dst 1])
989 -- GLD sz addr dst ==> FFREE %st(7) ; FLDsz addr ; FSTP (dst+1)
990 pprInstr g@(GLD sz addr dst)
991 = pprG g (hcat [gtab, text "ffree %st(7) ; fld", pprSize sz, gsp,
992 pprAddr addr, gsemi, gpop dst 1])
994 -- GST sz src addr ==> FFREE %st(7) ; FLD dst ; FSTPsz addr
995 pprInstr g@(GST sz src addr)
996 = pprG g (hcat [gtab, gpush src 0, gsemi,
997 text "fstp", pprSize sz, gsp, pprAddr addr])
999 pprInstr g@(GLDZ dst)
1000 = pprG g (hcat [gtab, text "ffree %st(7) ; fldz ; ", gpop dst 1])
1001 pprInstr g@(GLD1 dst)
1002 = pprG g (hcat [gtab, text "ffree %st(7) ; fld1 ; ", gpop dst 1])
1004 pprInstr g@(GFTOD src dst)
1006 pprInstr g@(GFTOI src dst)
1009 pprInstr g@(GDTOF src dst)
1011 pprInstr g@(GDTOI src dst)
1014 pprInstr g@(GITOF src dst)
1015 = pprInstr (GITOD src dst)
1016 pprInstr g@(GITOD src dst)
1017 = pprG g (hcat [gtab, text "pushl ", pprReg L src,
1018 text " ; ffree %st(7); fildl (%esp) ; ",
1019 gpop dst 1, text " ; addl $4,%esp"])
1021 pprInstr g@(GCMP sz src1 src2)
1022 = pprG g (hcat [gtab, text "pushl %eax ; ",
1023 gpush src2 0, gsemi, gpush src1 1]
1025 hcat [gtab, text "fcompp ; fstsw %ax ; sahf ; popl %eax"])
1027 pprInstr g@(GABS sz src dst)
1028 = pprG g (hcat [gtab, gpush src 0, text " ; fabs ; ", gpop dst 1])
1029 pprInstr g@(GNEG sz src dst)
1030 = pprG g (hcat [gtab, gpush src 0, text " ; fchs ; ", gpop dst 1])
1032 pprInstr g@(GSQRT sz src dst)
1033 = pprG g (hcat [gtab, gpush src 0, text " ; fsqrt"] $$
1034 hcat [gtab, gcoerceto sz, gpop dst 1])
1035 pprInstr g@(GSIN sz src dst)
1036 = pprG g (hcat [gtab, gpush src 0, text " ; fsin"] $$
1037 hcat [gtab, gcoerceto sz, gpop dst 1])
1038 pprInstr g@(GCOS sz src dst)
1039 = pprG g (hcat [gtab, gpush src 0, text " ; fcos"] $$
1040 hcat [gtab, gcoerceto sz, gpop dst 1])
1041 pprInstr g@(GTAN sz src dst)
1042 = pprG g (hcat [gtab, text "ffree %st(6) ; ",
1043 gpush src 0, text " ; fptan ; ",
1044 text " fstp %st(0)"] $$
1045 hcat [gtab, gcoerceto sz, gpop dst 1])
1047 pprInstr g@(GADD sz src1 src2 dst)
1048 = pprG g (hcat [gtab, gpush src1 0,
1049 text " ; fadd ", greg src2 1, text ",%st(0)",
1051 pprInstr g@(GSUB sz src1 src2 dst)
1052 = pprG g (hcat [gtab, gpush src1 0,
1053 text " ; fsub ", greg src2 1, text ",%st(0)",
1055 pprInstr g@(GMUL sz src1 src2 dst)
1056 = pprG g (hcat [gtab, gpush src1 0,
1057 text " ; fmul ", greg src2 1, text ",%st(0)",
1059 pprInstr g@(GDIV sz src1 src2 dst)
1060 = pprG g (hcat [gtab, gpush src1 0,
1061 text " ; fdiv ", greg src2 1, text ",%st(0)",
1065 = vcat [ ptext SLIT("\tffree %st(0) ;ffree %st(1) ;ffree %st(2) ;ffree %st(3)"),
1066 ptext SLIT("\tffree %st(4) ;ffree %st(5) ;ffree %st(6) ;ffree %st(7)")
1069 --------------------------
1071 -- coerce %st(0) to the specified size
1072 gcoerceto DF = empty
1073 gcoerceto F = text "subl $4,%esp ; fstps (%esp) ; flds (%esp) ; addl $4,%esp ; "
1076 = hcat [text "ffree %st(7) ; fld ", greg reg offset]
1078 = hcat [text "fstp ", greg reg offset]
1080 bogus = text "\tbogus"
1081 greg reg offset = text "%st(" <> int (gregno reg - 8+offset) <> char ')'
1085 gregno (FixedReg i) = I# i
1086 gregno (MappedReg i) = I# i
1087 gregno other = pprPanic "gregno" (text (show other))
1089 pprG :: Instr -> SDoc -> SDoc
1091 = (char '#' <> pprGInstr fake) $$ actual
1093 pprGInstr (GMOV src dst) = pprSizeRegReg SLIT("gmov") DF src dst
1094 pprGInstr (GLD sz src dst) = pprSizeAddrReg SLIT("gld") sz src dst
1095 pprGInstr (GST sz src dst) = pprSizeRegAddr SLIT("gst") sz src dst
1097 pprGInstr (GLDZ dst) = pprSizeReg SLIT("gldz") DF dst
1098 pprGInstr (GLD1 dst) = pprSizeReg SLIT("gld1") DF dst
1100 pprGInstr (GFTOD src dst) = pprSizeSizeRegReg SLIT("gftod") F DF src dst
1101 pprGInstr (GFTOI src dst) = pprSizeSizeRegReg SLIT("gftoi") F L src dst
1103 pprGInstr (GDTOF src dst) = pprSizeSizeRegReg SLIT("gdtof") DF F src dst
1104 pprGInstr (GDTOI src dst) = pprSizeSizeRegReg SLIT("gdtoi") DF L src dst
1106 pprGInstr (GITOF src dst) = pprSizeSizeRegReg SLIT("gitof") L F src dst
1107 pprGInstr (GITOD src dst) = pprSizeSizeRegReg SLIT("gitod") L DF src dst
1109 pprGInstr (GCMP sz src dst) = pprSizeRegReg SLIT("gcmp") sz src dst
1110 pprGInstr (GABS sz src dst) = pprSizeRegReg SLIT("gabs") sz src dst
1111 pprGInstr (GNEG sz src dst) = pprSizeRegReg SLIT("gneg") sz src dst
1112 pprGInstr (GSQRT sz src dst) = pprSizeRegReg SLIT("gsqrt") sz src dst
1113 pprGInstr (GSIN sz src dst) = pprSizeRegReg SLIT("gsin") sz src dst
1114 pprGInstr (GCOS sz src dst) = pprSizeRegReg SLIT("gcos") sz src dst
1115 pprGInstr (GTAN sz src dst) = pprSizeRegReg SLIT("gtan") sz src dst
1117 pprGInstr (GADD sz src1 src2 dst) = pprSizeRegRegReg SLIT("gadd") sz src1 src2 dst
1118 pprGInstr (GSUB sz src1 src2 dst) = pprSizeRegRegReg SLIT("gsub") sz src1 src2 dst
1119 pprGInstr (GMUL sz src1 src2 dst) = pprSizeRegRegReg SLIT("gmul") sz src1 src2 dst
1120 pprGInstr (GDIV sz src1 src2 dst) = pprSizeRegRegReg SLIT("gdiv") sz src1 src2 dst
1123 Continue with I386-only printing bits and bobs:
1125 pprDollImm :: Imm -> SDoc
1127 pprDollImm i = ptext SLIT("$") <> pprImm i
1129 pprOperand :: Size -> Operand -> SDoc
1130 pprOperand s (OpReg r) = pprReg s r
1131 pprOperand s (OpImm i) = pprDollImm i
1132 pprOperand s (OpAddr ea) = pprAddr ea
1134 pprSizeImmOp :: FAST_STRING -> Size -> Imm -> Operand -> SDoc
1135 pprSizeImmOp name size imm op1
1147 pprSizeOp :: FAST_STRING -> Size -> Operand -> SDoc
1148 pprSizeOp name size op1
1157 pprSizeOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1158 pprSizeOpOp name size op1 op2
1164 pprOperand size op1,
1169 pprSizeByteOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1170 pprSizeByteOpOp name size op1 op2
1181 pprSizeOpReg :: FAST_STRING -> Size -> Operand -> Reg -> SDoc
1182 pprSizeOpReg name size op1 reg
1188 pprOperand size op1,
1193 pprSizeReg :: FAST_STRING -> Size -> Reg -> SDoc
1194 pprSizeReg name size reg1
1203 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1204 pprSizeRegReg name size reg1 reg2
1215 pprSizeSizeRegReg :: FAST_STRING -> Size -> Size -> Reg -> Reg -> SDoc
1216 pprSizeSizeRegReg name size1 size2 reg1 reg2
1228 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1229 pprSizeRegRegReg name size reg1 reg2 reg3
1242 pprSizeAddr :: FAST_STRING -> Size -> MachRegsAddr -> SDoc
1243 pprSizeAddr name size op
1252 pprSizeAddrReg :: FAST_STRING -> Size -> MachRegsAddr -> Reg -> SDoc
1253 pprSizeAddrReg name size op dst
1264 pprSizeRegAddr :: FAST_STRING -> Size -> Reg -> MachRegsAddr -> SDoc
1265 pprSizeRegAddr name size src op
1276 pprOpOp :: FAST_STRING -> Size -> Operand -> Operand -> SDoc
1277 pprOpOp name size op1 op2
1281 pprOperand size op1,
1286 pprSizeOpOpCoerce :: FAST_STRING -> Size -> Size -> Operand -> Operand -> SDoc
1287 pprSizeOpOpCoerce name size1 size2 op1 op2
1288 = hcat [ char '\t', ptext name, pprSize size1, pprSize size2, space,
1289 pprOperand size1 op1,
1291 pprOperand size2 op2
1294 pprCondInstr :: FAST_STRING -> Cond -> SDoc -> SDoc
1295 pprCondInstr name cond arg
1296 = hcat [ char '\t', ptext name, pprCond cond, space, arg]
1298 #endif {-i386_TARGET_ARCH-}
1301 %************************************************************************
1303 \subsubsection{@pprInstr@ for a SPARC}
1305 %************************************************************************
1308 #if sparc_TARGET_ARCH
1310 -- a clumsy hack for now, to handle possible double alignment problems
1312 -- even clumsier, to allow for RegReg regs that show when doing indexed
1313 -- reads (bytearrays).
1315 pprInstr (LD DF (AddrRegReg g1 g2) reg)
1317 ptext SLIT("\tadd\t"), pprReg g1,comma,pprReg g2,comma,pprReg g1, char '\n',
1318 pp_ld_lbracket, pprReg g1, pp_rbracket_comma, pprReg reg, char '\n',
1319 pp_ld_lbracket, pprReg g1, ptext SLIT("+4]"), comma, pprReg (fPair reg)
1322 pprInstr (LD DF addr reg) | maybeToBool off_addr
1336 off_addr = addrOffset addr 4
1337 addr2 = case off_addr of Just x -> x
1339 pprInstr (LD size addr reg)
1350 -- The same clumsy hack as above
1352 pprInstr (ST DF reg (AddrRegReg g1 g2))
1354 ptext SLIT("\tadd\t"),
1355 pprReg g1,comma,pprReg g2,comma,pprReg g1, char '\n',
1356 ptext SLIT("\tst\t"),
1357 pprReg reg, pp_comma_lbracket, pprReg g1,
1358 ptext SLIT("]\n\tst\t"),
1359 pprReg (fPair reg), pp_comma_lbracket, pprReg g1, ptext SLIT("+4]")
1362 pprInstr (ST DF reg addr) | maybeToBool off_addr
1364 ptext SLIT("\tst\t"),
1365 pprReg reg, pp_comma_lbracket, pprAddr addr,
1367 ptext SLIT("]\n\tst\t"),
1368 pprReg (fPair reg), pp_comma_lbracket,
1369 pprAddr addr2, rbrack
1372 off_addr = addrOffset addr 4
1373 addr2 = case off_addr of Just x -> x
1375 -- no distinction is made between signed and unsigned bytes on stores for the
1376 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
1377 -- so we call a special-purpose pprSize for ST..
1379 pprInstr (ST size reg addr)
1390 pprInstr (ADD x cc reg1 ri reg2)
1391 | not x && not cc && riZero ri
1392 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1394 = pprRegRIReg (if x then SLIT("addx") else SLIT("add")) cc reg1 ri reg2
1396 pprInstr (SUB x cc reg1 ri reg2)
1397 | not x && cc && reg2 == g0
1398 = hcat [ ptext SLIT("\tcmp\t"), pprReg reg1, comma, pprRI ri ]
1399 | not x && not cc && riZero ri
1400 = hcat [ ptext SLIT("\tmov\t"), pprReg reg1, comma, pprReg reg2 ]
1402 = pprRegRIReg (if x then SLIT("subx") else SLIT("sub")) cc reg1 ri reg2
1404 pprInstr (AND b reg1 ri reg2) = pprRegRIReg SLIT("and") b reg1 ri reg2
1405 pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg SLIT("andn") b reg1 ri reg2
1407 pprInstr (OR b reg1 ri reg2)
1408 | not b && reg1 == g0
1409 = hcat [ ptext SLIT("\tmov\t"), pprRI ri, comma, pprReg reg2 ]
1411 = pprRegRIReg SLIT("or") b reg1 ri reg2
1413 pprInstr (ORN b reg1 ri reg2) = pprRegRIReg SLIT("orn") b reg1 ri reg2
1415 pprInstr (XOR b reg1 ri reg2) = pprRegRIReg SLIT("xor") b reg1 ri reg2
1416 pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg SLIT("xnor") b reg1 ri reg2
1418 pprInstr (SLL reg1 ri reg2) = pprRegRIReg SLIT("sll") False reg1 ri reg2
1419 pprInstr (SRL reg1 ri reg2) = pprRegRIReg SLIT("srl") False reg1 ri reg2
1420 pprInstr (SRA reg1 ri reg2) = pprRegRIReg SLIT("sra") False reg1 ri reg2
1422 pprInstr (SETHI imm reg)
1424 ptext SLIT("\tsethi\t"),
1430 pprInstr NOP = ptext SLIT("\tnop")
1432 pprInstr (FABS F reg1 reg2) = pprSizeRegReg SLIT("fabs") F reg1 reg2
1433 pprInstr (FABS DF reg1 reg2)
1434 = (<>) (pprSizeRegReg SLIT("fabs") F reg1 reg2)
1435 (if (reg1 == reg2) then empty
1436 else (<>) (char '\n')
1437 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1439 pprInstr (FADD size reg1 reg2 reg3)
1440 = pprSizeRegRegReg SLIT("fadd") size reg1 reg2 reg3
1441 pprInstr (FCMP e size reg1 reg2)
1442 = pprSizeRegReg (if e then SLIT("fcmpe") else SLIT("fcmp")) size reg1 reg2
1443 pprInstr (FDIV size reg1 reg2 reg3)
1444 = pprSizeRegRegReg SLIT("fdiv") size reg1 reg2 reg3
1446 pprInstr (FMOV F reg1 reg2) = pprSizeRegReg SLIT("fmov") F reg1 reg2
1447 pprInstr (FMOV DF reg1 reg2)
1448 = (<>) (pprSizeRegReg SLIT("fmov") F reg1 reg2)
1449 (if (reg1 == reg2) then empty
1450 else (<>) (char '\n')
1451 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1453 pprInstr (FMUL size reg1 reg2 reg3)
1454 = pprSizeRegRegReg SLIT("fmul") size reg1 reg2 reg3
1456 pprInstr (FNEG F reg1 reg2) = pprSizeRegReg SLIT("fneg") F reg1 reg2
1457 pprInstr (FNEG DF reg1 reg2)
1458 = (<>) (pprSizeRegReg SLIT("fneg") F reg1 reg2)
1459 (if (reg1 == reg2) then empty
1460 else (<>) (char '\n')
1461 (pprSizeRegReg SLIT("fmov") F (fPair reg1) (fPair reg2)))
1463 pprInstr (FSQRT size reg1 reg2) = pprSizeRegReg SLIT("fsqrt") size reg1 reg2
1464 pprInstr (FSUB size reg1 reg2 reg3) = pprSizeRegRegReg SLIT("fsub") size reg1 reg2 reg3
1465 pprInstr (FxTOy size1 size2 reg1 reg2)
1478 pprReg reg1, comma, pprReg reg2
1482 pprInstr (BI cond b lab)
1484 ptext SLIT("\tb"), pprCond cond,
1485 if b then pp_comma_a else empty,
1490 pprInstr (BF cond b lab)
1492 ptext SLIT("\tfb"), pprCond cond,
1493 if b then pp_comma_a else empty,
1498 pprInstr (JMP addr) = (<>) (ptext SLIT("\tjmp\t")) (pprAddr addr)
1500 pprInstr (CALL imm n _)
1501 = hcat [ ptext SLIT("\tcall\t"), pprImm imm, comma, int n ]
1504 Continue with SPARC-only printing bits and bobs:
1507 pprRI (RIReg r) = pprReg r
1508 pprRI (RIImm r) = pprImm r
1510 pprSizeRegReg :: FAST_STRING -> Size -> Reg -> Reg -> SDoc
1511 pprSizeRegReg name size reg1 reg2
1516 F -> ptext SLIT("s\t")
1517 DF -> ptext SLIT("d\t")),
1523 pprSizeRegRegReg :: FAST_STRING -> Size -> Reg -> Reg -> Reg -> SDoc
1524 pprSizeRegRegReg name size reg1 reg2 reg3
1529 F -> ptext SLIT("s\t")
1530 DF -> ptext SLIT("d\t")),
1538 pprRegRIReg :: FAST_STRING -> Bool -> Reg -> RI -> Reg -> SDoc
1539 pprRegRIReg name b reg1 ri reg2
1543 if b then ptext SLIT("cc\t") else char '\t',
1551 pprRIReg :: FAST_STRING -> Bool -> RI -> Reg -> SDoc
1552 pprRIReg name b ri reg1
1556 if b then ptext SLIT("cc\t") else char '\t',
1562 pp_ld_lbracket = ptext SLIT("\tld\t[")
1563 pp_rbracket_comma = text "],"
1564 pp_comma_lbracket = text ",["
1565 pp_comma_a = text ",a"
1567 #endif {-sparc_TARGET_ARCH-}