Merging in the new codegen branch
[ghc-hetmet.git] / compiler / nativeGen / RegAllocInfo.hs
index fefa314..80702bd 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
+
 -----------------------------------------------------------------------------
 --
 -- Machine-specific parts of the register allocator
@@ -28,14 +35,14 @@ module RegAllocInfo (
 
 #include "HsVersions.h"
 
+import BlockId
 import Cmm
 import CLabel
-import MachOp           ( MachRep(..), wordRep )
 import MachInstrs
 import MachRegs
 import Outputable
 import Constants       ( rESERVED_C_STACK_BYTES )
-import FastTypes
+import FastBool
 
 -- -----------------------------------------------------------------------------
 -- RegUsage type
@@ -69,6 +76,8 @@ interesting (RealReg i)       = isFastTrue (freeReg i)
 
 #if alpha_TARGET_ARCH
 regUsage instr = case instr of
+    SPILL  reg slot    -> usage ([reg], [])
+    RELOAD slot reg    -> usage ([], [reg])
     LD B reg addr      -> usage (regAddr addr, [reg, t9])
     LD Bu reg addr     -> usage (regAddr addr, [reg, t9])
 --  LD W reg addr      -> usage (regAddr addr, [reg, t9]) : UNUSED
@@ -202,20 +211,20 @@ regUsage instr = case instr of
     GMUL   sz s1 s2 dst        -> mkRU [s1,s2] [dst]
     GDIV   sz s1 s2 dst        -> mkRU [s1,s2] [dst]
 
-    GCMP   sz src1 src2        -> mkRUR [src1,src2]
-    GABS   sz src dst  -> mkRU [src] [dst]
-    GNEG   sz src dst  -> mkRU [src] [dst]
-    GSQRT  sz src dst  -> mkRU [src] [dst]
-    GSIN   sz src dst  -> mkRU [src] [dst]
-    GCOS   sz src dst  -> mkRU [src] [dst]
-    GTAN   sz src dst  -> mkRU [src] [dst]
+    GCMP   sz src1 src2   -> mkRUR [src1,src2]
+    GABS   sz src dst     -> mkRU [src] [dst]
+    GNEG   sz src dst     -> mkRU [src] [dst]
+    GSQRT  sz src dst     -> mkRU [src] [dst]
+    GSIN   sz _ _ src dst -> mkRU [src] [dst]
+    GCOS   sz _ _ src dst -> mkRU [src] [dst]
+    GTAN   sz _ _ src dst -> mkRU [src] [dst]
 #endif
 
 #if x86_64_TARGET_ARCH
     CVTSS2SD src dst   -> mkRU [src] [dst]
     CVTSD2SS src dst   -> mkRU [src] [dst]
-    CVTSS2SI src dst   -> mkRU (use_R src) [dst]
-    CVTSD2SI src dst   -> mkRU (use_R src) [dst]
+    CVTTSS2SIQ src dst -> mkRU (use_R src) [dst]
+    CVTTSD2SIQ src dst -> mkRU (use_R src) [dst]
     CVTSI2SS src dst   -> mkRU (use_R src) [dst]
     CVTSI2SD src dst   -> mkRU (use_R src) [dst]
     FDIV sz src dst     -> usageRM src dst
@@ -226,6 +235,8 @@ regUsage instr = case instr of
 
     COMMENT _          -> noUsage
     DELTA   _           -> noUsage
+    SPILL   reg slot   -> mkRU [reg] []
+    RELOAD  slot reg   -> mkRU []    [reg]
 
     _other             -> panic "regUsage: unrecognised instr"
 
@@ -275,6 +286,9 @@ regUsage instr = case instr of
 #if sparc_TARGET_ARCH
 
 regUsage instr = case instr of
+    SPILL reg slot     -> usage ([reg], [])
+    RELOAD slot reg    -> usage ([], [reg])
+
     LD    sz addr reg          -> usage (regAddr addr, [reg])
     ST    sz reg addr          -> usage (reg : regAddr addr, [])
     ADD   x cc r1 ar r2        -> usage (r1 : regRI ar, [r2])
@@ -327,6 +341,9 @@ regUsage instr = case instr of
 #if powerpc_TARGET_ARCH
 
 regUsage instr = case instr of
+    SPILL  reg slot    -> usage ([reg], [])
+    RELOAD slot reg    -> usage ([], [reg])
+
     LD    sz reg addr          -> usage (regAddr addr, [reg])
     LA    sz reg addr          -> usage (regAddr addr, [reg])
     ST    sz reg addr          -> usage (reg : regAddr addr, [])
@@ -471,6 +488,8 @@ patchRegs :: Instr -> (Reg -> Reg) -> Instr
 #if alpha_TARGET_ARCH
 
 patchRegs instr env = case instr of
+    SPILL  reg slot    -> SPILL (env reg) slot
+    RELOAD slot reg    -> RELOAD slot (env reg)
     LD sz reg addr -> LD sz (env reg) (fixAddr addr)
     LDA reg addr -> LDA (env reg) (fixAddr addr)
     LDAH reg addr -> LDAH (env reg) (fixAddr addr)
@@ -580,16 +599,16 @@ patchRegs instr env = case instr of
     GABS sz src dst    -> GABS sz (env src) (env dst)
     GNEG sz src dst    -> GNEG sz (env src) (env dst)
     GSQRT sz src dst   -> GSQRT sz (env src) (env dst)
-    GSIN sz src dst    -> GSIN sz (env src) (env dst)
-    GCOS sz src dst    -> GCOS sz (env src) (env dst)
-    GTAN sz src dst    -> GTAN sz (env src) (env dst)
+    GSIN sz l1 l2 src dst      -> GSIN sz l1 l2 (env src) (env dst)
+    GCOS sz l1 l2 src dst      -> GCOS sz l1 l2 (env src) (env dst)
+    GTAN sz l1 l2 src dst      -> GTAN sz l1 l2 (env src) (env dst)
 #endif
 
 #if x86_64_TARGET_ARCH
     CVTSS2SD src dst   -> CVTSS2SD (env src) (env dst)
     CVTSD2SS src dst   -> CVTSD2SS (env src) (env dst)
-    CVTSS2SI src dst   -> CVTSS2SI (patchOp src) (env dst)
-    CVTSD2SI src dst   -> CVTSD2SI (patchOp src) (env dst)
+    CVTTSS2SIQ src dst -> CVTTSS2SIQ (patchOp src) (env dst)
+    CVTTSD2SIQ src dst -> CVTTSD2SIQ (patchOp src) (env dst)
     CVTSI2SS src dst   -> CVTSI2SS (patchOp src) (env dst)
     CVTSI2SD src dst   -> CVTSI2SD (patchOp src) (env dst)
     FDIV sz src dst    -> FDIV sz (patchOp src) (patchOp dst)
@@ -604,6 +623,9 @@ patchRegs instr env = case instr of
     NOP                        -> instr
     COMMENT _          -> instr
     DELTA _            -> instr
+    SPILL  reg slot    -> SPILL (env reg) slot
+    RELOAD slot reg    -> RELOAD slot (env reg)
+
     JXX _ _            -> instr
     JXX_GBL _ _                -> instr
     CLTD _             -> instr
@@ -634,6 +656,8 @@ patchRegs instr env = case instr of
 #if sparc_TARGET_ARCH
 
 patchRegs instr env = case instr of
+    SPILL reg slot     -> SPILL (env reg) slot
+    RELOAD slot reg    -> RELOAD slot (env reg)
     LD    sz addr reg   -> LD sz (fixAddr addr) (env reg)
     ST    sz reg addr   -> ST sz (env reg) (fixAddr addr)
     ADD   x cc r1 ar r2 -> ADD x cc (env r1) (fixRI ar) (env r2)
@@ -677,6 +701,9 @@ patchRegs instr env = case instr of
 #if powerpc_TARGET_ARCH
 
 patchRegs instr env = case instr of
+    SPILL reg slot     -> SPILL (env reg) slot
+    RELOAD slot reg    -> RELOAD slot (env reg)
+
     LD    sz reg addr   -> LD sz (env reg) (fixAddr addr)
     LA    sz reg addr   -> LA sz (env reg) (fixAddr addr)
     ST    sz reg addr   -> ST sz (env reg) (fixAddr addr)
@@ -747,7 +774,7 @@ isRegRegMove (MOV _ (OpReg r1) (OpReg r2)) = Just (r1,r2)
 #elif powerpc_TARGET_ARCH
 isRegRegMove (MR dst src) = Just (src,dst)
 #else
-#warning ToDo: isRegRegMove
+#error ToDo: isRegRegMove
 #endif
 isRegRegMove _ = Nothing
 
@@ -755,14 +782,12 @@ isRegRegMove _ = Nothing
 -- Generating spill instructions
 
 mkSpillInstr
-   :: Reg              -- register to spill (should be a real)
+   :: Reg              -- register to spill
    -> Int              -- current stack delta
    -> Int              -- spill slot to use
    -> Instr
 mkSpillInstr reg delta slot
-  = ASSERT(isRealReg reg)
-    let        
-        off     = spillSlotToOffset slot
+  = let        off     = spillSlotToOffset slot
     in
 #ifdef alpha_TARGET_ARCH
     {-Alpha: spill below the stack pointer (?)-}
@@ -771,14 +796,14 @@ mkSpillInstr reg delta slot
 #ifdef i386_TARGET_ARCH
     let off_w = (off-delta) `div` 4
     in case regClass reg of
-          RcInteger -> MOV I32 (OpReg reg) (OpAddr (spRel off_w))
-          _         -> GST F80 reg (spRel off_w) {- RcFloat/RcDouble -}
+          RcInteger -> MOV II32 (OpReg reg) (OpAddr (spRel off_w))
+          _         -> GST FF80 reg (spRel off_w) {- RcFloat/RcDouble -}
 #endif
 #ifdef x86_64_TARGET_ARCH
     let off_w = (off-delta) `div` 8
     in case regClass reg of
-          RcInteger -> MOV I64 (OpReg reg) (OpAddr (spRel off_w))
-          RcDouble  -> MOV F64 (OpReg reg) (OpAddr (spRel off_w))
+          RcInteger -> MOV II64 (OpReg reg) (OpAddr (spRel off_w))
+          RcDouble  -> MOV FF64 (OpReg reg) (OpAddr (spRel off_w))
                -- ToDo: will it work to always spill as a double?
                -- does that cause a stall if the data was a float?
 #endif
@@ -789,25 +814,23 @@ mkSpillInstr reg delta slot
                                     RcInteger -> I32;
                                    RcFloat   -> F32;
                                     RcDouble  -> F64}}
-                        in ST sz reg (fpRel (- off_w))
+                        in ST sz reg (fpRel (negate off_w))
 #endif
 #ifdef powerpc_TARGET_ARCH
     let sz = case regClass reg of
-                RcInteger -> I32
-                RcDouble -> F64
+                RcInteger -> II32
+                RcDouble  -> FF64
     in ST sz reg (AddrRegImm sp (ImmInt (off-delta)))
 #endif
 
 
 mkLoadInstr
-   :: Reg              -- register to load (should be a real)
+   :: Reg              -- register to load
    -> Int              -- current stack delta
    -> Int              -- spill slot to use
    -> Instr
 mkLoadInstr reg delta slot
-  = ASSERT(isRealReg reg)
-    let
-        off     = spillSlotToOffset slot
+  = let off     = spillSlotToOffset slot
     in
 #if alpha_TARGET_ARCH
         LD  sz dyn (spRel (- (off `div` 8)))
@@ -815,27 +838,27 @@ mkLoadInstr reg delta slot
 #if i386_TARGET_ARCH
        let off_w = (off-delta) `div` 4
         in case regClass reg of {
-              RcInteger -> MOV I32 (OpAddr (spRel off_w)) (OpReg reg);
-              _         -> GLD F80 (spRel off_w) reg} {- RcFloat/RcDouble -}
+              RcInteger -> MOV II32 (OpAddr (spRel off_w)) (OpReg reg);
+              _         -> GLD FF80 (spRel off_w) reg} {- RcFloat/RcDouble -}
 #endif
 #if x86_64_TARGET_ARCH
        let off_w = (off-delta) `div` 8
         in case regClass reg of
-              RcInteger -> MOV I64 (OpAddr (spRel off_w)) (OpReg reg)
-              _         -> MOV F64 (OpAddr (spRel off_w)) (OpReg reg)
+              RcInteger -> MOV II64 (OpAddr (spRel off_w)) (OpReg reg)
+              _         -> MOV FF64 (OpAddr (spRel off_w)) (OpReg reg)
 #endif
 #if sparc_TARGET_ARCH
         let{off_w = 1 + (off `div` 4);
             sz = case regClass reg of {
-                   RcInteger -> I32;
-                  RcFloat   -> F32;
+                   RcInteger -> II32;
+                  RcFloat   -> FF32;
                    RcDouble  -> F64}}
         in LD sz (fpRel (- off_w)) reg
 #endif
 #if powerpc_TARGET_ARCH
     let sz = case regClass reg of
-                RcInteger -> I32
-                RcDouble -> F64
+                RcInteger -> II32
+                RcDouble  -> FF64
     in LD sz reg (AddrRegImm sp (ImmInt (off-delta)))
 #endif
 
@@ -846,14 +869,16 @@ mkRegRegMoveInstr
 mkRegRegMoveInstr src dst
 #if i386_TARGET_ARCH || x86_64_TARGET_ARCH
     = case regClass src of
-        RcInteger -> MOV wordRep (OpReg src) (OpReg dst)
+        RcInteger -> MOV wordSize (OpReg src) (OpReg dst)
 #if i386_TARGET_ARCH
         RcDouble  -> GMOV src dst
 #else
-        RcDouble  -> MOV F64 (OpReg src) (OpReg dst)
+        RcDouble  -> MOV FF64 (OpReg src) (OpReg dst)
 #endif
 #elif powerpc_TARGET_ARCH
     = MR dst src
+#else
+#error ToDo: mkRegRegMoveInstr
 #endif
 
 mkBranchInstr
@@ -891,4 +916,5 @@ spillSlotToOffset slot
    = 64 + spillSlotSize * slot
    | otherwise
    = pprPanic "spillSlotToOffset:" 
-              (text "invalid spill location: " <> int slot)
+              (   text "invalid spill location: " <> int slot
+             $$  text "maxSpillSlots:          " <> int maxSpillSlots)