Library mcertikos.mm.ALInitGenAsm


Require Import Coqlib.
Require Import Errors.
Require Import AST.
Require Import Integers.
Require Import Floats.
Require Import Op.
Require Import Locations.
Require Import AuxStateDataType.
Require Import Events.
Require Import Globalenvs.
Require Import Smallstep.
Require Import Op.
Require Import Values.
Require Import Memory.
Require Import Maps.
Require Import FlatMemory.
Require Import RefinementTactic.
Require Import AuxLemma.
Require Import RealParams.
Require Import Constant.
Require Import AsmImplLemma.
Require Import AsmImplTactic.
Require Import GlobIdent.
Require Import CommonTactic.

Require Import liblayers.compat.CompatLayers.
Require Import liblayers.compcertx.MakeProgram.
Require Import LAsmModuleSem.
Require Import LAsm.
Require Import liblayers.compat.CompatGenSem.
Require Import PrimSemantics.
Require Import Conventions.

Require Import MALInit.
Require Import MContainer.
Require Import ALInitGenAsmSource.
Require Import ALInitGenSpec.

Require Import LRegSet.
Require Import AbstractDataType.
Require Import LAsmModuleSemSpec.

Section ASM_VERIFICATION.

  Local Open Scope string_scope.
  Local Open Scope error_monad_scope.
  Local Open Scope Z_scope.

  Context `{real_params: RealParams}.
  Context `{multi_oracle_prop: MultiOracleProp}.

  Notation LDATA := RData.
  Notation LDATAOps := (cdata (cdata_ops := mcontainer_data_ops) LDATA).

  Section WITHMEM.

    Context `{Hstencil: Stencil}.
    Context `{Hmem: Mem.MemoryModelX}.
    Context `{Hmwd: UseMemWithData mem}.
    Context `{make_program_ops: !MakeProgramOps function Ctypes.type fundef unit}.
    Context `{make_program_prf: !MakeProgram function Ctypes.type fundef unit}.
    Context `{wait_time: WaitTime}.

    Ltac accessors_simpl:=
      match goal with
        | |- exec_storeex _ _ _ _ _ _ _ = _
          unfold exec_storeex, LoadStoreSem1.exec_storeex1;
            simpl; Lregset_simpl_tac;
            match goal with
              | |- context[Asm.exec_store _ _ _ _ _ _ _] ⇒
                unfold Asm.exec_store; simpl;
                Lregset_simpl_tac; lift_trivial
            end
        | |- exec_loadex _ _ _ _ _ _ = _
          unfold exec_loadex, LoadStoreSem1.exec_loadex1;
            simpl; Lregset_simpl_tac;
            match goal with
              | |- context[Asm.exec_load _ _ _ _ _ _ ] ⇒
                unfold Asm.exec_load; simpl;
                Lregset_simpl_tac; lift_trivial
            end
      end.

    Section REL.

      Lemma Hrel:
         MCode_Asm s ge,
          make_globalenv s MCode_Asm mcontainer = ret ge
          ( b, Genv.find_symbol ge release_lock = Some b
                      Genv.find_funct_ptr ge b =
                        Some (External (EF_external release_lock release_lock_sig)))
           get_layer_primitive release_lock mcontainer =
             OK (Some (primcall_release_lock_compatsem release_lock release_lock_spec0)).
      Proof.
        intros.
        assert (Hprim: get_layer_primitive release_lock mcontainer =
                       OK (Some (primcall_release_lock_compatsem release_lock release_lock_spec0)))
          by reflexivity.
        split; try assumption.
        eapply make_globalenv_get_layer_primitive; eauto.
      Qed.

      Lemma Hrel_AT:
         ge s b,
          make_globalenv s (release_lock_AT release_lock_AT_function) mcontainer = ret ge
          find_symbol s release_lock_AT = Some b
          stencil_matches s ge
          Genv.find_funct_ptr ge b = Some (Internal release_lock_AT_function).
      Proof.
        intros.
        assert (Hmodule: get_module_function release_lock_AT (release_lock_AT release_lock_AT_function)
                         = OK (Some release_lock_AT_function)) by
            reflexivity.
        assert (HInternal: make_internal release_lock_AT_function = OK (AST.Internal release_lock_AT_function)) by reflexivity.
        eapply make_globalenv_get_module_function in H; eauto.
        destruct H as [?[Hsymbol ?]].
        inv H1.
        rewrite stencil_matches_symbols in Hsymbol.
        rewrite H0 in Hsymbol. inv Hsymbol.
        assumption.
      Qed.


      Lemma release_lock_AT_code_spec:
         ge (s: stencil) (rs: regset) m labd labd´ b b0 l,
          make_globalenv s (release_lock_AT release_lock_AT_function) mcontainer = ret ge
          find_symbol s release_lock_AT = Some b
          rs PC = Vptr b Int.zero
          release_lock_spec0 ID_AT 0 l labd = Some (labd´) →
          find_symbol s AT_LOC = Some b0
          Mem.loadbytes m b0 0 (maxpage × 8) = Some (ByteList l) →
          asm_invariant (mem := mwd LDATAOps) s rs (m, labd)
          low_level_invariant (Mem.nextblock m) labd
          let rs´ := ((undef_regs (CR ZF :: CR CF :: CR PF :: CR SF :: CR OF
                                      :: IR EAX :: RA :: nil)
                                  (undef_regs (List.map preg_of destroyed_at_call) rs))# RA <- Vundef #PC <- (rs#RA)) in
           m0´ r_,
            lasm_step (release_lock_AT release_lock_AT_function) (mcontainer (Hmwd:= Hmwd) (Hmem:= Hmem))
                      release_lock_AT s rs
                      (m, labd) r_ (m0´, labd´)
             inject_incr (Mem.flat_inj (Mem.nextblock m))
             Memtype.Mem.inject m m0´
             (Mem.nextblock m Mem.nextblock m0´)%positive
             ( l,
                  Val.lessdef (Pregmap.get l rs´)
                              (Pregmap.get l r_)).
      Proof.
        intros until l.
        intros Hge Hsymbol HPC Hspec Hsymbol0 Hloadbyte Hasm Hlow.
        caseEq(Mem.alloc m 0 16).
        intros m1 b1 HALC.
        exploit (make_globalenv_stencil_matches (D:= LDATAOps)); eauto.
        intros Hstencil_matches.
        Local Opaque mcontainer.
        assert (Hblock: Ple (Genv.genv_next ge) b1 Plt b1 (Mem.nextblock m1)).
        {
          erewrite Mem.nextblock_alloc; eauto.
          apply Mem.alloc_result in HALC.
          rewrite HALC.
          inv Hasm. inv inv_inject_neutral.
          inv Hstencil_matches.
          rewrite stencil_matches_genv_next.
          lift_unfold.
          split; xomega.
        }

        
        exploit Hrel; eauto.
        intros [[b_acq [Hacq_symbol Hacq_fun]] prim_acq].

        specialize (Mem.valid_access_alloc_same _ _ _ _ _ HALC). intros.
        assert (HV1: Mem.valid_access m1 Mint32 b1 8 Freeable).
        {
          eapply H; auto; simpl; try omega.
           2; omega.
        }
        eapply Mem.valid_access_implies with (p2:= Writable) in HV1; [|constructor].
        destruct (Mem.valid_access_store _ _ _ _ (rs ESP) HV1) as [m2 HST1].

        assert (HV2: Mem.valid_access m2 Mint32 b1 12 Freeable).
        {
          eapply Mem.store_valid_access_1; eauto.
          eapply H; auto; simpl; try omega.
           3; omega.
        }
        eapply Mem.valid_access_implies with (p2:= Writable) in HV2; [|constructor].
        destruct (Mem.valid_access_store _ _ _ _ (rs RA) HV2) as [m3 HST2].

        assert (HV3: Mem.valid_access m3 Mint32 b1 0 Freeable).
        {
          eapply Mem.store_valid_access_1; eauto.
          eapply Mem.store_valid_access_1; eauto.
          eapply H; auto; simpl; try omega.
          apply Zdivide_0.
        }
        eapply Mem.valid_access_implies with (p2:= Writable) in HV3; [|constructor].
        destruct (Mem.valid_access_store _ _ _ _ (Vint (Int.repr ID_AT)) HV3) as [m4 HST3].

        assert (HV4: Mem.valid_access m4 Mint32 b1 4 Freeable).
        {
          eapply Mem.store_valid_access_1; eauto.
          eapply Mem.store_valid_access_1; eauto.
          eapply Mem.store_valid_access_1; eauto.
          eapply H; auto; simpl; try omega.
          apply Zdivide_refl.
        }
        eapply Mem.valid_access_implies with (p2:= Writable) in HV4; [|constructor].
        destruct (Mem.valid_access_store _ _ _ _ (Vint (Int.zero)) HV4) as [m5 HST4].

        assert (HFB: b2 delta, Mem.flat_inj (Mem.nextblock m) b2 Some (b1, delta)).
        {
          intros. unfold Mem.flat_inj.
          red; intros.
          destruct (plt b2 (Mem.nextblock m)). inv H0.
          rewrite (Mem.alloc_result _ _ _ _ _ HALC) in p.
          xomega. inv H0.
        }

        assert (Hinject: Mem.inject (Mem.flat_inj (Mem.nextblock m)) m m5).
        {
          repeat (eapply Mem.store_outside_inject; [ | | eassumption]
                  ; [|intros b2 delta; intros; specialize (HFB b2 delta); apply HFB; trivial]).
          eapply Mem.alloc_right_inject; eauto 1.
          inv Hasm. inv inv_inject_neutral.
          apply Mem.neutral_inject; trivial.
        }
        assert (Hnextblock5: Mem.nextblock m5 = Mem.nextblock m1).
        {
          rewrite (Mem.nextblock_store _ _ _ _ _ _ HST4); trivial.
          rewrite (Mem.nextblock_store _ _ _ _ _ _ HST3); trivial.
          rewrite (Mem.nextblock_store _ _ _ _ _ _ HST2); trivial.
          rewrite (Mem.nextblock_store _ _ _ _ _ _ HST1); trivial.
        }
        assert (HV5: Mem.range_perm m5 b1 0 16 Cur Freeable).
        {
          unfold Mem.range_perm. intros.
          repeat (eapply Mem.perm_store_1; [eassumption|]).
          eapply Mem.perm_alloc_2; eauto.
        }
        
        destruct (Mem.range_perm_free _ _ _ _ HV5) as [m6 HFree].
        assert (HUCTX: ikern labd = true
                        ihost labd = true).
        {
          revert Hspec. clear.
          unfold release_lock_spec. intros. subdestruct. auto.
        }
        destruct HUCTX as [ik ih].
        exploit Hrel_AT; eauto 2. intros Hfunct.

        assert (Hneq: b1 b0).
        {
          red; intros; subst.
          specialize (genv_symb_range _ _ _ Hsymbol0).
          intro HB.
          inv Hasm. inv inv_inject_neutral.
          exploit Mem.alloc_result; eauto.
          intros; subst.
          revert HB inv_mem_valid.
          clear. intros. lift_unfold.
          xomega.
        }

        rewrite (Lregset_rewrite rs).
        refine_split´.
        rewrite HPC.
        econstructor; eauto.

        one_step_forward´.
        Lregset_simpl_tac.
        lift_trivial.
        unfold set; simpl.
        rewrite HALC. simpl.
        change (Int.unsigned (Int.add Int.zero (Int.repr 8))) with 8.
        change (Int.unsigned (Int.add Int.zero (Int.repr 12))) with 12.
        rewrite HST1. simpl.
        rewrite HST2.
        reflexivity.
        Lregset_simpl_tac.

        one_step_forward´.
        Lregset_simpl_tac.

        Local Transparent mcontainer.

        one_step_forward´.
        unfold exec_storeex, LoadStoreSem1.exec_storeex1.
        simpl; Lregset_simpl_tac. rewrite ik, ih.
        unfold Asm.exec_store; simpl.
        Lregset_simpl_tac. lift_trivial.
        change (Int.unsigned (Int.add Int.zero (Int.add Int.zero Int.zero))) with 0.
        simpl in HST3.
        rewrite HST3. reflexivity.
        unfold set; simpl.

        one_step_forward´.
        Lregset_simpl_tac.

        one_step_forward´.
        unfold exec_storeex, LoadStoreSem1.exec_storeex1.
        simpl; Lregset_simpl_tac. rewrite ik, ih.
        unfold Asm.exec_store; simpl.
        Lregset_simpl_tac. lift_trivial.
        change (Int.unsigned (Int.add Int.zero (Int.add Int.zero (Int.repr 4)))) with 4.
        simpl in HST4.
        rewrite HST4. reflexivity.
        unfold set; simpl.

        one_step_forward´.
        unfold symbol_offset. unfold fundef.
        rewrite Hacq_symbol.
        Lregset_simpl_tac.

        econstructor; eauto.
        eapply (LAsm.exec_step_prim_call _ b_acq); eauto 1.
        econstructor; eauto 1.
        instantiate (4:= release_lock).
        change positive with ident in ×.
        rewrite prim_acq.
        refine_split´; try reflexivity.
        econstructor; eauto. simpl.
        intros; subst. simpl in Hspec.
        change 0 with (Int.unsigned (Int.zero)) in Hspec.
        {
          econstructor; eauto.
          {
            change (Int.unsigned Int.zero) with 0.
            simpl. trivial.
          }
          {
            erewrite Mem.loadbytes_store_other; try eapply HST4; [| left; auto].
            erewrite Mem.loadbytes_store_other; try eapply HST3; [| left; auto].
            erewrite Mem.loadbytes_store_other; try eapply HST2; [| left; auto].
            erewrite Mem.loadbytes_store_other; try eapply HST1; [| left; auto].
            erewrite Mem.loadbytes_alloc_unchanged; eauto.
            eapply Mem.loadbytes_range_perm in Hloadbyte; eauto.
            eapply (Mem.perm_valid_block _ _ 0); eauto.
          }
          constructor; eauto.
          {
            eapply extcall_arg_stack; eauto.
            simpl.
            change (Int.unsigned (Int.add Int.zero (Int.repr 0))) with 0.
            erewrite Mem.load_store_other; eauto; [|simpl; right; left; omega].
            erewrite Mem.load_store_same; eauto. trivial.
          }
          constructor; eauto.
          {
            eapply extcall_arg_stack; eauto.
            simpl.
            change (Int.unsigned (Int.add Int.zero (Int.repr 4))) with 4.
            erewrite Mem.load_store_same; eauto. trivial.
          }
          constructor; eauto.
          {
            inv Hstencil_matches.
            erewrite <- stencil_matches_symbols; eauto.
          }
          { reflexivity. }
        }
        Lregset_simpl_tac.

        one_step_forward´.
        lift_trivial.
        change (Int.unsigned (Int.add Int.zero (Int.repr 12))) with 12.
        change (Int.unsigned (Int.add Int.zero (Int.repr 8))) with 8.
        unfold set; simpl.
        assert (HLD1: Mem.load Mint32 m5 b1 12 = Some (rs RA)).
        {
          erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
          erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
          erewrite Mem.load_store_same; eauto.
          erewrite register_type_load_result. trivial.
          inv Hasm.
          apply inv_reg_wt.
        }
        rewrite HLD1.

        assert (HLD2: Mem.load Mint32 m5 b1 8 = Some (rs ESP)).
        {
          erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
          erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
          erewrite Mem.load_store_other; eauto; simpl; [| right; left; omega].
          erewrite Mem.load_store_same; eauto.
          erewrite register_type_load_result. trivial.
          inv Hasm.
          apply inv_reg_wt.
        }
        rewrite HLD2.
        rewrite HFree. reflexivity.
        Lregset_simpl_tac.

        one_step_forward´.
        Lregset_simpl_tac.
        constructor.

        - reflexivity.
        - reflexivity.
        - eapply Mem.free_right_inject; eauto 1.
          intros; specialize (HFB b2 delta); apply HFB; trivial.
        - rewrite (Mem.nextblock_free _ _ _ _ _ HFree); trivial.
          rewrite Hnextblock5.
          rewrite (Mem.nextblock_alloc _ _ _ _ _ HALC); eauto.
          clear. abstract xomega.
        - subst rs´.
          intros reg.
          unfold Lregset_fold; simpl.
          repeat (rewrite Pregmap.gsspec).
          simpl_destruct_reg.
          exploit reg_false; try eassumption.
          intros HF. inv HF.
      Qed.

      Lemma release_lock_AT_code_correct:
        asm_spec_le (release_lock_AT release_lock_AT_spec_low)
                    (release_lock_AT release_lock_AT_function mcontainer).
      Proof.
        eapply asm_sem_intro; try reflexivity; try (simpl; trivial; fail).
        intros. inv H.
        eapply make_program_make_globalenv in H0.
        exploit (make_globalenv_stencil_matches (D:= LDATAOps)); eauto.
        intros Hstencil_matches.
        assert(Hfun: Genv.find_funct_ptr (Genv.globalenv p) b = Some (Internal release_lock_AT_function)).
        {
          assert (Hmodule: get_module_function release_lock_AT (release_lock_AT release_lock_AT_function)
                           = OK (Some release_lock_AT_function)) by
              reflexivity.
          assert (HInternal: make_internal release_lock_AT_function = OK (AST.Internal release_lock_AT_function)) by reflexivity.
          eapply make_globalenv_get_module_function in H0; eauto.
          destruct H0 as [?[Hsymbol´ ?]].
          inv Hstencil_matches.
          rewrite stencil_matches_symbols in Hsymbol´.
          rewrite Hsymbol_PC in Hsymbol´.
          inv Hsymbol´.
          assumption.
        }
        simpl in Hsize. inv Hsize.
        exploit release_lock_AT_code_spec; eauto 2.
        intros ( & m0´ & r_ & Hstep & Hincr & Hv & Hnext & HV).
        refine_split´; try eassumption.
        - simpl. lift_trivial.
          reflexivity.
        - lift_unfold. split; trivial.
      Qed.

    End REL.

    Section ACQ.

      Lemma Hacq:
         MCode_Asm s ge,
          make_globalenv s MCode_Asm mcontainer = ret ge
          ( b, Genv.find_symbol ge acquire_lock = Some b
                      Genv.find_funct_ptr ge b =
                        Some (External (EF_external acquire_lock acquire_lock_sig)))
           get_layer_primitive acquire_lock mcontainer =
             OK (Some (primcall_acquire_lock_compatsem acquire_lock_spec0)).
      Proof.
        intros.
        assert (Hprim: get_layer_primitive acquire_lock mcontainer =
                       OK (Some (primcall_acquire_lock_compatsem acquire_lock_spec0)))
          by reflexivity.
        split; try assumption.
        eapply make_globalenv_get_layer_primitive; eauto.
      Qed.

      Lemma Hacq_AT:
         ge s b,
          make_globalenv s (acquire_lock_AT acquire_lock_AT_function) mcontainer = ret ge
          find_symbol s acquire_lock_AT = Some b
          stencil_matches s ge
          Genv.find_funct_ptr ge b = Some (Internal acquire_lock_AT_function).
      Proof.
        intros.
        assert (Hmodule: get_module_function acquire_lock_AT (acquire_lock_AT acquire_lock_AT_function)
                         = OK (Some acquire_lock_AT_function)) by
            reflexivity.
        assert (HInternal: make_internal acquire_lock_AT_function = OK (AST.Internal acquire_lock_AT_function)) by reflexivity.
        eapply make_globalenv_get_module_function in H; eauto.
        destruct H as [?[Hsymbol ?]].
        inv H1.
        rewrite stencil_matches_symbols in Hsymbol.
        rewrite H0 in Hsymbol. inv Hsymbol.
        assumption.
      Qed.

      Lemma id_eq:
         labd labd´ id l,
          acquire_lock_spec0 (Z.of_nat local_lock_bound) ID_AT 0 labd = Some (labd´, id, l)
          id = AT_LOC.
      Proof.
        intros. unfold acquire_lock_spec in ×.
        subdestruct; inv H. trivial.
      Qed.

      Lemma acquire_lock_AT_code_spec:
         ge (s: stencil) (rs: regset) m labd labd´ b b0 id l,
          make_globalenv s (acquire_lock_AT acquire_lock_AT_function) mcontainer = ret ge
          find_symbol s acquire_lock_AT = Some b
          rs PC = Vptr b Int.zero
          acquire_lock_spec0 (Z.of_nat local_lock_bound) ID_AT 0 labd = Some (labd´, id, l)
          find_symbol s AT_LOC = Some b0
          match l with
            | Some Mem.storebytes m b0 0 (ByteList ) = Some
            | _ = m
          end
          asm_invariant (mem := mwd LDATAOps) s rs (m, labd)
          low_level_invariant (Mem.nextblock m) labd
          let rs´ := ((undef_regs (CR ZF :: CR CF :: CR PF :: CR SF :: CR OF
                                      :: IR EAX :: RA :: nil)
                                  (undef_regs (List.map preg_of destroyed_at_call) rs))# RA <- Vundef #PC <- (rs#RA)) in
           m0´ r_,
            lasm_step (acquire_lock_AT acquire_lock_AT_function) (mcontainer (Hmwd:= Hmwd) (Hmem:= Hmem))
                      acquire_lock_AT s rs
                      (m, labd) r_ (m0´, labd´)
             inject_incr (Mem.flat_inj (Mem.nextblock m))
             Memtype.Mem.inject m0´
             (Mem.nextblock Mem.nextblock m0´)%positive
             ( l,
                  Val.lessdef (Pregmap.get l rs´)
                              (Pregmap.get l r_)).
      Proof.
        intros until l.
        intros Hge Hsymbol HPC Hspec Hsymbol0 Hstorebyte Hasm Hlow.
        caseEq(Mem.alloc m 0 20).
        intros m1 b1 HALC.
        exploit (make_globalenv_stencil_matches (D:= LDATAOps)); eauto.
        intros Hstencil_matches.
        Local Opaque mcontainer.
        assert (Hblock: Ple (Genv.genv_next ge) b1 Plt b1 (Mem.nextblock m1)).
        {
          erewrite Mem.nextblock_alloc; eauto.
          apply Mem.alloc_result in HALC.
          rewrite HALC.
          inv Hasm. inv inv_inject_neutral.
          inv Hstencil_matches.
          rewrite stencil_matches_genv_next.
          lift_unfold.
          split; xomega.
        }

        
        exploit Hacq; eauto.
        intros [[b_acq [Hacq_symbol Hacq_fun]] prim_acq].

        specialize (Mem.valid_access_alloc_same _ _ _ _ _ HALC). intros.
        assert (HV1: Mem.valid_access m1 Mint32 b1 12 Freeable).
        {
          eapply H; auto; simpl; try omega.
           3; omega.
        }
        eapply Mem.valid_access_implies with (p2:= Writable) in HV1; [|constructor].
        destruct (Mem.valid_access_store _ _ _ _ (rs ESP) HV1) as [m2 HST1].

        assert (HV2: Mem.valid_access m2 Mint32 b1 16 Freeable).
        {
          eapply Mem.store_valid_access_1; eauto.
          eapply H; auto; simpl; try omega.
           4; omega.
        }
        eapply Mem.valid_access_implies with (p2:= Writable) in HV2; [|constructor].
        destruct (Mem.valid_access_store _ _ _ _ (rs RA) HV2) as [m3 HST2].

        assert (HV3: Mem.valid_access m3 Mint32 b1 0 Freeable).
        {
          eapply Mem.store_valid_access_1; eauto.
          eapply Mem.store_valid_access_1; eauto.
          eapply H; auto; simpl; try omega.
          apply Zdivide_0.
        }
        eapply Mem.valid_access_implies with (p2:= Writable) in HV3; [|constructor].
        destruct (Mem.valid_access_store _ _ _ _ (Vint (Int.repr (Z.of_nat local_lock_bound))) HV3) as [m4 HST3].

        assert (HV4: Mem.valid_access m4 Mint32 b1 4 Freeable).
        {
          eapply Mem.store_valid_access_1; eauto.
          eapply Mem.store_valid_access_1; eauto.
          eapply Mem.store_valid_access_1; eauto.
          eapply H; auto; simpl; try omega.
          apply Zdivide_refl.
        }
        eapply Mem.valid_access_implies with (p2:= Writable) in HV4; [|constructor].
        destruct (Mem.valid_access_store _ _ _ _ (Vint (Int.repr ID_AT)) HV4) as [m5 HST4].

        assert (HV5: Mem.valid_access m5 Mint32 b1 8 Freeable).
        {
          eapply Mem.store_valid_access_1; eauto.
          eapply Mem.store_valid_access_1; eauto.
          eapply Mem.store_valid_access_1; eauto.
          eapply Mem.store_valid_access_1; eauto.
          eapply H; auto; simpl; try omega.
           2; omega.
        }
        eapply Mem.valid_access_implies with (p2:= Writable) in HV5; [|constructor].
        destruct (Mem.valid_access_store _ _ _ _ (Vint (Int.zero)) HV5) as [m6 HST5].

        assert (HFB: b2 delta, Mem.flat_inj (Mem.nextblock m) b2 Some (b1, delta)).
        {
          intros. unfold Mem.flat_inj.
          red; intros.
          destruct (plt b2 (Mem.nextblock m)). inv H0.
          rewrite (Mem.alloc_result _ _ _ _ _ HALC) in p.
          xomega. inv H0.
        }

        assert (Hinject: Mem.inject (Mem.flat_inj (Mem.nextblock m)) m m6).
        {
          repeat (eapply Mem.storebytes_outside_inject; [ | | eassumption]
                  ; [|intros b2 delta; intros; specialize (HFB b2 delta); apply HFB; trivial]).
          repeat (eapply Mem.store_outside_inject; [ | | eassumption]
                  ; [|intros b2 delta; intros; specialize (HFB b2 delta); apply HFB; trivial]).
          eapply Mem.alloc_right_inject; eauto 1.
          inv Hasm. inv inv_inject_neutral.
          apply Mem.neutral_inject; trivial.
        }
        assert (HF: m7,
                      match l with
                        | Some Mem.storebytes m6 b0 0 (ByteList ) = Some m7
                        | Nonem7 = m6
                      end
                       Mem.inject (Mem.flat_inj (Mem.nextblock m)) m7
                       Mem.nextblock m7 = Mem.nextblock m1
                       Mem.range_perm m7 b1 0 20 Cur Freeable).
        {
          destruct l; subst.
          - exploit Mem.storebytes_mapped_inject; eauto.
            {
              exploit stencil_find_symbol_inject´; eauto.
              intros HF.
              inv Hasm. inv inv_inject_neutral.
              lift_unfold.
              eapply flat_inj_inject_incr; eauto.
            }
            {
              eapply list_forall2_bytelist_inject.
            }
            simpl.
            intros (m7 & HSTB & Hinject´).
             m7.
            refine_split´; trivial.
            + erewrite (Mem.nextblock_storebytes _ _ _ _ _ HSTB); eauto.
              rewrite (Mem.nextblock_store _ _ _ _ _ _ HST5); trivial.
              rewrite (Mem.nextblock_store _ _ _ _ _ _ HST4); trivial.
              rewrite (Mem.nextblock_store _ _ _ _ _ _ HST3); trivial.
              rewrite (Mem.nextblock_store _ _ _ _ _ _ HST2); trivial.
              rewrite (Mem.nextblock_store _ _ _ _ _ _ HST1); trivial.
            + unfold Mem.range_perm. intros.
              eapply Mem.perm_storebytes_1; eauto.
              repeat (eapply Mem.perm_store_1; [eassumption|]).
              eapply Mem.perm_alloc_2; eauto.
          - refine_split´; trivial.
            + rewrite (Mem.nextblock_store _ _ _ _ _ _ HST5); trivial.
              rewrite (Mem.nextblock_store _ _ _ _ _ _ HST4); trivial.
              rewrite (Mem.nextblock_store _ _ _ _ _ _ HST3); trivial.
              rewrite (Mem.nextblock_store _ _ _ _ _ _ HST2); trivial.
              rewrite (Mem.nextblock_store _ _ _ _ _ _ HST1); trivial.
            + unfold Mem.range_perm. intros.
              repeat (eapply Mem.perm_store_1; [eassumption|]).
              eapply Mem.perm_alloc_2; eauto.
        }
        destruct HF as (m7 & HSTB & Hinject´ & Hnextblock7 & HV7).
        destruct (Mem.range_perm_free _ _ _ _ HV7) as [m8 HFree].
        assert (HUCTX: ikern labd = true
                        ihost labd = true).
        {
          revert Hspec. clear.
          unfold acquire_lock_spec. intros. subdestruct. auto.
        }
        destruct HUCTX as [ik ih].

        exploit Hacq_AT; eauto 2. intros Hfunct.

        rewrite (Lregset_rewrite rs).
        refine_split´.
        rewrite HPC.
        econstructor; eauto.

        one_step_forward´.
        Lregset_simpl_tac.
        lift_trivial.
        unfold set; simpl.
        rewrite HALC. simpl.
        change (Int.unsigned (Int.add Int.zero (Int.repr 16))) with 16.
        change (Int.unsigned (Int.add Int.zero (Int.repr 12))) with 12.
        rewrite HST1. simpl.
        rewrite HST2.
        reflexivity.
        Lregset_simpl_tac.

        one_step_forward´.
        Lregset_simpl_tac.

        Local Transparent mcontainer.

        one_step_forward´.
        unfold exec_storeex, LoadStoreSem1.exec_storeex1.
        simpl; Lregset_simpl_tac. rewrite ik, ih.
        unfold Asm.exec_store; simpl.
        Lregset_simpl_tac. lift_trivial.
        change (Int.unsigned (Int.add Int.zero (Int.add Int.zero Int.zero))) with 0.
        simpl in HST3.
        rewrite HST3. reflexivity.
        unfold set; simpl.

        one_step_forward´.
        Lregset_simpl_tac.

        one_step_forward´.
        unfold exec_storeex, LoadStoreSem1.exec_storeex1.
        simpl; Lregset_simpl_tac. rewrite ik, ih.
        unfold Asm.exec_store; simpl.
        Lregset_simpl_tac. lift_trivial.
        change (Int.unsigned (Int.add Int.zero (Int.add Int.zero (Int.repr 4)))) with 4.
        simpl in HST4.
        rewrite HST4. reflexivity.
        unfold set; simpl.

        one_step_forward´.
        Lregset_simpl_tac.

        one_step_forward´.
        unfold exec_storeex, LoadStoreSem1.exec_storeex1.
        simpl; Lregset_simpl_tac. rewrite ik, ih.
        unfold Asm.exec_store; simpl.
        Lregset_simpl_tac. lift_trivial.
        change (Int.unsigned (Int.add Int.zero (Int.add Int.zero (Int.repr 8)))) with 8.
        simpl in HST5.
        rewrite HST5. reflexivity.
        unfold set; simpl.

        one_step_forward´.
        unfold symbol_offset. unfold fundef.
        rewrite Hacq_symbol.
        Lregset_simpl_tac.

        econstructor; eauto.
        eapply (LAsm.exec_step_prim_call _ b_acq); eauto 1.
        econstructor; eauto 1.
        instantiate (4:= acquire_lock).
        change positive with ident in ×.
        rewrite prim_acq.
        refine_split´; try reflexivity.
        econstructor; eauto. simpl.
        exploit id_eq; eauto.
        intros; subst. simpl in Hspec.
        change 0 with (Int.unsigned (Int.zero)) in Hspec.
        change 10 with (Int.unsigned (Int.repr 10)) in Hspec.
        {
          econstructor; eauto.
          constructor; eauto.
          {
            eapply extcall_arg_stack; eauto.
            simpl.
            change (Int.unsigned (Int.add Int.zero (Int.repr 0))) with 0.
            erewrite Mem.load_store_other; eauto; [|simpl; right; left; omega].
            erewrite Mem.load_store_other; eauto; [|simpl; right; left; omega].
            erewrite Mem.load_store_same; eauto. trivial.
          }
          constructor; eauto.
          {
            eapply extcall_arg_stack; eauto.
            simpl.
            change (Int.unsigned (Int.add Int.zero (Int.repr 4))) with 4.
            erewrite Mem.load_store_other; eauto; [|simpl; right; left; omega].
            erewrite Mem.load_store_same; eauto. trivial.
          }
          constructor; eauto.
          {
            eapply extcall_arg_stack; eauto.
            simpl.
            change (Int.unsigned (Int.add Int.zero (Int.repr 8))) with 8.
            erewrite Mem.load_store_same; eauto. trivial.
          }
          constructor; eauto.
          {
            inv Hstencil_matches.
            erewrite <- stencil_matches_symbols; eauto.
          }
          { reflexivity. }
        }
        Lregset_simpl_tac.

        one_step_forward´.
        lift_trivial.
        change (Int.unsigned (Int.add Int.zero (Int.repr 12))) with 12.
        change (Int.unsigned (Int.add Int.zero (Int.repr 16))) with 16.
        unfold set; simpl.
        assert (Hneq: b1 b0).
        {
          red; intros; subst.
          specialize (genv_symb_range _ _ _ Hsymbol0).
          intro HB.
          inv Hasm. inv inv_inject_neutral.
          exploit Mem.alloc_result; eauto.
          intros; subst.
          revert HB inv_mem_valid.
          clear. intros. lift_unfold.
          xomega.
        }
        assert (HLD1: Mem.load Mint32 m7 b1 16 = Some (rs RA)).
        {
          assert (HLD1: Mem.load Mint32 m6 b1 16 = Some (rs RA)).
          {
            erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
            erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
            erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
            erewrite Mem.load_store_same; eauto.
            erewrite register_type_load_result. trivial.
            inv Hasm.
            apply inv_reg_wt.
          }
          destruct l; subst; trivial.
          erewrite Mem.load_storebytes_other; eauto; simpl.
        }
        rewrite HLD1.

        assert (HLD2: Mem.load Mint32 m7 b1 12 = Some (rs ESP)).
        {
          assert (HLD2: Mem.load Mint32 m6 b1 12 = Some (rs ESP)).
          {
            erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
            erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
            erewrite Mem.load_store_other; eauto; simpl; [| right; right; omega].
            erewrite Mem.load_store_other; eauto; simpl; [| right; left; omega].
            erewrite Mem.load_store_same; eauto.
            erewrite register_type_load_result. trivial.
            inv Hasm.
            apply inv_reg_wt.
          }
          destruct l; subst; trivial.
          erewrite Mem.load_storebytes_other; eauto; simpl.
        }
        rewrite HLD2.

        rewrite HFree. reflexivity.
        Lregset_simpl_tac.

        one_step_forward´.
        Lregset_simpl_tac.
        constructor.

        - reflexivity.
        - reflexivity.
        - eapply Mem.free_right_inject; eauto 1.
          intros; specialize (HFB b2 delta); apply HFB; trivial.
        - rewrite (Mem.nextblock_free _ _ _ _ _ HFree); trivial.
          rewrite Hnextblock7.
          rewrite (Mem.nextblock_alloc _ _ _ _ _ HALC); eauto.
          destruct l; subst.
          + erewrite (Mem.nextblock_storebytes _ _ _ _ _ Hstorebyte); eauto.
            clear. abstract xomega.
          + clear. abstract xomega.
        - subst rs´.
          intros reg.
          unfold Lregset_fold; simpl.
          repeat (rewrite Pregmap.gsspec).
          simpl_destruct_reg.
          exploit reg_false; try eassumption.
          intros HF. inv HF.
      Qed.

      Lemma acquire_lock_AT_code_correct:
        asm_spec_le (acquire_lock_AT acquire_lock_AT_spec_low)
                    (acquire_lock_AT acquire_lock_AT_function mcontainer).
      Proof.
        eapply asm_sem_intro; try reflexivity; try (simpl; trivial; fail).
        intros. inv H.
        eapply make_program_make_globalenv in H0.
        exploit (make_globalenv_stencil_matches (D:= LDATAOps)); eauto.
        intros Hstencil_matches.
        assert(Hfun: Genv.find_funct_ptr (Genv.globalenv p) b = Some (Internal acquire_lock_AT_function)).
        {
          assert (Hmodule: get_module_function acquire_lock_AT (acquire_lock_AT acquire_lock_AT_function)
                           = OK (Some acquire_lock_AT_function)) by
              reflexivity.
          assert (HInternal: make_internal acquire_lock_AT_function = OK (AST.Internal acquire_lock_AT_function)) by reflexivity.
          eapply make_globalenv_get_module_function in H0; eauto.
          destruct H0 as [?[Hsymbol´ ?]].
          inv Hstencil_matches.
          rewrite stencil_matches_symbols in Hsymbol´.
          rewrite Hsymbol_PC in Hsymbol´.
          inv Hsymbol´.
          assumption.
        }
        exploit id_eq; eauto. intros; subst.
        exploit acquire_lock_AT_code_spec; eauto 2.
        intros ( & m0´ & r_ & Hstep & Hincr & Hv & Hnext & HV).
        refine_split´; try eassumption.
        - simpl; lift_trivial.
          destruct l; subst.
          + exploit Mem.nextblock_storebytes; eauto.
            intros He. rewrite He. reflexivity.
          + reflexivity.
        - simpl; lift_trivial.
          destruct l; subst.
          + exploit Mem.nextblock_storebytes; try eassumption.
            intros He. rewrite He. eassumption.
          + eassumption.
        - lift_unfold. split; trivial.
      Qed.

    End ACQ.

  End WITHMEM.

End ASM_VERIFICATION.