+{-# 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-dependent assembly language
-- * Machine instructions
Instr(..),
Cond(..), condUnsigned, condToSigned, condToUnsigned,
-
+#if powerpc_TARGET_ARCH
+ condNegate,
+#endif
#if !powerpc_TARGET_ARCH && !i386_TARGET_ARCH && !x86_64_TARGET_ARCH
Size(..), machRepSize,
#endif
#include "HsVersions.h"
+import BlockId
import MachRegs
import Cmm
import MachOp ( MachRep(..) )
import FastString
import Constants ( wORD_SIZE )
-import GLAEXTS
+import GHC.Exts
-- -----------------------------------------------------------------------------
-- Our flavours of the Cmm types
-- Type synonyms for Cmm populated with native code
-type NatCmm = GenCmm CmmStatic Instr
-type NatCmmTop = GenCmmTop CmmStatic Instr
+type NatCmm = GenCmm CmmStatic [CmmStatic] (ListGraph Instr)
+type NatCmmTop = GenCmmTop CmmStatic [CmmStatic] (ListGraph Instr)
type NatBasicBlock = GenBasicBlock Instr
-- -----------------------------------------------------------------------------
condToUnsigned LE = LEU
condToUnsigned x = x
+#if powerpc_TARGET_ARCH
+condNegate ALWAYS = panic "condNegate: ALWAYS"
+condNegate EQQ = NE
+condNegate GE = LTT
+condNegate GEU = LU
+condNegate GTT = LE
+condNegate GU = LEU
+condNegate LE = GTT
+condNegate LEU = GU
+condNegate LTT = GE
+condNegate LU = GEU
+condNegate NE = EQQ
+#endif
+
-- -----------------------------------------------------------------------------
-- Sizes on this architecture
| DELTA Int -- specify current stack offset for
-- benefit of subsequent passes
+ | SPILL Reg Int -- ^ spill this reg to a stack slot
+ | RELOAD Int Reg -- ^ reload this reg from a stack slot
+
-- -----------------------------------------------------------------------------
-- Alpha instructions
| GABS MachRep Reg Reg -- src, dst
| GNEG MachRep Reg Reg -- src, dst
| GSQRT MachRep Reg Reg -- src, dst
- | GSIN MachRep Reg Reg -- src, dst
- | GCOS MachRep Reg Reg -- src, dst
- | GTAN MachRep Reg Reg -- src, dst
+ | GSIN MachRep CLabel CLabel Reg Reg -- src, dst
+ | GCOS MachRep CLabel CLabel Reg Reg -- src, dst
+ | GTAN MachRep CLabel CLabel Reg Reg -- src, dst
| GFREE -- do ffree on all x86 regs; an ugly hack
#endif
| CVTSS2SD Reg Reg -- F32 to F64
| CVTSD2SS Reg Reg -- F64 to F32
- | CVTSS2SI Operand Reg -- F32 to I32/I64 (with rounding)
- | CVTSD2SI Operand Reg -- F64 to I32/I64 (with rounding)
+ | CVTTSS2SIQ Operand Reg -- F32 to I32/I64 (with truncation)
+ | CVTTSD2SIQ Operand Reg -- F64 to I32/I64 (with truncation)
| CVTSI2SS Operand Reg -- I32/I64 to F32
| CVTSI2SD Operand Reg -- I32/I64 to F64
-- Jumping around.
| JMP Operand
| JXX Cond BlockId -- includes unconditional branches
+ | JXX_GBL Cond Imm -- non-local version of JXX
| JMP_TBL Operand [BlockId] -- table jump
| CALL (Either Imm Reg) [Reg]
#endif /* i386 or x86_64 */
#if i386_TARGET_ARCH
-i386_insert_ffrees :: [Instr] -> [Instr]
-i386_insert_ffrees insns
- | any is_G_instr insns
- = concatMap ffree_before_nonlocal_transfers insns
+i386_insert_ffrees :: [GenBasicBlock Instr] -> [GenBasicBlock Instr]
+i386_insert_ffrees blocks
+ | or (map (any is_G_instr) [ instrs | BasicBlock id instrs <- blocks ])
+ = map ffree_before_nonlocal_transfers blocks
| otherwise
- = insns
-
-ffree_before_nonlocal_transfers insn
- = case insn of
- CALL _ _ -> [GFREE, insn]
- JMP _ -> [GFREE, insn]
- other -> [insn]
-
+ = blocks
+ where
+ ffree_before_nonlocal_transfers (BasicBlock id insns)
+ = BasicBlock id (foldr p [] insns)
+ where p insn r = case insn of
+ CALL _ _ -> GFREE : insn : r
+ JMP _ -> GFREE : insn : r
+ other -> insn : r
-- if you ever add a new FP insn to the fake x86 FP insn set,
-- you must update this too
GSUB _ _ _ _ -> True; GMUL _ _ _ _ -> True
GCMP _ _ _ -> True; GABS _ _ _ -> True
GNEG _ _ _ -> True; GSQRT _ _ _ -> True
- GSIN _ _ _ -> True; GCOS _ _ _ -> True; GTAN _ _ _ -> True
+ GSIN _ _ _ _ _ -> True; GCOS _ _ _ _ _ -> True; GTAN _ _ _ _ _ -> True
GFREE -> panic "is_G_instr: GFREE (!)"
other -> False
#endif /* i386_TARGET_ARCH */
| CMPL MachRep Reg RI --- size, src1, src2
| BCC Cond BlockId
+ | BCCFAR Cond BlockId
| JMP CLabel -- same as branch,
-- but with CLabel instead of block ID
| MTCTR Reg
| FETCHPC Reg -- pseudo-instruction:
-- bcl to next insn, mflr reg
+ | LWSYNC -- memory barrier
#endif /* powerpc_TARGET_ARCH */