summaryrefslogtreecommitdiff
path: root/src/gen_lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/gen_lib')
-rw-r--r--src/gen_lib/prompt.lem40
-rw-r--r--src/gen_lib/prompt_monad.lem204
-rw-r--r--src/gen_lib/sail_operators.lem1
-rw-r--r--src/gen_lib/sail_operators_bitlists.lem1
-rw-r--r--src/gen_lib/sail_operators_mwords.lem1
-rw-r--r--src/gen_lib/sail_values.lem126
-rw-r--r--src/gen_lib/state.lem1
-rw-r--r--src/gen_lib/state_monad.lem56
8 files changed, 237 insertions, 193 deletions
diff --git a/src/gen_lib/prompt.lem b/src/gen_lib/prompt.lem
index d398ab52..756bb699 100644
--- a/src/gen_lib/prompt.lem
+++ b/src/gen_lib/prompt.lem
@@ -1,24 +1,24 @@
open import Pervasives_extra
-open import Sail_impl_base
+(*open import Sail_impl_base*)
open import Sail_values
open import Prompt_monad
open import {isabelle} `Prompt_monad_extras`
-val iter_aux : forall 'a 'e. integer -> (integer -> 'a -> M unit 'e) -> list 'a -> M unit 'e
+val iter_aux : forall 'rv 'a 'e. integer -> (integer -> 'a -> monad 'rv unit 'e) -> list 'a -> monad 'rv unit 'e
let rec iter_aux i f xs = match xs with
| x :: xs -> f i x >> iter_aux (i + 1) f xs
| [] -> return ()
end
-val iteri : forall 'a 'e. (integer -> 'a -> M unit 'e) -> list 'a -> M unit 'e
+val iteri : forall 'rv 'a 'e. (integer -> 'a -> monad 'rv unit 'e) -> list 'a -> monad 'rv unit 'e
let iteri f xs = iter_aux 0 f xs
-val iter : forall 'a 'e. ('a -> M unit 'e) -> list 'a -> M unit 'e
+val iter : forall 'rv 'a 'e. ('a -> monad 'rv unit 'e) -> list 'a -> monad 'rv unit 'e
let iter f xs = iteri (fun _ x -> f x) xs
-val foreachM_inc : forall 'vars 'e. (integer * integer * integer) -> 'vars ->
- (integer -> 'vars -> M 'vars 'e) -> M 'vars 'e
+val foreachM_inc : forall 'rv 'vars 'e. (integer * integer * integer) -> 'vars ->
+ (integer -> 'vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e
let rec foreachM_inc (i,stop,by) vars body =
if (by > 0 && i <= stop) || (by < 0 && stop <= i)
then
@@ -27,8 +27,8 @@ let rec foreachM_inc (i,stop,by) vars body =
else return vars
-val foreachM_dec : forall 'vars 'e. (integer * integer * integer) -> 'vars ->
- (integer -> 'vars -> M 'vars 'e) -> M 'vars 'e
+val foreachM_dec : forall 'rv 'vars 'e. (integer * integer * integer) -> 'vars ->
+ (integer -> 'vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e
let rec foreachM_dec (i,stop,by) vars body =
if (by > 0 && i >= stop) || (by < 0 && stop >= i)
then
@@ -40,21 +40,21 @@ val while_PP : forall 'vars. 'vars -> ('vars -> bool) -> ('vars -> 'vars) -> 'va
let rec while_PP vars cond body =
if cond vars then while_PP (body vars) cond body else vars
-val while_PM : forall 'vars 'e. 'vars -> ('vars -> bool) ->
- ('vars -> M 'vars 'e) -> M 'vars 'e
+val while_PM : forall 'rv 'vars 'e. 'vars -> ('vars -> bool) ->
+ ('vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e
let rec while_PM vars cond body =
if cond vars then
body vars >>= fun vars -> while_PM vars cond body
else return vars
-val while_MP : forall 'vars 'e. 'vars -> ('vars -> M bool 'e) ->
- ('vars -> 'vars) -> M 'vars 'e
+val while_MP : forall 'rv 'vars 'e. 'vars -> ('vars -> monad 'rv bool 'e) ->
+ ('vars -> 'vars) -> monad 'rv 'vars 'e
let rec while_MP vars cond body =
cond vars >>= fun cond_val ->
if cond_val then while_MP (body vars) cond body else return vars
-val while_MM : forall 'vars 'e. 'vars -> ('vars -> M bool 'e) ->
- ('vars -> M 'vars 'e) -> M 'vars 'e
+val while_MM : forall 'rv 'vars 'e. 'vars -> ('vars -> monad 'rv bool 'e) ->
+ ('vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e
let rec while_MM vars cond body =
cond vars >>= fun cond_val ->
if cond_val then
@@ -66,21 +66,21 @@ let rec until_PP vars cond body =
let vars = body vars in
if (cond vars) then vars else until_PP (body vars) cond body
-val until_PM : forall 'vars 'e. 'vars -> ('vars -> bool) ->
- ('vars -> M 'vars 'e) -> M 'vars 'e
+val until_PM : forall 'rv 'vars 'e. 'vars -> ('vars -> bool) ->
+ ('vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e
let rec until_PM vars cond body =
body vars >>= fun vars ->
if (cond vars) then return vars else until_PM vars cond body
-val until_MP : forall 'vars 'e. 'vars -> ('vars -> M bool 'e) ->
- ('vars -> 'vars) -> M 'vars 'e
+val until_MP : forall 'rv 'vars 'e. 'vars -> ('vars -> monad 'rv bool 'e) ->
+ ('vars -> 'vars) -> monad 'rv 'vars 'e
let rec until_MP vars cond body =
let vars = body vars in
cond vars >>= fun cond_val ->
if cond_val then return vars else until_MP vars cond body
-val until_MM : forall 'vars 'e. 'vars -> ('vars -> M bool 'e) ->
- ('vars -> M 'vars 'e) -> M 'vars 'e
+val until_MM : forall 'rv 'vars 'e. 'vars -> ('vars -> monad 'rv bool 'e) ->
+ ('vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e
let rec until_MM vars cond body =
body vars >>= fun vars ->
cond vars >>= fun cond_val ->
diff --git a/src/gen_lib/prompt_monad.lem b/src/gen_lib/prompt_monad.lem
index 45733caa..ff5e3726 100644
--- a/src/gen_lib/prompt_monad.lem
+++ b/src/gen_lib/prompt_monad.lem
@@ -1,70 +1,88 @@
open import Pervasives_extra
-open import Sail_impl_base
+(*open import Sail_impl_base*)
+open import Sail_instr_kinds
open import Sail_values
-type M 'a 'e = outcome 'a 'e
-
-val return : forall 'a 'e. 'a -> M 'a 'e
+type register_name = string
+
+type monad 'regval 'a 'e =
+ | Done of 'a
+ | Read_mem of read_kind * integer * integer * (list memory_byte -> monad 'regval 'a 'e)
+ (* Tell the system a write is imminent, at address lifted, of size nat *)
+ | Write_ea of write_kind * integer * integer * monad 'regval 'a 'e
+ (* Request the result of store-exclusive *)
+ | Excl_res of (bool -> monad 'regval 'a 'e)
+ (* Request to write memory at last signalled address. Memory value should be 8
+ times the size given in ea signal *)
+ | Write_memv of list memory_byte * (bool -> monad 'regval 'a 'e)
+ (* Request a memory barrier *)
+ | Barrier of barrier_kind * monad 'regval 'a 'e
+ (* Request to read register, will track dependency when mode.track_values *)
+ | Read_reg of register_name * ('regval -> monad 'regval 'a 'e)
+ (* Request to write register *)
+ | Write_reg of register_name * 'regval * monad 'regval 'a 'e
+ (*Result of a failed assert with possible error message to report*)
+ | Fail of string
+ | Error of string
+ (* Exception of type 'e *)
+ | Exception of 'e
+ (* TODO: Reading/writing tags *)
+
+val return : forall 'rv 'a 'e. 'a -> monad 'rv 'a 'e
let return a = Done a
-val bind : forall 'a 'b 'e. M 'a 'e -> ('a -> M 'b 'e) -> M 'b 'e
+val bind : forall 'rv 'a 'b 'e. monad 'rv 'a 'e -> ('a -> monad 'rv 'b 'e) -> monad 'rv 'b 'e
let rec bind m f = match m with
- | Done a -> f a
- | Read_mem descr k -> Read_mem descr (fun v -> let (o,opt) = k v in (bind o f,opt))
- | Read_reg descr k -> Read_reg descr (fun v -> let (o,opt) = k v in (bind o f,opt))
- | Write_memv descr k -> Write_memv descr (fun v -> let (o,opt) = k v in (bind o f,opt))
- | Excl_res k -> Excl_res (fun v -> let (o,opt) = k v in (bind o f,opt))
- | Write_ea descr o_s -> Write_ea descr (let (o,opt) = o_s in (bind o f,opt))
- | Barrier descr o_s -> Barrier descr (let (o,opt) = o_s in (bind o f,opt))
- | Footprint o_s -> Footprint (let (o,opt) = o_s in (bind o f,opt))
- | Write_reg descr o_s -> Write_reg descr (let (o,opt) = o_s in (bind o f,opt))
- | Escape descr -> Escape descr
- | Fail descr -> Fail descr
- | Error descr -> Error descr
- | Exception e -> Exception e
- | Internal descr o_s -> Internal descr (let (o,opt) = o_s in (bind o f ,opt))
+ | Done a -> f a
+ | Read_mem rk a sz k -> Read_mem rk a sz (fun v -> bind (k v) f)
+ | Write_memv descr k -> Write_memv descr (fun v -> bind (k v) f)
+ | Read_reg descr k -> Read_reg descr (fun v -> bind (k v) f)
+ | Excl_res k -> Excl_res (fun v -> bind (k v) f)
+ | Write_ea wk a sz k -> Write_ea wk a sz (bind k f)
+ | Barrier bk k -> Barrier bk (bind k f)
+ | Write_reg r v k -> Write_reg r v (bind k f)
+ | Fail descr -> Fail descr
+ | Error descr -> Error descr
+ | Exception e -> Exception e
end
let inline (>>=) = bind
-val (>>) : forall 'b 'e. M unit 'e -> M 'b 'e -> M 'b 'e
+val (>>) : forall 'rv 'b 'e. monad 'rv unit 'e -> monad 'rv 'b 'e -> monad 'rv 'b 'e
let inline (>>) m n = m >>= fun (_ : unit) -> n
-val exit : forall 'a 'e. unit -> M 'a 'e
-let exit () = Fail Nothing
+val exit : forall 'rv 'a 'e. unit -> monad 'rv 'a 'e
+let exit () = Fail "exit"
-val assert_exp : forall 'e. bool -> string -> M unit 'e
-let assert_exp exp msg = if exp then Done () else Fail (Just msg)
+val assert_exp : forall 'rv 'e. bool -> string -> monad 'rv unit 'e
+let assert_exp exp msg = if exp then Done () else Fail msg
-val throw : forall 'a 'e. 'e -> M 'a 'e
+val throw : forall 'rv 'a 'e. 'e -> monad 'rv 'a 'e
let throw e = Exception e
-val try_catch : forall 'a 'e1 'e2. M 'a 'e1 -> ('e1 -> M 'a 'e2) -> M 'a 'e2
+val try_catch : forall 'rv 'a 'e1 'e2. monad 'rv 'a 'e1 -> ('e1 -> monad 'rv 'a 'e2) -> monad 'rv 'a 'e2
let rec try_catch m h = match m with
- | Done a -> Done a
- | Read_mem descr k -> Read_mem descr (fun v -> let (o,opt) = k v in (try_catch o h,opt))
- | Read_reg descr k -> Read_reg descr (fun v -> let (o,opt) = k v in (try_catch o h,opt))
- | Write_memv descr k -> Write_memv descr (fun v -> let (o,opt) = k v in (try_catch o h,opt))
- | Excl_res k -> Excl_res (fun v -> let (o,opt) = k v in (try_catch o h,opt))
- | Write_ea descr o_s -> Write_ea descr (let (o,opt) = o_s in (try_catch o h,opt))
- | Barrier descr o_s -> Barrier descr (let (o,opt) = o_s in (try_catch o h,opt))
- | Footprint o_s -> Footprint (let (o,opt) = o_s in (try_catch o h,opt))
- | Write_reg descr o_s -> Write_reg descr (let (o,opt) = o_s in (try_catch o h,opt))
- | Escape descr -> Escape descr
- | Fail descr -> Fail descr
- | Error descr -> Error descr
- | Exception e -> h e
- | Internal descr o_s -> Internal descr (let (o,opt) = o_s in (try_catch o h ,opt))
+ | Done a -> Done a
+ | Read_mem rk a sz k -> Read_mem rk a sz (fun v -> try_catch (k v) h)
+ | Write_memv descr k -> Write_memv descr (fun v -> try_catch (k v) h)
+ | Read_reg descr k -> Read_reg descr (fun v -> try_catch (k v) h)
+ | Excl_res k -> Excl_res (fun v -> try_catch (k v) h)
+ | Write_ea wk a sz k -> Write_ea wk a sz (try_catch k h)
+ | Barrier bk k -> Barrier bk (try_catch k h)
+ | Write_reg r v k -> Write_reg r v (try_catch k h)
+ | Fail descr -> Fail descr
+ | Error descr -> Error descr
+ | Exception e -> h e
end
(* For early return, we abuse exceptions by throwing and catching
the return value. The exception type is "either 'r 'e", where "Right e"
represents a proper exception and "Left r" an early return of value "r". *)
-type MR 'a 'r 'e = M 'a (either 'r 'e)
+type monadR 'rv 'a 'r 'e = monad 'rv 'a (either 'r 'e)
-val early_return : forall 'a 'r 'e. 'r -> MR 'a 'r 'e
+val early_return : forall 'rv 'a 'r 'e. 'r -> monadR 'rv 'a 'r 'e
let early_return r = throw (Left r)
-val catch_early_return : forall 'a 'e. MR 'a 'a 'e -> M 'a 'e
+val catch_early_return : forall 'rv 'a 'e. monadR 'rv 'a 'a 'e -> monad 'rv 'a 'e
let catch_early_return m =
try_catch m
(function
@@ -73,11 +91,11 @@ let catch_early_return m =
end)
(* Lift to monad with early return by wrapping exceptions *)
-val liftR : forall 'a 'r 'e. M 'a 'e -> MR 'a 'r 'e
+val liftR : forall 'rv 'a 'r 'e. monad 'rv 'a 'e -> monadR 'rv 'a 'r 'e
let liftR m = try_catch m (fun e -> throw (Right e))
(* Catch exceptions in the presence of early returns *)
-val try_catchR : forall 'a 'r 'e1 'e2. MR 'a 'r 'e1 -> ('e1 -> MR 'a 'r 'e2) -> MR 'a 'r 'e2
+val try_catchR : forall 'rv 'a 'r 'e1 'e2. monadR 'rv 'a 'r 'e1 -> ('e1 -> monadR 'rv 'a 'r 'e2) -> monadR 'rv 'a 'r 'e2
let try_catchR m h =
try_catch m
(function
@@ -86,59 +104,62 @@ let try_catchR m h =
end)
-val read_mem : forall 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> M 'b 'e
+val read_mem : forall 'rv 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monad 'rv 'b 'e
let read_mem rk addr sz =
- let addr = address_lifted_of_bitv (bits_of addr) in
- let sz = natFromInteger sz in
- let k memory_value =
- let bitv = of_bits (internal_mem_value memory_value) in
- (Done bitv,Nothing) in
- Read_mem (rk,addr,sz) k
-
-val excl_result : forall 'e. unit -> M bool 'e
+ let addr = unsigned addr in
+ let k bytes =
+ let bitv = bits_of_bytes (List.reverse bytes) in
+ (Done bitv) in
+ Read_mem rk addr sz k
+
+val excl_result : forall 'rv 'e. unit -> monad 'rv bool 'e
let excl_result () =
- let k successful = (return successful,Nothing) in
+ let k successful = (return successful) in
Excl_res k
-val write_mem_ea : forall 'a 'e. Bitvector 'a => write_kind -> 'a -> integer -> M unit 'e
-let write_mem_ea wk addr sz =
- let addr = address_lifted_of_bitv (bits_of addr) in
- let sz = natFromInteger sz in
- Write_ea (wk,addr,sz) (Done (),Nothing)
-
-val write_mem_val : forall 'a 'e. Bitvector 'a => 'a -> M bool 'e
-let write_mem_val v =
- let v = external_mem_value (bits_of v) in
- let k successful = (return successful,Nothing) in
- Write_memv v k
-
-val read_reg_aux : forall 'a 'e. Bitvector 'a => reg_name -> M 'a 'e
-let read_reg_aux reg =
- let k reg_value =
- let v = of_bits (internal_reg_value reg_value) in
- (Done v,Nothing) in
- Read_reg reg k
+val write_mem_ea : forall 'rv 'a 'e. Bitvector 'a => write_kind -> 'a -> integer -> monad 'rv unit 'e
+let write_mem_ea wk addr sz = Write_ea wk (unsigned addr) sz (Done ())
+val write_mem_val : forall 'rv 'a 'e. Bitvector 'a => 'a -> monad 'rv bool 'e
+let write_mem_val v = match bytes_of_bits v with
+ | Just v ->
+ let k successful = (return successful) in
+ Write_memv (List.reverse v) k
+ | Nothing -> fail "write_mem_val"
+end
+
+val read_reg : forall 's 'rv 'a 'e. register_ref 's 'rv 'a -> monad 'rv 'a 'e
let read_reg reg =
- read_reg_aux (external_reg_whole reg)
+ let k v =
+ match reg.of_regval v with
+ | Just v -> Done v
+ | Nothing -> Error "read_reg: unrecognised value"
+ end
+ in
+ Read_reg reg.name k
+
+(* TODO
+val read_reg_range : forall 's 'r 'rv 'a 'e. Bitvector 'a => register_ref 's 'rv 'r -> integer -> integer -> monad 'rv 'a 'e
let read_reg_range reg i j =
- read_reg_aux (external_reg_slice reg (natFromInteger i,natFromInteger j))
+ read_reg_aux of_bits (external_reg_slice reg (natFromInteger i,natFromInteger j))
+
let read_reg_bit reg i =
- read_reg_aux (external_reg_slice reg (natFromInteger i,natFromInteger i)) >>= fun v ->
+ read_reg_aux (fun v -> v) (external_reg_slice reg (natFromInteger i,natFromInteger i)) >>= fun v ->
return (extract_only_element v)
+
let read_reg_field reg regfield =
- read_reg_aux (external_reg_field_whole reg regfield.field_name)
+ read_reg_aux (external_reg_field_whole reg regfield)
+
let read_reg_bitfield reg regfield =
- read_reg_aux (external_reg_field_whole reg regfield.field_name) >>= fun v ->
- return (extract_only_element v)
+ read_reg_aux (external_reg_field_whole reg regfield) >>= fun v ->
+ return (extract_only_element v)*)
let reg_deref = read_reg
-val write_reg_aux : forall 'a 'e. Bitvector 'a => reg_name -> 'a -> M unit 'e
-let write_reg_aux reg_name v =
- let regval = external_reg_value reg_name (bits_of v) in
- Write_reg (reg_name,regval) (Done (), Nothing)
+val write_reg : forall 's 'rv 'a 'e. register_ref 's 'rv 'a -> 'a -> monad 'rv unit 'e
+let write_reg reg v = Write_reg reg.name (reg.regval_of v) (Done ())
+(* TODO
let write_reg reg v =
write_reg_aux (external_reg_whole reg) v
let write_reg_range reg i j v =
@@ -149,20 +170,17 @@ let write_reg_pos reg i v =
let write_reg_bit = write_reg_pos
let write_reg_field reg regfield v =
write_reg_aux (external_reg_field_whole reg regfield.field_name) v
-(*let write_reg_field_bit reg regfield bit =
+let write_reg_field_bit reg regfield bit =
write_reg_aux (external_reg_field_whole reg regfield.field_name)
- (Vector [bit] 0 (is_inc_of_reg reg))*)
+ (Vector [bit] 0 (is_inc_of_reg reg))
let write_reg_field_range reg regfield i j v =
write_reg_aux (external_reg_field_slice reg regfield.field_name (natFromInteger i,natFromInteger j)) v
let write_reg_field_pos reg regfield i v =
write_reg_field_range reg regfield i i [v]
-let write_reg_field_bit = write_reg_field_pos
-
-let write_reg_ref (reg, v) = write_reg reg v
-
-val barrier : forall 'e. barrier_kind -> M unit 'e
-let barrier bk = Barrier bk (Done (), Nothing)
+let write_reg_field_bit = write_reg_field_pos*)
+val barrier : forall 'rv 'e. barrier_kind -> monad 'rv unit 'e
+let barrier bk = Barrier bk (Done ())
-val footprint : forall 'e. M unit 'e
-let footprint = Footprint (Done (),Nothing)
+(*val footprint : forall 'rv 'e. monad 'rv unit 'e
+let footprint = Footprint (Done ())*)
diff --git a/src/gen_lib/sail_operators.lem b/src/gen_lib/sail_operators.lem
index ada91bd0..7d6b156b 100644
--- a/src/gen_lib/sail_operators.lem
+++ b/src/gen_lib/sail_operators.lem
@@ -1,6 +1,5 @@
open import Pervasives_extra
open import Machine_word
-open import Sail_impl_base
open import Sail_values
(*** Bit vector operations *)
diff --git a/src/gen_lib/sail_operators_bitlists.lem b/src/gen_lib/sail_operators_bitlists.lem
index d2a2aea1..5658dc21 100644
--- a/src/gen_lib/sail_operators_bitlists.lem
+++ b/src/gen_lib/sail_operators_bitlists.lem
@@ -1,6 +1,5 @@
open import Pervasives_extra
open import Machine_word
-open import Sail_impl_base
open import Sail_values
open import Sail_operators
diff --git a/src/gen_lib/sail_operators_mwords.lem b/src/gen_lib/sail_operators_mwords.lem
index bd7ef2b4..fcc3153b 100644
--- a/src/gen_lib/sail_operators_mwords.lem
+++ b/src/gen_lib/sail_operators_mwords.lem
@@ -1,6 +1,5 @@
open import Pervasives_extra
open import Machine_word
-open import Sail_impl_base
open import Sail_values
open import Sail_operators
diff --git a/src/gen_lib/sail_values.lem b/src/gen_lib/sail_values.lem
index 4cbcc269..34e4bd98 100644
--- a/src/gen_lib/sail_values.lem
+++ b/src/gen_lib/sail_values.lem
@@ -2,7 +2,7 @@
open import Pervasives_extra
open import Machine_word
-open import Sail_impl_base
+(*open import Sail_impl_base*)
type ii = integer
@@ -57,6 +57,7 @@ val repeat : forall 'a. list 'a -> integer -> list 'a
let rec repeat xs n =
if n <= 0 then []
else xs ++ repeat xs (n-1)
+declare {isabelle} termination_argument repeat = automatic
let duplicate_to_list bit length = repeat [bit] length
@@ -66,6 +67,7 @@ let rec replace bs (n : integer) b' = match bs with
if n = 0 then b' :: bs
else b :: replace bs (n - 1) b'
end
+declare {isabelle} termination_argument replace = automatic
let upper n = n
@@ -135,7 +137,7 @@ end
let cast_bit_bool = bool_of_bitU
-let bit_lifted_of_bitU = function
+(*let bit_lifted_of_bitU = function
| B0 -> Bitl_zero
| B1 -> Bitl_one
| BU -> Bitl_undef
@@ -157,7 +159,7 @@ let bitU_of_bit_lifted = function
| Bitl_one -> B1
| Bitl_undef -> BU
| Bitl_unknown -> failwith "bitU_of_bit_lifted Bitl_unknown"
- end
+ end*)
let not_bit = function
| B1 -> B0
@@ -200,6 +202,7 @@ val bits_of_nat_aux : natural -> list bitU
let rec bits_of_nat_aux x =
if x = 0 then []
else (if x mod 2 = 1 then B1 else B0) :: bits_of_nat_aux (x / 2)
+declare {isabelle} termination_argument bits_of_nat_aux = automatic
let bits_of_nat n = List.reverse (bits_of_nat_aux n)
val nat_of_bits : list bitU -> natural
@@ -239,6 +242,7 @@ let signed_of_bits bits =
val pad_bitlist : bitU -> list bitU -> integer -> list bitU
let rec pad_bitlist b bits n =
if n <= 0 then bits else pad_bitlist b (b :: bits) (n - 1)
+declare {isabelle} termination_argument pad_bitlist = automatic
let ext_bits pad len bits =
let longer = len - (integerFromNat (List.length bits)) in
@@ -259,6 +263,7 @@ let rec add_one_bit_ignore_overflow_aux bits = match bits with
| B1 :: bits -> B0 :: add_one_bit_ignore_overflow_aux bits
| BU :: _ -> failwith "add_one_bit_ignore_overflow: undefined bit"
end
+declare {isabelle} termination_argument add_one_bit_ignore_overflow_aux = automatic
let add_one_bit_ignore_overflow bits =
List.reverse (add_one_bit_ignore_overflow_aux (List.reverse bits))
@@ -300,6 +305,7 @@ let rec hexstring_of_bits bs = match bs with
end
| _ -> Nothing
end
+declare {isabelle} termination_argument hexstring_of_bits = automatic
let show_bitlist bs =
match hexstring_of_bits bs with
@@ -370,6 +376,21 @@ let extract_only_element = function
| _ -> failwith "extract_only_element called for list with more elements"
end
+(* just_list takes a list of maybes and returns Just xs if all elements have
+ a value, and Nothing if one of the elements is Nothing. *)
+val just_list : forall 'a. list (maybe 'a) -> maybe (list 'a)
+let rec just_list [] = Just []
+and just_list (x :: xs) =
+ match (x, just_list xs) with
+ | (Just x, Just xs) -> Just (x :: xs)
+ | (_, _) -> Nothing
+ end
+declare {isabelle} termination_argument just_list = automatic
+
+lemma just_list_spec:
+ ((forall xs. (just_list xs = Nothing) <-> List.elem Nothing xs) &&
+ (forall xs es. (just_list xs = Just es) <-> (xs = List.map Just es)))
+
(*** Machine words *)
val length_mword : forall 'a. mword 'a -> integer
@@ -503,14 +524,24 @@ let string_of_bv v = show_bitlist (bits_of v)
(*** Bytes and addresses *)
-val byte_chunks : forall 'a. nat -> list 'a -> list (list 'a)
-let rec byte_chunks n list = match (n,list) with
- | (0,_) -> []
- | (n+1, a::b::c::d::e::f::g::h::rest) -> [a;b;c;d;e;f;g;h] :: byte_chunks n rest
- | _ -> failwith "byte_chunks not given enough bits"
+type memory_byte = list bitU
+
+val byte_chunks : forall 'a. list 'a -> maybe (list (list 'a))
+let rec byte_chunks bs = match bs with
+ | [] -> Just []
+ | a::b::c::d::e::f::g::h::rest ->
+ Maybe.bind (byte_chunks rest) (fun rest -> Just ([a;b;c;d;e;f;g;h] :: rest))
+ | _ -> Nothing
end
+declare {isabelle} termination_argument byte_chunks = automatic
+
+val bytes_of_bits : forall 'a. Bitvector 'a => 'a -> maybe (list memory_byte)
+let bytes_of_bits bs = byte_chunks (bits_of bs)
-val bitv_of_byte_lifteds : list Sail_impl_base.byte_lifted -> list bitU
+val bits_of_bytes : forall 'a. Bitvector 'a => list memory_byte -> 'a
+let bits_of_bytes bs = of_bits (List.concat (List.map bits_of bs))
+
+(*val bitv_of_byte_lifteds : list Sail_impl_base.byte_lifted -> list bitU
let bitv_of_byte_lifteds v =
foldl (fun x (Byte_lifted y) -> x ++ (List.map bitU_of_bit_lifted y)) [] v
@@ -545,10 +576,13 @@ let address_lifted_of_bitv v =
end in
Address_lifted byte_lifteds maybe_address_integer
+val bitv_of_address_lifted : address_lifted -> list bitU
+let bitv_of_address_lifted (Address_lifted bs _) = bitv_of_byte_lifteds bs
+
val address_of_bitv : list bitU -> address
let address_of_bitv v =
let bytes = bytes_of_bitv v in
- address_of_byte_list bytes
+ address_of_byte_list bytes*)
let rec reverse_endianness_list bits =
if List.length bits <= 8 then bits else
@@ -560,7 +594,7 @@ let reverse_endianness v = of_bits (reverse_endianness_list (bits_of v))
(*** Registers *)
-type register_field = string
+(*type register_field = string
type register_field_index = string * (integer * integer) (* name, start and end *)
type register =
@@ -570,14 +604,19 @@ type register =
bool * (* is increasing *)
list register_field_index
| UndefinedRegister of integer (* length *)
- | RegisterPair of register * register
+ | RegisterPair of register * register*)
-type register_ref 'regstate 'a =
- <| reg_name : string;
- reg_start : integer;
- reg_is_inc : bool;
+type register_ref 'regstate 'regval 'a =
+ <| name : string;
+ is_inc : bool;
read_from : 'regstate -> 'a;
- write_to : 'regstate -> 'a -> 'regstate |>
+ write_to : 'regstate -> 'a -> 'regstate;
+ of_regval : 'regval -> maybe 'a;
+ regval_of : 'a -> 'regval |>
+
+type register_accessors 'regstate 'regval =
+ ((string -> 'regstate -> maybe 'regval) *
+ (string -> 'regval -> 'regstate -> maybe 'regstate))
type field_ref 'regtype 'a =
<| field_name : string;
@@ -586,7 +625,7 @@ type field_ref 'regtype 'a =
get_field : 'regtype -> 'a;
set_field : 'regtype -> 'a -> 'regtype |>
-let name_of_reg = function
+(*let name_of_reg = function
| Register name _ _ _ _ -> name
| UndefinedRegister _ -> failwith "name_of_reg UndefinedRegister"
| RegisterPair _ _ -> failwith "name_of_reg RegisterPair"
@@ -597,7 +636,7 @@ let size_of_reg = function
| UndefinedRegister size -> size
| RegisterPair _ _ -> failwith "size_of_reg RegisterPair"
end
-
+
let start_of_reg = function
| Register _ _ start _ _ -> start
| UndefinedRegister _ -> failwith "start_of_reg UndefinedRegister"
@@ -638,11 +677,11 @@ let register_field_indices register rfield =
let register_field_indices_nat reg regfield=
let (i,j) = register_field_indices reg regfield in
- (natFromInteger i,natFromInteger j)
+ (natFromInteger i,natFromInteger j)*)
-let rec external_reg_value reg_name v =
+(*let rec external_reg_value reg_name v =
let (internal_start, external_start, direction) =
- match reg_name with
+ match reg_name with
| Reg _ start size dir ->
(start, (if dir = D_increasing then start else (start - (size +1))), dir)
| Reg_slice _ reg_start dir (slice_start, _) ->
@@ -653,10 +692,10 @@ let rec external_reg_value reg_name v =
slice_start, dir)
| Reg_f_slice _ reg_start dir _ _ (slice_start, _) ->
((if dir = D_increasing then slice_start else (reg_start - slice_start)),
- slice_start, dir)
+ slice_start, dir)
end in
let bits = bit_lifteds_of_bitv v in
- <| rv_bits = bits;
+ <| rv_bits = bits;
rv_dir = direction;
rv_start = external_start;
rv_start_internal = internal_start |>
@@ -672,42 +711,45 @@ let external_slice (d:direction) (start:nat) ((i,j):(nat*nat)) =
match d with
(*This is the case the thread/concurrecny model expects, so no change needed*)
| D_increasing -> (i,j)
- | D_decreasing -> let slice_i = start - i in
+ | D_decreasing -> let slice_i = start - i in
let slice_j = (i - j) + slice_i in
(slice_i,slice_j)
- end
+ end *)
-let external_reg_whole reg =
- Reg (name_of_reg reg) (start_of_reg_nat reg) (size_of_reg_nat reg) (dir_of_reg reg)
-
-let external_reg_slice reg (i,j) =
- let start = start_of_reg_nat reg in
- let dir = dir_of_reg reg in
- Reg_slice (name_of_reg reg) start dir (external_slice dir start (i,j))
+(* TODO
+let external_reg_whole r =
+ Reg (r.name) (natFromInteger r.start) (natFromInteger r.size) (dir_of_bool r.is_inc)
+
+let external_reg_slice r (i,j) =
+ let start = natFromInteger r.start in
+ let dir = dir_of_bool r.is_inc in
+ Reg_slice (r.name) start dir (external_slice dir start (i,j))
-let external_reg_field_whole reg rfield =
+let external_reg_field_whole reg rfield =
let (m,n) = register_field_indices_nat reg rfield in
let start = start_of_reg_nat reg in
let dir = dir_of_reg reg in
Reg_field (name_of_reg reg) start dir rfield (external_slice dir start (m,n))
-
-let external_reg_field_slice reg rfield (i,j) =
+
+let external_reg_field_slice reg rfield (i,j) =
let (m,n) = register_field_indices_nat reg rfield in
let start = start_of_reg_nat reg in
let dir = dir_of_reg reg in
Reg_f_slice (name_of_reg reg) start dir rfield
(external_slice dir start (m,n))
- (external_slice dir start (i,j))
+ (external_slice dir start (i,j))*)
+(*val external_mem_value : list bitU -> memory_value
let external_mem_value v =
byte_lifteds_of_bitv v $> List.reverse
+val internal_mem_value : memory_value -> list bitU
let internal_mem_value bytes =
- List.reverse bytes $> bitv_of_byte_lifteds
+ List.reverse bytes $> bitv_of_byte_lifteds*)
+
-
val foreach_inc : forall 'vars. (integer * integer * integer) -> 'vars ->
(integer -> 'vars -> 'vars) -> 'vars
@@ -756,7 +798,7 @@ let toNaturalFiveTup (n1,n2,n3,n4,n5) =
| RSliceBit of (string * integer)
| RField of (string * string)
-type niafp =
+type niafp =
| NIAFP_successor
| NIAFP_concrete_address of vector bitU
| NIAFP_LR
@@ -764,13 +806,13 @@ type niafp =
| NIAFP_register of regfp
(* only for MIPS *)
-type diafp =
+type diafp =
| DIAFP_none
| DIAFP_concrete of vector bitU
| DIAFP_reg of regfp
let regfp_to_reg (reg_info : string -> maybe string -> (nat * nat * direction * (nat * nat))) = function
- | RFull name ->
+ | RFull name ->
let (start,length,direction,_) = reg_info name Nothing in
Reg name start length direction
| RSlice (name,i,j) ->
diff --git a/src/gen_lib/state.lem b/src/gen_lib/state.lem
index ac6d55b5..d4e2b128 100644
--- a/src/gen_lib/state.lem
+++ b/src/gen_lib/state.lem
@@ -1,5 +1,4 @@
open import Pervasives_extra
-open import Sail_impl_base
open import Sail_values
open import State_monad
open import {isabelle} `State_monad_extras`
diff --git a/src/gen_lib/state_monad.lem b/src/gen_lib/state_monad.lem
index 2d8e412e..a3bf4b5f 100644
--- a/src/gen_lib/state_monad.lem
+++ b/src/gen_lib/state_monad.lem
@@ -1,5 +1,5 @@
open import Pervasives_extra
-open import Sail_impl_base
+open import Sail_instr_kinds
open import Sail_values
(* 'a is result type *)
@@ -103,37 +103,21 @@ let rec range i j =
else if i = j then [i]
else i :: range (i+1) j
-val get_reg : forall 'regs 'a. sequential_state 'regs -> register_ref 'regs 'a -> 'a
+val get_reg : forall 'regs 'rv 'a. sequential_state 'regs -> register_ref 'regs 'rv 'a -> 'a
let get_reg state reg = reg.read_from state.regstate
-val set_reg : forall 'regs 'a. sequential_state 'regs -> register_ref 'regs 'a -> 'a -> sequential_state 'regs
+val set_reg : forall 'regs 'rv 'a. sequential_state 'regs -> register_ref 'regs 'rv 'a -> 'a -> sequential_state 'regs
let set_reg state reg v =
<| state with regstate = reg.write_to state.regstate v |>
-let is_exclusive = function
- | Sail_impl_base.Read_plain -> false
- | 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
- | Sail_impl_base.Read_RISCV_acquire -> false
- | Sail_impl_base.Read_RISCV_strong_acquire -> false
- | Sail_impl_base.Read_RISCV_reserved -> true
- | Sail_impl_base.Read_RISCV_reserved_acquire -> true
- | Sail_impl_base.Read_RISCV_reserved_strong_acquire -> true
- | Sail_impl_base.Read_X86_locked -> true
-end
-
-
val read_mem : forall 'regs 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> M 'regs 'b 'e
let read_mem read_kind addr sz state =
let addr = unsigned 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 = of_bits (Sail_values.internal_mem_value memory_value) in
- if is_exclusive read_kind
+ let value = bits_of_bytes (List.reverse memory_value) in
+ if read_is_exclusive read_kind
then [(Value value, <| state with last_exclusive_operation_was_load = true |>)]
else [(Value value, state)]
@@ -147,7 +131,7 @@ let read_tag read_kind addr state =
| Just t -> t
| Nothing -> B0
end in
- if is_exclusive read_kind
+ if read_is_exclusive read_kind
then [(Value tag, <| state with last_exclusive_operation_was_load = true |>)]
else [(Value tag, state)]
@@ -167,11 +151,15 @@ let write_mem_val v state =
| 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 (bits_of v) in
- let addresses_with_value = List.zip addrs v in
- let memstate = List.foldl (fun mem (addr,v) -> Map.insert addr v mem)
- state.memstate addresses_with_value in
- [(Value true, <| state with memstate = memstate |>)]
+ match bytes_of_bits v with
+ | Just v ->
+ let addresses_with_value = List.zip addrs (List.reverse v) in
+ let memstate = List.foldl (fun mem (addr,v) -> Map.insert addr v mem)
+ state.memstate addresses_with_value in
+ [(Value true, <| state with memstate = memstate |>)]
+ | Nothing ->
+ [(Exception (Assert "write_mem_val"), state)]
+ end
val write_tag : forall 'regs 'e. bitU -> M 'regs bool 'e
let write_tag t state =
@@ -182,7 +170,7 @@ let write_tag t state =
let tagstate = Map.insert taddr t state.tagstate in
[(Value true, <| state with tagstate = tagstate |>)]
-val read_reg : forall 'regs 'a 'e. register_ref 'regs 'a -> M 'regs 'a 'e
+val read_reg : forall 'regs 'rv 'a 'e. register_ref 'regs 'rv 'a -> M 'regs 'a 'e
let read_reg reg state =
let v = reg.read_from state.regstate in
[(Value v,state)]
@@ -201,13 +189,13 @@ let read_reg_bitfield reg regfield =
let reg_deref = read_reg
-val write_reg : forall 'regs 'a 'e. register_ref 'regs 'a -> 'a -> M 'regs unit 'e
+val write_reg : forall 'regs 'rv 'a 'e. register_ref 'regs 'rv 'a -> 'a -> M 'regs unit 'e
let write_reg reg v state =
[(Value (), <| state with regstate = reg.write_to state.regstate v |>)]
let write_reg_ref (reg, v) = write_reg reg v
-val update_reg : forall 'regs 'a 'b 'e. register_ref 'regs 'a -> ('a -> 'b -> 'a) -> 'b -> M 'regs unit 'e
+val update_reg : forall 'regs 'rv 'a 'b 'e. register_ref 'regs 'rv 'a -> ('a -> 'b -> 'a) -> 'b -> M 'regs unit 'e
let update_reg reg f v state =
let current_value = get_reg state reg in
let new_value = f current_value v in
@@ -215,14 +203,14 @@ let update_reg reg f v state =
let write_reg_field reg regfield = update_reg reg regfield.set_field
-val update_reg_range : forall 'regs 'a 'b. Bitvector 'a, Bitvector 'b => register_ref 'regs 'a -> integer -> integer -> 'a -> 'b -> 'a
-let update_reg_range reg i j reg_val new_val = set_bits (reg.reg_is_inc) reg_val i j (bits_of new_val)
+val update_reg_range : forall 'regs 'rv 'a 'b. Bitvector 'a, Bitvector 'b => register_ref 'regs 'rv 'a -> integer -> integer -> 'a -> 'b -> 'a
+let update_reg_range reg i j reg_val new_val = set_bits (reg.is_inc) reg_val i j (bits_of new_val)
let write_reg_range reg i j = update_reg reg (update_reg_range reg i j)
-let update_reg_pos reg i reg_val x = update_list reg.reg_is_inc reg_val i x
+let update_reg_pos reg i reg_val x = update_list reg.is_inc reg_val i x
let write_reg_pos reg i = update_reg reg (update_reg_pos reg i)
-let update_reg_bit reg i reg_val bit = set_bit (reg.reg_is_inc) reg_val i (to_bitU bit)
+let update_reg_bit reg i reg_val bit = set_bit (reg.is_inc) reg_val i (to_bitU bit)
let write_reg_bit reg i = update_reg reg (update_reg_bit reg i)
let update_reg_field_range regfield i j reg_val new_val =