#include "HsVersions.h"
-import List ( partition, sort )
+import List ( sort )
import MachMisc
import MachRegs
import Stix ( DestInfo(..) )
-import CLabel ( pprCLabel_asm, isAsmTemp, CLabel{-instance Ord-} )
+import CLabel ( isAsmTemp, CLabel{-instance Ord-} )
import FiniteMap ( addToFM, lookupFM, FiniteMap )
import Outputable
import Constants ( rESERVED_C_STACK_BYTES )
import Unique ( Unique, Uniquable(..) )
+import FastTypes
+
\end{code}
%************************************************************************
interesting (VirtualRegI _) = True
interesting (VirtualRegF _) = True
interesting (VirtualRegD _) = True
-interesting (RealReg (I# i)) = _IS_TRUE_(freeReg i)
+interesting (RealReg i) = isFastTrue (freeReg i)
#if alpha_TARGET_ARCH
regUsage instr = case instr of
LD B reg addr -> usage (regAddr addr, [reg, t9])
- LD BU 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
--- LD WU reg addr -> usage (regAddr addr, [reg, t9]) : UNUSED
+-- LD Wu reg addr -> usage (regAddr addr, [reg, t9]) : UNUSED
LD sz reg addr -> usage (regAddr addr, [reg])
LDA reg addr -> usage (regAddr addr, [reg])
LDAH reg addr -> usage (regAddr addr, [reg])
ADD sz src dst -> usageRM src dst
SUB sz src dst -> usageRM src dst
IMUL sz src dst -> usageRM src dst
- IDIV sz src -> mkRU (eax:edx:use_R src) [eax,edx]
+ IMUL64 sd1 sd2 -> mkRU [sd1,sd2] [sd1,sd2]
+ MUL sz src dst -> usageRM src dst
+ IQUOT sz src dst -> usageRM src dst
+ IREM sz src dst -> usageRM src dst
+ QUOT sz src dst -> usageRM src dst
+ REM sz src dst -> usageRM src dst
AND sz src dst -> usageRM src dst
OR sz src dst -> usageRM src dst
XOR sz src dst -> usageRM src dst
GLDZ dst -> mkRU [] [dst]
GLD1 dst -> mkRU [] [dst]
- GFTOD src dst -> mkRU [src] [dst]
GFTOI src dst -> mkRU [src] [dst]
-
- GDTOF src dst -> mkRU [src] [dst]
GDTOI src dst -> mkRU [src] [dst]
GITOF src dst -> mkRU [src] [dst]
mkRU src dst = RU (regSetFromList (filter interesting src))
(regSetFromList (filter interesting dst))
--- Allow the spiller to de\cide whether or not it can use
--- %edx as a spill temporary.
-hasFixedEDX instr
- = case instr of
- IDIV _ _ -> True
- CLTD -> True
- other -> False
-
#endif {- i386_TARGET_ARCH -}
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if sparc_TARGET_ARCH
#endif
#if i386_TARGET_ARCH
-- We can use %fake4 and %fake5 safely for float temps.
- -- Int regs are more troublesome. Only %ecx is definitely
- -- available. If there are no division insns, we can use %edx
- -- too. At a pinch, we also could bag %eax if there are no
- -- divisions and no ccalls, but so far we've never encountered
+ -- Int regs are more troublesome. Only %ecx and %edx are
+ -- definitely. At a pinch, we also could bag %eax if there
+ -- are no ccalls, but so far we've never encountered
-- a situation where three integer temporaries are necessary.
--
-- Because registers are in short supply on x86, we give the
= let f1 = fake5
f2 = fake4
intregs_avail
- = ecx : if any hasFixedEDX instrs then [] else [edx]
+ = [ecx, edx]
possibilities
= case intregs_avail of
[i1] -> [ [], [i1], [f1], [i1,f1], [f1,f2],
ADD sz src dst -> patch2 (ADD sz) src dst
SUB sz src dst -> patch2 (SUB sz) src dst
IMUL sz src dst -> patch2 (IMUL sz) src dst
- IDIV sz src -> patch1 (IDIV sz) src
+ IMUL64 sd1 sd2 -> IMUL64 (env sd1) (env sd2)
+ MUL sz src dst -> patch2 (MUL sz) src dst
+ IQUOT sz src dst -> patch2 (IQUOT sz) src dst
+ IREM sz src dst -> patch2 (IREM sz) src dst
+ QUOT sz src dst -> patch2 (QUOT sz) src dst
+ REM sz src dst -> patch2 (REM sz) src dst
AND sz src dst -> patch2 (AND sz) src dst
OR sz src dst -> patch2 (OR sz) src dst
XOR sz src dst -> patch2 (XOR sz) src dst
GLDZ dst -> GLDZ (env dst)
GLD1 dst -> GLD1 (env dst)
- GFTOD src dst -> GFTOD (env src) (env dst)
GFTOI src dst -> GFTOI (env src) (env dst)
-
- GDTOF src dst -> GDTOF (env src) (env dst)
GDTOI src dst -> GDTOI (env src) (env dst)
GITOF src dst -> GITOF (env src) (env dst)
JXX _ _ -> instr
CALL _ -> instr
CLTD -> instr
- _ -> pprPanic "patchInstr(x86)" empty
+ _ -> pprPanic "patchRegs(x86)" empty
where
patch1 insn op = insn (patchOp op)
Spill to memory, and load it back...
JRS, 000122: on x86, don't spill directly above the stack pointer,
-since some insn sequences (int <-> conversions, and eventually
-StixInteger) use this as a temp location. Leave 8 words (ie, 64 bytes
-for a 64-bit arch) of slop.
+since some insn sequences (int <-> conversions) use this as a temp
+location. Leave 8 words (ie, 64 bytes for a 64-bit arch) of slop.
\begin{code}
spillSlotSize :: Int
= pprPanic "spillSlotToOffset:"
(text "invalid spill location: " <> int slot)
-vregToSpillSlot :: FiniteMap Unique Int -> Unique -> Int
+vregToSpillSlot :: FiniteMap VRegUnique Int -> VRegUnique -> Int
vregToSpillSlot vreg_to_slot_map u
= case lookupFM vreg_to_slot_map u of
Just xx -> xx
- Nothing -> pprPanic "vregToSpillSlot: unmapped vreg" (ppr u)
+ Nothing -> pprPanic "vregToSpillSlot: unmapped vreg" (pprVRegUnique u)
-spillReg, loadReg :: FiniteMap Unique Int -> Int -> Reg -> Reg -> Instr
+spillReg, loadReg :: FiniteMap VRegUnique Int -> Int -> Reg -> Reg -> Instr
spillReg vreg_to_slot_map delta dyn vreg
| isVirtualReg vreg
- = let slot_no = vregToSpillSlot vreg_to_slot_map (getUnique vreg)
+ = let slot_no = vregToSpillSlot vreg_to_slot_map (getVRegUnique vreg)
off = spillSlotToOffset slot_no
in
{-Alpha: spill below the stack pointer (?)-}
loadReg vreg_to_slot_map delta vreg dyn
| isVirtualReg vreg
- = let slot_no = vregToSpillSlot vreg_to_slot_map (getUnique vreg)
+ = let slot_no = vregToSpillSlot vreg_to_slot_map (getVRegUnique vreg)
off = spillSlotToOffset slot_no
in
IF_ARCH_alpha( LD sz dyn (spRel (- (off `div` 8)))