(** * Evaluation of builtin arguments *)
Section EVAL_BUILTIN_ARG.
Variable A: Type.
Variable ge: Senv.t.
Variable e: A -> val.
Variable sp: val.
Variable m: mem.
Inductive eval_builtin_arg: builtin_arg A -> val -> Prop :=
| eval_BA: forall x,
eval_builtin_arg (BA x) (e x)
| eval_BA_int: forall n,
eval_builtin_arg (BA_int n) (Vint n)
| eval_BA_long: forall n,
eval_builtin_arg (BA_long n) (Vlong n)
| eval_BA_float: forall n,
eval_builtin_arg (BA_float n) (Vfloat n)
| eval_BA_single: forall n,
eval_builtin_arg (BA_single n) (Vsingle n)
| eval_BA_loadstack: forall chunk ofs v,
Mem.loadv chunk m (Val.offset_ptr sp ofs) = Some v ->
eval_builtin_arg (BA_loadstack chunk ofs) v
| eval_BA_addrstack: forall ofs,
eval_builtin_arg (BA_addrstack ofs) (Val.offset_ptr sp ofs)
| eval_BA_loadglobal: forall chunk id ofs v,
Mem.loadv chunk m (Senv.symbol_address ge id ofs) = Some v ->
eval_builtin_arg (BA_loadglobal chunk id ofs) v
| eval_BA_addrglobal: forall id ofs,
eval_builtin_arg (BA_addrglobal id ofs) (Senv.symbol_address ge id ofs)
| eval_BA_splitlong: forall hi lo vhi vlo,
eval_builtin_arg hi vhi -> eval_builtin_arg lo vlo ->
eval_builtin_arg (BA_splitlong hi lo) (Val.longofwords vhi vlo)
| eval_BA_addptr: forall a1 a2 v1 v2,
eval_builtin_arg a1 v1 -> eval_builtin_arg a2 v2 ->
eval_builtin_arg (BA_addptr a1 a2)
(if Archi.ptr64 then Val.addl v1 v2 else Val.add v1 v2).
Definition eval_builtin_args (al: list (builtin_arg A)) (vl: list val) : Prop :=
list_forall2 eval_builtin_arg al vl.

Lemma eval_builtin_arg_determ:
forall a v, eval_builtin_arg a v -> forall v', eval_builtin_arg a v' -> v' = v.