{-# 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) =
  forall doc. IsDoc doc => NCGConfig -> Section -> doc
pprSectionAlign NCGConfig
config Section
section
  forall doc. IsDoc doc => doc -> doc -> 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 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:
         forall doc. IsDoc doc => NCGConfig -> Section -> doc
pprSectionAlign NCGConfig
config (SectionType -> CLabel -> Section
Section SectionType
Text CLabel
lbl) forall doc. IsDoc doc => doc -> doc -> doc
$$
         (case Platform -> Arch
platformArch Platform
platform of
            ArchPPC_64 PPC_64ABI
ELF_V1 -> forall doc. IsDoc doc => Platform -> CLabel -> doc
pprFunctionDescriptor Platform
platform CLabel
lbl
            ArchPPC_64 PPC_64ABI
ELF_V2 -> forall doc. IsDoc doc => Platform -> CLabel -> doc
pprFunctionPrologue Platform
platform CLabel
lbl
            Arch
_ -> forall doc. IsDoc doc => Platform -> CLabel -> doc
pprLabel Platform
platform CLabel
lbl) forall doc. IsDoc doc => doc -> doc -> doc
$$ -- blocks guaranteed not null,
                                           -- so label needed
         forall doc. IsDoc doc => [doc] -> doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map (forall doc.
IsDoc doc =>
NCGConfig -> LabelMap RawCmmStatics -> GenBasicBlock Instr -> doc
pprBasicBlock NCGConfig
config LabelMap RawCmmStatics
top_info) [GenBasicBlock Instr]
blocks) forall doc. IsDoc doc => doc -> doc -> doc
$$
         forall doc. IsOutput doc => Bool -> doc -> doc
ppWhen (NCGConfig -> Bool
ncgDwarfEnabled NCGConfig
config) (forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkAsmTempEndLabel CLabel
lbl)
                                                forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
':') forall doc. IsDoc doc => doc -> doc -> doc
$$
                                          forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => Platform -> CLabel -> doc
pprProcEndLabel Platform
platform CLabel
lbl)) forall doc. IsDoc doc => doc -> doc -> doc
$$
         forall doc. IsDoc doc => Platform -> CLabel -> doc
pprSizeDecl Platform
platform CLabel
lbl

    Just (CmmStaticsRaw CLabel
info_lbl [CmmStatic]
_) ->
      forall doc. IsDoc doc => NCGConfig -> Section -> doc
pprSectionAlign NCGConfig
config (SectionType -> CLabel -> Section
Section SectionType
Text CLabel
info_lbl) forall doc. IsDoc doc => doc -> doc -> doc
$$
      (if Platform -> Bool
platformHasSubsectionsViaSymbols Platform
platform
          then forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkDeadStripPreventer CLabel
info_lbl) forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
':')
          else forall doc. IsOutput doc => doc
empty) forall doc. IsDoc doc => doc -> doc -> doc
$$
      forall doc. IsDoc doc => [doc] -> doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map (forall doc.
IsDoc doc =>
NCGConfig -> LabelMap RawCmmStatics -> GenBasicBlock Instr -> doc
pprBasicBlock NCGConfig
config LabelMap RawCmmStatics
top_info) [GenBasicBlock Instr]
blocks) 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
                forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"\t.long "
                      forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
info_lbl
                      forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Char -> doc
char Char
'-'
                      forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkDeadStripPreventer CLabel
info_lbl))
       else forall doc. IsOutput doc => doc
empty) forall doc. IsDoc doc => doc -> doc -> 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 forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"\t.size" forall doc. IsLine doc => doc -> doc -> doc
<+> Line doc
prettyLbl forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => String -> doc
text String
", .-" forall doc. IsLine doc => doc -> doc -> doc
<> Line doc
codeLbl)
   else forall doc. IsOutput doc => doc
empty
  where
    prettyLbl :: Line doc
prettyLbl = forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
    codeLbl :: Line doc
codeLbl
      | Platform -> Arch
platformArch Platform
platform forall a. Eq a => a -> a -> Bool
== PPC_64ABI -> Arch
ArchPPC_64 PPC_64ABI
ELF_V1 = forall doc. IsLine doc => Char -> doc
char Char
'.' 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 =
  forall doc. IsDoc doc => [doc] -> doc
vcat [forall doc. IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl Platform
platform CLabel
lab,
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"\t.section \".opd\", \"aw\""),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"\t.align 3"),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
':'),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"\t.quad ."
              forall doc. IsLine doc => doc -> doc -> doc
<>  forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab
              forall doc. IsLine doc => doc -> doc -> doc
<>  forall doc. IsLine doc => String -> doc
text String
",.TOC.@tocbase,0"),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"\t.previous"),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"\t.type"
              forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab
              forall doc. IsLine doc => doc -> doc -> doc
<>  forall doc. IsLine doc => String -> doc
text String
", @function"),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => Char -> doc
char Char
'.' forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab forall doc. IsLine doc => doc -> doc -> 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 =
  forall doc. IsDoc doc => [doc] -> doc
vcat [forall doc. IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl Platform
platform CLabel
lab,
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
".type " forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => String -> doc
text String
", @function"),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
':'),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"0:\taddis\t" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Reg -> doc
pprReg Reg
toc forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => String -> doc
text String
",12,.TOC.-0b@ha"),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"\taddi\t" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Reg -> doc
pprReg Reg
toc forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
',' forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Reg -> doc
pprReg Reg
toc forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => String -> doc
text String
",.TOC.-0b@l"),
        forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
"\t.localentry\t" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lab forall doc. IsLine doc => doc -> doc -> doc
<>
              forall doc. IsLine doc => String -> doc
text String
",.-" forall doc. IsLine doc => doc -> doc -> 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 =
    forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkAsmTempProcEndLabel CLabel
lbl) forall doc. IsLine doc => doc -> doc -> 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 forall doc. IsDoc doc => doc -> doc -> doc
$$
    forall doc. IsDoc doc => Platform -> CLabel -> doc
pprLabel Platform
platform CLabel
asmLbl forall doc. IsDoc doc => doc -> doc -> doc
$$
    forall doc. IsDoc doc => [doc] -> doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map (forall doc. IsDoc doc => Platform -> Instr -> doc
pprInstr Platform
platform) [Instr]
instrs) forall doc. IsDoc doc => doc -> doc -> doc
$$
    forall doc. IsOutput doc => Bool -> doc -> doc
ppWhen (NCGConfig -> Bool
ncgDwarfEnabled NCGConfig
config) (
      forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform (CLabel -> CLabel
mkAsmTempEndLabel CLabel
asmLbl) forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
':'
            forall doc. IsLine doc => doc -> doc -> 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 forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup BlockId
blockid LabelMap RawCmmStatics
info_env of
       Maybe RawCmmStatics
Nothing   -> forall doc. IsOutput doc => doc
empty
       Just (CmmStaticsRaw CLabel
info_lbl [CmmStatic]
info) ->
           forall doc. IsDoc doc => Platform -> SectionType -> doc
pprAlignForSection Platform
platform SectionType
Text forall doc. IsDoc doc => doc -> doc -> doc
$$
           forall doc. IsDoc doc => [doc] -> doc
vcat (forall a b. (a -> b) -> [a] -> [b]
map (forall doc. IsDoc doc => Platform -> CmmStatic -> doc
pprData Platform
platform) [CmmStatic]
info) forall doc. IsDoc doc => doc -> doc -> 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 forall a. Eq a => a -> a -> Bool
== CLabel
mkIndStaticInfoLabel
  , let labelInd :: CmmLit -> Maybe CLabel
labelInd (CmmLabelOff CLabel
l Int
_) = forall a. a -> Maybe a
Just CLabel
l
        labelInd (CmmLabel CLabel
l) = forall a. a -> Maybe a
Just CLabel
l
        labelInd CmmLit
_ = forall a. Maybe a
Nothing
  , Just CLabel
ind' <- CmmLit -> Maybe CLabel
labelInd CmmLit
ind
  , CLabel
alias CLabel -> CLabel -> Bool
`mayRedirectTo` CLabel
ind'
  = forall doc. IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl Platform
platform CLabel
alias
    forall doc. IsDoc doc => doc -> doc -> doc
$$ forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
".equiv" forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
alias forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => doc
comma forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
ind')
pprDatas Platform
platform (CmmStaticsRaw CLabel
lbl [CmmStatic]
dats) = forall doc. IsDoc doc => [doc] -> doc
vcat (forall doc. IsDoc doc => Platform -> CLabel -> doc
pprLabel Platform
platform CLabel
lbl forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (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          -> forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => ByteString -> doc
pprString ByteString
str)
   CmmFileEmbed String
path Int
_    -> forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
pprFileEmbed String
path)
   CmmUninitialised Int
bytes -> forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
".space " forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Int -> doc
int Int
bytes)
   CmmStaticLit CmmLit
lit       -> 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) = forall doc. IsOutput doc => doc
empty
  | Bool
otherwise = forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => String -> doc
text String
".globl " forall doc. IsLine doc => doc -> doc -> 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 forall a. Eq a => a -> a -> Bool
== OS
OSLinux Bool -> Bool -> Bool
&& CLabel -> Bool
externallyVisibleCLabel CLabel
lbl
    then forall doc. IsLine doc => String -> doc
text String
".type " forall doc. IsLine doc => doc -> doc -> doc
<>
         forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => String -> doc
text String
", @object"
    else 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 =
   forall doc. IsDoc doc => Platform -> CLabel -> doc
pprGloblDecl Platform
platform CLabel
lbl
   forall doc. IsDoc doc => doc -> doc -> doc
$$ forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => Platform -> CLabel -> doc
pprTypeAndSizeDecl Platform
platform CLabel
lbl)
   forall doc. IsDoc doc => doc -> doc -> doc
$$ forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl forall doc. IsLine doc => doc -> doc -> 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)  -> forall doc. IsLine doc => String -> doc
text String
"%vI_"   forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
u
      RegVirtual (VirtualRegHi Unique
u)  -> forall doc. IsLine doc => String -> doc
text String
"%vHi_"  forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
u
      RegVirtual (VirtualRegF  Unique
u)  -> forall doc. IsLine doc => String -> doc
text String
"%vF_"   forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
u
      RegVirtual (VirtualRegD  Unique
u)  -> forall doc. IsLine doc => String -> doc
text String
"%vD_"   forall doc. IsLine doc => doc -> doc -> 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 forall a. Ord a => a -> a -> Bool
<= Int
31   = forall doc. IsLine doc => Int -> doc
int Int
i      -- GPRs
         | Int
i forall a. Ord a => a -> a -> Bool
<= Int
63   = forall doc. IsLine doc => Int -> doc
int (Int
iforall a. Num a => a -> a -> a
-Int
32) -- FPRs
         | Bool
otherwise = 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  -> forall doc. IsLine doc => String -> doc
text String
"b"
                Format
II16 -> forall doc. IsLine doc => String -> doc
text String
"h"
                Format
II32 -> forall doc. IsLine doc => String -> doc
text String
"w"
                Format
II64 -> forall doc. IsLine doc => String -> doc
text String
"d"
                Format
FF32 -> forall doc. IsLine doc => String -> doc
text String
"fs"
                Format
FF64 -> 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  -> forall doc. IsLine doc => String -> doc
text String
"";
                Cond
EQQ     -> forall doc. IsLine doc => String -> doc
text String
"eq";  Cond
NE    -> forall doc. IsLine doc => String -> doc
text String
"ne";
                Cond
LTT     -> forall doc. IsLine doc => String -> doc
text String
"lt";  Cond
GE    -> forall doc. IsLine doc => String -> doc
text String
"ge";
                Cond
GTT     -> forall doc. IsLine doc => String -> doc
text String
"gt";  Cond
LE    -> forall doc. IsLine doc => String -> doc
text String
"le";
                Cond
LU      -> forall doc. IsLine doc => String -> doc
text String
"lt";  Cond
GEU   -> forall doc. IsLine doc => String -> doc
text String
"ge";
                Cond
GU      -> forall doc. IsLine doc => String -> doc
text String
"gt";  Cond
LEU   -> 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       -> forall doc. IsLine doc => Int -> doc
int Int
i
   ImmInteger Integer
i   -> forall doc. IsLine doc => Integer -> doc
integer Integer
i
   ImmCLbl CLabel
l      -> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
l
   ImmIndex CLabel
l Int
i   -> forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
l forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
'+' forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Int -> doc
int Int
i
   ImmLit FastString
s       -> forall doc. IsLine doc => FastString -> doc
ftext FastString
s
   ImmFloat Rational
f     -> forall doc. IsLine doc => Float -> doc
float forall a b. (a -> b) -> a -> b
$ forall a. Fractional a => Rational -> a
fromRational Rational
f
   ImmDouble Rational
d    -> forall doc. IsLine doc => Double -> doc
double forall a b. (a -> b) -> a -> b
$ forall a. Fractional a => Rational -> a
fromRational Rational
d
   ImmConstantSum Imm
a Imm
b   -> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
a forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
'+' forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
b
   ImmConstantDiff Imm
a Imm
b  -> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
a forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
'-' forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => doc
lparen forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
b forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => doc
rparen
   LO (ImmInt Int
i)        -> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform (Imm -> Imm
LO (Integer -> Imm
ImmInteger (forall a. Integral a => a -> Integer
toInteger Int
i)))
   LO (ImmInteger Integer
i)    -> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform (Integer -> Imm
ImmInteger (forall a. Integral a => a -> Integer
toInteger Int16
lo16))
        where
          lo16 :: Int16
lo16 = forall a. Num a => Integer -> a
fromInteger (Integer
i forall a. Bits a => a -> a -> a
.&. Integer
0xffff) :: Int16

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

   HA Imm
i        -> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
i forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => String -> doc
text String
"@ha"
   HIGHERA Imm
i   -> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
i forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => String -> doc
text String
"@highera"
   HIGHESTA Imm
i  -> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
i forall doc. IsLine doc => doc -> doc -> 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             -> forall doc. IsLine doc => Reg -> doc
pprReg Reg
r1 forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Char -> doc
char Char
',' forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Reg -> doc
pprReg Reg
r2
   AddrRegImm Reg
r1 (ImmInt Int
i)     -> forall doc. IsLine doc => [doc] -> doc
hcat [ forall doc. IsLine doc => Int -> doc
int Int
i, forall doc. IsLine doc => Char -> doc
char Char
'(', forall doc. IsLine doc => Reg -> doc
pprReg Reg
r1, forall doc. IsLine doc => Char -> doc
char Char
')' ]
   AddrRegImm Reg
r1 (ImmInteger Integer
i) -> forall doc. IsLine doc => [doc] -> doc
hcat [ forall doc. IsLine doc => Integer -> doc
integer Integer
i, forall doc. IsLine doc => Char -> doc
char Char
'(', forall doc. IsLine doc => Reg -> doc
pprReg Reg
r1, forall doc. IsLine doc => Char -> doc
char Char
')' ]
   AddrRegImm Reg
r1 Imm
imm            -> forall doc. IsLine doc => [doc] -> doc
hcat [ forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm, forall doc. IsLine doc => Char -> doc
char Char
'(', forall doc. IsLine doc => Reg -> doc
pprReg Reg
r1, 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
_) =
   forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => NCGConfig -> Section -> doc
pprSectionHeader NCGConfig
config Section
sec) forall doc. IsDoc doc => doc -> doc -> 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 = forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$
 let ppc64 :: Bool
ppc64    = Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ Platform -> Bool
target32Bit Platform
platform
 in case SectionType
seg of
       SectionType
Text              -> forall doc. IsLine doc => String -> doc
text String
".align 2"
       SectionType
Data
        | Bool
ppc64          -> forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> forall doc. IsLine doc => String -> doc
text String
".align 2"
       SectionType
ReadOnlyData
        | Bool
ppc64          -> forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> forall doc. IsLine doc => String -> doc
text String
".align 2"
       SectionType
RelocatableReadOnlyData
        | Bool
ppc64          -> forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> forall doc. IsLine doc => String -> doc
text String
".align 2"
       SectionType
UninitialisedData
        | Bool
ppc64          -> forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> 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         -> forall doc. IsLine doc => String -> doc
text String
".align 3"
       SectionType
FiniArray         -> forall doc. IsLine doc => String -> doc
text String
".align 3"
       SectionType
CString
        | Bool
ppc64          -> forall doc. IsLine doc => String -> doc
text String
".align 3"
        | Bool
otherwise      -> forall doc. IsLine doc => String -> doc
text String
".align 2"
       OtherSection String
_    -> 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
  = forall doc. IsDoc doc => [Line doc] -> doc
lines_ (Format -> CmmLit -> [Line doc]
ppr_item (CmmType -> Format
cmmTypeFormat 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 forall a b. (a -> b) -> a -> b
$ Platform -> Bool
target32Bit Platform
platform

        ppr_item :: Format -> CmmLit -> [Line doc]
ppr_item Format
II8  CmmLit
_ = [forall doc. IsLine doc => String -> doc
text String
"\t.byte\t"  forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm]
        ppr_item Format
II16 CmmLit
_ = [forall doc. IsLine doc => String -> doc
text String
"\t.short\t" forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm]
        ppr_item Format
II32 CmmLit
_ = [forall doc. IsLine doc => String -> doc
text String
"\t.long\t"  forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm]
        ppr_item Format
II64 CmmLit
_
           | Bool
archPPC_64 = [forall doc. IsLine doc => String -> doc
text String
"\t.quad\t"  forall doc. IsLine doc => doc -> doc -> 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 =
                [forall doc. IsLine doc => String -> doc
text String
"\t.long\t"
                    forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Int -> doc
int (forall a b. (Integral a, Num b) => a -> b
fromIntegral
                        (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
x forall a. Bits a => a -> Int -> a
`shiftR` Int
32) :: Word32)),
                 forall doc. IsLine doc => String -> doc
text String
"\t.long\t"
                    forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => Int -> doc
int (forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
x :: Word32))]


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

        ppr_item Format
_ CmmLit
_
                = 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 = forall doc. IsOutput doc => doc -> doc
whenPprDebug forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => String -> doc
text String
"#" 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
      -> forall doc. IsDoc doc => Line doc -> doc
line (forall doc. IsLine doc => doc -> doc
asmComment (forall doc. IsLine doc => FastString -> doc
ftext FastString
s))

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

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

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

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

   LDFAR Format
fmt Reg
reg (AddrRegImm Reg
source Imm
off)
      -> forall doc. IsDoc doc => [doc] -> doc
vcat
            [ 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))
            , 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
_
      -> forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr LDFAR: no match"

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

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

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

   STFAR Format
fmt Reg
reg (AddrRegImm Reg
source Imm
off)
      -> forall doc. IsDoc doc => [doc] -> doc
vcat [ 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))
              , 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
_
      -> forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr STFAR: no match"

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

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

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

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

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

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

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

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

   BCCFAR Cond
cond BlockId
blockid Maybe Bool
prediction
      -> forall doc. IsDoc doc => [Line doc] -> doc
lines_ [
           forall doc. IsLine doc => [doc] -> doc
hcat [
               forall doc. IsLine doc => String -> doc
text String
"\tb",
               forall doc. IsLine doc => Cond -> doc
pprCond (Cond -> Cond
condNegate Cond
cond),
               Line doc
neg_prediction,
               forall doc. IsLine doc => String -> doc
text String
"\t$+8"
           ],
           forall doc. IsLine doc => [doc] -> doc
hcat [
               forall doc. IsLine doc => String -> doc
text String
"\tb\t",
               forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
           ]
          ]
          where lbl :: CLabel
lbl = Unique -> CLabel
mkLocalBlockLabel (forall a. Uniquable a => a -> Unique
getUnique BlockId
blockid)
                neg_prediction :: Line doc
neg_prediction = case Maybe Bool
prediction of
                  Maybe Bool
Nothing    -> forall doc. IsOutput doc => doc
empty
                  Just Bool
True  -> forall doc. IsLine doc => Char -> doc
char Char
'-'
                  Just Bool
False -> 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 -> forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr: JMP to ForeignLabel"
     | Bool
otherwise ->
       forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [ -- an alias for b that takes a CLabel
           forall doc. IsLine doc => String -> doc
text String
"\tb\t",
           forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
       ]

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

   BCTR [Maybe BlockId]
_ Maybe CLabel
_ [Reg]
_
      -> forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
           forall doc. IsLine doc => Char -> doc
char Char
'\t',
           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.
             forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
               forall doc. IsLine doc => String -> doc
text String
"\tbl\t.",
               forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
             ]
           OS
_ ->
             forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
               forall doc. IsLine doc => String -> doc
text String
"\tbl\t",
               forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl
             ]

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

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

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

   ADDO Reg
reg1 Reg
reg2 Reg
reg3
      -> forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (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
      -> forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (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
      -> forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (forall doc. IsLine doc => String -> doc
text String
"adde") Reg
reg1 Reg
reg2 (Reg -> RI
RIReg Reg
reg3)

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

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

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

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

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

   DIV Format
fmt Bool
sgn Reg
reg1 Reg
reg2 Reg
reg3
      -> 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)
      -> forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
            forall doc. IsLine doc => Char -> doc
char Char
'\t',
            forall doc. IsLine doc => String -> doc
text String
"andi.",
            forall doc. IsLine doc => Char -> doc
char Char
'\t',
            forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
            forall doc. IsLine doc => String -> doc
text String
", ",
            forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
            forall doc. IsLine doc => String -> doc
text String
", ",
            forall doc. IsLine doc => Platform -> Imm -> doc
pprImm Platform
platform Imm
imm
        ]

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

   ANDC Reg
reg1 Reg
reg2 Reg
reg3
      -> forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (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
      -> forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (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
      -> forall doc.
IsDoc doc =>
Platform -> Line doc -> Reg -> Reg -> RI -> doc
pprLogic Platform
platform (forall doc. IsLine doc => String -> doc
text String
"or") Reg
reg1 Reg
reg2 RI
ri

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

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

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

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

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

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

   NOT Reg
reg1 Reg
reg2
      -> forall doc. IsDoc doc => Line doc -> Reg -> Reg -> doc
pprUnary (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 forall a. Ord a => a -> a -> Bool
< Int
0  Bool -> Bool -> Bool
|| Int
i forall a. Ord a => a -> a -> Bool
> Int
31 -> 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 forall a. Ord a => a -> a -> Bool
< Int
0  Bool -> Bool -> Bool
|| Int
i forall a. Ord a => a -> a -> Bool
> Int
31 -> 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 forall a. Ord a => a -> a -> Bool
> Int
31 -> 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 -> forall doc. IsLine doc => String -> doc
text String
"slw"
                       Format
II64 -> forall doc. IsLine doc => String -> doc
text String
"sld"
                       Format
_    -> forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr: shift illegal size"
         in 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 -> forall doc. IsLine doc => String -> doc
text String
"srw"
                       Format
II64 -> forall doc. IsLine doc => String -> doc
text String
"srd"
                       Format
_    -> forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr: shift illegal size"
         in 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 -> forall doc. IsLine doc => String -> doc
text String
"sraw"
                       Format
II64 -> forall doc. IsLine doc => String -> doc
text String
"srad"
                       Format
_    -> forall a. HasCallStack => String -> a
panic String
"PPC.Ppr.pprInstr: shift illegal size"
         in 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
      -> forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
             forall doc. IsLine doc => String -> doc
text String
"\trlwinm\t",
             forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
             forall doc. IsLine doc => String -> doc
text String
", ",
             forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
             forall doc. IsLine doc => String -> doc
text String
", ",
             forall doc. IsLine doc => Int -> doc
int Int
sh,
             forall doc. IsLine doc => String -> doc
text String
", ",
             forall doc. IsLine doc => Int -> doc
int Int
mb,
             forall doc. IsLine doc => String -> doc
text String
", ",
             forall doc. IsLine doc => Int -> doc
int Int
me
         ]

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

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

   FADD Format
fmt Reg
reg1 Reg
reg2 Reg
reg3
      -> forall doc.
IsDoc doc =>
Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF (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
      -> forall doc.
IsDoc doc =>
Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF (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
      -> forall doc.
IsDoc doc =>
Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF (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
      -> forall doc.
IsDoc doc =>
Line doc -> Format -> Reg -> Reg -> Reg -> doc
pprBinaryF (forall doc. IsLine doc => String -> doc
text String
"fdiv") Format
fmt Reg
reg1 Reg
reg2 Reg
reg3

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

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

   FCMP Reg
reg1 Reg
reg2
      -> forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
           forall doc. IsLine doc => Char -> doc
char Char
'\t',
           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.
           forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
           forall doc. IsLine doc => String -> doc
text String
", ",
           forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2
         ]

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

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

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

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

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

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

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

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

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

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

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

   Instr
NOP
      -> forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ 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 = forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Line doc
op,
        case RI
ri of
            RIReg Reg
_ -> forall doc. IsOutput doc => doc
empty
            RIImm Imm
_ -> forall doc. IsLine doc => Char -> doc
char Char
'i',
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        forall doc. IsLine doc => String -> doc
text String
", ",
        forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
        forall doc. IsLine doc => String -> doc
text String
", ",
        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 = forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        forall doc. IsLine doc => String -> doc
text String
"mull",
        case RI
ri of
            RIReg Reg
_ -> case Format
fmt of
              Format
II32 -> forall doc. IsLine doc => Char -> doc
char Char
'w'
              Format
II64 -> forall doc. IsLine doc => Char -> doc
char Char
'd'
              Format
_    -> forall a. HasCallStack => String -> a
panic String
"PPC: illegal format"
            RIImm Imm
_ -> forall doc. IsLine doc => Char -> doc
char Char
'i',
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        forall doc. IsLine doc => String -> doc
text String
", ",
        forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
        forall doc. IsLine doc => String -> doc
text String
", ",
        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 = forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        forall doc. IsLine doc => String -> doc
text String
"div",
        case Format
fmt of
          Format
II32 -> forall doc. IsLine doc => Char -> doc
char Char
'w'
          Format
II64 -> forall doc. IsLine doc => Char -> doc
char Char
'd'
          Format
_    -> forall a. HasCallStack => String -> a
panic String
"PPC: illegal format",
        if Bool
sgn then forall doc. IsOutput doc => doc
empty else forall doc. IsLine doc => Char -> doc
char Char
'u',
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        forall doc. IsLine doc => String -> doc
text String
", ",
        forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
        forall doc. IsLine doc => String -> doc
text String
", ",
        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 = forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Line doc
op,
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        forall doc. IsLine doc => String -> doc
text String
", ",
        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 = forall doc. IsDoc doc => Line doc -> doc
line forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hcat [
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        Line doc
op,
        forall doc. IsLine doc => Format -> doc
pprFFormat Format
fmt,
        forall doc. IsLine doc => Char -> doc
char Char
'\t',
        forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg1,
        forall doc. IsLine doc => String -> doc
text String
", ",
        forall doc. IsLine doc => Reg -> doc
pprReg Reg
reg2,
        forall doc. IsLine doc => String -> doc
text String
", ",
        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) = forall doc. IsLine doc => Reg -> doc
pprReg Reg
r
pprRI Platform
platform (RIImm Imm
r) = 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     = forall doc. IsOutput doc => doc
empty
pprFFormat Format
FF32     = forall doc. IsLine doc => Char -> doc
char Char
's'
pprFFormat Format
_        = 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 forall a. Ord a => a -> a -> Bool
> Int
63 Bool -> Bool -> Bool
|| Int
i forall a. Ord a => a -> a -> Bool
< Int
0 =
  forall a. HasCallStack => String -> a
panic forall a b. (a -> b) -> a -> b
$ String
"PPC.Ppr: Shift by " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i forall a. [a] -> [a] -> [a]
++ String
" bits is not allowed."
limitShiftRI Format
II32 (RIImm (ImmInt Int
i)) | Int
i forall a. Ord a => a -> a -> Bool
> Int
31 Bool -> Bool -> Bool
|| Int
i forall a. Ord a => a -> a -> Bool
< Int
0 =
  forall a. HasCallStack => String -> a
panic forall a b. (a -> b) -> a -> b
$ String
"PPC.Ppr: 32 bit: Shift by " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i forall a. [a] -> [a] -> [a]
++ String
" bits is not allowed."
limitShiftRI Format
_ RI
x = RI
x