summaryrefslogtreecommitdiff
path: root/src/lem_interp/interp_interface.lem
blob: f74a70dbac7a59548e0078f7c2bfe93e62d92707 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import Interp
open import Num

type read_kind = Interp.read_kind
type write_kind = Interp.write_kind
type barrier_kind = Interp.barrier_kind

type word8 = nat (* bounded at a byte, for when lem supports it*)

type value = 
| Bitvector of list bool (* For register accesses *)
| Bytevector of list word8 (* For memory accesses *)
| Unknown

type instruction_state = Interp.stack
type context = Interp.top_level

type slice = (integer * integer)

type reg_name = 
| Reg of string (*Name of the register, accessing the entire register*)
| Reg_slice of string * slice (*Name of the register, accessing from the first to second integer of the slice*)
| Reg_field of string * string * slice (*Name of the register, name of the field of the register accessed, the slice of the field*)
| Reg_f_slice of string * string * slice * slice (* Same as above but only accessing second slice of the field *)

type outcome =
| Read_mem of read_kind * value * (value -> instruction_state)
| Write_mem of write_kind * value * value * (bool -> instruction_state)
| Barrier of barrier_kind * instruction_state
| Read_reg of reg_name * (value -> instruction_state) 
| Write_reg of reg_name * value * instruction_state
| Nondet_choice of list instruction_state * instruction_state
| Internal of instruction_state
| Done
| Error of string

type event = 
| E_read_mem of read_kind * value
| E_write_mem of write_kind * value * value
| E_barrier of barrier_kind
| E_read_reg of reg_name
| E_write_reg of reg_name * value
| E_error of string (* Should not happen, but may if the symbolic evaluation doesn't work out*)
(*Should multiple memory accesses be represented with a special form to denote this or potentially merged into one read or left in place*)


val build_context : Interp_ast.defs Interp.tannot -> context
val initial_instruction_state : context -> string -> value -> instruction_state

type interp_mode = <| eager_eval : bool |>
val interp : interp_mode -> instruction_state -> outcome

val interp_exhaustive : instruction_state -> list event

val rr_interp_exhaustive : instruction_state -> list event -> (outcome * (list event)) (* Like interp_exhaustive but will read registers; the outcome will only ever be a rreg request, done, or error *)

val mem_read_analysis : instruction_state -> list event (*Should record all rreg events where the registers are involved in memory reads to compute the addressses in is*)

val mem_write_analysis : instruction_state -> list event (*Should record all rreg events where the registers are involved in memory writes to compute the address (and value?, in a separate list?)*)