Remark decompose_int_thumb_nil:
  forall N n p, decompose_int_thumb N n p = nil -> n = Int.zero.

(* Specifications: *)
Lemma decompose_int_general: forall (f: val -> int -> val) (g: int -> int -> int), (forall v1 n2 n3, f (f v1 n2) n3 = f v1 (g n2 n3)) -> (forall n1 n2 n3, g (g n1 n2) n3 = g n1 (g n2 n3)) -> (forall n, g Int.zero n = n) -> (forall N n p x, List.fold_left g (decompose_int_arm N n p) x = g x n) -> (forall N n p x, List.fold_left g (decompose_int_thumb N n p) x = g x n) -> forall n v, List.fold_left f (decompose_int n) v = f v n.
Lemma decompose_int_or: forall n v, List.fold_left (fun v i => Val.or v (Vint i)) (decompose_int n) v = Val.or v (Vint n).
Lemma decompose_int_bic: forall n v, List.fold_left (fun v i => Val.and v (Vint (Int.not i))) (decompose_int n) v = Val.and v (Vint (Int.not n)).
Lemma decompose_int_xor: forall n v, List.fold_left (fun v i => Val.xor v (Vint i)) (decompose_int n) v = Val.xor v (Vint n).
Lemma decompose_int_add: forall n v, List.fold_left (fun v i => Val.add v (Vint i)) (decompose_int n) v = Val.add v (Vint n).
Lemma decompose_int_sub: forall n v, List.fold_left (fun v i => Val.sub v (Vint i)) (decompose_int n) v = Val.sub v (Vint n).
Lemma int_signed_eq: forall x y, Int.eq x y = zeq (Int.signed x) (Int.signed y).
Lemma int_not_lt: forall x y, negb (Int.lt y x) = (Int.lt x y || Int.eq x y).
Lemma int_lt_not: forall x y, Int.lt y x = negb (Int.lt x y) && negb (Int.eq x y).
Lemma int_not_ltu: forall x y, negb (Int.ltu y x) = (Int.ltu x y || Int.eq x y).
Lemma int_ltu_not: forall x y, Int.ltu y x = negb (Int.ltu x y) && negb (Int.eq x y).
Lemma cond_for_signed_cmp_correct: forall c v1 v2 rs m b, Val.cmp_bool c v1 v2 = Some b -> eval_testcond (cond_for_signed_cmp c) (nextinstr (compare_int rs v1 v2 m)) = Some b.
Lemma cond_for_unsigned_cmp_correct: forall c v1 v2 rs m b, Val.cmpu_bool (Mem.valid_pointer m) c v1 v2 = Some b -> eval_testcond (cond_for_unsigned_cmp c) (nextinstr (compare_int rs v1 v2 m)) = Some b.
Lemma compare_float_nextpc: forall rs v1 v2, nextinstr (compare_float rs v1 v2) PC = Val.offset_ptr (rs PC) Ptrofs.one.
Lemma cond_for_float_cmp_correct: forall c n1 n2 rs, eval_testcond (cond_for_float_cmp c) (nextinstr (compare_float rs (Vfloat n1) (Vfloat n2))) = Some(Float.cmp c n1 n2).
Lemma cond_for_float_not_cmp_correct: forall c n1 n2 rs, eval_testcond (cond_for_float_not_cmp c) (nextinstr (compare_float rs (Vfloat n1) (Vfloat n2)))= Some(negb(Float.cmp c n1 n2)).
Lemma compare_float32_nextpc: forall rs v1 v2, nextinstr (compare_float32 rs v1 v2) PC = Val.offset_ptr (rs PC) Ptrofs.one.
Lemma cond_for_float32_cmp_correct: forall c n1 n2 rs, eval_testcond (cond_for_float_cmp c) (nextinstr (compare_float32 rs (Vsingle n1) (Vsingle n2))) = Some(Float32.cmp c n1 n2).
Lemma cond_for_float32_not_cmp_correct: forall c n1 n2 rs, eval_testcond (cond_for_float_not_cmp c) (nextinstr (compare_float32 rs (Vsingle n1) (Vsingle n2)))= Some(negb(Float32.cmp c n1 n2)).