Inductive RTL_core : Type :=
  | RTL_State:
      forall (stack: list stackframe) (**r call stack *)
             (f: function)            (**r current function *)
             (sp: val)                (**r stack pointer *)
             (pc: node)               (**r current program point in [c] *)
             (rs: regset),             (**r register state *)
      RTL_core
  | RTL_Callstate:
      forall (stack: list stackframe) (**r call stack *)
             (f: fundef)              (**r function to call *)
             (args: list val),         (**r arguments to the call *)
      RTL_core
  | RTL_Returnstate:
      forall (stack: list stackframe) (**r call stack *)
             (v: val),                 (**r return value for the call *)
      RTL_core.Inductive RTL_core : Type :=
  | RTL_State:
      forall (stack: list stackframe) (**r call stack *)
             (f: function)            (**r current function *)
             (sp: val)                (**r stack pointer *)
             (pc: node)               (**r current program point in [c] *)
             (rs: regset),             (**r register state *)
      RTL_core
  | RTL_Callstate:
      forall (stack: list stackframe) (**r call stack *)
             (f: fundef)              (**r function to call *)
             (args: list val),         (**r arguments to the call *)
      RTL_core
  | RTL_Returnstate:
      forall (stack: list stackframe) (**r call stack *)
             (v: val),                 (**r return value for the call *)
      RTL_core.Inductive RTL_core : Type :=
  | RTL_State:
      forall (stack: list stackframe) (**r call stack *)
             (f: function)            (**r current function *)
             (sp: val)                (**r stack pointer *)
             (pc: node)               (**r current program point in [c] *)
             (rs: regset),             (**r register state *)
      RTL_core
  | RTL_Callstate:
      forall (stack: list stackframe) (**r call stack *)
             (f: fundef)              (**r function to call *)
             (args: list val),         (**r arguments to the call *)
      RTL_core
  | RTL_Returnstate:
      forall (stack: list stackframe) (**r call stack *)
             (v: val),                 (**r return value for the call *)
      RTL_core.Inductive RTL_core : Type :=
  | RTL_State:
      forall (stack: list stackframe) (**r call stack *)
             (f: function)            (**r current function *)
             (sp: val)                (**r stack pointer *)
             (pc: node)               (**r current program point in [c] *)
             (rs: regset),             (**r register state *)
      RTL_core
  | RTL_Callstate:
      forall (stack: list stackframe) (**r call stack *)
             (f: fundef)              (**r function to call *)
             (args: list val),         (**r arguments to the call *)
      RTL_core
  | RTL_Returnstate:
      forall (stack: list stackframe) (**r call stack *)
             (v: val),                 (**r return value for the call *)
      RTL_core.(* Transformations between the new and the old definitions of state *)
Definition core2state (q:RTL_core)(m:mem): state:=
  match q with
      RTL_State stack f sp pc rs => State stack f sp pc rs m
    | RTL_Callstate stack f args => Callstate stack f args m
    | RTL_Returnstate stack v => Returnstate stack v m
  end.Definition state2core (s:state): RTL_core * mem :=
  match s with
      State stack f sp pc rs m => (RTL_State stack f sp pc rs, m)
    | Callstate stack f args m => (RTL_Callstate stack f args, m)
    | Returnstate stack v m => (RTL_Returnstate stack v, m)
  end.(* New initial state *)
Definition RTL_initial_core (ge: genv) (v:val)(args: list val): option RTL_core:=
  match v with
      Vptr b i =>
      if Int.eq_dec i Int.zero
      then match Genv.find_funct_ptr ge b with
               None => None
             | Some f => Some (RTL_Callstate nil f args)
           end
      else None
    | _ => None
  end.(** A final state is a [Returnstate] with an empty call stack. *)

(*LENB: in shared-memory compcert, we should allow arbitrary
  return values, not just integers*)
Definition RTL_halted (c: RTL_core ): option val :=
  match c with
(*      RTL_Returnstate nil (Vint i) => Some (Vint i)*)
      RTL_Returnstate nil v => Some v
    | _ => None
  end.(* New definition of semantics *)
Definition RTL_at_external (c: RTL_core): option (external_function * signature * list val) :=
  match c with
    | RTL_State stack f sp pc rs => None
    | RTL_Callstate stack f args =>  match f with
                                        Internal _ => None
                                      | External f' => Some( f', ef_sig f', args)
                                    end
    | RTL_Returnstate stack v => None
  end.Definition RTL_after_external (vret: option val)(c: RTL_core): option RTL_core :=
  match c with
    | RTL_State stack f sp pc rs => None
    | RTL_Callstate stack f args =>
      match f with
          Internal _ => None
        | External f' => match vret with
                             None => Some (RTL_Returnstate stack Vundef)
                           | Some v => Some (RTL_Returnstate stack v)
                         end
      end
    | RTL_Returnstate stack v => None
  end.

(* Specifications: *)
Lemma corestep_not_external: forall (ge : genv) (m : mem) (q : RTL_core) (m' : mem) (q' : RTL_core), RTL_corestep ge q m q' m' -> RTL_at_external q = None.
Lemma corestep_not_halted: forall (ge : genv) (m : mem) (q : RTL_core) (m' : mem) (q' : RTL_core), RTL_corestep ge q m q' m' -> RTL_halted q = None.
Lemma external_xor_halted: forall q : RTL_core, RTL_at_external q = None \/ RTL_halted q = None.
Lemma after_xor_at_external: forall (retv : option val) (q q' : RTL_core), RTL_after_external retv q = Some q' -> RTL_at_external q' = None.