FIX #1910: fix code generated for GDTOI on x86_32
[ghc-hetmet.git] / compiler / nativeGen / PprMach.hs
index 52d7706..26a6f28 100644 (file)
@@ -1,3 +1,10 @@
+{-# 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
@@ -13,8 +20,8 @@
 #include "nativeGen/NCG.h"
 
 module PprMach ( 
-       pprNatCmmTop, pprBasicBlock,
-       pprInstr, pprSize, pprUserReg,
+       pprNatCmmTop, pprBasicBlock, pprSectionHeader, pprData,
+       pprInstr, pprSize, pprUserReg
   ) where
 
 
@@ -36,6 +43,7 @@ import Unique         ( pprUnique )
 import Pretty
 import FastString
 import qualified Outputable
+import Outputable      ( Outputable )
 
 import Data.Array.ST
 import Data.Word       ( Word8 )
@@ -60,27 +68,23 @@ pprNatCmmTop (CmmData section dats) =
   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),
@@ -694,9 +698,13 @@ pprGloblDecl 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 $$ pprTypeAndSizeDecl lbl $$ (pprCLabel_asm lbl <> char ':')
@@ -794,6 +802,9 @@ pprDataItem lit
 -- -----------------------------------------------------------------------------
 -- pprInstr: print an 'Instr'
 
+instance Outputable Instr where
+    ppr         instr  = Outputable.docToSDoc $ pprInstr instr
+
 pprInstr :: Instr -> Doc
 
 --pprInstr (COMMENT s) = empty -- nuke 'em
@@ -821,6 +832,22 @@ pprInstr (LDATA _ _)
 
 #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"),
@@ -1203,14 +1230,21 @@ pprSizeRegRegReg name size reg1 reg2 reg3
 
 #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
@@ -1381,9 +1415,18 @@ pprInstr g@(GDTOI src dst)
 pprInstr g@(GITOF src dst) 
    = pprInstr (GITOD src dst)
 pprInstr g@(GITOD src dst) 
-   = pprG g (hcat [gtab, text "pushl ", pprReg I32 src, 
-                   text " ; ffree %st(7); fildl (%esp) ; ",
-                   gpop dst 1, text " ; addl $4,%esp"])
+   = 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
 
 {- Gruesome swamp follows.  If you're unfortunate enough to have ventured
    this far into the jungle AND you give a Rat's Ass (tm) what's going
@@ -1773,6 +1816,22 @@ pprCondInstr name cond arg
 -- 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
@@ -2047,6 +2106,23 @@ pp_comma_a         = text ",a"
 -- 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"),