(* *********************************************************************)
(*                                                                     *)
(*            The CertiKOS Certified Kit Operating System              *)
(*                                                                     *)
(*                   The FLINT Group, Yale University                  *)
(*                                                                     *)
(*  Copyright The FLINT Group, Yale University.  All rights reserved.  *)
(*  This file is distributed under the terms of the Yale University    *)
(*  Non-Commercial License Agreement.                                  *)
(*                                                                     *)
(* *********************************************************************)
(* *********************************************************************)
(*                                                                     *)
(*              Layers of VMM                                          *)
(*                                                                     *)
(*          Refinement Proof for PQueueInit                            *)
(*                                                                     *)
(*          Ronghui Gu <ronghui.gu@yale.edu>                           *)
(*                                                                     *)
(*          Yale Flint Group                                           *)
(*                                                                     *)
(* *********************************************************************)
Require Import Coqlib.
Require Import Errors.
Require Import AST.
Require Import Integers.
Require Import Floats.
Require Import Op.
Require Import Asm.
Require Import Events.
Require Import Globalenvs.
Require Import Smallstep.
Require Import Values.
Require Import Memory.
Require Import Maps.
Require Import CommonTactic.
Require Import AuxLemma.
Require Import FlatMemory.
Require Import AuxStateDataType.
Require Import Constant.
Require Import GlobIdent.
Require Import RealParams.
Require Import LoadStoreSem2.
Require Import AsmImplLemma.
Require Import GenSem.
Require Import RefinementTactic.
Require Import PrimSemantics.
Require Import XOmega.

Require Import liblayers.logic.PTreeModules.
Require Import liblayers.logic.LayerLogicImpl.
Require Import liblayers.compcertx.Stencil.
Require Import liblayers.compcertx.MakeProgram.
Require Import liblayers.compat.CompatLayers.
Require Import liblayers.compat.CompatGenSem.
Require Import compcert.cfrontend.Ctypes.

(*Require Import LAsmModuleSemAux.*)
Require Import LayerCalculusLemma.
Require Import AbstractDataType.

Require Import PIPCIntro.
Require Import PIPC.
Require Import IPCGenSpec.

(** * Definition of the refinement relation*)
Section Refinement.

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

  Context `{real_params: RealParams}.

  Notation HDATA := RData.
  Notation LDATA := RData.

  Notation HDATAOps := (cdata (cdata_ops := pipc_data_ops) HDATA).
  Notation LDATAOps := (cdata (cdata_ops := pthread_data_ops) LDATA).

  Section WITHMEM.

    Context `{Hstencil: Stencil}.
    Context `{Hmem: Mem.MemoryModel}.
    Context `{Hmwd: UseMemWithData mem}.

    (** Relation between raw data at two layers*)
    Record relate_RData (f: meminj) (hadt: HDATA) (ladt: LDATA) :=
      mkrelate_RData {
          flatmem_re: FlatMem.flatmem_inj (HP hadt) (HP ladt);
          vmxinfo_re: vmxinfo hadt = vmxinfo ladt;
          devout_re: devout hadt = devout ladt;
          CR3_re:  CR3 hadt = CR3 ladt;
          ikern_re: ikern hadt = ikern ladt;
          pg_re: pg hadt = pg ladt;
          ihost_re: ihost hadt = ihost ladt;
          AC_re: AC hadt = AC ladt;
          ti_fst_re: (fst (ti hadt)) = (fst (ti ladt));
          ti_snd_re: val_inject f (snd (ti hadt)) (snd (ti ladt));
          LAT_re: LAT hadt = LAT ladt;
          nps_re: nps hadt = nps ladt;
          init_re: init hadt = init ladt;

          pperm_re: pperm hadt = pperm ladt;
          PT_re:  PT hadt = PT ladt;
          ptp_re: ptpool hadt = ptpool ladt;
          idpde_re: idpde hadt = idpde ladt;
          ipt_re: ipt hadt = ipt ladt;
          smspool_re: smspool hadt = smspool ladt;

          kctxt_re: kctxt_inj f num_proc (kctxt hadt) (kctxt ladt);
          abtcb_re:  abtcb hadt = abtcb ladt;
          abq_re:  abq hadt = abq ladt;
          cid_re:  cid hadt = cid ladt;
          chpool_re:  syncchpool hadt = syncchpool ladt
        }.

    Inductive match_RData: stencil -> HDATA -> mem -> meminj -> Prop :=
    | MATCH_RDATA: forall habd m f s, match_RData s habd m f.

    Local Hint Resolve MATCH_RDATA.

    Global Instance rel_ops: CompatRelOps HDATAOps LDATAOps :=
      {
        relate_AbData s f d1 d2 := relate_RData f d1 d2;
        match_AbData s d1 m f := match_RData s d1 m f;
        new_glbl := nil
      }.

    (** ** Properties of relations*)
    Section Rel_Property.

      (** Prove that after taking one step, the refinement relation still holds*)
      Lemma relate_incr:
        forall abd abd' f f',
          relate_RData f abd abd'
          -> inject_incr f f'
          -> relate_RData f' abd abd'.
      Proof.
        inversion 1; subst; intros; inv H; constructor; eauto.
        - eapply kctxt_inj_incr; eauto.
      Qed.

      Lemma relate_kernel_mode:
        forall abd abd' f,
          relate_RData f abd abd'
          -> (kernel_mode abd <-> kernel_mode abd').
      Proof.
        inversion 1; simpl; split; congruence.
      Qed.

      Lemma relate_observe:
        forall p abd abd' f,
          relate_RData f abd abd' ->
          observe p abd = observe p abd'.
      Proof.
        inversion 1; simpl; unfold ObservationImpl.observe; congruence.
      Qed.

      Global Instance rel_prf: CompatRel HDATAOps LDATAOps.
      Proof.
        constructor; intros; simpl; trivial.
        eapply relate_incr; eauto.
        eapply relate_kernel_mode; eauto.
        eapply relate_observe; eauto.
      Qed.

    End Rel_Property.

    (** * Proofs the one-step forward simulations for the low level specifications*)
    Section OneStep_Forward_Relation.

      Section FRESH_PRIM.

        Require Import CommonTactic.

        Lemma proc_init_kern_mode:
          forall i v d,
            proc_init_spec i d = Some v
            -> kernel_mode d.
        Proof.
          unfold proc_init_spec. simpl; intros.
          subdestruct; auto.
        Qed.

        Lemma proc_init_spec_ref:
          compatsim (crel HDATA LDATA) (gensem proc_init_spec)
                    proc_init_spec_low.
        Proof.
          compatsim_simpl (@match_AbData).
          exploit proc_init_exist; eauto 1.
          intros (labd' & HP & HM).
          exploit proc_init_kern_mode; eauto. intros.
          refine_split; try econstructor; eauto. constructor.
        Qed.

        Lemma syncreceive_chan_kern_mode:
          forall v d i1 i2 i3,
            syncreceive_chan_spec i1 i2 i3 d = Some v
            -> kernel_mode d
               /\ 0 <= i1 < num_proc.
        Proof.
          unfold syncreceive_chan_spec. simpl; intros.
          subdestruct; auto.
        Qed.

        Lemma syncreceive_chan_spec_ref:
          compatsim (crel HDATA LDATA) (gensem syncreceive_chan_spec)
                    syncreceive_chan_spec_low.
        Proof.
          compatsim_simpl (@match_AbData).
          exploit syncreceive_chan_exist; eauto 1.
          intros (labd' & HP & HM).
          exploit syncreceive_chan_kern_mode; eauto.
          intros (Hkern & Hrange).
          refine_split; try econstructor; eauto.
          constructor.
        Qed.

        Lemma syncsendto_chan_pre_kern_mode:
          forall i1 i2 i3 v d,
            syncsendto_chan_pre_spec i1 i2 i3 d = Some v
            -> kernel_mode d.
        Proof.
          unfold syncsendto_chan_pre_spec. simpl; intros.
          subdestruct; auto.
        Qed.

        Lemma syncsendto_chan_pre_spec_ref:
          compatsim (crel HDATA LDATA) (gensem syncsendto_chan_pre_spec)
                    syncsendto_chan_pre_spec_low.
        Proof.
          compatsim_simpl (@match_AbData).
          exploit syncsendto_chan_pre_exist; eauto 1.
          intros (labd' & HP & HM).
          exploit syncsendto_chan_pre_kern_mode; eauto. intros.
          refine_split; try econstructor; eauto. constructor.
        Qed.

        Lemma syncsendto_chan_post_kern_mode:
          forall v d,
            syncsendto_chan_post_spec d = Some v
            -> kernel_mode d.
        Proof.
          unfold syncsendto_chan_post_spec. simpl; intros.
          subdestruct; auto.
        Qed.

        Lemma syncsendto_chan_post_spec_ref:
          compatsim (crel HDATA LDATA) (gensem syncsendto_chan_post_spec)
                    syncsendto_chan_post_spec_low.
        Proof.
          compatsim_simpl (@match_AbData).
          exploit syncsendto_chan_post_exist; eauto 1.
          intros (labd' & HP & HM).
          exploit syncsendto_chan_post_kern_mode; eauto. intros.
          refine_split; try econstructor; eauto. constructor.
        Qed.

      End FRESH_PRIM.

      Section PASSTHROUGH_PRIM.

        Global Instance: (LoadStoreProp (hflatmem_store:= flatmem_store) (lflatmem_store:= flatmem_store)).
        Proof.
          accessor_prop_tac.
          - eapply flatmem_store_exists; eauto.
        Qed.

        Lemma passthrough_correct:
          sim (crel HDATA LDATA) pipc_passthrough pipcintro.
        Proof.
          sim_oplus.
          - apply fload_sim.
          - apply fstore_sim.
          - apply vmxinfo_get_sim.
          - apply device_output_sim.
          - apply pfree_sim.
          - apply setPT_sim.
          - apply ptRead_sim.
          - apply ptResv_sim.
          - apply shared_mem_status_sim.
          - apply offer_shared_mem_sim.
          - apply get_curid_sim.
          - apply thread_spawn_sim.
          - apply thread_wakeup_sim.
          - apply ptin_sim.
          - apply ptout_sim.
          - apply container_get_nchildren_sim.
          - apply container_get_quota_sim.
          - apply container_get_usage_sim.
          - apply container_can_consume_sim.
          - apply alloc_sim.
          - apply trapin_sim.
          - apply trapout_sim.
          - apply hostin_sim.
          - apply hostout_sim.
          - apply trap_info_get_sim.
          - apply trap_info_ret_sim.
          - apply thread_yield_sim.
          - apply thread_sleep_sim.
          - layer_sim_simpl.
            + eapply load_correct2.
            + eapply store_correct2.
        Qed.

      End PASSTHROUGH_PRIM.

    End OneStep_Forward_Relation.

  End WITHMEM.

End Refinement.


Require Import Lia.
Require Import Bool.
Require Import RelationClasses.

From sflib Require Import sflib.
From Paco Require Import paco.

From PromisingLib Require Import Axioms.
From PromisingLib Require Import Basic.
From PromisingLib Require Import DataStructure.
From PromisingLib Require Import DenseOrder.
From PromisingLib Require Import Loc.
From PromisingLib Require Import Language.
From PromisingLib Require Import Event.

Require Import Time.
Require Import View.
Require Import BoolMap.
Require Import Promises.
Require Import Cell.
Require Import Memory.
Require Import TView.
Require Import Global.
Require Import Local.
Require Import Thread.
Require Import Configuration.
Require Import PFConfiguration.
Require Import Behavior.

Require Import OrdStep.
Require Import Writes.
Require Import WStep.
Require Import Stable.
Require Import PFtoRASim.
Require Import PFtoRAThread.

Set Implicit Arguments.

Module PFtoRA.
  Section PFtoRA.
    Variable L: Loc.t -> bool.

    (* well-formedness *)

    Variant wf_pf (c: Configuration.t): Prop :=
    | wf_pf_intro
        (WF: Configuration.wf c)
        (PRM: forall tid lang st lc
                (TH: IdentMap.find tid (Configuration.threads c) = Some (existT _ lang st, lc)),
            Local.promises lc = BoolMap.bot)
        (GPRM: Global.promises (Configuration.global c) = BoolMap.bot)
    .

    Variant wf_ra (rels: Writes.t) (c: Configuration.t): Prop :=
    | wf_ra_intro
        (WF: Configuration.wf c)
        (RELS: Writes.wf L rels (Global.memory (Configuration.global c)))
        (PRM: forall tid lang st lc
                (TH: IdentMap.find tid (Configuration.threads c) = Some (existT _ lang st, lc)),
            Local.promises lc = BoolMap.bot)
        (GPRM: Global.promises (Configuration.global c) = BoolMap.bot)
    .

    Lemma wf_pf_thread
          c tid lang st lc
          (WF: wf_pf c)
          (FIND: IdentMap.find tid (Configuration.threads c) = Some (existT _ lang st, lc)):
      PFtoRAThread.wf_pf (Thread.mk _ st lc (Configuration.global c)).
    Proof.
      inv WF. inv WF0. inv WF.
      econs; eauto.
    Qed.

    Lemma wf_ra_thread
          rels c tid lang st lc
          (WF: wf_ra rels c)
          (FIND: IdentMap.find tid (Configuration.threads c) = Some (existT _ lang st, lc)):
      PFtoRAThread.wf_ra L rels (Thread.mk _ st lc (Configuration.global c)).
    Proof.
      inv WF. inv WF0. inv WF.
      econs; eauto.
    Qed.

    Lemma step_pf_future
          e tid c1 c2
          (WF1: wf_pf c1)
          (STEP: PFConfiguration.estep e tid c1 c2):
      <<WF2: wf_pf c2>>.
    Proof.
      exploit PFConfiguration.estep_future; try apply WF1; eauto. i. des.
      inv STEP. ss.
      exploit wf_pf_thread; eauto. i.
      exploit PFtoRAThread.step_pf_future; eauto. i. des. inv x1. ss.
      econs; ss. i. Configuration.simplify.
      inv WF1. eauto.
    Qed.

    Lemma step_ra_future
          ordr ordw
          e tid rels1 rels2 c1 c2
          (WF1: wf_ra rels1 c1)
          (ORD: Ordering.le Ordering.plain ordw)
          (STEP: WConfiguration.step L ordr ordw e tid rels1 rels2 c1 c2):
      <<WF2: wf_ra rels2 c2>>.
    Proof.
      exploit WConfiguration.step_future; try eapply WF1; eauto. i. des.
      inv STEP. ss.
      exploit wf_ra_thread; eauto. i.
      hexploit WThread.step_writes_wf; eauto; try apply x0. s. i.
      exploit PFtoRAThread.step_ra_future; eauto. i. des. inv x1. ss.
      econs; ss. i. Configuration.simplify; ss.
      inv WF1. eauto.
    Qed.

    Lemma steps_pf_future
          c1 c2
          (WF1: wf_pf c1)
          (STEPS: rtc (PFConfiguration.all_step) c1 c2):
      <<WF2: wf_pf c2>>.
    Proof.
      induction STEPS; ss. inv H.
      exploit step_pf_future; eauto.
    Qed.

    Lemma steps_ra_future
          ordr ordw
          rels1 rels2 c1 c2
          (WF1: wf_ra rels1 c1)
          (ORD: Ordering.le Ordering.plain ordw)
          (STEPS: WConfiguration.steps L ordr ordw rels1 rels2 c1 c2):
      <<WF2: wf_ra rels2 c2>>.
    Proof.
      induction STEPS; ss.
      exploit step_ra_future; eauto.
    Qed.

    (* sim *)

    Variant sim_thread_sl (rels: Writes.t) (gl_pf gl_ra: Global.t):
      forall (sl_pf sl_ra: {lang: language & Language.state lang} * Local.t), Prop :=
    | sim_thread_sl_intro
        lang st_pf lc_pf st_ra lc_ra
        (SIM: PFtoRAThread.sim_thread L rels
                                      (Thread.mk lang st_pf lc_pf gl_pf)
                                      (Thread.mk lang st_ra lc_ra gl_ra)):
        sim_thread_sl rels gl_pf gl_ra
                      (existT _ lang st_pf, lc_pf) (existT _ lang st_ra, lc_ra)
    .

    Variant sim_conf (rels: Writes.t): forall (c_pf c_ra: Configuration.t), Prop :=
    | sim_conf_intro
        ths_pf gl_pf
        ths_ra gl_ra
        (THS: forall tid,
            option_rel
              (sim_thread_sl rels gl_pf gl_ra)
              (IdentMap.find tid ths_pf)
              (IdentMap.find tid ths_ra)):
        sim_conf rels
                 (Configuration.mk ths_pf gl_pf)
                 (Configuration.mk ths_ra gl_ra)
    .

    Lemma init_wf_pf syn:
      wf_pf (Configuration.init syn).
    Proof.
      econs; eauto using Configuration.init_wf.
      i. ss.
      unfold Threads.init in *.
      rewrite IdentMap.Facts.map_o in *.
      destruct (@UsualFMapPositive.UsualPositiveMap'.find
                  (@sigT _ (@Language.syntax ProgramEvent.t)) tid syn); inv TH.
      apply inj_pair2 in H1. subst. ss.
    Qed.

    Lemma init_wf_ra syn:
      wf_ra [] (Configuration.init syn).
    Proof.
      econs; eauto using Configuration.init_wf; i; ss.
      - econs; i; ss.
        unfold Memory.get, Memory.init, Cell.get, Cell.init in *. ss.
        apply DOMap.singleton_find_inv in GET. des. inv GET0. ss.
      -unfold Threads.init in *.
        rewrite IdentMap.Facts.map_o in *.
        destruct (@UsualFMapPositive.UsualPositiveMap'.find
                    (@sigT _ (@Language.syntax ProgramEvent.t)) tid syn); inv TH.
        apply inj_pair2 in H1. subst. ss.
    Qed.

    Lemma init_sim_conf syn:
      sim_conf [] (Configuration.init syn) (Configuration.init syn).
    Proof.
      econs; ss. i. unfold option_rel.
      destruct (IdentMap.find tid (Threads.init syn)) as [[[lang st] lc]|] eqn:FIND; ss.
      unfold Threads.init in *.
      rewrite IdentMap.Facts.map_o in *.
      destruct (@UsualFMapPositive.UsualPositiveMap'.find
                  (@sigT _ (@Language.syntax ProgramEvent.t)) tid syn); inv FIND.
      apply inj_pair2 in H1. subst.
      econs. econs; ss.
      (* - econs; ss; try refl. econs; try refl. ii. *)
      (*   rewrite Memory.bot_get. ss. *)
      (* - econs; ss. econs; ss; eauto. i. *)
      (*   unfold Memory.get, Memory.init, Cell.get, Cell.init in *. ss. *)
      (*   apply DOMap.singleton_find_inv in GET. des. inv GET0. ss. *)
      - econs; ss.
        + econs; ss. econs; ss. i. condtac; ss. refl.
        + econs; ss; i.
          * unfold Memory.get, Memory.init, Cell.get, Cell.init in *. ss.
            apply DOMap.singleton_find_inv in GET_SRC. des. inv GET_SRC0.
            esplits; ss. econs; ss. condtac; ss.
          * unfold Memory.get, Memory.init, Cell.get, Cell.init in *. ss.
            apply DOMap.singleton_find_inv in GET_TGT. des. inv GET_TGT0.
            esplits; ss. econs; ss. condtac; ss.
          * unfold Memory.get, Memory.init, Cell.get, Cell.init in *. ss.
            apply DOMap.singleton_find_inv in GET_TGT. des. inv GET_TGT0. ss.
      - econs; ss. ii.
        unfold Memory.get, Memory.init, Cell.get, Cell.init in *. ss.
        apply DOMap.singleton_find_inv in GET. des. inv GET0.
      - econs; ss. ii.
        unfold Memory.get, Memory.init, Cell.get, Cell.init in *. ss.
        apply DOMap.singleton_find_inv in GET. des. inv GET0.
      - econs; ss. ii. des; ss.
        unfold Memory.get, Memory.init, Cell.get, Cell.init in *. ss.
        apply DOMap.singleton_find_inv in GET. des. inv GET1.
    Qed.

    Lemma sim_conf_terminal
          rels c_pf c_ra
          (WF_RA: wf_ra rels c_ra)
          (SIM: sim_conf rels c_pf c_ra)
          (TERMINAL: Configuration.is_terminal c_pf):
      Configuration.is_terminal c_ra.
    Proof.
      ii. inv SIM. specialize (THS tid).
      unfold option_rel in *. ss. des_ifs.
      destruct p as [[]]. inv THS.
      Configuration.simplify.
      inv SIM. inv SIM_RA. ss. subst.
      exploit TERMINAL; eauto. i. des.
      split; ss.
      inv WF_RA. eauto.
    Qed.

    (* step *)

    Lemma sim_conf_step
          rels1 c1_pf c1_ra
          tid e_pf c2_pf
          (SIM1: sim_conf rels1 c1_pf c1_ra)
          (WF1_PF: wf_pf c1_pf)
          (WF1_RA: wf_ra rels1 c1_ra)
          (STEP: PFConfiguration.estep e_pf tid c1_pf c2_pf):
      (exists e_ra rels2 c2_ra,
          (<<STEP_RA: WConfiguration.step L Ordering.acqrel Ordering.acqrel
                                          e_ra tid rels1 rels2 c1_ra c2_ra>>) /\
          (<<EVENT_RA: PFtoRASim.sim_event e_ra e_pf>>) /\
          (<<SIM2: sim_conf rels2 c2_pf c2_ra>>)) \/
      (<<RACE: RARaceW.ra_race_steps L Ordering.acqrel Ordering.acqrel rels1 c1_ra>>).
    Proof.
      dup SIM1. inv SIM0. inv STEP. ss.
      dup THS. specialize (THS0 tid). unfold option_rel in THS0. des_ifs.
      inv THS0. apply inj_pair2 in H1. subst.
      exploit wf_pf_thread; eauto. s. i.
      exploit wf_ra_thread; try exact WF1_RA; eauto. s. i.
      exploit PFtoRAThread.sim_thread_step; eauto. i. des; cycle 1.
      { right. unfold RARaceW.ra_race_steps.
        esplits; [econs 1|..]; eauto.
      }
      destruct e2_ra as [st2_ra lc2_ra gl2_ra].
      left. esplits.
      - econs; eauto.
      - ss.
      - econs; ss. i.
        repeat rewrite IdentMap.gsspec. condtac; ss.
        specialize (THS tid0). unfold option_rel in THS. des_ifs. inv THS. ss.
        inv SIM0. econs. econs; s.
        + inv SIM_RA. ss. subst.
          inv SIM2. inv SIM_RA. ss.
        + econs; try apply SIM2; try apply NORMAL_PF.
        + econs; try apply SIM2; try apply NORMAL_RA.
        + econs; s; try apply SIM2; try apply STABLE_RA.
          exploit WThread.step_future; try exact STEP_RA; try apply x1. s. i. des.
          exploit wf_ra_thread; try exact WF1_RA; try eapply Heq2. s. i.
          exploit Stable.future_stable_tview;
            try eapply STABLE_RA; try apply x2; try apply GL_FUTURE; eauto.
    Qed.

    Lemma sim_conf_steps
          rels1 c1_pf c1_ra
          c2_pf
          (SIM1: sim_conf rels1 c1_pf c1_ra)
          (WF1_PF: wf_pf c1_pf)
          (WF1_RA: wf_ra rels1 c1_ra)
          (STEPS: rtc PFConfiguration.all_step c1_pf c2_pf):
      (exists rels2 c2_ra,
          (<<STEPS_RA: WConfiguration.steps L Ordering.acqrel Ordering.acqrel rels1 rels2 c1_ra c2_ra>>) /\
          (<<SIM2: sim_conf rels2 c2_pf c2_ra>>)) \/
      (<<RACE: RARaceW.ra_race_steps L Ordering.acqrel Ordering.acqrel rels1 c1_ra>>).
    Proof.
      revert rels1  c1_ra SIM1 WF1_PF WF1_RA.
      induction STEPS; i.
      { left. esplits; try by econs 1. ss. }
      inv H. exploit sim_conf_step; eauto. i. des; eauto.
      exploit step_pf_future; eauto. i. des.
      exploit step_ra_future; try exact STEP_RA; eauto. i. des.
      exploit IHSTEPS; eauto. i. des.
      - left. esplits; (try by econs 2; eauto); ss.
      - right. unfold RARaceW.ra_race_steps in *. des.
        esplits; [econs 2; eauto|..]; eauto.
    Qed.

    (* behaviors *)

    Lemma sim_conf_behavior
          rels c_pf c_ra
          (SIM: sim_conf rels c_pf c_ra)
          (WF_PF: wf_pf c_pf)
          (WF_RA: wf_ra rels c_ra)
          (RACEFREE: RARaceW.racefree L Ordering.acqrel Ordering.acqrel rels c_ra):
      behaviors (PFConfiguration.step ThreadEvent.get_machine_event_pf) c_pf <2=
      behaviors (@OrdConfiguration.step L Ordering.acqrel Ordering.acqrel) c_ra.
    Proof.
      i. revert rels  c_ra SIM WF_PF WF_RA RACEFREE.
      induction PR; i.
      - econs 1. eapply sim_conf_terminal; eauto.
      - inv STEP. exploit sim_conf_step; eauto. i. des.
        + exploit WConfiguration.step_ord_step; eauto. i.
          inv EVENT_RA; ss. inv H0.
          econs 2.
          { replace (MachineEvent.syscall e2) with
              (ThreadEvent.get_machine_event_pf (ThreadEvent.syscall e2)) by ss.
            econs; eauto.
          }
          { hexploit RARaceW.step_racefree; eauto. i.
            exploit step_pf_future; eauto. i. des.
            exploit step_ra_future; try exact STEP_RA; eauto.
          }
          { ss. }
        + exfalso. unfold RARaceW.ra_race_steps in *. des. eauto.
      - inv STEP. exploit sim_conf_step; eauto. i. des.
        + exploit WConfiguration.step_ord_step; eauto. i.
          econs 3.
          replace MachineEvent.failure with (ThreadEvent.get_machine_event_pf e_ra); [econs; eauto|].
          inv EVENT_RA; ss.
        + exfalso. unfold RARaceW.ra_race_steps in *. des. eauto.
      - inv STEP. exploit sim_conf_step; eauto. i. des.
        + exploit WConfiguration.step_ord_step; eauto. i.
          econs 4.
          { replace MachineEvent.silent with (ThreadEvent.get_machine_event_pf e_ra); cycle 1.
            { inv EVENT_RA; ss. }
            econs; eauto.
          }
          hexploit RARaceW.step_racefree; eauto. i.
          exploit step_pf_future; eauto. i. des.
          exploit step_ra_future; try exact STEP_RA; eauto.
        + exfalso. unfold RARaceW.ra_race_steps in *. des. eauto.
      - econs 5.
    Qed.
  End PFtoRA.
End PFtoRA.


(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)

(** Typing rules for LTLin. *)

Require Import Coqlib.
Require Import Maps.
Require Import AST.
Require Import Integers.
Require Import Memdata.
Require Import Op.
Require Import RTL.
Require Import Locations.
Require Import LTLin.
Require LTLtyping.
Require Import Conventions.

(** The following predicates define a type system for LTLin similar to that
  of LTL. *)

Section WT_INSTR.

Variable funsig: signature.

Inductive wt_instr : instruction -> Prop :=
  | wt_Lopmove:
      forall r1 r,
      Loc.type r1 = Loc.type r -> loc_acceptable r1 -> loc_acceptable r ->
      wt_instr (Lop Omove (r1 :: nil) r)
  | wt_Lop:
      forall op args res,
      op <> Omove ->
      (List.map Loc.type args, Loc.type res) = type_of_operation op ->
      locs_acceptable args -> loc_acceptable res ->
      wt_instr (Lop op args res)
  | wt_Lload:
      forall chunk addr args dst,
      List.map Loc.type args = type_of_addressing addr ->
      Loc.type dst = type_of_chunk chunk ->
      locs_acceptable args -> loc_acceptable dst ->
      wt_instr (Lload chunk addr args dst)
  | wt_Lstore:
      forall chunk addr args src,
      List.map Loc.type args = type_of_addressing addr ->
      Loc.type src = type_of_chunk chunk ->
      locs_acceptable args -> loc_acceptable src ->
      wt_instr (Lstore chunk addr args src)
  | wt_Lcall:
      forall sig ros args res,
      List.map Loc.type args = sig.(sig_args) ->
      Loc.type res = proj_sig_res sig ->
      LTLtyping.call_loc_acceptable sig ros ->
      locs_acceptable args -> loc_acceptable res ->
      wt_instr (Lcall sig ros args res)
  | wt_Ltailcall:
      forall sig ros args,
      List.map Loc.type args = sig.(sig_args) ->
      LTLtyping.call_loc_acceptable sig ros ->
      locs_acceptable args ->
      sig.(sig_res) = funsig.(sig_res) ->
      tailcall_possible sig ->
      wt_instr (Ltailcall sig ros args)
  | wt_Lbuiltin:
      forall ef args res,
      List.map Loc.type args = (ef_sig ef).(sig_args) ->
      Loc.type res = proj_sig_res (ef_sig ef) ->
      arity_ok (ef_sig ef).(sig_args) = true \/ ef_reloads ef = false ->
      locs_acceptable args -> loc_acceptable res ->
       wt_instr (Lbuiltin ef args res)
  | wt_Llabel: forall lbl,
      wt_instr (Llabel lbl)
  | wt_Lgoto: forall lbl,
      wt_instr (Lgoto lbl)
  | wt_Lcond:
      forall cond args lbl,
      List.map Loc.type args = type_of_condition cond ->
      locs_acceptable args ->
      wt_instr (Lcond cond args lbl)
  | wt_Ljumptable:
      forall arg tbl,
      Loc.type arg = Tint ->
      loc_acceptable arg ->
      list_length_z tbl * 4 <= Int.max_unsigned ->
      wt_instr (Ljumptable arg tbl)
  | wt_Lreturn:
      forall optres,
      option_map Loc.type optres = funsig.(sig_res) ->
      match optres with None => True | Some r => loc_acceptable r end ->
      wt_instr (Lreturn optres).

Definition wt_code (c: code) : Prop :=
  forall i, In i c -> wt_instr i.

End WT_INSTR.

Record wt_function (f: function): Prop :=
  mk_wt_function {
    wt_params:
      List.map Loc.type f.(fn_params) = f.(fn_sig).(sig_args);
    wt_acceptable:
      locs_acceptable f.(fn_params);
    wt_norepet:
      Loc.norepet f.(fn_params);
    wt_instrs:
      wt_code f.(fn_sig) f.(fn_code)
}.

Inductive wt_fundef: fundef -> Prop :=
  | wt_fundef_external: forall ef,
      wt_fundef (External ef)
  | wt_function_internal: forall f,
      wt_function f ->
      wt_fundef (Internal f).

Definition wt_program (p: program): Prop :=
  forall i f, In (i, f) (prog_funct p) -> wt_fundef f.


From Coq Require Import String List ZArith.
From compcert Require Import Coqlib Integers Floats AST Ctypes Cop Clight Clightdefs.
Import Clightdefs.ClightNotations.
Local Open Scope Z_scope.
Local Open Scope string_scope.
Local Open Scope clight_scope.

Module Info.
  Definition version := "3.10".
  Definition build_number := "".
  Definition build_tag := "".
  Definition build_branch := "".
  Definition arch := "x86".
  Definition model := "32sse2".
  Definition abi := "standard".
  Definition bitsize := 32.
  Definition big_endian := false.
  Definition source_file := "dotprod.c".
  Definition normalized := true.
End Info.

Definition _N : ident := $"N".
Definition _R : ident := $"R".
Definition _REPEAT : ident := $"REPEAT".
Definition _T : ident := $"T".
Definition __155 : ident := $"_155".
Definition __156 : ident := $"_156".
Definition __229 : ident := $"_229".
Definition __230 : ident := $"_230".
Definition __231 : ident := $"_231".
Definition __Bigint : ident := $"_Bigint".
Definition ___builtin_annot : ident := $"__builtin_annot".
Definition ___builtin_annot_intval : ident := $"__builtin_annot_intval".
Definition ___builtin_bswap : ident := $"__builtin_bswap".
Definition ___builtin_bswap16 : ident := $"__builtin_bswap16".
Definition ___builtin_bswap32 : ident := $"__builtin_bswap32".
Definition ___builtin_bswap64 : ident := $"__builtin_bswap64".
Definition ___builtin_clz : ident := $"__builtin_clz".
Definition ___builtin_clzl : ident := $"__builtin_clzl".
Definition ___builtin_clzll : ident := $"__builtin_clzll".
Definition ___builtin_ctz : ident := $"__builtin_ctz".
Definition ___builtin_ctzl : ident := $"__builtin_ctzl".
Definition ___builtin_ctzll : ident := $"__builtin_ctzll".
Definition ___builtin_debug : ident := $"__builtin_debug".
Definition ___builtin_expect : ident := $"__builtin_expect".
Definition ___builtin_fabs : ident := $"__builtin_fabs".
Definition ___builtin_fabsf : ident := $"__builtin_fabsf".
Definition ___builtin_fmadd : ident := $"__builtin_fmadd".
Definition ___builtin_fmax : ident := $"__builtin_fmax".
Definition ___builtin_fmin : ident := $"__builtin_fmin".
Definition ___builtin_fmsub : ident := $"__builtin_fmsub".
Definition ___builtin_fnmadd : ident := $"__builtin_fnmadd".
Definition ___builtin_fnmsub : ident := $"__builtin_fnmsub".
Definition ___builtin_fsqrt : ident := $"__builtin_fsqrt".
Definition ___builtin_membar : ident := $"__builtin_membar".
Definition ___builtin_memcpy_aligned : ident := $"__builtin_memcpy_aligned".
Definition ___builtin_read16_reversed : ident := $"__builtin_read16_reversed".
Definition ___builtin_read32_reversed : ident := $"__builtin_read32_reversed".
Definition ___builtin_sel : ident := $"__builtin_sel".
Definition ___builtin_sqrt : ident := $"__builtin_sqrt".
Definition ___builtin_unreachable : ident := $"__builtin_unreachable".
Definition ___builtin_va_arg : ident := $"__builtin_va_arg".
Definition ___builtin_va_copy : ident := $"__builtin_va_copy".
Definition ___builtin_va_end : ident := $"__builtin_va_end".
Definition ___builtin_va_start : ident := $"__builtin_va_start".
Definition ___builtin_write16_reversed : ident := $"__builtin_write16_reversed".
Definition ___builtin_write32_reversed : ident := $"__builtin_write32_reversed".
Definition ___cleanup : ident := $"__cleanup".
Definition ___compcert_i64_dtos : ident := $"__compcert_i64_dtos".
Definition ___compcert_i64_dtou : ident := $"__compcert_i64_dtou".
Definition ___compcert_i64_sar : ident := $"__compcert_i64_sar".
Definition ___compcert_i64_sdiv : ident := $"__compcert_i64_sdiv".
Definition ___compcert_i64_shl : ident := $"__compcert_i64_shl".
Definition ___compcert_i64_shr : ident := $"__compcert_i64_shr".
Definition ___compcert_i64_smod : ident := $"__compcert_i64_smod".
Definition ___compcert_i64_smulh : ident := $"__compcert_i64_smulh".
Definition ___compcert_i64_stod : ident := $"__compcert_i64_stod".
Definition ___compcert_i64_stof : ident := $"__compcert_i64_stof".
Definition ___compcert_i64_udiv : ident := $"__compcert_i64_udiv".
Definition ___compcert_i64_umod : ident := $"__compcert_i64_umod".
Definition ___compcert_i64_umulh : ident := $"__compcert_i64_umulh".
Definition ___compcert_i64_utod : ident := $"__compcert_i64_utod".
Definition ___compcert_i64_utof : ident := $"__compcert_i64_utof".
Definition ___compcert_va_composite : ident := $"__compcert_va_composite".
Definition ___compcert_va_float64 : ident := $"__compcert_va_float64".
Definition ___compcert_va_int32 : ident := $"__compcert_va_int32".
Definition ___compcert_va_int64 : ident := $"__compcert_va_int64".
Definition ___count : ident := $"__count".
Definition ___getreent : ident := $"__getreent".
Definition ___locale_t : ident := $"__locale_t".
Definition ___sFILE64 : ident := $"__sFILE64".
Definition ___sbuf : ident := $"__sbuf".
Definition ___sdidinit : ident := $"__sdidinit".
Definition ___sf : ident := $"__sf".
Definition ___sglue : ident := $"__sglue".
Definition ___stringlit_1 : ident := $"__stringlit_1".
Definition ___stringlit_2 : ident := $"__stringlit_2".
Definition ___tm : ident := $"__tm".
Definition ___tm_hour : ident := $"__tm_hour".
Definition ___tm_isdst : ident := $"__tm_isdst".
Definition ___tm_mday : ident := $"__tm_mday".
Definition ___tm_min : ident := $"__tm_min".
Definition ___tm_mon : ident := $"__tm_mon".
Definition ___tm_sec : ident := $"__tm_sec".
Definition ___tm_wday : ident := $"__tm_wday".
Definition ___tm_yday : ident := $"__tm_yday".
Definition ___tm_year : ident := $"__tm_year".
Definition ___value : ident := $"__value".
Definition ___wch : ident := $"__wch".
Definition ___wchb : ident := $"__wchb".
Definition __add : ident := $"_add".
Definition __asctime_buf : ident := $"_asctime_buf".
Definition __atexit : ident := $"_atexit".
Definition __atexit0 : ident := $"_atexit0".
Definition __base : ident := $"_base".
Definition __bf : ident := $"_bf".
Definition __blksize : ident := $"_blksize".
Definition __close : ident := $"_close".
Definition __cookie : ident := $"_cookie".
Definition __cvtbuf : ident := $"_cvtbuf".
Definition __cvtlen : ident := $"_cvtlen".
Definition __data : ident := $"_data".
Definition __dso_handle : ident := $"_dso_handle".
Definition __emergency : ident := $"_emergency".
Definition __errno : ident := $"_errno".
Definition __file : ident := $"_file".
Definition __flags : ident := $"_flags".
Definition __flags2 : ident := $"_flags2".
Definition __fnargs : ident := $"_fnargs".
Definition __fns : ident := $"_fns".
Definition __fntypes : ident := $"_fntypes".
Definition __freelist : ident := $"_freelist".
Definition __gamma_signgam : ident := $"_gamma_signgam".
Definition __getdate_err : ident := $"_getdate_err".
Definition __glue : ident := $"_glue".
Definition __h_errno : ident := $"_h_errno".
Definition __inc : ident := $"_inc".
Definition __ind : ident := $"_ind".
Definition __iobs : ident := $"_iobs".
Definition __is_cxa : ident := $"_is_cxa".
Definition __k : ident := $"_k".
Definition __l64a_buf : ident := $"_l64a_buf".
Definition __lb : ident := $"_lb".
Definition __lbfsize : ident := $"_lbfsize".
Definition __locale : ident := $"_locale".
Definition __localtime_buf : ident := $"_localtime_buf".
Definition __lock : ident := $"_lock".
Definition __maxwds : ident := $"_maxwds".
Definition __mblen_state : ident := $"_mblen_state".
Definition __mbrlen_state : ident := $"_mbrlen_state".
Definition __mbrtowc_state : ident := $"_mbrtowc_state".
Definition __mbsrtowcs_state : ident := $"_mbsrtowcs_state".
Definition __mbstate : ident := $"_mbstate".
Definition __mbtowc_state : ident := $"_mbtowc_state".
Definition __mult : ident := $"_mult".
Definition __nbuf : ident := $"_nbuf".
Definition __new : ident := $"_new".
Definition __next : ident := $"_next".
Definition __nextf : ident := $"_nextf".
Definition __niobs : ident := $"_niobs".
Definition __nmalloc : ident := $"_nmalloc".
Definition __offset : ident := $"_offset".
Definition __on_exit_args : ident := $"_on_exit_args".
Definition __p : ident := $"_p".
Definition __p5s : ident := $"_p5s".
Definition __r : ident := $"_r".
Definition __r48 : ident := $"_r48".
Definition __rand48 : ident := $"_rand48".
Definition __rand_next : ident := $"_rand_next".
Definition __read : ident := $"_read".
Definition __reent : ident := $"_reent".
Definition __result : ident := $"_result".
Definition __result_k : ident := $"_result_k".
Definition __seed : ident := $"_seed".
Definition __seek : ident := $"_seek".
Definition __seek64 : ident := $"_seek64".
Definition __sig_func : ident := $"_sig_func".
Definition __sign : ident := $"_sign".
Definition __signal_buf : ident := $"_signal_buf".
Definition __size : ident := $"_size".
Definition __stderr : ident := $"_stderr".
Definition __stdin : ident := $"_stdin".
Definition __stdout : ident := $"_stdout".
Definition __strtok_last : ident := $"_strtok_last".
Definition __ub : ident := $"_ub".
Definition __ubuf : ident := $"_ubuf".
Definition __unspecified_locale_info : ident := $"_unspecified_locale_info".
Definition __unused : ident := $"_unused".
Definition __unused_rand : ident := $"_unused_rand".
Definition __up : ident := $"_up".
Definition __ur : ident := $"_ur".
Definition __w : ident := $"_w".
Definition __wcrtomb_state : ident := $"_wcrtomb_state".
Definition __wcsrtombs_state : ident := $"_wcsrtombs_state".
Definition __wctomb_state : ident := $"_wctomb_state".
Definition __wds : ident := $"_wds".
Definition __write : ident := $"_write".
Definition __x : ident := $"_x".
Definition _acquire : ident := $"acquire".
Definition _argc : ident := $"argc".
Definition _argv : ident := $"argv".
Definition _atoi : ident := $"atoi".
Definition _atom_int : ident := $"atom_int".
Definition _closure : ident := $"closure".
Definition _d : ident := $"d".
Definition _delta : ident := $"delta".
Definition _delta_next : ident := $"delta_next".
Definition _delta_next__1 : ident := $"delta_next__1".
Definition _do_tasks : ident := $"do_tasks".
Definition _dotprod : ident := $"dotprod".
Definition _dotprod_task : ident := $"dotprod_task".
Definition _dotprod_worker : ident := $"dotprod_worker".
Definition _dtasks : ident := $"dtasks".
Definition _exit : ident := $"exit".
Definition _fprintf : ident := $"fprintf".
Definition _freelock : ident := $"freelock".
Definition _goal : ident := $"goal".
Definition _i : ident := $"i".
Definition _initialize_task : ident := $"initialize_task".
Definition _j : ident := $"j".
Definition _main : ident := $"main".
Definition _make_dotprod_tasks : ident := $"make_dotprod_tasks".
Definition _make_tasks : ident := $"make_tasks".
Definition _makelock : ident := $"makelock".
Definition _malloc : ident := $"malloc".
Definition _n : ident := $"n".
Definition _num_threads : ident := $"num_threads".
Definition _placeholder : ident := $"placeholder".
Definition _printf : ident := $"printf".
Definition _release : ident := $"release".
Definition _result : ident := $"result".
Definition _spawn : ident := $"spawn".
Definition _t : ident := $"t".
Definition _task : ident := $"task".
Definition _tasks : ident := $"tasks".
Definition _test : ident := $"test".
Definition _tp : ident := $"tp".
Definition _vec1 : ident := $"vec1".
Definition _vec2 : ident := $"vec2".
Definition _w : ident := $"w".
Definition _t'1 : ident := 128%positive.
Definition _t'2 : ident := 129%positive.
Definition _t'3 : ident := 130%positive.
Definition _t'4 : ident := 131%positive.
Definition _t'5 : ident := 132%positive.

Definition v_tasks := {|
  gvar_info := (tptr (Tstruct _task noattr));
  gvar_init := (Init_space 4 :: nil);
  gvar_readonly := false;
  gvar_volatile := false
|}.

Definition v_num_threads := {|
  gvar_info := tuint;
  gvar_init := (Init_space 4 :: nil);
  gvar_readonly := false;
  gvar_volatile := false
|}.

Definition v_dtasks := {|
  gvar_info := (tptr (Tstruct _dotprod_task noattr));
  gvar_init := (Init_space 4 :: nil);
  gvar_readonly := false;
  gvar_volatile := false
|}.

Definition f_dotprod_worker := {|
  fn_return := tvoid;
  fn_callconv := cc_default;
  fn_params := ((_closure, (tptr tvoid)) :: nil);
  fn_vars := nil;
  fn_temps := ((_w, (tptr (Tstruct _dotprod_task noattr))) ::
               (_result, tdouble) :: (_n, tuint) ::
               (_vec1, (tptr tdouble)) :: (_vec2, (tptr tdouble)) ::
               (_i, tuint) :: (_t'2, tdouble) :: (_t'1, tdouble) :: nil);
  fn_body :=
(Ssequence
  (Sset _w
    (Ecast (Etempvar _closure (tptr tvoid))
      (tptr (Tstruct _dotprod_task noattr))))
  (Ssequence
    (Sset _result (Econst_float (Float.of_bits (Int64.repr 0)) tdouble))
    (Ssequence
      (Sset _n
        (Efield
          (Ederef (Etempvar _w (tptr (Tstruct _dotprod_task noattr)))
            (Tstruct _dotprod_task noattr)) _n tuint))
      (Ssequence
        (Sset _vec1
          (Efield
            (Ederef (Etempvar _w (tptr (Tstruct _dotprod_task noattr)))
              (Tstruct _dotprod_task noattr)) _vec1 (tptr tdouble)))
        (Ssequence
          (Sset _vec2
            (Efield
              (Ederef (Etempvar _w (tptr (Tstruct _dotprod_task noattr)))
                (Tstruct _dotprod_task noattr)) _vec2 (tptr tdouble)))
          (Ssequence
            (Ssequence
              (Sset _i (Econst_int (Int.repr 0) tint))
              (Sloop
                (Ssequence
                  (Sifthenelse (Ebinop Olt (Etempvar _i tuint)
                                 (Etempvar _n tuint) tint)
                    Sskip
                    Sbreak)
                  (Ssequence
                    (Sset _t'1
                      (Ederef
                        (Ebinop Oadd (Etempvar _vec1 (tptr tdouble))
                          (Etempvar _i tuint) (tptr tdouble)) tdouble))
                    (Ssequence
                      (Sset _t'2
                        (Ederef
                          (Ebinop Oadd (Etempvar _vec2 (tptr tdouble))
                            (Etempvar _i tuint) (tptr tdouble)) tdouble))
                      (Sset _result
                        (Ebinop Oadd (Etempvar _result tdouble)
                          (Ebinop Omul (Etempvar _t'1 tdouble)
                            (Etempvar _t'2 tdouble) tdouble) tdouble)))))
                (Sset _i
                  (Ebinop Oadd (Etempvar _i tuint)
                    (Econst_int (Int.repr 1) tint) tuint))))
            (Sassign
              (Efield
                (Ederef (Etempvar _w (tptr (Tstruct _dotprod_task noattr)))
                  (Tstruct _dotprod_task noattr)) _result tdouble)
              (Etempvar _result tdouble))))))))
|}.

Definition f_dotprod := {|
  fn_return := tdouble;
  fn_callconv := cc_default;
  fn_params := ((_vec1, (tptr tdouble)) :: (_vec2, (tptr tdouble)) ::
                (_n, tuint) :: nil);
  fn_vars := nil;
  fn_temps := ((_result, tdouble) :: (_T, tuint) :: (_t, tuint) ::
               (_delta, tuint) :: (_delta_next, tuint) ::
               (_tp, (tptr (Tstruct _dotprod_task noattr))) ::
               (_delta_next__1, tuint) ::
               (_t'4, (tptr (Tstruct _dotprod_task noattr))) ::
               (_t'3, (tptr (Tstruct _task noattr))) :: (_t'2, tdouble) ::
               (_t'1, (tptr (Tstruct _dotprod_task noattr))) :: nil);
  fn_body :=
(Ssequence
  (Sset _T (Evar _num_threads tuint))
  (Ssequence
    (Sset _delta (Econst_int (Int.repr 0) tint))
    (Ssequence
      (Ssequence
        (Sset _t (Econst_int (Int.repr 0) tint))
        (Sloop
          (Ssequence
            (Sifthenelse (Ebinop Olt (Etempvar _t tuint) (Etempvar _T tuint)
                           tint)
              Sskip
              Sbreak)
            (Ssequence
              (Ssequence
                (Sset _t'4
                  (Evar _dtasks (tptr (Tstruct _dotprod_task noattr))))
                (Sset _tp
                  (Ebinop Oadd
                    (Etempvar _t'4 (tptr (Tstruct _dotprod_task noattr)))
                    (Etempvar _t tuint)
                    (tptr (Tstruct _dotprod_task noattr)))))
              (Ssequence
                (Sassign
                  (Efield
                    (Ederef
                      (Etempvar _tp (tptr (Tstruct _dotprod_task noattr)))
                      (Tstruct _dotprod_task noattr)) _vec1 (tptr tdouble))
                  (Ebinop Oadd (Etempvar _vec1 (tptr tdouble))
                    (Etempvar _delta tuint) (tptr tdouble)))
                (Ssequence
                  (Sassign
                    (Efield
                      (Ederef
                        (Etempvar _tp (tptr (Tstruct _dotprod_task noattr)))
                        (Tstruct _dotprod_task noattr)) _vec2 (tptr tdouble))
                    (Ebinop Oadd (Etempvar _vec2 (tptr tdouble))
                      (Etempvar _delta tuint) (tptr tdouble)))
                  (Ssequence
                    (Sset _delta_next__1
                      (Ecast
                        (Ebinop Odiv
                          (Ebinop Omul
                            (Ecast
                              (Ebinop Oadd (Etempvar _t tuint)
                                (Econst_int (Int.repr 1) tint) tuint) tulong)
                            (Ecast (Etempvar _n tuint) tulong) tulong)
                          (Ecast (Etempvar _T tuint) tulong) tulong) tuint))
                    (Ssequence
                      (Sassign
                        (Efield
                          (Ederef
                            (Etempvar _tp (tptr (Tstruct _dotprod_task noattr)))
                            (Tstruct _dotprod_task noattr)) _n tuint)
                        (Ebinop Osub (Etempvar _delta_next__1 tuint)
                          (Etempvar _delta tuint) tuint))
                      (Sset _delta (Etempvar _delta_next__1 tuint))))))))
          (Sset _t
            (Ebinop Oadd (Etempvar _t tuint) (Econst_int (Int.repr 1) tint)
              tuint))))
      (Ssequence
        (Ssequence
          (Sset _t'3 (Evar _tasks (tptr (Tstruct _task noattr))))
          (Scall None
            (Evar _do_tasks (Tfunction
                              (Tcons (tptr (Tstruct _task noattr))
                                (Tcons tuint Tnil)) tvoid cc_default))
            ((Etempvar _t'3 (tptr (Tstruct _task noattr))) ::
             (Etempvar _T tuint) :: nil)))
        (Ssequence
          (Sset _result
            (Econst_float (Float.of_bits (Int64.repr 0)) tdouble))
          (Ssequence
            (Ssequence
              (Sset _t (Econst_int (Int.repr 0) tint))
              (Sloop
                (Ssequence
                  (Sifthenelse (Ebinop Olt (Etempvar _t tuint)
                                 (Etempvar _T tuint) tint)
                    Sskip
                    Sbreak)
                  (Ssequence
                    (Sset _t'1
                      (Evar _dtasks (tptr (Tstruct _dotprod_task noattr))))
                    (Ssequence
                      (Sset _t'2
                        (Efield
                          (Ederef
                            (Ebinop Oadd
                              (Etempvar _t'1 (tptr (Tstruct _dotprod_task noattr)))
                              (Etempvar _t tuint)
                              (tptr (Tstruct _dotprod_task noattr)))
                            (Tstruct _dotprod_task noattr)) _result tdouble))
                      (Sset _result
                        (Ebinop Oadd (Etempvar _result tdouble)
                          (Etempvar _t'2 tdouble) tdouble)))))
                (Sset _t
                  (Ebinop Oadd (Etempvar _t tuint)
                    (Econst_int (Int.repr 1) tint) tuint))))
            (Sreturn (Some (Etempvar _result tdouble)))))))))
|}.

Definition f_make_dotprod_tasks := {|
  fn_return := tvoid;
  fn_callconv := cc_default;
  fn_params := ((_T, tuint) :: nil);
  fn_vars := nil;
  fn_temps := ((_t, tuint) :: (_t'2, (tptr tvoid)) ::
               (_t'1, (tptr (Tstruct _task noattr))) ::
               (_t'5, (tptr (Tstruct _dotprod_task noattr))) ::
               (_t'4, (tptr (Tstruct _dotprod_task noattr))) ::
               (_t'3, (tptr (Tstruct _task noattr))) :: nil);
  fn_body :=
(Ssequence
  (Ssequence
    (Scall (Some _t'1)
      (Evar _make_tasks (Tfunction (Tcons tuint Tnil)
                          (tptr (Tstruct _task noattr)) cc_default))
      ((Etempvar _T tuint) :: nil))
    (Sassign (Evar _tasks (tptr (Tstruct _task noattr)))
      (Etempvar _t'1 (tptr (Tstruct _task noattr)))))
  (Ssequence
    (Sassign (Evar _num_threads tuint) (Etempvar _T tuint))
    (Ssequence
      (Ssequence
        (Scall (Some _t'2)
          (Evar _malloc (Tfunction (Tcons tuint Tnil) (tptr tvoid)
                          cc_default))
          ((Ebinop Omul (Etempvar _T tuint)
             (Esizeof (Tstruct _dotprod_task noattr) tuint) tuint) :: nil))
        (Sassign (Evar _dtasks (tptr (Tstruct _dotprod_task noattr)))
          (Ecast (Etempvar _t'2 (tptr tvoid))
            (tptr (Tstruct _dotprod_task noattr)))))
      (Ssequence
        (Ssequence
          (Sset _t'5 (Evar _dtasks (tptr (Tstruct _dotprod_task noattr))))
          (Sifthenelse (Eunop Onotbool
                         (Etempvar _t'5 (tptr (Tstruct _dotprod_task noattr)))
                         tint)
            (Scall None
              (Evar _exit (Tfunction (Tcons tint Tnil) tvoid cc_default))
              ((Econst_int (Int.repr 1) tint) :: nil))
            Sskip))
        (Ssequence
          (Sset _t (Econst_int (Int.repr 0) tint))
          (Sloop
            (Ssequence
              (Sifthenelse (Ebinop Olt (Etempvar _t tuint)
                             (Etempvar _T tuint) tint)
                Sskip
                Sbreak)
              (Ssequence
                (Sset _t'3 (Evar _tasks (tptr (Tstruct _task noattr))))
                (Ssequence
                  (Sset _t'4
                    (Evar _dtasks (tptr (Tstruct _dotprod_task noattr))))
                  (Scall None
                    (Evar _initialize_task (Tfunction
                                             (Tcons
                                               (tptr (Tstruct _task noattr))
                                               (Tcons tuint
                                                 (Tcons
                                                   (tptr (Tfunction
                                                           (Tcons
                                                             (tptr tvoid)
                                                             Tnil) tvoid
                                                           cc_default))
                                                   (Tcons (tptr tvoid) Tnil))))
                                             tvoid cc_default))
                    ((Etempvar _t'3 (tptr (Tstruct _task noattr))) ::
                     (Etempvar _t tuint) ::
                     (Evar _dotprod_worker (Tfunction
                                             (Tcons (tptr tvoid) Tnil) tvoid
                                             cc_default)) ::
                     (Ebinop Oadd
                       (Etempvar _t'4 (tptr (Tstruct _dotprod_task noattr)))
                       (Etempvar _t tuint)
                       (tptr (Tstruct _dotprod_task noattr))) :: nil)))))
            (Sset _t
              (Ebinop Oadd (Etempvar _t tuint) (Econst_int (Int.repr 1) tint)
                tuint))))))))
|}.

Definition composites : list composite_definition :=
(Composite _dotprod_task Struct
   (Member_plain _vec1 (tptr tdouble) :: Member_plain _vec2 (tptr tdouble) ::
    Member_plain _n tuint :: Member_plain _result tdouble :: nil)
   noattr :: nil).

Definition global_definitions : list (ident * globdef fundef type) :=
((___compcert_va_int32,
   Gfun(External (EF_runtime "__compcert_va_int32"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons (tptr tvoid) Tnil) tuint cc_default)) ::
 (___compcert_va_int64,
   Gfun(External (EF_runtime "__compcert_va_int64"
                   (mksignature (AST.Tint :: nil) AST.Tlong cc_default))
     (Tcons (tptr tvoid) Tnil) tulong cc_default)) ::
 (___compcert_va_float64,
   Gfun(External (EF_runtime "__compcert_va_float64"
                   (mksignature (AST.Tint :: nil) AST.Tfloat cc_default))
     (Tcons (tptr tvoid) Tnil) tdouble cc_default)) ::
 (___compcert_va_composite,
   Gfun(External (EF_runtime "__compcert_va_composite"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tint
                     cc_default)) (Tcons (tptr tvoid) (Tcons tuint Tnil))
     (tptr tvoid) cc_default)) ::
 (___compcert_i64_dtos,
   Gfun(External (EF_runtime "__compcert_i64_dtos"
                   (mksignature (AST.Tfloat :: nil) AST.Tlong cc_default))
     (Tcons tdouble Tnil) tlong cc_default)) ::
 (___compcert_i64_dtou,
   Gfun(External (EF_runtime "__compcert_i64_dtou"
                   (mksignature (AST.Tfloat :: nil) AST.Tlong cc_default))
     (Tcons tdouble Tnil) tulong cc_default)) ::
 (___compcert_i64_stod,
   Gfun(External (EF_runtime "__compcert_i64_stod"
                   (mksignature (AST.Tlong :: nil) AST.Tfloat cc_default))
     (Tcons tlong Tnil) tdouble cc_default)) ::
 (___compcert_i64_utod,
   Gfun(External (EF_runtime "__compcert_i64_utod"
                   (mksignature (AST.Tlong :: nil) AST.Tfloat cc_default))
     (Tcons tulong Tnil) tdouble cc_default)) ::
 (___compcert_i64_stof,
   Gfun(External (EF_runtime "__compcert_i64_stof"
                   (mksignature (AST.Tlong :: nil) AST.Tsingle cc_default))
     (Tcons tlong Tnil) tfloat cc_default)) ::
 (___compcert_i64_utof,
   Gfun(External (EF_runtime "__compcert_i64_utof"
                   (mksignature (AST.Tlong :: nil) AST.Tsingle cc_default))
     (Tcons tulong Tnil) tfloat cc_default)) ::
 (___compcert_i64_sdiv,
   Gfun(External (EF_runtime "__compcert_i64_sdiv"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tlong Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_udiv,
   Gfun(External (EF_runtime "__compcert_i64_udiv"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tulong (Tcons tulong Tnil)) tulong
     cc_default)) ::
 (___compcert_i64_smod,
   Gfun(External (EF_runtime "__compcert_i64_smod"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tlong Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_umod,
   Gfun(External (EF_runtime "__compcert_i64_umod"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tulong (Tcons tulong Tnil)) tulong
     cc_default)) ::
 (___compcert_i64_shl,
   Gfun(External (EF_runtime "__compcert_i64_shl"
                   (mksignature (AST.Tlong :: AST.Tint :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tint Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_shr,
   Gfun(External (EF_runtime "__compcert_i64_shr"
                   (mksignature (AST.Tlong :: AST.Tint :: nil) AST.Tlong
                     cc_default)) (Tcons tulong (Tcons tint Tnil)) tulong
     cc_default)) ::
 (___compcert_i64_sar,
   Gfun(External (EF_runtime "__compcert_i64_sar"
                   (mksignature (AST.Tlong :: AST.Tint :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tint Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_smulh,
   Gfun(External (EF_runtime "__compcert_i64_smulh"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tlong Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_umulh,
   Gfun(External (EF_runtime "__compcert_i64_umulh"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tulong (Tcons tulong Tnil)) tulong
     cc_default)) ::
 (___builtin_bswap64,
   Gfun(External (EF_builtin "__builtin_bswap64"
                   (mksignature (AST.Tlong :: nil) AST.Tlong cc_default))
     (Tcons tulong Tnil) tulong cc_default)) ::
 (___builtin_bswap,
   Gfun(External (EF_builtin "__builtin_bswap"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tuint cc_default)) ::
 (___builtin_bswap32,
   Gfun(External (EF_builtin "__builtin_bswap32"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tuint cc_default)) ::
 (___builtin_bswap16,
   Gfun(External (EF_builtin "__builtin_bswap16"
                   (mksignature (AST.Tint :: nil) AST.Tint16unsigned
                     cc_default)) (Tcons tushort Tnil) tushort cc_default)) ::
 (___builtin_clz,
   Gfun(External (EF_builtin "__builtin_clz"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tint cc_default)) ::
 (___builtin_clzl,
   Gfun(External (EF_builtin "__builtin_clzl"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tint cc_default)) ::
 (___builtin_clzll,
   Gfun(External (EF_builtin "__builtin_clzll"
                   (mksignature (AST.Tlong :: nil) AST.Tint cc_default))
     (Tcons tulong Tnil) tint cc_default)) ::
 (___builtin_ctz,
   Gfun(External (EF_builtin "__builtin_ctz"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tint cc_default)) ::
 (___builtin_ctzl,
   Gfun(External (EF_builtin "__builtin_ctzl"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tint cc_default)) ::
 (___builtin_ctzll,
   Gfun(External (EF_builtin "__builtin_ctzll"
                   (mksignature (AST.Tlong :: nil) AST.Tint cc_default))
     (Tcons tulong Tnil) tint cc_default)) ::
 (___builtin_fabs,
   Gfun(External (EF_builtin "__builtin_fabs"
                   (mksignature (AST.Tfloat :: nil) AST.Tfloat cc_default))
     (Tcons tdouble Tnil) tdouble cc_default)) ::
 (___builtin_fabsf,
   Gfun(External (EF_builtin "__builtin_fabsf"
                   (mksignature (AST.Tsingle :: nil) AST.Tsingle cc_default))
     (Tcons tfloat Tnil) tfloat cc_default)) ::
 (___builtin_fsqrt,
   Gfun(External (EF_builtin "__builtin_fsqrt"
                   (mksignature (AST.Tfloat :: nil) AST.Tfloat cc_default))
     (Tcons tdouble Tnil) tdouble cc_default)) ::
 (___builtin_sqrt,
   Gfun(External (EF_builtin "__builtin_sqrt"
                   (mksignature (AST.Tfloat :: nil) AST.Tfloat cc_default))
     (Tcons tdouble Tnil) tdouble cc_default)) ::
 (___builtin_memcpy_aligned,
   Gfun(External (EF_builtin "__builtin_memcpy_aligned"
                   (mksignature
                     (AST.Tint :: AST.Tint :: AST.Tint :: AST.Tint :: nil)
                     AST.Tvoid cc_default))
     (Tcons (tptr tvoid)
       (Tcons (tptr tvoid) (Tcons tuint (Tcons tuint Tnil)))) tvoid
     cc_default)) ::
 (___builtin_sel,
   Gfun(External (EF_builtin "__builtin_sel"
                   (mksignature (AST.Tint :: nil) AST.Tvoid
                     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|}))
     (Tcons tbool Tnil) tvoid
     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|})) ::
 (___builtin_annot,
   Gfun(External (EF_builtin "__builtin_annot"
                   (mksignature (AST.Tint :: nil) AST.Tvoid
                     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|}))
     (Tcons (tptr tschar) Tnil) tvoid
     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|})) ::
 (___builtin_annot_intval,
   Gfun(External (EF_builtin "__builtin_annot_intval"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tint
                     cc_default)) (Tcons (tptr tschar) (Tcons tint Tnil))
     tint cc_default)) ::
 (___builtin_membar,
   Gfun(External (EF_builtin "__builtin_membar"
                   (mksignature nil AST.Tvoid cc_default)) Tnil tvoid
     cc_default)) ::
 (___builtin_va_start,
   Gfun(External (EF_builtin "__builtin_va_start"
                   (mksignature (AST.Tint :: nil) AST.Tvoid cc_default))
     (Tcons (tptr tvoid) Tnil) tvoid cc_default)) ::
 (___builtin_va_arg,
   Gfun(External (EF_builtin "__builtin_va_arg"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default)) (Tcons (tptr tvoid) (Tcons tuint Tnil))
     tvoid cc_default)) ::
 (___builtin_va_copy,
   Gfun(External (EF_builtin "__builtin_va_copy"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default))
     (Tcons (tptr tvoid) (Tcons (tptr tvoid) Tnil)) tvoid cc_default)) ::
 (___builtin_va_end,
   Gfun(External (EF_builtin "__builtin_va_end"
                   (mksignature (AST.Tint :: nil) AST.Tvoid cc_default))
     (Tcons (tptr tvoid) Tnil) tvoid cc_default)) ::
 (___builtin_unreachable,
   Gfun(External (EF_builtin "__builtin_unreachable"
                   (mksignature nil AST.Tvoid cc_default)) Tnil tvoid
     cc_default)) ::
 (___builtin_expect,
   Gfun(External (EF_builtin "__builtin_expect"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tint
                     cc_default)) (Tcons tint (Tcons tint Tnil)) tint
     cc_default)) ::
 (___builtin_fmax,
   Gfun(External (EF_builtin "__builtin_fmax"
                   (mksignature (AST.Tfloat :: AST.Tfloat :: nil) AST.Tfloat
                     cc_default)) (Tcons tdouble (Tcons tdouble Tnil))
     tdouble cc_default)) ::
 (___builtin_fmin,
   Gfun(External (EF_builtin "__builtin_fmin"
                   (mksignature (AST.Tfloat :: AST.Tfloat :: nil) AST.Tfloat
                     cc_default)) (Tcons tdouble (Tcons tdouble Tnil))
     tdouble cc_default)) ::
 (___builtin_fmadd,
   Gfun(External (EF_builtin "__builtin_fmadd"
                   (mksignature
                     (AST.Tfloat :: AST.Tfloat :: AST.Tfloat :: nil)
                     AST.Tfloat cc_default))
     (Tcons tdouble (Tcons tdouble (Tcons tdouble Tnil))) tdouble
     cc_default)) ::
 (___builtin_fmsub,
   Gfun(External (EF_builtin "__builtin_fmsub"
                   (mksignature
                     (AST.Tfloat :: AST.Tfloat :: AST.Tfloat :: nil)
                     AST.Tfloat cc_default))
     (Tcons tdouble (Tcons tdouble (Tcons tdouble Tnil))) tdouble
     cc_default)) ::
 (___builtin_fnmadd,
   Gfun(External (EF_builtin "__builtin_fnmadd"
                   (mksignature
                     (AST.Tfloat :: AST.Tfloat :: AST.Tfloat :: nil)
                     AST.Tfloat cc_default))
     (Tcons tdouble (Tcons tdouble (Tcons tdouble Tnil))) tdouble
     cc_default)) ::
 (___builtin_fnmsub,
   Gfun(External (EF_builtin "__builtin_fnmsub"
                   (mksignature
                     (AST.Tfloat :: AST.Tfloat :: AST.Tfloat :: nil)
                     AST.Tfloat cc_default))
     (Tcons tdouble (Tcons tdouble (Tcons tdouble Tnil))) tdouble
     cc_default)) ::
 (___builtin_read16_reversed,
   Gfun(External (EF_builtin "__builtin_read16_reversed"
                   (mksignature (AST.Tint :: nil) AST.Tint16unsigned
                     cc_default)) (Tcons (tptr tushort) Tnil) tushort
     cc_default)) ::
 (___builtin_read32_reversed,
   Gfun(External (EF_builtin "__builtin_read32_reversed"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons (tptr tuint) Tnil) tuint cc_default)) ::
 (___builtin_write16_reversed,
   Gfun(External (EF_builtin "__builtin_write16_reversed"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default)) (Tcons (tptr tushort) (Tcons tushort Tnil))
     tvoid cc_default)) ::
 (___builtin_write32_reversed,
   Gfun(External (EF_builtin "__builtin_write32_reversed"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default)) (Tcons (tptr tuint) (Tcons tuint Tnil))
     tvoid cc_default)) ::
 (___builtin_debug,
   Gfun(External (EF_external "__builtin_debug"
                   (mksignature (AST.Tint :: nil) AST.Tvoid
                     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|}))
     (Tcons tint Tnil) tvoid
     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|})) ::
 (_exit,
   Gfun(External (EF_external "exit"
                   (mksignature (AST.Tint :: nil) AST.Tvoid cc_default))
     (Tcons tint Tnil) tvoid cc_default)) ::
 (_malloc,
   Gfun(External EF_malloc (Tcons tuint Tnil) (tptr tvoid) cc_default)) ::
 (_make_tasks,
   Gfun(External (EF_external "make_tasks"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) (tptr (Tstruct _task noattr)) cc_default)) ::
 (_initialize_task,
   Gfun(External (EF_external "initialize_task"
                   (mksignature
                     (AST.Tint :: AST.Tint :: AST.Tint :: AST.Tint :: nil)
                     AST.Tvoid cc_default))
     (Tcons (tptr (Tstruct _task noattr))
       (Tcons tuint
         (Tcons (tptr (Tfunction (Tcons (tptr tvoid) Tnil) tvoid cc_default))
           (Tcons (tptr tvoid) Tnil)))) tvoid cc_default)) ::
 (_do_tasks,
   Gfun(External (EF_external "do_tasks"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default))
     (Tcons (tptr (Tstruct _task noattr)) (Tcons tuint Tnil)) tvoid
     cc_default)) :: (_tasks, Gvar v_tasks) ::
 (_num_threads, Gvar v_num_threads) :: (_dtasks, Gvar v_dtasks) ::
 (_dotprod_worker, Gfun(Internal f_dotprod_worker)) ::
 (_dotprod, Gfun(Internal f_dotprod)) ::
 (_make_dotprod_tasks, Gfun(Internal f_make_dotprod_tasks)) :: nil).

Definition public_idents : list ident :=
(_make_dotprod_tasks :: _dotprod :: _dotprod_worker :: _dtasks ::
 _num_threads :: _tasks :: _do_tasks :: _initialize_task :: _make_tasks ::
 _malloc :: _exit :: ___builtin_debug :: ___builtin_write32_reversed ::
 ___builtin_write16_reversed :: ___builtin_read32_reversed ::
 ___builtin_read16_reversed :: ___builtin_fnmsub :: ___builtin_fnmadd ::
 ___builtin_fmsub :: ___builtin_fmadd :: ___builtin_fmin ::
 ___builtin_fmax :: ___builtin_expect :: ___builtin_unreachable ::
 ___builtin_va_end :: ___builtin_va_copy :: ___builtin_va_arg ::
 ___builtin_va_start :: ___builtin_membar :: ___builtin_annot_intval ::
 ___builtin_annot :: ___builtin_sel :: ___builtin_memcpy_aligned ::
 ___builtin_sqrt :: ___builtin_fsqrt :: ___builtin_fabsf ::
 ___builtin_fabs :: ___builtin_ctzll :: ___builtin_ctzl :: ___builtin_ctz ::
 ___builtin_clzll :: ___builtin_clzl :: ___builtin_clz ::
 ___builtin_bswap16 :: ___builtin_bswap32 :: ___builtin_bswap ::
 ___builtin_bswap64 :: ___compcert_i64_umulh :: ___compcert_i64_smulh ::
 ___compcert_i64_sar :: ___compcert_i64_shr :: ___compcert_i64_shl ::
 ___compcert_i64_umod :: ___compcert_i64_smod :: ___compcert_i64_udiv ::
 ___compcert_i64_sdiv :: ___compcert_i64_utof :: ___compcert_i64_stof ::
 ___compcert_i64_utod :: ___compcert_i64_stod :: ___compcert_i64_dtou ::
 ___compcert_i64_dtos :: ___compcert_va_composite ::
 ___compcert_va_float64 :: ___compcert_va_int64 :: ___compcert_va_int32 ::
 nil).

Definition prog : Clight.program :=
  mkprogram composites global_definitions public_idents _main Logic.I.