(** Useful simplification tactic *)

Ltac Simplif :=
  match goal with
  | [ |- nextinstr_nf _ _ = _ ] =>
      ((rewrite nextinstr_nf_inv by auto with asmgen)
       || (rewrite nextinstr_nf_inv1 by auto with asmgen)); auto
  | [ |- nextinstr _ _ = _ ] =>
      ((rewrite nextinstr_inv by auto with asmgen)
       || (rewrite nextinstr_inv1 by auto with asmgen)); auto
  | [ |- Pregmap.get ?x (Pregmap.set ?x _ _) = _ ] =>
      rewrite Pregmap.gss; auto
  | [ |- Pregmap.set ?x _ _ ?x = _ ] =>
      rewrite Pregmap.gss; auto
  | [ |- Pregmap.get _ (Pregmap.set _ _ _) = _ ] =>
      rewrite Pregmap.gso by (auto with asmgen); auto
  | [ |- Pregmap.set _ _ _ _ = _ ] =>
      rewrite Pregmap.gso by (auto with asmgen); auto
  end.Ltac Simplifs := repeat Simplif.

(* Specifications: *)
Lemma divu_modu_exists: forall v1 v2, Val.divu v1 v2 <> None \/ Val.modu v1 v2 <> None -> exists n d q r, v1 = Vint n /\ v2 = Vint d /\ Int.divmodu2 Int.zero n d = Some(q, r) /\ Val.divu v1 v2 = Some (Vint q) /\ Val.modu v1 v2 = Some (Vint r).
Lemma divs_mods_exists: forall v1 v2, Val.divs v1 v2 <> None \/ Val.mods v1 v2 <> None -> exists nh nl d q r, Val.shr v1 (Vint (Int.repr 31)) = Vint nh /\ v1 = Vint nl /\ v2 = Vint d /\ Int.divmods2 nh nl d = Some(q, r) /\ Val.divs v1 v2 = Some (Vint q) /\ Val.mods v1 v2 = Some (Vint r).
Lemma divlu_modlu_exists: forall v1 v2, Val.divlu v1 v2 <> None \/ Val.modlu v1 v2 <> None -> exists n d q r, v1 = Vlong n /\ v2 = Vlong d /\ Int64.divmodu2 Int64.zero n d = Some(q, r) /\ Val.divlu v1 v2 = Some (Vlong q) /\ Val.modlu v1 v2 = Some (Vlong r).
Lemma divls_modls_exists: forall v1 v2, Val.divls v1 v2 <> None \/ Val.modls v1 v2 <> None -> exists nh nl d q r, Val.shrl v1 (Vint (Int.repr 63)) = Vlong nh /\ v1 = Vlong nl /\ v2 = Vlong d /\ Int64.divmods2 nh nl d = Some(q, r) /\ Val.divls v1 v2 = Some (Vlong q) /\ Val.modls v1 v2 = Some (Vlong r).
Lemma addressing_mentions_correct: forall a r (rs1 rs2: regset), (forall (r': ireg), r' <> r -> rs1 r' = rs2 r') -> addressing_mentions a r = false -> eval_addrmode32 ge a rs1 = eval_addrmode32 ge a rs2.