(* Given gfs, gfs0, and a name for gfs1, instantiate gfs1 s.t. (gfs = gfs1 ++ gfs0). Called suffix because these paths are reversed lists. *)
Ltac calc_gfs_suffix gfs gfs0 gfs1 :=
let len := fresh "len" in
pose ((length gfs - length gfs0)%nat) as len;
hnf in len;
match goal with
| len := ?len' |- _ =>
pose (firstn len' gfs) as gfs1
end;
clear len;
unfold gfs in gfs1;
let gfs1' := (eval_list gfs1) in change gfs1' in (value of gfs1);
let gfs0' := (eval_list gfs0) in change gfs0' in (value of gfs0);
change gfs with (gfs1 ++ gfs0) in *.
Ltac find_load_result Hresult t_root gfs0 v gfs1 :=
let result := fresh "result" in evar (result: val);
assert (Hresult: JMeq (proj_reptype (nested_field_type t_root gfs0) gfs1 v) result);
subst result;
[ (solve_load_rule_evaluation || fail 1000 "solve_load_rule_evaluation' failed")
| ].
Ltac solve_efield_denote Delta P Q R efs gfs H :=
evar (gfs : list gfield);
assert (ENTAIL Delta, PROPx P (LOCALx Q (SEPx R)) |-- local (efield_denote efs gfs)) as H;
[
unfold efs, gfs;
match goal with
| efs := nil |- _ =>
instantiate (1 := nil);
intros rho; apply prop_right; constructor
| efs := ?ef :: ?efs' |- _ =>
let efs0 := fresh "efs" in
let gfs0 := fresh "gfs" in
let H0 := fresh "H" in
pose efs' as efs0;
solve_efield_denote Delta P Q R efs0 gfs0 H0;
match goal with
| gfs0 := ?gfs0' |- _ =>
match ef with
| eArraySubsc ?ei =>
let HA := fresh "H" in
let vi := fresh "vi" in evar (vi: val);
do_compute_expr Delta P Q R ei vi HA;
revert vi HA;
let vvvv := fresh "vvvv" in
let HHHH := fresh "HHHH" in
match goal with
| |- let vi := ?V in _ => remember V as vvvv eqn:HHHH
end;
autorewrite with norm in HHHH;
match type of HHHH with
| _ = Vint (Int.repr _) => idtac
| _ = Vint (Int.sub _ _) => unfold Int.sub in HHHH
| _ = Vint (Int.add _ _) => unfold Int.add in HHHH
| _ = Vint (Int.mul _ _) => unfold Int.mul in HHHH
| _ = Vint (Int.and _ _) => unfold Int.and in HHHH
| _ = Vint (Int.or _ _) => unfold Int.or in HHHH
| _ = Vint ?V =>
replace V with (Int.repr (Int.unsigned V)) in HHHH
by (rewrite (Int.repr_unsigned V); reflexivity)
end;
subst vvvv; intros vi HA;
match goal with
| vi := Vint (Int.repr ?i) |- _ => instantiate (1 := ArraySubsc i :: gfs0')
end;
let HB := fresh "H" in
assert (is_int_type (typeof ei) = true) as HB by reflexivity;
apply (efield_denote_cons_array _ _ _ _ _ H0 HA HB)
| eStructField ?i =>
instantiate (1 := StructField i :: gfs0');
apply efield_denote_cons_struct, H0
| eUnionField ?i =>
instantiate (1 := UnionField i :: gfs0');
apply efield_denote_cons_union, H0
end
end
end
|].

Lemma sem_add_ptr_int_lem:
forall {cs: compspecs} v t i,
isptr v ->
Clight_Cop2.sem_add (tptr t) tint v (Vint (Int.repr i)) = Some (add_ptr_int t v i).