summaryrefslogtreecommitdiff
path: root/mips/mips_extras.lem
blob: 2e07586c78332b05dd5563e2c86d93fd34484b22 (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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
open import Pervasives
open import Pervasives_extra
open import Sail2_instr_kinds
open import Sail2_values
open import Sail2_operators
open import Sail2_prompt_monad
open import Sail2_prompt

val MEMr             : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> monad 'regval 'b 'e
val MEMr_reserve     : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> monad 'regval 'b 'e
val MEMr_tag         : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> monad 'regval (bool * 'b) 'e
val MEMr_tag_reserve : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> monad 'regval (bool * 'b) 'e

let MEMr addr size             = read_mem Read_plain addr size
let MEMr_reserve addr size     = read_mem Read_reserve addr size

val read_tag_bool : forall 'regval 'a 'e. Bitvector 'a => 'a -> monad 'regval bool 'e
let read_tag_bool addr =
  read_tag addr >>= fun t ->
  maybe_fail "read_tag_bool" (bool_of_bitU t)

val write_tag_bool : forall 'regval 'a 'e. Bitvector 'a => 'a -> bool -> monad 'regval unit 'e
let write_tag_bool addr t = write_tag addr (bitU_of_bool t) >>= fun _ -> return ()

let MEMr_tag addr size =
  read_mem Read_plain addr size >>= fun v ->
  read_tag_bool addr >>= fun t ->
  return (t, v)

let MEMr_tag_reserve addr size =
  read_mem Read_plain addr size >>= fun v ->
  read_tag_bool addr >>= fun t ->
  return (t, v)


val MEMea                 : forall 'regval 'a 'e. Bitvector 'a => 'a -> integer -> monad 'regval unit 'e
val MEMea_conditional     : forall 'regval 'a 'e. Bitvector 'a => 'a -> integer -> monad 'regval unit 'e
val MEMea_tag             : forall 'regval 'a 'e. Bitvector 'a => 'a -> integer -> monad 'regval unit 'e
val MEMea_tag_conditional : forall 'regval 'a 'e. Bitvector 'a => 'a -> integer -> monad 'regval unit 'e

let MEMea addr size                 = write_mem_ea Write_plain addr size
let MEMea_conditional addr size     = write_mem_ea Write_conditional addr size

let MEMea_tag addr size             = write_mem_ea Write_plain addr size
let MEMea_tag_conditional addr size = write_mem_ea Write_conditional addr size


val MEMval                 : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> 'b -> monad 'regval unit 'e
val MEMval_conditional     : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> 'b -> monad 'regval bool 'e
val MEMval_tag             : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> bool -> 'b -> monad 'regval unit 'e
val MEMval_tag_conditional : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> bool -> 'b -> monad 'regval bool 'e

let MEMval _ size v                      = write_mem_val v >>= fun _ -> return ()
let MEMval_conditional _ size v          = write_mem_val v >>= fun b -> return (if b then true else false)
let MEMval_tag addr size t v             = write_mem_val v >>= fun _ -> write_tag_bool addr t >>= fun _ -> return ()
let MEMval_tag_conditional addr size t v = write_mem_val v >>= fun b -> write_tag_bool addr t >>= fun _ -> return (if b then true else false)

val MEM_sync  : forall 'regval 'e. unit -> monad 'regval unit 'e

let MEM_sync () = barrier Barrier_MIPS_SYNC

(* Some wrappers copied from aarch64_extras *)
(* TODO: Harmonise into a common library *)

let get_slice_int_bl len n lo =
  (* TODO: Is this the intended behaviour? *)
  let hi = lo + len - 1 in
  let bs = bools_of_int (hi + 1) n in
  subrange_list false bs hi lo

val get_slice_int : forall 'a. Bitvector 'a => integer -> integer -> integer -> 'a
let get_slice_int len n lo = of_bools (get_slice_int_bl len n lo)

let write_ram _ size _ addr data =
  MEMea addr size >>
  MEMval addr size data

let read_ram _ size _ addr = MEMr addr size

let string_of_int = show

let shift_bits_left v n =
  let r = Maybe.bind (unsigned n) (fun n -> of_bits (shiftl_bv v n)) in
  maybe_fail "shift_bits_left" r
let shift_bits_right v n =
  let r = Maybe.bind (unsigned n) (fun n -> of_bits (shiftr_bv v n)) in
  maybe_fail "shift_bits_right" r
let shift_bits_right_arith v n =
  let r = Maybe.bind (unsigned n) (fun n -> of_bits (arith_shiftr_bv v n)) in
  maybe_fail "shift_bits_right_arith" r

(* Use constants for undefined values for now *)
let internal_pick vs = return (head vs)
let undefined_string () = return ""
let undefined_unit () = return ()
let undefined_int () = return (0:ii)
val undefined_vector : forall 'rv 'a 'e. integer -> 'a -> monad 'rv (list 'a) 'e
let undefined_vector len u = return (repeat [u] len)
val undefined_bitvector : forall 'rv 'a 'e. Bitvector 'a => integer -> monad 'rv 'a 'e
let undefined_bitvector len = return (of_bools (repeat [false] len))
val undefined_bits : forall 'rv 'a 'e. Bitvector 'a => integer -> monad 'rv 'a 'e
let undefined_bits = undefined_bitvector
let undefined_bit () = return B0
let undefined_real () = return (realFromFrac 0 1)
let undefined_range i j = return i
let undefined_atom i = return i
let undefined_nat () = return (0:ii)

let skip () = return ()

val elf_entry : unit -> integer
let elf_entry () = 0
declare ocaml target_rep function elf_entry = `Elf_loader.elf_entry`

let print_bits msg bs = prerr_endline (msg ^ (string_of_bv bs))

val get_time_ns : unit -> integer
let get_time_ns () = 0
declare ocaml target_rep function get_time_ns = `(fun () -> Big_int.of_int (int_of_float (1e9 *. Unix.gettimeofday ())))`

val cycle_count : unit -> unit
let cycle_count _ = ()

let inline eq_bit = eq