aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2023-10-30 14:55:51 +0100
committerYann Herklotz <git@yannherklotz.com>2023-10-30 14:56:54 +0100
commit64a7fd889491bedffa3e3bcf130599c841c7008e (patch)
treed44e90c7aa37d74b41f48e237b46dad2aee67959
parent9db69b471864cb9e3868dd2c82bc0e2df3955b51 (diff)
downloadvericert-64a7fd889491bedffa3e3bcf130599c841c7008e.tar.gz
vericert-64a7fd889491bedffa3e3bcf130599c841c7008e.zip
Changed and proved some more theorems
-rw-r--r--src/hls/DHTLgen.v41
-rw-r--r--src/hls/DHTLgenproof.v1051
-rw-r--r--src/hls/HTLgenproof.v2412
-rw-r--r--src/hls/Predicate.v26
4 files changed, 2192 insertions, 1338 deletions
diff --git a/src/hls/DHTLgen.v b/src/hls/DHTLgen.v
index d573dda..d9e1cd4 100644
--- a/src/hls/DHTLgen.v
+++ b/src/hls/DHTLgen.v
@@ -291,7 +291,7 @@ Definition tbl_to_case_expr (st : reg) (ns : list node) : list (expr * stmnt) :=
end)
(enumerate 0 ns).
-Definition translate_cfi (ctrl: control_regs) p (cfi: cf_instr)
+Definition translate_cfi curr_n (ctrl: control_regs) p (cfi: cf_instr)
: Errors.res stmnt :=
match cfi with
| RBgoto n' =>
@@ -302,9 +302,13 @@ Definition translate_cfi (ctrl: control_regs) p (cfi: cf_instr)
| RBreturn r =>
match r with
| Some r' =>
- Errors.OK (Vseq (Vblock (Vvar ctrl.(ctrl_fin)) (Vlit (ZToValue 1%Z))) (Vblock (Vvar ctrl.(ctrl_return)) (Vvar (reg_enc r'))))
+ Errors.OK (Vseq (Vseq (translate_predicate Vblock p (Vvar ctrl.(ctrl_fin)) (Vlit (ZToValue 1)))
+ (translate_predicate Vblock p (Vvar ctrl.(ctrl_return)) (Vvar (reg_enc r'))))
+ (state_goto p ctrl.(ctrl_st) curr_n))
| None =>
- Errors.OK (Vseq (Vblock (Vvar ctrl.(ctrl_fin)) (Vlit (ZToValue 1%Z))) (Vblock (Vvar ctrl.(ctrl_return)) (Vlit (ZToValue 0%Z))))
+ Errors.OK (Vseq (Vseq (translate_predicate Vblock p (Vvar ctrl.(ctrl_fin)) (Vlit (ZToValue 1)))
+ (translate_predicate Vblock p (Vvar ctrl.(ctrl_return)) (Vlit (ZToValue 0))))
+ (state_goto p ctrl.(ctrl_st) curr_n))
end
| RBjumptable r tbl =>
Errors.OK (Vcase (Vvar (reg_enc r)) (list_to_stmnt (tbl_to_case_expr ctrl.(ctrl_st) tbl)) (Some Vskip))
@@ -316,7 +320,23 @@ Definition translate_cfi (ctrl: control_regs) p (cfi: cf_instr)
Errors.Error (Errors.msg "HTLPargen: RBbuildin not supported.")
end.
-Definition transf_instr (ctrl: control_regs) (dc: pred_op * stmnt) (i: instr)
+Definition assert_ (b: bool) m: res unit :=
+ if b then OK tt else Error (msg m).
+
+Definition check_cfi n (cfi: cf_instr): res unit :=
+ do _assert <- assert_ (Z.pos n <=? Integers.Int.max_unsigned) "DHTLgen: State larger than 2^32";
+ match cfi with
+ | RBgoto n' =>
+ assert_ (Z.pos n' <=? Integers.Int.max_unsigned) "DHTLgen: State larger than 2^32"
+ | RBcond c args n1 n2 =>
+ assert_ ((Z.pos n1 <=? Integers.Int.max_unsigned)
+ && (Z.pos n2 <=? Integers.Int.max_unsigned)) "DHTLgen: State larger than 2^32"
+ | RBjumptable r tbl =>
+ assert_ (forallb (fun x => Z.pos x <=? Integers.Int.max_unsigned) tbl) "DHTLgen: State larger than 2^32"
+ | _ => OK tt
+ end.
+
+Definition transf_instr n (ctrl: control_regs) (dc: pred_op * stmnt) (i: instr)
: Errors.res (pred_op * stmnt) :=
let '(curr_p, d) := dc in
let npred p := Some (Pand curr_p (dfltp p)) in
@@ -339,24 +359,25 @@ Definition transf_instr (ctrl: control_regs) (dc: pred_op * stmnt) (i: instr)
let stmnt := translate_predicate Vblock (npred p') (pred_expr (Plit (true, p))) cond' in
Errors.OK (curr_p, Vseq d stmnt)
| RBexit p cf =>
- do d_stmnt <- translate_cfi ctrl (npred p) cf;
+ do _check <- check_cfi n cf;
+ do d_stmnt <- translate_cfi n ctrl (npred p) cf;
Errors.OK (Pand curr_p (negate (dfltp p)), Vseq d d_stmnt)
end.
-Definition transf_chained_block (ctrl: control_regs) (dc: @pred_op positive * stmnt) (block: list instr)
+Definition transf_chained_block n (ctrl: control_regs) (dc: @pred_op positive * stmnt) (block: list instr)
: Errors.res (pred_op * stmnt) :=
- mfold_left (transf_instr ctrl) block (OK dc).
+ mfold_left (transf_instr n ctrl) block (OK dc).
-Definition transf_parallel_block (ctrl: control_regs) (block: list (list instr))
+Definition transf_parallel_block n (ctrl: control_regs) (block: list (list instr))
: Errors.res (pred_op * stmnt) :=
- mfold_left (transf_chained_block ctrl) block (OK (Ptrue, Vskip)).
+ mfold_left (transf_chained_block n ctrl) block (OK (Ptrue, Vskip)).
Definition transf_seq_block (ctrl: control_regs) (d: datapath) (ni: node * SubParBB.t)
: Errors.res datapath :=
let (n, bb) := ni in
match d ! n with
| None =>
- do (_pred, stmnt) <- transf_chained_block ctrl (Ptrue, Vskip) (concat bb);
+ do (_pred, stmnt) <- transf_chained_block n ctrl (Ptrue, Vskip) (concat bb);
OK (PTree.set n stmnt d)
| _ => Error (msg "DHTLgen: overwriting location")
end.
diff --git a/src/hls/DHTLgenproof.v b/src/hls/DHTLgenproof.v
index bd8320e..6b2cc8d 100644
--- a/src/hls/DHTLgenproof.v
+++ b/src/hls/DHTLgenproof.v
@@ -49,11 +49,16 @@ Require Import Lia.
Local Open Scope assocmap.
+Local Opaque Int.max_unsigned.
+
#[local] Hint Resolve AssocMap.gss : htlproof.
#[local] Hint Resolve AssocMap.gso : htlproof.
#[local] Hint Unfold find_assocmap AssocMapExt.get_default : htlproof.
+Definition get_mem n r :=
+ Option.default (NToValue 0) (Option.join (array_get_error n r)).
+
Inductive match_assocmaps : positive -> positive -> Gible.regset -> Gible.predset -> assocmap -> Prop :=
match_assocmap : forall rs pr am max_reg max_pred,
(forall r, Ple r max_reg ->
@@ -73,8 +78,7 @@ Inductive match_arrs (stack_size: Z) (stk: positive) (stk_len: nat) (sp : Values
0 <= ptr < Z.of_nat stack.(arr_length) ->
opt_val_value_lessdef (Mem.loadv AST.Mint32 mem
(Values.Val.offset_ptr sp (Ptrofs.repr (4 * ptr))))
- (Option.default (NToValue 0)
- (Option.join (array_get_error (Z.to_nat ptr) stack)))) ->
+ (get_mem (Z.to_nat ptr) stack)) ->
match_arrs stack_size stk stk_len sp mem asa.
Definition stack_based (v : Values.val) (sp : Values.block) : Prop :=
@@ -1104,6 +1108,7 @@ Ltac unfold_merge :=
(combine merge_cell (arr_repeat None (Datatypes.length arr_contents))
{| arr_contents := arr_contents; arr_length := Datatypes.length arr_contents; arr_wf := eq_refl |}))).
{ apply array_get_error_equal; auto. cbn. now rewrite list_combine_none. }
+ unfold get_mem in *.
rewrite <- H1. auto.
Qed.
@@ -1265,8 +1270,8 @@ Proof.
Qed.
Lemma transl_iop_correct:
- forall ctrl sp max_reg max_pred d d' curr_p next_p rs ps m rs' ps' p op args dst asr arr asr' arr' stk stk_len,
- transf_instr ctrl (curr_p, d) (RBop p op args dst) = Errors.OK (next_p, d') ->
+ forall ctrl sp max_reg max_pred d d' curr_p next_p rs ps m rs' ps' p op args dst asr arr asr' arr' stk stk_len n,
+ transf_instr n ctrl (curr_p, d) (RBop p op args dst) = Errors.OK (next_p, d') ->
step_instr ge sp (Iexec (mk_instr_state rs ps m)) (RBop p op args dst) (Iexec (mk_instr_state rs' ps m)) ->
stmnt_runp tt (e_assoc asr) (e_assoc_arr stk stk_len arr) d (e_assoc asr') (e_assoc_arr stk stk_len arr') ->
match_assocmaps max_reg max_pred rs ps asr' ->
@@ -1387,6 +1392,17 @@ Opaque Mem.alloc.
eauto.
Qed.
+ Lemma mfold_left_app:
+ forall A B f a l x y,
+ @mfold_left A B f (a ++ l) x = OK y ->
+ exists y', @mfold_left A B f a x = OK y' /\ @mfold_left A B f l (OK y') = OK y.
+ Proof.
+ induction a.
+ - intros. destruct x; [|now rewrite mfold_left_error in H]. exists a. eauto.
+ - intros. destruct x; [|now rewrite mfold_left_error in H]. rewrite <- app_comm_cons in H.
+ exploit mfold_left_cons; eauto.
+ Qed.
+
Lemma step_cf_instr_pc_ind :
forall s f sp rs' pr' m' pc pc' cf t state,
step_cf_instr ge (GibleSubPar.State s f sp pc rs' pr' m') cf t state ->
@@ -1444,10 +1460,812 @@ Opaque Mem.alloc.
+ cbn in *. eapply step_exec_concat2'; eauto.
Qed.
+ Lemma one_ne_zero:
+ Int.repr 1 <> Int.repr 0.
+ Proof.
+ unfold not; intros.
+ assert (Int.unsigned (Int.repr 1) = Int.unsigned (Int.repr 0)) by (now rewrite H).
+ rewrite ! Int.unsigned_repr in H0 by crush. lia.
+ Qed.
+
+ Lemma int_and_boolToValue :
+ forall b1 b2,
+ Int.and (boolToValue b1) (boolToValue b2) = boolToValue (b1 && b2).
+ Proof.
+ destruct b1; destruct b2; cbn; unfold boolToValue; unfold natToValue;
+ replace (Z.of_nat 1) with 1 by auto;
+ replace (Z.of_nat 0) with 0 by auto.
+ - apply Int.and_idem.
+ - apply Int.and_zero.
+ - apply Int.and_zero_l.
+ - apply Int.and_zero.
+ Qed.
+
+ Lemma int_or_boolToValue :
+ forall b1 b2,
+ Int.or (boolToValue b1) (boolToValue b2) = boolToValue (b1 || b2).
+ Proof.
+ destruct b1; destruct b2; cbn; unfold boolToValue; unfold natToValue;
+ replace (Z.of_nat 1) with 1 by auto;
+ replace (Z.of_nat 0) with 0 by auto.
+ - apply Int.or_idem.
+ - apply Int.or_zero.
+ - apply Int.or_zero_l.
+ - apply Int.or_zero_l.
+ Qed.
+
+ Lemma pred_expr_correct :
+ forall curr_p pr asr asa,
+ (forall r, Ple r (max_predicate curr_p) ->
+ find_assocmap 1 (pred_enc r) asr = boolToValue (PMap.get r pr)) ->
+ expr_runp tt asr asa (pred_expr curr_p) (boolToValue (eval_predf pr curr_p)).
+ Proof.
+ induction curr_p.
+ - intros * HFRL. cbn. destruct p as [b p']. destruct b.
+ + constructor. eapply HFRL. cbn. unfold Ple. lia.
+ + econstructor. constructor. eapply HFRL. cbn. unfold Ple; lia.
+ econstructor. cbn. f_equal. unfold boolToValue.
+ f_equal. destruct pr !! p' eqn:?. cbn.
+ rewrite Int.eq_false; auto. unfold natToValue.
+ replace (Z.of_nat 1) with 1 by auto. unfold Int.zero.
+ apply one_ne_zero.
+ cbn. rewrite Int.eq_true; auto.
+ - intros. cbn. constructor.
+ - intros. cbn. constructor.
+ - cbn -[eval_predf]; intros. econstructor. eapply IHcurr_p1. intros. eapply H.
+ unfold Ple in *. lia.
+ eapply IHcurr_p2; intros. eapply H. unfold Ple in *; lia.
+ cbn -[eval_predf]. f_equal. symmetry. apply int_and_boolToValue.
+ - cbn -[eval_predf]; intros. econstructor. eapply IHcurr_p1. intros. eapply H.
+ unfold Ple in *. lia.
+ eapply IHcurr_p2; intros. eapply H. unfold Ple in *; lia.
+ cbn -[eval_predf]. f_equal. symmetry. apply int_or_boolToValue.
+ Qed.
+
+ Local Opaque deep_simplify.
+
+ Lemma valueToBool_correct:
+ forall b,
+ valueToBool (boolToValue b) = b.
+ Proof.
+ unfold valueToBool, boolToValue; intros.
+ unfold uvalueToZ, natToValue. destruct b; cbn;
+ rewrite Int.unsigned_repr; crush.
+ Qed.
+
+ Lemma negb_inj':
+ forall a b, a = b -> negb a = negb b.
+ Proof. intros. destruct a, b; auto. Qed.
+
+ Lemma transl_predicate_correct :
+ forall asr asa a b asr' asa' p r e max_pred max_reg rs ps,
+ stmnt_runp tt (e_assoc asr) (e_assoc_arr a b asa) (translate_predicate Vblock (Some p) (Vvar r) e) (e_assoc asr') (e_assoc_arr a b asa') ->
+ Ple (max_predicate p) max_pred ->
+ match_assocmaps max_reg max_pred rs ps asr ->
+ eval_predf ps p = false ->
+ (forall x, asr # x = asr' # x) /\ asa = asa'.
+ Proof.
+ intros * HSTMNT HPLE HMATCH HEVAL *.
+ pose proof HEVAL as HEVAL_DEEP.
+ erewrite <- eval_predf_deep_simplify in HEVAL_DEEP.
+ cbn in *. destruct_match.
+ - inv HSTMNT; inv H6. split; auto. intros.
+ exploit pred_expr_correct. inv HMATCH; eauto. intros. eapply H0. instantiate (1 := deep_simplify peq p) in H1.
+ eapply max_predicate_deep_simplify in H1. unfold Ple in *. lia.
+ intros. inv H7. unfold e_assoc in *; cbn in *.
+ pose proof H as H'. eapply expr_runp_determinate in H6; eauto. rewrite HEVAL_DEEP in H6.
+ rewrite H6 in H10. now rewrite valueToBool_correct in H10.
+ unfold e_assoc_arr, e_assoc in *; cbn in *. inv H9.
+ destruct (peq r0 x); subst; [now rewrite assocmap_gss|now rewrite assocmap_gso by auto].
+ - unfold sat_pred_simple in Heqo. repeat (destruct_match; try discriminate).
+ unfold eval_predf in HEVAL_DEEP.
+ apply negb_inj' in HEVAL_DEEP.
+ rewrite <- negate_correct in HEVAL_DEEP. rewrite e0 in HEVAL_DEEP. discriminate.
+ Qed.
+
+ Inductive lessdef_memory: option value -> option value -> Prop :=
+ | lessdef_memory_none:
+ lessdef_memory None (Some (ZToValue 0))
+ | lessdef_memory_eq: forall a,
+ lessdef_memory a a.
+
+ Lemma transl_predicate_correct_arr :
+ forall asr asa a b asr' asa' p r e max_pred max_reg rs ps e1,
+ stmnt_runp tt (e_assoc asr) (e_assoc_arr a b asa) (translate_predicate Vblock (Some p) (Vvari r e1) e) (e_assoc asr') (e_assoc_arr a b asa') ->
+ Ple (max_predicate p) max_pred ->
+ match_assocmaps max_reg max_pred rs ps asr ->
+ eval_predf ps p = false ->
+ asr = asr' /\ (forall x a, asa ! x = Some a -> exists a', asa' ! x = Some a'
+ /\ (forall y, (y < arr_length a)%nat -> exists av av', array_get_error y a = Some av /\ array_get_error y a' = Some av' /\ lessdef_memory av av')).
+ Proof.
+ intros * HSTMNT HPLE HMATCH HEVAL *.
+ pose proof HEVAL as HEVAL_DEEP.
+ erewrite <- eval_predf_deep_simplify in HEVAL_DEEP.
+ cbn in *. destruct_match.
+ - inv HSTMNT; inv H6; split; auto; intros.
+ exploit pred_expr_correct. inv HMATCH; eauto. intros. eapply H1. instantiate (1 := deep_simplify peq p) in H2.
+ eapply max_predicate_deep_simplify in H2. unfold Ple in *. lia.
+ intros. inv H7. unfold e_assoc in *; cbn in *.
+ pose proof H0 as H'. eapply expr_runp_determinate in H9; eauto. rewrite HEVAL_DEEP in H9.
+ rewrite H9 in H12. now rewrite valueToBool_correct in H12.
+ unfold e_assoc_arr, e_assoc in *; cbn in *. inv H11.
+ destruct (peq r0 x); subst.
+ + unfold arr_assocmap_set. rewrite H.
+ rewrite AssocMap.gss. eexists. split; eauto. unfold arr_assocmap_lookup in H10.
+ rewrite H in H10. inv H10. eapply expr_runp_determinate in H3; eauto. subst.
+ intros.
+ destruct (Nat.eq_dec y (valueToNat i)); subst.
+ * rewrite array_get_error_set_bound by auto.
+ destruct (array_get_error (valueToNat i) a1) eqn:?.
+ -- do 2 eexists. split; eauto. split. eauto.
+ destruct o; cbn; constructor.
+ -- exploit (@array_get_error_bound (option value)); eauto. simplify.
+ rewrite H3 in Heqo0. discriminate.
+ * rewrite array_gso by auto.
+ exploit (@array_get_error_bound (option value)); eauto. simplify.
+ rewrite H3. do 2 eexists; repeat split; constructor.
+ + unfold arr_assocmap_set. destruct_match.
+ * rewrite PTree.gso by auto. setoid_rewrite H. eexists. split; eauto.
+ intros. exploit (@array_get_error_bound (option value)); eauto. simplify.
+ rewrite H4. do 2 eexists; repeat split; constructor.
+ * eexists. split; eauto. intros. exploit (@array_get_error_bound (option value)); eauto. simplify.
+ rewrite H4. do 2 eexists; repeat split; constructor.
+ - unfold sat_pred_simple in Heqo. repeat (destruct_match; try discriminate).
+ unfold eval_predf in HEVAL_DEEP.
+ apply negb_inj' in HEVAL_DEEP.
+ rewrite <- negate_correct in HEVAL_DEEP. rewrite e0 in HEVAL_DEEP. discriminate.
+ Qed.
+
+ Lemma transl_predicate_correct2 :
+ forall asr asa a b p r e max_pred max_reg rs ps,
+ Ple (max_predicate p) max_pred ->
+ match_assocmaps max_reg max_pred rs ps asr ->
+ eval_predf ps p = false ->
+ exists asr', stmnt_runp tt (e_assoc asr) (e_assoc_arr a b asa) (translate_predicate Vblock (Some p) (Vvar r) e) (e_assoc asr') (e_assoc_arr a b asa) /\ (forall x, asr # x = asr' # x).
+ Proof.
+ intros * HPLE HMATCH HEVAL. pose proof HEVAL as HEVAL_DEEP.
+ unfold translate_predicate. erewrite <- eval_predf_deep_simplify in HEVAL_DEEP.
+ destruct_match.
+ - econstructor; split.
+ + econstructor; [econstructor|]. eapply erun_Vternary_false.
+ * eapply pred_expr_correct. intros. eapply max_predicate_deep_simplify in H.
+ inv HMATCH. eapply H1; unfold Ple in *. lia.
+ * now econstructor.
+ * rewrite HEVAL_DEEP. auto.
+ + intros. destruct (peq x r); subst.
+ * now rewrite assocmap_gss.
+ * now rewrite assocmap_gso.
+ - unfold sat_pred_simple in Heqo. repeat (destruct_match; try discriminate).
+ apply negb_inj' in HEVAL_DEEP. unfold eval_predf in *. rewrite <- negate_correct in HEVAL_DEEP.
+ now rewrite e0 in HEVAL_DEEP.
+ Qed.
+
+ Lemma arr_assocmap_set_gss :
+ forall r i v asa ar,
+ asa ! r = Some ar ->
+ (arr_assocmap_set r i v asa) ! r = Some (array_set i (Some v) ar).
+ Proof.
+ unfold arr_assocmap_set.
+ intros. rewrite H. rewrite PTree.gss. auto.
+ Qed.
+
+ Lemma arr_assocmap_set_gso :
+ forall r x i v asa ar,
+ asa ! x = Some ar ->
+ r <> x ->
+ (arr_assocmap_set r i v asa) ! x = asa ! x.
+ Proof.
+ unfold arr_assocmap_set. intros.
+ destruct (asa!r) eqn:?; auto; now rewrite PTree.gso by auto.
+ Qed.
+
+ Lemma arr_assocmap_set_gs2 :
+ forall r x i v asa,
+ asa ! x = None ->
+ (arr_assocmap_set r i v asa) ! x = None.
+ Proof.
+ unfold arr_assocmap_set. intros.
+ destruct (peq r x); subst; [now rewrite H|].
+ destruct (asa!r) eqn:?; auto.
+ now rewrite PTree.gso by auto.
+ Qed.
+
+ Lemma get_mem_set_array_gss :
+ forall y a x,
+ (y < arr_length a)%nat ->
+ get_mem y (array_set y (Some x) a) = x.
+ Proof.
+ unfold get_mem; intros.
+ rewrite array_get_error_set_bound by eauto; auto.
+ Qed.
+
+ Lemma get_mem_set_array_gss2 :
+ forall y a,
+ (y < arr_length a)%nat ->
+ get_mem y (array_set y None a) = ZToValue 0.
+ Proof.
+ unfold get_mem; intros.
+ rewrite array_get_error_set_bound by eauto; auto.
+ Qed.
+
+ Lemma get_mem_set_array_gso :
+ forall y a x z,
+ y <> z ->
+ get_mem y (array_set z x a) = get_mem y a.
+ Proof. unfold get_mem; intros. now rewrite array_gso by auto. Qed.
+
+ Lemma get_mem_set_array_gso2 :
+ forall y a x z,
+ (y >= arr_length a)%nat ->
+ get_mem y (array_set z x a) = ZToValue 0.
+ Proof.
+ intros; unfold get_mem. unfold array_get_error.
+ erewrite array_set_len with (i:=z) (x:=x) in H.
+ remember (array_set z x a). destruct a0. cbn in *. rewrite <- arr_wf in H.
+ assert (Datatypes.length arr_contents <= y)%nat by lia.
+ apply nth_error_None in H0. rewrite H0. auto.
+ Qed.
+
+ Lemma get_mem_set_array_gss3 :
+ forall y a,
+ get_mem y (array_set y None a) = ZToValue 0.
+ Proof.
+ intros.
+ assert (y < arr_length a \/ y >= arr_length a)%nat by lia.
+ inv H.
+ - now rewrite get_mem_set_array_gss2.
+ - now rewrite get_mem_set_array_gso2.
+ Qed.
+
+ Lemma arr_assocmap_lookup_get_mem:
+ forall asa r i v,
+ arr_assocmap_lookup asa r i = Some v ->
+ exists ar, asa ! r = Some ar /\ get_mem i ar = v.
+ Proof.
+ unfold arr_assocmap_lookup in *; intros.
+ repeat (destruct_match; try discriminate). inv H.
+ eexists; eauto.
+ Qed.
+
+ Lemma transl_predicate_correct_arr2 :
+ forall asr asa a b p r e max_pred max_reg rs ps e1 v1 ar,
+ Ple (max_predicate p) max_pred ->
+ match_assocmaps max_reg max_pred rs ps asr ->
+ eval_predf ps p = false ->
+ expr_runp tt (assoc_blocking (e_assoc asr)) (assoc_blocking (e_assoc_arr a b asa)) e1 v1 ->
+ arr_assocmap_lookup (assoc_blocking (e_assoc_arr a b asa)) r (valueToNat v1) = Some ar ->
+ exists asa', stmnt_runp tt (e_assoc asr) (e_assoc_arr a b asa) (translate_predicate Vblock (Some p) (Vvari r e1) e) (e_assoc asr) (e_assoc_arr a b asa')
+ /\ (forall x a, asa ! x = Some a ->
+ exists a', asa' ! x = Some a'
+ /\ (forall y, (y < arr_length a)%nat -> get_mem y a = get_mem y a')
+ /\ (arr_length a = arr_length a')).
+ Proof.
+ intros * HPLE HMATCH HEVAL HEXPRRUN HLOOKUP. pose proof HEVAL as HEVAL_DEEP.
+ unfold translate_predicate. erewrite <- eval_predf_deep_simplify in HEVAL_DEEP.
+ destruct_match.
+ - econstructor; split.
+ + econstructor; [econstructor|]; eauto. eapply erun_Vternary_false.
+ * eapply pred_expr_correct. intros. eapply max_predicate_deep_simplify in H.
+ inv HMATCH. eapply H1; unfold Ple in *. lia.
+ * econstructor; eauto.
+ * rewrite HEVAL_DEEP. auto.
+ + intros. destruct (peq x r); subst.
+ * erewrite arr_assocmap_set_gss by eauto.
+ eexists; repeat split; eauto; intros.
+ destruct (Nat.eq_dec y (valueToNat v1)); subst.
+ -- rewrite get_mem_set_array_gss by auto.
+ exploit arr_assocmap_lookup_get_mem; eauto. intros (ar' & HASSOC & HGET).
+ unfold e_assoc_arr in HASSOC. cbn in *. rewrite HASSOC in H. inv H. auto.
+ -- now rewrite get_mem_set_array_gso by auto.
+ * erewrite arr_assocmap_set_gso by eauto. unfold e_assoc_arr; cbn. eexists; split; eauto.
+ - unfold sat_pred_simple in Heqo. repeat (destruct_match; try discriminate).
+ apply negb_inj' in HEVAL_DEEP. unfold eval_predf in *. rewrite <- negate_correct in HEVAL_DEEP.
+ now rewrite e0 in HEVAL_DEEP.
+ Qed.
+
+ Definition unchanged (asr : assocmap) asa asr' asa' :=
+ (forall x, asr ! x = asr' ! x)
+ /\ (forall x a, asa ! x = Some a ->
+ exists a', asa' ! x = Some a'
+ /\ (forall y, (y < arr_length a)%nat -> get_mem y a = get_mem y a')
+ /\ arr_length a = arr_length a').
+
+ Lemma unchanged_refl :
+ forall a b, unchanged a b a b.
+ Proof.
+ unfold unchanged; split; intros. eauto.
+ eexists; eauto.
+ Qed.
+
+ Lemma unchanged_trans :
+ forall a b a' b' a'' b'', unchanged a b a' b' -> unchanged a' b' a'' b'' -> unchanged a b a'' b''.
+ Proof.
+ unfold unchanged; simplify; intros.
+ congruence.
+ pose proof H as H'. apply H3 in H'. simplify. pose proof H5 as H5'.
+ apply H2 in H5'. simplify. eexists; eauto; simplify; eauto; try congruence.
+ intros. rewrite H4 by auto. now rewrite <- H6 by lia.
+ Qed.
+
+ Lemma transl_step_state_correct_single_instr :
+ forall s f sp pc curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa n i,
+ (* (fn_code f) ! pc = Some bb -> *)
+ transf_instr n (mk_ctrl f) (curr_p, stmnt) i = OK (next_p, stmnt') ->
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
+ eval_predf pr curr_p = true ->
+ step_instr ge sp (Iexec {| is_rs := rs; is_ps := pr; is_mem := m |}) i
+ (Iexec {| is_rs := rs'; is_ps := pr'; is_mem := m' |}) ->
+ match_states (GibleSubPar.State s f sp pc rs pr m) (DHTL.State s' m_ pc asr asa) ->
+ exists asr' asa',
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt' (e_assoc asr') (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa')
+ /\ match_states (GibleSubPar.State s f sp pc rs' pr' m') (DHTL.State s' m_ pc asr' asa')
+ /\ eval_predf pr' next_p = true.
+ Proof. Admitted.
+
+ Lemma transl_step_state_correct_single_instr_term :
+ forall s f sp pc curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa n i cf pc',
+ (* (fn_code f) ! pc = Some bb -> *)
+ transf_instr n (mk_ctrl f) (curr_p, stmnt) i = OK (next_p, stmnt') ->
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
+ eval_predf pr curr_p = true ->
+ step_instr ge sp (Iexec {| is_rs := rs; is_ps := pr; is_mem := m |}) i
+ (Iterm {| is_rs := rs'; is_ps := pr'; is_mem := m' |} cf) ->
+ step_cf_instr ge (GibleSubPar.State s f sp pc rs' pr' m') cf Events.E0 (GibleSubPar.State s f sp pc' rs' pr' m') ->
+ match_states (GibleSubPar.State s f sp pc rs pr m) (DHTL.State s' m_ pc asr asa) ->
+ exists asr' asa',
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt' (e_assoc asr') (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa')
+ /\ match_states (GibleSubPar.State s f sp pc' rs' pr' m') (DHTL.State s' m_ pc' asr' asa')
+ /\ eval_predf pr' next_p = false.
+ Proof. Admitted.
+
+ Lemma transl_step_state_correct_single_instr_term_return :
+ forall s f sp pc curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa n i cf v m'',
+ (* (fn_code f) ! pc = Some bb -> *)
+ transf_instr n (mk_ctrl f) (curr_p, stmnt) i = OK (next_p, stmnt') ->
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
+ eval_predf pr curr_p = true ->
+ step_instr ge sp (Iexec {| is_rs := rs; is_ps := pr; is_mem := m |}) i
+ (Iterm {| is_rs := rs'; is_ps := pr'; is_mem := m' |} cf) ->
+ step_cf_instr ge (GibleSubPar.State s f sp pc rs' pr' m') cf Events.E0 (GibleSubPar.Returnstate s v m'') ->
+ match_states (GibleSubPar.State s f sp pc rs pr m) (DHTL.State s' m_ pc asr asa) ->
+ exists retval,
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt' (e_assoc (AssocMap.set m_.(DHTL.mod_st) (posToValue n) (AssocMap.set (m_.(DHTL.mod_return)) retval (AssocMap.set (m_.(DHTL.mod_finish)) (ZToValue 1) asr)))) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa)
+ /\ val_value_lessdef v retval
+ /\ eval_predf pr' next_p = false.
+ Proof. Admitted.
+
+ #[local] Ltac destr := destruct_match; try discriminate; [].
+
+ Lemma pred_in_pred_uses:
+ forall A (p: A) pop,
+ PredIn p pop ->
+ In p (predicate_use pop).
+ Proof.
+ induction pop; crush.
+ - destr. inv Heqp1. inv H. now constructor.
+ - inv H.
+ - inv H.
+ - apply in_or_app. inv H. inv H1; intuition.
+ - apply in_or_app. inv H. inv H1; intuition.
+ Qed.
+
+ Lemma le_max_pred :
+ forall p max_pred,
+ Forall (fun x : positive => Ple x max_pred) (predicate_use p) ->
+ Ple (max_predicate p) max_pred.
+ Proof.
+ induction p; intros.
+ - intros; cbn. destruct_match. inv Heqp0. cbn in *. now inv H.
+ - cbn. unfold Ple. lia.
+ - cbn. unfold Ple. lia.
+ - cbn in *. eapply Forall_app in H. inv H. unfold Ple in *. eapply IHp1 in H0.
+ eapply IHp2 in H1. lia.
+ - cbn in *. eapply Forall_app in H. inv H. unfold Ple in *. eapply IHp1 in H0.
+ eapply IHp2 in H1. lia.
+ Qed.
+
+ (* Lemma storev_stack_bounds : *)
+ (* forall m sp v dst m' hi, *)
+ (* Mem.storev Mint32 m (Values.Vptr sp (Ptrofs.repr v)) dst = Some m' -> *)
+ (* stack_bounds (Values.Vptr sp (Ptrofs.repr 0)) hi m -> *)
+ (* v mod 4 = 0 -> *)
+ (* 0 <= v < hi. *)
+ (* Proof. *)
+ (* intros. unfold stack_bounds in *. *)
+ (* assert (0 <= v < hi \/ hi <= ) *)
+
+ Ltac tac :=
+ repeat match goal with
+ | [ _ : error _ _ = OK _ _ _ |- _ ] => discriminate
+ | [ _ : context[if (?x && ?y) then _ else _] |- _ ] =>
+ let EQ1 := fresh "EQ" in
+ let EQ2 := fresh "EQ" in
+ destruct x eqn:EQ1; destruct y eqn:EQ2; simpl in *
+ | [ _ : context[if ?x then _ else _] |- _ ] =>
+ let EQ := fresh "EQ" in
+ destruct x eqn:EQ; simpl in *
+ | [ H : ret _ _ = _ |- _ ] => inv H
+ | [ _ : context[match ?x with | _ => _ end] |- _ ] => destruct x
+ end.
+
+ Ltac inv_arr_access :=
+ match goal with
+ | [ _ : translate_arr_access ?chunk ?addr ?args _ _ = OK ?c _ _ |- _] =>
+ destruct c, chunk, addr, args; crush; tac; crush
+ end.
+
+ Lemma offset_expr_ok :
+ forall v z, (Z.to_nat
+ (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu
+ (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ v))
+ (Integers.Ptrofs.of_int (Integers.Int.repr z)))
+ (Integers.Ptrofs.repr 4)))
+ = valueToNat (Int.divu (Int.add v (ZToValue z)) (ZToValue 4))).
+ Proof.
+ simplify_val. unfold valueToNat. unfold Int.divu, Ptrofs.divu.
+ pose proof Integers.Ptrofs.agree32_add as AGR.
+ unfold Integers.Ptrofs.agree32 in AGR.
+ assert (Ptrofs.unsigned (Ptrofs.add (Ptrofs.repr (Int.unsigned v))
+ (Ptrofs.repr (Int.unsigned (Int.repr z)))) =
+ Int.unsigned (Int.add v (ZToValue z))).
+ apply AGR; auto.
+ apply Ptrofs.unsigned_repr. apply Int.unsigned_range_2.
+ apply Ptrofs.unsigned_repr. apply Int.unsigned_range_2.
+ rewrite H. replace (Ptrofs.unsigned (Ptrofs.repr 4)) with 4.
+ replace (Int.unsigned (ZToValue 4)) with 4.
+ pose proof Ptrofs.agree32_repr. unfold Ptrofs.agree32 in *.
+ rewrite H0. trivial. auto.
+ unfold ZToValue. symmetry. apply Int.unsigned_repr.
+ unfold_constants. lia.
+ unfold ZToValue. symmetry. apply Int.unsigned_repr.
+ unfold_constants. lia.
+ Qed.
+
+ Lemma offset_expr_ok_2 :
+ forall v0 v1 z0 z1,
+ (Z.to_nat
+ (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu
+ (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ v0))
+ (Integers.Ptrofs.of_int
+ (Integers.Int.add
+ (Integers.Int.mul (valueToInt v1) (Integers.Int.repr z1))
+ (Integers.Int.repr z0)))) (Ptrofs.repr 4))))
+ = valueToNat (Int.divu (Int.add (Int.add v0 (ZToValue z0))
+ (Int.mul v1 (ZToValue z1))) (ZToValue 4)).
+ intros. unfold ZToValue, valueToNat, valueToInt, Ptrofs.divu, Int.divu, Ptrofs.of_int.
+
+ assert (H : (Ptrofs.unsigned
+ (Ptrofs.add (Ptrofs.repr (uvalueToZ v0))
+ (Ptrofs.of_int (Int.add (Int.mul (valueToInt v1) (Int.repr z1)) (Int.repr z0)))) /
+ Ptrofs.unsigned (Ptrofs.repr 4))
+ = (Int.unsigned (Int.add (Int.add v0 (Int.repr z0)) (Int.mul v1 (Int.repr z1))) /
+ Int.unsigned (Int.repr 4))).
+ { unfold ZToValue, valueToNat, valueToInt, Ptrofs.divu, Int.divu, Ptrofs.of_int.
+ rewrite Ptrofs.unsigned_repr by (unfold_constants; lia).
+ rewrite Int.unsigned_repr by (unfold_constants; lia).
+
+ unfold Ptrofs.of_int. rewrite Int.add_commut.
+ pose proof Integers.Ptrofs.agree32_add as AGR. unfold Ptrofs.agree32 in *.
+ erewrite AGR.
+ 3: { unfold uvalueToZ. rewrite Ptrofs.unsigned_repr. trivial. apply Int.unsigned_range_2. }
+ 3: { rewrite Ptrofs.unsigned_repr. trivial. apply Int.unsigned_range_2. }
+ rewrite Int.add_assoc. trivial. auto.
+ }
+
+ rewrite <- H. auto.
+
+ Qed.
+
+ Lemma offset_expr_ok_3 :
+ forall OFFSET,
+ Z.to_nat (Ptrofs.unsigned (Ptrofs.divu OFFSET (Ptrofs.repr 4)))
+ = valueToNat (ZToValue (Ptrofs.unsigned OFFSET / 4)).
+ Proof. auto. Qed.
+
+ Lemma storev_mod_ok' :
+ forall m sp' ptr src m',
+ 0 <= ptr <= Ptrofs.max_unsigned ->
+ Mem.storev Mint32 m (Values.Val.offset_ptr (Values.Vptr sp' (Ptrofs.repr 0)) (Ptrofs.repr ptr)) src = Some m' ->
+ ptr mod 4 = 0.
+ Proof.
+ unfold Mem.storev; intros * BOUND **. repeat destruct_match; try discriminate.
+ eapply Mem.store_valid_access_3 in H.
+ unfold Mem.valid_access in H. inv H. apply Zdivide_mod. cbn -[Ptrofs.max_unsigned]in *.
+ inv Heqv. rewrite Ptrofs.add_unsigned in H1.
+ rewrite ! Ptrofs.unsigned_repr in H1; try lia. auto.
+ rewrite ! Ptrofs.unsigned_repr; lia.
+ Qed.
+
+ Lemma loadv_mod_ok' :
+ forall m sp' ptr v,
+ 0 <= ptr <= Ptrofs.max_unsigned ->
+ Mem.loadv Mint32 m (Values.Val.offset_ptr (Values.Vptr sp' (Ptrofs.repr 0)) (Ptrofs.repr ptr)) = Some v ->
+ ptr mod 4 = 0.
+ Proof.
+ unfold Mem.loadv; intros * BOUND **. repeat destruct_match; try discriminate.
+ eapply Mem.load_valid_access in H.
+ unfold Mem.valid_access in H. inv H. apply Zdivide_mod. cbn -[Ptrofs.max_unsigned]in *.
+ inv Heqv0. rewrite Ptrofs.add_unsigned in H1.
+ rewrite ! Ptrofs.unsigned_repr in H1; try lia. auto.
+ rewrite ! Ptrofs.unsigned_repr; lia.
+ Qed.
+
+ Lemma offset_ptr_equiv :
+ forall sp' v,
+ Values.Val.offset_ptr (Values.Vptr sp' (Ptrofs.repr 0)) v = Values.Vptr sp' v.
+ Proof.
+ unfold Values.Val.offset_ptr; intros.
+ replace (Ptrofs.repr 0) with Ptrofs.zero by auto.
+ now rewrite Ptrofs.add_zero_l.
+ Qed.
+
+ Lemma loadv_mod_ok :
+ forall m sp' ptr v,
+ 0 <= ptr <= Ptrofs.max_unsigned ->
+ Mem.loadv Mint32 m (Values.Vptr sp' (Ptrofs.repr ptr)) = Some v ->
+ ptr mod 4 = 0.
+ Proof.
+ intros. eapply loadv_mod_ok'; eauto.
+ rewrite offset_ptr_equiv; eauto.
+ Qed.
+
+ Lemma storev_mod_ok :
+ forall m sp' ptr src m',
+ 0 <= ptr <= Ptrofs.max_unsigned ->
+ Mem.storev Mint32 m (Values.Vptr sp' (Ptrofs.repr ptr)) src = Some m' ->
+ ptr mod 4 = 0.
+ Proof.
+ intros. eapply storev_mod_ok'; eauto.
+ rewrite offset_ptr_equiv; eauto.
+ Qed.
+
+ Lemma loadv_mod_ok2 :
+ forall m sp' v v',
+ Mem.loadv Mint32 m (Values.Vptr sp' v) = Some v' ->
+ (Ptrofs.unsigned v) mod 4 = 0.
+ Proof.
+ unfold Mem.loadv; intros. repeat destruct_match; try discriminate.
+ eapply Mem.load_valid_access in H.
+ unfold Mem.valid_access in H. inv H. apply Zdivide_mod. cbn -[Ptrofs.max_unsigned]in *.
+ auto.
+ Qed.
+
+ Lemma storev_mod_ok2 :
+ forall m sp' src m' v,
+ Mem.storev Mint32 m (Values.Vptr sp' v) src = Some m' ->
+ (Ptrofs.unsigned v) mod 4 = 0.
+ Proof.
+ unfold Mem.storev; intros. repeat destruct_match; try discriminate.
+ eapply Mem.store_valid_access_3 in H.
+ unfold Mem.valid_access in H. inv H. apply Zdivide_mod. cbn -[Ptrofs.max_unsigned]in *.
+ auto.
+ Qed.
+
+ Lemma storev_exists_ptr:
+ forall m v src m',
+ Mem.storev Mint32 m v src = Some m' ->
+ exists sp v', v = Values.Vptr sp v'.
+ Proof.
+ intros.
+ unfold Mem.storev in *. destruct_match; try discriminate.
+ subst. eauto.
+ Qed.
+
+ Lemma val_add_stack_based :
+ forall v1 v2 sp,
+ stack_based v1 sp ->
+ stack_based v2 sp ->
+ stack_based (Values.Val.add v1 v2) sp.
+ Proof.
+ intros. destruct v1, v2; auto.
+ inv H. inv H0. cbn; auto.
+ Qed.
+
+ Lemma ptrofs_unsigned_add_0:
+ forall x0,
+ Ptrofs.unsigned (Ptrofs.add (Ptrofs.repr 0) (Ptrofs.repr (Ptrofs.unsigned x0))) = Ptrofs.unsigned x0.
+ Proof.
+ intros. replace (Ptrofs.repr 0) with (Ptrofs.zero) by auto.
+ rewrite Ptrofs.add_zero_l. rewrite Ptrofs.unsigned_repr; auto.
+ apply Ptrofs.unsigned_range_2.
+ Qed.
+
+ Lemma exists_ptr_add_int :
+ forall a b sp' x0,
+ Values.Val.add a (Values.Vint b) = Values.Vptr sp' x0 ->
+ exists a', a = Values.Vptr sp' a'.
+ Proof.
+ intros. destruct a; eauto; cbn in *; try discriminate.
+ assert (Xx: Archi.ptr64 = false) by auto. rewrite Xx in H. inv H. eauto.
+ Qed.
+
+ Lemma transl_arr_access_correct :
+ forall addr args e rs ps m sp a chnk src m' s f pc s' m_ asr arr,
+ translate_arr_access chnk addr args m_.(DHTL.mod_stk) = OK e ->
+ Op.eval_addressing ge sp addr (List.map (fun r => Registers.Regmap.get r rs) args) = Some a ->
+ Mem.storev chnk m a (Registers.Regmap.get src rs) = Some m' ->
+ match_states (GibleSubPar.State s f sp pc rs ps m) (DHTL.State s' m_ pc asr arr) ->
+ exists x, expr_runp tt asr arr e x.
+ Proof.
+ assert (HARCH: Archi.ptr64 = false) by auto.
+ intros. unfold translate_arr_access in *. repeat destr.
+ destruct_match; try discriminate; repeat destr.
+ - inv H. cbn in *. unfold Op.eval_addressing in *. rewrite HARCH in H0.
+ cbn in *. inv H0. inv H2. unfold stack_bounds in *.
+ exploit storev_exists_ptr; eauto. simplify.
+ assert (stack_based (Values.Vint (Int.repr z)) sp') by (cbn; auto).
+ assert (stack_based (rs !! r) sp') by (cbn; auto).
+ eapply val_add_stack_based in H0; eauto. rewrite H in H0. cbn in *. inv H0.
+ rewrite H in H1. exploit storev_mod_ok2; eauto; intros.
+ specialize (BOUNDS (Ptrofs.unsigned x0) rs !! src).
+ pose proof (ptrofs_unsigned_lt_int_max x0).
+ assert (0 <= Ptrofs.unsigned x0 < fn_stacksize f \/ fn_stacksize f <= Ptrofs.unsigned x0 <= Int.max_unsigned) by lia.
+ inv H4.
+ + inv MARR. inv H4. eexists. econstructor. econstructor. econstructor. econstructor.
+ eauto. econstructor. cbn. eauto. econstructor. cbn. unfold ZToValue.
+ unfold Int.zero. unfold Int.eq. rewrite ! Int.unsigned_repr by crush.
+ cbn. eauto. (* exploit exists_ptr_add_int; eauto. intros (a & HPTR). *)
+ (* rewrite HPTR in H. cbn in H. *)
+ assert (HARCHI: Archi.ptr64 = false) by auto.
+ unfold arr_assocmap_lookup. setoid_rewrite H6. eauto.
+ + apply BOUNDS in H5; auto. inv H5. rewrite ptrofs_unsigned_add_0 in H6.
+ unfold Mem.storev in H1. rewrite H6 in H1. discriminate.
+ - inv H. inv H2. inv MARR. inv H. repeat econstructor. unfold arr_assocmap_lookup.
+ setoid_rewrite H2. auto.
+ - inv H. inv H2. inv MARR. inv H. repeat econstructor. unfold arr_assocmap_lookup.
+ setoid_rewrite H2. auto.
+ Qed.
+
+ Lemma transl_step_state_correct_single_false_standard :
+ forall f bb curr_p next_p m_ stmnt stmnt' asr0 asa0 asr asa n max_reg max_pred rs ps sp m o,
+ (* (fn_code f) ! pc = Some bb -> *)
+ transf_instr n (mk_ctrl f) (curr_p, stmnt) bb = OK (next_p, stmnt') ->
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
+ Forall (fun x => Ple x max_pred) (pred_uses bb) ->
+ Ple (max_predicate curr_p) max_pred ->
+ eval_predf ps curr_p = false ->
+ match_assocmaps max_reg max_pred rs ps asr ->
+ step_instr ge sp (Iexec (mk_instr_state rs ps m)) bb o ->
+ (forall a b c d e, bb <> RBstore a b c d e) ->
+ (forall a b, bb <> RBexit a b) ->
+ exists asr' asa', stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt'
+ (e_assoc asr') (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa')
+ /\ unchanged asr asa asr' asa'
+ /\ Ple (max_predicate next_p) max_pred
+ /\ eval_predf ps next_p = false.
+ Proof.
+ destruct bb; intros * HTRANSF HSTMNT HFRL HPLE HEVAL HMATCH HSTEP_INSTR HNO_RBSTORE HNO_EXIT.
+ - cbn in HTRANSF. inv HTRANSF. exists asr, asa; repeat split; eauto.
+ - cbn -[translate_predicate deep_simplify] in HTRANSF; unfold Errors.bind in HTRANSF.
+ destruct_match; try discriminate.
+ assert (forall A a b, @OK A a = OK b -> a = b) by now inversion 1. apply H in HTRANSF.
+ assert (forall A B (a b: A) (c d: B), (a, c) = (b, d) -> a = b /\ c = d) by now inversion 1.
+ apply H0 in HTRANSF. destruct HTRANSF. rewrite H1 in *. rewrite <- H2 in *.
+ assert (eval_predf ps (Pand next_p (dfltp o)) = false).
+ { rewrite eval_predf_Pand. subst. rewrite HEVAL. auto. }
+ assert (Ple (max_predicate (Pand next_p (dfltp o))) max_pred).
+ { cbn. cbn in HFRL. destruct o; cbn; [|unfold Ple in *; lia].
+ eapply le_max_pred in HFRL. unfold Ple in *; lia. }
+ exploit transl_predicate_correct2; eauto. intros (asr' & HSTMNT' & FRL).
+ exists asr', asa. repeat split; eauto.
+ econstructor; eauto.
+ - cbn -[translate_predicate deep_simplify] in HTRANSF; unfold Errors.bind in HTRANSF.
+ destruct_match; try discriminate.
+ assert (forall A a b, @OK A a = OK b -> a = b) by now inversion 1. apply H in HTRANSF.
+ assert (forall A B (a b: A) (c d: B), (a, c) = (b, d) -> a = b /\ c = d) by now inversion 1.
+ apply H0 in HTRANSF. destruct HTRANSF. rewrite H1 in *. rewrite <- H2 in *.
+ assert (eval_predf ps (Pand next_p (dfltp o)) = false).
+ { rewrite eval_predf_Pand. subst. rewrite HEVAL. auto. }
+ assert (Ple (max_predicate (Pand next_p (dfltp o))) max_pred).
+ { cbn. cbn in HFRL. destruct o; cbn; [|unfold Ple in *; lia].
+ eapply le_max_pred in HFRL. unfold Ple in *; lia. }
+ exploit transl_predicate_correct2; eauto. intros (asr' & HSTMNT' & FRL).
+ exists asr', asa. repeat split; eauto.
+ econstructor; eauto.
+ - exfalso; eapply HNO_RBSTORE; auto.
+ - cbn -[translate_predicate deep_simplify] in HTRANSF; unfold Errors.bind in HTRANSF.
+ destruct_match; try discriminate.
+ assert (forall A a b, @OK A a = OK b -> a = b) by now inversion 1. apply H in HTRANSF.
+ assert (forall A B (a b: A) (c d: B), (a, c) = (b, d) -> a = b /\ c = d) by now inversion 1.
+ apply H0 in HTRANSF. destruct HTRANSF. rewrite H1 in *. rewrite <- H2 in *.
+ assert (eval_predf ps (Pand next_p (dfltp o)) = false).
+ { rewrite eval_predf_Pand. subst. rewrite HEVAL. auto. }
+ assert (Ple (max_predicate (Pand next_p (dfltp o))) max_pred).
+ { cbn. cbn in HFRL. destruct o; cbn; [|unfold Ple in *; lia]. inv HFRL.
+ eapply le_max_pred in H7. unfold Ple in *; lia. }
+ exploit transl_predicate_correct2; eauto. intros (asr' & HSTMNT' & FRL).
+ exists asr', asa. repeat split; eauto.
+ econstructor; eauto.
+ - exfalso; eapply HNO_EXIT; auto.
+ Qed.
+
+ Lemma unchanged_implies_match :
+ forall s f sp rs ps m s' m_ pc asr' asa' asa asr,
+ unchanged asr' asa' asr asa ->
+ match_states (GibleSubPar.State s f sp pc rs ps m) (DHTL.State s' m_ pc asr' asa') ->
+ match_states (GibleSubPar.State s f sp pc rs ps m) (DHTL.State s' m_ pc asr asa).
+ Proof.
+ intros. inv H. inv H0.
+ econstructor; auto.
+ - econstructor; intros; inv MASSOC; rewrite <- H1; eauto.
+ - unfold state_st_wf in *. destruct
+
+ Lemma transl_step_state_correct_single_false_standard_top :
+ forall f s s' pc bb curr_p next_p m_ stmnt stmnt' asr0 asa0 asr asa n rs ps sp m o,
+ (* (fn_code f) ! pc = Some bb -> *)
+ transf_instr n (mk_ctrl f) (curr_p, stmnt) bb = OK (next_p, stmnt') ->
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0)
+ stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
+ Forall (fun x => Ple x (max_pred_function f)) (pred_uses bb) ->
+ Ple (max_predicate curr_p) (max_pred_function f) ->
+ eval_predf ps curr_p = false ->
+ match_states (GibleSubPar.State s f sp pc rs ps m) (DHTL.State s' m_ pc asr asa) ->
+ step_instr ge sp (Iexec (mk_instr_state rs ps m)) bb o ->
+ exists asr' asa',
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt'
+ (e_assoc asr') (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa')
+ /\ match_states (GibleSubPar.State s f sp pc rs ps m) (DHTL.State s' m_ pc asr' asa')
+ /\ Ple (max_predicate next_p) (max_pred_function f)
+ /\ eval_predf ps next_p = false.
+ Proof.
+ intros * HTRANSF HSTMNT HFRL HPLE HEVAL HMATCH HSTEP. destruct bb.
+ - inv HMATCH.
+ exploit transl_step_state_correct_single_false_standard; eauto; try discriminate.
+ intros (asr' & asa' & HSTMNT' & HUNCHG & HPLE' & HEVAL').
+ exists asr', asa'. repeat split; auto.
+
+ Lemma iterm_intermediate_state :
+ forall sp rs pr m bb rs' pr' m' cf,
+ SubParBB.step_instr_list ge sp (Iexec {| is_rs := rs; is_ps := pr; is_mem := m |}) bb
+ (Iterm {| is_rs := rs'; is_ps := pr'; is_mem := m' |} cf) ->
+ exists bb' i bb'',
+ SubParBB.step_instr_list ge sp (Iexec {| is_rs := rs; is_ps := pr; is_mem := m |}) bb'
+ (Iexec {| is_rs := rs'; is_ps := pr'; is_mem := m' |})
+ /\ step_instr ge sp (Iexec {| is_rs := rs'; is_ps := pr'; is_mem := m' |}) i (Iterm {| is_rs := rs'; is_ps := pr'; is_mem := m' |} cf)
+ /\ bb = bb' ++ (i :: bb'').
+ Proof. Admitted.
+
+ Lemma transl_step_state_correct_instr :
+ forall s f sp bb pc curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa n,
+ (* (fn_code f) ! pc = Some bb -> *)
+ mfold_left (transf_instr n (mk_ctrl f)) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
+ eval_predf pr curr_p = true ->
+ SubParBB.step_instr_list ge sp (Iexec {| is_rs := rs; is_ps := pr; is_mem := m |}) bb
+ (Iexec {| is_rs := rs'; is_ps := pr'; is_mem := m' |}) ->
+ match_states (GibleSubPar.State s f sp pc rs pr m) (DHTL.State s' m_ pc asr asa) ->
+ exists asr' asa',
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt' (e_assoc asr') (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa')
+ /\ match_states (GibleSubPar.State s f sp pc rs' pr' m') (DHTL.State s' m_ pc asr' asa')
+ /\ eval_predf pr' next_p = true.
+ Proof. Admitted.
+
+ Lemma transl_step_state_correct_instr_false :
+ forall f bb curr_p next_p m_ stmnt stmnt' asr0 asa0 asr asa n max_reg max_pred rs ps,
+ (* (fn_code f) ! pc = Some bb -> *)
+ mfold_left (transf_instr n (mk_ctrl f)) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
+ Forall (fun i => Forall (fun x : positive => Ple x max_pred) (pred_uses i)) bb ->
+ Ple (max_predicate curr_p) max_pred ->
+ eval_predf ps curr_p = false ->
+ match_assocmaps max_reg max_pred rs ps asr ->
+ stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt' (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa).
+ Proof.
+ induction bb.
+ - cbn; inversion 2; auto.
+ - intros * HFOLD HSTMNT HFRL HPLE HEVAL HMATCH. exploit mfold_left_cons; eauto.
+ intros (x' & y' & HFOLD' & HTRANS & HINV). inv HINV. destruct y'.
+ (* exploit transl_step_state_correct_single_false; eauto; intros. inv HFRL; eauto. *)
+ (* inv H. inv H1. *)
+ (* exploit IHbb; eauto. inv HFRL; eauto. *)
+ (* Qed. *) Admitted.
+
Lemma transl_step_state_correct_instr_state :
- forall s f sp bb pc curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa cf pc',
+ forall s f sp bb pc curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa cf pc' n,
(* (fn_code f) ! pc = Some bb -> *)
- mfold_left (transf_instr (mk_ctrl f)) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
+ mfold_left (transf_instr n (mk_ctrl f)) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
eval_predf pr curr_p = true ->
SubParBB.step_instr_list ge sp (Iexec {| is_rs := rs; is_ps := pr; is_mem := m |}) bb
@@ -1457,30 +2275,60 @@ Opaque Mem.alloc.
exists asr' asa',
stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt' (e_assoc asr') (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa')
/\ match_states (GibleSubPar.State s f sp pc' rs' pr' m') (DHTL.State s' m_ pc' asr' asa').
- Proof. Admitted.
+ Proof.
+ intros * HFOLD HSTMNT HEVAL HSTEP HSTEPCF HMATCH.
+ exploit iterm_intermediate_state; eauto.
+ intros (bb' & i & bb'' & HSTEP' & HSTEPINSTR & HBB). subst.
+ exploit mfold_left_app; eauto. intros (y' & HFOLD1 & HFOLD2).
+ exploit mfold_left_cons; eauto. intros (x' & y_other & HFOLDFINAL & HINSTR & HSUBST).
+ inv HSUBST.
+ destruct x'. destruct y_other.
+ exploit transl_step_state_correct_instr; try eapply HFOLD1; eauto.
+ intros (asr' & asa' & HSTMNT' & HMATCH' & HNEXT).
+ exploit transl_step_state_correct_single_instr_term; eauto.
+ intros (asr'0 & asa'0 & HSTMNT'' & HMATCH'' & HNEXT'').
+ exploit transl_step_state_correct_instr_false; eauto.
+ Admitted.
Lemma transl_step_state_correct_instr_return :
- forall s f sp bb pc curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa cf v,
+ forall s f sp bb pc curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa cf v m'' n,
(* (fn_code f) ! pc = Some bb -> *)
- mfold_left (transf_instr (mk_ctrl f)) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
+ mfold_left (transf_instr n (mk_ctrl f)) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
eval_predf pr curr_p = true ->
SubParBB.step_instr_list ge sp (Iexec {| is_rs := rs; is_ps := pr; is_mem := m |}) bb
(Iterm {| is_rs := rs'; is_ps := pr'; is_mem := m' |} cf) ->
- step_cf_instr ge (GibleSubPar.State s f sp pc rs' pr' m') cf Events.E0 (GibleSubPar.Returnstate s v m') ->
+ step_cf_instr ge (GibleSubPar.State s f sp pc rs' pr' m') cf Events.E0 (GibleSubPar.Returnstate s v m'') ->
match_states (GibleSubPar.State s f sp pc rs pr m) (DHTL.State s' m_ pc asr asa) ->
exists asr' asa' retval,
stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt' (e_assoc asr') (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa')
/\ val_value_lessdef v retval
/\ asr'!(m_.(DHTL.mod_finish)) = Some (ZToValue 1)
/\ asr'!(m_.(DHTL.mod_return)) = Some retval
- /\ match_states (GibleSubPar.Returnstate s v m') (DHTL.Returnstate s' retval).
- Proof. Admitted.
+ /\ asr'!(m_.(DHTL.mod_st)) = Some (posToValue n).
+ Proof.
+ intros * HFOLD HSTMNT HEVAL HSTEP HSTEPCF HMATCH.
+ exploit iterm_intermediate_state; eauto.
+ intros (bb' & i & bb'' & HSTEP' & HSTEPINSTR & HBB). subst.
+ exploit mfold_left_app; eauto. intros (y' & HFOLD1 & HFOLD2).
+ exploit mfold_left_cons; eauto. intros (x' & y_other & HFOLDFINAL & HINSTR & HSUBST).
+ inv HSUBST.
+ destruct x'. destruct y_other.
+ exploit transl_step_state_correct_instr; try eapply HFOLD1; eauto.
+ intros (asr' & asa' & HSTMNT' & HMATCH' & HNEXT).
+ exploit transl_step_state_correct_single_instr_term_return; eauto.
+ intros (v' & HSTMNT'' & HEVAL2 & HEVAL3).
+ exploit transl_step_state_correct_instr_false; eauto.
+ intros.
+ pose proof (mod_ordering_wf m_). unfold module_ordering in H0. inv H0. inv H2.
+ eexists. exists asa'. exists v'.
+ repeat split; eauto; repeat rewrite PTree.gso by lia; apply PTree.gss.
+ Qed.
Lemma transl_step_state_correct_chained_state :
- forall s f sp bb pc pc' curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa cf,
+ forall s f sp bb pc pc' curr_p next_p rs rs' m m' pr pr' m_ s' stmnt stmnt' asr0 asa0 asr asa cf n,
(* (fn_code f) ! pc = Some bb -> *)
- mfold_left (transf_chained_block (mk_ctrl f)) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
+ mfold_left (transf_chained_block n (mk_ctrl f)) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
stmnt_runp tt (e_assoc asr0) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa0) stmnt (e_assoc asr) (e_assoc_arr (DHTL.mod_stk m_) (DHTL.mod_stk_len m_) asa) ->
eval_predf pr curr_p = true ->
SubParBB.step ge sp (Iexec {| is_rs := rs; is_ps := pr; is_mem := m |}) bb
@@ -1493,10 +2341,10 @@ Opaque Mem.alloc.
Proof. Abort.
Lemma transl_step_through_cfi' :
- forall bb ctrl curr_p stmnt next_p stmnt' p cf,
- mfold_left (transf_instr ctrl) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
+ forall bb ctrl curr_p stmnt next_p stmnt' p cf n,
+ mfold_left (transf_instr n ctrl) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
In (RBexit p cf) bb ->
- exists curr_p' stmnt'', translate_cfi ctrl (Some (Pand curr_p' (dfltp p))) cf = OK stmnt''.
+ exists curr_p' stmnt'', translate_cfi n ctrl (Some (Pand curr_p' (dfltp p))) cf = OK stmnt'' /\ check_cfi n cf = OK tt.
Proof.
induction bb.
- inversion 2.
@@ -1506,15 +2354,15 @@ Opaque Mem.alloc.
inversion HSUBST. inv H0. clear HSUBST.
inv HIN; destruct y'; eauto.
cbn in HTRANSF. unfold Errors.bind in HTRANSF. repeat (destruct_match; try discriminate; []).
- inv HTRANSF. eauto.
+ inv HTRANSF. destruct u. eauto.
Qed.
Lemma transl_step_through_cfi :
- forall bb ctrl curr_p stmnt next_p stmnt' l p cf,
- mfold_left (transf_chained_block ctrl) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
+ forall bb ctrl curr_p stmnt next_p stmnt' l p cf n,
+ mfold_left (transf_chained_block n ctrl) bb (OK (curr_p, stmnt)) = OK (next_p, stmnt') ->
In l bb ->
In (RBexit p cf) l ->
- exists curr_p' stmnt'', translate_cfi ctrl (Some (Pand curr_p' (dfltp p))) cf = OK stmnt''.
+ exists curr_p' stmnt'', translate_cfi n ctrl (Some (Pand curr_p' (dfltp p))) cf = OK stmnt''.
Proof.
induction bb.
- inversion 2.
@@ -1524,6 +2372,7 @@ Opaque Mem.alloc.
destruct y'. inv HSUBST.
inv HIN1; eauto.
exploit transl_step_through_cfi'; eauto.
+ simplify. eauto.
Qed.
Lemma cf_in_bb_subparbb' :
@@ -1556,8 +2405,8 @@ Opaque Mem.alloc.
Qed.
Lemma match_states_cf_events_translate_cfi:
- forall T1 cf T2 p t ctrl stmnt,
- translate_cfi ctrl p cf = OK stmnt ->
+ forall T1 cf T2 p t ctrl stmnt n,
+ translate_cfi n ctrl p cf = OK stmnt ->
step_cf_instr ge T1 cf t T2 ->
t = Events.E0.
Proof.
@@ -1566,8 +2415,8 @@ Opaque Mem.alloc.
Qed.
Lemma match_states_cf_states_translate_cfi:
- forall T1 cf T2 p t ctrl stmnt,
- translate_cfi ctrl p cf = OK stmnt ->
+ forall T1 cf T2 p t ctrl stmnt n,
+ translate_cfi n ctrl p cf = OK stmnt ->
step_cf_instr ge T1 cf t T2 ->
exists s f sp pc rs pr m,
T1 = GibleSubPar.State s f sp pc rs pr m
@@ -1578,106 +2427,18 @@ Opaque Mem.alloc.
destruct cf; try discriminate; inv HSTEP; try (now repeat econstructor).
Qed.
- Lemma one_ne_zero:
- Int.repr 1 <> Int.repr 0.
- Proof.
- unfold not; intros.
- assert (Int.unsigned (Int.repr 1) = Int.unsigned (Int.repr 0)) by (now rewrite H).
- rewrite ! Int.unsigned_repr in H0 by crush. lia.
- Qed.
-
- Lemma int_and_boolToValue :
- forall b1 b2,
- Int.and (boolToValue b1) (boolToValue b2) = boolToValue (b1 && b2).
- Proof.
- destruct b1; destruct b2; cbn; unfold boolToValue; unfold natToValue;
- replace (Z.of_nat 1) with 1 by auto;
- replace (Z.of_nat 0) with 0 by auto.
- - apply Int.and_idem.
- - apply Int.and_zero.
- - apply Int.and_zero_l.
- - apply Int.and_zero.
- Qed.
-
- Lemma int_or_boolToValue :
- forall b1 b2,
- Int.or (boolToValue b1) (boolToValue b2) = boolToValue (b1 || b2).
- Proof.
- destruct b1; destruct b2; cbn; unfold boolToValue; unfold natToValue;
- replace (Z.of_nat 1) with 1 by auto;
- replace (Z.of_nat 0) with 0 by auto.
- - apply Int.or_idem.
- - apply Int.or_zero.
- - apply Int.or_zero_l.
- - apply Int.or_zero_l.
- Qed.
-
- Lemma translate_pred_correct :
- forall curr_p pr asr asa,
- (forall r, Ple r (max_predicate curr_p) ->
- find_assocmap 1 (pred_enc r) asr = boolToValue (PMap.get r pr)) ->
- expr_runp tt asr asa (pred_expr curr_p) (boolToValue (eval_predf pr curr_p)).
- Proof.
- induction curr_p.
- - intros * HFRL. cbn. destruct p as [b p']. destruct b.
- + constructor. eapply HFRL. cbn. unfold Ple. lia.
- + econstructor. constructor. eapply HFRL. cbn. unfold Ple; lia.
- econstructor. cbn. f_equal. unfold boolToValue.
- f_equal. destruct pr !! p' eqn:?. cbn.
- rewrite Int.eq_false; auto. unfold natToValue.
- replace (Z.of_nat 1) with 1 by auto. unfold Int.zero.
- apply one_ne_zero.
- cbn. rewrite Int.eq_true; auto.
- - intros. cbn. constructor.
- - intros. cbn. constructor.
- - cbn -[eval_predf]; intros. econstructor. eapply IHcurr_p1. intros. eapply H.
- unfold Ple in *. lia.
- eapply IHcurr_p2; intros. eapply H. unfold Ple in *; lia.
- cbn -[eval_predf]. f_equal. symmetry. apply int_and_boolToValue.
- - cbn -[eval_predf]; intros. econstructor. eapply IHcurr_p1. intros. eapply H.
- unfold Ple in *. lia.
- eapply IHcurr_p2; intros. eapply H. unfold Ple in *; lia.
- cbn -[eval_predf]. f_equal. symmetry. apply int_or_boolToValue.
- Qed.
-
- Lemma max_predicate_deep_simplify' :
- forall peq curr r,
- (r <= max_predicate (deep_simplify' peq curr))%positive ->
- (r <= max_predicate curr)%positive.
- Proof.
- destruct curr; cbn -[deep_simplify']; auto.
- - intros. unfold deep_simplify' in H.
- destruct curr1; destruct curr2; try (destruct_match; cbn in *); lia.
- - intros. unfold deep_simplify' in H.
- destruct curr1; destruct curr2; try (destruct_match; cbn in *); lia.
- Qed.
-
- Lemma max_predicate_deep_simplify :
- forall peq curr r,
- (r <= max_predicate (deep_simplify peq curr))%positive ->
- (r <= max_predicate curr)%positive.
- Proof.
- induction curr; try solve [cbn; auto]; cbn -[deep_simplify'] in *.
- - intros. apply max_predicate_deep_simplify' in H. cbn -[deep_simplify'] in *.
- assert (HX: (r <= max_predicate (deep_simplify peq curr1))%positive \/ (r <= max_predicate (deep_simplify peq curr2))%positive) by lia.
- inv HX; [eapply IHcurr1 in H0 | eapply IHcurr2 in H0]; lia.
- - intros. apply max_predicate_deep_simplify' in H. cbn -[deep_simplify'] in *.
- assert (HX: (r <= max_predicate (deep_simplify peq curr1))%positive \/ (r <= max_predicate (deep_simplify peq curr2))%positive) by lia.
- inv HX; [eapply IHcurr1 in H0 | eapply IHcurr2 in H0]; lia.
- Qed.
-
Lemma translate_cfi_goto:
- forall pr curr_p pc s ctrl asr asa,
+ forall pr curr_p pc s ctrl asr asa n,
(forall r, Ple r (max_predicate curr_p) ->
find_assocmap 1 (pred_enc r) asr = boolToValue (PMap.get r pr)) ->
eval_predf pr curr_p = true ->
- translate_cfi ctrl (Some curr_p) (RBgoto pc) = OK s ->
+ translate_cfi n ctrl (Some curr_p) (RBgoto pc) = OK s ->
stmnt_runp tt (e_assoc asr) asa s
(e_assoc (AssocMap.set ctrl.(ctrl_st) (posToValue pc) asr)) asa.
Proof.
intros * HPLE HEVAL HTRANSL. unfold translate_cfi in *.
inversion_clear HTRANSL as []. destruct_match.
- - constructor. constructor. econstructor. eapply translate_pred_correct.
+ - constructor. constructor. econstructor. eapply pred_expr_correct.
intros. unfold Ple in *. eapply HPLE.
now apply max_predicate_deep_simplify in H.
eauto. constructor. rewrite eval_predf_deep_simplify. rewrite HEVAL. auto.
@@ -1685,8 +2446,8 @@ Opaque Mem.alloc.
Qed.
Lemma translate_cfi_goto_none:
- forall pc s ctrl asr asa,
- translate_cfi ctrl None (RBgoto pc) = OK s ->
+ forall pc s ctrl asr asa n,
+ translate_cfi n ctrl None (RBgoto pc) = OK s ->
stmnt_runp tt (e_assoc asr) asa s
(e_assoc (AssocMap.set ctrl.(ctrl_st) (posToValue pc) asr)) asa.
Proof. intros; inversion_clear H as []; repeat constructor. Qed.
@@ -1727,7 +2488,7 @@ Opaque Mem.alloc.
forall l ctrl d_in d_out pc bb,
mfold_left (transf_seq_block ctrl) l (OK d_in) = OK d_out ->
In (pc, bb) l ->
- exists pred' stmnt, transf_chained_block ctrl (Ptrue, Vskip) (concat bb) = OK (pred', stmnt)
+ exists n pred' stmnt, transf_chained_block n ctrl (Ptrue, Vskip) (concat bb) = OK (pred', stmnt)
/\ d_out ! pc = Some stmnt.
Proof.
induction l; [now inversion 2|].
@@ -1746,10 +2507,33 @@ Opaque Mem.alloc.
forall ctrl d_in d_out pc bb c,
mfold_left (transf_seq_block ctrl) (PTree.elements c) (OK d_in) = OK d_out ->
c ! pc = Some bb ->
- exists pred' stmnt, transf_chained_block ctrl (Ptrue, Vskip) (concat bb) = OK (pred', stmnt)
+ exists n pred' stmnt, transf_chained_block n ctrl (Ptrue, Vskip) (concat bb) = OK (pred', stmnt)
/\ d_out ! pc = Some stmnt.
Proof. intros. eapply transl_spec_correct'; eauto using PTree.elements_correct. Qed.
+ Lemma lt_check_step_cf_instr :
+ forall s f sp pc rs pr m cf t s' f' sp' x rs' pr' m' ctrl p st n,
+ translate_cfi n ctrl p cf = OK st ->
+ check_cfi n cf = OK tt ->
+ step_cf_instr ge (GibleSubPar.State s f sp pc rs pr m) cf t
+ (GibleSubPar.State s' f' sp' x rs' pr' m') ->
+ Z.pos x <= Int.max_unsigned.
+ Proof.
+ intros.
+ destruct cf; cbn in *; try discriminate; unfold check_cfi, assert_, Errors.bind in *; repeat (destruct_match; try discriminate); simplify; inv H1; try destruct_match; try lia.
+ apply list_nth_z_in in H19.
+ eapply forallb_forall in Heqb; eauto. lia.
+ Qed.
+
+ Lemma lt_check_step_cf_instr2 :
+ forall cf n,
+ check_cfi n cf = OK tt ->
+ Z.pos n <= Int.max_unsigned.
+ Proof.
+ intros.
+ destruct cf; cbn in *; try discriminate; unfold check_cfi, assert_, Errors.bind in *; repeat (destruct_match; try discriminate); simplify; try destruct_match; try lia.
+ Qed.
+
Lemma transl_step_state_correct :
forall s f sp pc rs rs' m m' bb pr pr' state cf t,
(fn_code f) ! pc = Some bb ->
@@ -1766,10 +2550,10 @@ Opaque Mem.alloc.
unfold transl_module, Errors.bind, bind, ret in HTRANSL.
repeat (destruct_match; try discriminate; []).
exploit transl_spec_correct; eauto.
- intros (pred' & stmnt0 & HTRANSF & HGET).
+ intros (n & pred' & stmnt0 & HTRANSF & HGET).
exploit step_exec_concat; eauto; intros HCONCAT.
exploit cf_in_bb_subparbb'; eauto. intros (exit_p & HINEXIT & HTRUTHY).
- exploit transl_step_through_cfi'; eauto. intros (curr_p & _stmnt & HCFI).
+ exploit transl_step_through_cfi'; eauto. intros (curr_p & _stmnt & HCFI & HCHECK).
exploit match_states_cf_states_translate_cfi; eauto. intros (s0 & f1 & sp0 & pc0 & rs0 & pr0 & m2 & HPARSTATE & HEXISTS).
exploit match_states_cf_events_translate_cfi; eauto; intros; subst.
inv HEXISTS.
@@ -1780,6 +2564,29 @@ Opaque Mem.alloc.
apply Smallstep.plus_one. econstructor; eauto.
inv HTRANSL. auto. erewrite transl_module_ram_none by eauto. constructor.
inv HMATCH'. unfold state_st_wf in WF0. auto.
+ eapply lt_check_step_cf_instr; eauto.
+ - inv HPARSTATE; simplify. exploit transl_step_state_correct_instr_return; eauto.
+ constructor. intros (asr' & asa' & retval & HSTMNT_RUN & HVAL & HASR1 & HASR2 & HASR3).
+ inv HMATCH. inv CONST.
+ econstructor. split.
+ eapply Smallstep.plus_two.
+ econstructor.
+ + eauto.
+ + eauto.
+ + eauto.
+ + inv HTRANSL. eauto.
+ + eauto.
+ + erewrite transl_module_ram_none by eauto. constructor.
+ + eauto.
+ + eauto.
+ + unfold merge_regs. rewrite AssocMapExt.merge_base_1. rewrite AssocMapExt.merge_base_1. eauto.
+ + eapply lt_check_step_cf_instr2; eauto.
+ + eapply DHTL.step_finish.
+ * now do 2 rewrite AssocMapExt.merge_base_1.
+ * do 2 rewrite AssocMapExt.merge_base_1; eauto.
+ + auto.
+ + constructor. auto. auto.
+ Qed.
Theorem transl_step_correct:
forall (S1 : GibleSubPar.state) t S2,
diff --git a/src/hls/HTLgenproof.v b/src/hls/HTLgenproof.v
index 1668580..4475342 100644
--- a/src/hls/HTLgenproof.v
+++ b/src/hls/HTLgenproof.v
@@ -1328,373 +1328,373 @@ Ltac unfold_merge :=
Smallstep.plus HTL.step tge R1 Events.E0 R2 /\
match_states (RTL.State s f sp pc' (Registers.Regmap.set dst v rs) m) R2.
Proof.
- (* intros s f sp pc rs m chunk addr args dst pc' a v H H0 H1 R1 MSTATE. *)
- (* inv_state. inv_arr_access. *)
-
- (* + (** Preamble *) *)
- (* inv MARR. inv CONST. crush. *)
-
- (* unfold Op.eval_addressing in H0. *)
- (* destruct (Archi.ptr64) eqn:ARCHI; crush. *)
-
- (* unfold reg_stack_based_pointers in RSBP. *)
- (* pose proof (RSBP r0) as RSBPr0. *)
-
- (* destruct (Registers.Regmap.get r0 rs) eqn:EQr0; crush. *)
-
- (* rewrite ARCHI in H1. crush. *)
- (* subst. *)
-
- (* pose proof MASSOC as MASSOC'. *)
- (* inv MASSOC'. *)
- (* pose proof (H0 r0). *)
- (* assert (HPler0 : Ple r0 (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_use; eauto; crush; eauto). *)
- (* apply H0 in HPler0. *)
- (* inv HPler0; try congruence. *)
- (* rewrite EQr0 in H11. *)
- (* inv H11. *)
-
- (* unfold check_address_parameter_signed in *; *)
- (* unfold check_address_parameter_unsigned in *; crush. *)
-
- (* remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0)) *)
- (* (Integers.Ptrofs.of_int (Integers.Int.repr z))) as OFFSET. *)
-
- (* (** Modular preservation proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE. *)
- (* { apply Mem.load_valid_access in H1. unfold Mem.valid_access in *. simplify. *)
- (* apply Zdivide_mod. assumption. } *)
-
- (* (** Read bounds proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as READ_BOUND_HIGH. *)
- (* { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:EQ; crush; auto. *)
- (* unfold stack_bounds in BOUNDS. *)
- (* exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET)); auto. *)
- (* split; try lia; apply Integers.Ptrofs.unsigned_range_2. *)
- (* small_tac. } *)
-
- (* (** Normalisation proof *) *)
- (* assert (Integers.Ptrofs.repr *)
- (* (4 * Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4))) = OFFSET) *)
- (* as NORMALISE. *)
- (* { replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) at 1 by reflexivity. *)
- (* rewrite <- PtrofsExtra.mul_unsigned. *)
- (* apply PtrofsExtra.mul_divu; crush; auto. } *)
-
- (* (** Normalised bounds proof *) *)
- (* assert (0 <= *)
- (* Integers.Ptrofs.unsigned (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4)) *)
- (* < (RTL.fn_stacksize f / 4)) *)
- (* as NORMALISE_BOUND. *)
- (* { split. *)
- (* apply Integers.Ptrofs.unsigned_range_2. *)
- (* assert (HDIV: forall x y, Integers.Ptrofs.divu x y = Integers.Ptrofs.divu x y ) by reflexivity. *)
- (* unfold Integers.Ptrofs.divu at 2 in HDIV. *)
- (* rewrite HDIV. clear HDIV. *)
- (* rewrite Integers.Ptrofs.unsigned_repr; crush. *)
- (* apply Zmult_lt_reg_r with (p := 4); try lia. *)
- (* repeat rewrite ZLib.div_mul_undo; try lia. *)
- (* apply Z.div_pos; small_tac. *)
- (* apply Z.div_le_upper_bound; small_tac. } *)
-
- (* inversion NORMALISE_BOUND as [ NORMALISE_BOUND_LOW NORMALISE_BOUND_HIGH ]; *)
- (* clear NORMALISE_BOUND. *)
-
- (* (** Start of proof proper *) *)
- (* eexists. split. *)
- (* eapply Smallstep.plus_one. *)
- (* eapply HTL.step_module; eauto. *)
- (* econstructor. econstructor. econstructor. crush. *)
- (* econstructor. econstructor. econstructor. crush. *)
- (* econstructor. econstructor. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
- (* econstructor. econstructor. *)
-
- (* all: big_tac. *)
-
- (* 1: { *)
- (* assert (HPle : Ple dst (RTL.max_reg_function f)). *)
- (* eapply RTL.max_reg_function_def. eassumption. auto. *)
- (* apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. *)
- (* } *)
-
- (* 2: { *)
- (* assert (HPle : Ple dst (RTL.max_reg_function f)). *)
- (* eapply RTL.max_reg_function_def. eassumption. auto. *)
- (* apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. *)
- (* } *)
-
- (* (** Match assocmaps *) *)
- (* apply regs_lessdef_add_match; big_tac. *)
-
- (* (** Equality proof *) *)
- (* rewrite <- offset_expr_ok. *)
-
- (* specialize (H9 (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.divu *)
- (* OFFSET *)
- (* (Integers.Ptrofs.repr 4)))). *)
- (* exploit H9; big_tac. *)
-
- (* (** RSBP preservation *) *)
- (* unfold arr_stack_based_pointers in ASBP. *)
- (* specialize (ASBP (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4)))). *)
- (* exploit ASBP; big_tac. *)
- (* rewrite NORMALISE in H14. rewrite HeqOFFSET in H14. rewrite H1 in H14. assumption. *)
- (* constructor; simplify. rewrite AssocMap.gso. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
- (* assert (HPle: Ple dst (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_def; eauto; simpl; auto). *)
- (* unfold Ple in HPle. lia. *)
- (* rewrite AssocMap.gso. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
- (* assert (HPle: Ple dst (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_def; eauto; simpl; auto). *)
- (* unfold Ple in HPle. lia. *)
- (* + (** Preamble *) *)
- (* inv MARR. inv CONST. crush. *)
-
- (* unfold Op.eval_addressing in H0. *)
- (* destruct (Archi.ptr64) eqn:ARCHI; crush. *)
-
- (* unfold reg_stack_based_pointers in RSBP. *)
- (* pose proof (RSBP r0) as RSBPr0. *)
- (* pose proof (RSBP r1) as RSBPr1. *)
-
- (* destruct (Registers.Regmap.get r0 rs) eqn:EQr0; *)
- (* destruct (Registers.Regmap.get r1 rs) eqn:EQr1; crush. *)
-
- (* rewrite ARCHI in H1. crush. *)
- (* subst. *)
- (* clear RSBPr1. *)
-
- (* pose proof MASSOC as MASSOC'. *)
- (* inv MASSOC'. *)
- (* pose proof (H0 r0). *)
- (* pose proof (H0 r1). *)
- (* assert (HPler0 : Ple r0 (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_use; eauto; crush; eauto). *)
- (* assert (HPler1 : Ple r1 (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_use; eauto; simpl; auto). *)
- (* apply H8 in HPler0. *)
- (* apply H11 in HPler1. *)
- (* inv HPler0; inv HPler1; try congruence. *)
- (* rewrite EQr0 in H13. *)
- (* rewrite EQr1 in H14. *)
- (* inv H13. inv H14. *)
- (* clear H0. clear H8. clear H11. *)
-
- (* unfold check_address_parameter_signed in *; *)
- (* unfold check_address_parameter_unsigned in *; crush. *)
-
- (* remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0)) *)
- (* (Integers.Ptrofs.of_int *)
- (* (Integers.Int.add (Integers.Int.mul (valueToInt asr # r1) (Integers.Int.repr z)) *)
- (* (Integers.Int.repr z0)))) as OFFSET. *)
-
- (* (** Modular preservation proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE. *)
- (* { apply Mem.load_valid_access in H1. unfold Mem.valid_access in *. simplify. *)
- (* apply Zdivide_mod. assumption. } *)
-
- (* (** Read bounds proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as READ_BOUND_HIGH. *)
- (* { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:EQ; crush; auto. *)
- (* unfold stack_bounds in BOUNDS. *)
- (* exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET)); auto. *)
- (* split; try lia; apply Integers.Ptrofs.unsigned_range_2. *)
- (* small_tac. } *)
-
- (* (** Normalisation proof *) *)
- (* assert (Integers.Ptrofs.repr *)
- (* (4 * Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4))) = OFFSET) *)
- (* as NORMALISE. *)
- (* { replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) at 1 by reflexivity. *)
- (* rewrite <- PtrofsExtra.mul_unsigned. *)
- (* apply PtrofsExtra.mul_divu; crush. } *)
-
- (* (** Normalised bounds proof *) *)
- (* assert (0 <= *)
- (* Integers.Ptrofs.unsigned (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4)) *)
- (* < (RTL.fn_stacksize f / 4)) *)
- (* as NORMALISE_BOUND. *)
- (* { split. *)
- (* apply Integers.Ptrofs.unsigned_range_2. *)
- (* assert (forall x y, Integers.Ptrofs.divu x y = Integers.Ptrofs.divu x y ) by reflexivity. *)
- (* unfold Integers.Ptrofs.divu at 2 in H14. *)
- (* rewrite H14. clear H14. *)
- (* rewrite Integers.Ptrofs.unsigned_repr; crush. *)
- (* apply Zmult_lt_reg_r with (p := 4); try lia. *)
- (* repeat rewrite ZLib.div_mul_undo; try lia. *)
- (* apply Z.div_pos; small_tac. *)
- (* apply Z.div_le_upper_bound; lia. } *)
-
- (* inversion NORMALISE_BOUND as [ NORMALISE_BOUND_LOW NORMALISE_BOUND_HIGH ]; *)
- (* clear NORMALISE_BOUND. *)
-
- (* (** Start of proof proper *) *)
- (* eexists. split. *)
- (* eapply Smallstep.plus_one. *)
- (* eapply HTL.step_module; eauto. *)
- (* econstructor. econstructor. econstructor. crush. *)
- (* econstructor. econstructor. econstructor. crush. *)
- (* econstructor. econstructor. econstructor. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
- (* econstructor. econstructor. auto. econstructor. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
- (* all: big_tac. *)
-
- (* 1: { assert (HPle : Ple dst (RTL.max_reg_function f)). *)
- (* eapply RTL.max_reg_function_def. eassumption. auto. *)
- (* apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. } *)
-
- (* 2: { assert (HPle : Ple dst (RTL.max_reg_function f)). *)
- (* eapply RTL.max_reg_function_def. eassumption. auto. *)
- (* apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. } *)
-
- (* (** Match assocmaps *) *)
- (* apply regs_lessdef_add_match; big_tac. *)
-
- (* (** Equality proof *) *)
- (* rewrite <- offset_expr_ok_2. *)
-
- (* specialize (H9 (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.divu *)
- (* OFFSET *)
- (* (Integers.Ptrofs.repr 4)))). *)
- (* exploit H9; big_tac. *)
-
- (* (** RSBP preservation *) *)
- (* unfold arr_stack_based_pointers in ASBP. *)
- (* specialize (ASBP (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4)))). *)
- (* exploit ASBP; big_tac. *)
- (* rewrite NORMALISE in H14. rewrite HeqOFFSET in H14. rewrite H1 in H14. assumption. *)
-
- (* constructor; simplify. rewrite AssocMap.gso. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
- (* assert (HPle: Ple dst (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_def; eauto; simpl; auto). *)
- (* unfold Ple in HPle. lia. *)
- (* rewrite AssocMap.gso. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
- (* assert (HPle: Ple dst (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_def; eauto; simpl; auto). *)
- (* unfold Ple in HPle. lia. *)
-
- (* + inv MARR. inv CONST. crush. *)
-
- (* unfold Op.eval_addressing in H0. *)
- (* destruct (Archi.ptr64) eqn:ARCHI; crush. *)
- (* rewrite ARCHI in H0. crush. *)
-
- (* unfold check_address_parameter_unsigned in *; *)
- (* unfold check_address_parameter_signed in *; crush. *)
-
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity. *)
- (* rewrite ZERO in H1. clear ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l in H1. *)
-
- (* remember i0 as OFFSET. *)
-
- (* (** Modular preservation proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE. *)
- (* { apply Mem.load_valid_access in H1. unfold Mem.valid_access in *. simplify. *)
- (* apply Zdivide_mod. assumption. } *)
-
- (* (** Read bounds proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as READ_BOUND_HIGH. *)
- (* { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:?EQ; crush; auto. *)
- (* unfold stack_bounds in BOUNDS. *)
- (* exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET)); big_tac. } *)
-
- (* (** Normalisation proof *) *)
- (* assert (Integers.Ptrofs.repr *)
- (* (4 * Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4))) = OFFSET) *)
- (* as NORMALISE. *)
- (* { replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) at 1 by reflexivity. *)
- (* rewrite <- PtrofsExtra.mul_unsigned. *)
- (* apply PtrofsExtra.mul_divu; crush. } *)
-
- (* (** Normalised bounds proof *) *)
- (* assert (0 <= *)
- (* Integers.Ptrofs.unsigned (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4)) *)
- (* < (RTL.fn_stacksize f / 4)) *)
- (* as NORMALISE_BOUND. *)
- (* { split. *)
- (* apply Integers.Ptrofs.unsigned_range_2. *)
- (* assert (forall x y, Integers.Ptrofs.divu x y = Integers.Ptrofs.divu x y ) by reflexivity. *)
- (* unfold Integers.Ptrofs.divu at 2 in H0. *)
- (* rewrite H0. clear H0. *)
- (* rewrite Integers.Ptrofs.unsigned_repr; crush. *)
- (* apply Zmult_lt_reg_r with (p := 4); try lia. *)
- (* repeat rewrite ZLib.div_mul_undo; try lia. *)
- (* apply Z.div_pos; small_tac. *)
- (* apply Z.div_le_upper_bound; lia. } *)
-
- (* inversion NORMALISE_BOUND as [ NORMALISE_BOUND_LOW NORMALISE_BOUND_HIGH ]; *)
- (* clear NORMALISE_BOUND. *)
-
- (* (** Start of proof proper *) *)
- (* eexists. split. *)
- (* eapply Smallstep.plus_one. *)
- (* eapply HTL.step_module; eauto. *)
- (* econstructor. econstructor. econstructor. crush. *)
- (* econstructor. econstructor. econstructor. econstructor. crush. *)
-
- (* all: big_tac. *)
-
- (* 1: { assert (HPle : Ple dst (RTL.max_reg_function f)). *)
- (* eapply RTL.max_reg_function_def. eassumption. auto. *)
- (* apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. } *)
-
- (* 2: { assert (HPle : Ple dst (RTL.max_reg_function f)). *)
- (* eapply RTL.max_reg_function_def. eassumption. auto. *)
- (* apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. } *)
-
- (* (** Match assocmaps *) *)
- (* apply regs_lessdef_add_match; big_tac. *)
-
- (* (** Equality proof *) *)
- (* rewrite <- offset_expr_ok_3. *)
-
- (* specialize (H9 (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.divu *)
- (* OFFSET *)
- (* (Integers.Ptrofs.repr 4)))). *)
- (* exploit H9; big_tac. *)
-
- (* (** RSBP preservation *) *)
- (* unfold arr_stack_based_pointers in ASBP. *)
- (* specialize (ASBP (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4)))). *)
- (* exploit ASBP; big_tac. *)
- (* rewrite NORMALISE in H0. rewrite H1 in H0. assumption. *)
-
- (* constructor; simplify. rewrite AssocMap.gso. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
- (* assert (HPle: Ple dst (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_def; eauto; simpl; auto). *)
- (* unfold Ple in HPle. lia. *)
- (* rewrite AssocMap.gso. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
- (* assert (HPle: Ple dst (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_def; eauto; simpl; auto). *)
- (* unfold Ple in HPle. lia. *)
-
- (* Unshelve. *)
- (* exact (Values.Vint (Int.repr 0)). *)
- (* exact tt. *)
- (* exact (Values.Vint (Int.repr 0)). *)
- (* exact tt. *)
- (* exact (Values.Vint (Int.repr 0)). *)
- (* exact tt. *)
- (* Qed. *)
+ intros s f sp pc rs m chunk addr args dst pc' a v H H0 H1 R1 MSTATE.
+ inv_state. inv_arr_access.
+
+ + (** Preamble *)
+ inv MARR. inv CONST. crush.
+
+ unfold Op.eval_addressing in H0.
+ destruct (Archi.ptr64) eqn:ARCHI; crush.
+
+ unfold reg_stack_based_pointers in RSBP.
+ pose proof (RSBP r0) as RSBPr0.
+
+ destruct (Registers.Regmap.get r0 rs) eqn:EQr0; crush.
+
+ rewrite ARCHI in H1. crush.
+ subst.
+
+ pose proof MASSOC as MASSOC'.
+ inv MASSOC'.
+ pose proof (H0 r0).
+ assert (HPler0 : Ple r0 (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_use; eauto; crush; eauto).
+ apply H0 in HPler0.
+ inv HPler0; try congruence.
+ rewrite EQr0 in H11.
+ inv H11.
+
+ unfold check_address_parameter_signed in *;
+ unfold check_address_parameter_unsigned in *; crush.
+
+ remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0))
+ (Integers.Ptrofs.of_int (Integers.Int.repr z))) as OFFSET.
+
+ (** Modular preservation proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE.
+ { apply Mem.load_valid_access in H1. unfold Mem.valid_access in *. simplify.
+ apply Zdivide_mod. assumption. }
+
+ (** Read bounds proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as READ_BOUND_HIGH.
+ { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:EQ; crush; auto.
+ unfold stack_bounds in BOUNDS.
+ exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET)); auto.
+ split; try lia; apply Integers.Ptrofs.unsigned_range_2.
+ small_tac. }
+
+ (** Normalisation proof *)
+ assert (Integers.Ptrofs.repr
+ (4 * Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4))) = OFFSET)
+ as NORMALISE.
+ { replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) at 1 by reflexivity.
+ rewrite <- PtrofsExtra.mul_unsigned.
+ apply PtrofsExtra.mul_divu; crush; auto. }
+
+ (** Normalised bounds proof *)
+ assert (0 <=
+ Integers.Ptrofs.unsigned (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4))
+ < (RTL.fn_stacksize f / 4))
+ as NORMALISE_BOUND.
+ { split.
+ apply Integers.Ptrofs.unsigned_range_2.
+ assert (HDIV: forall x y, Integers.Ptrofs.divu x y = Integers.Ptrofs.divu x y ) by reflexivity.
+ unfold Integers.Ptrofs.divu at 2 in HDIV.
+ rewrite HDIV. clear HDIV.
+ rewrite Integers.Ptrofs.unsigned_repr; crush.
+ apply Zmult_lt_reg_r with (p := 4); try lia.
+ repeat rewrite ZLib.div_mul_undo; try lia.
+ apply Z.div_pos; small_tac.
+ apply Z.div_le_upper_bound; small_tac. }
+
+ inversion NORMALISE_BOUND as [ NORMALISE_BOUND_LOW NORMALISE_BOUND_HIGH ];
+ clear NORMALISE_BOUND.
+
+ (** Start of proof proper *)
+ eexists. split.
+ eapply Smallstep.plus_one.
+ eapply HTL.step_module; eauto.
+ econstructor. econstructor. econstructor. crush.
+ econstructor. econstructor. econstructor. crush.
+ econstructor. econstructor.
+ econstructor. econstructor. econstructor. econstructor.
+ econstructor. econstructor.
+
+ all: big_tac.
+
+ 1: {
+ assert (HPle : Ple dst (RTL.max_reg_function f)).
+ eapply RTL.max_reg_function_def. eassumption. auto.
+ apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption.
+ }
+
+ 2: {
+ assert (HPle : Ple dst (RTL.max_reg_function f)).
+ eapply RTL.max_reg_function_def. eassumption. auto.
+ apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption.
+ }
+
+ (** Match assocmaps *)
+ (* apply regs_lessdef_add_match; big_tac. *) admit. admit. admit. admit.
+
+ (** Equality proof *)
+ rewrite <- offset_expr_ok.
+
+ specialize (H9 (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu
+ OFFSET
+ (Integers.Ptrofs.repr 4)))).
+ exploit H9; big_tac. admit.
+
+ (** RSBP preservation *)
+ unfold arr_stack_based_pointers in ASBP.
+ specialize (ASBP (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4)))).
+ exploit ASBP; big_tac.
+ rewrite NORMALISE in H14. rewrite HeqOFFSET in H14. rewrite H1 in H14. assumption.
+ constructor; simplify. rewrite AssocMap.gso. rewrite AssocMap.gso.
+ assumption. lia.
+ assert (HPle: Ple dst (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_def; eauto; simpl; auto).
+ unfold Ple in HPle. lia.
+ rewrite AssocMap.gso. rewrite AssocMap.gso.
+ assumption. lia.
+ assert (HPle: Ple dst (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_def; eauto; simpl; auto).
+ unfold Ple in HPle. lia.
+ + (** Preamble *)
+ inv MARR. inv CONST. crush.
+
+ unfold Op.eval_addressing in H0.
+ destruct (Archi.ptr64) eqn:ARCHI; crush.
+
+ unfold reg_stack_based_pointers in RSBP.
+ pose proof (RSBP r0) as RSBPr0.
+ pose proof (RSBP r1) as RSBPr1.
+
+ destruct (Registers.Regmap.get r0 rs) eqn:EQr0;
+ destruct (Registers.Regmap.get r1 rs) eqn:EQr1; crush.
+
+ rewrite ARCHI in H1. crush.
+ subst.
+ clear RSBPr1.
+
+ pose proof MASSOC as MASSOC'.
+ inv MASSOC'.
+ pose proof (H0 r0).
+ pose proof (H0 r1).
+ assert (HPler0 : Ple r0 (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_use; eauto; crush; eauto).
+ assert (HPler1 : Ple r1 (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_use; eauto; simpl; auto).
+ apply H8 in HPler0.
+ apply H11 in HPler1.
+ inv HPler0; inv HPler1; try congruence.
+ rewrite EQr0 in H13.
+ rewrite EQr1 in H14.
+ inv H13. inv H14.
+ clear H0. clear H8. clear H11.
+
+ unfold check_address_parameter_signed in *;
+ unfold check_address_parameter_unsigned in *; crush.
+
+ remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0))
+ (Integers.Ptrofs.of_int
+ (Integers.Int.add (Integers.Int.mul (valueToInt asr # r1) (Integers.Int.repr z))
+ (Integers.Int.repr z0)))) as OFFSET.
+
+ (** Modular preservation proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE.
+ { apply Mem.load_valid_access in H1. unfold Mem.valid_access in *. simplify.
+ apply Zdivide_mod. assumption. }
+
+ (** Read bounds proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as READ_BOUND_HIGH.
+ { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:EQ; crush; auto.
+ unfold stack_bounds in BOUNDS.
+ exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET)); auto.
+ split; try lia; apply Integers.Ptrofs.unsigned_range_2.
+ small_tac. }
+
+ (** Normalisation proof *)
+ assert (Integers.Ptrofs.repr
+ (4 * Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4))) = OFFSET)
+ as NORMALISE.
+ { replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) at 1 by reflexivity.
+ rewrite <- PtrofsExtra.mul_unsigned.
+ apply PtrofsExtra.mul_divu; crush. }
+
+ (** Normalised bounds proof *)
+ assert (0 <=
+ Integers.Ptrofs.unsigned (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4))
+ < (RTL.fn_stacksize f / 4))
+ as NORMALISE_BOUND.
+ { split.
+ apply Integers.Ptrofs.unsigned_range_2.
+ assert (forall x y, Integers.Ptrofs.divu x y = Integers.Ptrofs.divu x y ) by reflexivity.
+ unfold Integers.Ptrofs.divu at 2 in H14.
+ rewrite H14. clear H14.
+ rewrite Integers.Ptrofs.unsigned_repr; crush.
+ apply Zmult_lt_reg_r with (p := 4); try lia.
+ repeat rewrite ZLib.div_mul_undo; try lia.
+ apply Z.div_pos; small_tac.
+ apply Z.div_le_upper_bound; lia. }
+
+ inversion NORMALISE_BOUND as [ NORMALISE_BOUND_LOW NORMALISE_BOUND_HIGH ];
+ clear NORMALISE_BOUND.
+
+ (** Start of proof proper *)
+ eexists. split.
+ eapply Smallstep.plus_one.
+ eapply HTL.step_module; eauto.
+ econstructor. econstructor. econstructor. crush.
+ econstructor. econstructor. econstructor. crush.
+ econstructor. econstructor. econstructor.
+ econstructor. econstructor. econstructor. econstructor.
+ econstructor. econstructor. auto. econstructor.
+ econstructor. econstructor. econstructor. econstructor.
+ all: big_tac.
+
+ 1: { assert (HPle : Ple dst (RTL.max_reg_function f)).
+ eapply RTL.max_reg_function_def. eassumption. auto.
+ apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. }
+
+ 2: { assert (HPle : Ple dst (RTL.max_reg_function f)).
+ eapply RTL.max_reg_function_def. eassumption. auto.
+ apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. }
+
+ (** Match assocmaps *)
+ apply regs_lessdef_add_match; big_tac.
+
+ (** Equality proof *)
+ rewrite <- offset_expr_ok_2.
+
+ specialize (H9 (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu
+ OFFSET
+ (Integers.Ptrofs.repr 4)))).
+ exploit H9; big_tac.
+
+ (** RSBP preservation *)
+ unfold arr_stack_based_pointers in ASBP.
+ specialize (ASBP (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4)))).
+ exploit ASBP; big_tac.
+ rewrite NORMALISE in H14. rewrite HeqOFFSET in H14. rewrite H1 in H14. assumption.
+
+ constructor; simplify. rewrite AssocMap.gso. rewrite AssocMap.gso.
+ assumption. lia.
+ assert (HPle: Ple dst (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_def; eauto; simpl; auto).
+ unfold Ple in HPle. lia.
+ rewrite AssocMap.gso. rewrite AssocMap.gso.
+ assumption. lia.
+ assert (HPle: Ple dst (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_def; eauto; simpl; auto).
+ unfold Ple in HPle. lia.
+
+ + inv MARR. inv CONST. crush.
+
+ unfold Op.eval_addressing in H0.
+ destruct (Archi.ptr64) eqn:ARCHI; crush.
+ rewrite ARCHI in H0. crush.
+
+ unfold check_address_parameter_unsigned in *;
+ unfold check_address_parameter_signed in *; crush.
+
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity.
+ rewrite ZERO in H1. clear ZERO.
+ rewrite Integers.Ptrofs.add_zero_l in H1.
+
+ remember i0 as OFFSET.
+
+ (** Modular preservation proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE.
+ { apply Mem.load_valid_access in H1. unfold Mem.valid_access in *. simplify.
+ apply Zdivide_mod. assumption. }
+
+ (** Read bounds proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as READ_BOUND_HIGH.
+ { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:?EQ; crush; auto.
+ unfold stack_bounds in BOUNDS.
+ exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET)); big_tac. }
+
+ (** Normalisation proof *)
+ assert (Integers.Ptrofs.repr
+ (4 * Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4))) = OFFSET)
+ as NORMALISE.
+ { replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) at 1 by reflexivity.
+ rewrite <- PtrofsExtra.mul_unsigned.
+ apply PtrofsExtra.mul_divu; crush. }
+
+ (** Normalised bounds proof *)
+ assert (0 <=
+ Integers.Ptrofs.unsigned (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4))
+ < (RTL.fn_stacksize f / 4))
+ as NORMALISE_BOUND.
+ { split.
+ apply Integers.Ptrofs.unsigned_range_2.
+ assert (forall x y, Integers.Ptrofs.divu x y = Integers.Ptrofs.divu x y ) by reflexivity.
+ unfold Integers.Ptrofs.divu at 2 in H0.
+ rewrite H0. clear H0.
+ rewrite Integers.Ptrofs.unsigned_repr; crush.
+ apply Zmult_lt_reg_r with (p := 4); try lia.
+ repeat rewrite ZLib.div_mul_undo; try lia.
+ apply Z.div_pos; small_tac.
+ apply Z.div_le_upper_bound; lia. }
+
+ inversion NORMALISE_BOUND as [ NORMALISE_BOUND_LOW NORMALISE_BOUND_HIGH ];
+ clear NORMALISE_BOUND.
+
+ (** Start of proof proper *)
+ eexists. split.
+ eapply Smallstep.plus_one.
+ eapply HTL.step_module; eauto.
+ econstructor. econstructor. econstructor. crush.
+ econstructor. econstructor. econstructor. econstructor. crush.
+
+ all: big_tac.
+
+ 1: { assert (HPle : Ple dst (RTL.max_reg_function f)).
+ eapply RTL.max_reg_function_def. eassumption. auto.
+ apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. }
+
+ 2: { assert (HPle : Ple dst (RTL.max_reg_function f)).
+ eapply RTL.max_reg_function_def. eassumption. auto.
+ apply ZExtra.Pge_not_eq. apply ZExtra.Ple_Plt_Succ. assumption. }
+
+ (** Match assocmaps *)
+ apply regs_lessdef_add_match; big_tac.
+
+ (** Equality proof *)
+ rewrite <- offset_expr_ok_3.
+
+ specialize (H9 (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu
+ OFFSET
+ (Integers.Ptrofs.repr 4)))).
+ exploit H9; big_tac.
+
+ (** RSBP preservation *)
+ unfold arr_stack_based_pointers in ASBP.
+ specialize (ASBP (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.divu OFFSET (Integers.Ptrofs.repr 4)))).
+ exploit ASBP; big_tac.
+ rewrite NORMALISE in H0. rewrite H1 in H0. assumption.
+
+ constructor; simplify. rewrite AssocMap.gso. rewrite AssocMap.gso.
+ assumption. lia.
+ assert (HPle: Ple dst (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_def; eauto; simpl; auto).
+ unfold Ple in HPle. lia.
+ rewrite AssocMap.gso. rewrite AssocMap.gso.
+ assumption. lia.
+ assert (HPle: Ple dst (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_def; eauto; simpl; auto).
+ unfold Ple in HPle. lia.
+
+ Unshelve.
+ exact (Values.Vint (Int.repr 0)).
+ exact tt.
+ exact (Values.Vint (Int.repr 0)).
+ exact tt.
+ exact (Values.Vint (Int.repr 0)).
+ exact tt.
+ Qed.
Admitted.
#[local] Hint Resolve transl_iload_correct : htlproof.
@@ -1711,861 +1711,861 @@ Ltac unfold_merge :=
exists R2 : HTL.state,
Smallstep.plus HTL.step tge R1 Events.E0 R2 /\ match_states (RTL.State s f sp pc' rs m') R2.
Proof.
- (* intros s f sp pc rs m chunk addr args src pc' a m' H H0 H1 R1 MSTATES. *)
- (* inv_state. inv_arr_access. *)
-
- (* + (** Preamble *) *)
- (* inv MARR. inv CONST. crush. *)
-
- (* unfold Op.eval_addressing in H0. *)
- (* destruct (Archi.ptr64) eqn:ARCHI; crush. *)
-
- (* unfold reg_stack_based_pointers in RSBP. *)
- (* pose proof (RSBP r0) as RSBPr0. *)
-
- (* destruct (Registers.Regmap.get r0 rs) eqn:EQr0; crush. *)
-
- (* rewrite ARCHI in H1. crush. *)
- (* subst. *)
-
- (* pose proof MASSOC as MASSOC'. *)
- (* inv MASSOC'. *)
- (* pose proof (H0 r0). *)
- (* assert (HPler0 : Ple r0 (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_use; eauto; crush; eauto). *)
- (* apply H8 in HPler0. *)
- (* inv HPler0; try congruence. *)
- (* rewrite EQr0 in H11. *)
- (* inv H11. *)
- (* clear H0. clear H8. *)
-
- (* unfold check_address_parameter_unsigned in *; *)
- (* unfold check_address_parameter_signed in *; crush. *)
-
- (* remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0)) *)
- (* (Integers.Ptrofs.of_int (Integers.Int.repr z))) as OFFSET. *)
-
- (* (** Modular preservation proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE. *)
- (* { apply Mem.store_valid_access_3 in H1. unfold Mem.valid_access in *. simplify. *)
- (* apply Zdivide_mod. assumption. } *)
-
- (* (** Write bounds proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as WRITE_BOUND_HIGH. *)
- (* { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:EQ; crush; auto. *)
- (* unfold stack_bounds in BOUNDS. *)
- (* exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET) (Registers.Regmap.get src rs)); big_tac. *)
- (* apply Integers.Ptrofs.unsigned_range_2. } *)
-
- (* (** Start of proof proper *) *)
- (* eexists. split. *)
- (* eapply Smallstep.plus_one. *)
- (* eapply HTL.step_module; eauto. *)
- (* econstructor. econstructor. econstructor. *)
- (* eapply Verilog.stmnt_runp_Vnonblock_arr. crush. *)
- (* econstructor. *)
- (* econstructor. *)
- (* econstructor. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
-
- (* all: try constructor; crush. *)
+ intros s f sp pc rs m chunk addr args src pc' a m' H H0 H1 R1 MSTATES.
+ inv_state. inv_arr_access.
+
+ + (** Preamble *)
+ inv MARR. inv CONST. crush.
+
+ unfold Op.eval_addressing in H0.
+ destruct (Archi.ptr64) eqn:ARCHI; crush.
+
+ unfold reg_stack_based_pointers in RSBP.
+ pose proof (RSBP r0) as RSBPr0.
+
+ destruct (Registers.Regmap.get r0 rs) eqn:EQr0; crush.
+
+ rewrite ARCHI in H1. crush.
+ subst.
+
+ pose proof MASSOC as MASSOC'.
+ inv MASSOC'.
+ pose proof (H0 r0).
+ assert (HPler0 : Ple r0 (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_use; eauto; crush; eauto).
+ apply H8 in HPler0.
+ inv HPler0; try congruence.
+ rewrite EQr0 in H11.
+ inv H11.
+ clear H0. clear H8.
+
+ unfold check_address_parameter_unsigned in *;
+ unfold check_address_parameter_signed in *; crush.
+
+ remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0))
+ (Integers.Ptrofs.of_int (Integers.Int.repr z))) as OFFSET.
+
+ (** Modular preservation proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE.
+ { apply Mem.store_valid_access_3 in H1. unfold Mem.valid_access in *. simplify.
+ apply Zdivide_mod. assumption. }
+
+ (** Write bounds proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as WRITE_BOUND_HIGH.
+ { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:EQ; crush; auto.
+ unfold stack_bounds in BOUNDS.
+ exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET) (Registers.Regmap.get src rs)); big_tac.
+ apply Integers.Ptrofs.unsigned_range_2. }
+
+ (** Start of proof proper *)
+ eexists. split.
+ eapply Smallstep.plus_one.
+ eapply HTL.step_module; eauto.
+ econstructor. econstructor. econstructor.
+ eapply Verilog.stmnt_runp_Vnonblock_arr. crush.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor. econstructor. econstructor. econstructor.
+ econstructor. econstructor. econstructor. econstructor.
- (* (** State Lookup *) *)
- (* unfold Verilog.merge_regs. *)
- (* crush. *)
- (* unfold_merge. *)
- (* apply AssocMap.gss. *)
+ all: try constructor; crush.
- (* (** Match states *) *)
- (* econstructor; eauto. *)
+ (** State Lookup *)
+ unfold Verilog.merge_regs.
+ crush.
+ unfold_merge.
+ apply AssocMap.gss.
- (* (** Match assocmaps *) *)
- (* unfold Verilog.merge_regs. crush. unfold_merge. *)
- (* apply regs_lessdef_add_greater. *)
- (* unfold Plt; lia. *)
- (* assumption. *)
+ (** Match states *)
+ econstructor; eauto.
- (* (** States well formed *) *)
- (* unfold state_st_wf. inversion 1. crush. *)
- (* unfold Verilog.merge_regs. *)
- (* unfold_merge. *)
- (* apply AssocMap.gss. *)
+ (** Match assocmaps *)
+ unfold Verilog.merge_regs. crush. unfold_merge.
+ apply regs_lessdef_add_greater.
+ unfold Plt; lia.
+ assumption.
- (* (** Equality proof *) *)
-
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity. *)
- (* inversion MASSOC; revert HeqOFFSET; subst; clear MASSOC; intros HeqOFFSET. *)
-
- (* econstructor. *)
- (* repeat split; crush. *)
- (* unfold HTL.empty_stack. *)
- (* crush. *)
- (* unfold Verilog.merge_arrs. *)
-
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* rewrite AssocMap.gss. *)
- (* erewrite Verilog.merge_arr_empty2. *)
- (* unfold Verilog.arr_assocmap_set. *)
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* rewrite AssocMap.gss. *)
- (* rewrite AssocMap.gss. *)
- (* unfold Verilog.merge_arr. *)
- (* setoid_rewrite H7. *)
- (* reflexivity. *)
-
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* unfold Verilog.merge_arr. *)
- (* unfold Verilog.arr_assocmap_set. *)
- (* rewrite AssocMap.gss. *)
- (* rewrite AssocMap.gss. *)
- (* setoid_rewrite H7. *)
- (* reflexivity. *)
-
- (* rewrite combine_length. *)
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* symmetry. *)
- (* apply list_repeat_len. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite H4. *)
- (* apply list_repeat_len. *)
-
- (* rewrite combine_length. *)
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* apply list_repeat_len. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite H4. *)
- (* apply list_repeat_len. *)
-
- (* remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0)) *)
- (* (Integers.Ptrofs.of_int (Integers.Int.repr z))) as OFFSET. *)
-
- (* destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET). *)
-
- (* erewrite Mem.load_store_same. *)
- (* 2: { rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite e. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* rewrite HeqOFFSET. *)
- (* exact H1. *)
- (* apply Integers.Ptrofs.unsigned_range_2. } *)
- (* constructor. *)
- (* erewrite combine_lookup_second. *)
- (* simplify. *)
- (* assert (HPle : Ple src (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_use; eauto; simpl; auto); *)
- (* apply H11 in HPle. *)
- (* destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; constructor; inv HPle; eauto. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite list_repeat_len. auto. *)
-
- (* assert (HMul : 4 * ptr / 4 = Integers.Ptrofs.unsigned OFFSET / 4) by (f_equal; assumption). *)
- (* rewrite Z.mul_comm in HMul. *)
- (* rewrite Z_div_mult in HMul; try lia. *)
- (* replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) in HMul by reflexivity. *)
- (* rewrite <- PtrofsExtra.divu_unsigned in HMul; unfold_constants; try lia. *)
- (* rewrite HMul. rewrite <- offset_expr_ok. *)
- (* rewrite HeqOFFSET. *)
- (* rewrite array_get_error_set_bound. *)
- (* reflexivity. *)
- (* unfold arr_length, arr_repeat. simpl. *)
- (* rewrite list_repeat_len. rewrite HeqOFFSET in HMul. lia. *)
-
- (* erewrite Mem.load_store_other with (m1 := m). *)
- (* 2: { exact H1. } *)
- (* 2: { right. *)
- (* rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* simpl. *)
- (* rewrite HeqOFFSET in *. simplify_val. *)
- (* destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto. *)
- (* rewrite HeqOFFSET in *. simplify_val. *)
- (* left; auto. *)
- (* rewrite HeqOFFSET in *. simplify_val. *)
- (* right. *)
- (* apply ZExtra.mod_0_bounds; try lia. *)
- (* apply ZLib.Z_mod_mult'. *)
- (* rewrite Z2Nat.id in H15; try lia. *)
- (* apply Zmult_lt_compat_r with (p := 4) in H15; try lia. *)
- (* rewrite ZLib.div_mul_undo in H15; try lia. *)
- (* split; try lia. *)
- (* apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia. *)
- (* } *)
-
- (* rewrite <- offset_expr_ok. *)
- (* rewrite PtrofsExtra.divu_unsigned; auto; try (unfold_constants; lia). *)
- (* destruct (ptr ==Z Integers.Ptrofs.unsigned OFFSET / 4). *)
- (* apply Z.mul_cancel_r with (p := 4) in e; try lia. *)
- (* rewrite ZLib.div_mul_undo in e; try lia. *)
- (* rewrite combine_lookup_first. *)
- (* eapply H9; eauto. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite list_repeat_len. auto. *)
- (* rewrite array_gso. *)
- (* unfold array_get_error. *)
- (* unfold arr_repeat. *)
- (* crush. *)
- (* apply list_repeat_lookup. *)
- (* lia. *)
- (* unfold_constants. *)
- (* intro. *)
- (* apply Z2Nat.inj_iff in H13; rewrite HeqOFFSET in n0; try lia. *)
- (* apply Z.div_pos; try lia. *)
- (* apply Integers.Ptrofs.unsigned_range. *)
- (* apply Integers.Ptrofs.unsigned_range_2. *)
-
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO1 by reflexivity. *)
- (* unfold arr_stack_based_pointers. *)
- (* intros. *)
- (* destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET). *)
-
- (* crush. *)
- (* erewrite Mem.load_store_same. *)
- (* 2: { rewrite ZERO1. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite e. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* exact H1. *)
- (* apply Integers.Ptrofs.unsigned_range_2. } *)
- (* crush. *)
- (* destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; try constructor. *)
- (* destruct (Archi.ptr64); try discriminate. *)
- (* pose proof (RSBP src). rewrite EQ_SRC in H11. *)
- (* assumption. *)
-
- (* simpl. *)
- (* erewrite Mem.load_store_other with (m1 := m). *)
- (* 2: { exact H1. } *)
- (* 2: { right. *)
- (* rewrite ZERO1. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* simpl. *)
- (* destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto. *)
- (* rewrite HeqOFFSET in *. simplify_val. *)
- (* left; auto. *)
- (* rewrite HeqOFFSET in *. simplify_val. *)
- (* right. *)
- (* apply ZExtra.mod_0_bounds; try lia. *)
- (* apply ZLib.Z_mod_mult'. *)
- (* inv H11. *)
- (* apply Zmult_lt_compat_r with (p := 4) in H14; try lia. *)
- (* rewrite ZLib.div_mul_undo in H14; try lia. *)
- (* split; try lia. *)
- (* apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia. *)
- (* } *)
- (* apply ASBP; assumption. *)
-
- (* unfold stack_bounds in *. intros. *)
- (* simpl. *)
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity. *)
- (* erewrite Mem.load_store_other with (m1 := m). *)
- (* 2: { exact H1. } *)
- (* 2: { rewrite HeqOFFSET in *. simplify_val. *)
- (* right. right. simpl. *)
- (* rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite Integers.Ptrofs.unsigned_repr; crush; try lia. *)
- (* apply ZExtra.mod_0_bounds; crush; try lia. } *)
- (* crush. *)
- (* exploit (BOUNDS ptr); try lia. intros. crush. *)
- (* exploit (BOUNDS ptr v); try lia. intros. *)
- (* inv H11. *)
- (* match goal with | |- ?x = _ => destruct x eqn:EQ end; try reflexivity. *)
- (* assert (Mem.valid_access m AST.Mint32 sp' *)
- (* (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.add (Integers.Ptrofs.repr 0) *)
- (* (Integers.Ptrofs.repr ptr))) Writable). *)
- (* { pose proof H1. eapply Mem.store_valid_access_2 in H11. *)
- (* exact H11. eapply Mem.store_valid_access_3. eassumption. } *)
- (* pose proof (Mem.valid_access_store m AST.Mint32 sp' *)
- (* (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.add (Integers.Ptrofs.repr 0) *)
- (* (Integers.Ptrofs.repr ptr))) v). *)
- (* apply X in H11. inv H11. congruence. *)
-
- (* constructor; simplify. unfold Verilog.merge_regs. unfold_merge. *)
- (* rewrite AssocMap.gso. *)
- (* assumption. lia. *)
- (* unfold Verilog.merge_regs. unfold_merge. *)
- (* rewrite AssocMap.gso. *)
- (* assumption. lia. *)
-
- (* + (** Preamble *) *)
- (* inv MARR. inv CONST. crush. *)
-
- (* unfold Op.eval_addressing in H0. *)
- (* destruct (Archi.ptr64) eqn:ARCHI; crush. *)
-
- (* unfold reg_stack_based_pointers in RSBP. *)
- (* pose proof (RSBP r0) as RSBPr0. *)
- (* pose proof (RSBP r1) as RSBPr1. *)
-
- (* destruct (Registers.Regmap.get r0 rs) eqn:EQr0; *)
- (* destruct (Registers.Regmap.get r1 rs) eqn:EQr1; crush. *)
-
- (* rewrite ARCHI in H1. crush. *)
- (* subst. *)
- (* clear RSBPr1. *)
-
- (* pose proof MASSOC as MASSOC'. *)
- (* inv MASSOC'. *)
- (* pose proof (H0 r0). *)
- (* pose proof (H0 r1). *)
- (* assert (HPler0 : Ple r0 (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_use; eauto; crush; eauto). *)
- (* assert (HPler1 : Ple r1 (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_use; eauto; simpl; auto). *)
- (* apply H8 in HPler0. *)
- (* apply H11 in HPler1. *)
- (* inv HPler0; inv HPler1; try congruence. *)
- (* rewrite EQr0 in H13. *)
- (* rewrite EQr1 in H14. *)
- (* inv H13. inv H14. *)
- (* clear H0. clear H8. clear H11. *)
-
- (* unfold check_address_parameter_signed in *; *)
- (* unfold check_address_parameter_unsigned in *; crush. *)
-
- (* remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0)) *)
- (* (Integers.Ptrofs.of_int *)
- (* (Integers.Int.add (Integers.Int.mul (valueToInt asr # r1) (Integers.Int.repr z)) *)
- (* (Integers.Int.repr z0)))) as OFFSET. *)
-
- (* (** Modular preservation proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE. *)
- (* { apply Mem.store_valid_access_3 in H1. unfold Mem.valid_access in *. simplify. *)
- (* apply Zdivide_mod. assumption. } *)
-
- (* (** Write bounds proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as WRITE_BOUND_HIGH. *)
- (* { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:EQ; crush; auto. *)
- (* unfold stack_bounds in BOUNDS. *)
- (* exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET) (Registers.Regmap.get src rs)); auto. *)
- (* split; try lia; apply Integers.Ptrofs.unsigned_range_2. *)
- (* small_tac. } *)
-
- (* (** Start of proof proper *) *)
- (* eexists. split. *)
- (* eapply Smallstep.plus_one. *)
- (* eapply HTL.step_module; eauto. *)
- (* econstructor. econstructor. econstructor. *)
- (* eapply Verilog.stmnt_runp_Vnonblock_arr. crush. *)
- (* econstructor. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
- (* econstructor. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
-
- (* all: try constructor; crush. *)
-
- (* (** State Lookup *) *)
- (* unfold Verilog.merge_regs. *)
- (* crush. *)
- (* unfold_merge. *)
- (* apply AssocMap.gss. *)
+ (** States well formed *)
+ unfold state_st_wf. inversion 1. crush.
+ unfold Verilog.merge_regs.
+ unfold_merge.
+ apply AssocMap.gss.
+
+ (** Equality proof *)
+
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity.
+ inversion MASSOC; revert HeqOFFSET; subst; clear MASSOC; intros HeqOFFSET.
+
+ econstructor.
+ repeat split; crush.
+ unfold HTL.empty_stack.
+ crush.
+ unfold Verilog.merge_arrs.
+
+ rewrite AssocMap.gcombine by reflexivity.
+ rewrite AssocMap.gss.
+ erewrite Verilog.merge_arr_empty2.
+ unfold Verilog.arr_assocmap_set.
+ rewrite AssocMap.gcombine by reflexivity.
+ rewrite AssocMap.gss.
+ rewrite AssocMap.gss.
+ unfold Verilog.merge_arr.
+ setoid_rewrite H7.
+ reflexivity.
+
+ rewrite AssocMap.gcombine by reflexivity.
+ unfold Verilog.merge_arr.
+ unfold Verilog.arr_assocmap_set.
+ rewrite AssocMap.gss.
+ rewrite AssocMap.gss.
+ setoid_rewrite H7.
+ reflexivity.
+
+ rewrite combine_length.
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ symmetry.
+ apply list_repeat_len.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite H4.
+ apply list_repeat_len.
+
+ rewrite combine_length.
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ apply list_repeat_len.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite H4.
+ apply list_repeat_len.
+
+ remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0))
+ (Integers.Ptrofs.of_int (Integers.Int.repr z))) as OFFSET.
+
+ destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET).
+
+ erewrite Mem.load_store_same.
+ 2: { rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite e.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ rewrite HeqOFFSET.
+ exact H1.
+ apply Integers.Ptrofs.unsigned_range_2. }
+ constructor.
+ erewrite combine_lookup_second.
+ simplify.
+ assert (HPle : Ple src (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_use; eauto; simpl; auto);
+ apply H11 in HPle.
+ destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; constructor; inv HPle; eauto.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite list_repeat_len. auto.
+
+ assert (HMul : 4 * ptr / 4 = Integers.Ptrofs.unsigned OFFSET / 4) by (f_equal; assumption).
+ rewrite Z.mul_comm in HMul.
+ rewrite Z_div_mult in HMul; try lia.
+ replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) in HMul by reflexivity.
+ rewrite <- PtrofsExtra.divu_unsigned in HMul; unfold_constants; try lia.
+ rewrite HMul. rewrite <- offset_expr_ok.
+ rewrite HeqOFFSET.
+ rewrite array_get_error_set_bound.
+ reflexivity.
+ unfold arr_length, arr_repeat. simpl.
+ rewrite list_repeat_len. rewrite HeqOFFSET in HMul. lia.
+
+ erewrite Mem.load_store_other with (m1 := m).
+ 2: { exact H1. }
+ 2: { right.
+ rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ simpl.
+ rewrite HeqOFFSET in *. simplify_val.
+ destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto.
+ rewrite HeqOFFSET in *. simplify_val.
+ left; auto.
+ rewrite HeqOFFSET in *. simplify_val.
+ right.
+ apply ZExtra.mod_0_bounds; try lia.
+ apply ZLib.Z_mod_mult'.
+ rewrite Z2Nat.id in H15; try lia.
+ apply Zmult_lt_compat_r with (p := 4) in H15; try lia.
+ rewrite ZLib.div_mul_undo in H15; try lia.
+ split; try lia.
+ apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia.
+ }
- (* (** Match states *) *)
- (* econstructor; eauto. *)
+ rewrite <- offset_expr_ok.
+ rewrite PtrofsExtra.divu_unsigned; auto; try (unfold_constants; lia).
+ destruct (ptr ==Z Integers.Ptrofs.unsigned OFFSET / 4).
+ apply Z.mul_cancel_r with (p := 4) in e; try lia.
+ rewrite ZLib.div_mul_undo in e; try lia.
+ rewrite combine_lookup_first.
+ eapply H9; eauto.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite list_repeat_len. auto.
+ rewrite array_gso.
+ unfold array_get_error.
+ unfold arr_repeat.
+ crush.
+ apply list_repeat_lookup.
+ lia.
+ unfold_constants.
+ intro.
+ apply Z2Nat.inj_iff in H13; rewrite HeqOFFSET in n0; try lia.
+ apply Z.div_pos; try lia.
+ apply Integers.Ptrofs.unsigned_range.
+ apply Integers.Ptrofs.unsigned_range_2.
+
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO1 by reflexivity.
+ unfold arr_stack_based_pointers.
+ intros.
+ destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET).
+
+ crush.
+ erewrite Mem.load_store_same.
+ 2: { rewrite ZERO1.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite e.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ exact H1.
+ apply Integers.Ptrofs.unsigned_range_2. }
+ crush.
+ destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; try constructor.
+ destruct (Archi.ptr64); try discriminate.
+ pose proof (RSBP src). rewrite EQ_SRC in H11.
+ assumption.
+
+ simpl.
+ erewrite Mem.load_store_other with (m1 := m).
+ 2: { exact H1. }
+ 2: { right.
+ rewrite ZERO1.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ simpl.
+ destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto.
+ rewrite HeqOFFSET in *. simplify_val.
+ left; auto.
+ rewrite HeqOFFSET in *. simplify_val.
+ right.
+ apply ZExtra.mod_0_bounds; try lia.
+ apply ZLib.Z_mod_mult'.
+ inv H11.
+ apply Zmult_lt_compat_r with (p := 4) in H14; try lia.
+ rewrite ZLib.div_mul_undo in H14; try lia.
+ split; try lia.
+ apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia.
+ }
+ apply ASBP; assumption.
+
+ unfold stack_bounds in *. intros.
+ simpl.
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity.
+ erewrite Mem.load_store_other with (m1 := m).
+ 2: { exact H1. }
+ 2: { rewrite HeqOFFSET in *. simplify_val.
+ right. right. simpl.
+ rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite Integers.Ptrofs.unsigned_repr; crush; try lia.
+ apply ZExtra.mod_0_bounds; crush; try lia. }
+ crush.
+ exploit (BOUNDS ptr); try lia. intros. crush.
+ exploit (BOUNDS ptr v); try lia. intros.
+ inv H11.
+ match goal with | |- ?x = _ => destruct x eqn:EQ end; try reflexivity.
+ assert (Mem.valid_access m AST.Mint32 sp'
+ (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.add (Integers.Ptrofs.repr 0)
+ (Integers.Ptrofs.repr ptr))) Writable).
+ { pose proof H1. eapply Mem.store_valid_access_2 in H11.
+ exact H11. eapply Mem.store_valid_access_3. eassumption. }
+ pose proof (Mem.valid_access_store m AST.Mint32 sp'
+ (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.add (Integers.Ptrofs.repr 0)
+ (Integers.Ptrofs.repr ptr))) v).
+ apply X in H11. inv H11. congruence.
+
+ constructor; simplify. unfold Verilog.merge_regs. unfold_merge.
+ rewrite AssocMap.gso.
+ assumption. lia.
+ unfold Verilog.merge_regs. unfold_merge.
+ rewrite AssocMap.gso.
+ assumption. lia.
+
+ + (** Preamble *)
+ inv MARR. inv CONST. crush.
+
+ unfold Op.eval_addressing in H0.
+ destruct (Archi.ptr64) eqn:ARCHI; crush.
+
+ unfold reg_stack_based_pointers in RSBP.
+ pose proof (RSBP r0) as RSBPr0.
+ pose proof (RSBP r1) as RSBPr1.
+
+ destruct (Registers.Regmap.get r0 rs) eqn:EQr0;
+ destruct (Registers.Regmap.get r1 rs) eqn:EQr1; crush.
+
+ rewrite ARCHI in H1. crush.
+ subst.
+ clear RSBPr1.
+
+ pose proof MASSOC as MASSOC'.
+ inv MASSOC'.
+ pose proof (H0 r0).
+ pose proof (H0 r1).
+ assert (HPler0 : Ple r0 (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_use; eauto; crush; eauto).
+ assert (HPler1 : Ple r1 (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_use; eauto; simpl; auto).
+ apply H8 in HPler0.
+ apply H11 in HPler1.
+ inv HPler0; inv HPler1; try congruence.
+ rewrite EQr0 in H13.
+ rewrite EQr1 in H14.
+ inv H13. inv H14.
+ clear H0. clear H8. clear H11.
+
+ unfold check_address_parameter_signed in *;
+ unfold check_address_parameter_unsigned in *; crush.
+
+ remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0))
+ (Integers.Ptrofs.of_int
+ (Integers.Int.add (Integers.Int.mul (valueToInt asr # r1) (Integers.Int.repr z))
+ (Integers.Int.repr z0)))) as OFFSET.
+
+ (** Modular preservation proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE.
+ { apply Mem.store_valid_access_3 in H1. unfold Mem.valid_access in *. simplify.
+ apply Zdivide_mod. assumption. }
+
+ (** Write bounds proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as WRITE_BOUND_HIGH.
+ { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:EQ; crush; auto.
+ unfold stack_bounds in BOUNDS.
+ exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET) (Registers.Regmap.get src rs)); auto.
+ split; try lia; apply Integers.Ptrofs.unsigned_range_2.
+ small_tac. }
+
+ (** Start of proof proper *)
+ eexists. split.
+ eapply Smallstep.plus_one.
+ eapply HTL.step_module; eauto.
+ econstructor. econstructor. econstructor.
+ eapply Verilog.stmnt_runp_Vnonblock_arr. crush.
+ econstructor.
+ econstructor. econstructor. econstructor. econstructor.
+ econstructor.
+ econstructor. econstructor. econstructor. econstructor.
+ econstructor. econstructor. econstructor. econstructor.
+ econstructor. econstructor. econstructor. econstructor.
+
+ all: try constructor; crush.
+
+ (** State Lookup *)
+ unfold Verilog.merge_regs.
+ crush.
+ unfold_merge.
+ apply AssocMap.gss.
- (* (** Match assocmaps *) *)
- (* unfold Verilog.merge_regs. crush. unfold_merge. *)
- (* apply regs_lessdef_add_greater. *)
- (* unfold Plt; lia. *)
- (* assumption. *)
+ (** Match states *)
+ econstructor; eauto.
- (* (** States well formed *) *)
- (* unfold state_st_wf. inversion 1. crush. *)
- (* unfold Verilog.merge_regs. *)
- (* unfold_merge. *)
- (* apply AssocMap.gss. *)
+ (** Match assocmaps *)
+ unfold Verilog.merge_regs. crush. unfold_merge.
+ apply regs_lessdef_add_greater.
+ unfold Plt; lia.
+ assumption.
- (* (** Equality proof *) *)
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity. *)
- (* inversion MASSOC; revert HeqOFFSET; subst; clear MASSOC; intros HeqOFFSET. *)
-
- (* econstructor. *)
- (* repeat split; crush. *)
- (* unfold HTL.empty_stack. *)
- (* crush. *)
- (* unfold Verilog.merge_arrs. *)
-
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* rewrite AssocMap.gss. *)
- (* erewrite Verilog.merge_arr_empty2. *)
- (* unfold Verilog.arr_assocmap_set. *)
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* rewrite AssocMap.gss. *)
- (* rewrite AssocMap.gss. *)
- (* unfold Verilog.merge_arr. *)
- (* setoid_rewrite H7. *)
- (* reflexivity. *)
-
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* unfold Verilog.merge_arr. *)
- (* unfold Verilog.arr_assocmap_set. *)
- (* rewrite AssocMap.gss. *)
- (* rewrite AssocMap.gss. *)
- (* setoid_rewrite H7. *)
- (* reflexivity. *)
-
- (* rewrite combine_length. *)
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* symmetry. *)
- (* apply list_repeat_len. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite H4. *)
- (* apply list_repeat_len. *)
-
- (* rewrite combine_length. *)
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* apply list_repeat_len. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite H4. *)
- (* apply list_repeat_len. *)
-
- (* remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0)) *)
- (* (Integers.Ptrofs.of_int *)
- (* (Integers.Int.add (Integers.Int.mul (valueToInt asr # r1) (Integers.Int.repr z)) *)
- (* (Integers.Int.repr z0)))) as OFFSET. *)
- (* destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET). *)
-
- (* erewrite Mem.load_store_same. *)
- (* 2: { rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite e. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* rewrite HeqOFFSET. *)
- (* exact H1. *)
- (* apply Integers.Ptrofs.unsigned_range_2. } *)
- (* constructor. *)
- (* erewrite combine_lookup_second. *)
- (* simpl. *)
- (* assert (Ple src (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_use; eauto; simpl; auto); *)
- (* apply H14 in H15. *)
- (* destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; constructor; inv H15; eauto. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite list_repeat_len. auto. *)
-
- (* assert (4 * ptr / 4 = Integers.Ptrofs.unsigned OFFSET / 4) by (f_equal; assumption). *)
- (* rewrite Z.mul_comm in H15. *)
- (* rewrite Z_div_mult in H15; try lia. *)
- (* replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) in H15 by reflexivity. *)
- (* rewrite <- PtrofsExtra.divu_unsigned in H15; unfold_constants; try lia. *)
- (* rewrite H15. rewrite <- offset_expr_ok_2. *)
- (* rewrite HeqOFFSET in *. *)
- (* rewrite array_get_error_set_bound. *)
- (* reflexivity. *)
- (* unfold arr_length, arr_repeat. simpl. *)
- (* rewrite list_repeat_len. lia. *)
-
- (* erewrite Mem.load_store_other with (m1 := m). *)
- (* 2: { exact H1. } *)
- (* 2: { right. *)
- (* rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* simpl. *)
- (* destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto. *)
- (* rewrite HeqOFFSET in *. simplify_val. *)
- (* left; auto. *)
- (* rewrite HeqOFFSET in *. simplify_val. *)
- (* right. *)
- (* apply ZExtra.mod_0_bounds; try lia. *)
- (* apply ZLib.Z_mod_mult'. *)
- (* rewrite Z2Nat.id in H17; try lia. *)
- (* apply Zmult_lt_compat_r with (p := 4) in H17; try lia. *)
- (* rewrite ZLib.div_mul_undo in H17; try lia. *)
- (* split; try lia. *)
- (* apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia. *)
- (* } *)
-
- (* rewrite <- offset_expr_ok_2. *)
- (* rewrite PtrofsExtra.divu_unsigned; auto; try (unfold_constants; lia). *)
- (* destruct (ptr ==Z Integers.Ptrofs.unsigned OFFSET / 4). *)
- (* apply Z.mul_cancel_r with (p := 4) in e; try lia. *)
- (* rewrite ZLib.div_mul_undo in e; try lia. *)
- (* rewrite combine_lookup_first. *)
- (* eapply H9; eauto. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite list_repeat_len. auto. *)
- (* rewrite array_gso. *)
- (* unfold array_get_error. *)
- (* unfold arr_repeat. *)
- (* crush. *)
- (* apply list_repeat_lookup. *)
- (* lia. *)
- (* unfold_constants. *)
- (* intro. *)
- (* rewrite HeqOFFSET in *. *)
- (* apply Z2Nat.inj_iff in H15; try lia. *)
- (* apply Z.div_pos; try lia. *)
- (* apply Integers.Ptrofs.unsigned_range. *)
- (* apply Integers.Ptrofs.unsigned_range_2. *)
-
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO1 by reflexivity. *)
- (* unfold arr_stack_based_pointers. *)
- (* intros. *)
- (* destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET). *)
-
- (* crush. *)
- (* erewrite Mem.load_store_same. *)
- (* 2: { rewrite ZERO1. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite e. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* exact H1. *)
- (* apply Integers.Ptrofs.unsigned_range_2. } *)
- (* crush. *)
- (* destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; try constructor. *)
- (* destruct (Archi.ptr64); try discriminate. *)
- (* pose proof (RSBP src). rewrite EQ_SRC in H14. *)
- (* assumption. *)
-
- (* simpl. *)
- (* erewrite Mem.load_store_other with (m1 := m). *)
- (* 2: { exact H1. } *)
- (* 2: { right. *)
- (* rewrite ZERO1. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* simpl. *)
- (* destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto. *)
- (* rewrite HeqOFFSET in *. simplify_val. *)
- (* left; auto. *)
- (* rewrite HeqOFFSET in *. simplify_val. *)
- (* right. *)
- (* apply ZExtra.mod_0_bounds; try lia. *)
- (* apply ZLib.Z_mod_mult'. *)
- (* inv H14. *)
- (* apply Zmult_lt_compat_r with (p := 4) in H16; try lia. *)
- (* rewrite ZLib.div_mul_undo in H16; try lia. *)
- (* split; try lia. *)
- (* apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia. *)
- (* } *)
- (* apply ASBP; assumption. *)
-
- (* unfold stack_bounds in *. intros. *)
- (* simpl. *)
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity. *)
- (* erewrite Mem.load_store_other with (m1 := m). *)
- (* 2: { exact H1. } *)
- (* 2: { rewrite HeqOFFSET in *. simplify_val. *)
- (* right. right. simpl. *)
- (* rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite Integers.Ptrofs.unsigned_repr; crush; try lia. *)
- (* apply ZExtra.mod_0_bounds; crush; try lia. } *)
- (* crush. *)
- (* exploit (BOUNDS ptr); try lia. intros. crush. *)
- (* exploit (BOUNDS ptr v); try lia. intros. *)
- (* simplify. *)
- (* match goal with | |- ?x = _ => destruct x eqn:EQ end; try reflexivity. *)
- (* assert (Mem.valid_access m AST.Mint32 sp' *)
- (* (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.add (Integers.Ptrofs.repr 0) *)
- (* (Integers.Ptrofs.repr ptr))) Writable). *)
- (* { pose proof H1. eapply Mem.store_valid_access_2 in H14. *)
- (* exact H14. eapply Mem.store_valid_access_3. eassumption. } *)
- (* pose proof (Mem.valid_access_store m AST.Mint32 sp' *)
- (* (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.add (Integers.Ptrofs.repr 0) *)
- (* (Integers.Ptrofs.repr ptr))) v). *)
- (* apply X in H14. inv H14. congruence. *)
-
- (* constructor; simplify. unfold Verilog.merge_regs. unfold_merge. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
- (* unfold Verilog.merge_regs. unfold_merge. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
-
- (* + inv MARR. inv CONST. crush. *)
-
- (* unfold Op.eval_addressing in H0. *)
- (* destruct (Archi.ptr64) eqn:ARCHI; crush. *)
- (* rewrite ARCHI in H0. crush. *)
-
- (* unfold check_address_parameter_unsigned in *; *)
- (* unfold check_address_parameter_signed in *; crush. *)
-
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity. *)
- (* rewrite ZERO in H1. clear ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l in H1. *)
-
- (* remember i0 as OFFSET. *)
-
- (* (** Modular preservation proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE. *)
- (* { apply Mem.store_valid_access_3 in H1. unfold Mem.valid_access in *. simplify. *)
- (* apply Zdivide_mod. assumption. } *)
-
- (* (** Write bounds proof *) *)
- (* assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as WRITE_BOUND_HIGH. *)
- (* { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:?EQ; crush; auto. *)
- (* unfold stack_bounds in BOUNDS. *)
- (* exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET) (Registers.Regmap.get src rs)); auto. *)
- (* crush. *)
- (* replace (Integers.Ptrofs.repr 0) with (Integers.Ptrofs.zero) by reflexivity. *)
- (* small_tac. } *)
-
- (* (** Start of proof proper *) *)
- (* eexists. split. *)
- (* eapply Smallstep.plus_one. *)
- (* eapply HTL.step_module; eauto. *)
- (* econstructor. econstructor. econstructor. *)
- (* eapply Verilog.stmnt_runp_Vnonblock_arr. crush. *)
- (* econstructor. econstructor. econstructor. econstructor. *)
+ (** States well formed *)
+ unfold state_st_wf. inversion 1. crush.
+ unfold Verilog.merge_regs.
+ unfold_merge.
+ apply AssocMap.gss.
+
+ (** Equality proof *)
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity.
+ inversion MASSOC; revert HeqOFFSET; subst; clear MASSOC; intros HeqOFFSET.
+
+ econstructor.
+ repeat split; crush.
+ unfold HTL.empty_stack.
+ crush.
+ unfold Verilog.merge_arrs.
+
+ rewrite AssocMap.gcombine by reflexivity.
+ rewrite AssocMap.gss.
+ erewrite Verilog.merge_arr_empty2.
+ unfold Verilog.arr_assocmap_set.
+ rewrite AssocMap.gcombine by reflexivity.
+ rewrite AssocMap.gss.
+ rewrite AssocMap.gss.
+ unfold Verilog.merge_arr.
+ setoid_rewrite H7.
+ reflexivity.
+
+ rewrite AssocMap.gcombine by reflexivity.
+ unfold Verilog.merge_arr.
+ unfold Verilog.arr_assocmap_set.
+ rewrite AssocMap.gss.
+ rewrite AssocMap.gss.
+ setoid_rewrite H7.
+ reflexivity.
+
+ rewrite combine_length.
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ symmetry.
+ apply list_repeat_len.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite H4.
+ apply list_repeat_len.
+
+ rewrite combine_length.
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ apply list_repeat_len.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite H4.
+ apply list_repeat_len.
+
+ remember (Integers.Ptrofs.add (Integers.Ptrofs.repr (uvalueToZ asr # r0))
+ (Integers.Ptrofs.of_int
+ (Integers.Int.add (Integers.Int.mul (valueToInt asr # r1) (Integers.Int.repr z))
+ (Integers.Int.repr z0)))) as OFFSET.
+ destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET).
+
+ erewrite Mem.load_store_same.
+ 2: { rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite e.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ rewrite HeqOFFSET.
+ exact H1.
+ apply Integers.Ptrofs.unsigned_range_2. }
+ constructor.
+ erewrite combine_lookup_second.
+ simpl.
+ assert (Ple src (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_use; eauto; simpl; auto);
+ apply H14 in H15.
+ destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; constructor; inv H15; eauto.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite list_repeat_len. auto.
+
+ assert (4 * ptr / 4 = Integers.Ptrofs.unsigned OFFSET / 4) by (f_equal; assumption).
+ rewrite Z.mul_comm in H15.
+ rewrite Z_div_mult in H15; try lia.
+ replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) in H15 by reflexivity.
+ rewrite <- PtrofsExtra.divu_unsigned in H15; unfold_constants; try lia.
+ rewrite H15. rewrite <- offset_expr_ok_2.
+ rewrite HeqOFFSET in *.
+ rewrite array_get_error_set_bound.
+ reflexivity.
+ unfold arr_length, arr_repeat. simpl.
+ rewrite list_repeat_len. lia.
+
+ erewrite Mem.load_store_other with (m1 := m).
+ 2: { exact H1. }
+ 2: { right.
+ rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ simpl.
+ destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto.
+ rewrite HeqOFFSET in *. simplify_val.
+ left; auto.
+ rewrite HeqOFFSET in *. simplify_val.
+ right.
+ apply ZExtra.mod_0_bounds; try lia.
+ apply ZLib.Z_mod_mult'.
+ rewrite Z2Nat.id in H17; try lia.
+ apply Zmult_lt_compat_r with (p := 4) in H17; try lia.
+ rewrite ZLib.div_mul_undo in H17; try lia.
+ split; try lia.
+ apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia.
+ }
- (* all: try constructor; crush. *)
+ rewrite <- offset_expr_ok_2.
+ rewrite PtrofsExtra.divu_unsigned; auto; try (unfold_constants; lia).
+ destruct (ptr ==Z Integers.Ptrofs.unsigned OFFSET / 4).
+ apply Z.mul_cancel_r with (p := 4) in e; try lia.
+ rewrite ZLib.div_mul_undo in e; try lia.
+ rewrite combine_lookup_first.
+ eapply H9; eauto.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite list_repeat_len. auto.
+ rewrite array_gso.
+ unfold array_get_error.
+ unfold arr_repeat.
+ crush.
+ apply list_repeat_lookup.
+ lia.
+ unfold_constants.
+ intro.
+ rewrite HeqOFFSET in *.
+ apply Z2Nat.inj_iff in H15; try lia.
+ apply Z.div_pos; try lia.
+ apply Integers.Ptrofs.unsigned_range.
+ apply Integers.Ptrofs.unsigned_range_2.
+
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO1 by reflexivity.
+ unfold arr_stack_based_pointers.
+ intros.
+ destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET).
+
+ crush.
+ erewrite Mem.load_store_same.
+ 2: { rewrite ZERO1.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite e.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ exact H1.
+ apply Integers.Ptrofs.unsigned_range_2. }
+ crush.
+ destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; try constructor.
+ destruct (Archi.ptr64); try discriminate.
+ pose proof (RSBP src). rewrite EQ_SRC in H14.
+ assumption.
+
+ simpl.
+ erewrite Mem.load_store_other with (m1 := m).
+ 2: { exact H1. }
+ 2: { right.
+ rewrite ZERO1.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ simpl.
+ destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto.
+ rewrite HeqOFFSET in *. simplify_val.
+ left; auto.
+ rewrite HeqOFFSET in *. simplify_val.
+ right.
+ apply ZExtra.mod_0_bounds; try lia.
+ apply ZLib.Z_mod_mult'.
+ inv H14.
+ apply Zmult_lt_compat_r with (p := 4) in H16; try lia.
+ rewrite ZLib.div_mul_undo in H16; try lia.
+ split; try lia.
+ apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia.
+ }
+ apply ASBP; assumption.
+
+ unfold stack_bounds in *. intros.
+ simpl.
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity.
+ erewrite Mem.load_store_other with (m1 := m).
+ 2: { exact H1. }
+ 2: { rewrite HeqOFFSET in *. simplify_val.
+ right. right. simpl.
+ rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite Integers.Ptrofs.unsigned_repr; crush; try lia.
+ apply ZExtra.mod_0_bounds; crush; try lia. }
+ crush.
+ exploit (BOUNDS ptr); try lia. intros. crush.
+ exploit (BOUNDS ptr v); try lia. intros.
+ simplify.
+ match goal with | |- ?x = _ => destruct x eqn:EQ end; try reflexivity.
+ assert (Mem.valid_access m AST.Mint32 sp'
+ (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.add (Integers.Ptrofs.repr 0)
+ (Integers.Ptrofs.repr ptr))) Writable).
+ { pose proof H1. eapply Mem.store_valid_access_2 in H14.
+ exact H14. eapply Mem.store_valid_access_3. eassumption. }
+ pose proof (Mem.valid_access_store m AST.Mint32 sp'
+ (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.add (Integers.Ptrofs.repr 0)
+ (Integers.Ptrofs.repr ptr))) v).
+ apply X in H14. inv H14. congruence.
+
+ constructor; simplify. unfold Verilog.merge_regs. unfold_merge. rewrite AssocMap.gso.
+ assumption. lia.
+ unfold Verilog.merge_regs. unfold_merge. rewrite AssocMap.gso.
+ assumption. lia.
+
+ + inv MARR. inv CONST. crush.
+
+ unfold Op.eval_addressing in H0.
+ destruct (Archi.ptr64) eqn:ARCHI; crush.
+ rewrite ARCHI in H0. crush.
+
+ unfold check_address_parameter_unsigned in *;
+ unfold check_address_parameter_signed in *; crush.
+
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity.
+ rewrite ZERO in H1. clear ZERO.
+ rewrite Integers.Ptrofs.add_zero_l in H1.
+
+ remember i0 as OFFSET.
+
+ (** Modular preservation proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET mod 4 = 0) as MOD_PRESERVE.
+ { apply Mem.store_valid_access_3 in H1. unfold Mem.valid_access in *. simplify.
+ apply Zdivide_mod. assumption. }
+
+ (** Write bounds proof *)
+ assert (Integers.Ptrofs.unsigned OFFSET < f.(RTL.fn_stacksize)) as WRITE_BOUND_HIGH.
+ { destruct (Integers.Ptrofs.unsigned OFFSET <? f.(RTL.fn_stacksize)) eqn:?EQ; crush; auto.
+ unfold stack_bounds in BOUNDS.
+ exploit (BOUNDS (Integers.Ptrofs.unsigned OFFSET) (Registers.Regmap.get src rs)); auto.
+ crush.
+ replace (Integers.Ptrofs.repr 0) with (Integers.Ptrofs.zero) by reflexivity.
+ small_tac. }
+
+ (** Start of proof proper *)
+ eexists. split.
+ eapply Smallstep.plus_one.
+ eapply HTL.step_module; eauto.
+ econstructor. econstructor. econstructor.
+ eapply Verilog.stmnt_runp_Vnonblock_arr. crush.
+ econstructor. econstructor. econstructor. econstructor.
- (* (** State Lookup *) *)
- (* unfold Verilog.merge_regs. *)
- (* crush. *)
- (* unfold_merge. *)
- (* apply AssocMap.gss. *)
+ all: try constructor; crush.
- (* (** Match states *) *)
- (* econstructor; eauto. *)
+ (** State Lookup *)
+ unfold Verilog.merge_regs.
+ crush.
+ unfold_merge.
+ apply AssocMap.gss.
- (* (** Match assocmaps *) *)
- (* unfold Verilog.merge_regs. crush. unfold_merge. *)
- (* apply regs_lessdef_add_greater. *)
- (* unfold Plt; lia. *)
- (* assumption. *)
+ (** Match states *)
+ econstructor; eauto.
- (* (** States well formed *) *)
- (* unfold state_st_wf. inversion 1. crush. *)
- (* unfold Verilog.merge_regs. *)
- (* unfold_merge. *)
- (* apply AssocMap.gss. *)
+ (** Match assocmaps *)
+ unfold Verilog.merge_regs. crush. unfold_merge.
+ apply regs_lessdef_add_greater.
+ unfold Plt; lia.
+ assumption.
- (* (** Equality proof *) *)
-
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity. *)
- (* inversion MASSOC; revert HeqOFFSET; subst; clear MASSOC; intros HeqOFFSET. *)
-
- (* econstructor. *)
- (* repeat split; crush. *)
- (* unfold HTL.empty_stack. *)
- (* crush. *)
- (* unfold Verilog.merge_arrs. *)
-
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* rewrite AssocMap.gss. *)
- (* erewrite Verilog.merge_arr_empty2. *)
- (* unfold Verilog.arr_assocmap_set. *)
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* rewrite AssocMap.gss. *)
- (* rewrite AssocMap.gss. *)
- (* unfold Verilog.merge_arr. *)
- (* setoid_rewrite H7. *)
- (* reflexivity. *)
-
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* unfold Verilog.merge_arr. *)
- (* unfold Verilog.arr_assocmap_set. *)
- (* rewrite AssocMap.gss. *)
- (* rewrite AssocMap.gss. *)
- (* setoid_rewrite H7. *)
- (* reflexivity. *)
-
- (* rewrite combine_length. *)
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* symmetry. *)
- (* apply list_repeat_len. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite H4. *)
- (* apply list_repeat_len. *)
-
- (* rewrite combine_length. *)
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* apply list_repeat_len. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite H4. *)
- (* apply list_repeat_len. *)
-
- (* remember i0 as OFFSET. *)
- (* destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET). *)
-
- (* erewrite Mem.load_store_same. *)
- (* 2: { rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite e. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* exact H1. *)
- (* apply Integers.Ptrofs.unsigned_range_2. } *)
- (* constructor. *)
- (* erewrite combine_lookup_second. *)
- (* simpl. *)
- (* assert (Ple src (RTL.max_reg_function f)) *)
- (* by (eapply RTL.max_reg_function_use; eauto; simpl; auto); *)
- (* apply H0 in H8. *)
- (* destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; constructor; inv H8; eauto. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite list_repeat_len. auto. *)
-
- (* assert (4 * ptr / 4 = Integers.Ptrofs.unsigned OFFSET / 4) by (f_equal; assumption). *)
- (* rewrite Z.mul_comm in H8. *)
- (* rewrite Z_div_mult in H8; try lia. *)
- (* replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) in H8 by reflexivity. *)
- (* rewrite <- PtrofsExtra.divu_unsigned in H8; unfold_constants; try lia. *)
- (* rewrite H8. rewrite <- offset_expr_ok_3. *)
- (* rewrite array_get_error_set_bound. *)
- (* reflexivity. *)
- (* unfold arr_length, arr_repeat. simpl. *)
- (* rewrite list_repeat_len. lia. *)
-
- (* erewrite Mem.load_store_other with (m1 := m). *)
- (* 2: { exact H1. } *)
- (* 2: { right. *)
- (* rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* simpl. *)
- (* destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto. *)
- (* right. *)
- (* apply ZExtra.mod_0_bounds; try lia. *)
- (* apply ZLib.Z_mod_mult'. *)
- (* rewrite Z2Nat.id in H13; try lia. *)
- (* apply Zmult_lt_compat_r with (p := 4) in H13; try lia. *)
- (* rewrite ZLib.div_mul_undo in H13; try lia. *)
- (* split; try lia. *)
- (* apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia. *)
- (* } *)
-
- (* rewrite <- offset_expr_ok_3. *)
- (* rewrite PtrofsExtra.divu_unsigned; auto; try (unfold_constants; lia). *)
- (* destruct (ptr ==Z Integers.Ptrofs.unsigned OFFSET / 4). *)
- (* apply Z.mul_cancel_r with (p := 4) in e; try lia. *)
- (* rewrite ZLib.div_mul_undo in e; try lia. *)
- (* rewrite combine_lookup_first. *)
- (* eapply H9; eauto. *)
-
- (* rewrite <- array_set_len. *)
- (* unfold arr_repeat. crush. *)
- (* rewrite list_repeat_len. auto. *)
- (* rewrite array_gso. *)
- (* unfold array_get_error. *)
- (* unfold arr_repeat. *)
- (* crush. *)
- (* apply list_repeat_lookup. *)
- (* lia. *)
- (* unfold_constants. *)
- (* intro. *)
- (* apply Z2Nat.inj_iff in H8; try lia. *)
- (* apply Z.div_pos; try lia. *)
- (* apply Integers.Ptrofs.unsigned_range. *)
-
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity. *)
- (* unfold arr_stack_based_pointers. *)
- (* intros. *)
- (* destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET). *)
-
- (* crush. *)
- (* erewrite Mem.load_store_same. *)
- (* 2: { rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite e. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* exact H1. *)
- (* apply Integers.Ptrofs.unsigned_range_2. } *)
- (* crush. *)
- (* destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; try constructor. *)
- (* destruct (Archi.ptr64); try discriminate. *)
- (* pose proof (RSBP src). rewrite EQ_SRC in H0. *)
- (* assumption. *)
-
- (* simpl. *)
- (* erewrite Mem.load_store_other with (m1 := m). *)
- (* 2: { exact H1. } *)
- (* 2: { right. *)
- (* rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite Integers.Ptrofs.unsigned_repr. *)
- (* simpl. *)
- (* destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto. *)
- (* right. *)
- (* apply ZExtra.mod_0_bounds; try lia. *)
- (* apply ZLib.Z_mod_mult'. *)
- (* inv H0. *)
- (* apply Zmult_lt_compat_r with (p := 4) in H11; try lia. *)
- (* rewrite ZLib.div_mul_undo in H11; try lia. *)
- (* split; try lia. *)
- (* apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia. *)
- (* } *)
- (* apply ASBP; assumption. *)
-
- (* unfold stack_bounds in *. intros. *)
- (* simpl. *)
- (* assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity. *)
- (* erewrite Mem.load_store_other with (m1 := m). *)
- (* 2: { exact H1. } *)
- (* 2: { right. right. simpl. *)
- (* rewrite ZERO. *)
- (* rewrite Integers.Ptrofs.add_zero_l. *)
- (* rewrite Integers.Ptrofs.unsigned_repr; crush; try lia. *)
- (* apply ZExtra.mod_0_bounds; crush; try lia. } *)
- (* crush. *)
- (* exploit (BOUNDS ptr); try lia. intros. crush. *)
- (* exploit (BOUNDS ptr v); try lia. intros. *)
- (* inv H0. *)
- (* match goal with | |- ?x = _ => destruct x eqn:?EQ end; try reflexivity. *)
- (* assert (Mem.valid_access m AST.Mint32 sp' *)
- (* (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.add (Integers.Ptrofs.repr 0) *)
- (* (Integers.Ptrofs.repr ptr))) Writable). *)
- (* { pose proof H1. eapply Mem.store_valid_access_2 in H0. *)
- (* exact H0. eapply Mem.store_valid_access_3. eassumption. } *)
- (* pose proof (Mem.valid_access_store m AST.Mint32 sp' *)
- (* (Integers.Ptrofs.unsigned *)
- (* (Integers.Ptrofs.add (Integers.Ptrofs.repr 0) *)
- (* (Integers.Ptrofs.repr ptr))) v). *)
- (* apply X in H0. inv H0. congruence. *)
-
- (* constructor; simplify. unfold Verilog.merge_regs. unfold_merge. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
- (* unfold Verilog.merge_regs. unfold_merge. rewrite AssocMap.gso. *)
- (* assumption. lia. *)
+ (** States well formed *)
+ unfold state_st_wf. inversion 1. crush.
+ unfold Verilog.merge_regs.
+ unfold_merge.
+ apply AssocMap.gss.
+
+ (** Equality proof *)
+
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity.
+ inversion MASSOC; revert HeqOFFSET; subst; clear MASSOC; intros HeqOFFSET.
+
+ econstructor.
+ repeat split; crush.
+ unfold HTL.empty_stack.
+ crush.
+ unfold Verilog.merge_arrs.
+
+ rewrite AssocMap.gcombine by reflexivity.
+ rewrite AssocMap.gss.
+ erewrite Verilog.merge_arr_empty2.
+ unfold Verilog.arr_assocmap_set.
+ rewrite AssocMap.gcombine by reflexivity.
+ rewrite AssocMap.gss.
+ rewrite AssocMap.gss.
+ unfold Verilog.merge_arr.
+ setoid_rewrite H7.
+ reflexivity.
+
+ rewrite AssocMap.gcombine by reflexivity.
+ unfold Verilog.merge_arr.
+ unfold Verilog.arr_assocmap_set.
+ rewrite AssocMap.gss.
+ rewrite AssocMap.gss.
+ setoid_rewrite H7.
+ reflexivity.
+
+ rewrite combine_length.
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ symmetry.
+ apply list_repeat_len.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite H4.
+ apply list_repeat_len.
+
+ rewrite combine_length.
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ apply list_repeat_len.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite H4.
+ apply list_repeat_len.
+
+ remember i0 as OFFSET.
+ destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET).
+
+ erewrite Mem.load_store_same.
+ 2: { rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite e.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ exact H1.
+ apply Integers.Ptrofs.unsigned_range_2. }
+ constructor.
+ erewrite combine_lookup_second.
+ simpl.
+ assert (Ple src (RTL.max_reg_function f))
+ by (eapply RTL.max_reg_function_use; eauto; simpl; auto);
+ apply H0 in H8.
+ destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; constructor; inv H8; eauto.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite list_repeat_len. auto.
+
+ assert (4 * ptr / 4 = Integers.Ptrofs.unsigned OFFSET / 4) by (f_equal; assumption).
+ rewrite Z.mul_comm in H8.
+ rewrite Z_div_mult in H8; try lia.
+ replace 4 with (Integers.Ptrofs.unsigned (Integers.Ptrofs.repr 4)) in H8 by reflexivity.
+ rewrite <- PtrofsExtra.divu_unsigned in H8; unfold_constants; try lia.
+ rewrite H8. rewrite <- offset_expr_ok_3.
+ rewrite array_get_error_set_bound.
+ reflexivity.
+ unfold arr_length, arr_repeat. simpl.
+ rewrite list_repeat_len. lia.
+
+ erewrite Mem.load_store_other with (m1 := m).
+ 2: { exact H1. }
+ 2: { right.
+ rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ simpl.
+ destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto.
+ right.
+ apply ZExtra.mod_0_bounds; try lia.
+ apply ZLib.Z_mod_mult'.
+ rewrite Z2Nat.id in H13; try lia.
+ apply Zmult_lt_compat_r with (p := 4) in H13; try lia.
+ rewrite ZLib.div_mul_undo in H13; try lia.
+ split; try lia.
+ apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia.
+ }
- (* Unshelve. *)
- (* exact tt. *)
- (* exact (Values.Vint (Int.repr 0)). *)
- (* exact tt. *)
- (* exact (Values.Vint (Int.repr 0)). *)
- (* exact tt. *)
- (* exact (Values.Vint (Int.repr 0)). *)
- (* Qed. *) Admitted.
+ rewrite <- offset_expr_ok_3.
+ rewrite PtrofsExtra.divu_unsigned; auto; try (unfold_constants; lia).
+ destruct (ptr ==Z Integers.Ptrofs.unsigned OFFSET / 4).
+ apply Z.mul_cancel_r with (p := 4) in e; try lia.
+ rewrite ZLib.div_mul_undo in e; try lia.
+ rewrite combine_lookup_first.
+ eapply H9; eauto.
+
+ rewrite <- array_set_len.
+ unfold arr_repeat. crush.
+ rewrite list_repeat_len. auto.
+ rewrite array_gso.
+ unfold array_get_error.
+ unfold arr_repeat.
+ crush.
+ apply list_repeat_lookup.
+ lia.
+ unfold_constants.
+ intro.
+ apply Z2Nat.inj_iff in H8; try lia.
+ apply Z.div_pos; try lia.
+ apply Integers.Ptrofs.unsigned_range.
+
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity.
+ unfold arr_stack_based_pointers.
+ intros.
+ destruct (4 * ptr ==Z Integers.Ptrofs.unsigned OFFSET).
+
+ crush.
+ erewrite Mem.load_store_same.
+ 2: { rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite e.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ exact H1.
+ apply Integers.Ptrofs.unsigned_range_2. }
+ crush.
+ destruct (Registers.Regmap.get src rs) eqn:EQ_SRC; try constructor.
+ destruct (Archi.ptr64); try discriminate.
+ pose proof (RSBP src). rewrite EQ_SRC in H0.
+ assumption.
+
+ simpl.
+ erewrite Mem.load_store_other with (m1 := m).
+ 2: { exact H1. }
+ 2: { right.
+ rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite Integers.Ptrofs.unsigned_repr.
+ simpl.
+ destruct (Z_le_gt_dec (4 * ptr + 4) (Integers.Ptrofs.unsigned OFFSET)); eauto.
+ right.
+ apply ZExtra.mod_0_bounds; try lia.
+ apply ZLib.Z_mod_mult'.
+ inv H0.
+ apply Zmult_lt_compat_r with (p := 4) in H11; try lia.
+ rewrite ZLib.div_mul_undo in H11; try lia.
+ split; try lia.
+ apply Z.le_trans with (m := RTL.fn_stacksize f); crush; lia.
+ }
+ apply ASBP; assumption.
+
+ unfold stack_bounds in *. intros.
+ simpl.
+ assert (Integers.Ptrofs.repr 0 = Integers.Ptrofs.zero) as ZERO by reflexivity.
+ erewrite Mem.load_store_other with (m1 := m).
+ 2: { exact H1. }
+ 2: { right. right. simpl.
+ rewrite ZERO.
+ rewrite Integers.Ptrofs.add_zero_l.
+ rewrite Integers.Ptrofs.unsigned_repr; crush; try lia.
+ apply ZExtra.mod_0_bounds; crush; try lia. }
+ crush.
+ exploit (BOUNDS ptr); try lia. intros. crush.
+ exploit (BOUNDS ptr v); try lia. intros.
+ inv H0.
+ match goal with | |- ?x = _ => destruct x eqn:?EQ end; try reflexivity.
+ assert (Mem.valid_access m AST.Mint32 sp'
+ (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.add (Integers.Ptrofs.repr 0)
+ (Integers.Ptrofs.repr ptr))) Writable).
+ { pose proof H1. eapply Mem.store_valid_access_2 in H0.
+ exact H0. eapply Mem.store_valid_access_3. eassumption. }
+ pose proof (Mem.valid_access_store m AST.Mint32 sp'
+ (Integers.Ptrofs.unsigned
+ (Integers.Ptrofs.add (Integers.Ptrofs.repr 0)
+ (Integers.Ptrofs.repr ptr))) v).
+ apply X in H0. inv H0. congruence.
+
+ constructor; simplify. unfold Verilog.merge_regs. unfold_merge. rewrite AssocMap.gso.
+ assumption. lia.
+ unfold Verilog.merge_regs. unfold_merge. rewrite AssocMap.gso.
+ assumption. lia.
+
+ Unshelve.
+ exact tt.
+ exact (Values.Vint (Int.repr 0)).
+ exact tt.
+ exact (Values.Vint (Int.repr 0)).
+ exact tt.
+ exact (Values.Vint (Int.repr 0)).
+ Qed. Admitted.
#[local] Hint Resolve transl_istore_correct : htlproof.
Lemma transl_icond_correct:
diff --git a/src/hls/Predicate.v b/src/hls/Predicate.v
index 7786c5d..8ff61e7 100644
--- a/src/hls/Predicate.v
+++ b/src/hls/Predicate.v
@@ -672,6 +672,32 @@ Fixpoint max_predicate (p: pred_op) : positive :=
| Por a b => Pos.max (max_predicate a) (max_predicate b)
end.
+ Lemma max_predicate_deep_simplify' :
+ forall peq curr r,
+ (r <= max_predicate (deep_simplify' peq curr))%positive ->
+ (r <= max_predicate curr)%positive.
+ Proof.
+ destruct curr; cbn -[deep_simplify']; auto.
+ - intros. unfold deep_simplify' in H.
+ destruct curr1; destruct curr2; try (destruct_match; cbn in *); lia.
+ - intros. unfold deep_simplify' in H.
+ destruct curr1; destruct curr2; try (destruct_match; cbn in *); lia.
+ Qed.
+
+ Lemma max_predicate_deep_simplify :
+ forall peq curr r,
+ (r <= max_predicate (deep_simplify peq curr))%positive ->
+ (r <= max_predicate curr)%positive.
+ Proof.
+ induction curr; try solve [cbn; auto]; cbn -[deep_simplify'] in *.
+ - intros. apply max_predicate_deep_simplify' in H. cbn -[deep_simplify'] in *.
+ assert (HX: (r <= max_predicate (deep_simplify peq curr1))%positive \/ (r <= max_predicate (deep_simplify peq curr2))%positive) by lia.
+ inv HX; [eapply IHcurr1 in H0 | eapply IHcurr2 in H0]; lia.
+ - intros. apply max_predicate_deep_simplify' in H. cbn -[deep_simplify'] in *.
+ assert (HX: (r <= max_predicate (deep_simplify peq curr1))%positive \/ (r <= max_predicate (deep_simplify peq curr2))%positive) by lia.
+ inv HX; [eapply IHcurr1 in H0 | eapply IHcurr2 in H0]; lia.
+ Qed.
+
Definition tseytin (p: pred_op) :
{fm: formula | forall a,
sat_predicate p a = true <-> sat_formula fm a}.