never executed always true always false
1 {-# LANGUAGE LambdaCase #-}
2 {-# LANGUAGE MultiParamTypeClasses #-}
3 {-# LANGUAGE FlexibleInstances #-}
4
5
6 -----------------------------------------------------------------------------
7 --
8 -- Pretty-printing assembly language
9 --
10 -- (c) The University of Glasgow 1993-2005
11 --
12 -----------------------------------------------------------------------------
13
14 {-# OPTIONS_GHC -fno-warn-orphans #-}
15 module GHC.CmmToAsm.SPARC.Ppr (
16 pprNatCmmDecl,
17 pprBasicBlock,
18 pprData,
19 pprInstr,
20 pprFormat,
21 pprImm,
22 pprDataItem
23 )
24
25 where
26
27 import GHC.Prelude
28
29 import Data.Word
30 import qualified Data.Array.Unsafe as U ( castSTUArray )
31 import Data.Array.ST
32
33 import Control.Monad.ST
34
35 import GHC.CmmToAsm.SPARC.Regs
36 import GHC.CmmToAsm.SPARC.Instr
37 import GHC.CmmToAsm.SPARC.Cond
38 import GHC.CmmToAsm.SPARC.Imm
39 import GHC.CmmToAsm.SPARC.AddrMode
40 import GHC.CmmToAsm.SPARC.Base
41 import GHC.Platform.Reg
42 import GHC.CmmToAsm.Format
43 import GHC.CmmToAsm.Ppr
44 import GHC.CmmToAsm.Config
45 import GHC.CmmToAsm.Types
46 import GHC.CmmToAsm.Utils
47
48 import GHC.Cmm hiding (topInfoTable)
49 import GHC.Cmm.Ppr() -- For Outputable instances
50 import GHC.Cmm.BlockId
51 import GHC.Cmm.CLabel
52 import GHC.Cmm.Dataflow.Label
53 import GHC.Cmm.Dataflow.Collections
54
55 import GHC.Types.Unique ( pprUniqueAlways )
56 import GHC.Utils.Outputable
57 import GHC.Utils.Panic
58 import GHC.Platform
59
60 -- -----------------------------------------------------------------------------
61 -- Printing this stuff out
62
63 pprNatCmmDecl :: NCGConfig -> NatCmmDecl RawCmmStatics Instr -> SDoc
64 pprNatCmmDecl config (CmmData section dats) =
65 pprSectionAlign config section
66 $$ pprDatas (ncgPlatform config) dats
67
68 pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) =
69 let platform = ncgPlatform config in
70 case topInfoTable proc of
71 Nothing ->
72 -- special case for code without info table:
73 pprSectionAlign config (Section Text lbl) $$
74 pprLabel platform lbl $$ -- blocks guaranteed not null, so label needed
75 vcat (map (pprBasicBlock platform top_info) blocks)
76
77 Just (CmmStaticsRaw info_lbl _) ->
78 (if platformHasSubsectionsViaSymbols platform
79 then pprSectionAlign config dspSection $$
80 pdoc platform (mkDeadStripPreventer info_lbl) <> char ':'
81 else empty) $$
82 vcat (map (pprBasicBlock platform top_info) blocks) $$
83 -- above: Even the first block gets a label, because with branch-chain
84 -- elimination, it might be the target of a goto.
85 (if platformHasSubsectionsViaSymbols platform
86 then
87 -- See Note [Subsections Via Symbols] in X86/Ppr.hs
88 text "\t.long "
89 <+> pdoc platform info_lbl
90 <+> char '-'
91 <+> pdoc platform (mkDeadStripPreventer info_lbl)
92 else empty)
93
94 dspSection :: Section
95 dspSection = Section Text $
96 panic "subsections-via-symbols doesn't combine with split-sections"
97
98 pprBasicBlock :: Platform -> LabelMap RawCmmStatics -> NatBasicBlock Instr -> SDoc
99 pprBasicBlock platform info_env (BasicBlock blockid instrs)
100 = maybe_infotable $$
101 pprLabel platform (blockLbl blockid) $$
102 vcat (map (pprInstr platform) instrs)
103 where
104 maybe_infotable = case mapLookup blockid info_env of
105 Nothing -> empty
106 Just (CmmStaticsRaw info_lbl info) ->
107 pprAlignForSection Text $$
108 vcat (map (pprData platform) info) $$
109 pprLabel platform info_lbl
110
111
112 pprDatas :: Platform -> RawCmmStatics -> SDoc
113 -- See note [emit-time elimination of static indirections] in "GHC.Cmm.CLabel".
114 pprDatas platform (CmmStaticsRaw alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _])
115 | lbl == mkIndStaticInfoLabel
116 , let labelInd (CmmLabelOff l _) = Just l
117 labelInd (CmmLabel l) = Just l
118 labelInd _ = Nothing
119 , Just ind' <- labelInd ind
120 , alias `mayRedirectTo` ind'
121 = pprGloblDecl platform alias
122 $$ text ".equiv" <+> pdoc platform alias <> comma <> pdoc platform (CmmLabel ind')
123 pprDatas platform (CmmStaticsRaw lbl dats) = vcat (pprLabel platform lbl : map (pprData platform) dats)
124
125 pprData :: Platform -> CmmStatic -> SDoc
126 pprData platform d = case d of
127 CmmString str -> pprString str
128 CmmFileEmbed path -> pprFileEmbed path
129 CmmUninitialised bytes -> text ".skip " <> int bytes
130 CmmStaticLit lit -> pprDataItem platform lit
131
132 pprGloblDecl :: Platform -> CLabel -> SDoc
133 pprGloblDecl platform lbl
134 | not (externallyVisibleCLabel lbl) = empty
135 | otherwise = text ".global " <> pdoc platform lbl
136
137 pprTypeAndSizeDecl :: Platform -> CLabel -> SDoc
138 pprTypeAndSizeDecl platform lbl
139 = if platformOS platform == OSLinux && externallyVisibleCLabel lbl
140 then text ".type " <> pdoc platform lbl <> text ", @object"
141 else empty
142
143 pprLabel :: Platform -> CLabel -> SDoc
144 pprLabel platform lbl =
145 pprGloblDecl platform lbl
146 $$ pprTypeAndSizeDecl platform lbl
147 $$ (pdoc platform lbl <> char ':')
148
149 -- -----------------------------------------------------------------------------
150 -- pprInstr: print an 'Instr'
151
152 instance OutputableP Platform Instr where
153 pdoc = pprInstr
154
155
156 -- | Pretty print a register.
157 pprReg :: Reg -> SDoc
158 pprReg reg
159 = case reg of
160 RegVirtual vr
161 -> case vr of
162 VirtualRegI u -> text "%vI_" <> pprUniqueAlways u
163 VirtualRegHi u -> text "%vHi_" <> pprUniqueAlways u
164 VirtualRegF u -> text "%vF_" <> pprUniqueAlways u
165 VirtualRegD u -> text "%vD_" <> pprUniqueAlways u
166
167
168 RegReal rr
169 -> case rr of
170 RealRegSingle r1
171 -> pprReg_ofRegNo r1
172
173 RealRegPair r1 r2
174 -> text "(" <> pprReg_ofRegNo r1
175 <> vbar <> pprReg_ofRegNo r2
176 <> text ")"
177
178
179
180 -- | Pretty print a register name, based on this register number.
181 -- The definition has been unfolded so we get a jump-table in the
182 -- object code. This function is called quite a lot when emitting
183 -- the asm file..
184 --
185 pprReg_ofRegNo :: Int -> SDoc
186 pprReg_ofRegNo i
187 = case i of {
188 0 -> text "%g0"; 1 -> text "%g1";
189 2 -> text "%g2"; 3 -> text "%g3";
190 4 -> text "%g4"; 5 -> text "%g5";
191 6 -> text "%g6"; 7 -> text "%g7";
192 8 -> text "%o0"; 9 -> text "%o1";
193 10 -> text "%o2"; 11 -> text "%o3";
194 12 -> text "%o4"; 13 -> text "%o5";
195 14 -> text "%o6"; 15 -> text "%o7";
196 16 -> text "%l0"; 17 -> text "%l1";
197 18 -> text "%l2"; 19 -> text "%l3";
198 20 -> text "%l4"; 21 -> text "%l5";
199 22 -> text "%l6"; 23 -> text "%l7";
200 24 -> text "%i0"; 25 -> text "%i1";
201 26 -> text "%i2"; 27 -> text "%i3";
202 28 -> text "%i4"; 29 -> text "%i5";
203 30 -> text "%i6"; 31 -> text "%i7";
204 32 -> text "%f0"; 33 -> text "%f1";
205 34 -> text "%f2"; 35 -> text "%f3";
206 36 -> text "%f4"; 37 -> text "%f5";
207 38 -> text "%f6"; 39 -> text "%f7";
208 40 -> text "%f8"; 41 -> text "%f9";
209 42 -> text "%f10"; 43 -> text "%f11";
210 44 -> text "%f12"; 45 -> text "%f13";
211 46 -> text "%f14"; 47 -> text "%f15";
212 48 -> text "%f16"; 49 -> text "%f17";
213 50 -> text "%f18"; 51 -> text "%f19";
214 52 -> text "%f20"; 53 -> text "%f21";
215 54 -> text "%f22"; 55 -> text "%f23";
216 56 -> text "%f24"; 57 -> text "%f25";
217 58 -> text "%f26"; 59 -> text "%f27";
218 60 -> text "%f28"; 61 -> text "%f29";
219 62 -> text "%f30"; 63 -> text "%f31";
220 _ -> text "very naughty sparc register" }
221
222
223 -- | Pretty print a format for an instruction suffix.
224 pprFormat :: Format -> SDoc
225 pprFormat x
226 = case x of
227 II8 -> text "ub"
228 II16 -> text "uh"
229 II32 -> text ""
230 II64 -> text "d"
231 FF32 -> text ""
232 FF64 -> text "d"
233
234
235 -- | Pretty print a format for an instruction suffix.
236 -- eg LD is 32bit on sparc, but LDD is 64 bit.
237 pprStFormat :: Format -> SDoc
238 pprStFormat x
239 = case x of
240 II8 -> text "b"
241 II16 -> text "h"
242 II32 -> text ""
243 II64 -> text "x"
244 FF32 -> text ""
245 FF64 -> text "d"
246
247
248
249 -- | Pretty print a condition code.
250 pprCond :: Cond -> SDoc
251 pprCond c
252 = case c of
253 ALWAYS -> text ""
254 NEVER -> text "n"
255 GEU -> text "geu"
256 LU -> text "lu"
257 EQQ -> text "e"
258 GTT -> text "g"
259 GE -> text "ge"
260 GU -> text "gu"
261 LTT -> text "l"
262 LE -> text "le"
263 LEU -> text "leu"
264 NE -> text "ne"
265 NEG -> text "neg"
266 POS -> text "pos"
267 VC -> text "vc"
268 VS -> text "vs"
269
270
271 -- | Pretty print an address mode.
272 pprAddr :: Platform -> AddrMode -> SDoc
273 pprAddr platform am
274 = case am of
275 AddrRegReg r1 (RegReal (RealRegSingle 0))
276 -> pprReg r1
277
278 AddrRegReg r1 r2
279 -> hcat [ pprReg r1, char '+', pprReg r2 ]
280
281 AddrRegImm r1 (ImmInt i)
282 | i == 0 -> pprReg r1
283 | not (fits13Bits i) -> largeOffsetError i
284 | otherwise -> hcat [ pprReg r1, pp_sign, int i ]
285 where
286 pp_sign = if i > 0 then char '+' else empty
287
288 AddrRegImm r1 (ImmInteger i)
289 | i == 0 -> pprReg r1
290 | not (fits13Bits i) -> largeOffsetError i
291 | otherwise -> hcat [ pprReg r1, pp_sign, integer i ]
292 where
293 pp_sign = if i > 0 then char '+' else empty
294
295 AddrRegImm r1 imm
296 -> hcat [ pprReg r1, char '+', pprImm platform imm ]
297
298
299 -- | Pretty print an immediate value.
300 pprImm :: Platform -> Imm -> SDoc
301 pprImm platform imm
302 = case imm of
303 ImmInt i -> int i
304 ImmInteger i -> integer i
305 ImmCLbl l -> pdoc platform l
306 ImmIndex l i -> pdoc platform l <> char '+' <> int i
307 ImmLit s -> s
308
309 ImmConstantSum a b
310 -> pprImm platform a <> char '+' <> pprImm platform b
311
312 ImmConstantDiff a b
313 -> pprImm platform a <> char '-' <> lparen <> pprImm platform b <> rparen
314
315 LO i
316 -> hcat [ text "%lo(", pprImm platform i, rparen ]
317
318 HI i
319 -> hcat [ text "%hi(", pprImm platform i, rparen ]
320
321 -- these should have been converted to bytes and placed
322 -- in the data section.
323 ImmFloat _ -> text "naughty float immediate"
324 ImmDouble _ -> text "naughty double immediate"
325
326
327 -- | Pretty print a section \/ segment header.
328 -- On SPARC all the data sections must be at least 8 byte aligned
329 -- incase we store doubles in them.
330 --
331 pprSectionAlign :: NCGConfig -> Section -> SDoc
332 pprSectionAlign config sec@(Section seg _) =
333 pprSectionHeader config sec $$
334 pprAlignForSection seg
335
336 -- | Print appropriate alignment for the given section type.
337 pprAlignForSection :: SectionType -> SDoc
338 pprAlignForSection seg =
339 case seg of
340 Text -> text ".align 4"
341 Data -> text ".align 8"
342 ReadOnlyData -> text ".align 8"
343 RelocatableReadOnlyData -> text ".align 8"
344 UninitialisedData -> text ".align 8"
345 ReadOnlyData16 -> text ".align 16"
346 -- TODO: This is copied from the ReadOnlyData case, but it can likely be
347 -- made more efficient.
348 CString -> text ".align 8"
349 OtherSection _ -> panic "PprMach.pprSectionHeader: unknown section"
350
351 -- | Pretty print a data item.
352 pprDataItem :: Platform -> CmmLit -> SDoc
353 pprDataItem platform lit
354 = vcat (ppr_item (cmmTypeFormat $ cmmLitType platform lit) lit)
355 where
356 imm = litToImm lit
357
358 ppr_item II8 _ = [text "\t.byte\t" <> pprImm platform imm]
359 ppr_item II32 _ = [text "\t.long\t" <> pprImm platform imm]
360
361 ppr_item FF32 (CmmFloat r _)
362 = let bs = floatToBytes (fromRational r)
363 in map (\b -> text "\t.byte\t" <> pprImm platform (ImmInt b)) bs
364
365 ppr_item FF64 (CmmFloat r _)
366 = let bs = doubleToBytes (fromRational r)
367 in map (\b -> text "\t.byte\t" <> pprImm platform (ImmInt b)) bs
368
369 ppr_item II16 _ = [text "\t.short\t" <> pprImm platform imm]
370 ppr_item II64 _ = [text "\t.quad\t" <> pprImm platform imm]
371 ppr_item _ _ = panic "SPARC.Ppr.pprDataItem: no match"
372
373 floatToBytes :: Float -> [Int]
374 floatToBytes f
375 = runST (do
376 arr <- newArray_ ((0::Int),3)
377 writeArray arr 0 f
378 arr <- castFloatToWord8Array arr
379 i0 <- readArray arr 0
380 i1 <- readArray arr 1
381 i2 <- readArray arr 2
382 i3 <- readArray arr 3
383 return (map fromIntegral [i0,i1,i2,i3])
384 )
385
386 castFloatToWord8Array :: STUArray s Int Float -> ST s (STUArray s Int Word8)
387 castFloatToWord8Array = U.castSTUArray
388
389
390 asmComment :: SDoc -> SDoc
391 asmComment c = whenPprDebug $ text "#" <+> c
392
393
394 -- | Pretty print an instruction.
395 pprInstr :: Platform -> Instr -> SDoc
396 pprInstr platform = \case
397 COMMENT s -> asmComment s
398 DELTA d -> asmComment $ text ("\tdelta = " ++ show d)
399
400 -- Newblocks and LData should have been slurped out before producing the .s file.
401 NEWBLOCK _ -> panic "X86.Ppr.pprInstr: NEWBLOCK"
402 LDATA _ _ -> panic "PprMach.pprInstr: LDATA"
403
404 -- 64 bit FP loads are expanded into individual instructions in CodeGen.Expand
405 LD FF64 _ reg
406 | RegReal (RealRegSingle{}) <- reg
407 -> panic "SPARC.Ppr: not emitting potentially misaligned LD FF64 instr"
408
409 LD format addr reg
410 -> hcat [
411 text "\tld",
412 pprFormat format,
413 char '\t',
414 lbrack,
415 pprAddr platform addr,
416 pp_rbracket_comma,
417 pprReg reg
418 ]
419
420 -- 64 bit FP stores are expanded into individual instructions in CodeGen.Expand
421 ST FF64 reg _
422 | RegReal (RealRegSingle{}) <- reg
423 -> panic "SPARC.Ppr: not emitting potentially misaligned ST FF64 instr"
424
425 -- no distinction is made between signed and unsigned bytes on stores for the
426 -- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
427 -- so we call a special-purpose pprFormat for ST..
428 ST format reg addr
429 -> hcat [
430 text "\tst",
431 pprStFormat format,
432 char '\t',
433 pprReg reg,
434 pp_comma_lbracket,
435 pprAddr platform addr,
436 rbrack
437 ]
438
439
440 ADD x cc reg1 ri reg2
441 | not x && not cc && riZero ri
442 -> hcat [ text "\tmov\t", pprReg reg1, comma, pprReg reg2 ]
443
444 | otherwise
445 -> pprRegRIReg platform (if x then text "addx" else text "add") cc reg1 ri reg2
446
447
448 SUB x cc reg1 ri reg2
449 | not x && cc && reg2 == g0
450 -> hcat [ text "\tcmp\t", pprReg reg1, comma, pprRI platform ri ]
451
452 | not x && not cc && riZero ri
453 -> hcat [ text "\tmov\t", pprReg reg1, comma, pprReg reg2 ]
454
455 | otherwise
456 -> pprRegRIReg platform (if x then text "subx" else text "sub") cc reg1 ri reg2
457
458 AND b reg1 ri reg2 -> pprRegRIReg platform (text "and") b reg1 ri reg2
459
460 ANDN b reg1 ri reg2 -> pprRegRIReg platform (text "andn") b reg1 ri reg2
461
462 OR b reg1 ri reg2
463 | not b && reg1 == g0
464 -> let doit = hcat [ text "\tmov\t", pprRI platform ri, comma, pprReg reg2 ]
465 in case ri of
466 RIReg rrr | rrr == reg2 -> empty
467 _ -> doit
468
469 | otherwise
470 -> pprRegRIReg platform (text "or") b reg1 ri reg2
471
472 ORN b reg1 ri reg2 -> pprRegRIReg platform (text "orn") b reg1 ri reg2
473
474 XOR b reg1 ri reg2 -> pprRegRIReg platform (text "xor") b reg1 ri reg2
475 XNOR b reg1 ri reg2 -> pprRegRIReg platform (text "xnor") b reg1 ri reg2
476
477 SLL reg1 ri reg2 -> pprRegRIReg platform (text "sll") False reg1 ri reg2
478 SRL reg1 ri reg2 -> pprRegRIReg platform (text "srl") False reg1 ri reg2
479 SRA reg1 ri reg2 -> pprRegRIReg platform (text "sra") False reg1 ri reg2
480
481 RDY rd -> text "\trd\t%y," <> pprReg rd
482 WRY reg1 reg2
483 -> text "\twr\t"
484 <> pprReg reg1
485 <> char ','
486 <> pprReg reg2
487 <> char ','
488 <> text "%y"
489
490 SMUL b reg1 ri reg2 -> pprRegRIReg platform (text "smul") b reg1 ri reg2
491 UMUL b reg1 ri reg2 -> pprRegRIReg platform (text "umul") b reg1 ri reg2
492 SDIV b reg1 ri reg2 -> pprRegRIReg platform (text "sdiv") b reg1 ri reg2
493 UDIV b reg1 ri reg2 -> pprRegRIReg platform (text "udiv") b reg1 ri reg2
494
495 SETHI imm reg
496 -> hcat [
497 text "\tsethi\t",
498 pprImm platform imm,
499 comma,
500 pprReg reg
501 ]
502
503 NOP -> text "\tnop"
504
505 FABS format reg1 reg2
506 -> pprFormatRegReg (text "fabs") format reg1 reg2
507
508 FADD format reg1 reg2 reg3
509 -> pprFormatRegRegReg (text "fadd") format reg1 reg2 reg3
510
511 FCMP e format reg1 reg2
512 -> pprFormatRegReg (if e then text "fcmpe" else text "fcmp")
513 format reg1 reg2
514
515 FDIV format reg1 reg2 reg3
516 -> pprFormatRegRegReg (text "fdiv") format reg1 reg2 reg3
517
518 FMOV format reg1 reg2
519 -> pprFormatRegReg (text "fmov") format reg1 reg2
520
521 FMUL format reg1 reg2 reg3
522 -> pprFormatRegRegReg (text "fmul") format reg1 reg2 reg3
523
524 FNEG format reg1 reg2
525 -> pprFormatRegReg (text "fneg") format reg1 reg2
526
527 FSQRT format reg1 reg2
528 -> pprFormatRegReg (text "fsqrt") format reg1 reg2
529
530 FSUB format reg1 reg2 reg3
531 -> pprFormatRegRegReg (text "fsub") format reg1 reg2 reg3
532
533 FxTOy format1 format2 reg1 reg2
534 -> hcat [
535 text "\tf",
536 (case format1 of
537 II32 -> text "ito"
538 FF32 -> text "sto"
539 FF64 -> text "dto"
540 _ -> panic "SPARC.Ppr.pprInstr.FxToY: no match"),
541 (case format2 of
542 II32 -> text "i\t"
543 II64 -> text "x\t"
544 FF32 -> text "s\t"
545 FF64 -> text "d\t"
546 _ -> panic "SPARC.Ppr.pprInstr.FxToY: no match"),
547 pprReg reg1, comma, pprReg reg2
548 ]
549
550
551 BI cond b blockid
552 -> hcat [
553 text "\tb", pprCond cond,
554 if b then pp_comma_a else empty,
555 char '\t',
556 pdoc platform (blockLbl blockid)
557 ]
558
559 BF cond b blockid
560 -> hcat [
561 text "\tfb", pprCond cond,
562 if b then pp_comma_a else empty,
563 char '\t',
564 pdoc platform (blockLbl blockid)
565 ]
566
567 JMP addr -> text "\tjmp\t" <> pprAddr platform addr
568 JMP_TBL op _ _ -> pprInstr platform (JMP op)
569
570 CALL (Left imm) n _
571 -> hcat [ text "\tcall\t", pprImm platform imm, comma, int n ]
572
573 CALL (Right reg) n _
574 -> hcat [ text "\tcall\t", pprReg reg, comma, int n ]
575
576
577 -- | Pretty print a RI
578 pprRI :: Platform -> RI -> SDoc
579 pprRI platform = \case
580 RIReg r -> pprReg r
581 RIImm r -> pprImm platform r
582
583
584 -- | Pretty print a two reg instruction.
585 pprFormatRegReg :: SDoc -> Format -> Reg -> Reg -> SDoc
586 pprFormatRegReg name format reg1 reg2
587 = hcat [
588 char '\t',
589 name,
590 (case format of
591 FF32 -> text "s\t"
592 FF64 -> text "d\t"
593 _ -> panic "SPARC.Ppr.pprFormatRegReg: no match"),
594
595 pprReg reg1,
596 comma,
597 pprReg reg2
598 ]
599
600
601 -- | Pretty print a three reg instruction.
602 pprFormatRegRegReg :: SDoc -> Format -> Reg -> Reg -> Reg -> SDoc
603 pprFormatRegRegReg name format reg1 reg2 reg3
604 = hcat [
605 char '\t',
606 name,
607 (case format of
608 FF32 -> text "s\t"
609 FF64 -> text "d\t"
610 _ -> panic "SPARC.Ppr.pprFormatRegReg: no match"),
611 pprReg reg1,
612 comma,
613 pprReg reg2,
614 comma,
615 pprReg reg3
616 ]
617
618
619 -- | Pretty print an instruction of two regs and a ri.
620 pprRegRIReg :: Platform -> SDoc -> Bool -> Reg -> RI -> Reg -> SDoc
621 pprRegRIReg platform name b reg1 ri reg2
622 = hcat [
623 char '\t',
624 name,
625 if b then text "cc\t" else char '\t',
626 pprReg reg1,
627 comma,
628 pprRI platform ri,
629 comma,
630 pprReg reg2
631 ]
632
633 {-
634 pprRIReg :: SDoc -> Bool -> RI -> Reg -> SDoc
635 pprRIReg name b ri reg1
636 = hcat [
637 char '\t',
638 name,
639 if b then text "cc\t" else char '\t',
640 pprRI ri,
641 comma,
642 pprReg reg1
643 ]
644 -}
645
646 {-
647 pp_ld_lbracket :: SDoc
648 pp_ld_lbracket = text "\tld\t["
649 -}
650
651 pp_rbracket_comma :: SDoc
652 pp_rbracket_comma = text "],"
653
654
655 pp_comma_lbracket :: SDoc
656 pp_comma_lbracket = text ",["
657
658
659 pp_comma_a :: SDoc
660 pp_comma_a = text ",a"