fpRelEA,
moveSp,
+ isUnconditionalJump,
+
Instr(..),
maxSpillSlots
)
import SPARC.AddrMode
import SPARC.Cond
import SPARC.Regs
+import SPARC.RegPlate
import SPARC.Base
+import TargetReg
import Instruction
import RegClass
import Reg
import Cmm
import FastString
import FastBool
-
-import GHC.Exts
+import Outputable
-- | Register or immediate
-- - a literal zero
-- - register %g0, which is always zero.
--
-riZero :: RI -> Bool
-riZero (RIImm (ImmInt 0)) = True
-riZero (RIImm (ImmInteger 0)) = True
-riZero (RIReg (RealReg 0)) = True
-riZero _ = False
+riZero :: RI -> Bool
+riZero (RIImm (ImmInt 0)) = True
+riZero (RIImm (ImmInteger 0)) = True
+riZero (RIReg (RegReal (RealRegSingle 0))) = True
+riZero _ = False
-- | Calculate the effective address which would be used by the
moveSp n
= ADD False False sp (RIImm (ImmInt (n * wordLength))) sp
+-- | An instruction that will cause the one after it never to be exectuted
+isUnconditionalJump :: Instr -> Bool
+isUnconditionalJump ii
+ = case ii of
+ CALL{} -> True
+ JMP{} -> True
+ JMP_TBL{} -> True
+ BI ALWAYS _ _ -> True
+ BF ALWAYS _ _ -> True
+ _ -> False
+
-- | instance for sparc instruction set
instance Instruction Instr where
| ST Size Reg AddrMode -- size, src, dst
-- Int Arithmetic.
+ -- x: add/sub with carry bit.
+ -- In SPARC V9 addx and friends were renamed addc.
+ --
+ -- cc: modify condition codes
+ --
| ADD Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
| SUB Bool Bool Reg RI Reg -- x?, cc?, src1, src2, dst
interesting :: Reg -> Bool
interesting reg
= case reg of
- VirtualRegI _ -> True
- VirtualRegHi _ -> True
- VirtualRegF _ -> True
- VirtualRegD _ -> True
- RealReg i -> isFastTrue (freeReg i)
+ RegVirtual _ -> True
+ RegReal (RealRegSingle r1) -> isFastTrue (freeReg r1)
+ RegReal (RealRegPair r1 _) -> isFastTrue (freeReg r1)
sparc_mkSpillInstr reg _ slot
= let off = spillSlotToOffset slot
off_w = 1 + (off `div` 4)
- sz = case regClass reg of
+ sz = case targetClassOfReg reg of
RcInteger -> II32
RcFloat -> FF32
RcDouble -> FF64
-- | Make a spill reload instruction.
sparc_mkLoadInstr
- :: Reg -- ^ register to load
+ :: Reg -- ^ register to load into
-> Int -- ^ current stack delta
-> Int -- ^ spill slot to use
-> Instr
sparc_mkLoadInstr reg _ slot
= let off = spillSlotToOffset slot
off_w = 1 + (off `div` 4)
- sz = case regClass reg of
+ sz = case targetClassOfReg reg of
RcInteger -> II32
RcFloat -> FF32
RcDouble -> FF64
-> Instr
sparc_mkRegRegMoveInstr src dst
- = case regClass src of
- RcInteger -> ADD False False src (RIReg g0) dst
- RcDouble -> FMOV FF64 src dst
- RcFloat -> FMOV FF32 src dst
+ | srcClass <- targetClassOfReg src
+ , dstClass <- targetClassOfReg dst
+ , srcClass == dstClass
+ = case srcClass of
+ RcInteger -> ADD False False src (RIReg g0) dst
+ RcDouble -> FMOV FF64 src dst
+ RcFloat -> FMOV FF32 src dst
+
+ | otherwise
+ = panic "SPARC.Instr.mkRegRegMoveInstr: classes of src and dest not the same"
-- | Check whether an instruction represents a reg-reg move.