patchJump,
isRegRegMove,
+ JumpDest, canShortcut, shortcutJump, shortcutStatic,
+
maxSpillSlots,
mkSpillInstr,
mkLoadInstr,
#include "HsVersions.h"
-import Cmm ( BlockId )
+import Cmm
+import CLabel
import MachOp ( MachRep(..), wordRep )
import MachInstrs
import MachRegs
CMP sz src dst -> mkRUR (use_R src ++ use_R dst)
SETCC cond op -> mkRU [] (def_W op)
JXX cond lbl -> mkRU [] []
+ JXX_GBL cond lbl -> mkRU [] []
JMP op -> mkRUR (use_R op)
JMP_TBL op ids -> mkRUR (use_R op)
CALL (Left imm) params -> mkRU params callClobberedRegs
#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
#endif
_other -> insn
+data JumpDest = DestBlockId BlockId | DestImm Imm
+
+canShortcut :: Instr -> Maybe JumpDest
+#if i386_TARGET_ARCH || x86_64_TARGET_ARCH
+canShortcut (JXX ALWAYS id) = Just (DestBlockId id)
+canShortcut (JMP (OpImm imm)) = Just (DestImm imm)
+#endif
+canShortcut _ = Nothing
+
+shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
+#if i386_TARGET_ARCH || x86_64_TARGET_ARCH
+shortcutJump fn insn@(JXX cc id) =
+ case fn id of
+ Nothing -> insn
+ Just (DestBlockId id') -> shortcutJump fn (JXX cc id')
+ Just (DestImm imm) -> shortcutJump fn (JXX_GBL cc imm)
+#endif
+shortcutJump fn other = other
+
+-- Here because it knows about JumpDest
+shortcutStatic :: (BlockId -> Maybe JumpDest) -> CmmStatic -> CmmStatic
+shortcutStatic fn (CmmStaticLit (CmmLabel lab))
+ | Just uq <- maybeAsmTemp lab
+ = CmmStaticLit (CmmLabel (shortBlockId fn (BlockId uq)))
+shortcutStatic fn (CmmStaticLit (CmmLabelDiffOff lbl1 lbl2 off))
+ | Just uq <- maybeAsmTemp lbl1
+ = CmmStaticLit (CmmLabelDiffOff (shortBlockId fn (BlockId uq)) lbl2 off)
+ -- slightly dodgy, we're ignoring the second label, but this
+ -- works with the way we use CmmLabelDiffOff for jump tables now.
+shortcutStatic fn other_static
+ = other_static
+
+shortBlockId fn blockid@(BlockId uq) =
+ case fn blockid of
+ Nothing -> mkAsmTempLabel uq
+ Just (DestBlockId blockid') -> shortBlockId fn blockid'
+ Just (DestImm (ImmCLbl lbl)) -> lbl
+ _other -> panic "shortBlockId"
+
-- -----------------------------------------------------------------------------
-- 'patchRegs' function
#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)
COMMENT _ -> instr
DELTA _ -> instr
JXX _ _ -> instr
+ JXX_GBL _ _ -> instr
CLTD _ -> instr
_other -> panic "patchRegs: unrecognised instr"