{-# LANGUAGE LambdaCase #-}

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

module GHC.CmmToAsm.PPC.Ppr
   ( pprNatCmmDecl
   , pprInstr
   )
where

import GHC.Prelude

import GHC.CmmToAsm.PPC.Regs
import GHC.CmmToAsm.PPC.Instr
import GHC.CmmToAsm.PPC.Cond
import GHC.CmmToAsm.Ppr
import GHC.CmmToAsm.Format
import GHC.Platform.Reg
import GHC.Platform.Reg.Class
import GHC.CmmToAsm.Reg.Target
import GHC.CmmToAsm.Config
import GHC.CmmToAsm.Types
import GHC.CmmToAsm.Utils

import GHC.Cmm hiding (topInfoTable)
import GHC.Cmm.Dataflow.Collections
import GHC.Cmm.Dataflow.Label

import GHC.Cmm.BlockId
import GHC.Cmm.CLabel

import GHC.Types.Unique ( pprUniqueAlways, getUnique )
import GHC.Platform
import GHC.Utils.Outputable
import GHC.Utils.Panic

import Data.Word
import Data.Int

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

pprNatCmmDecl :: IsDoc doc => NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc
pprNatCmmDecl :: forall doc.
IsDoc doc =>
NCGConfig -> NatCmmDecl RawCmmStatics Instr -> doc
pprNatCmmDecl NCGConfig
config (CmmData Section
section RawCmmStatics
dats) =
  NCGConfig -> Section -> doc
forall doc. IsDoc doc => NCGConfig -> Section -> doc
pprSectionAlign NCGConfig
config Section
section
  doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Platform -> RawCmmStatics -> doc
forall doc. IsDoc doc => Platform -> RawCmmStatics -> doc
pprDatas (NCGConfig -> Platform
ncgPlatform NCGConfig
config) RawCmmStatics
dats

pprNatCmmDecl NCGConfig
config proc :: NatCmmDecl RawCmmStatics Instr
proc@(CmmProc LabelMap RawCmmStatics
top_info CLabel
lbl [GlobalReg]
_ (ListGraph [GenBasicBlock Instr]
blocks)) =
  let platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config in
  case NatCmmDecl RawCmmStatics Instr -> Maybe RawCmmStatics
forall a i b. GenCmmDecl a (LabelMap i) (ListGraph b) -> Maybe i
topInfoTable NatCmmDecl RawCmmStatics Instr
proc of
    Maybe RawCmmStatics
Nothing ->
         -- special case for code without info table:
         NCGConfig -> Section -> doc
forall doc. IsDoc doc => NCGConfig -> Section -> doc
pprSectionAlign NCGConfig
config (SectionType -> CLabel -> Section
Section SectionType
Text CLabel
lbl) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
         (case Platform -> Arch
platformArch Platform
platform of
            ArchPPC_64 PPC_64ABI
ELF_V1 -> Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprFunctionDescriptor Platform
platform CLabel
lbl
            ArchPPC_64 PPC_64ABI
ELF_V2 -> Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprFunctionPrologue Platform
platform CLabel
lbl
            Arch
_ -> Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprLabel Platform
platform CLabel
lbl) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$ -- blocks guaranteed not null,
                                           -- so label needed
         [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat ((GenBasicBlock Instr -> doc) -> [GenBasicBlock Instr] -> [doc]
forall a b. (a -> b) -> [a] -> [b]
map (NCGConfig -> LabelMap RawCmmStatics -> GenBasicBlock Instr -> doc
forall doc.
IsDoc doc =>
NCGConfig -> LabelMap RawCmmStatics -> GenBasicBlock Instr -> doc
pprBasicBlock NCGConfig
config LabelMap RawCmmStatics
top_info) [GenBasicBlock Instr]
blocks) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
         Bool -> doc -> doc
forall doc. IsOutput doc => Bool -> doc -> doc
ppWhen (NCGConfig -> Bool
ncgDwarfEnabled NCGConfig
config) (Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkAsmTempEndLabel CLabel
lbl)
                                                Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
':') doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
                                          Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprProcEndLabel Platform
platform CLabel
lbl)) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
         Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprSizeDecl Platform
platform CLabel
lbl

    Just (CmmStaticsRaw CLabel
info_lbl [CmmStatic]
_) ->
      NCGConfig -> Section -> doc
forall doc. IsDoc doc => NCGConfig -> Section -> doc
pprSectionAlign NCGConfig
config (SectionType -> CLabel -> Section
Section SectionType
Text CLabel
info_lbl) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
      (if Platform -> Bool
platformHasSubsectionsViaSymbols Platform
platform
          then Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkDeadStripPreventer CLabel
info_lbl) Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
':')
          else doc
forall doc. IsOutput doc => doc
empty) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
      [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat ((GenBasicBlock Instr -> doc) -> [GenBasicBlock Instr] -> [doc]
forall a b. (a -> b) -> [a] -> [b]
map (NCGConfig -> LabelMap RawCmmStatics -> GenBasicBlock Instr -> doc
forall doc.
IsDoc doc =>
NCGConfig -> LabelMap RawCmmStatics -> GenBasicBlock Instr -> doc
pprBasicBlock NCGConfig
config LabelMap RawCmmStatics
top_info) [GenBasicBlock Instr]
blocks) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
      -- 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
                Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.long "
                      Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
info_lbl
                      Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'-'
                      Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkDeadStripPreventer CLabel
info_lbl))
       else doc
forall doc. IsOutput doc => doc
empty) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
      Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprSizeDecl Platform
platform CLabel
info_lbl
{-# SPECIALIZE pprNatCmmDecl :: NCGConfig -> NatCmmDecl RawCmmStatics Instr -> SDoc #-}
{-# SPECIALIZE pprNatCmmDecl :: NCGConfig -> NatCmmDecl RawCmmStatics Instr -> HDoc #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable

-- | Output the ELF .size directive.
pprSizeDecl :: IsDoc doc => Platform -> CLabel -> doc
pprSizeDecl :: forall doc. IsDoc doc => Platform -> CLabel -> doc
pprSizeDecl Platform
platform CLabel
lbl
 = if OS -> Bool
osElfTarget (Platform -> OS
platformOS Platform
platform)
   then Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.size" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Line doc
prettyLbl Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", .-" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Line doc
codeLbl)
   else doc
forall doc. IsOutput doc => doc
empty
  where
    prettyLbl :: Line doc
prettyLbl = Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
    codeLbl :: Line doc
codeLbl
      | Platform -> Arch
platformArch Platform
platform Arch -> Arch -> Bool
forall a. Eq a => a -> a -> Bool
== PPC_64ABI -> Arch
ArchPPC_64 PPC_64ABI
ELF_V1 = Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'.' Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Line doc
prettyLbl
      | Bool
otherwise                                  = Line doc
prettyLbl

pprFunctionDescriptor :: IsDoc doc => Platform -> CLabel -> doc
pprFunctionDescriptor :: forall doc. IsDoc doc => Platform -> CLabel -> doc
pprFunctionDescriptor Platform
platform CLabel
lab =
  [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat [Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl Platform
platform CLabel
lab,
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.section \".opd\", \"aw\""),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.align 3"),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
':'),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.quad ."
              Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<>  Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab
              Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<>  String -> Line doc
forall doc. IsLine doc => String -> doc
text String
",.TOC.@tocbase,0"),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.previous"),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.type"
              Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab
              Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<>  String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", @function"),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'.' Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
':')]

pprFunctionPrologue :: IsDoc doc => Platform -> CLabel -> doc
pprFunctionPrologue :: forall doc. IsDoc doc => Platform -> CLabel -> doc
pprFunctionPrologue Platform
platform CLabel
lab =
  [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat [Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl Platform
platform CLabel
lab,
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".type " Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", @function"),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
':'),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"0:\taddis\t" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
toc Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
",12,.TOC.-0b@ha"),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\taddi\t" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
toc Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
',' Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
toc Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
",.TOC.-0b@l"),
        Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.localentry\t" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<>
              String -> Line doc
forall doc. IsLine doc => String -> doc
text String
",.-" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab)]

pprProcEndLabel :: IsLine doc => Platform -> CLabel -- ^ Procedure name
                -> doc
pprProcEndLabel :: forall doc. IsLine doc => Platform -> CLabel -> doc
pprProcEndLabel Platform
platform CLabel
lbl =
    Platform -> CLabel -> doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkAsmTempProcEndLabel CLabel
lbl) doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
':'

pprBasicBlock :: IsDoc doc => NCGConfig -> LabelMap RawCmmStatics -> NatBasicBlock Instr
              -> doc
pprBasicBlock :: forall doc.
IsDoc doc =>
NCGConfig -> LabelMap RawCmmStatics -> GenBasicBlock Instr -> doc
pprBasicBlock NCGConfig
config LabelMap RawCmmStatics
info_env (BasicBlock BlockId
blockid [Instr]
instrs)
  = doc
maybe_infotable doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
    Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprLabel Platform
platform CLabel
asmLbl doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
    [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat ((Instr -> doc) -> [Instr] -> [doc]
forall a b. (a -> b) -> [a] -> [b]
map (Platform -> Instr -> doc
forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform) [Instr]
instrs) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
    Bool -> doc -> doc
forall doc. IsOutput doc => Bool -> doc -> doc
ppWhen (NCGConfig -> Bool
ncgDwarfEnabled NCGConfig
config) (
      Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkAsmTempEndLabel CLabel
asmLbl) Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
':'
            Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprProcEndLabel Platform
platform CLabel
asmLbl)
    )
  where
    asmLbl :: CLabel
asmLbl = BlockId -> CLabel
blockLbl BlockId
blockid
    platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
    maybe_infotable :: doc
maybe_infotable = case KeyOf LabelMap -> LabelMap RawCmmStatics -> Maybe RawCmmStatics
forall a. KeyOf LabelMap -> LabelMap a -> Maybe a
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup KeyOf LabelMap
BlockId
blockid LabelMap RawCmmStatics
info_env of
       Maybe RawCmmStatics
Nothing   -> doc
forall doc. IsOutput doc => doc
empty
       Just (CmmStaticsRaw CLabel
info_lbl [CmmStatic]
info) ->
           Platform -> SectionType -> doc
forall doc. IsDoc doc => Platform -> SectionType -> doc
pprAlignForSection Platform
platform SectionType
Text doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
           [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat ((CmmStatic -> doc) -> [CmmStatic] -> [doc]
forall a b. (a -> b) -> [a] -> [b]
map (Platform -> CmmStatic -> doc
forall doc. IsDoc doc => Platform -> CmmStatic -> doc
pprData Platform
platform) [CmmStatic]
info) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
           Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprLabel Platform
platform CLabel
info_lbl



pprDatas :: IsDoc doc => Platform -> RawCmmStatics -> doc
-- See Note [emit-time elimination of static indirections] in "GHC.Cmm.CLabel".
pprDatas :: forall doc. IsDoc doc => Platform -> RawCmmStatics -> doc
pprDatas Platform
platform (CmmStaticsRaw 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'
  = Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl Platform
platform CLabel
alias
    doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".equiv" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
alias Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Line doc
forall doc. IsLine doc => doc
comma Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
ind')
pprDatas Platform
platform (CmmStaticsRaw CLabel
lbl [CmmStatic]
dats) = [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat (Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprLabel Platform
platform CLabel
lbl doc -> [doc] -> [doc]
forall a. a -> [a] -> [a]
: (CmmStatic -> doc) -> [CmmStatic] -> [doc]
forall a b. (a -> b) -> [a] -> [b]
map (Platform -> CmmStatic -> doc
forall doc. IsDoc doc => Platform -> CmmStatic -> doc
pprData Platform
platform) [CmmStatic]
dats)

pprData :: IsDoc doc => Platform -> CmmStatic -> doc
pprData :: forall doc. IsDoc doc => Platform -> CmmStatic -> doc
pprData Platform
platform CmmStatic
d = case CmmStatic
d of
   CmmString ByteString
str          -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (ByteString -> Line doc
forall doc. IsLine doc => ByteString -> doc
pprString ByteString
str)
   CmmFileEmbed String
path Int
_    -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
pprFileEmbed String
path)
   CmmUninitialised Int
bytes -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".space " Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
bytes)
   CmmStaticLit CmmLit
lit       -> Platform -> CmmLit -> doc
forall doc. IsDoc doc => Platform -> CmmLit -> doc
pprDataItem Platform
platform CmmLit
lit

pprGloblDecl :: IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl :: forall doc. IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl Platform
platform CLabel
lbl
  | Bool -> Bool
not (CLabel -> Bool
externallyVisibleCLabel CLabel
lbl) = doc
forall doc. IsOutput doc => doc
empty
  | Bool
otherwise = Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".globl " Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl)

pprTypeAndSizeDecl :: IsLine doc => Platform -> CLabel -> doc
pprTypeAndSizeDecl :: forall doc. IsLine doc => Platform -> CLabel -> doc
pprTypeAndSizeDecl Platform
platform CLabel
lbl
  = 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 -> doc
forall doc. IsLine doc => String -> doc
text String
".type " doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<>
         Platform -> CLabel -> doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> doc
forall doc. IsLine doc => String -> doc
text String
", @object"
    else doc
forall doc. IsOutput doc => doc
empty

pprLabel :: IsDoc doc => Platform -> CLabel -> doc
pprLabel :: forall doc. IsDoc doc => Platform -> CLabel -> doc
pprLabel Platform
platform CLabel
lbl =
   Platform -> CLabel -> doc
forall doc. IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl Platform
platform CLabel
lbl
   doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprTypeAndSizeDecl Platform
platform CLabel
lbl)
   doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$ Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
':')

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

pprReg :: forall doc. IsLine doc => Reg -> doc

pprReg :: forall doc. IsLine doc => Reg -> doc
pprReg Reg
r
  = case Reg
r of
      RegReal    (RealRegSingle Int
i) -> Int -> doc
ppr_reg_no Int
i
      RegVirtual (VirtualRegI  Unique
u)  -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"%vI_"   doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
u
      RegVirtual (VirtualRegHi Unique
u)  -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"%vHi_"  doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
u
      RegVirtual (VirtualRegF  Unique
u)  -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"%vF_"   doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
u
      RegVirtual (VirtualRegD  Unique
u)  -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"%vD_"   doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
u

  where
    ppr_reg_no :: Int -> doc
    ppr_reg_no :: Int -> doc
ppr_reg_no Int
i
         | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
31   = Int -> doc
forall doc. IsLine doc => Int -> doc
int Int
i      -- GPRs
         | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
63   = Int -> doc
forall doc. IsLine doc => Int -> doc
int (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
32) -- FPRs
         | Bool
otherwise = String -> doc
forall doc. IsLine doc => String -> doc
text String
"very naughty powerpc register"



pprFormat :: IsLine doc => Format -> doc
pprFormat :: forall doc. IsLine doc => Format -> doc
pprFormat Format
x
 = case Format
x of
                Format
II8  -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"b"
                Format
II16 -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"h"
                Format
II32 -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"w"
                Format
II64 -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"d"
                Format
FF32 -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"fs"
                Format
FF64 -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"fd"


pprCond :: IsLine doc => Cond -> doc
pprCond :: forall doc. IsLine doc => Cond -> doc
pprCond Cond
c
 = case Cond
c of {
                Cond
ALWAYS  -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"";
                Cond
EQQ     -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"eq";  Cond
NE    -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"ne";
                Cond
LTT     -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"lt";  Cond
GE    -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"ge";
                Cond
GTT     -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"gt";  Cond
LE    -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"le";
                Cond
LU      -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"lt";  Cond
GEU   -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"ge";
                Cond
GU      -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"gt";  Cond
LEU   -> String -> doc
forall doc. IsLine doc => String -> doc
text String
"le"; }


pprImm :: IsLine doc => Platform -> Imm -> doc
pprImm :: forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform = \case
   ImmInt Int
i       -> Int -> doc
forall doc. IsLine doc => Int -> doc
int Int
i
   ImmInteger Integer
i   -> Integer -> doc
forall doc. IsLine doc => Integer -> doc
integer Integer
i
   ImmCLbl CLabel
l      -> Platform -> CLabel -> doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
l
   ImmIndex CLabel
l Int
i   -> Platform -> CLabel -> doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
l doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'+' doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> doc
forall doc. IsLine doc => Int -> doc
int Int
i
   ImmLit FastString
s       -> FastString -> doc
forall doc. IsLine doc => FastString -> doc
ftext FastString
s
   ImmFloat Rational
f     -> Float -> doc
forall doc. IsLine doc => Float -> doc
float (Float -> doc) -> Float -> doc
forall a b. (a -> b) -> a -> b
$ Rational -> Float
forall a. Fractional a => Rational -> a
fromRational Rational
f
   ImmDouble Rational
d    -> Double -> doc
forall doc. IsLine doc => Double -> doc
double (Double -> doc) -> Double -> doc
forall a b. (a -> b) -> a -> b
$ Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
d
   ImmConstantSum Imm
a Imm
b   -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
a doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'+' doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
b
   ImmConstantDiff Imm
a Imm
b  -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
a doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'-' doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc
forall doc. IsLine doc => doc
lparen doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
b doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc
forall doc. IsLine doc => doc
rparen
   LO (ImmInt Int
i)        -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform (Imm -> Imm
LO (Integer -> Imm
ImmInteger (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
i)))
   LO (ImmInteger Integer
i)    -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform (Integer -> Imm
ImmInteger (Int16 -> Integer
forall a. Integral a => a -> Integer
toInteger Int16
lo16))
        where
          lo16 :: Int16
lo16 = Integer -> Int16
forall a. Num a => Integer -> a
fromInteger (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xffff) :: Int16

   LO Imm
i              -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
i doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> doc
forall doc. IsLine doc => String -> doc
text String
"@l"
   HI Imm
i              -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
i doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> doc
forall doc. IsLine doc => String -> doc
text String
"@h"
   HA (ImmInt Int
i)     -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform (Imm -> Imm
HA (Integer -> Imm
ImmInteger (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
i)))
   HA (ImmInteger Integer
i) -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform (Integer -> Imm
ImmInteger Integer
ha16)
        where
          ha16 :: Integer
ha16 = if Integer
lo16 Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0x8000 then Integer
hi16Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1 else Integer
hi16
          hi16 :: Integer
hi16 = (Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
16)
          lo16 :: Integer
lo16 = Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
0xffff

   HA Imm
i        -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
i doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> doc
forall doc. IsLine doc => String -> doc
text String
"@ha"
   HIGHERA Imm
i   -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
i doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> doc
forall doc. IsLine doc => String -> doc
text String
"@highera"
   HIGHESTA Imm
i  -> Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
i doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> doc
forall doc. IsLine doc => String -> doc
text String
"@highesta"


pprAddr :: IsLine doc => Platform -> AddrMode -> doc
pprAddr :: forall doc. IsLine doc => Platform -> AddrMode -> doc
pprAddr Platform
platform = \case
   AddrRegReg Reg
r1 Reg
r2             -> Reg -> doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
r1 doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
',' doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Reg -> doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
r2
   AddrRegImm Reg
r1 (ImmInt Int
i)     -> [doc] -> doc
forall doc. IsLine doc => [doc] -> doc
hcat [ Int -> doc
forall doc. IsLine doc => Int -> doc
int Int
i, Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'(', Reg -> doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
r1, Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
')' ]
   AddrRegImm Reg
r1 (ImmInteger Integer
i) -> [doc] -> doc
forall doc. IsLine doc => [doc] -> doc
hcat [ Integer -> doc
forall doc. IsLine doc => Integer -> doc
integer Integer
i, Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'(', Reg -> doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
r1, Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
')' ]
   AddrRegImm Reg
r1 Imm
imm            -> [doc] -> doc
forall doc. IsLine doc => [doc] -> doc
hcat [ Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm, Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'(', Reg -> doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
r1, Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
')' ]


pprSectionAlign :: IsDoc doc => NCGConfig -> Section -> doc
pprSectionAlign :: forall doc. IsDoc doc => NCGConfig -> Section -> doc
pprSectionAlign NCGConfig
config sec :: Section
sec@(Section SectionType
seg CLabel
_) =
   Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (NCGConfig -> Section -> Line doc
forall doc. IsLine doc => NCGConfig -> Section -> doc
pprSectionHeader NCGConfig
config Section
sec) doc -> doc -> doc
forall doc. IsDoc doc => doc -> doc -> doc
$$
   Platform -> SectionType -> doc
forall doc. IsDoc doc => Platform -> SectionType -> doc
pprAlignForSection (NCGConfig -> Platform
ncgPlatform NCGConfig
config) SectionType
seg

-- | Print appropriate alignment for the given section type.
pprAlignForSection :: IsDoc doc => Platform -> SectionType -> doc
pprAlignForSection :: forall doc. IsDoc doc => Platform -> SectionType -> doc
pprAlignForSection Platform
platform SectionType
seg = Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$
 let ppc64 :: Bool
ppc64    = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Platform -> Bool
target32Bit Platform
platform
 in case SectionType
seg of
       SectionType
Text              -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 2"
       SectionType
Data
        | Bool
ppc64          -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 2"
       SectionType
ReadOnlyData
        | Bool
ppc64          -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 2"
       SectionType
RelocatableReadOnlyData
        | Bool
ppc64          -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 2"
       SectionType
UninitialisedData
        | Bool
ppc64          -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 2"
       -- TODO: This is copied from the ReadOnlyData case, but it can likely be
       -- made more efficient.
       SectionType
InitArray         -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 3"
       SectionType
FiniArray         -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 3"
       SectionType
CString
        | Bool
ppc64          -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
".align 2"
       OtherSection String
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PprMach.pprSectionAlign: unknown section"

pprDataItem :: IsDoc doc => Platform -> CmmLit -> doc
pprDataItem :: forall doc. IsDoc doc => Platform -> CmmLit -> doc
pprDataItem Platform
platform CmmLit
lit
  = [Line doc] -> doc
forall doc. IsDoc doc => [Line doc] -> doc
lines_ (Format -> CmmLit -> [Line doc]
ppr_item (CmmType -> Format
cmmTypeFormat (CmmType -> Format) -> CmmType -> Format
forall a b. (a -> b) -> a -> b
$ Platform -> CmmLit -> CmmType
cmmLitType Platform
platform CmmLit
lit) CmmLit
lit)
    where
        imm :: Imm
imm = CmmLit -> Imm
litToImm CmmLit
lit
        archPPC_64 :: Bool
archPPC_64 = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Platform -> Bool
target32Bit Platform
platform

        ppr_item :: Format -> CmmLit -> [Line doc]
ppr_item Format
II8  CmmLit
_ = [String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.byte\t"  Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm]
        ppr_item Format
II16 CmmLit
_ = [String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.short\t" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm]
        ppr_item Format
II32 CmmLit
_ = [String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.long\t"  Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm]
        ppr_item Format
II64 CmmLit
_
           | Bool
archPPC_64 = [String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.quad\t"  Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm]

        ppr_item Format
II64 (CmmInt Integer
x Width
_)
           | Bool -> Bool
not Bool
archPPC_64 =
                [String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.long\t"
                    Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> Line doc
forall doc. IsLine doc => Int -> doc
int (Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
                        (Integer -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
x Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
32) :: Word32)),
                 String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.long\t"
                    Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> Line doc
forall doc. IsLine doc => Int -> doc
int (Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
x :: Word32))]


        ppr_item Format
FF32 CmmLit
_ = [String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.float\t" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm]
        ppr_item Format
FF64 CmmLit
_ = [String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.double\t" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm]

        ppr_item Format
_ CmmLit
_
                = String -> [Line doc]
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprDataItem: no match"


asmComment :: IsLine doc => doc -> doc
asmComment :: forall doc. IsLine doc => doc -> doc
asmComment doc
c = doc -> doc
forall doc. IsOutput doc => doc -> doc
whenPprDebug (doc -> doc) -> doc -> doc
forall a b. (a -> b) -> a -> b
$ String -> doc
forall doc. IsLine doc => String -> doc
text String
"#" doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<+> doc
c


pprInstr :: IsDoc doc => Platform -> Instr -> doc
pprInstr :: forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform Instr
instr = case Instr
instr of

   COMMENT FastString
s
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> Line doc
forall doc. IsLine doc => doc -> doc
asmComment (FastString -> Line doc
forall doc. IsLine doc => FastString -> doc
ftext FastString
s))

   LOCATION Int
file Int
line' Int
col String
_name
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t.loc" Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
file Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
line' Line doc -> Line doc -> Line doc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
col)

   DELTA Int
d
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> Line doc
forall doc. IsLine doc => doc -> doc
asmComment (Line doc -> Line doc) -> Line doc -> Line doc
forall a b. (a -> b) -> a -> b
$ String -> Line doc
forall doc. IsLine doc => String -> doc
text (String
"\tdelta = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
d))

   NEWBLOCK BlockId
_
      -> String -> doc
forall a. HasCallStack => String -> a
panic String
"PprMach.pprInstr: NEWBLOCK"

   LDATA Section
_ RawCmmStatics
_
      -> String -> doc
forall a. HasCallStack => String -> a
panic String
"PprMach.pprInstr: LDATA"

{-
   SPILL reg slot
      -> hcat [
              text "\tSPILL",
           char '\t',
           pprReg reg,
           comma,
           text "SLOT" <> parens (int slot)]

   RELOAD slot reg
      -> hcat [
              text "\tRELOAD",
           char '\t',
           text "SLOT" <> parens (int slot),
           comma,
           pprReg reg]
-}

   LD Format
fmt Reg
reg AddrMode
addr
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"l",
           (case Format
fmt of
               Format
II8  -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"bz"
               Format
II16 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"hz"
               Format
II32 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"wz"
               Format
II64 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"d"
               Format
FF32 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fs"
               Format
FF64 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fd"
               ),
           case AddrMode
addr of AddrRegImm Reg
_ Imm
_ -> Line doc
forall doc. IsOutput doc => doc
empty
                        AddrRegReg Reg
_ Reg
_ -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'x',
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> AddrMode -> Line doc
forall doc. IsLine doc => Platform -> AddrMode -> doc
pprAddr Platform
platform AddrMode
addr
       ]

   LDFAR Format
fmt Reg
reg (AddrRegImm Reg
source Imm
off)
      -> [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat
            [ Platform -> Instr -> doc
forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform (Reg -> Reg -> Imm -> Instr
ADDIS (Platform -> Reg
tmpReg Platform
platform) Reg
source (Imm -> Imm
HA Imm
off))
            , Platform -> Instr -> doc
forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform (Format -> Reg -> AddrMode -> Instr
LD Format
fmt Reg
reg (Reg -> Imm -> AddrMode
AddrRegImm (Platform -> Reg
tmpReg Platform
platform) (Imm -> Imm
LO Imm
off)))
            ]

   LDFAR Format
_ Reg
_ AddrMode
_
      -> String -> doc
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr LDFAR: no match"

   LDR Format
fmt Reg
reg1 AddrMode
addr
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tl",
           case Format
fmt of
             Format
II32 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'w'
             Format
II64 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'd'
             Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.Instr LDR: no match",
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"arx\t",
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> AddrMode -> Line doc
forall doc. IsLine doc => Platform -> AddrMode -> doc
pprAddr Platform
platform AddrMode
addr
           ]

   LA Format
fmt Reg
reg AddrMode
addr
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"l",
           (case Format
fmt of
               Format
II8  -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"ba"
               Format
II16 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"ha"
               Format
II32 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"wa"
               Format
II64 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"d"
               Format
FF32 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fs"
               Format
FF64 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fd"
               ),
           case AddrMode
addr of AddrRegImm Reg
_ Imm
_ -> Line doc
forall doc. IsOutput doc => doc
empty
                        AddrRegReg Reg
_ Reg
_ -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'x',
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> AddrMode -> Line doc
forall doc. IsLine doc => Platform -> AddrMode -> doc
pprAddr Platform
platform AddrMode
addr
           ]

   ST Format
fmt Reg
reg AddrMode
addr
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"st",
           Format -> Line doc
forall doc. IsLine doc => Format -> doc
pprFormat Format
fmt,
           case AddrMode
addr of AddrRegImm Reg
_ Imm
_ -> Line doc
forall doc. IsOutput doc => doc
empty
                        AddrRegReg Reg
_ Reg
_ -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'x',
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> AddrMode -> Line doc
forall doc. IsLine doc => Platform -> AddrMode -> doc
pprAddr Platform
platform AddrMode
addr
           ]

   STFAR Format
fmt Reg
reg (AddrRegImm Reg
source Imm
off)
      -> [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat [ Platform -> Instr -> doc
forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform (Reg -> Reg -> Imm -> Instr
ADDIS (Platform -> Reg
tmpReg Platform
platform) Reg
source (Imm -> Imm
HA Imm
off))
              , Platform -> Instr -> doc
forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform (Format -> Reg -> AddrMode -> Instr
ST Format
fmt Reg
reg (Reg -> Imm -> AddrMode
AddrRegImm (Platform -> Reg
tmpReg Platform
platform) (Imm -> Imm
LO Imm
off)))
              ]

   STFAR Format
_ Reg
_ AddrMode
_
      -> String -> doc
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr STFAR: no match"

   STU Format
fmt Reg
reg AddrMode
addr
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"st",
           Format -> Line doc
forall doc. IsLine doc => Format -> doc
pprFormat Format
fmt,
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'u',
           case AddrMode
addr of AddrRegImm Reg
_ Imm
_ -> Line doc
forall doc. IsOutput doc => doc
empty
                        AddrRegReg Reg
_ Reg
_ -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'x',
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> AddrMode -> Line doc
forall doc. IsLine doc => Platform -> AddrMode -> doc
pprAddr Platform
platform AddrMode
addr
           ]

   STC Format
fmt Reg
reg1 AddrMode
addr
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tst",
           case Format
fmt of
             Format
II32 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'w'
             Format
II64 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'd'
             Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.Instr STC: no match",
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"cx.\t",
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> AddrMode -> Line doc
forall doc. IsLine doc => Platform -> AddrMode -> doc
pprAddr Platform
platform AddrMode
addr
           ]

   LIS Reg
reg Imm
imm
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"lis",
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm
           ]

   LI Reg
reg Imm
imm
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"li",
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm
           ]

   MR Reg
reg1 Reg
reg2
    | Reg
reg1 Reg -> Reg -> Bool
forall a. Eq a => a -> a -> Bool
== Reg
reg2 -> doc
forall doc. IsOutput doc => doc
empty
    | Bool
otherwise    -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        case Platform -> Reg -> RegClass
targetClassOfReg Platform
platform Reg
reg1 of
            RegClass
RcInteger -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"mr"
            RegClass
_ -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fmr",
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2
        ]

   CMP Format
fmt Reg
reg RI
ri
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Line doc
op,
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> RI -> Line doc
forall doc. IsLine doc => Platform -> RI -> doc
pprRI Platform
platform RI
ri
           ]
         where
           op :: Line doc
op = [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
                   String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"cmp",
                   Format -> Line doc
forall doc. IsLine doc => Format -> doc
pprFormat Format
fmt,
                   case RI
ri of
                       RIReg Reg
_ -> Line doc
forall doc. IsOutput doc => doc
empty
                       RIImm Imm
_ -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'i'
               ]

   CMPL Format
fmt Reg
reg RI
ri
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Line doc
op,
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> RI -> Line doc
forall doc. IsLine doc => Platform -> RI -> doc
pprRI Platform
platform RI
ri
           ]
          where
              op :: Line doc
op = [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
                      String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"cmpl",
                      Format -> Line doc
forall doc. IsLine doc => Format -> doc
pprFormat Format
fmt,
                      case RI
ri of
                          RIReg Reg
_ -> Line doc
forall doc. IsOutput doc => doc
empty
                          RIImm Imm
_ -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'i'
                  ]

   BCC Cond
cond BlockId
blockid Maybe Bool
prediction
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"b",
           Cond -> Line doc
forall doc. IsLine doc => Cond -> doc
pprCond Cond
cond,
           Maybe Bool -> Line doc
forall {doc}. IsLine doc => Maybe Bool -> doc
pprPrediction Maybe Bool
prediction,
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
           ]
         where lbl :: CLabel
lbl = Unique -> CLabel
mkLocalBlockLabel (BlockId -> Unique
forall a. Uniquable a => a -> Unique
getUnique BlockId
blockid)
               pprPrediction :: Maybe Bool -> doc
pprPrediction Maybe Bool
p = case Maybe Bool
p of
                 Maybe Bool
Nothing    -> doc
forall doc. IsOutput doc => doc
empty
                 Just Bool
True  -> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'+'
                 Just Bool
False -> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'-'

   BCCFAR Cond
cond BlockId
blockid Maybe Bool
prediction
      -> [Line doc] -> doc
forall doc. IsDoc doc => [Line doc] -> doc
lines_ [
           [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tb",
               Cond -> Line doc
forall doc. IsLine doc => Cond -> doc
pprCond (Cond -> Cond
condNegate Cond
cond),
               Line doc
neg_prediction,
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\t$+8"
           ],
           [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tb\t",
               Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
           ]
          ]
          where lbl :: CLabel
lbl = Unique -> CLabel
mkLocalBlockLabel (BlockId -> Unique
forall a. Uniquable a => a -> Unique
getUnique BlockId
blockid)
                neg_prediction :: Line doc
neg_prediction = case Maybe Bool
prediction of
                  Maybe Bool
Nothing    -> Line doc
forall doc. IsOutput doc => doc
empty
                  Just Bool
True  -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'-'
                  Just Bool
False -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'+'

   JMP CLabel
lbl [Reg]
_
     -- We never jump to ForeignLabels; if we ever do, c.f. handling for "BL"
     | CLabel -> Bool
isForeignLabel CLabel
lbl -> String -> doc
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr: JMP to ForeignLabel"
     | Bool
otherwise ->
       Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [ -- an alias for b that takes a CLabel
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tb\t",
           Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
       ]

   MTCTR Reg
reg
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"mtctr",
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg
        ]

   BCTR [Maybe BlockId]
_ Maybe CLabel
_ [Reg]
_
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"bctr"
         ]

   BL CLabel
lbl [Reg]
_
      -> case Platform -> OS
platformOS Platform
platform of
           OS
OSAIX ->
             -- On AIX, "printf" denotes a function-descriptor (for use
             -- by function pointers), whereas the actual entry-code
             -- address is denoted by the dot-prefixed ".printf" label.
             -- Moreover, the PPC NCG only ever emits a BL instruction
             -- for calling C ABI functions. Most of the time these calls
             -- originate from FFI imports and have a 'ForeignLabel',
             -- but when profiling the codegen inserts calls via
             -- 'emitRtsCallGen' which are 'CmmLabel's even though
             -- they'd technically be more like 'ForeignLabel's.
             Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tbl\t.",
               Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
             ]
           OS
_ ->
             Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tbl\t",
               Platform -> CLabel -> Line doc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
             ]

   BCTRL [Reg]
_
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
             Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"bctrl"
         ]

   ADD Reg
reg1 Reg
reg2 RI
ri
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"add") Reg
reg1 Reg
reg2 RI
ri

   ADDIS Reg
reg1 Reg
reg2 Imm
imm
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"addis",
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm
           ]

   ADDO Reg
reg1 Reg
reg2 Reg
reg3
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"addo") Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg3)

   ADDC Reg
reg1 Reg
reg2 Reg
reg3
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"addc") Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg3)

   ADDE Reg
reg1 Reg
reg2 Reg
reg3
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"adde") Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg3)

   ADDZE Reg
reg1 Reg
reg2
      -> Line doc -> Reg -> Reg -> doc
forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"addze") Reg
reg1 Reg
reg2

   SUBF Reg
reg1 Reg
reg2 Reg
reg3
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"subf") Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg3)

   SUBFO Reg
reg1 Reg
reg2 Reg
reg3
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"subfo") Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg3)

   SUBFC Reg
reg1 Reg
reg2 RI
ri
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"subf",
           case RI
ri of
               RIReg Reg
_ -> Line doc
forall doc. IsOutput doc => doc
empty
               RIImm Imm
_ -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'i',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"c\t",
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Platform -> RI -> Line doc
forall doc. IsLine doc => Platform -> RI -> doc
pprRI Platform
platform RI
ri
           ]

   SUBFE Reg
reg1 Reg
reg2 Reg
reg3
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"subfe") Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg3)

   MULL Format
fmt Reg
reg1 Reg
reg2 RI
ri
      -> Platform -> Format -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Format -> Reg -> Reg -> RI -> doc
pprMul Platform
platform Format
fmt Reg
reg1 Reg
reg2 RI
ri

   MULLO Format
fmt Reg
reg1 Reg
reg2 Reg
reg3
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
             Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"mull",
             case Format
fmt of
               Format
II32 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'w'
               Format
II64 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'd'
               Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC: illegal format",
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"o\t",
             Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
             Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
             Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg3
         ]

   MFOV Format
fmt Reg
reg
      -> [doc] -> doc
forall doc. IsDoc doc => [doc] -> doc
vcat [
           Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
               Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"mfxer",
               Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
               Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg
               ],
           Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
               Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"extr",
               case Format
fmt of
                 Format
II32 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'w'
                 Format
II64 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'd'
                 Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC: illegal format",
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"i\t",
               Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
               Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg,
               String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", 1, ",
               case Format
fmt of
                 Format
II32 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"1"
                 Format
II64 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"33"
                 Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC: illegal format"
               ]
           ]

   MULHU Format
fmt Reg
reg1 Reg
reg2 Reg
reg3
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
            Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"mulh",
            case Format
fmt of
              Format
II32 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'w'
              Format
II64 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'd'
              Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC: illegal format",
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"u\t",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg3
        ]

   DIV Format
fmt Bool
sgn Reg
reg1 Reg
reg2 Reg
reg3
      -> Format -> Bool -> Reg -> Reg -> Reg -> doc
forall doc. IsDoc doc => Format -> Bool -> Reg -> Reg -> Reg -> doc
pprDiv Format
fmt Bool
sgn Reg
reg1 Reg
reg2 Reg
reg3

        -- for some reason, "andi" doesn't exist.
        -- we'll use "andi." instead.
   AND Reg
reg1 Reg
reg2 (RIImm Imm
imm)
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
            Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"andi.",
            Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm
        ]

   AND Reg
reg1 Reg
reg2 RI
ri
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"and") Reg
reg1 Reg
reg2 RI
ri

   ANDC Reg
reg1 Reg
reg2 Reg
reg3
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"andc") Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg3)

   NAND Reg
reg1 Reg
reg2 Reg
reg3
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"nand") Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg3)

   OR Reg
reg1 Reg
reg2 RI
ri
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"or") Reg
reg1 Reg
reg2 RI
ri

   XOR Reg
reg1 Reg
reg2 RI
ri
      -> Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"xor") Reg
reg1 Reg
reg2 RI
ri

   ORIS Reg
reg1 Reg
reg2 Imm
imm
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
            Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"oris",
            Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm
        ]

   XORIS Reg
reg1 Reg
reg2 Imm
imm
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
            Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"xoris",
            Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Platform -> Imm -> Line doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm
        ]

   EXTS Format
fmt Reg
reg1 Reg
reg2
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"exts",
           Format -> Line doc
forall doc. IsLine doc => Format -> doc
pprFormat Format
fmt,
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2
         ]

   CNTLZ Format
fmt Reg
reg1 Reg
reg2
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"cntlz",
           case Format
fmt of
             Format
II32 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'w'
             Format
II64 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'd'
             Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC: illegal format",
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2
         ]

   NEG Reg
reg1 Reg
reg2
      -> Line doc -> Reg -> Reg -> doc
forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"neg") Reg
reg1 Reg
reg2

   NOT Reg
reg1 Reg
reg2
      -> Line doc -> Reg -> Reg -> doc
forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"not") Reg
reg1 Reg
reg2

   SR Format
II32 Reg
reg1 Reg
reg2 (RIImm (ImmInt Int
i))
    -- Handle the case where we are asked to shift a 32 bit register by
    -- less than zero or more than 31 bits. We convert this into a clear
    -- of the destination register.
    -- Fixes ticket https://gitlab.haskell.org/ghc/ghc/issues/5900
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0  Bool -> Bool -> Bool
|| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
31 -> Platform -> Instr -> doc
forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform (Reg -> Reg -> RI -> Instr
XOR Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg2))

   SL Format
II32 Reg
reg1 Reg
reg2 (RIImm (ImmInt Int
i))
    -- As above for SR, but for left shifts.
    -- Fixes ticket https://gitlab.haskell.org/ghc/ghc/issues/10870
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0  Bool -> Bool -> Bool
|| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
31 -> Platform -> Instr -> doc
forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform (Reg -> Reg -> RI -> Instr
XOR Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg2))

   SRA Format
II32 Reg
reg1 Reg
reg2 (RIImm (ImmInt Int
i))
    -- PT: I don't know what to do for negative shift amounts:
    -- For now just panic.
    --
    -- For shift amounts greater than 31 set all bit to the
    -- value of the sign bit, this also what sraw does.
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
31 -> Platform -> Instr -> doc
forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform (Format -> Reg -> Reg -> RI -> Instr
SRA Format
II32 Reg
reg1 Reg
reg2 (Imm -> RI
RIImm (Int -> Imm
ImmInt Int
31)))

   SL Format
fmt Reg
reg1 Reg
reg2 RI
ri
      -> let op :: Line doc
op = case Format
fmt of
                       Format
II32 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"slw"
                       Format
II64 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"sld"
                       Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr: shift illegal size"
         in Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform Line doc
op Reg
reg1 Reg
reg2 (Format -> RI -> RI
limitShiftRI Format
fmt RI
ri)

   SR Format
fmt Reg
reg1 Reg
reg2 RI
ri
      -> let op :: Line doc
op = case Format
fmt of
                       Format
II32 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"srw"
                       Format
II64 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"srd"
                       Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr: shift illegal size"
         in Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform Line doc
op Reg
reg1 Reg
reg2 (Format -> RI -> RI
limitShiftRI Format
fmt RI
ri)

   SRA Format
fmt Reg
reg1 Reg
reg2 RI
ri
      -> let op :: Line doc
op = case Format
fmt of
                       Format
II32 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"sraw"
                       Format
II64 -> String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"srad"
                       Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr: shift illegal size"
         in Platform -> Line doc -> Reg -> Reg -> RI -> doc
forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform Line doc
op Reg
reg1 Reg
reg2 (Format -> RI -> RI
limitShiftRI Format
fmt RI
ri)

   RLWINM Reg
reg1 Reg
reg2 Int
sh Int
mb Int
me
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\trlwinm\t",
             Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
             Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
             Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
sh,
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
             Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
mb,
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
             Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
me
         ]

   CLRLI Format
fmt Reg
reg1 Reg
reg2 Int
n
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tclrl",
            Format -> Line doc
forall doc. IsLine doc => Format -> doc
pprFormat Format
fmt,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"i ",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
n
        ]

   CLRRI Format
fmt Reg
reg1 Reg
reg2 Int
n
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tclrr",
            Format -> Line doc
forall doc. IsLine doc => Format -> doc
pprFormat Format
fmt,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"i ",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
            String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
            Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
n
        ]

   FADD Format
fmt Reg
reg1 Reg
reg2 Reg
reg3
      -> Line doc -> Format -> Reg -> Reg -> Reg -> doc
forall doc.
IsDoc doc =>
Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fadd") Format
fmt Reg
reg1 Reg
reg2 Reg
reg3

   FSUB Format
fmt Reg
reg1 Reg
reg2 Reg
reg3
      -> Line doc -> Format -> Reg -> Reg -> Reg -> doc
forall doc.
IsDoc doc =>
Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fsub") Format
fmt Reg
reg1 Reg
reg2 Reg
reg3

   FMUL Format
fmt Reg
reg1 Reg
reg2 Reg
reg3
      -> Line doc -> Format -> Reg -> Reg -> Reg -> doc
forall doc.
IsDoc doc =>
Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fmul") Format
fmt Reg
reg1 Reg
reg2 Reg
reg3

   FDIV Format
fmt Reg
reg1 Reg
reg2 Reg
reg3
      -> Line doc -> Format -> Reg -> Reg -> Reg -> doc
forall doc.
IsDoc doc =>
Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fdiv") Format
fmt Reg
reg1 Reg
reg2 Reg
reg3

   FABS Reg
reg1 Reg
reg2
      -> Line doc -> Reg -> Reg -> doc
forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fabs") Reg
reg1 Reg
reg2

   FNEG Reg
reg1 Reg
reg2
      -> Line doc -> Reg -> Reg -> doc
forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fneg") Reg
reg1 Reg
reg2

   FCMP Reg
reg1 Reg
reg2
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fcmpu\t0, ",
               -- Note: we're using fcmpu, not fcmpo
               -- The difference is with fcmpo, compare with NaN is an invalid operation.
               -- We don't handle invalid fp ops, so we don't care.
               -- Moreover, we use `fcmpu 0, ...` rather than `fcmpu cr0, ...` for
               -- better portability since some non-GNU assembler (such as
               -- IBM's `as`) tend not to support the symbolic register name cr0.
               -- This matches the syntax that GCC seems to emit for PPC targets.
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2
         ]

   FCTIWZ Reg
reg1 Reg
reg2
      -> Line doc -> Reg -> Reg -> doc
forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fctiwz") Reg
reg1 Reg
reg2

   FCTIDZ Reg
reg1 Reg
reg2
      -> Line doc -> Reg -> Reg -> doc
forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fctidz") Reg
reg1 Reg
reg2

   FCFID Reg
reg1 Reg
reg2
      -> Line doc -> Reg -> Reg -> doc
forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"fcfid") Reg
reg1 Reg
reg2

   FRSP Reg
reg1 Reg
reg2
      -> Line doc -> Reg -> Reg -> doc
forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"frsp") Reg
reg1 Reg
reg2

   CRNOR Int
dst Int
src1 Int
src2
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tcrnor\t",
           Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
dst,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
src1,
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
           Int -> Line doc
forall doc. IsLine doc => Int -> doc
int Int
src2
         ]

   MFCR Reg
reg
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
             Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"mfcr",
             Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
             Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg
         ]

   MFLR Reg
reg
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"mflr",
           Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
           Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg
         ]

   FETCHPC Reg
reg
      -> [Line doc] -> doc
forall doc. IsDoc doc => [Line doc] -> doc
lines_ [
             String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tbcl\t20,31,1f",
             [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [ String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"1:\tmflr\t", Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg ]
         ]

   Instr
HWSYNC
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tsync"

   Instr
ISYNC
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tisync"

   Instr
LWSYNC
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tlwsync"

   Instr
NOP
      -> Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"\tnop"

pprLogic :: IsDoc doc => Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic :: forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform Line doc
op Reg
reg1 Reg
reg2 RI
ri = Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Line doc
op,
        case RI
ri of
            RIReg Reg
_ -> Line doc
forall doc. IsOutput doc => doc
empty
            RIImm Imm
_ -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'i',
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Platform -> RI -> Line doc
forall doc. IsLine doc => Platform -> RI -> doc
pprRI Platform
platform RI
ri
    ]


pprMul :: IsDoc doc => Platform -> Format -> Reg -> Reg -> RI -> doc
pprMul :: forall doc.
IsDoc doc =>
Platform -> Format -> Reg -> Reg -> RI -> doc
pprMul Platform
platform Format
fmt Reg
reg1 Reg
reg2 RI
ri = Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"mull",
        case RI
ri of
            RIReg Reg
_ -> case Format
fmt of
              Format
II32 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'w'
              Format
II64 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'd'
              Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC: illegal format"
            RIImm Imm
_ -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'i',
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Platform -> RI -> Line doc
forall doc. IsLine doc => Platform -> RI -> doc
pprRI Platform
platform RI
ri
    ]


pprDiv :: IsDoc doc => Format -> Bool -> Reg -> Reg -> Reg -> doc
pprDiv :: forall doc. IsDoc doc => Format -> Bool -> Reg -> Reg -> Reg -> doc
pprDiv Format
fmt Bool
sgn Reg
reg1 Reg
reg2 Reg
reg3 = Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
"div",
        case Format
fmt of
          Format
II32 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'w'
          Format
II64 -> Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'd'
          Format
_    -> String -> Line doc
forall a. HasCallStack => String -> a
panic String
"PPC: illegal format",
        if Bool
sgn then Line doc
forall doc. IsOutput doc => doc
empty else Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'u',
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg3
    ]


pprUnary :: IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary :: forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary Line doc
op Reg
reg1 Reg
reg2 = Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Line doc
op,
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2
    ]


pprBinaryF :: IsDoc doc => Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF :: forall doc.
IsDoc doc =>
Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF Line doc
op Format
fmt Reg
reg1 Reg
reg2 Reg
reg3 = Line doc -> doc
forall doc. IsDoc doc => Line doc -> doc
line (Line doc -> doc) -> Line doc -> doc
forall a b. (a -> b) -> a -> b
$ [Line doc] -> Line doc
forall doc. IsLine doc => [doc] -> doc
hcat [
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Line doc
op,
        Format -> Line doc
forall doc. IsLine doc => Format -> doc
pprFFormat Format
fmt,
        Char -> Line doc
forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
        String -> Line doc
forall doc. IsLine doc => String -> doc
text String
", ",
        Reg -> Line doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg3
    ]

pprRI :: IsLine doc => Platform -> RI -> doc
pprRI :: forall doc. IsLine doc => Platform -> RI -> doc
pprRI Platform
_        (RIReg Reg
r) = Reg -> doc
forall doc. IsLine doc => Reg -> doc
pprReg Reg
r
pprRI Platform
platform (RIImm Imm
r) = Platform -> Imm -> doc
forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
r


pprFFormat :: IsLine doc => Format -> doc
pprFFormat :: forall doc. IsLine doc => Format -> doc
pprFFormat Format
FF64     = doc
forall doc. IsOutput doc => doc
empty
pprFFormat Format
FF32     = Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
's'
pprFFormat Format
_        = String -> doc
forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprFFormat: no match"

    -- limit immediate argument for shift instruction to range 0..63
    -- for 64 bit size and 0..32 otherwise
limitShiftRI :: Format -> RI -> RI
limitShiftRI :: Format -> RI -> RI
limitShiftRI Format
II64 (RIImm (ImmInt Int
i)) | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
63 Bool -> Bool -> Bool
|| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
  String -> RI
forall a. HasCallStack => String -> a
panic (String -> RI) -> String -> RI
forall a b. (a -> b) -> a -> b
$ String
"PPC.Ppr: Shift by " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" bits is not allowed."
limitShiftRI Format
II32 (RIImm (ImmInt Int
i)) | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
31 Bool -> Bool -> Bool
|| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 =
  String -> RI
forall a. HasCallStack => String -> a
panic (String -> RI) -> String -> RI
forall a b. (a -> b) -> a -> b
$ String
"PPC.Ppr: 32 bit: Shift by " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" bits is not allowed."
limitShiftRI Format
_ RI
x = RI
x