summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Pulte2016-11-15 13:55:57 +0000
committerChristopher Pulte2016-11-15 13:55:57 +0000
commit16e18906fb35b5a6810b8c215ff3ee51e26616fe (patch)
tree08d507dae245490e61cf329e4a888611720002a1
parent14e052bedf2bbe2ef6239972f4aa1b8e38764c9e (diff)
wrap state monad into list monoad for non-deterministic write exclusive operations
-rw-r--r--src/gen_lib/state.lem96
1 files changed, 62 insertions, 34 deletions
diff --git a/src/gen_lib/state.lem b/src/gen_lib/state.lem
index 98596b6d..02fe8094 100644
--- a/src/gen_lib/state.lem
+++ b/src/gen_lib/state.lem
@@ -3,32 +3,33 @@ open import Sail_impl_base
open import Sail_values
(* 'a is result type *)
-type State 's 'a = 's -> (either 'a string * 's)
type memstate = map integer memory_byte
type regstate = map string (vector bitU)
type sequential_state = <| regstate : regstate;
memstate : memstate;
- write_ea : maybe (integer * integer) |>
+ write_ea : maybe (write_kind * integer * integer);
+ last_exclusive_operation_was_load : bool|>
-type M 'a = State sequential_state 'a
-
-val return : forall 's 'a. 'a -> State 's 'a
-let return a s = (Left a,s)
+type M 'a = sequential_state -> list ((either 'a string) * sequential_state)
-val bind : forall 's 'a 'b. State 's 'a -> ('a -> State 's 'b) -> State 's 'b
-let bind m f s = match m s with
- | (Left a,s') -> f a s'
- | (Right error,s') -> (Right error,s')
- end
+val return : forall 'a. 'a -> M 'a
+let return a s = [(Left a,s)]
+
+val bind : forall 'a 'b. M 'a -> ('a -> M 'b) -> M 'b
+let bind m f (s : sequential_state) =
+ List.concatMap (function
+ | (Left a, s') -> f a s'
+ | (Right e, s') -> [(Right e, s')]
+ end) (m s)
let inline (>>=) = bind
-val (>>): forall 's 'b. State 's unit -> State 's 'b -> State 's 'b
+val (>>): forall 'b. M unit -> M 'b -> M 'b
let inline (>>) m n = m >>= fun _ -> n
-val exit : forall 's 'e 'a. 'e -> State 's 'a
-let exit _ s = (Right "exit",s)
+val exit : forall 'e 'a. 'e -> M 'a
+let exit _ s = [(Right "exit",s)]
val range : integer -> integer -> list integer
@@ -45,45 +46,72 @@ let set_reg state reg bitv =
val read_mem : end_flag -> bool -> read_kind -> vector bitU -> integer -> M (vector bitU)
-let read_mem endian dir _ addr sz state =
+let read_mem endian dir read_kind addr sz state =
let addr = integer_of_address (address_of_bitv addr) in
let addrs = range addr (addr+sz-1) in
let memory_value = List.map (fun addr -> Map_extra.find addr state.memstate) addrs in
let value = Sail_values.internal_mem_value endian dir memory_value in
- (Left value,state)
-
+ let is_exclusive = match read_kind with
+ | Sail_impl_base.Read_plain -> false
+ | Sail_impl_base.Read_tag -> failwith "Read_tag not implemented"
+ | Sail_impl_base.Read_tag_reserve -> failwith "Read_tag_reserve not implemented"
+ | Sail_impl_base.Read_reserve -> true
+ | Sail_impl_base.Read_acquire -> false
+ | Sail_impl_base.Read_exclusive -> true
+ | Sail_impl_base.Read_exclusive_acquire -> true
+ | Sail_impl_base.Read_stream -> false
+ end in
+
+ if is_exclusive
+ then [(Left value, <| state with last_exclusive_operation_was_load = true |>)]
+ else [(Left value, state)]
+
-val write_mem_address_value : write_kind -> address -> integer -> end_flag -> vector bitU -> M bool
-let write_mem_address_value _ addr sz endian v state =
- let addr = integer_of_address addr in
- let addrs = range addr (addr+sz-1) in
- let v = external_mem_value endian v in
- let addresses_with_value = List.zip addrs v in
- let mem = List.foldl (fun mem (addr,v) -> Map.insert addr v mem)
- state.memstate addresses_with_value in
- (Left true,<| state with memstate = mem |>)
val write_mem_ea : write_kind -> vector bitU -> integer -> M unit
-let write_mem_ea _ addr sz state =
+let write_mem_ea write_kind addr sz state =
let addr = integer_of_address (address_of_bitv addr) in
- (Left (), <| state with write_ea = Just (addr,sz) |>)
+ [(Left (), <| state with write_ea = Just (write_kind,addr,sz) |>)]
val write_mem_val : end_flag -> vector bitU -> M bool
let write_mem_val endian v state =
- let (addr,sz) = match state.write_ea with
+ let (write_kind,addr,sz) = match state.write_ea with
| Nothing -> failwith "write ea has not been announced yet"
| Just write_ea -> write_ea end in
let addrs = range addr (addr+sz-1) in
let v = external_mem_value endian v in
let addresses_with_value = List.zip addrs v in
- let mem = List.foldl (fun mem (addr,v) -> Map.insert addr v mem)
- state.memstate addresses_with_value in
- (Left true,<| state with memstate = mem |>)
+ let memstate = List.foldl (fun mem (addr,v) -> Map.insert addr v mem)
+ state.memstate addresses_with_value in
+
+ let is_exclusive = match write_kind with
+ | Sail_impl_base.Write_plain -> false
+ | Sail_impl_base.Write_tag -> failwith "Write_tag not implemented"
+ | Sail_impl_base.Write_tag_conditional -> failwith "Write_tag_conditional not implemented"
+ | Sail_impl_base.Write_conditional -> true
+ | Sail_impl_base.Write_release -> false
+ | Sail_impl_base.Write_exclusive -> true
+ | Sail_impl_base.Write_exclusive_release -> true
+ end in
+
+ if is_exclusive
+ then
+ let success =
+ (Left true, <| state with memstate = memstate;
+ last_exclusive_operation_was_load = false |>) in
+ let failure =
+ (Left false, <| state with last_exclusive_operation_was_load = false |>) in
+ if state.last_exclusive_operation_was_load
+ then [failure;success]
+ else [failure]
+ else [(Left true, <| state with memstate = memstate |>)]
+
+
val read_reg : register -> M (vector bitU)
let read_reg reg state =
let v = Map_extra.find (name_of_reg reg) state.regstate in
- (Left v,state)
+ [(Left v,state)]
let read_reg_range reg i j =
read_reg reg >>= fun rv ->
return (slice rv i j)
@@ -99,7 +127,7 @@ let read_reg_bitfield reg regfield =
val write_reg : register -> vector bitU -> M unit
let write_reg reg v state =
- (Left (),<| state with regstate = Map.insert (name_of_reg reg) v state.regstate |>)
+ [(Left (),<| state with regstate = Map.insert (name_of_reg reg) v state.regstate |>)]
let write_reg_range reg i j v =
read_reg reg >>= fun current_value ->
let new_value = update current_value i j v in