+{-# OPTIONS -w #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and fix
+-- any warnings in the module. See
+-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
+-- for details
+
-----------------------------------------------------------------------------
--
-- Pretty-printing assembly language
#include "nativeGen/NCG.h"
module PprMach (
- pprNatCmmTop, pprBasicBlock,
- pprInstr, pprSize, pprUserReg,
+ pprNatCmmTop, pprBasicBlock, pprSectionHeader, pprData,
+ pprInstr, pprSize, pprUserReg
) where
import Pretty
import FastString
import qualified Outputable
+import Outputable ( Outputable )
import Data.Array.ST
import Data.Word ( Word8 )
pprSectionHeader section $$ vcat (map pprData dats)
-- special case for split markers:
-pprNatCmmTop (CmmProc [] lbl _ []) = pprLabel lbl
+pprNatCmmTop (CmmProc [] lbl _ (ListGraph [])) = pprLabel lbl
-pprNatCmmTop (CmmProc info lbl params blocks) =
+pprNatCmmTop (CmmProc info lbl params (ListGraph blocks)) =
pprSectionHeader Text $$
- (if not (null info)
- then
+ (if null info then -- blocks guaranteed not null, so label needed
+ pprLabel lbl
+ else
#if HAVE_SUBSECTIONS_VIA_SYMBOLS
pprCLabel_asm (mkDeadStripPreventer $ entryLblToInfoLbl lbl)
<> char ':' $$
#endif
- vcat (map pprData info) $$
- pprLabel (entryLblToInfoLbl lbl)
- else empty) $$
- (case blocks of
- [] -> empty
- (BasicBlock _ instrs : rest) ->
- (if null info then pprLabel lbl else empty) $$
- -- the first block doesn't get a label:
- vcat (map pprInstr instrs) $$
- vcat (map pprBasicBlock rest)
- )
+ vcat (map pprData info) $$
+ pprLabel (entryLblToInfoLbl lbl)
+ ) $$
+ vcat (map pprBasicBlock blocks)
+ -- ^ Even the first block gets a label, because with branch-chain
+ -- elimination, it might be the target of a goto.
#if HAVE_SUBSECTIONS_VIA_SYMBOLS
-- If we are using the .subsections_via_symbols directive
-- (available on recent versions of Darwin),
SLIT(".globl ")) <>
pprCLabel_asm lbl
+pprTypeAndSizeDecl :: CLabel -> Doc
+pprTypeAndSizeDecl lbl
+#if linux_TARGET_OS
+ | not (externallyVisibleCLabel lbl) = empty
+ | otherwise = ptext SLIT(".type ") <>
+ pprCLabel_asm lbl <> ptext SLIT(", @object")
+#else
+ = empty
+#endif
+
pprLabel :: CLabel -> Doc
-pprLabel lbl = pprGloblDecl lbl $$ (pprCLabel_asm lbl <> char ':')
+pprLabel lbl = pprGloblDecl lbl $$ pprTypeAndSizeDecl lbl $$ (pprCLabel_asm lbl <> char ':')
pprASCII str
-- -----------------------------------------------------------------------------
-- pprInstr: print an 'Instr'
+instance Outputable Instr where
+ ppr instr = Outputable.docToSDoc $ pprInstr instr
+
pprInstr :: Instr -> Doc
--pprInstr (COMMENT s) = empty -- nuke 'em
#if alpha_TARGET_ARCH
+pprInstr (SPILL reg slot)
+ = hcat [
+ ptext SLIT("\tSPILL"),
+ char '\t',
+ pprReg reg,
+ comma,
+ ptext SLIT("SLOT") <> parens (int slot)]
+
+pprInstr (RELOAD slot reg)
+ = hcat [
+ ptext SLIT("\tRELOAD"),
+ char '\t',
+ ptext SLIT("SLOT") <> parens (int slot),
+ comma,
+ pprReg reg]
+
pprInstr (LD size reg addr)
= hcat [
ptext SLIT("\tld"),
#if i386_TARGET_ARCH || x86_64_TARGET_ARCH
-pprInstr v@(MOV size s@(OpReg src) d@(OpReg dst)) -- hack
- | src == dst
- =
-#if 0 /* #ifdef DEBUG */
- (<>) (ptext SLIT("# warning: ")) (pprSizeOpOp SLIT("mov") size s d)
-#else
- empty
-#endif
+pprInstr (SPILL reg slot)
+ = hcat [
+ ptext SLIT("\tSPILL"),
+ char ' ',
+ pprUserReg reg,
+ comma,
+ ptext SLIT("SLOT") <> parens (int slot)]
+
+pprInstr (RELOAD slot reg)
+ = hcat [
+ ptext SLIT("\tRELOAD"),
+ char ' ',
+ ptext SLIT("SLOT") <> parens (int slot),
+ comma,
+ pprUserReg reg]
pprInstr (MOV size src dst)
= pprSizeOpOp SLIT("mov") size src dst
pprInstr g@(GFTOI src dst)
= pprInstr (GDTOI src dst)
pprInstr g@(GDTOI src dst)
- = pprG g (hcat [gtab, text "subl $4, %esp ; ",
- gpush src 0, gsemi, text "fistpl 0(%esp) ; popl ",
- pprReg I32 dst])
+ = pprG g (vcat [
+ hcat [gtab, text "subl $8, %esp ; fnstcw 4(%esp)"],
+ hcat [gtab, gpush src 0],
+ hcat [gtab, text "movzwl 4(%esp), ", reg,
+ text " ; orl $0xC00, ", reg],
+ hcat [gtab, text "movl ", reg, text ", 0(%esp) ; fldcw 0(%esp)"],
+ hcat [gtab, text "fistpl 0(%esp)"],
+ hcat [gtab, text "fldcw 4(%esp) ; movl 0(%esp), ", reg],
+ hcat [gtab, text "addl $8, %esp"]
+ ])
+ where
+ reg = pprReg I32 dst
pprInstr g@(GITOF src dst)
= pprInstr (GITOD src dst)
-- reads (bytearrays).
--
+pprInstr (SPILL reg slot)
+ = hcat [
+ ptext SLIT("\tSPILL"),
+ char '\t',
+ pprReg reg,
+ comma,
+ ptext SLIT("SLOT") <> parens (int slot)]
+
+pprInstr (RELOAD slot reg)
+ = hcat [
+ ptext SLIT("\tRELOAD"),
+ char '\t',
+ ptext SLIT("SLOT") <> parens (int slot),
+ comma,
+ pprReg reg]
+
-- Translate to the following:
-- add g1,g2,g1
-- ld [g1],%fn
-- pprInstr for PowerPC
#if powerpc_TARGET_ARCH
+
+pprInstr (SPILL reg slot)
+ = hcat [
+ ptext SLIT("\tSPILL"),
+ char '\t',
+ pprReg reg,
+ comma,
+ ptext SLIT("SLOT") <> parens (int slot)]
+
+pprInstr (RELOAD slot reg)
+ = hcat [
+ ptext SLIT("\tRELOAD"),
+ char '\t',
+ ptext SLIT("SLOT") <> parens (int slot),
+ comma,
+ pprReg reg]
+
pprInstr (LD sz reg addr) = hcat [
char '\t',
ptext SLIT("l"),