<commit_before>{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, MultiWayIf #-}
module Clash where
--import qualified Prelude as P
import Program
import Utility
import CSR
import Data.Int
import Data.Word
import Data.Bits
import Data.Char
import Data.Maybe
import qualified Data.List as L
import Control.Applicative
import Control.Monad
import Control.Monad.State
import Control.Monad.Trans
import Control.Monad.Trans.Maybe
import System.IO.Error
import qualified Data.Map as S
import ExecuteClash
import qualified Decode as D
import Clash.Prelude


data MMIOClash = MMIOClash { registers :: Vec 31 Int32, pc :: Int32, nextPC :: Int32 , store:: Maybe (Int32,Int32,(Bool,Bool,Bool,Bool)), load :: Int32, loadAddress :: Maybe (Int32,(Bool,Bool,Bool,Bool)), exception :: Bool }
              deriving (Show) -- Beurk, I need to use Word32 instead of Int32 for the addresses.

type MState = State MMIOClash
type MMState = MaybeT MState

extract :: Integral a => (Bool,Bool,Bool,Bool) -> Word32 -> a
extract byteen load  -- quot get rid of the bits on the right fromIntegral, those on the left.
	|(\(x,y,z,t)-> t) byteen == True  = fromIntegral load
	|(\(x,y,z,t)-> z) byteen == True  = fromIntegral (load `quot` 256)
	|(\(x,y,z,t)-> y) byteen == True  = fromIntegral (load `quot` 65536)
	|(\(x,y,z,t)-> x) byteen == True  = fromIntegral (load `quot` 16777216)

 
embed :: Integral a => (Bool,Bool,Bool,Bool) -> Word32 -> a
embed byteen store  -- quot get rid of the bits on the right fromIntegral, those on the left.
	|(\(x,y,z,t)-> t) byteen == True  = fromIntegral store
	|(\(x,y,z,t)-> z) byteen == True  = fromIntegral (store * 256)
	|(\(x,y,z,t)-> y) byteen == True  = fromIntegral (store * 65536)
	|(\(x,y,z,t)-> x) byteen == True  = fromIntegral (store * 16777216)

instance RiscvProgram MState Int32 where
  getRegister reg = state $ \comp -> (if reg == 0 then 0 else (registers comp) !! (fromIntegral reg-1), comp)
  setRegister reg val = state $ \comp ->((), if reg == 0 then comp else comp { registers = replace (fromIntegral reg-1) (fromIntegral val) (registers comp) })
-- Fake load and stores
  loadByte ina = state $ \comp -> let a = ina .&. (complement 3) 
                                      offset = mod ina 4 
                                      byteen | offset == 3 = (True,False,False,False)
                                             | offset == 2 = (False,True,False,False)
                                             | offset == 1 = (False,False,True,False)
                                             | offset == 0 = (False,False,False,True) in
                         (extract byteen (fromIntegral (load comp)), comp{loadAddress = Just $ (fromIntegral a, byteen)})
  loadHalf ina =state $ \comp -> let a = ina .&. (complement 3) 
                                     offset = mod ina 4 
                                     byteen | offset == 2 = (True,True,False,False)
                                            | offset == 0 = (False,False,True,True)
                                            | otherwise = (False,False,False,False) -- Should not happen
                         in
                         (extract byteen (fromIntegral (load comp)), comp{loadAddress = Just $ (fromIntegral a, byteen)})
  loadWord a = state $ \comp -> (extract (True,True,True,True) (fromIntegral (load comp)), comp{loadAddress = Just $ (fromIntegral a,(True,True,True,True))})
  loadDouble a = state $ \comp -> (0, comp)
  storeByte ina v = state $ \comp -> let a = ina .&. (complement 3) 
                                         offset = mod ina 4 
                                         byteen | offset == 3 = (True,False,False,False)
                                                | offset == 2 = (False,True,False,False)
                                                | offset == 1 = (False,False,True,False)
                                                | offset == 0 = (False,False,False,True)
                         in ((), comp{store=Just (fromIntegral a, embed byteen (fromIntegral v), byteen)})
  storeHalf ina v = state $ \comp ->let a = ina .&. (complement 3)
                                        offset = mod ina 4 
                                        byteen | offset == 2 = (True,True,False,False)
                                               | offset == 0 = (False,False,True,True)
                                               | otherwise = (False,False,False,False) -- Should not happen
                         in
                         ((), comp{store=Just (fromIntegral a, embed byteen (fromIntegral v), byteen)})
  storeWord  a v = state $ \comp -> ((), comp{store=Just (fromIntegral a, fromIntegral v,(True,True,True,True))})
  storeDouble  a v = state $ \comp -> ((), comp)
-- fake CSR
  getCSRField field = state $ \comp -> (0, comp)
  setCSRField field val = state $ \comp -> ((), comp)
  getPC = state $ \comp -> (pc comp, comp)
  setPC val = state $ \comp -> ((), comp { nextPC = fromIntegral val })
  commit = state $ \comp -> ((), comp { pc = nextPC comp })





oneStep :: Int32 -> MState ()
oneStep i = do 
  result <- runMaybeT $ do
    pc <- getPC
    setPC (pc + 4)
    execute (D.decode D.RV32I $ fromIntegral i)
    commit 
  case result of
    Nothing -> commit >> (state $ \comp -> ((), comp{exception = True})) -- early return
    Just r -> return r
<commit_msg>Add get priv mode in clash that was messing up a bit of everything through udefined behavior<commit_after>{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, MultiWayIf #-}
module Clash where
--import qualified Prelude as P
import Program
import Utility
import CSR
import Data.Int
import Data.Word
import Data.Bits
import Data.Char
import Data.Maybe
import qualified Data.List as L
import Control.Applicative
import Control.Monad
import Control.Monad.State
import Control.Monad.Trans
import Control.Monad.Trans.Maybe
import System.IO.Error
import qualified Data.Map as S
import ExecuteClash
import qualified Decode as D
import Clash.Prelude


data MMIOClash = MMIOClash { registers :: Vec 31 Int32, pc :: Int32, nextPC :: Int32 , store:: Maybe (Int32,Int32,(Bool,Bool,Bool,Bool)), load :: Int32, loadAddress :: Maybe (Int32,(Bool,Bool,Bool,Bool)), exception :: Bool }
              deriving (Show) -- Beurk, I need to use Word32 instead of Int32 for the addresses.

type MState = State MMIOClash
type MMState = MaybeT MState

extract :: Integral a => (Bool,Bool,Bool,Bool) -> Word32 -> a
extract byteen load  -- quot get rid of the bits on the right fromIntegral, those on the left.
	|(\(x,y,z,t)-> t) byteen == True  = fromIntegral load
	|(\(x,y,z,t)-> z) byteen == True  = fromIntegral (load `quot` 256)
	|(\(x,y,z,t)-> y) byteen == True  = fromIntegral (load `quot` 65536)
	|(\(x,y,z,t)-> x) byteen == True  = fromIntegral (load `quot` 16777216)

 
embed :: Integral a => (Bool,Bool,Bool,Bool) -> Word32 -> a
embed byteen store  -- quot get rid of the bits on the right fromIntegral, those on the left.
	|(\(x,y,z,t)-> t) byteen == True  = fromIntegral store
	|(\(x,y,z,t)-> z) byteen == True  = fromIntegral (store * 256)
	|(\(x,y,z,t)-> y) byteen == True  = fromIntegral (store * 65536)
	|(\(x,y,z,t)-> x) byteen == True  = fromIntegral (store * 16777216)

instance RiscvProgram MState Int32 where
  getRegister reg = state $ \comp -> (if reg == 0 then 0 else (registers comp) !! (fromIntegral reg-1), comp)
  setRegister reg val = state $ \comp ->((), if reg == 0 then comp else comp { registers = replace (fromIntegral reg-1) (fromIntegral val) (registers comp) })
-- Fake load and stores
  loadByte ina = state $ \comp -> let a = ina .&. (complement 3) 
                                      offset = mod ina 4 
                                      byteen | offset == 3 = (True,False,False,False)
                                             | offset == 2 = (False,True,False,False)
                                             | offset == 1 = (False,False,True,False)
                                             | offset == 0 = (False,False,False,True) in
                         (extract byteen (fromIntegral (load comp)), comp{loadAddress = Just $ (fromIntegral a, byteen)})
  loadHalf ina =state $ \comp -> let a = ina .&. (complement 3) 
                                     offset = mod ina 4 
                                     byteen | offset == 2 = (True,True,False,False)
                                            | offset == 0 = (False,False,True,True)
                                            | otherwise = (False,False,False,False) -- Should not happen
                         in
                         (extract byteen (fromIntegral (load comp)), comp{loadAddress = Just $ (fromIntegral a, byteen)})
  loadWord a = state $ \comp -> (extract (True,True,True,True) (fromIntegral (load comp)), comp{loadAddress = Just $ (fromIntegral a,(True,True,True,True))})
  loadDouble a = state $ \comp -> (0, comp)
  storeByte ina v = state $ \comp -> let a = ina .&. (complement 3) 
                                         offset = mod ina 4 
                                         byteen | offset == 3 = (True,False,False,False)
                                                | offset == 2 = (False,True,False,False)
                                                | offset == 1 = (False,False,True,False)
                                                | offset == 0 = (False,False,False,True)
                         in ((), comp{store=Just (fromIntegral a, embed byteen (fromIntegral v), byteen)})
  storeHalf ina v = state $ \comp ->let a = ina .&. (complement 3)
                                        offset = mod ina 4 
                                        byteen | offset == 2 = (True,True,False,False)
                                               | offset == 0 = (False,False,True,True)
                                               | otherwise = (False,False,False,False) -- Should not happen
                         in
                         ((), comp{store=Just (fromIntegral a, embed byteen (fromIntegral v), byteen)})
  storeWord  a v = state $ \comp -> ((), comp{store=Just (fromIntegral a, fromIntegral v,(True,True,True,True))})
  storeDouble  a v = state $ \comp -> ((), comp)
-- fake CSR
  getCSRField field = state $ \comp -> (0, comp)
  setCSRField field val = state $ \comp -> ((), comp)
  getPC = state $ \comp -> (pc comp, comp)
  setPC val = state $ \comp -> ((), comp { nextPC = fromIntegral val })
  commit = state $ \comp -> ((), comp { pc = nextPC comp })
  getPrivMode = state $ \comp -> (Machine , comp) 
  setPrivMode m = state $ \comp -> ((), comp)
 




oneStep :: Int32 -> MState ()
oneStep i = do 
  result <- runMaybeT $ do
    pc <- getPC
    setPC (pc + 4)
    execute (D.decode D.RV32I $ fromIntegral i)
  case result of
    Nothing -> commit >> (state $ \comp -> ((), comp{exception = True})) -- early return
    Just r -> commit >> return r -- this is a ()

{'fraction_non_alphanumeric': 0.12765175865552392, 'fraction_numerical': 0.016530443566902378, 'mean_word_length': 1.935309973045822, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 60, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1245609', 'n_tokens_mistral': 3305, 'n_tokens_neox': 3097, 'n_words': 1027}