aboutsummaryrefslogtreecommitdiffstats
path: root/src/translation/HTLgenproof.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/translation/HTLgenproof.v')
-rw-r--r--src/translation/HTLgenproof.v367
1 files changed, 324 insertions, 43 deletions
diff --git a/src/translation/HTLgenproof.v b/src/translation/HTLgenproof.v
index 4b7f268..046ae06 100644
--- a/src/translation/HTLgenproof.v
+++ b/src/translation/HTLgenproof.v
@@ -18,9 +18,11 @@
From compcert Require RTL Registers AST Integers.
From compcert Require Import Globalenvs Memory.
-From coqup Require Import Coquplib HTLgenspec HTLgen Value AssocMap.
+From coqup Require Import Coquplib HTLgenspec HTLgen Value AssocMap Array.
From coqup Require HTL Verilog.
+Require Import Lia.
+
Local Open Scope assocmap.
Hint Resolve Smallstep.forward_simulation_plus : htlproof.
@@ -42,44 +44,64 @@ Definition state_st_wf (m : HTL.module) (s : HTL.state) :=
asa!(m.(HTL.mod_st)) = Some (posToValue 32 st).
Hint Unfold state_st_wf : htlproof.
-Inductive match_stacks : list RTL.stackframe -> list HTL.stackframe -> Prop :=
+Inductive match_arrs (m : HTL.module) (f : RTL.function) (sp : Values.val) (mem : mem) :
+ Verilog.assocmap_arr -> Prop :=
+| match_arr : forall asa stack,
+ asa ! (m.(HTL.mod_stk)) = Some stack /\
+ stack.(arr_length) = Z.to_nat (f.(RTL.fn_stacksize) / 4) /\
+ (forall ptr,
+ 0 <= ptr < Z.of_nat m.(HTL.mod_stk_len) ->
+ opt_val_value_lessdef (Mem.loadv AST.Mint32 mem
+ (Values.Val.offset_ptr sp (Integers.Ptrofs.repr (4 * ptr))))
+ (Option.default (NToValue 32 0)
+ (Option.join (array_get_error (Z.to_nat ptr) stack)))) ->
+ match_arrs m f sp mem asa.
+
+Inductive match_stacks (mem : mem) : list RTL.stackframe -> list HTL.stackframe -> Prop :=
| match_stacks_nil :
- match_stacks nil nil
+ match_stacks mem nil nil
| match_stacks_cons :
- forall cs lr r f sp pc rs m assoc
+ forall cs lr r f sp pc rs m asr asa
(TF : tr_module f m)
- (ST: match_stacks cs lr)
- (MA: match_assocmaps f rs assoc),
- match_stacks (RTL.Stackframe r f sp pc rs :: cs)
- (HTL.Stackframe r m pc assoc :: lr).
-
-Inductive match_arrs (m : HTL.module) : RTL.function -> mem -> AssocMap.t (list value) -> Prop :=
-| match_arr : forall mem asa stack sp f sz,
- sz = f.(RTL.fn_stacksize) ->
- asa ! (m.(HTL.mod_stk)) = Some stack ->
- (forall ptr,
- 0 <= ptr < sz ->
- nth_error stack (Z.to_nat ptr) =
- (Coquplib.Option.bind (Mem.loadv AST.Mint32 mem
- (Values.Val.offset_ptr sp (Integers.Ptrofs.repr ptr)))
- valToValue)) ->
- match_arrs m f mem asa.
+ (ST: match_stacks mem cs lr)
+ (MA: match_assocmaps f rs asr)
+ (MARR : match_arrs m f sp mem asa),
+ match_stacks mem (RTL.Stackframe r f sp pc rs :: cs)
+ (HTL.Stackframe r m pc asr asa :: lr).
+
+Definition reg_stack_based_pointers (sp : Values.block) (rs : Registers.Regmap.t Values.val) : Prop :=
+ forall r, match Registers.Regmap.get r rs with
+ | Values.Vptr sp' off => sp' = sp
+ | _ => True
+ end.
+
+Definition arr_stack_based_pointers (spb : Values.block) (m : mem) (stack_length : Z)
+ (sp : Values.val) : Prop :=
+ forall ptr,
+ 0 <= ptr < (stack_length / 4) ->
+ match Mem.loadv AST.Mint32 m (Values.Val.offset_ptr sp (Integers.Ptrofs.repr (4 * ptr))) with
+ | Some (Values.Vptr sp' off) => sp' = spb
+ | _ => True
+ end.
Inductive match_states : RTL.state -> HTL.state -> Prop :=
-| match_state : forall asa asr sf f sp rs mem m st res
+| match_state : forall asa asr sf f sp sp' rs mem m st res
(MASSOC : match_assocmaps f rs asr)
(TF : tr_module f m)
(WF : state_st_wf m (HTL.State res m st asr asa))
- (MS : match_stacks sf res)
- (MA : match_arrs m f mem asa),
+ (MS : match_stacks mem sf res)
+ (MARR : match_arrs m f sp mem asa)
+ (SP : sp = Values.Vptr sp' (Integers.Ptrofs.repr 0))
+ (RSBP: reg_stack_based_pointers sp' rs)
+ (ASBP: arr_stack_based_pointers sp' mem (f.(RTL.fn_stacksize)) sp),
match_states (RTL.State sf f sp st rs mem)
(HTL.State res m st asr asa)
| match_returnstate :
forall
- v v' stack m res
- (MS : match_stacks stack res),
+ v v' stack mem res
+ (MS : match_stacks mem stack res),
val_value_lessdef v v' ->
- match_states (RTL.Returnstate stack v m) (HTL.Returnstate res v')
+ match_states (RTL.Returnstate stack v mem) (HTL.Returnstate res v')
| match_initial_call :
forall f m m0
(TF : tr_module f m),
@@ -129,6 +151,33 @@ Proof.
Qed.
Hint Resolve regs_lessdef_add_match : htlproof.
+Lemma list_combine_none :
+ forall n l,
+ length l = n ->
+ list_combine Verilog.merge_cell (list_repeat None n) l = l.
+Proof.
+ induction n; intros; simplify.
+ - symmetry. apply length_zero_iff_nil. auto.
+ - destruct l; simplify.
+ rewrite list_repeat_cons.
+ simplify. f_equal.
+ eauto.
+Qed.
+
+Lemma combine_none :
+ forall n a,
+ a.(arr_length) = n ->
+ arr_contents (combine Verilog.merge_cell (arr_repeat None n) a) = arr_contents a.
+Proof.
+ intros.
+ unfold combine.
+ simplify.
+
+ rewrite <- (arr_wf a) in H.
+ apply list_combine_none.
+ assumption.
+Qed.
+
(* Need to eventually move posToValue 32 to posToValueAuto, as that has this proof. *)
Lemma assumption_32bit :
forall v,
@@ -297,21 +346,51 @@ Section CORRECTNESS.
eapply HTL.step_module; eauto.
(* processing of state *)
econstructor.
- simpl. trivial.
+ simplify.
econstructor.
econstructor.
econstructor.
+ simplify.
- (* prove stval *)
- unfold merge_assocmap.
- unfold_merge. simpl. apply AssocMap.gss.
+ unfold Verilog.merge_regs.
+ unfold_merge. apply AssocMap.gss.
(* prove match_state *)
rewrite assumption_32bit.
- constructor; auto.
+ econstructor; simplify; eauto.
+
+ unfold Verilog.merge_regs.
unfold_merge. simpl. apply regs_lessdef_add_greater. apply greater_than_max_func.
assumption.
+ unfold Verilog.merge_regs.
unfold state_st_wf. inversion 1. subst. unfold_merge. apply AssocMap.gss.
+
+ (* prove match_arrs *)
+ invert MARR. simplify.
+ unfold HTL.empty_stack. simplify. unfold Verilog.merge_arrs.
+ econstructor.
+ simplify. repeat split.
+
+ rewrite AssocMap.gcombine.
+ 2: { reflexivity. }
+ rewrite AssocMap.gss.
+ unfold Verilog.merge_arr.
+ setoid_rewrite H1.
+ reflexivity.
+
+ rewrite combine_length.
+ unfold arr_repeat. simplify.
+ rewrite list_repeat_len.
+ reflexivity.
+
+ unfold arr_repeat. simplify.
+ rewrite list_repeat_len; auto.
+ intros.
+ erewrite array_get_error_equal.
+ eauto. apply combine_none.
+
+ assumption.
+
- (* Iop *)
(* destruct v eqn:?; *)
(* try ( *)
@@ -390,8 +469,195 @@ Section CORRECTNESS.
(* assumption. *)
admit.
- - admit.
- - admit.
+ Ltac rt :=
+ 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 _ _ = _ |- _ ] => invert H
+ | [ _ : context[match ?x with | _ => _ end] |- _ ] => destruct x
+ end.
+
+ Opaque Z.mul.
+
+ - (* FIXME: Should be able to use the spec to avoid destructing here. *)
+ destruct c, chunk, addr, args; simplify; rt; simplify.
+
+ + admit. (* FIXME: Alignment *)
+
+ + (* FIXME: Why is this degenerate? Should we support this mode? *)
+ unfold Op.eval_addressing in H0.
+ destruct (Archi.ptr64) eqn:ARCHI; simplify.
+ destruct (Registers.Regmap.get r0 rs) eqn:EQr0; discriminate.
+
+ + invert MARR. simplify.
+
+ unfold Op.eval_addressing in H0.
+ destruct (Archi.ptr64) eqn:ARCHI; simplify.
+
+ 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; simplify.
+
+ rewrite ARCHI in H1. simplify.
+ subst.
+
+ eexists. split.
+ eapply Smallstep.plus_one.
+ eapply HTL.step_module; eauto.
+ econstructor. econstructor. econstructor. simplify.
+ econstructor. econstructor. econstructor. econstructor. simplify.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor.
+ econstructor. (* FIXME: Oh dear. *)
+
+ unfold Verilog.arr_assocmap_lookup. simplify. setoid_rewrite H3.
+ f_equal.
+
+ simplify. unfold Verilog.merge_regs.
+ unfold_merge.
+ rewrite AssocMap.gso.
+ apply AssocMap.gss.
+ apply st_greater_than_res.
+
+ simplify. rewrite assumption_32bit.
+ econstructor; simplify; eauto.
+
+ unfold Verilog.merge_regs. unfold_merge.
+ apply regs_lessdef_add_match.
+
+ all: admit.
+
+ + invert MARR. simplify.
+
+ unfold Op.eval_addressing in H0.
+ destruct (Archi.ptr64) eqn:ARCHI; simplify.
+ rewrite ARCHI in H0. simplify.
+
+ (** Here we are assuming that any stack read will be within the bounds
+ of the activation record. *)
+ assert (0 <= Integers.Ptrofs.unsigned i0) as READ_BOUND_LOW by admit.
+ assert (Integers.Ptrofs.unsigned i0 < f.(RTL.fn_stacksize)) as READ_BOUND_HIGH by admit.
+
+ eexists. split.
+ eapply Smallstep.plus_one.
+ eapply HTL.step_module; eauto.
+ econstructor. econstructor. econstructor. simplify.
+ econstructor. econstructor. econstructor. econstructor. simplify.
+
+ unfold Verilog.arr_assocmap_lookup. setoid_rewrite H3.
+ f_equal.
+
+ simplify. unfold Verilog.merge_regs.
+ unfold_merge.
+ rewrite AssocMap.gso.
+ apply AssocMap.gss.
+ apply st_greater_than_res.
+
+ simplify. rewrite assumption_32bit.
+ econstructor; simplify; eauto.
+
+ unfold Verilog.merge_regs. unfold_merge.
+ apply regs_lessdef_add_match.
+
+ (** Equality proof *)
+ (* FIXME: 32-bit issue. *)
+ assert (forall x, valueToNat (ZToValue 32 x) = Z.to_nat x) as VALUE_IDENTITY by admit.
+ rewrite VALUE_IDENTITY.
+ specialize (H5 (Integers.Ptrofs.unsigned i0 / 4)).
+ rewrite Z2Nat.id in H5; try lia.
+ exploit H5; auto; intros.
+ 1: {
+ split.
+ - apply Z.div_pos; lia.
+ - apply Zmult_lt_reg_r with (p := 4); try lia.
+ repeat rewrite ZLib.div_mul_undo; lia.
+ }
+ 2: {
+ assert (0 < RTL.fn_stacksize f) by lia.
+ apply Z.div_pos; lia.
+ }
+ replace (4 * (Integers.Ptrofs.unsigned i0 / 4)) with (Integers.Ptrofs.unsigned i0) in H0.
+ 2: {
+ rewrite Z.mul_comm.
+ rewrite ZLib.div_mul_undo; lia.
+ }
+ rewrite Integers.Ptrofs.repr_unsigned in H0.
+ rewrite H1 in H0.
+ invert H0. assumption.
+
+ apply regs_lessdef_add_greater.
+ apply greater_than_max_func.
+ assumption.
+
+ unfold state_st_wf. inversion 1. simplify.
+ unfold Verilog.merge_regs.
+ unfold_merge. rewrite AssocMap.gso.
+ apply AssocMap.gss.
+ apply st_greater_than_res.
+
+ econstructor.
+ repeat split; simplify.
+ unfold HTL.empty_stack.
+ simplify.
+ unfold Verilog.merge_arrs.
+
+ rewrite AssocMap.gcombine.
+ 2: { reflexivity. }
+ rewrite AssocMap.gss.
+ unfold Verilog.merge_arr.
+ setoid_rewrite H3.
+ reflexivity.
+
+ rewrite combine_length.
+ unfold arr_repeat. simplify.
+ rewrite list_repeat_len.
+ reflexivity.
+
+ unfold arr_repeat. simplify.
+ rewrite list_repeat_len.
+ congruence.
+
+ intros.
+ erewrite array_get_error_equal.
+ eauto. apply combine_none.
+ assumption.
+
+ (* FIXME: RSBP Proof. *)
+
+ - destruct c, chunk, addr, args; simplify; rt; simplify.
+ + admit.
+ + admit.
+ + admit.
+
+ (* + eexists. split. *)
+ (* eapply Smallstep.plus_one. *)
+ (* eapply HTL.step_module; eauto. *)
+ (* econstructor. econstructor. econstructor. simplify. *)
+ + admit.
- eexists. split. apply Smallstep.plus_one.
eapply HTL.step_module; eauto.
@@ -453,8 +719,7 @@ Section CORRECTNESS.
econstructor; simpl; trivial.
constructor.
- constructor.
- constructor.
+ constructor. constructor.
unfold_merge. simpl.
rewrite AssocMap.gso.
@@ -470,7 +735,8 @@ Section CORRECTNESS.
apply AssocMap.gss.
rewrite Events.E0_left. reflexivity.
constructor.
- assumption.
+
+ admit.
constructor.
- econstructor. split.
@@ -499,21 +765,38 @@ Section CORRECTNESS.
apply AssocMap.gss.
rewrite Events.E0_left. trivial.
- constructor. assumption. simpl. inversion MASSOC. subst.
+ constructor.
+ admit.
+
+ simpl. inversion MASSOC. subst.
unfold find_assocmap, AssocMapExt.get_default. rewrite AssocMap.gso.
apply H1. eapply RTL.max_reg_function_use. eauto. simpl; tauto.
apply st_greater_than_res.
- inversion MSTATE; subst. inversion TF; subst.
econstructor. split. apply Smallstep.plus_one.
- eapply HTL.step_call.
+ eapply HTL.step_call. simpl.
constructor. apply regs_lessdef_add_greater.
apply greater_than_max_func.
apply init_reg_assoc_empty. assumption. unfold state_st_wf.
intros. inv H1. apply AssocMap.gss. constructor.
- admit.
+ econstructor; simpl.
+ reflexivity.
+ rewrite AssocMap.gss. reflexivity.
+ intros.
+ destruct (Mem.load AST.Mint32 m' stk
+ (Integers.Ptrofs.unsigned (Integers.Ptrofs.add
+ Integers.Ptrofs.zero
+ (Integers.Ptrofs.repr ptr)))) eqn:LOAD.
+ pose proof Mem.load_alloc_same as LOAD_ALLOC.
+ pose proof H as ALLOC.
+ eapply LOAD_ALLOC in ALLOC.
+ 2: { exact LOAD. }
+ rewrite ALLOC.
+ repeat constructor.
+ constructor.
- inversion MSTATE; subst. inversion MS; subst. econstructor.
split. apply Smallstep.plus_one.
@@ -525,13 +808,11 @@ Section CORRECTNESS.
unfold state_st_wf. intros. inv H. rewrite AssocMap.gso.
rewrite AssocMap.gss. trivial. apply st_greater_than_res.
- admit.
-
Unshelve.
exact (AssocMap.empty value).
exact (AssocMap.empty value).
- admit.
- admit.
+ exact (AssocMap.empty value).
+ exact (AssocMap.empty value).
(* exact (ZToValue 32 0). *)
(* exact (AssocMap.empty value). *)
(* exact (AssocMap.empty value). *)