[project @ 2000-08-21 15:40:14 by sewardj]
[ghc-hetmet.git] / ghc / compiler / nativeGen / MachMisc.lhs
index 6f53373..116b8f9 100644 (file)
@@ -20,8 +20,6 @@ module MachMisc (
        fmtAsmLbl,
        exactLog2,
 
-        stixFor_stdout, stixFor_stderr, stixFor_stdin,
-
        Instr(..),  IF_ARCH_i386(Operand(..) COMMA,)
        Cond(..),
        Size(..),
@@ -33,7 +31,7 @@ module MachMisc (
 #if i386_TARGET_ARCH
 #endif
 #if sparc_TARGET_ARCH
-       , RI(..), riZero
+       RI(..), riZero, fpRelEA, moveSp, fPair
 #endif
     ) where
 
@@ -43,18 +41,20 @@ module MachMisc (
 import AbsCSyn         ( MagicId(..) ) 
 import AbsCUtils       ( magicIdPrimRep )
 import CLabel           ( CLabel, isAsmTemp )
-import Const           ( mkMachInt, Literal(..) )
+import Literal         ( mkMachInt, Literal(..) )
 import MachRegs                ( stgReg, callerSaves, RegLoc(..),
                          Imm(..), Reg(..), 
                          MachRegsAddr(..)
+#                         if sparc_TARGET_ARCH
+                          ,fp, sp
+#                         endif
                        )
 import PrimRep         ( PrimRep(..) )
-import SMRep           ( SMRep(..) )
-import Stix            ( StixTree(..), StixReg(..), CodeSegment )
+import Stix            ( StixTree(..), StixReg(..), CodeSegment, DestInfo(..) )
 import Panic           ( panic )
-import Char            ( isDigit )
 import GlaExts         ( word2Int#, int2Word#, shiftRL#, and#, (/=#) )
-import Outputable      ( text )
+import Outputable      ( pprPanic, ppr )
+import IOExts          ( trace )
 \end{code}
 
 \begin{code}
@@ -79,53 +79,6 @@ fmtAsmLbl s
      ,{-otherwise-}
      '.':'L':s
      )
-
----------------------------
-stixFor_stdout, stixFor_stderr, stixFor_stdin :: StixTree
-#if i386_TARGET_ARCH
--- Linux glibc 2 / libc6
-stixFor_stdout  = StInd PtrRep (StLitLbl (text "stdout"))
-stixFor_stderr  = StInd PtrRep (StLitLbl (text "stderr"))
-stixFor_stdin   = StInd PtrRep (StLitLbl (text "stdin"))
-#endif
-
-#if alpha_TARGET_ARCH
-stixFor_stdout = error "stixFor_stdout: not implemented for Alpha"
-stixFor_stderr = error "stixFor_stderr: not implemented for Alpha"
-stixFor_stdin  = error "stixFor_stdin: not implemented for Alpha"
-#endif
-
-#if sparc_TARGET_ARCH
-stixFor_stdout = error "stixFor_stdout: not implemented for Sparc"
-stixFor_stderr = error "stixFor_stderr: not implemented for Sparc"
-stixFor_stdin  = error "stixFor_stdin: not implemented for Sparc"
-#endif
-
-#if 0
-Here's some old stuff from which it shouldn't be too hard to
-implement the above for Alpha/Sparc.
-
-cvtLitLit :: String -> String
-
---
--- Rather than relying on guessing, use FILE_SIZE to compute the
--- _iob offsets.
---
-cvtLitLit "stdin"  = IF_ARCH_alpha("_iob+0" {-probably OK...-}
-                   ,IF_ARCH_i386("stdin"
-                   ,IF_ARCH_sparc("__iob+0x0"{-probably OK...-}
-                   ,)))
-
-cvtLitLit "stdout" = IF_ARCH_alpha("_iob+"++show (``FILE_SIZE''::Int)
-                   ,IF_ARCH_i386("stdout"
-                   ,IF_ARCH_sparc("__iob+"++show (``FILE_SIZE''::Int)
-                   ,)))
-cvtLitLit "stderr" = IF_ARCH_alpha("_iob+"++show (2*(``FILE_SIZE''::Int))
-                   ,IF_ARCH_i386("stderr"
-                   ,IF_ARCH_sparc("__iob+"++show (2*(``FILE_SIZE''::Int))
-                   ,)))
-#endif
-
 \end{code}
 
 % ----------------------------------------------------------------
@@ -147,7 +100,7 @@ sizeOf :: PrimRep -> Integer{-in bytes-}
     -- the result is an Integer only because it's more convenient
 
 sizeOf pr = case (primRepToSize pr) of
-  IF_ARCH_alpha({B -> 1; BU -> 1; {-W -> 2; WU -> 2; L -> 4; SF -> 4;-} _ -> 8},)
+  IF_ARCH_alpha({B -> 1; BU -> 1; {-W -> 2; WU -> 2;-} L -> 4; {-SF -> 4;-} _ -> 8},)
   IF_ARCH_sparc({B -> 1; BU -> 1; {-HW -> 2; HWU -> 2;-} W -> 4; {-D -> 8;-} F -> 4; DF -> 8},)
   IF_ARCH_i386( {B -> 1; {-S -> 2;-} L -> 4; F -> 4; DF -> 8 },)
 \end{code}
@@ -286,7 +239,7 @@ data Size
     | BU
 --  | W            -- word (2 bytes): UNUSED
 --  | WU    -- : UNUSED
---  | L            -- longword (4 bytes): UNUSED
+    | L            -- longword (4 bytes)
     | Q            -- quadword (8 bytes)
 --  | FF    -- VAX F-style floating pt: UNUSED
 --  | GF    -- VAX G-style floating pt: UNUSED
@@ -301,6 +254,7 @@ data Size
     | L
     | F            -- IEEE single-precision floating pt
     | DF    -- IEEE single-precision floating pt
+    | F80   -- Intel 80-bit internal FP format; only used for spilling
 #endif
 #if sparc_TARGET_ARCH
     = B     -- byte (signed)
@@ -320,7 +274,8 @@ primRepToSize CodePtrRep    = IF_ARCH_alpha( Q,      IF_ARCH_i386( L, IF_ARCH_sparc(
 primRepToSize DataPtrRep    = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
 primRepToSize RetRep       = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
 primRepToSize CostCentreRep = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
-primRepToSize CharRep      = IF_ARCH_alpha( BU, IF_ARCH_i386( B, IF_ARCH_sparc( BU,)))
+primRepToSize CharRep      = IF_ARCH_alpha( L,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize Int8Rep      = IF_ARCH_alpha( B,  IF_ARCH_i386( B, IF_ARCH_sparc( B ,)))
 primRepToSize IntRep       = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
 primRepToSize WordRep      = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
 primRepToSize AddrRep      = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
@@ -329,8 +284,13 @@ primRepToSize DoubleRep        = IF_ARCH_alpha( TF, IF_ARCH_i386( DF,IF_ARCH_sparc(
 primRepToSize ArrayRep     = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
 primRepToSize ByteArrayRep  = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
 primRepToSize WeakPtrRep    = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
-primRepToSize ForeignObjRep  = IF_ARCH_alpha( Q, IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize ForeignObjRep = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize BCORep        = IF_ARCH_alpha( Q,  IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
 primRepToSize StablePtrRep  = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+primRepToSize ThreadIdRep   = IF_ARCH_alpha( Q,         IF_ARCH_i386( L, IF_ARCH_sparc( W ,)))
+-- SUP: Wrong!!! Only for testing the rest of the NCG
+primRepToSize Word64Rep     = trace "primRepToSize: Word64Rep not handled" B
+primRepToSize Int64Rep      = trace "primRepToSize: Int64Rep not handled"  B
 \end{code}
 
 %************************************************************************
@@ -351,6 +311,8 @@ data Instr
            String              -- the literal string
   | DATA    Size
            [Imm]
+  | DELTA   Int                 -- specify current stack offset for
+                                -- benefit of subsequent passes
 \end{code}
 
 \begin{code}
@@ -470,6 +432,10 @@ contents, would not impose a fixed mapping from %fake to %st regs, and
 hopefully could avoid most of the redundant reg-reg moves of the
 current translation.
 
+We might as well make use of whatever unique FP facilities Intel have
+chosen to bless us with (let's not be churlish, after all).
+Hence GLDZ and GLD1.  Bwahahahahahahaha!
+
 \begin{code}
 #if i386_TARGET_ARCH
 
@@ -509,10 +475,10 @@ current translation.
               | BT            Size Imm Operand
              | NOP
 
--- Float Arithmetic. -- ToDo for 386
+-- Float Arithmetic.
 
--- Note that we cheat by treating G{ABS,MOV,NEG} of doubles as single instructions
--- right up until we spit them out.
+-- Note that we cheat by treating G{ABS,MOV,NEG} of doubles 
+-- as single instructions right up until we spit them out.
 
               -- all the 3-operand fake fp insns are src1 src2 dst
               -- and furthermore are constrained to be fp regs only.
@@ -521,6 +487,9 @@ current translation.
               | GLD           Size MachRegsAddr Reg -- src, dst(fpreg)
               | GST           Size Reg MachRegsAddr -- src(fpreg), dst
 
+              | GLDZ          Reg -- dst(fpreg)
+              | GLD1          Reg -- dst(fpreg)
+
              | GFTOD         Reg Reg -- src(fpreg), dst(fpreg)
               | GFTOI         Reg Reg -- src(fpreg), dst(intreg)
 
@@ -560,7 +529,7 @@ current translation.
 
 -- Jumping around.
 
-             | JMP           Operand -- target
+             | JMP           DestInfo Operand -- possible dests, target
              | JXX           Cond CLabel -- target
              | CALL          Imm
 
@@ -583,10 +552,14 @@ i386_insert_ffrees insns
 
 ffree_before_nonlocal_transfers insn
    = case insn of
-        CALL _                                      -> [GFREE, insn]
-        JMP (OpImm (ImmCLbl clbl)) | isAsmTemp clbl -> [insn]
-        JMP _                                       -> [GFREE, insn]
-        other                                       -> [insn]
+        CALL _                                        -> [GFREE, insn]
+        -- Jumps to immediate labels are local
+        JMP _ (OpImm (ImmCLbl clbl)) | isAsmTemp clbl -> [insn]
+        -- If a jump mentions dests, it is a local jump thru
+        -- a case table.
+        JMP (DestInfo _) _                            -> [insn]
+        JMP _ _                                       -> [GFREE, insn]
+        other                                         -> [insn]
 
 
 -- if you ever add a new FP insn to the fake x86 FP insn set,
@@ -595,6 +568,7 @@ is_G_instr :: Instr -> Bool
 is_G_instr instr
    = case instr of
         GMOV _ _ -> True; GLD _ _ _ -> True; GST _ _ _ -> True;
+        GLDZ _ -> True; GLD1 _ -> True;
         GFTOD _ _ -> True; GFTOI _ _ -> True;
         GDTOF _ _ -> True; GDTOI _ _ -> True;
         GITOF _ _ -> True; GITOD _ _ -> True;
@@ -669,8 +643,24 @@ riZero :: RI -> Bool
 
 riZero (RIImm (ImmInt 0))          = True
 riZero (RIImm (ImmInteger 0))      = True
-riZero (RIReg (FixedReg ILIT(0)))   = True
+riZero (RIReg (RealReg 0))          = True
 riZero _                           = False
 
+-- Calculate the effective address which would be used by the
+-- corresponding fpRel sequence.  fpRel is in MachRegs.lhs,
+-- alas -- can't have fpRelEA here because of module dependencies.
+fpRelEA :: Int -> Reg -> Instr
+fpRelEA n dst
+   = ADD False False fp (RIImm (ImmInt (n * BYTES_PER_WORD))) dst
+
+-- Code to shift the stack pointer by n words.
+moveSp :: Int -> Instr
+moveSp n
+   = ADD False False sp (RIImm (ImmInt (n * BYTES_PER_WORD))) sp
+
+-- Produce the second-half-of-a-double register given the first half.
+fPair :: Reg -> Reg
+fPair (RealReg n) | n >= 32 && n `mod` 2 == 0  = RealReg (n+1)
+fPair other = pprPanic "fPair(sparc NCG)" (ppr other)
 #endif {- sparc_TARGET_ARCH -}
 \end{code}