Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.Inductive clc_evstep: state -> mem -> list mem_event -> state -> mem -> Prop :=
  | clc_evstep_assign: forall f a1 a2 k e le m loc ofs v2 v m' T1 T2 T3 mx,
      eval_lvalueT g e le m a1 loc ofs T1 ->
      eval_exprT g e le m a2 v2 T2 ->
      sem_cast v2 (typeof a2) (typeof a1) m = Some v ->
      assign_locT g (typeof a1) m loc ofs v m' T3 ->
      clc_evstep (Clight.State f (Sassign a1 a2) k e le mx) m (T1++T2++T3)
                 (Clight.State f Sskip k e le m') m'

  | clc_evstep_set: forall f id a k e le m v T mx,
      eval_exprT g e le m a v T ->
      clc_evstep (Clight.State f (Sset id a) k e le mx) m
        T (Clight.State f Sskip k e (PTree.set id v le) m) m

  | clc_evstep_call: forall f optid a al k e le m tyargs tyres cconv vf vargs fd T1 T2 mx,
      classify_fun (typeof a) = fun_case_f tyargs tyres cconv ->
      eval_exprT g e le m a vf T1 ->
      eval_exprTlist g e le m al tyargs vargs T2 ->
      Genv.find_funct g vf = Some fd ->
      type_of_fundef fd = Tfunction tyargs tyres cconv ->
      clc_evstep (Clight.State f (Scall optid a al) k e le mx) m 
        (T1++T2) (Clight.Callstate fd vargs (Clight.Kcall optid f e le k) m) m

  | clc_evstep_builtin: forall f optid ef tyargs al k e le m vargs t vres m' T1 T2 mx,
      eval_exprTlist g e le m al tyargs vargs T1 ->
      builtin_event ef m vargs T2 ->
      Events.external_call ef g vargs m t vres m' ->
      clc_evstep (Clight.State f (Sbuiltin optid ef tyargs al) k e le mx) m
                 (T1++T2) (Clight.State f Sskip k e (set_opttemp optid vres le) m') m'
    
  | clc_evstep_seq:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Ssequence s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kseq s2 k) e le m) m
  | clc_evstep_skip_seq: forall f s k e le m mx,
      (*~ is_call_cont k ->*)
      clc_evstep (Clight.State f Sskip (Clight.Kseq s k) e le mx) m
        nil (Clight.State f s k e le m) m
  | clc_evstep_continue_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m
  | clc_evstep_break_seq: forall f s k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kseq s k) e le mx) m
        nil (Clight.State f Sbreak k e le m) m

  | clc_evstep_ifthenelse:  forall f a s1 s2 k e le m v1 b T mx,
      eval_exprT g e le m a v1 T ->
      bool_val v1 (typeof a) m = Some b ->
      clc_evstep (Clight.State f (Sifthenelse a s1 s2) k e le mx) m
        T (Clight.State f (if b then s1 else s2) k e le m) m

  | clc_evstep_loop: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f (Sloop s1 s2) k e le mx) m
        nil (Clight.State f s1 (Clight.Kloop1 s1 s2 k) e le m) m
  | clc_evstep_skip_or_continue_loop1:  forall f s1 s2 k e le m x mx,
      x = Sskip \/ x = Scontinue ->
      clc_evstep (Clight.State f x (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f s2 (Clight.Kloop2 s1 s2 k) e le m) m
  | clc_evstep_break_loop1:  forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop1 s1 s2 k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_skip_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sskip (Clight.Kloop2 s1 s2 k) e le mx) m
        nil (Clight.State f (Sloop s1 s2) k e le m) m
  | clc_evstep_break_loop2: forall f s1 s2 k e le m mx,
      clc_evstep (Clight.State f Sbreak (Clight.Kloop2 s1 s2 k) e le mx) m
                 nil (Clight.State f Sskip k e le m) m
                 
  | clc_evstep_return_0: forall f k e le m m' mx,
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn None) k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef (Clight.call_cont k) m') m'
  | clc_evstep_return_1: forall f a k e le m v v' m' T mx,
      eval_exprT g e le m a v T ->
      sem_cast v (typeof a) f.(fn_return) m = Some v' ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f (Sreturn (Some a)) k e le mx) m
        (T++Free (blocks_of_env g e)::nil) (Returnstate v' (Clight.call_cont k) m') m'
  | clc_evstep_skip_call: forall f k e le m m' mx,
      is_call_cont k ->
      Mem.free_list m (blocks_of_env g e) = Some m' ->
      clc_evstep (Clight.State f Sskip k e le mx) m
        (Free (blocks_of_env g e)::nil) (Returnstate Vundef k m') m'

  | clc_evstep_switch: forall f a sl k e le m v n T mx,
      eval_exprT g e le m a v T ->
      sem_switch_arg v (typeof a) = Some n ->
      clc_evstep (Clight.State f (Sswitch a sl) k e le mx) m
        T (Clight.State f (seq_of_labeled_statement (select_switch n sl)) (Clight.Kswitch k) e le m) m
  | clc_evstep_skip_break_switch: forall f x k e le m mx,
      x = Sskip \/ x = Sbreak ->
      clc_evstep (Clight.State f x (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Sskip k e le m) m
  | clc_evstep_continue_switch: forall f k e le m mx,
      clc_evstep (Clight.State f Scontinue (Clight.Kswitch k) e le mx) m
        nil (Clight.State f Scontinue k e le m) m

  | clc_evstep_label: forall f lbl s k e le m mx,
      clc_evstep (Clight.State f (Slabel lbl s) k e le mx) m
        nil (Clight.State f s k e le m) m

  | clc_evstep_goto: forall f lbl k e le m s' k' mx,
      Clight.find_label lbl f.(fn_body) (Clight.call_cont k) = Some (s', k') ->
      clc_evstep (Clight.State f (Sgoto lbl) k e le mx) m
        nil (Clight.State f s' k' e le m) m

  | clc_evstep_internal_function: forall f vargs k m e le m1 T mx,
      function_entryT f vargs m e le m1 T ->
      clc_evstep (Clight.Callstate (Internal f) vargs k mx) m
        T (Clight.State f f.(fn_body) k e le m1) m1
(*
  | clc_evstep_external_function: forall ef targs tres cconv vargs k m vres t m',
      external_call ef ge vargs m t vres m' ->
      clc_evstep (Clight.Callstate (External ef targs tres cconv) vargs k m)
         t (Clight.Returnstate vres k m')*)

  | clc_evstep_returnstate: forall v optid f e le k m mx,
      clc_evstep (Clight.Returnstate v (Clight.Kcall optid f e le k) mx) m
        nil (Clight.State f Sskip k e (set_opttemp optid v le) m) m.

Lemma extcall_ev_elim: forall ef g vargs m t vres m' ev (Hext: Events.external_call ef g vargs m t vres m') (Hev: builtin_event ef m vargs ev) (Hef: match ef with EF_malloc | EF_free | EF_memcpy _ _ => False | _ => True end), ev_elim m ev m'.