Nondetfunction splitlong (e: expr) (f: expr -> expr -> expr) := match e with | Eop Omakelong (h ::: l ::: Enil) => f h l | _ => Elet e (f (Eop Ohighlong (Eletvar O ::: Enil)) (Eop Olowlong (Eletvar O ::: Enil))) end.
Nondetfunction splitlong2 (e1 e2: expr) (f: expr -> expr -> expr -> expr -> expr) :=
match e1, e2 with
| Eop Omakelong (h1 ::: l1 ::: Enil), Eop Omakelong (h2 ::: l2 ::: Enil) =>
f h1 l1 h2 l2
| Eop Omakelong (h1 ::: l1 ::: Enil), t2 =>
Elet t2 (f (lift h1) (lift l1)
(Eop Ohighlong (Eletvar O ::: Enil)) (Eop Olowlong (Eletvar O ::: Enil)))
| t1, Eop Omakelong (h2 ::: l2 ::: Enil) =>
Elet t1 (f (Eop Ohighlong (Eletvar O ::: Enil)) (Eop Olowlong (Eletvar O ::: Enil))
(lift h2) (lift l2))
| _, _ =>
Elet e1 (Elet (lift e2)
(f (Eop Ohighlong (Eletvar 1 ::: Enil)) (Eop Olowlong (Eletvar 1 ::: Enil))
(Eop Ohighlong (Eletvar O ::: Enil)) (Eop Olowlong (Eletvar O ::: Enil))))
end.
Nondetfunction lowlong (e: expr) := match e with | Eop Omakelong (e1 ::: e2 ::: Enil) => e2 | _ => Eop Olowlong (e ::: Enil) end.
Nondetfunction highlong (e: expr) := match e with | Eop Omakelong (e1 ::: e2 ::: Enil) => e1 | _ => Eop Ohighlong (e ::: Enil) end.
Nondetfunction is_longconst (e: expr) :=
match e with
| Eop Omakelong (Eop (Ointconst h) Enil ::: Eop (Ointconst l) Enil ::: Enil) =>
Some(Int64.ofwords h l)
| _ =>
None
end.
Nondetfunction longofint (e: expr) := match e with | Eop (Ointconst n) Enil => longconst (Int64.repr (Int.signed n)) | _ => Elet e (makelong (shrimm (Eletvar O) (Int.repr 31)) (Eletvar O)) end.