Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
167 lines (142 sloc) 5.57 KB
{-# OPTIONS_GHC -fglasgow-exts #-}
module MicroOp where
import qualified Types as F
import qualified GPP as F
import PPrint
import Text.PrettyPrint.HughesPJ as PP
------------------------------------------------------------------------------
-- | A Path Variable (PV) is a temporary name for a value on the data path.
-- It is generated by an output port of a functional unit and is alive for
-- exactly one routing operation. A PV may be used as the input to multiple
-- functional units, provided the data path allows for this.
--
-- If the same value is meant to be used in multiple cycles, it has to be
-- stored in a temporary location and read again when it is needed again.
data PathVar = PV Int (Maybe PVOrigin) deriving (Read, Show)
instance Eq PathVar where PV x _ == PV y _ = x == y
instance Ord PathVar where PV x _ `compare` PV y _ = x `compare` y
-- | Describes the origin of a |PathVar|. This is used to
--
-- * determine dependencies
--
-- * determine locations in the register file for write-backs, or
--
-- * determine intermediate storage while routing the value to its
-- use sites.
--
data PVOrigin
= OrigRead F.Reg
-- ^ The path variable is the result of reading an (externally defined)
-- register
| OrigImm F.Const
-- ^ The path variable is the local name for a value from the immediate
-- port.
| OrigWrite F.Reg
-- ^ The path variable is the result of some operation in the current code
-- block. If the PV needs a write-back, this is where it has to be
-- written to.
deriving (Show, Read)
instance PPrint PVOrigin where
pshow (OrigRead r) = parens $ char '=' <> pshow r
pshow (OrigImm i) = parens $ pshow i
pshow (OrigWrite r) = parens $ pshow r <> char '='
-- | A Micro Operation for the scheduler.
data MicroOp' info = Mop info (Maybe PathVar) Oper
deriving (Show, Read, Eq)
type MicroOp = MicroOp' Int
-- | All possible micro-operations.
data Oper
= Imm F.Const -- ^ Read an immediate.
| ALU F.ALUOp PathVar PathVar -- ^ ALU operation
| Load F.LSWidth F.Sign PathVar -- ^ Load from memory
| ReadReg Int -- ^ Read register
| ReadBuf Int -- ^ Read buffer
-- | ReadMult Bool -- ^ Read multiplier result
| ReadPC
| MultMIPS PathVar PathVar -- ^ Multiply
| WriteReg Int PathVar -- ^ Write register
| Store F.LSWidth PathVar PathVar -- ^ Store to memory (addr, value)
| Branch F.BCond PathVar PathVar -- ^ args are: cond target
| Jump Bool PathVar
| WriteBuf Int PathVar
deriving (Show, Read, Eq)
data ReadPort = RPBuf1 | RPBuf2 | RP1 | RP2 | RPImm
deriving (Eq, Ord, Show, Enum, Bounded)
instance PPrint ReadPort where
pshow = text . show
------------------------------------------------------------------------------
-- helpers
def :: PathVar -> Oper -> MicroOp' ()
def pv op = Mop () (Just pv) op
eff :: Oper -> MicroOp' ()
eff = Mop () Nothing
mopInfo :: MicroOp' i -> i
mopInfo (Mop i _ _) = i
--mopInfo (Eff i _) = i
--mopInfo (ParPair x _y) = mopInfo x
isBranch :: MicroOp' a -> Bool
isBranch (Mop _ _ (Jump _ _)) = True
isBranch (Mop _ _ (Branch _ _ _)) = True
isBranch _ = False
instance Ord a => Ord (MicroOp' a) where
compare x y = compare (mopInfo x) (mopInfo y)
instance PPrint PathVar where
pshow (PV i n) = char 'p' <> int i <> maybe empty pshow n
instance PPrint (MicroOp' Int) where
pshow (Mop i (Just pv) op) = ppMopId i <+> (pshow pv <+> text "<-" <+> pshow op)
pshow (Mop i Nothing ef) = ppMopId i <+> pshow ef
-- pshow (ParPair x y) = sep [pshow x, pshow y]
ppMopId :: (Show a) => a -> Doc
ppMopId i = char 'I' <> text (show i `padTo` 4)
where
padTo _ l | l `seq` False = undefined
padTo (x:xs) len = x : padTo xs (len - 1)
padTo [] len | len > 0 = replicate len ' '
| otherwise = []
instance PPrint Oper where
pshow op = case op of
Imm i -> text $ show i
ALU o s1 s2 -> pshow s1 <+> pshow o <+> pshow s2
Load w _ a -> char 'M' <> pshow w <> brackets (pshow a)
ReadReg r -> char '$' <> int r
ReadBuf b -> char 'B' <> int b
ReadPC -> text "PC"
WriteReg r p -> char '$' <> int r <+> text "-" <+> pshow p
WriteBuf b p -> char 'B' <> int b <+> text "<-" <+> pshow p
Store w a s -> char 'M' <> pshow w <> brackets (pshow a) <+>
text "<-" <+> pshow s
MultMIPS x y -> pshow x <+> char '*' <+> pshow y
Branch z c a -> text "if" <+> pshow c <+> cmp z <+>
text "then goto" <+> pshow a
Jump True a -> text "call" <+> pshow a
Jump False a -> text "goto" <+> pshow a
where cmp F.Z = text "== 0"
cmp F.NZ = text "/= 0"
{-
instance PPrint F.LSWidth where pshow w = text $ memsize w
where
memsize F.LSW_1 = "1"
memsize F.LSW_2 = "2"
memsize F.LSW_3 = "3"
memsize F.LSW_4 = "4"
-}
--instance PPrint Effect where
-- pshow ef = case ef of
instance PPrint F.ALUOp where
pshow o = text $ case o of
F.AO_ADD -> "+"
F.AO_ADDU -> "+"
F.AO_SUB -> "-"
F.AO_SUBU -> "-"
F.AO_AND -> "&"
F.AO_OR -> "|"
F.AO_NOR -> "nor"
F.AO_XOR -> "xor"
F.AO_SLL -> "<<"
F.AO_SRL -> ">>"
F.AO_SHR -> ">>>"
F.AO_SLT -> "<"
F.AO_SLE -> "<=" -- Set on less than or equal
F.AO_SEQ -> "==" -- Set on equal
F.AO_SNE -> "/=" -- Set on not equal
F.AO_TEST -> "#ignore:" -- Return operand 1