(** Processor conditions and comparisons *)

(* Specifications: *)
Lemma compare_ints_spec:
forall rs v1 v2 m,
let rs' := nextinstr (compare_ints v1 v2 rs m) in
rs'#ZF = Val.cmpu (Mem.valid_pointer m) Ceq v1 v2
/\ rs'#CF = Val.cmpu (Mem.valid_pointer m) Clt v1 v2
/\ rs'#SF = Val.negative (Val.sub v1 v2)
/\ rs'#OF = Val.sub_overflow v1 v2
/\ (forall r, data_preg r = true -> rs'#r = rs#r).
Lemma testcond_for_signed_comparison_32_correct:
forall c v1 v2 rs m b,
Val.cmp_bool c v1 v2 = Some b ->
eval_testcond (testcond_for_signed_comparison c)
(nextinstr (compare_ints v1 v2 rs m)) = Some b.
Lemma testcond_for_unsigned_comparison_32_correct:
forall c v1 v2 rs m b,
Val.cmpu_bool (Mem.valid_pointer m) c v1 v2 = Some b ->
eval_testcond (testcond_for_unsigned_comparison c)
(nextinstr (compare_ints v1 v2 rs m)) = Some b.
Lemma compare_longs_spec:
forall rs v1 v2 m,
let rs' := nextinstr (compare_longs v1 v2 rs m) in
rs'#ZF = Val.maketotal (Val.cmplu (Mem.valid_pointer m) Ceq v1 v2)
/\ rs'#CF = Val.maketotal (Val.cmplu (Mem.valid_pointer m) Clt v1 v2)
/\ rs'#SF = Val.negativel (Val.subl v1 v2)
/\ rs'#OF = Val.subl_overflow v1 v2
/\ (forall r, data_preg r = true -> rs'#r = rs#r).
Lemma int64_sub_overflow:
forall x y,
Int.xor (Int.repr (Int64.unsigned (Int64.sub_overflow x y Int64.zero)))
(Int.repr (Int64.unsigned (Int64.negative (Int64.sub x y)))) =
(if Int64.lt x y then Int.one else Int.zero).
Lemma testcond_for_signed_comparison_64_correct:
forall c v1 v2 rs m b,
Val.cmpl_bool c v1 v2 = Some b ->
eval_testcond (testcond_for_signed_comparison c)
(nextinstr (compare_longs v1 v2 rs m)) = Some b.
Lemma testcond_for_unsigned_comparison_64_correct:
forall c v1 v2 rs m b,
Val.cmplu_bool (Mem.valid_pointer m) c v1 v2 = Some b ->
eval_testcond (testcond_for_unsigned_comparison c)
(nextinstr (compare_longs v1 v2 rs m)) = Some b.
Lemma compare_floats_spec:
forall rs n1 n2,
let rs' := nextinstr (compare_floats (Vfloat n1) (Vfloat n2) rs) in
rs'#ZF = Val.of_bool (Float.cmp Ceq n1 n2 || negb (Float.ordered n1 n2))
/\ rs'#CF = Val.of_bool (negb (Float.cmp Cge n1 n2))
/\ rs'#PF = Val.of_bool (negb (Float.ordered n1 n2))
/\ (forall r, data_preg r = true -> rs'#r = rs#r).
Lemma compare_floats32_spec:
forall rs n1 n2,
let rs' := nextinstr (compare_floats32 (Vsingle n1) (Vsingle n2) rs) in
rs'#ZF = Val.of_bool (Float32.cmp Ceq n1 n2 || negb (Float32.ordered n1 n2))
/\ rs'#CF = Val.of_bool (negb (Float32.cmp Cge n1 n2))
/\ rs'#PF = Val.of_bool (negb (Float32.ordered n1 n2))
/\ (forall r, data_preg r = true -> rs'#r = rs#r).