Commit fd2acc75 authored by Jonathan Moerman's avatar Jonathan Moerman
Browse files

Why3's interface hates me for this, but we seem to be at 0.88 parity now

parent 996cae87
......@@ -44,39 +44,24 @@ let constant r29: register = 29
let constant r30: register = 30
let constant r31: register = 31
type cpu_flag = { mutable value: bool }
type cpu_flag = ref bool
function (?) (x: cpu_flag): int = if x.value then 1 else 0
function (?) (x: cpu_flag): int = if !x then 1 else 0
let (?) (x: cpu_flag) ensures { result = ?x } = if x.value then 1 else 0
let (?) (x: cpu_flag) ensures { result = ?x } = if !x then 1 else 0
val cf: cpu_flag
(*
type byte = < range 0 255 >
meta coercion function byte'int
*)
meta rewrite_def function (?)
(*WIP: invariant is disabled for now*)
(*
let lemma address_space_exists (): map int int
ensures { forall x. 0 <= result x < 256 }
= fun x -> 0
val cf: cpu_flag
type address_space = { mutable data: map int int }
invariant { forall i. 0 <= data[i] < 256 }
*)
type address_space = { mutable data: map int int }
meta coercion function data
predicate valid_addr_space (addr_space: address_space) = forall i. 0 <= (data addr_space)[i] < 256
(* WIP: only needed in case we have an invariant *)
goal address_space_eq:
forall m1 m2. m1.data = m2.data <-> m1 = m2
meta coercion function data
function get_uint_term (rlo: (address_space, int)) (i: int): int
= let (reg, lo) = rlo in pow2 (8*i) * reg.data[lo+i]
= let (reg, lo) = rlo in pow2 (8*i) * (reg.data[lo+i])
let rec ghost function uint_sum (rlo: (address_space, int)) (i: int) (j: int) : int =
variant { j - i }
......@@ -89,6 +74,19 @@ clone sum.Sum as B with type container = container, function f = get_uint_term,
function uint (w: int) (reg: address_space) (lo: register): int
= uint_sum (reg,lo) 0 w
(* WIP COMMENT: i'm not sure if this is beneficial for the proof context *)
let ghost function lo8 (x: int): int
ensures { result = mod x 256 }
= mod x 256
let ghost function hi8 (x: int): int
requires { 0 <= x < 0x10000 }
ensures { result = div x 256 }
= div x 256
meta rewrite_def function lo8
meta rewrite_def function hi8
val reg: address_space
(* WIP COMMENT: in why3 1.x, the "ghost" vs "non-ghost" distinction seems to be converging towards
......@@ -96,90 +94,110 @@ val reg: address_space
in non-ghost code by conjuring it into existence using the 'any' expression. in Why3 1.x, this is
safe (a witness must be provided), whereas in Why3 0.8x it would not be safe.
note: this may no longer work in future versions of Why3
this comment can be removed at any time.*)
let data_set (d: map int int) (i: register) (v: int): map int int
ensures { result = Map.set d i v }
= any map int int ensures { result = Map.set d i v }
let data_set (m: map int int) (i: register) (v: int): map int int
requires { 0 <= v < 256 }
ensures { result = Map.set m i v }
= any map int int ensures { result = Map.set m i v }
let read (m: address_space) (i: int): int
= any int ensures { m[i] = result }
let mov (dst src: register): unit
writes { reg }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst<-reg[src]] }
= reg.data <- data_set reg.data dst (Map.get reg.data src)
= reg.data <- data_set reg.data dst (read reg src)
let mul (dst src: register): unit
writes { cf }
writes { reg }
ensures { let p = old (reg[src]*reg[dst]) in reg = (old reg)[0 <- mod p 256][1 <- div p 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { let p = old (reg[src]*reg[dst]) in reg = (old reg)[0 <- lo8 p][1 <- hi8 p] }
ensures { let p = old (reg[src]*reg[dst]) in ?cf = div p (pow2 15) }
(* ensures { reg[1] < 255 } *)
= let prod = Map.get reg.data dst*Map.get reg.data src in
= let prod = read reg dst*read reg src in
reg.data <- data_set (data_set reg.data 0 (mod prod 256)) 1 (div prod 256);
cf.value <- (div prod 0x8000 <> 0);
cf := (div prod 0x8000 <> 0);
()
let add (dst src: register): unit
writes { cf }
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] + reg[src])) 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] + reg[src]))] }
ensures { ?cf = div (old (reg[dst] + reg[src])) 256 }
= let sum = Map.get reg.data src + Map.get reg.data dst in
let r1 = (Map.get reg.data dst) in
let r2 = (Map.get reg.data src) in
= let sum = read reg src + read reg dst in
let r1 = (read reg dst) in
let r2 = (read reg src) in
reg.data <- data_set reg.data dst (mod sum 256);
let res = (Map.get reg.data dst) in
let res = (read reg dst) in
if r1 >= 128 && r2 >= 128 ||
r1 >= 128 && res < 128 ||
r2 >= 128 && res < 128
then
cf.value <- True
cf := True
else
cf.value <- False
cf := False
let adc (dst src: register): unit
writes { cf }
reads { cf }
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] + reg[src] + ?cf)) 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] + reg[src] + ?cf))] }
ensures { ?cf = div (old (reg[dst] + reg[src] + ?cf)) 256 }
= let sum = Map.get reg.data src + Map.get reg.data dst + ?cf in
= let sum = read reg src + read reg dst + ?cf in
reg.data <- data_set reg.data dst (mod sum 256);
cf.value <- (div sum 256 <> 0);
cf := (div sum 256 <> 0);
()
let sub (dst src: register): unit
writes { cf }
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] - reg[src])) 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] - reg[src]))] }
ensures { ?cf = -div (old (reg[dst] - reg[src])) 256 }
= let sum = Map.get reg.data dst - Map.get reg.data src in
= let sum = read reg dst - read reg src in
reg.data <- data_set reg.data dst (mod sum 256);
assert { -255 <= sum <= 255 };
cf.value <- (-div sum 256 <> 0);
cf := (-div sum 256 <> 0);
()
let sbc (dst src: register): unit
writes { cf }
reads { cf }
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] - reg[src] - ?cf)) 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] - reg[src] - ?cf))] }
ensures { ?cf = -div (old (reg[dst] - reg[src] - ?cf)) 256 }
= let sum = Map.get reg.data dst - Map.get reg.data src - ?cf in
= let sum = read reg dst - read reg src - ?cf in
reg.data <- data_set reg.data dst (mod sum 256);
cf.value <- (-div sum 256 <> 0);
cf := (-div sum 256 <> 0);
()
let neg (dst: register): unit
writes { cf }
writes { reg }
ensures { reg = old reg[dst <- mod (old (-reg[dst])) 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (-reg[dst]))] }
(* TODO: which one is useful?
ensures { ?cf = if reg[dst] = 0 then 0 else 1 }
ensures { ?cf = -div (old (-reg[dst])) 256 }
*)
= let sum = - Map.get reg.data dst in
= let sum = - read reg dst in
reg.data <- data_set reg.data dst (mod sum 256);
assert { -255 <= sum <= 255 };
cf.value <- (-div sum 256 <> 0);
cf := (-div sum 256 <> 0);
()
(* immediate versions *)
......@@ -187,11 +205,13 @@ let subi (dst: register) (k: int): unit
requires { 0 <= k <= 255 }
writes { cf }
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] - k)) 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] - k))] }
ensures { ?cf = -div (old (reg[dst] - k)) 256 }
= let sum = Map.get reg.data dst - k in
= let sum = read reg dst - k in
reg.data <- data_set reg.data dst (mod sum 256);
cf.value <- (-div sum 256 <> 0);
cf := (-div sum 256 <> 0);
()
let sbci (dst: register) (k: int): unit
......@@ -199,24 +219,30 @@ let sbci (dst: register) (k: int): unit
writes { cf }
reads { cf }
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] - k - ?cf)) 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] - k - ?cf))] }
ensures { ?cf = -div (old (reg[dst] - k - ?cf)) 256 }
= let sum = Map.get reg.data dst - k - ?cf in
= let sum = read reg dst - k - ?cf in
reg.data <- data_set reg.data dst (mod sum 256);
cf.value <- (-div sum 256 <> 0);
cf := (-div sum 256 <> 0);
()
(* these instructions do not modify the carry flag *)
let inc (dst: register): unit
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] + 1)) 256] }
= let sum = Map.get reg.data dst + 1 in
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] + 1))] }
= let sum = read reg dst + 1 in
reg.data <- data_set reg.data dst (mod sum 256)
let dec (dst: register): unit
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] - 1)) 256] }
= let sum = Map.get reg.data dst - 1 in
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] - 1))] }
= let sum = read reg dst - 1 in
reg.data <- data_set reg.data dst (mod sum 256)
let constant rX: register = 26
......@@ -229,34 +255,43 @@ let ld_inc (dst src: register): unit
writes { reg }
reads { mem }
requires { 32 <= uint 2 reg src < pow2 16-1 }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
requires { valid_addr_space mem }
(* TODO unnecessary
requires { dst <> src /\ dst <> src+1 }
*)
ensures { let cur = uint 2 (old reg) src in
let inc = cur+1 in
reg = (old reg)[dst <- mem[cur]][src <- mod inc 256][src+1 <- div inc 256] }
reg = (old reg)[dst <- mem[cur]][src <- lo8 inc][src+1 <- hi8 inc] }
ensures { uint 2 reg src = old(uint 2 reg src)+1 }
= let cur = Map.get reg.data src + 256*Map.get reg.data (src+1) in
= let cur = read reg src + 256*read reg (src+1) in
let nxt = mod (cur+1) 0x10000 in
reg.data <- data_set (data_set (data_set reg.data dst (Map.get mem.data cur)) src (mod nxt 256)) (src+1) (div nxt 256)
reg.data <- data_set (data_set (data_set reg.data dst (read mem cur)) src (mod nxt 256)) (src+1) (div nxt 256)
let ldd (dst src ofs: register): unit
writes { reg }
reads { mem }
requires { valid_addr_space mem }
requires { 32 <= uint 2 reg src + ofs < pow2 16 }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { let cur = uint 2 (old reg) src in
reg = (old reg)[dst <- mem[cur+ofs]] }
= let cur = Map.get reg.data src + 256*Map.get reg.data (src+1) in
reg.data <- data_set reg.data dst (Map.get mem.data (cur+ofs))
= let cur = read reg src + 256*read reg (src+1) in
reg.data <- data_set reg.data dst (read mem (cur+ofs))
let std (dst ofs src: register): unit
writes { mem }
reads { reg }
requires { 32 <= uint 2 reg dst + ofs < pow2 16 }
requires { valid_addr_space reg }
requires { valid_addr_space mem }
ensures { valid_addr_space mem }
ensures { let cur = uint 2 (old reg) dst in
mem = (old mem)[cur+ofs <- reg[src]] }
= let cur = Map.get reg.data dst + 256*Map.get reg.data (dst+1) in
mem.data <- data_set mem.data (cur+ofs) (Map.get reg.data src)
= let cur = read reg dst + 256*read reg (dst+1) in
mem.data <- data_set mem.data (cur+ofs) (read reg src)
(* stack operations *)
......@@ -267,18 +302,24 @@ val stack: address_space
let push (src: register): unit
writes { stack, stack_pointer }
reads { reg }
requires { valid_addr_space reg }
requires { valid_addr_space stack }
ensures { valid_addr_space stack }
ensures { stack = old(stack[!stack_pointer <- reg[src]]) }
ensures { !stack_pointer = old !stack_pointer - 1 }
= stack.data <- data_set stack.data (!stack_pointer) (Map.get reg.data src);
= stack.data <- data_set stack.data (!stack_pointer) (read reg src);
stack_pointer := !stack_pointer - 1
let pop (dst: register): unit
writes { reg, stack_pointer }
reads { stack }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
requires { valid_addr_space stack }
ensures { reg = (old reg)[dst <- stack[!stack_pointer]] }
ensures { !stack_pointer = old !stack_pointer + 1 }
= stack_pointer := !stack_pointer + 1;
reg.data <- data_set reg.data dst (Map.get stack.data !stack_pointer)
reg.data <- data_set reg.data dst (read stack !stack_pointer)
let nop (): unit
= ()
......@@ -400,8 +441,10 @@ let movw (dst src: register): unit
requires { mod dst 2 = 0 /\ mod src 2 = 0 }
*)
writes { reg }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst<-reg[src]][dst+1<-reg[src+1]] }
= reg.data <- data_set (data_set reg.data dst (Map.get reg.data src)) (dst+1) (Map.get reg.data (src+1))
= reg.data <- data_set (data_set reg.data dst (read reg src)) (dst+1) (read reg (src+1))
let adiw (dst: register) (k: int): unit
requires { 0 <= k < 64 }
......@@ -410,15 +453,17 @@ let adiw (dst: register) (k: int): unit
*)
writes { reg }
writes { cf }
ensures { reg = old reg[dst <- mod (old (reg[dst] + k)) 256]
[dst+1 <- mod (old (reg[dst+1] + div (reg[dst] + k) 256)) 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] + k))]
[dst+1 <- lo8 (old (reg[dst+1] + div (reg[dst] + k) 256))] }
ensures { ?cf = div (old (uint 2 reg dst + k)) 65536 }
ensures { ?cf*pow2 16 + uint 2 reg dst = old (uint 2 reg dst + k) }
= let sum = Map.get reg.data dst + 256*Map.get reg.data (dst+1) +k in
= let sum = read reg dst + 256*read reg (dst+1) +k in
reg.data <- data_set reg.data dst (mod sum 256);
assert { mod sum 256 = mod (old (reg[dst] + k)) 256 };
reg.data <- data_set reg.data (dst+1) (mod (div sum 256) 256);
cf.value <- (sum > 65535)
cf := (sum > 65535)
let sbiw (dst: register) (k: int): unit
......@@ -428,8 +473,10 @@ let sbiw (dst: register) (k: int): unit
*)
writes { reg }
writes { cf }
ensures { reg = old reg[dst <- mod (old (reg[dst] - k)) 256]
[dst+1 <- mod (old (reg[dst+1] + div (reg[dst] - k) 256)) 256] }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] - k))]
[dst+1 <- lo8 (old (reg[dst+1] + div (reg[dst] - k) 256))] }
ensures { ?cf = -div (old (uint 2 reg dst - k)) 65536 }
ensures { uint 2 reg dst = ?cf*pow2 16 + old (uint 2 reg dst - k) }
= subi dst k;
......@@ -447,96 +494,116 @@ axiom bv8_nth_def: forall x y. (256 > x >= 0 /\ 8 > y >= 0) -> (BV8.nth (BV8.of_
(*
let add_ (dst src: register): unit
writes { reg, cf }
ensures { reg = old (reg[dst <- mod (reg[dst] + reg[src]) 256]) }
ensures { reg = old (reg[dst <- lo8 (reg[dst] + reg[src])]) }
ensures { ?cf = old (div (reg[dst] + reg[src]) 256) }
= let rd = BV8.of_int (Map.get reg.data dst) in
let rr = BV8.of_int (Map.get reg.data src) in
= let rd = BV8.of_int (read reg dst) in
let rr = BV8.of_int (read reg src) in
let rd' = BV8.add rd rr in
reg.data <- data_set reg.data dst (bv8_to_int rd');
cf.value <- (BV8.nth rd 7 && BV8.nth rr 7 || BV8.nth rd 7 && not BV8.nth rd' 7 || not BV8.nth rd' 7 && BV8.nth rr 7)
let sub_ (dst src: register): unit
writes { reg, cf }
ensures { reg = old reg[dst <- mod (old (reg[dst] - reg[src])) 256] }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] - reg[src]))] }
ensures { ?cf = -div (old (reg[dst] - reg[src])) 256 }
= let rd = BV8.of_int (Map.get reg.data dst) in
let rr = BV8.of_int (Map.get reg.data src) in
= let rd = BV8.of_int (read reg dst) in
let rr = BV8.of_int (read reg src) in
let rd' = BV8.sub rd rr in
reg.data <- data_set reg.data dst (bv8_to_int rd');
cf.value <- (not BV8.nth rd 7 && BV8.nth rr 7 || BV8.nth rr 7 && BV8.nth rd' 7 || BV8.nth rd' 7 && not BV8.nth rd 7)
*)
let inc_ (dst: register): unit
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] + 1)) 256] }
= let rd = BV8.of_int (Map.get reg.data dst) in
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] + 1))] }
= let rd = BV8.of_int (read reg dst) in
let rd' = BV8.add rd (BV8.of_int 1) in
reg.data <- data_set reg.data dst (bv8_to_int rd')
let dec_ (dst: register): unit
writes { reg }
ensures { reg = old reg[dst <- mod (old (reg[dst] - 1)) 256] }
= let sum = Map.get reg.data dst - 1 in
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- lo8 (old (reg[dst] - 1))] }
= let sum = read reg dst - 1 in
reg.data <- data_set reg.data dst (mod sum 256)
let eor (dst src: register): unit
writes { reg }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst <- BV8.t'int (BV8.bw_xor (BV8.of_int reg[dst]) (BV8.of_int reg[src])) ] }
= let tmp = bv8_to_int (BV8.bw_xor (BV8.of_int (Map.get reg.data dst)) (BV8.of_int (Map.get reg.data src))) in
= let tmp = bv8_to_int (BV8.bw_xor (BV8.of_int (read reg dst)) (BV8.of_int (read reg src))) in
reg.data <- data_set reg.data dst tmp
let clr (dst: register): unit
writes { reg }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst<-0] }
= eor dst dst
let com (dst: register): unit
writes { reg }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst<- BV8.t'int (BV8.bw_not (BV8.of_int reg[dst]))] }
= let tmp = bv8_to_int (BV8.bw_not (BV8.of_int (Map.get reg.data dst))) in
= let tmp = bv8_to_int (BV8.bw_not (BV8.of_int (read reg dst))) in
reg.data <- data_set reg.data dst tmp
let asr (dst: register): unit
writes { reg, cf }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst<- BV8.t'int (BV8.asr (BV8.of_int reg[dst]) 1)] }
ensures { ?cf = mod (old reg[dst]) 2 }
ensures { cf.value = BV8.nth (BV8.of_int (old reg[dst])) 0 }
= cf.value <- BV8.nth (BV8.of_int (Map.get reg.data dst)) 0;
reg.data <- data_set reg.data dst (bv8_to_int (BV8.asr (BV8.of_int (Map.get reg.data dst)) 1))
ensures { !cf = BV8.nth (BV8.of_int (old reg[dst])) 0 }
= cf := BV8.nth (BV8.of_int (read reg dst)) 0;
reg.data <- data_set reg.data dst (bv8_to_int (BV8.asr (BV8.of_int (read reg dst)) 1))
let lsr (dst: register): unit
writes { reg, cf }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst<- BV8.t'int (BV8.lsr (BV8.of_int reg[dst]) 1)] }
ensures { ?cf = mod (old reg[dst]) 2 }
ensures { cf.value = BV8.nth (BV8.of_int (old reg[dst])) 0 }
= cf.value <- BV8.nth (BV8.of_int (Map.get reg.data dst)) 0;
reg.data <- data_set reg.data dst (bv8_to_int (BV8.lsr (BV8.of_int (Map.get reg.data dst)) 1))
ensures { !cf = BV8.nth (BV8.of_int (old reg[dst])) 0 }
= cf := BV8.nth (BV8.of_int (read reg dst)) 0;
reg.data <- data_set reg.data dst (bv8_to_int (BV8.lsr (BV8.of_int (read reg dst)) 1))
(* WIP: this will become the future definition, since 'lsl rX' is the same opcode as 'add rX, rX' *)
(*
let lsl (dst: register): unit
writes { reg, cf }
ensures { reg = old reg[dst <- mod (old (2*reg[dst])) 256] }
ensures { reg = old reg[dst <- lo8 (old (2*reg[dst]))] }
ensures { ?cf = div (old (2*reg[dst])) 256 }
= add dst dst
*)
let lsl (dst: register): unit
writes { reg, cf }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
ensures { reg = old reg[dst<- BV8.t'int (BV8.lsl (BV8.of_int reg[dst]) 1)] }
ensures { ?cf = 0 <-> old reg[dst] < 128 }
ensures { cf.value = BV8.nth (BV8.of_int (old reg[dst])) 7 }
= cf.value <- BV8.nth (BV8.of_int (Map.get reg.data dst)) 7;
reg.data <- data_set reg.data dst (bv8_to_int (BV8.lsl (BV8.of_int (Map.get reg.data dst)) 1))
ensures { !cf = BV8.nth (BV8.of_int (old reg[dst])) 7 }
= cf := BV8.nth (BV8.of_int (read reg dst)) 7;
reg.data <- data_set reg.data dst (bv8_to_int (BV8.lsl (BV8.of_int (read reg dst)) 1))
(* t flag operations *)
val tf: cpu_flag
let bst (dst: register) (bit: int): unit
writes { tf }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
requires { 0 <= bit < 8 }
ensures { tf.value = BV8.nth (BV8.of_int reg[dst]) bit }
= tf.value <- BV8.nth (BV8.of_int (Map.get reg.data dst)) bit
ensures { !tf = BV8.nth (BV8.of_int reg[dst]) bit }
= tf := BV8.nth (BV8.of_int (read reg dst)) bit
function bitset (w: BV8.t) (b: int) (v: bool): BV8.t =
let mask = BV8.lsl (BV8.of_int 1) b in
......@@ -576,9 +643,11 @@ goal bitsetx_equiv_def:
let bld (dst: register) (bit: int): unit
writes { reg }
requires { valid_addr_space reg }
ensures { valid_addr_space reg }
requires { 0 <= bit < 8 }
ensures { reg = (old reg)[dst <- BV8.t'int (bitset (BV8.of_int (old reg)[dst]) bit tf.value)] }
= let rd = BV8.of_int (Map.get reg.data dst) in
ensures { reg = (old reg)[dst <- BV8.t'int (bitset (BV8.of_int (old reg)[dst]) bit !tf)] }
= let rd = BV8.of_int (read reg dst) in
let mask = BV8.lsl (BV8.of_int 1) bit in
if ?tf = 0 then
reg.data <- data_set reg.data dst (bv8_to_int (BV8.bw_and rd (BV8.bw_not mask)))
......@@ -589,8 +658,8 @@ let bld (dst: register) (bit: int): unit
let bld' (dst: register) (bit: int): unit
writes { reg }
requires { 0 <= bit < 8 }
ensures { reg = (old reg)[dst <- BV8.t'int (bitset' (BV8.of_int (old reg)[dst]) bit tf.value)] }
= let rd = BV8.of_int (Map.get reg.data dst) in
ensures { reg = (old reg)[dst <- BV8.t'int (bitset' (BV8.of_int (old reg)[dst]) bit !tf)] }
= let rd = BV8.of_int (read reg dst) in
let mask = BV8.lsl (BV8.of_int 1) bit in
if ?tf = 0 then
reg.data <- data_set reg.data dst (BV8.t'int (BV8.bw_and rd (BV8.bw_not mask)))
......@@ -600,8 +669,8 @@ let bld' (dst: register) (bit: int): unit
let bld'' (dst: register) (bit: int): unit
writes { reg }
requires { 0 <= bit < 8 }
ensures { reg = (old reg)[dst <- BV8.t'int (bitsetx (BV8.of_int (old reg)[dst]) bit tf.value)] }
= let rd = BV8.of_int (Map.get reg.data dst) in
ensures { reg = (old reg)[dst <- BV8.t'int (bitsetx (BV8.of_int (old reg)[dst]) bit !tf)] }
= let rd = BV8.of_int (read reg dst) in
let mask = BV8.lsl (BV8.of_int 1) bit in
if ?tf = 0 then
reg.data <- data_set reg.data dst (BV8.t'int (BV8.bw_and rd (BV8.bw_not mask)))
......@@ -709,38 +778,38 @@ predicate synchronized (self: shadow_registers) (avr: address_space) =
val shadow: shadow_registers
let ghost modify_r0 () ensures { !(shadow.r0) = reg.data[0] } = shadow.r0 := Map.get reg.data 0
let ghost modify_r1 () ensures { !(shadow.r1) = reg.data[1] } = shadow.r1 := Map.get reg.data 1; ()
let ghost modify_r2 () ensures { !(shadow.r2) = reg.data[2] } = shadow.r2 := Map.get reg.data 2
let ghost modify_r3 () ensures { !(shadow.r3) = reg.data[3] } = shadow.r3 := Map.get reg.data 3
let ghost modify_r4 () ensures { !(shadow.r4) = reg.data[4] } = shadow.r4 := Map.get reg.data 4
let ghost modify_r5 () ensures { !(shadow.r5) = reg.data[5] } = shadow.r5 := Map.get reg.data 5
let ghost modify_r6 () ensures { !(shadow.r6) = reg.data[6] } = shadow.r6 := Map.get reg.data 6
let ghost modify_r7 () ensures { !(shadow.r7) = reg.data[7] } = shadow.r7 := Map.get reg.data 7
let ghost modify_r8 () ensures { !(shadow.r8) = reg.data[8] } = shadow.r8 := Map.get reg.data 8
let ghost modify_r9 () ensures { !(shadow.r9) = reg.data[9] } = shadow.r9 := Map.get reg.data 9
let ghost modify_r10 () ensures { !(shadow.r10) = reg.data[10] } = shadow.r10 := Map.get reg.data 10
let ghost modify_r11 () ensures { !(shadow.r11) = reg.data[11] } = shadow.r11 := Map.get reg.data 11
let ghost modify_r12 () ensures { !(shadow.r12) = reg.data[12] } = shadow.r12 := Map.get reg.data 12
let ghost modify_r13 () ensures { !(shadow.r13) = reg.data[13] } = shadow.r13 := Map.get reg.data 13
let ghost modify_r14 () ensures { !(shadow.r14) = reg.data[14] } = shadow.r14 := Map.get reg.data 14
let ghost modify_r15 () ensures { !(shadow.r15) = reg.data[15] } = shadow.r15 := Map.get reg.data 15
let ghost modify_r16 () ensures { !(shadow.r16) = reg.data[16] } = shadow.r16 := Map.get reg.data 16
let ghost modify_r17 () ensures { !(shadow.r17) = reg.data[17] } = shadow.r17 := Map.get reg.data 17
let ghost modify_r18 () ensures { !(shadow.r18) = reg.data[18] } = shadow.r18 := Map.get reg.data 18
let ghost modify_r19 () ensures { !(shadow.r19) = reg.data[19] } = shadow.r19 := Map.get reg.data 19
let ghost modify_r20 () ensures { !(shadow.r20) = reg.data[20] } = shadow.r20 := Map.get reg.data 20
let ghost modify_r21 () ensures { !(shadow.r21) = reg.data[21] } = shadow.r21 := Map.get reg.data 21
let ghost modify_r22 () ensures { !(shadow.r22) = reg.data[22] } = shadow.r22 := Map.get reg.data 22
let ghost modify_r23 () ensures { !(shadow.r23) = reg.data[23] } = shadow.r23 := Map.get reg.data 23
let ghost modify_r24 () ensures { !(shadow.r24) = reg.data[24] } = shadow.r24 := Map.get reg.data 24
let ghost modify_r25 () ensures { !(shadow.r25) = reg.data[25] } = shadow.r25 := Map.get reg.data 25
let ghost modify_r26 () ensures { !(shadow.r26) = reg.data[26] } = shadow.r26 := Map.get reg.data 26
let ghost modify_r27 () ensures { !(shadow.r27) = reg.data[27] } = shadow.r27 := Map.get reg.data 27
let ghost modify_r28 () ensures { !(shadow.r28) = reg.data[28] } = shadow.r28 := Map.get reg.data 28
let ghost modify_r29 () ensures { !(shadow.r29) = reg.data[29] } = shadow.r29 := Map.get reg.data 29
let ghost modify_r30 () ensures { !(shadow.r30) = reg.data[30] } = shadow.r30 := Map.get reg.data 30
let ghost modify_r31 () ensures { !(shadow.r31) = reg.data[31] } = shadow.r31 := Map.get reg.data 31
let ghost modify_r0 () ensures { !(shadow.r0) = reg.data[0] } = shadow.r0 := read reg 0
let ghost modify_r1 () ensures { !(shadow.r1) = reg.data[1] } = shadow.r1 := read reg 1; ()
let ghost modify_r2 () ensures { !(shadow.r2) = reg.data[2] } = shadow.r2 := read reg 2
let ghost modify_r3 () ensures { !(shadow.r3) = reg.data[3] } = shadow.r3 := read reg 3
let ghost modify_r4 () ensures { !(shadow.r4) = reg.data[4] } = shadow.r4 := read reg 4
let ghost modify_r5 () ensures { !(shadow.r5) = reg.data[5] } = shadow.r5 := read reg 5
let ghost modify_r6 () ensures { !(shadow.r6) = reg.data[6] } = shadow.r6 := read reg 6
let ghost modify_r7 () ensures { !(shadow.r7) = reg.data[7] } = shadow.r7 := read reg 7
let ghost modify_r8 () ensures { !(shadow.r8) = reg.data[8] } = shadow.r8 := read reg 8
let ghost modify_r9 () ensures { !(shadow.r9) = reg.data[9] } = shadow.r9 := read reg 9
let ghost modify_r10 () ensures { !(shadow.r10) = reg.data[10] } = shadow.r10 := read reg 10
let ghost modify_r11 () ensures { !(shadow.r11) = reg.data[11] } = shadow.r11 := read reg 11
let ghost modify_r12 () ensures { !(shadow.r12) = reg.data[12] } = shadow.r12 := read reg 12
let ghost modify_r13 () ensures { !(shadow.r13) = reg.data[13] } = shadow.r13 := read reg 13
let ghost modify_r14 () ensures { !(shadow.r14) = reg.data[14] } = shadow.r14 := read reg 14
let ghost modify_r15 () ensures { !(shadow.r15) = reg.data[15] } = shadow.r15 := read reg 15
let ghost modify_r16 () ensures { !(shadow.r16) = reg.data[16] } = shadow.r16 := read reg 16
let ghost modify_r17 () ensures { !(shadow.r17) = reg.data[17] } = shadow.r17 := read reg 17
let ghost modify_r18 () ensures { !(shadow.r18) = reg.data[18] } = shadow.r18 := read reg 18
let ghost modify_r19 () ensures { !(shadow.r19) = reg.data[19] } = shadow.r19 := read reg 19
let ghost modify_r20 () ensures { !(shadow.r20) = reg.data[20] } = shadow.r20 := read reg 20
let ghost modify_r21 () ensures { !(shadow.r21) = reg.data[21] } = shadow.r21 := read reg 21
let ghost modify_r22 () ensures { !(shadow.r22) = reg.data[22] } = shadow.r22 := read reg 22
let ghost modify_r23 () ensures { !(shadow.r23) = reg.data[23] } = shadow.r23 := read reg 23
let ghost modify_r24 () ensures { !(shadow.r24) = reg.data[24] } = shadow.r24 := read reg 24
let ghost modify_r25 () ensures { !(shadow.r25) = reg.data[25] } = shadow.r25 := read reg 25
let ghost modify_r26 () ensures { !(shadow.r26) = reg.data[26] } = shadow.r26 := read reg 26
let ghost modify_r27 () ensures { !(shadow.r27) = reg.data[27] } = shadow.r27 := read reg 27
let ghost modify_r28 () ensures { !(shadow.r28) = reg.data[28] } = shadow.r28 := read reg 28
let ghost modify_r29 () ensures { !(shadow.r29) = reg.data[29] } = shadow.r29 := read reg 29
let ghost modify_r30 () ensures { !(shadow.r30) = reg.data[30] } = shadow.r30 := read reg 30
let ghost modify_r31 () ensures { !(shadow.r31) = reg.data[31] } = shadow.r31 := read reg 31
let ghost init() ensures { synchronized shadow reg } =
modify_r0 ();
......
......@@ -2,272 +2,458 @@
<!DOCTYPE why3session PUBLIC "-//Why3//proof session v5//EN"
"http://why3.lri.fr/why3session.dtd">
<why3session shape_version="5">
<prover id="0" name="CVC3" version="2.4.1" timelimit="13" steplimit="0" memlimit="1000"/>
<prover id="2" name="CVC4" version="1.4" timelimit="13" steplimit="0" memlimit="1000"/>
<prover id="3" name="CVC4" version="1.5" timelimit="1" steplimit="0" memlimit="1000"/>
<prover id="4" name="Alt-Ergo" version="2.0.0" timelimit="13" steplimit="0" memlimit="1000"/>
<prover id="5" name="CVC4" version="1.4" alternative="noBV" timelimit="13" steplimit="0" memlimit="1000"/>
<prover id="6" name="CVC4" version="1.5" alternative="noBV" timelimit="60" steplimit="0" memlimit="12000"/>
<prover id="7" name="CVC4" version="1.6" alternative="noBV" timelimit="60" steplimit="0" memlimit="12000"/>
<prover id="8" name="CVC4" version="1.6" timelimit="60" steplimit="0" memlimit="12000"/>
<file proved="true">
<prover id="0" name="CVC4" version="1.4" timelimit="5" steplimit="0" memlimit="1000"/>
<prover id="1" name="Z3" version="4.4.1" alternative="noBV" timelimit="60" steplimit="0" memlimit="12000"/>
<prover id="2" name="Alt-Ergo" version="2.0.0" timelimit="13" steplimit="0" memlimit="1000"/>
<prover id="3" name="CVC4" version="1.6" alternative="noBV" timelimit="1" steplimit="0" memlimit="1000"/>
<prover id="4" name="CVC4" version="1.4" alternative="noBV" timelimit="13" steplimit="0" memlimit="1000"/>
<prover id="5" name="CVC3" version="2.4.1" timelimit="13" steplimit="0" memlimit="1000"/>
<prover id="6" name="Z3" version="4.4.1" timelimit="1" steplimit="0" memlimit="1000"/>
<prover id="7" name="CVC4" version="1.6" timelimit="1" steplimit="0" memlimit="1000"/>
<prover id="8" name="CVC4" version="1.5" timelimit="1" steplimit="0" memlimit="1000"/>
<file>
<path name=".."/>
<path name="avrmodel.mlw"/>
<theory name="AVRint" proved="true">
<theory name="AVRint">
<goal name="VC prefix ?" expl="VC for prefix ?" proved="true">
<proof prover="3"><result status="valid" time="0.02"/></proof>
<proof prover="4" timelimit="60" memlimit="12000"><result status="valid" time="0.04"/></proof>
</goal>
<goal name="VC address_space_exists" expl="VC for address_space_exists" proved="true">