module SPARC.Instr (
RI(..),
+ riZero,
+
+ fpRelEA,
+ moveSp,
+
+ isUnconditionalJump,
+
Instr(..),
maxSpillSlots
)
where
-import SPARC.Regs
+import SPARC.Stack
+import SPARC.Imm
+import SPARC.AddrMode
import SPARC.Cond
+import SPARC.Regs
+import SPARC.RegPlate
+import SPARC.Base
+import TargetReg
import Instruction
import RegClass
import Reg
import Size
import BlockId
-import Cmm
-import Outputable
-import Constants (rESERVED_C_STACK_BYTES )
+import OldCmm
import FastString
import FastBool
-
-import GHC.Exts
+import Outputable
-- | Register or immediate
= RIReg Reg
| RIImm Imm
+-- | Check if a RI represents a zero value.
+-- - a literal zero
+-- - register %g0, which is always zero.
+--
+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
+-- corresponding fpRel sequence.
+fpRelEA :: Int -> Reg -> Instr
+fpRelEA n dst
+ = ADD False False fp (RIImm (ImmInt (n * wordLength))) dst
+
+
+-- | Code to shift the stack pointer by n words.
+moveSp :: Int -> Instr
+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
+ _ -> panic "sparc_mkSpillInstr"
in ST sz reg (fpRel (negate off_w))
-- | 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
+ _ -> panic "sparc_mkLoadInstr"
in LD sz (fpRel (- off_w)) reg
--- | Convert a spill slot number to a *byte* offset, with no sign.
---
-spillSlotToOffset :: Int -> Int
-spillSlotToOffset slot
- | slot >= 0 && slot < maxSpillSlots
- = 64 + spillSlotSize * slot
-
- | otherwise
- = pprPanic "spillSlotToOffset:"
- ( text "invalid spill location: " <> int slot
- $$ text "maxSpillSlots: " <> int maxSpillSlots)
-
-
--- | We need 8 bytes because our largest registers are 64 bit.
-spillSlotSize :: Int
-spillSlotSize = 8
-
-
--- | The maximum number of spill slots available on the C stack.
--- If we use up all of the slots, then we're screwed.
-maxSpillSlots :: Int
-maxSpillSlots = ((rESERVED_C_STACK_BYTES - 64) `div` spillSlotSize) - 1
-
--------------------------------------------------------------------------------
-- | See if this instruction is telling us the current C stack delta
-> 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
+ _ -> panic "sparc_mkRegRegMoveInstr"
+
+ | otherwise
+ = panic "SPARC.Instr.mkRegRegMoveInstr: classes of src and dest not the same"
-- | Check whether an instruction represents a reg-reg move.