Section WT_INSTR.
Variable funct: function.
Definition slot_valid (sl: slot) (ofs: Z) (ty: typ): bool :=
match sl with
| Local => zle 0 ofs
| Outgoing => zle 0 ofs
| Incoming => In_dec Loc.eq (S Incoming ofs ty) (regs_of_rpairs (loc_parameters funct.(fn_sig)))
end
&& Zdivide_dec (typealign ty) ofs.
Definition slot_writable (sl: slot) : bool :=
match sl with
| Local => true
| Outgoing => true
| Incoming => false
end.
Definition loc_valid (l: loc) : bool :=
match l with
| R r => true
| S Local ofs ty => slot_valid Local ofs ty
| S _ _ _ => false
end.
Fixpoint wt_builtin_res (ty: typ) (res: builtin_res mreg) : bool :=
match res with
| BR r => subtype ty (mreg_type r)
| BR_none => true
| BR_splitlong hi lo => wt_builtin_res Tint hi && wt_builtin_res Tint lo
end.
Definition wt_instr (i: instruction) : bool :=
match i with
| Lgetstack sl ofs ty r =>
subtype ty (mreg_type r) && slot_valid sl ofs ty
| Lsetstack r sl ofs ty =>
slot_valid sl ofs ty && slot_writable sl
| Lop op args res =>
match is_move_operation op args with
| Some arg =>
subtype (mreg_type arg) (mreg_type res)
| None =>
let (targs, tres) := type_of_operation op in
subtype tres (mreg_type res)
end
| Lload chunk addr args dst =>
subtype (type_of_chunk chunk) (mreg_type dst)
| Ltailcall sg ros =>
zeq (size_arguments sg) 0
| Lbuiltin ef args res =>
wt_builtin_res (proj_sig_res (ef_sig ef)) res
&& forallb loc_valid (params_of_builtin_args args)
| _ =>
true
end.
End WT_INSTR.
Definition wt_code (f: function) (c: code) : bool :=
forallb (wt_instr f) c.
Definition wt_function (f: function) : bool :=
wt_code f f.(fn_code).
(** Typing the run-time state. *)
Definition wt_locset (ls: locset) : Prop :=
forall l, Val.has_type (ls l) (Loc.type l).
(** In addition to type preservation during evaluation, we also show properties of the environment [ls] at call points and at return points. These properties are used in the proof of the [Stacking] pass. For call points, we have that the current environment [ls] and the one from the top call stack agree on the [Outgoing] locations used for parameter passing. *)
Definition agree_outgoing_arguments (sg: signature) (ls pls: locset) : Prop :=
forall ty ofs,
In (S Outgoing ofs ty) (regs_of_rpairs (loc_arguments sg)) ->
ls (S Outgoing ofs ty) = pls (S Outgoing ofs ty).
(** For return points, we have that all [Outgoing] stack locations have been set to [Vundef]. *)
Definition outgoing_undef (ls: locset) : Prop :=
forall ty ofs, ls (S Outgoing ofs ty) = Vundef.
(** Soundness of the type system *)
Definition wt_fundef (fd: fundef) :=
match fd with
| Internal f => wt_function f = true
| External ef => True
end.
Inductive wt_callstack: list stackframe -> Prop :=
| wt_callstack_nil:
wt_callstack nil
| wt_callstack_cons: forall f sp rs c s
(WTSTK: wt_callstack s)
(WTF: wt_function f = true)
(WTC: wt_code f c = true)
(WTRS: wt_locset rs),
wt_callstack (Stackframe f sp rs c :: s).

Lemma wt_parent_locset:
forall s, wt_callstack s -> wt_locset (parent_locset s).