{-# LANGUAGE CPP #-}

-----------------------------------------------------------------------------
--
-- Pretty-printing assembly language
--
-- (c) The University of Glasgow 1993-2005
--
-----------------------------------------------------------------------------

{-# OPTIONS_GHC -fno-warn-orphans #-}

module SPARC.Ppr (
        pprNatCmmDecl,
        pprBasicBlock,
        pprData,
        pprInstr,
        pprFormat,
        pprImm,
        pprDataItem
)

where

#include "HsVersions.h"

import GhcPrelude

import SPARC.Regs
import SPARC.Instr
import SPARC.Cond
import SPARC.Imm
import SPARC.AddrMode
import SPARC.Base
import Instruction
import Reg
import Format
import PprBase

import Cmm hiding (topInfoTable)
import PprCmm() -- For Outputable instances
import BlockId
import CLabel
import Hoopl.Label
import Hoopl.Collections

import Unique           ( pprUniqueAlways )
import Outputable
import GHC.Platform
import FastString

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

pprNatCmmDecl :: NatCmmDecl CmmStatics Instr -> SDoc
pprNatCmmDecl :: NatCmmDecl CmmStatics Instr -> SDoc
pprNatCmmDecl (CmmData Section
section CmmStatics
dats) =
  Section -> SDoc
pprSectionAlign Section
section SDoc -> SDoc -> SDoc
$$ CmmStatics -> SDoc
pprDatas CmmStatics
dats

pprNatCmmDecl proc :: NatCmmDecl CmmStatics Instr
proc@(CmmProc LabelMap CmmStatics
top_info CLabel
lbl [GlobalReg]
_ (ListGraph [GenBasicBlock Instr]
blocks)) =
  case NatCmmDecl CmmStatics Instr -> Maybe CmmStatics
forall a i b. GenCmmDecl a (LabelMap i) (ListGraph b) -> Maybe i
topInfoTable NatCmmDecl CmmStatics Instr
proc of
    Maybe CmmStatics
Nothing ->
        -- special case for code without info table:
        Section -> SDoc
pprSectionAlign (SectionType -> CLabel -> Section
Section SectionType
Text CLabel
lbl) SDoc -> SDoc -> SDoc
$$
        CLabel -> SDoc
pprLabel CLabel
lbl SDoc -> SDoc -> SDoc
$$ -- blocks guaranteed not null, so label needed
        [SDoc] -> SDoc
vcat ((GenBasicBlock Instr -> SDoc) -> [GenBasicBlock Instr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LabelMap CmmStatics -> GenBasicBlock Instr -> SDoc
pprBasicBlock LabelMap CmmStatics
top_info) [GenBasicBlock Instr]
blocks)

    Just (Statics CLabel
info_lbl [CmmStatic]
_) ->
      (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Platform
platform ->
      (if Platform -> Bool
platformHasSubsectionsViaSymbols Platform
platform
          then Section -> SDoc
pprSectionAlign Section
dspSection SDoc -> SDoc -> SDoc
$$
               CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> CLabel
mkDeadStripPreventer CLabel
info_lbl) SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
':'
          else SDoc
empty) SDoc -> SDoc -> SDoc
$$
      [SDoc] -> SDoc
vcat ((GenBasicBlock Instr -> SDoc) -> [GenBasicBlock Instr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LabelMap CmmStatics -> GenBasicBlock Instr -> SDoc
pprBasicBlock LabelMap CmmStatics
top_info) [GenBasicBlock Instr]
blocks) SDoc -> SDoc -> SDoc
$$
      -- above: Even the first block gets a label, because with branch-chain
      -- elimination, it might be the target of a goto.
      (if Platform -> Bool
platformHasSubsectionsViaSymbols Platform
platform
       then
       -- See Note [Subsections Via Symbols] in X86/Ppr.hs
                String -> SDoc
text String
"\t.long "
            SDoc -> SDoc -> SDoc
<+> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
info_lbl
            SDoc -> SDoc -> SDoc
<+> Char -> SDoc
char Char
'-'
            SDoc -> SDoc -> SDoc
<+> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> CLabel
mkDeadStripPreventer CLabel
info_lbl)
       else SDoc
empty)

dspSection :: Section
dspSection :: Section
dspSection = SectionType -> CLabel -> Section
Section SectionType
Text (CLabel -> Section) -> CLabel -> Section
forall a b. (a -> b) -> a -> b
$
    String -> CLabel
forall a. String -> a
panic String
"subsections-via-symbols doesn't combine with split-sections"

pprBasicBlock :: LabelMap CmmStatics -> NatBasicBlock Instr -> SDoc
pprBasicBlock :: LabelMap CmmStatics -> GenBasicBlock Instr -> SDoc
pprBasicBlock LabelMap CmmStatics
info_env (BasicBlock BlockId
blockid [Instr]
instrs)
  = SDoc
maybe_infotable SDoc -> SDoc -> SDoc
$$
    CLabel -> SDoc
pprLabel (BlockId -> CLabel
blockLbl BlockId
blockid) SDoc -> SDoc -> SDoc
$$
    [SDoc] -> SDoc
vcat ((Instr -> SDoc) -> [Instr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Instr -> SDoc
pprInstr [Instr]
instrs)
  where
    maybe_infotable :: SDoc
maybe_infotable = case KeyOf LabelMap -> LabelMap CmmStatics -> Maybe CmmStatics
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
blockid LabelMap CmmStatics
info_env of
       Maybe CmmStatics
Nothing   -> SDoc
empty
       Just (Statics CLabel
info_lbl [CmmStatic]
info) ->
           SectionType -> SDoc
pprAlignForSection SectionType
Text SDoc -> SDoc -> SDoc
$$
           [SDoc] -> SDoc
vcat ((CmmStatic -> SDoc) -> [CmmStatic] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map CmmStatic -> SDoc
pprData [CmmStatic]
info) SDoc -> SDoc -> SDoc
$$
           CLabel -> SDoc
pprLabel CLabel
info_lbl


pprDatas :: CmmStatics -> SDoc
-- See note [emit-time elimination of static indirections] in CLabel.
pprDatas :: CmmStatics -> SDoc
pprDatas (Statics CLabel
alias [CmmStaticLit (CmmLabel CLabel
lbl), CmmStaticLit CmmLit
ind, CmmStatic
_, CmmStatic
_])
  | CLabel
lbl CLabel -> CLabel -> Bool
forall a. Eq a => a -> a -> Bool
== CLabel
mkIndStaticInfoLabel
  , let labelInd :: CmmLit -> Maybe CLabel
labelInd (CmmLabelOff CLabel
l Int
_) = CLabel -> Maybe CLabel
forall a. a -> Maybe a
Just CLabel
l
        labelInd (CmmLabel CLabel
l) = CLabel -> Maybe CLabel
forall a. a -> Maybe a
Just CLabel
l
        labelInd CmmLit
_ = Maybe CLabel
forall a. Maybe a
Nothing
  , Just CLabel
ind' <- CmmLit -> Maybe CLabel
labelInd CmmLit
ind
  , CLabel
alias CLabel -> CLabel -> Bool
`mayRedirectTo` CLabel
ind'
  = CLabel -> SDoc
pprGloblDecl CLabel
alias
    SDoc -> SDoc -> SDoc
$$ String -> SDoc
text String
".equiv" SDoc -> SDoc -> SDoc
<+> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
alias SDoc -> SDoc -> SDoc
<> SDoc
comma SDoc -> SDoc -> SDoc
<> CmmLit -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> CmmLit
CmmLabel CLabel
ind')
pprDatas (Statics CLabel
lbl [CmmStatic]
dats) = [SDoc] -> SDoc
vcat (CLabel -> SDoc
pprLabel CLabel
lbl SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
: (CmmStatic -> SDoc) -> [CmmStatic] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map CmmStatic -> SDoc
pprData [CmmStatic]
dats)

pprData :: CmmStatic -> SDoc
pprData :: CmmStatic -> SDoc
pprData (CmmString ByteString
str)          = ByteString -> SDoc
pprBytes ByteString
str
pprData (CmmUninitialised Int
bytes) = String -> SDoc
text String
".skip " SDoc -> SDoc -> SDoc
<> Int -> SDoc
int Int
bytes
pprData (CmmStaticLit CmmLit
lit)       = CmmLit -> SDoc
pprDataItem CmmLit
lit

pprGloblDecl :: CLabel -> SDoc
pprGloblDecl :: CLabel -> SDoc
pprGloblDecl CLabel
lbl
  | Bool -> Bool
not (CLabel -> Bool
externallyVisibleCLabel CLabel
lbl) = SDoc
empty
  | Bool
otherwise = String -> SDoc
text String
".global " SDoc -> SDoc -> SDoc
<> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
lbl

pprTypeAndSizeDecl :: CLabel -> SDoc
pprTypeAndSizeDecl :: CLabel -> SDoc
pprTypeAndSizeDecl CLabel
lbl
    = (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Platform
platform ->
      if Platform -> OS
platformOS Platform
platform OS -> OS -> Bool
forall a. Eq a => a -> a -> Bool
== OS
OSLinux Bool -> Bool -> Bool
&& CLabel -> Bool
externallyVisibleCLabel CLabel
lbl
      then String -> SDoc
text String
".type " SDoc -> SDoc -> SDoc
<> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
lbl SDoc -> SDoc -> SDoc
<> PtrString -> SDoc
ptext (String -> PtrString
sLit String
", @object")
      else SDoc
empty

pprLabel :: CLabel -> SDoc
pprLabel :: CLabel -> SDoc
pprLabel CLabel
lbl = CLabel -> SDoc
pprGloblDecl CLabel
lbl
            SDoc -> SDoc -> SDoc
$$ CLabel -> SDoc
pprTypeAndSizeDecl CLabel
lbl
            SDoc -> SDoc -> SDoc
$$ (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
lbl SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
':')

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

instance Outputable Instr where
    ppr :: Instr -> SDoc
ppr Instr
instr = Instr -> SDoc
pprInstr Instr
instr


-- | Pretty print a register.
pprReg :: Reg -> SDoc
pprReg :: Reg -> SDoc
pprReg Reg
reg
 = case Reg
reg of
        RegVirtual VirtualReg
vr
         -> case VirtualReg
vr of
                VirtualRegI   Unique
u -> String -> SDoc
text String
"%vI_"   SDoc -> SDoc -> SDoc
<> Unique -> SDoc
pprUniqueAlways Unique
u
                VirtualRegHi  Unique
u -> String -> SDoc
text String
"%vHi_"  SDoc -> SDoc -> SDoc
<> Unique -> SDoc
pprUniqueAlways Unique
u
                VirtualRegF   Unique
u -> String -> SDoc
text String
"%vF_"   SDoc -> SDoc -> SDoc
<> Unique -> SDoc
pprUniqueAlways Unique
u
                VirtualRegD   Unique
u -> String -> SDoc
text String
"%vD_"   SDoc -> SDoc -> SDoc
<> Unique -> SDoc
pprUniqueAlways Unique
u


        RegReal RealReg
rr
         -> case RealReg
rr of
                RealRegSingle Int
r1
                 -> Int -> SDoc
pprReg_ofRegNo Int
r1

                RealRegPair Int
r1 Int
r2
                 -> String -> SDoc
text String
"(" SDoc -> SDoc -> SDoc
<> Int -> SDoc
pprReg_ofRegNo Int
r1
                 SDoc -> SDoc -> SDoc
<> SDoc
vbar     SDoc -> SDoc -> SDoc
<> Int -> SDoc
pprReg_ofRegNo Int
r2
                 SDoc -> SDoc -> SDoc
<> String -> SDoc
text String
")"



-- | Pretty print a register name, based on this register number.
--   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..
--
pprReg_ofRegNo :: Int -> SDoc
pprReg_ofRegNo :: Int -> SDoc
pprReg_ofRegNo Int
i
 = PtrString -> SDoc
ptext
    (case Int
i of {
         Int
0 -> String -> PtrString
sLit String
"%g0";   Int
1 -> String -> PtrString
sLit String
"%g1";
         Int
2 -> String -> PtrString
sLit String
"%g2";   Int
3 -> String -> PtrString
sLit String
"%g3";
         Int
4 -> String -> PtrString
sLit String
"%g4";   Int
5 -> String -> PtrString
sLit String
"%g5";
         Int
6 -> String -> PtrString
sLit String
"%g6";   Int
7 -> String -> PtrString
sLit String
"%g7";
         Int
8 -> String -> PtrString
sLit String
"%o0";   Int
9 -> String -> PtrString
sLit String
"%o1";
        Int
10 -> String -> PtrString
sLit String
"%o2";  Int
11 -> String -> PtrString
sLit String
"%o3";
        Int
12 -> String -> PtrString
sLit String
"%o4";  Int
13 -> String -> PtrString
sLit String
"%o5";
        Int
14 -> String -> PtrString
sLit String
"%o6";  Int
15 -> String -> PtrString
sLit String
"%o7";
        Int
16 -> String -> PtrString
sLit String
"%l0";  Int
17 -> String -> PtrString
sLit String
"%l1";
        Int
18 -> String -> PtrString
sLit String
"%l2";  Int
19 -> String -> PtrString
sLit String
"%l3";
        Int
20 -> String -> PtrString
sLit String
"%l4";  Int
21 -> String -> PtrString
sLit String
"%l5";
        Int
22 -> String -> PtrString
sLit String
"%l6";  Int
23 -> String -> PtrString
sLit String
"%l7";
        Int
24 -> String -> PtrString
sLit String
"%i0";  Int
25 -> String -> PtrString
sLit String
"%i1";
        Int
26 -> String -> PtrString
sLit String
"%i2";  Int
27 -> String -> PtrString
sLit String
"%i3";
        Int
28 -> String -> PtrString
sLit String
"%i4";  Int
29 -> String -> PtrString
sLit String
"%i5";
        Int
30 -> String -> PtrString
sLit String
"%i6";  Int
31 -> String -> PtrString
sLit String
"%i7";
        Int
32 -> String -> PtrString
sLit String
"%f0";  Int
33 -> String -> PtrString
sLit String
"%f1";
        Int
34 -> String -> PtrString
sLit String
"%f2";  Int
35 -> String -> PtrString
sLit String
"%f3";
        Int
36 -> String -> PtrString
sLit String
"%f4";  Int
37 -> String -> PtrString
sLit String
"%f5";
        Int
38 -> String -> PtrString
sLit String
"%f6";  Int
39 -> String -> PtrString
sLit String
"%f7";
        Int
40 -> String -> PtrString
sLit String
"%f8";  Int
41 -> String -> PtrString
sLit String
"%f9";
        Int
42 -> String -> PtrString
sLit String
"%f10"; Int
43 -> String -> PtrString
sLit String
"%f11";
        Int
44 -> String -> PtrString
sLit String
"%f12"; Int
45 -> String -> PtrString
sLit String
"%f13";
        Int
46 -> String -> PtrString
sLit String
"%f14"; Int
47 -> String -> PtrString
sLit String
"%f15";
        Int
48 -> String -> PtrString
sLit String
"%f16"; Int
49 -> String -> PtrString
sLit String
"%f17";
        Int
50 -> String -> PtrString
sLit String
"%f18"; Int
51 -> String -> PtrString
sLit String
"%f19";
        Int
52 -> String -> PtrString
sLit String
"%f20"; Int
53 -> String -> PtrString
sLit String
"%f21";
        Int
54 -> String -> PtrString
sLit String
"%f22"; Int
55 -> String -> PtrString
sLit String
"%f23";
        Int
56 -> String -> PtrString
sLit String
"%f24"; Int
57 -> String -> PtrString
sLit String
"%f25";
        Int
58 -> String -> PtrString
sLit String
"%f26"; Int
59 -> String -> PtrString
sLit String
"%f27";
        Int
60 -> String -> PtrString
sLit String
"%f28"; Int
61 -> String -> PtrString
sLit String
"%f29";
        Int
62 -> String -> PtrString
sLit String
"%f30"; Int
63 -> String -> PtrString
sLit String
"%f31";
        Int
_  -> String -> PtrString
sLit String
"very naughty sparc register" })


-- | Pretty print a format for an instruction suffix.
pprFormat :: Format -> SDoc
pprFormat :: Format -> SDoc
pprFormat Format
x
 = PtrString -> SDoc
ptext
    (case Format
x of
        Format
II8     -> String -> PtrString
sLit String
"ub"
        Format
II16    -> String -> PtrString
sLit String
"uh"
        Format
II32    -> String -> PtrString
sLit String
""
        Format
II64    -> String -> PtrString
sLit String
"d"
        Format
FF32    -> String -> PtrString
sLit String
""
        Format
FF64    -> String -> PtrString
sLit String
"d")


-- | Pretty print a format for an instruction suffix.
--      eg LD is 32bit on sparc, but LDD is 64 bit.
pprStFormat :: Format -> SDoc
pprStFormat :: Format -> SDoc
pprStFormat Format
x
 = PtrString -> SDoc
ptext
    (case Format
x of
        Format
II8   -> String -> PtrString
sLit String
"b"
        Format
II16  -> String -> PtrString
sLit String
"h"
        Format
II32  -> String -> PtrString
sLit String
""
        Format
II64  -> String -> PtrString
sLit String
"x"
        Format
FF32  -> String -> PtrString
sLit String
""
        Format
FF64  -> String -> PtrString
sLit String
"d")



-- | Pretty print a condition code.
pprCond :: Cond -> SDoc
pprCond :: Cond -> SDoc
pprCond Cond
c
 = PtrString -> SDoc
ptext
    (case Cond
c of
        Cond
ALWAYS  -> String -> PtrString
sLit String
""
        Cond
NEVER   -> String -> PtrString
sLit String
"n"
        Cond
GEU     -> String -> PtrString
sLit String
"geu"
        Cond
LU      -> String -> PtrString
sLit String
"lu"
        Cond
EQQ     -> String -> PtrString
sLit String
"e"
        Cond
GTT     -> String -> PtrString
sLit String
"g"
        Cond
GE      -> String -> PtrString
sLit String
"ge"
        Cond
GU      -> String -> PtrString
sLit String
"gu"
        Cond
LTT     -> String -> PtrString
sLit String
"l"
        Cond
LE      -> String -> PtrString
sLit String
"le"
        Cond
LEU     -> String -> PtrString
sLit String
"leu"
        Cond
NE      -> String -> PtrString
sLit String
"ne"
        Cond
NEG     -> String -> PtrString
sLit String
"neg"
        Cond
POS     -> String -> PtrString
sLit String
"pos"
        Cond
VC      -> String -> PtrString
sLit String
"vc"
        Cond
VS      -> String -> PtrString
sLit String
"vs")


-- | Pretty print an address mode.
pprAddr :: AddrMode -> SDoc
pprAddr :: AddrMode -> SDoc
pprAddr AddrMode
am
 = case AddrMode
am of
        AddrRegReg Reg
r1 (RegReal (RealRegSingle Int
0))
         -> Reg -> SDoc
pprReg Reg
r1

        AddrRegReg Reg
r1 Reg
r2
         -> [SDoc] -> SDoc
hcat [ Reg -> SDoc
pprReg Reg
r1, Char -> SDoc
char Char
'+', Reg -> SDoc
pprReg Reg
r2 ]

        AddrRegImm Reg
r1 (ImmInt Int
i)
         | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0               -> Reg -> SDoc
pprReg Reg
r1
         | Bool -> Bool
not (Int -> Bool
forall a. Integral a => a -> Bool
fits13Bits Int
i)   -> Int -> SDoc
forall a b. Show a => a -> b
largeOffsetError Int
i
         | Bool
otherwise            -> [SDoc] -> SDoc
hcat [ Reg -> SDoc
pprReg Reg
r1, SDoc
pp_sign, Int -> SDoc
int Int
i ]
         where
                pp_sign :: SDoc
pp_sign = if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then Char -> SDoc
char Char
'+' else SDoc
empty

        AddrRegImm Reg
r1 (ImmInteger Integer
i)
         | Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0               -> Reg -> SDoc
pprReg Reg
r1
         | Bool -> Bool
not (Integer -> Bool
forall a. Integral a => a -> Bool
fits13Bits Integer
i)   -> Integer -> SDoc
forall a b. Show a => a -> b
largeOffsetError Integer
i
         | Bool
otherwise            -> [SDoc] -> SDoc
hcat [ Reg -> SDoc
pprReg Reg
r1, SDoc
pp_sign, Integer -> SDoc
integer Integer
i ]
         where
                pp_sign :: SDoc
pp_sign = if Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 then Char -> SDoc
char Char
'+' else SDoc
empty

        AddrRegImm Reg
r1 Imm
imm
         -> [SDoc] -> SDoc
hcat [ Reg -> SDoc
pprReg Reg
r1, Char -> SDoc
char Char
'+', Imm -> SDoc
pprImm Imm
imm ]


-- | Pretty print an immediate value.
pprImm :: Imm -> SDoc
pprImm :: Imm -> SDoc
pprImm Imm
imm
 = case Imm
imm of
        ImmInt Int
i        -> Int -> SDoc
int Int
i
        ImmInteger Integer
i    -> Integer -> SDoc
integer Integer
i
        ImmCLbl CLabel
l       -> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
l
        ImmIndex CLabel
l Int
i    -> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
l SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
'+' SDoc -> SDoc -> SDoc
<> Int -> SDoc
int Int
i
        ImmLit SDoc
s        -> SDoc
s

        ImmConstantSum Imm
a Imm
b
         -> Imm -> SDoc
pprImm Imm
a SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
'+' SDoc -> SDoc -> SDoc
<> Imm -> SDoc
pprImm Imm
b

        ImmConstantDiff Imm
a Imm
b
         -> Imm -> SDoc
pprImm Imm
a SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
'-' SDoc -> SDoc -> SDoc
<> SDoc
lparen SDoc -> SDoc -> SDoc
<> Imm -> SDoc
pprImm Imm
b SDoc -> SDoc -> SDoc
<> SDoc
rparen

        LO Imm
i
         -> [SDoc] -> SDoc
hcat [ String -> SDoc
text String
"%lo(", Imm -> SDoc
pprImm Imm
i, SDoc
rparen ]

        HI Imm
i
         -> [SDoc] -> SDoc
hcat [ String -> SDoc
text String
"%hi(", Imm -> SDoc
pprImm Imm
i, SDoc
rparen ]

        -- these should have been converted to bytes and placed
        --      in the data section.
        ImmFloat Rational
_      -> String -> SDoc
text String
"naughty float immediate"
        ImmDouble Rational
_     -> String -> SDoc
text String
"naughty double immediate"


-- | Pretty print a section \/ segment header.
--      On SPARC all the data sections must be at least 8 byte aligned
--      incase we store doubles in them.
--
pprSectionAlign :: Section -> SDoc
pprSectionAlign :: Section -> SDoc
pprSectionAlign sec :: Section
sec@(Section SectionType
seg CLabel
_) =
  (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \Platform
platform ->
    Platform -> Section -> SDoc
pprSectionHeader Platform
platform Section
sec SDoc -> SDoc -> SDoc
$$
    SectionType -> SDoc
pprAlignForSection SectionType
seg

-- | Print appropriate alignment for the given section type.
pprAlignForSection :: SectionType -> SDoc
pprAlignForSection :: SectionType -> SDoc
pprAlignForSection SectionType
seg =
    PtrString -> SDoc
ptext (case SectionType
seg of
      SectionType
Text              -> String -> PtrString
sLit String
".align 4"
      SectionType
Data              -> String -> PtrString
sLit String
".align 8"
      SectionType
ReadOnlyData      -> String -> PtrString
sLit String
".align 8"
      SectionType
RelocatableReadOnlyData
                        -> String -> PtrString
sLit String
".align 8"
      SectionType
UninitialisedData -> String -> PtrString
sLit String
".align 8"
      SectionType
ReadOnlyData16    -> String -> PtrString
sLit String
".align 16"
      -- TODO: This is copied from the ReadOnlyData case, but it can likely be
      -- made more efficient.
      SectionType
CString           -> String -> PtrString
sLit String
".align 8"
      OtherSection String
_    -> String -> PtrString
forall a. String -> a
panic String
"PprMach.pprSectionHeader: unknown section")

-- | Pretty print a data item.
pprDataItem :: CmmLit -> SDoc
pprDataItem :: CmmLit -> SDoc
pprDataItem CmmLit
lit
  = (DynFlags -> SDoc) -> SDoc
sdocWithDynFlags ((DynFlags -> SDoc) -> SDoc) -> (DynFlags -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \DynFlags
dflags ->
    [SDoc] -> SDoc
vcat (Format -> CmmLit -> [SDoc]
ppr_item (CmmType -> Format
cmmTypeFormat (CmmType -> Format) -> CmmType -> Format
forall a b. (a -> b) -> a -> b
$ DynFlags -> CmmLit -> CmmType
cmmLitType DynFlags
dflags CmmLit
lit) CmmLit
lit)
    where
        imm :: Imm
imm = CmmLit -> Imm
litToImm CmmLit
lit

        ppr_item :: Format -> CmmLit -> [SDoc]
ppr_item Format
II8   CmmLit
_        = [String -> SDoc
text String
"\t.byte\t" SDoc -> SDoc -> SDoc
<> Imm -> SDoc
pprImm Imm
imm]
        ppr_item Format
II32  CmmLit
_        = [String -> SDoc
text String
"\t.long\t" SDoc -> SDoc -> SDoc
<> Imm -> SDoc
pprImm Imm
imm]

        ppr_item Format
FF32  (CmmFloat Rational
r Width
_)
         = let bs :: [Int]
bs = Float -> [Int]
floatToBytes (Rational -> Float
forall a. Fractional a => Rational -> a
fromRational Rational
r)
           in  (Int -> SDoc) -> [Int] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (\Int
b -> String -> SDoc
text String
"\t.byte\t" SDoc -> SDoc -> SDoc
<> Imm -> SDoc
pprImm (Int -> Imm
ImmInt Int
b)) [Int]
bs

        ppr_item Format
FF64 (CmmFloat Rational
r Width
_)
         = let bs :: [Int]
bs = Double -> [Int]
doubleToBytes (Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
r)
           in  (Int -> SDoc) -> [Int] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (\Int
b -> String -> SDoc
text String
"\t.byte\t" SDoc -> SDoc -> SDoc
<> Imm -> SDoc
pprImm (Int -> Imm
ImmInt Int
b)) [Int]
bs

        ppr_item Format
II16  CmmLit
_        = [String -> SDoc
text String
"\t.short\t" SDoc -> SDoc -> SDoc
<> Imm -> SDoc
pprImm Imm
imm]
        ppr_item Format
II64  CmmLit
_        = [String -> SDoc
text String
"\t.quad\t" SDoc -> SDoc -> SDoc
<> Imm -> SDoc
pprImm Imm
imm]
        ppr_item Format
_ CmmLit
_            = String -> [SDoc]
forall a. String -> a
panic String
"SPARC.Ppr.pprDataItem: no match"


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

-- nuke comments.
pprInstr :: Instr -> SDoc
pprInstr (COMMENT FastString
_)
        = SDoc
empty

pprInstr (DELTA Int
d)
        = Instr -> SDoc
pprInstr (FastString -> Instr
COMMENT (String -> FastString
mkFastString (String
"\tdelta = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
d)))

-- Newblocks and LData should have been slurped out before producing the .s file.
pprInstr (NEWBLOCK BlockId
_)
        = String -> SDoc
forall a. String -> a
panic String
"X86.Ppr.pprInstr: NEWBLOCK"

pprInstr (LDATA Section
_ CmmStatics
_)
        = String -> SDoc
forall a. String -> a
panic String
"PprMach.pprInstr: LDATA"

-- 64 bit FP loads are expanded into individual instructions in CodeGen.Expand
pprInstr (LD Format
FF64 AddrMode
_ Reg
reg)
        | RegReal (RealRegSingle{})     <- Reg
reg
        = String -> SDoc
forall a. String -> a
panic String
"SPARC.Ppr: not emitting potentially misaligned LD FF64 instr"

pprInstr (LD Format
format AddrMode
addr Reg
reg)
        = [SDoc] -> SDoc
hcat [
               String -> SDoc
text String
"\tld",
               Format -> SDoc
pprFormat Format
format,
               Char -> SDoc
char Char
'\t',
               SDoc
lbrack,
               AddrMode -> SDoc
pprAddr AddrMode
addr,
               SDoc
pp_rbracket_comma,
               Reg -> SDoc
pprReg Reg
reg
            ]

-- 64 bit FP stores are expanded into individual instructions in CodeGen.Expand
pprInstr (ST Format
FF64 Reg
reg AddrMode
_)
        | RegReal (RealRegSingle{}) <- Reg
reg
        = String -> SDoc
forall a. String -> a
panic String
"SPARC.Ppr: not emitting potentially misaligned ST FF64 instr"

-- 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),
-- so we call a special-purpose pprFormat for ST..
pprInstr (ST Format
format Reg
reg AddrMode
addr)
        = [SDoc] -> SDoc
hcat [
               String -> SDoc
text String
"\tst",
               Format -> SDoc
pprStFormat Format
format,
               Char -> SDoc
char Char
'\t',
               Reg -> SDoc
pprReg Reg
reg,
               SDoc
pp_comma_lbracket,
               AddrMode -> SDoc
pprAddr AddrMode
addr,
               SDoc
rbrack
            ]


pprInstr (ADD Bool
x Bool
cc Reg
reg1 RI
ri Reg
reg2)
        | Bool -> Bool
not Bool
x Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
cc Bool -> Bool -> Bool
&& RI -> Bool
riZero RI
ri
        = [SDoc] -> SDoc
hcat [ String -> SDoc
text String
"\tmov\t", Reg -> SDoc
pprReg Reg
reg1, SDoc
comma, Reg -> SDoc
pprReg Reg
reg2 ]

        | Bool
otherwise
        = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (if Bool
x then String -> PtrString
sLit String
"addx" else String -> PtrString
sLit String
"add") Bool
cc Reg
reg1 RI
ri Reg
reg2


pprInstr (SUB Bool
x Bool
cc Reg
reg1 RI
ri Reg
reg2)
        | Bool -> Bool
not Bool
x Bool -> Bool -> Bool
&& Bool
cc Bool -> Bool -> Bool
&& Reg
reg2 Reg -> Reg -> Bool
forall a. Eq a => a -> a -> Bool
== Reg
g0
        = [SDoc] -> SDoc
hcat [ String -> SDoc
text String
"\tcmp\t", Reg -> SDoc
pprReg Reg
reg1, SDoc
comma, RI -> SDoc
pprRI RI
ri ]

        | Bool -> Bool
not Bool
x Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
cc Bool -> Bool -> Bool
&& RI -> Bool
riZero RI
ri
        = [SDoc] -> SDoc
hcat [ String -> SDoc
text String
"\tmov\t", Reg -> SDoc
pprReg Reg
reg1, SDoc
comma, Reg -> SDoc
pprReg Reg
reg2 ]

        | Bool
otherwise
        = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (if Bool
x then String -> PtrString
sLit String
"subx" else String -> PtrString
sLit String
"sub") Bool
cc Reg
reg1 RI
ri Reg
reg2

pprInstr (AND  Bool
b Reg
reg1 RI
ri Reg
reg2) = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"and")  Bool
b Reg
reg1 RI
ri Reg
reg2

pprInstr (ANDN Bool
b Reg
reg1 RI
ri Reg
reg2) = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"andn") Bool
b Reg
reg1 RI
ri Reg
reg2

pprInstr (OR Bool
b Reg
reg1 RI
ri Reg
reg2)
        | Bool -> Bool
not Bool
b Bool -> Bool -> Bool
&& Reg
reg1 Reg -> Reg -> Bool
forall a. Eq a => a -> a -> Bool
== Reg
g0
        = let doit :: SDoc
doit = [SDoc] -> SDoc
hcat [ String -> SDoc
text String
"\tmov\t", RI -> SDoc
pprRI RI
ri, SDoc
comma, Reg -> SDoc
pprReg Reg
reg2 ]
          in  case RI
ri of
                   RIReg Reg
rrr | Reg
rrr Reg -> Reg -> Bool
forall a. Eq a => a -> a -> Bool
== Reg
reg2 -> SDoc
empty
                   RI
_                       -> SDoc
doit

        | Bool
otherwise
        = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"or") Bool
b Reg
reg1 RI
ri Reg
reg2

pprInstr (ORN Bool
b Reg
reg1 RI
ri Reg
reg2)  = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"orn") Bool
b Reg
reg1 RI
ri Reg
reg2

pprInstr (XOR  Bool
b Reg
reg1 RI
ri Reg
reg2) = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"xor")  Bool
b Reg
reg1 RI
ri Reg
reg2
pprInstr (XNOR Bool
b Reg
reg1 RI
ri Reg
reg2) = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"xnor") Bool
b Reg
reg1 RI
ri Reg
reg2

pprInstr (SLL Reg
reg1 RI
ri Reg
reg2)    = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"sll") Bool
False Reg
reg1 RI
ri Reg
reg2
pprInstr (SRL Reg
reg1 RI
ri Reg
reg2)    = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"srl") Bool
False Reg
reg1 RI
ri Reg
reg2
pprInstr (SRA Reg
reg1 RI
ri Reg
reg2)    = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"sra") Bool
False Reg
reg1 RI
ri Reg
reg2

pprInstr (RDY Reg
rd)              = String -> SDoc
text String
"\trd\t%y," SDoc -> SDoc -> SDoc
<> Reg -> SDoc
pprReg Reg
rd
pprInstr (WRY Reg
reg1 Reg
reg2)
        = String -> SDoc
text String
"\twr\t"
                SDoc -> SDoc -> SDoc
<> Reg -> SDoc
pprReg Reg
reg1
                SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
','
                SDoc -> SDoc -> SDoc
<> Reg -> SDoc
pprReg Reg
reg2
                SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
','
                SDoc -> SDoc -> SDoc
<> String -> SDoc
text String
"%y"

pprInstr (SMUL Bool
b Reg
reg1 RI
ri Reg
reg2) = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"smul")  Bool
b Reg
reg1 RI
ri Reg
reg2
pprInstr (UMUL Bool
b Reg
reg1 RI
ri Reg
reg2) = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"umul")  Bool
b Reg
reg1 RI
ri Reg
reg2
pprInstr (SDIV Bool
b Reg
reg1 RI
ri Reg
reg2) = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"sdiv")  Bool
b Reg
reg1 RI
ri Reg
reg2
pprInstr (UDIV Bool
b Reg
reg1 RI
ri Reg
reg2) = PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg (String -> PtrString
sLit String
"udiv")  Bool
b Reg
reg1 RI
ri Reg
reg2

pprInstr (SETHI Imm
imm Reg
reg)
  = [SDoc] -> SDoc
hcat [
        String -> SDoc
text String
"\tsethi\t",
        Imm -> SDoc
pprImm Imm
imm,
        SDoc
comma,
        Reg -> SDoc
pprReg Reg
reg
    ]

pprInstr Instr
NOP
        = String -> SDoc
text String
"\tnop"

pprInstr (FABS Format
format Reg
reg1 Reg
reg2)
        = PtrString -> Format -> Reg -> Reg -> SDoc
pprFormatRegReg (String -> PtrString
sLit String
"fabs") Format
format Reg
reg1 Reg
reg2

pprInstr (FADD Format
format Reg
reg1 Reg
reg2 Reg
reg3)
        = PtrString -> Format -> Reg -> Reg -> Reg -> SDoc
pprFormatRegRegReg (String -> PtrString
sLit String
"fadd") Format
format Reg
reg1 Reg
reg2 Reg
reg3

pprInstr (FCMP Bool
e Format
format Reg
reg1 Reg
reg2)
        = PtrString -> Format -> Reg -> Reg -> SDoc
pprFormatRegReg (if Bool
e then String -> PtrString
sLit String
"fcmpe" else String -> PtrString
sLit String
"fcmp")
                          Format
format Reg
reg1 Reg
reg2

pprInstr (FDIV Format
format Reg
reg1 Reg
reg2 Reg
reg3)
        = PtrString -> Format -> Reg -> Reg -> Reg -> SDoc
pprFormatRegRegReg (String -> PtrString
sLit String
"fdiv") Format
format Reg
reg1 Reg
reg2 Reg
reg3

pprInstr (FMOV Format
format Reg
reg1 Reg
reg2)
        = PtrString -> Format -> Reg -> Reg -> SDoc
pprFormatRegReg (String -> PtrString
sLit String
"fmov") Format
format Reg
reg1 Reg
reg2

pprInstr (FMUL Format
format Reg
reg1 Reg
reg2 Reg
reg3)
        = PtrString -> Format -> Reg -> Reg -> Reg -> SDoc
pprFormatRegRegReg (String -> PtrString
sLit String
"fmul") Format
format Reg
reg1 Reg
reg2 Reg
reg3

pprInstr (FNEG Format
format Reg
reg1 Reg
reg2)
        = PtrString -> Format -> Reg -> Reg -> SDoc
pprFormatRegReg (String -> PtrString
sLit String
"fneg") Format
format Reg
reg1 Reg
reg2

pprInstr (FSQRT Format
format Reg
reg1 Reg
reg2)
        = PtrString -> Format -> Reg -> Reg -> SDoc
pprFormatRegReg (String -> PtrString
sLit String
"fsqrt") Format
format Reg
reg1 Reg
reg2

pprInstr (FSUB Format
format Reg
reg1 Reg
reg2 Reg
reg3)
        = PtrString -> Format -> Reg -> Reg -> Reg -> SDoc
pprFormatRegRegReg (String -> PtrString
sLit String
"fsub") Format
format Reg
reg1 Reg
reg2 Reg
reg3

pprInstr (FxTOy Format
format1 Format
format2 Reg
reg1 Reg
reg2)
  = [SDoc] -> SDoc
hcat [
        String -> SDoc
text String
"\tf",
        PtrString -> SDoc
ptext
        (case Format
format1 of
            Format
II32  -> String -> PtrString
sLit String
"ito"
            Format
FF32  -> String -> PtrString
sLit String
"sto"
            Format
FF64  -> String -> PtrString
sLit String
"dto"
            Format
_     -> String -> PtrString
forall a. String -> a
panic String
"SPARC.Ppr.pprInstr.FxToY: no match"),
        PtrString -> SDoc
ptext
        (case Format
format2 of
            Format
II32  -> String -> PtrString
sLit String
"i\t"
            Format
II64  -> String -> PtrString
sLit String
"x\t"
            Format
FF32  -> String -> PtrString
sLit String
"s\t"
            Format
FF64  -> String -> PtrString
sLit String
"d\t"
            Format
_     -> String -> PtrString
forall a. String -> a
panic String
"SPARC.Ppr.pprInstr.FxToY: no match"),
        Reg -> SDoc
pprReg Reg
reg1, SDoc
comma, Reg -> SDoc
pprReg Reg
reg2
    ]


pprInstr (BI Cond
cond Bool
b BlockId
blockid)
  = [SDoc] -> SDoc
hcat [
        String -> SDoc
text String
"\tb", Cond -> SDoc
pprCond Cond
cond,
        if Bool
b then SDoc
pp_comma_a else SDoc
empty,
        Char -> SDoc
char Char
'\t',
        CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (BlockId -> CLabel
blockLbl BlockId
blockid)
    ]

pprInstr (BF Cond
cond Bool
b BlockId
blockid)
  = [SDoc] -> SDoc
hcat [
        String -> SDoc
text String
"\tfb", Cond -> SDoc
pprCond Cond
cond,
        if Bool
b then SDoc
pp_comma_a else SDoc
empty,
        Char -> SDoc
char Char
'\t',
        CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (BlockId -> CLabel
blockLbl BlockId
blockid)
    ]

pprInstr (JMP AddrMode
addr) = String -> SDoc
text String
"\tjmp\t" SDoc -> SDoc -> SDoc
<> AddrMode -> SDoc
pprAddr AddrMode
addr
pprInstr (JMP_TBL AddrMode
op [Maybe BlockId]
_ CLabel
_)  = Instr -> SDoc
pprInstr (AddrMode -> Instr
JMP AddrMode
op)

pprInstr (CALL (Left Imm
imm) Int
n Bool
_)
  = [SDoc] -> SDoc
hcat [ String -> SDoc
text String
"\tcall\t", Imm -> SDoc
pprImm Imm
imm, SDoc
comma, Int -> SDoc
int Int
n ]

pprInstr (CALL (Right Reg
reg) Int
n Bool
_)
  = [SDoc] -> SDoc
hcat [ String -> SDoc
text String
"\tcall\t", Reg -> SDoc
pprReg Reg
reg, SDoc
comma, Int -> SDoc
int Int
n ]


-- | Pretty print a RI
pprRI :: RI -> SDoc
pprRI :: RI -> SDoc
pprRI (RIReg Reg
r) = Reg -> SDoc
pprReg Reg
r
pprRI (RIImm Imm
r) = Imm -> SDoc
pprImm Imm
r


-- | Pretty print a two reg instruction.
pprFormatRegReg :: PtrString -> Format -> Reg -> Reg -> SDoc
pprFormatRegReg :: PtrString -> Format -> Reg -> Reg -> SDoc
pprFormatRegReg PtrString
name Format
format Reg
reg1 Reg
reg2
  = [SDoc] -> SDoc
hcat [
        Char -> SDoc
char Char
'\t',
        PtrString -> SDoc
ptext PtrString
name,
        (case Format
format of
            Format
FF32 -> String -> SDoc
text String
"s\t"
            Format
FF64 -> String -> SDoc
text String
"d\t"
            Format
_    -> String -> SDoc
forall a. String -> a
panic String
"SPARC.Ppr.pprFormatRegReg: no match"),

        Reg -> SDoc
pprReg Reg
reg1,
        SDoc
comma,
        Reg -> SDoc
pprReg Reg
reg2
    ]


-- | Pretty print a three reg instruction.
pprFormatRegRegReg :: PtrString -> Format -> Reg -> Reg -> Reg -> SDoc
pprFormatRegRegReg :: PtrString -> Format -> Reg -> Reg -> Reg -> SDoc
pprFormatRegRegReg PtrString
name Format
format Reg
reg1 Reg
reg2 Reg
reg3
  = [SDoc] -> SDoc
hcat [
        Char -> SDoc
char Char
'\t',
        PtrString -> SDoc
ptext PtrString
name,
        (case Format
format of
            Format
FF32  -> String -> SDoc
text String
"s\t"
            Format
FF64  -> String -> SDoc
text String
"d\t"
            Format
_    -> String -> SDoc
forall a. String -> a
panic String
"SPARC.Ppr.pprFormatRegReg: no match"),
        Reg -> SDoc
pprReg Reg
reg1,
        SDoc
comma,
        Reg -> SDoc
pprReg Reg
reg2,
        SDoc
comma,
        Reg -> SDoc
pprReg Reg
reg3
    ]


-- | Pretty print an instruction of two regs and a ri.
pprRegRIReg :: PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg :: PtrString -> Bool -> Reg -> RI -> Reg -> SDoc
pprRegRIReg PtrString
name Bool
b Reg
reg1 RI
ri Reg
reg2
  = [SDoc] -> SDoc
hcat [
        Char -> SDoc
char Char
'\t',
        PtrString -> SDoc
ptext PtrString
name,
        if Bool
b then String -> SDoc
text String
"cc\t" else Char -> SDoc
char Char
'\t',
        Reg -> SDoc
pprReg Reg
reg1,
        SDoc
comma,
        RI -> SDoc
pprRI RI
ri,
        SDoc
comma,
        Reg -> SDoc
pprReg Reg
reg2
    ]

{-
pprRIReg :: PtrString -> Bool -> RI -> Reg -> SDoc
pprRIReg name b ri reg1
  = hcat [
        char '\t',
        ptext name,
        if b then text "cc\t" else char '\t',
        pprRI ri,
        comma,
        pprReg reg1
    ]
-}

{-
pp_ld_lbracket :: SDoc
pp_ld_lbracket    = text "\tld\t["
-}

pp_rbracket_comma :: SDoc
pp_rbracket_comma :: SDoc
pp_rbracket_comma = String -> SDoc
text String
"],"


pp_comma_lbracket :: SDoc
pp_comma_lbracket :: SDoc
pp_comma_lbracket = String -> SDoc
text String
",["


pp_comma_a :: SDoc
pp_comma_a :: SDoc
pp_comma_a        = String -> SDoc
text String
",a"