Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs.  mk_varspecs prog. Defined.
Definition pair_pair_t := (Tstruct _pair_pair noattr).
Definition array_size := 100.
Definition get22_spec :=
DECLARE _get22
WITH pps: val, i: Z, x11: int, x12: int, x21: int, x22: int, sh : share
PRE [ _pps OF (tptr pair_pair_t), _i OF tint ]
PROP  (readable_share sh; 0 <= i < array_size)
LOCAL (temp _pps pps; temp _i (Vint (Int.repr i)))
SEP   (field_at sh (tarray pair_pair_t array_size) [ArraySubsc i]
((Vint x11, Vint x12), (Vint x21, Vint x22)) pps)
POST [ tint ]
PROP () LOCAL (temp ret_temp (Vint x22))
SEP   (field_at sh (tarray pair_pair_t array_size) [ArraySubsc i]
((Vint x11, Vint x12), (Vint x21, Vint x22)) pps).
Definition uint_sum (contents : list Z) : int :=
fold_right (fun el sum => Int.add sum (Int.repr el)) Int.zero contents.
Definition fiddle_spec :=
DECLARE _fiddle
WITH p: val, n: Z, tag: Z, contents: list Z
PRE [ _p OF tptr tuint ]
PROP  (Int.unsigned (Int.shru (Int.repr tag) (Int.repr 10)) = n)
LOCAL (temp _p p)
SEP (data_at Ews (tarray tuint (1+n))
(map Vint (map Int.repr (tag::contents)))
(offset_val (-sizeof tuint) p))
POST [ tint ]
PROP ( )
LOCAL (temp ret_temp (Vint (Int.add (Int.repr (Z.land tag 255)) (uint_sum contents))))
SEP (data_at Ews (tarray tuint (1+n))
(map Vint (map Int.repr (tag::contents)))
(offset_val (-sizeof tuint) p)).
Definition get_uint32_le (arr: list Z) : int :=
(Int.or (Int.or (Int.or
(Int.repr (Znth 0 arr))
(Int.shl (Int.repr (Znth 1 arr)) (Int.repr  8)))
(Int.shl (Int.repr (Znth 2 arr)) (Int.repr 16)))
(Int.shl (Int.repr (Znth 3 arr)) (Int.repr 24))).
Definition get_little_endian_spec :=
DECLARE _get_little_endian
WITH input : val, in_sh : share, arr : list Z
PRE [ _input OF (tptr tuchar) ]
PROP (Zlength arr = 4;
readable_share in_sh;
forall i, 0 <= i < 4 -> 0 <= Znth i arr <= Byte.max_unsigned)
LOCAL (temp _input input)
SEP (data_at in_sh (tarray tuchar 4) (map Vint (map Int.repr arr)) input)
POST [ tuint ]
PROP() LOCAL(temp ret_temp (Vint (get_uint32_le arr)))
SEP (data_at in_sh (tarray tuchar 4) (map Vint (map Int.repr arr)) input).
Definition Gprog : funspecs := ltac:(with_library prog
[get22_spec; fiddle_spec; get_little_endian_spec]).
Ltac solve_arr_range H :=
match goal with |- context [Znth ?i _] =>
specialize (H i); spec H; [ computable | ];
rewrite Int.unsigned_repr; rep_omega
end.

(* Specifications: *)
Lemma body_get_little_endian: semax_body Vprog Gprog f_get_little_endian get_little_endian_spec.
Lemma uint_sum_app: forall a b, uint_sum (a++b) = Int.add (uint_sum a) (uint_sum b).
Lemma body_fiddle: semax_body Vprog Gprog f_fiddle fiddle_spec.
Lemma body_get22_root_expr: semax_body Vprog Gprog f_get22 get22_spec.
Lemma body_get22_full_expr: semax_body Vprog Gprog f_get22 get22_spec.
Lemma body_get22_alt: semax_body Vprog Gprog f_get22 get22_spec.