Ppr.hs 18.8 KB
Newer Older
1 2
{-# LANGUAGE CPP #-}

3 4 5 6 7 8 9 10
-----------------------------------------------------------------------------
--
-- Pretty-printing assembly language
--
-- (c) The University of Glasgow 1993-2005
--
-----------------------------------------------------------------------------

11
{-# OPTIONS_GHC -fno-warn-orphans #-}
Ian Lynagh's avatar
Ian Lynagh committed
12

13
module SPARC.Ppr (
14 15 16 17
        pprNatCmmDecl,
        pprBasicBlock,
        pprData,
        pprInstr,
18
        pprFormat,
19 20
        pprImm,
        pprDataItem
21 22 23 24 25 26 27
)

where

#include "HsVersions.h"
#include "nativeGen/NCG.h"

28 29
import GhcPrelude

30 31
import SPARC.Regs
import SPARC.Instr
32
import SPARC.Cond
33 34 35
import SPARC.Imm
import SPARC.AddrMode
import SPARC.Base
36 37
import Instruction
import Reg
38
import Format
39
import PprBase
40

41
import Cmm hiding (topInfoTable)
42
import PprCmm() -- For Outputable instances
43
import BlockId
44
import CLabel
45 46
import Hoopl.Label
import Hoopl.Collections
47

48
import Unique           ( pprUniqueAlways )
49
import Outputable
John Ericson's avatar
John Ericson committed
50
import GHC.Platform
51
import FastString
52 53 54 55

-- -----------------------------------------------------------------------------
-- Printing this stuff out

56 57
pprNatCmmDecl :: NatCmmDecl CmmStatics Instr -> SDoc
pprNatCmmDecl (CmmData section dats) =
58
  pprSectionAlign section $$ pprDatas dats
59

60
pprNatCmmDecl proc@(CmmProc top_info lbl _ (ListGraph blocks)) =
61 62
  case topInfoTable proc of
    Nothing ->
Ben Gamari's avatar
Ben Gamari committed
63 64 65 66
        -- special case for code without info table:
        pprSectionAlign (Section Text lbl) $$
        pprLabel lbl $$ -- blocks guaranteed not null, so label needed
        vcat (map (pprBasicBlock top_info) blocks)
67

68
    Just (Statics info_lbl _) ->
69
      sdocWithPlatform $ \platform ->
70
      (if platformHasSubsectionsViaSymbols platform
71
          then pprSectionAlign dspSection $$
72 73 74
               ppr (mkDeadStripPreventer info_lbl) <> char ':'
          else empty) $$
      vcat (map (pprBasicBlock top_info) blocks) $$
75 76 77 78
      -- above: Even the first block gets a label, because with branch-chain
      -- elimination, it might be the target of a goto.
      (if platformHasSubsectionsViaSymbols platform
       then
79
       -- See Note [Subsections Via Symbols] in X86/Ppr.hs
80 81 82 83 84 85 86 87 88
                text "\t.long "
            <+> ppr info_lbl
            <+> char '-'
            <+> ppr (mkDeadStripPreventer info_lbl)
       else empty)

dspSection :: Section
dspSection = Section Text $
    panic "subsections-via-symbols doesn't combine with split-sections"
89

90
pprBasicBlock :: LabelMap CmmStatics -> NatBasicBlock Instr -> SDoc
91 92
pprBasicBlock info_env (BasicBlock blockid instrs)
  = maybe_infotable $$
93
    pprLabel (blockLbl blockid) $$
94 95 96 97 98
    vcat (map pprInstr instrs)
  where
    maybe_infotable = case mapLookup blockid info_env of
       Nothing   -> empty
       Just (Statics info_lbl info) ->
99
           pprAlignForSection Text $$
100 101
           vcat (map pprData info) $$
           pprLabel info_lbl
102 103


104
pprDatas :: CmmStatics -> SDoc
105 106 107 108 109 110 111 112 113 114
-- See note [emit-time elimination of static indirections] in CLabel.
pprDatas (Statics alias [CmmStaticLit (CmmLabel lbl), CmmStaticLit ind, _, _])
  | lbl == mkIndStaticInfoLabel
  , let labelInd (CmmLabelOff l _) = Just l
        labelInd (CmmLabel l) = Just l
        labelInd _ = Nothing
  , Just ind' <- labelInd ind
  , alias `mayRedirectTo` ind'
  = pprGloblDecl alias
    $$ text ".equiv" <+> ppr alias <> comma <> ppr (CmmLabel ind')
115
pprDatas (Statics lbl dats) = vcat (pprLabel lbl : map pprData dats)
116

117
pprData :: CmmStatic -> SDoc
118
pprData (CmmString str)          = pprBytes str
119
pprData (CmmUninitialised bytes) = text ".skip " <> int bytes
120
pprData (CmmStaticLit lit)       = pprDataItem lit
121

122 123
pprGloblDecl :: CLabel -> SDoc
pprGloblDecl lbl
124
  | not (externallyVisibleCLabel lbl) = empty
125
  | otherwise = text ".global " <> ppr lbl
126

127 128 129 130
pprTypeAndSizeDecl :: CLabel -> SDoc
pprTypeAndSizeDecl lbl
    = sdocWithPlatform $ \platform ->
      if platformOS platform == OSLinux && externallyVisibleCLabel lbl
131
      then text ".type " <> ppr lbl <> ptext (sLit ", @object")
132
      else empty
133

134 135 136 137
pprLabel :: CLabel -> SDoc
pprLabel lbl = pprGloblDecl lbl
            $$ pprTypeAndSizeDecl lbl
            $$ (ppr lbl <> char ':')
138 139 140 141

-- -----------------------------------------------------------------------------
-- pprInstr: print an 'Instr'

Ian Lynagh's avatar
Ian Lynagh committed
142
instance Outputable Instr where
143
    ppr instr = pprInstr instr
144 145 146


-- | Pretty print a register.
147
pprReg :: Reg -> SDoc
148 149
pprReg reg
 = case reg of
150
        RegVirtual vr
151 152 153 154 155 156
         -> case vr of
                VirtualRegI   u -> text "%vI_"   <> pprUniqueAlways u
                VirtualRegHi  u -> text "%vHi_"  <> pprUniqueAlways u
                VirtualRegF   u -> text "%vF_"   <> pprUniqueAlways u
                VirtualRegD   u -> text "%vD_"   <> pprUniqueAlways u

157

158 159 160 161 162 163 164
        RegReal rr
         -> case rr of
                RealRegSingle r1
                 -> pprReg_ofRegNo r1

                RealRegPair r1 r2
                 -> text "(" <> pprReg_ofRegNo r1
165
                 <> vbar     <> pprReg_ofRegNo r2
166
                 <> text ")"
167

168 169 170


-- | Pretty print a register name, based on this register number.
171 172 173
--   The definition has been unfolded so we get a jump-table in the
--   object code. This function is called quite a lot when emitting
--   the asm file..
174
--
175
pprReg_ofRegNo :: Int -> SDoc
176 177 178
pprReg_ofRegNo i
 = ptext
    (case i of {
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
         0 -> sLit "%g0";   1 -> sLit "%g1";
         2 -> sLit "%g2";   3 -> sLit "%g3";
         4 -> sLit "%g4";   5 -> sLit "%g5";
         6 -> sLit "%g6";   7 -> sLit "%g7";
         8 -> sLit "%o0";   9 -> sLit "%o1";
        10 -> sLit "%o2";  11 -> sLit "%o3";
        12 -> sLit "%o4";  13 -> sLit "%o5";
        14 -> sLit "%o6";  15 -> sLit "%o7";
        16 -> sLit "%l0";  17 -> sLit "%l1";
        18 -> sLit "%l2";  19 -> sLit "%l3";
        20 -> sLit "%l4";  21 -> sLit "%l5";
        22 -> sLit "%l6";  23 -> sLit "%l7";
        24 -> sLit "%i0";  25 -> sLit "%i1";
        26 -> sLit "%i2";  27 -> sLit "%i3";
        28 -> sLit "%i4";  29 -> sLit "%i5";
        30 -> sLit "%i6";  31 -> sLit "%i7";
        32 -> sLit "%f0";  33 -> sLit "%f1";
        34 -> sLit "%f2";  35 -> sLit "%f3";
        36 -> sLit "%f4";  37 -> sLit "%f5";
        38 -> sLit "%f6";  39 -> sLit "%f7";
        40 -> sLit "%f8";  41 -> sLit "%f9";
        42 -> sLit "%f10"; 43 -> sLit "%f11";
        44 -> sLit "%f12"; 45 -> sLit "%f13";
        46 -> sLit "%f14"; 47 -> sLit "%f15";
        48 -> sLit "%f16"; 49 -> sLit "%f17";
        50 -> sLit "%f18"; 51 -> sLit "%f19";
        52 -> sLit "%f20"; 53 -> sLit "%f21";
        54 -> sLit "%f22"; 55 -> sLit "%f23";
        56 -> sLit "%f24"; 57 -> sLit "%f25";
        58 -> sLit "%f26"; 59 -> sLit "%f27";
        60 -> sLit "%f28"; 61 -> sLit "%f29";
        62 -> sLit "%f30"; 63 -> sLit "%f31";
        _  -> sLit "very naughty sparc register" })
212 213


214 215 216
-- | Pretty print a format for an instruction suffix.
pprFormat :: Format -> SDoc
pprFormat x
217
 = ptext
218
    (case x of
219 220 221 222 223
        II8     -> sLit "ub"
        II16    -> sLit "uh"
        II32    -> sLit ""
        II64    -> sLit "d"
        FF32    -> sLit ""
224
        FF64    -> sLit "d")
225 226


227
-- | Pretty print a format for an instruction suffix.
228
--      eg LD is 32bit on sparc, but LDD is 64 bit.
229 230
pprStFormat :: Format -> SDoc
pprStFormat x
231
 = ptext
232
    (case x of
233 234 235 236 237
        II8   -> sLit "b"
        II16  -> sLit "h"
        II32  -> sLit ""
        II64  -> sLit "x"
        FF32  -> sLit ""
238
        FF64  -> sLit "d")
239

240 241


242
-- | Pretty print a condition code.
243
pprCond :: Cond -> SDoc
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
pprCond c
 = ptext
    (case c of
        ALWAYS  -> sLit ""
        NEVER   -> sLit "n"
        GEU     -> sLit "geu"
        LU      -> sLit "lu"
        EQQ     -> sLit "e"
        GTT     -> sLit "g"
        GE      -> sLit "ge"
        GU      -> sLit "gu"
        LTT     -> sLit "l"
        LE      -> sLit "le"
        LEU     -> sLit "leu"
        NE      -> sLit "ne"
        NEG     -> sLit "neg"
        POS     -> sLit "pos"
        VC      -> sLit "vc"
        VS      -> sLit "vs")
263 264 265


-- | Pretty print an address mode.
266 267
pprAddr :: AddrMode -> SDoc
pprAddr am
268
 = case am of
269 270
        AddrRegReg r1 (RegReal (RealRegSingle 0))
         -> pprReg r1
271

272 273
        AddrRegReg r1 r2
         -> hcat [ pprReg r1, char '+', pprReg r2 ]
274

275 276 277 278 279 280
        AddrRegImm r1 (ImmInt i)
         | i == 0               -> pprReg r1
         | not (fits13Bits i)   -> largeOffsetError i
         | otherwise            -> hcat [ pprReg r1, pp_sign, int i ]
         where
                pp_sign = if i > 0 then char '+' else empty
281

282 283 284 285 286 287
        AddrRegImm r1 (ImmInteger i)
         | i == 0               -> pprReg r1
         | not (fits13Bits i)   -> largeOffsetError i
         | otherwise            -> hcat [ pprReg r1, pp_sign, integer i ]
         where
                pp_sign = if i > 0 then char '+' else empty
288

289
        AddrRegImm r1 imm
290
         -> hcat [ pprReg r1, char '+', pprImm imm ]
291 292 293


-- | Pretty print an immediate value.
294 295
pprImm :: Imm -> SDoc
pprImm imm
296
 = case imm of
297 298
        ImmInt i        -> int i
        ImmInteger i    -> integer i
299 300
        ImmCLbl l       -> ppr l
        ImmIndex l i    -> ppr l <> char '+' <> int i
301
        ImmLit s        -> s
302

303
        ImmConstantSum a b
304
         -> pprImm a <> char '+' <> pprImm b
305

306
        ImmConstantDiff a b
307
         -> pprImm a <> char '-' <> lparen <> pprImm b <> rparen
308

309
        LO i
310
         -> hcat [ text "%lo(", pprImm i, rparen ]
311

312
        HI i
313
         -> hcat [ text "%hi(", pprImm i, rparen ]
314 315 316

        -- these should have been converted to bytes and placed
        --      in the data section.
317 318
        ImmFloat _      -> text "naughty float immediate"
        ImmDouble _     -> text "naughty double immediate"
319 320 321


-- | Pretty print a section \/ segment header.
322 323
--      On SPARC all the data sections must be at least 8 byte aligned
--      incase we store doubles in them.
324
--
325 326 327 328
pprSectionAlign :: Section -> SDoc
pprSectionAlign sec@(Section seg _) =
  sdocWithPlatform $ \platform ->
    pprSectionHeader platform sec $$
329 330 331 332 333
    pprAlignForSection seg

-- | Print appropriate alignment for the given section type.
pprAlignForSection :: SectionType -> SDoc
pprAlignForSection seg =
334 335 336 337 338 339 340 341
    ptext (case seg of
      Text              -> sLit ".align 4"
      Data              -> sLit ".align 8"
      ReadOnlyData      -> sLit ".align 8"
      RelocatableReadOnlyData
                        -> sLit ".align 8"
      UninitialisedData -> sLit ".align 8"
      ReadOnlyData16    -> sLit ".align 16"
342 343 344
      -- TODO: This is copied from the ReadOnlyData case, but it can likely be
      -- made more efficient.
      CString           -> sLit ".align 8"
345
      OtherSection _    -> panic "PprMach.pprSectionHeader: unknown section")
346 347

-- | Pretty print a data item.
348 349
pprDataItem :: CmmLit -> SDoc
pprDataItem lit
350
  = sdocWithDynFlags $ \dflags ->
351
    vcat (ppr_item (cmmTypeFormat $ cmmLitType dflags lit) lit)
352
    where
353
        imm = litToImm lit
354

355 356
        ppr_item II8   _        = [text "\t.byte\t" <> pprImm imm]
        ppr_item II32  _        = [text "\t.long\t" <> pprImm imm]
357

358
        ppr_item FF32  (CmmFloat r _)
359
         = let bs = floatToBytes (fromRational r)
360
           in  map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
361

362
        ppr_item FF64 (CmmFloat r _)
363
         = let bs = doubleToBytes (fromRational r)
364
           in  map (\b -> text "\t.byte\t" <> pprImm (ImmInt b)) bs
365

366 367
        ppr_item II16  _        = [text "\t.short\t" <> pprImm imm]
        ppr_item II64  _        = [text "\t.quad\t" <> pprImm imm]
368
        ppr_item _ _            = panic "SPARC.Ppr.pprDataItem: no match"
369 370 371


-- | Pretty print an instruction.
372
pprInstr :: Instr -> SDoc
373 374

-- nuke comments.
375
pprInstr (COMMENT _)
376
        = empty
377

378 379
pprInstr (DELTA d)
        = pprInstr (COMMENT (mkFastString ("\tdelta = " ++ show d)))
380 381

-- Newblocks and LData should have been slurped out before producing the .s file.
382
pprInstr (NEWBLOCK _)
383
        = panic "X86.Ppr.pprInstr: NEWBLOCK"
384

385
pprInstr (LDATA _ _)
386
        = panic "PprMach.pprInstr: LDATA"
387

388
-- 64 bit FP loads are expanded into individual instructions in CodeGen.Expand
389
pprInstr (LD FF64 _ reg)
390 391
        | RegReal (RealRegSingle{})     <- reg
        = panic "SPARC.Ppr: not emitting potentially misaligned LD FF64 instr"
392

393
pprInstr (LD format addr reg)
394
        = hcat [
395
               text "\tld",
396
               pprFormat format,
397 398
               char '\t',
               lbrack,
399
               pprAddr addr,
400 401 402
               pp_rbracket_comma,
               pprReg reg
            ]
403

Gabor Greif's avatar
Gabor Greif committed
404
-- 64 bit FP stores are expanded into individual instructions in CodeGen.Expand
405
pprInstr (ST FF64 reg _)
406 407
        | RegReal (RealRegSingle{}) <- reg
        = panic "SPARC.Ppr: not emitting potentially misaligned ST FF64 instr"
408 409 410

-- no distinction is made between signed and unsigned bytes on stores for the
-- Sparc opcodes (at least I cannot see any, and gas is nagging me --SOF),
411 412
-- so we call a special-purpose pprFormat for ST..
pprInstr (ST format reg addr)
413
        = hcat [
414
               text "\tst",
415
               pprStFormat format,
416 417 418
               char '\t',
               pprReg reg,
               pp_comma_lbracket,
419
               pprAddr addr,
420 421
               rbrack
            ]
422 423


424
pprInstr (ADD x cc reg1 ri reg2)
425
        | not x && not cc && riZero ri
426
        = hcat [ text "\tmov\t", pprReg reg1, comma, pprReg reg2 ]
427

428
        | otherwise
429
        = pprRegRIReg (if x then sLit "addx" else sLit "add") cc reg1 ri reg2
430 431


432
pprInstr (SUB x cc reg1 ri reg2)
433
        | not x && cc && reg2 == g0
434
        = hcat [ text "\tcmp\t", pprReg reg1, comma, pprRI ri ]
435 436

        | not x && not cc && riZero ri
437
        = hcat [ text "\tmov\t", pprReg reg1, comma, pprReg reg2 ]
438

439
        | otherwise
440
        = pprRegRIReg (if x then sLit "subx" else sLit "sub") cc reg1 ri reg2
441

442
pprInstr (AND  b reg1 ri reg2) = pprRegRIReg (sLit "and")  b reg1 ri reg2
443

444
pprInstr (ANDN b reg1 ri reg2) = pprRegRIReg (sLit "andn") b reg1 ri reg2
445

446
pprInstr (OR b reg1 ri reg2)
447
        | not b && reg1 == g0
448
        = let doit = hcat [ text "\tmov\t", pprRI ri, comma, pprReg reg2 ]
449 450 451 452 453
          in  case ri of
                   RIReg rrr | rrr == reg2 -> empty
                   _                       -> doit

        | otherwise
454
        = pprRegRIReg (sLit "or") b reg1 ri reg2
455

456
pprInstr (ORN b reg1 ri reg2)  = pprRegRIReg (sLit "orn") b reg1 ri reg2
457

458 459
pprInstr (XOR  b reg1 ri reg2) = pprRegRIReg (sLit "xor")  b reg1 ri reg2
pprInstr (XNOR b reg1 ri reg2) = pprRegRIReg (sLit "xnor") b reg1 ri reg2
460

461 462 463
pprInstr (SLL reg1 ri reg2)    = pprRegRIReg (sLit "sll") False reg1 ri reg2
pprInstr (SRL reg1 ri reg2)    = pprRegRIReg (sLit "srl") False reg1 ri reg2
pprInstr (SRA reg1 ri reg2)    = pprRegRIReg (sLit "sra") False reg1 ri reg2
464

465
pprInstr (RDY rd)              = text "\trd\t%y," <> pprReg rd
466
pprInstr (WRY reg1 reg2)
467
        = text "\twr\t"
468 469 470 471
                <> pprReg reg1
                <> char ','
                <> pprReg reg2
                <> char ','
472
                <> text "%y"
473

474 475 476 477
pprInstr (SMUL b reg1 ri reg2) = pprRegRIReg (sLit "smul")  b reg1 ri reg2
pprInstr (UMUL b reg1 ri reg2) = pprRegRIReg (sLit "umul")  b reg1 ri reg2
pprInstr (SDIV b reg1 ri reg2) = pprRegRIReg (sLit "sdiv")  b reg1 ri reg2
pprInstr (UDIV b reg1 ri reg2) = pprRegRIReg (sLit "udiv")  b reg1 ri reg2
478

479
pprInstr (SETHI imm reg)
480
  = hcat [
481
        text "\tsethi\t",
482
        pprImm imm,
483 484
        comma,
        pprReg reg
485 486
    ]

487
pprInstr NOP
488
        = text "\tnop"
489

490 491
pprInstr (FABS format reg1 reg2)
        = pprFormatRegReg (sLit "fabs") format reg1 reg2
492

493 494
pprInstr (FADD format reg1 reg2 reg3)
        = pprFormatRegRegReg (sLit "fadd") format reg1 reg2 reg3
495

496 497 498
pprInstr (FCMP e format reg1 reg2)
        = pprFormatRegReg (if e then sLit "fcmpe" else sLit "fcmp")
                          format reg1 reg2
499

500 501
pprInstr (FDIV format reg1 reg2 reg3)
        = pprFormatRegRegReg (sLit "fdiv") format reg1 reg2 reg3
502

503 504
pprInstr (FMOV format reg1 reg2)
        = pprFormatRegReg (sLit "fmov") format reg1 reg2
505

506 507
pprInstr (FMUL format reg1 reg2 reg3)
        = pprFormatRegRegReg (sLit "fmul") format reg1 reg2 reg3
508

509 510
pprInstr (FNEG format reg1 reg2)
        = pprFormatRegReg (sLit "fneg") format reg1 reg2
511

512 513
pprInstr (FSQRT format reg1 reg2)
        = pprFormatRegReg (sLit "fsqrt") format reg1 reg2
514

515 516
pprInstr (FSUB format reg1 reg2 reg3)
        = pprFormatRegRegReg (sLit "fsub") format reg1 reg2 reg3
517

518
pprInstr (FxTOy format1 format2 reg1 reg2)
519
  = hcat [
520
        text "\tf",
521
        ptext
522
        (case format1 of
523 524 525 526 527
            II32  -> sLit "ito"
            FF32  -> sLit "sto"
            FF64  -> sLit "dto"
            _     -> panic "SPARC.Ppr.pprInstr.FxToY: no match"),
        ptext
528
        (case format2 of
529 530 531 532 533 534
            II32  -> sLit "i\t"
            II64  -> sLit "x\t"
            FF32  -> sLit "s\t"
            FF64  -> sLit "d\t"
            _     -> panic "SPARC.Ppr.pprInstr.FxToY: no match"),
        pprReg reg1, comma, pprReg reg2
535 536 537
    ]


538
pprInstr (BI cond b blockid)
539
  = hcat [
540
        text "\tb", pprCond cond,
541 542
        if b then pp_comma_a else empty,
        char '\t',
543
        ppr (blockLbl blockid)
544 545
    ]

546
pprInstr (BF cond b blockid)
547
  = hcat [
548
        text "\tfb", pprCond cond,
549 550
        if b then pp_comma_a else empty,
        char '\t',
551
        ppr (blockLbl blockid)
552 553
    ]

554
pprInstr (JMP addr) = text "\tjmp\t" <> pprAddr addr
555
pprInstr (JMP_TBL op _ _)  = pprInstr (JMP op)
556

557
pprInstr (CALL (Left imm) n _)
558
  = hcat [ text "\tcall\t", pprImm imm, comma, int n ]
559

560
pprInstr (CALL (Right reg) n _)
561
  = hcat [ text "\tcall\t", pprReg reg, comma, int n ]
562 563 564


-- | Pretty print a RI
565 566 567
pprRI :: RI -> SDoc
pprRI (RIReg r) = pprReg r
pprRI (RIImm r) = pprImm r
568 569 570


-- | Pretty print a two reg instruction.
Sylvain Henry's avatar
Sylvain Henry committed
571
pprFormatRegReg :: PtrString -> Format -> Reg -> Reg -> SDoc
572
pprFormatRegReg name format reg1 reg2
573
  = hcat [
574 575
        char '\t',
        ptext name,
576
        (case format of
577 578
            FF32 -> text "s\t"
            FF64 -> text "d\t"
579
            _    -> panic "SPARC.Ppr.pprFormatRegReg: no match"),
580 581 582 583

        pprReg reg1,
        comma,
        pprReg reg2
584 585 586 587
    ]


-- | Pretty print a three reg instruction.
Sylvain Henry's avatar
Sylvain Henry committed
588
pprFormatRegRegReg :: PtrString -> Format -> Reg -> Reg -> Reg -> SDoc
589
pprFormatRegRegReg name format reg1 reg2 reg3
590
  = hcat [
591 592
        char '\t',
        ptext name,
593
        (case format of
594 595
            FF32  -> text "s\t"
            FF64  -> text "d\t"
596
            _    -> panic "SPARC.Ppr.pprFormatRegReg: no match"),
597 598 599 600 601
        pprReg reg1,
        comma,
        pprReg reg2,
        comma,
        pprReg reg3
602 603 604 605
    ]


-- | Pretty print an instruction of two regs and a ri.
Sylvain Henry's avatar
Sylvain Henry committed
606
pprRegRIReg :: PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
607
pprRegRIReg name b reg1 ri reg2
608
  = hcat [
609 610
        char '\t',
        ptext name,
611
        if b then text "cc\t" else char '\t',
612 613
        pprReg reg1,
        comma,
614
        pprRI ri,
615 616
        comma,
        pprReg reg2
617 618 619
    ]

{-
Sylvain Henry's avatar
Sylvain Henry committed
620
pprRIReg :: PtrString -> Bool -> RI -> Reg -> SDoc
621 622
pprRIReg name b ri reg1
  = hcat [
623 624
        char '\t',
        ptext name,
625
        if b then text "cc\t" else char '\t',
626 627 628
        pprRI ri,
        comma,
        pprReg reg1
629 630 631
    ]
-}

632
{-
633
pp_ld_lbracket :: SDoc
634
pp_ld_lbracket    = text "\tld\t["
635
-}
636

637
pp_rbracket_comma :: SDoc
638 639 640
pp_rbracket_comma = text "],"


641
pp_comma_lbracket :: SDoc
642 643 644
pp_comma_lbracket = text ",["


645
pp_comma_a :: SDoc
646
pp_comma_a        = text ",a"