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.