aboutsummaryrefslogtreecommitdiffstats
path: root/arm/SelectOp.v
diff options
context:
space:
mode:
Diffstat (limited to 'arm/SelectOp.v')
-rw-r--r--arm/SelectOp.v1430
1 files changed, 738 insertions, 692 deletions
diff --git a/arm/SelectOp.v b/arm/SelectOp.v
index 65809019..64d15cbc 100644
--- a/arm/SelectOp.v
+++ b/arm/SelectOp.v
@@ -60,14 +60,9 @@ Definition addrstack (ofs: int) :=
(** ** Integer logical negation *)
-(** The natural way to write smart constructors is by pattern-matching
- on their arguments, recognizing cases where cheaper operators
- or combined operators are applicable. For instance, integer logical
- negation has three special cases (not-and, not-or and not-xor),
- along with a default case that uses not-or over its arguments and itself.
- This is written naively as follows:
+(** Original definition:
<<
-Definition notint (e: expr) :=
+Nondetfunction notint (e: expr) :=
match e with
| Eop (Oshift s) (t1:::Enil) => Eop (Onotshift s) (t1:::Enil)
| Eop Onot (t1:::Enil) => t1
@@ -75,80 +70,39 @@ Definition notint (e: expr) :=
| _ => Eop Onot (e:::Enil)
end.
>>
- However, Coq expands complex pattern-matchings like the above into
- elementary matchings over all constructors of an inductive type,
- resulting in much duplication of the final catch-all case.
- Such duplications generate huge executable code and duplicate
- cases in the correctness proofs.
-
- To limit this duplication, we use the following trick due to
- Yves Bertot. We first define a dependent inductive type that
- characterizes the expressions that match each of the 4 cases of interest.
*)
Inductive notint_cases: forall (e: expr), Type :=
- | notint_case1:
- forall s t1,
- notint_cases (Eop (Oshift s) (t1:::Enil))
- | notint_case2:
- forall t1,
- notint_cases (Eop Onot (t1:::Enil))
- | notint_case3:
- forall s t1,
- notint_cases (Eop (Onotshift s) (t1:::Enil))
- | notint_default:
- forall (e: expr),
- notint_cases e.
-
-(** We then define a classification function that takes an expression
- and return the case in which it falls. Note that the catch-all case
- [notint_default] does not state that it is mutually exclusive with
- the first three, more specific cases. The classification function
- nonetheless chooses the specific cases in preference to the catch-all
- case. *)
+ | notint_case1: forall s t1, notint_cases (Eop (Oshift s) (t1:::Enil))
+ | notint_case2: forall t1, notint_cases (Eop Onot (t1:::Enil))
+ | notint_case3: forall s t1, notint_cases (Eop (Onotshift s) (t1:::Enil))
+ | notint_default: forall (e: expr), notint_cases e.
Definition notint_match (e: expr) :=
- match e as z1 return notint_cases z1 with
- | Eop (Oshift s) (t1:::Enil) =>
- notint_case1 s t1
- | Eop Onot (t1:::Enil) =>
- notint_case2 t1
- | Eop (Onotshift s) (t1:::Enil) =>
- notint_case3 s t1
- | e =>
- notint_default e
- end.
-
-(** Finally, the [notint] function we need is defined by a 4-case match
- over the result of the classification function. Thus, no duplication
- of the right-hand sides of this match occur, and the proof has only
- 4 cases to consider (it proceeds by case over [notint_match e]).
- Since the default case is not obviously exclusive with the three
- specific cases, it is important that its right-hand side is
- semantically correct for all possible values of [e], which is the
- case here and for all other smart constructors. *)
+ match e as zz1 return notint_cases zz1 with
+ | Eop (Oshift s) (t1:::Enil) => notint_case1 s t1
+ | Eop Onot (t1:::Enil) => notint_case2 t1
+ | Eop (Onotshift s) (t1:::Enil) => notint_case3 s t1
+ | e => notint_default e
+ end.
Definition notint (e: expr) :=
match notint_match e with
- | notint_case1 s t1 =>
+ | notint_case1 s t1 => (* Eop (Oshift s) (t1:::Enil) *)
Eop (Onotshift s) (t1:::Enil)
- | notint_case2 t1 =>
+ | notint_case2 t1 => (* Eop Onot (t1:::Enil) *)
t1
- | notint_case3 s t1 =>
+ | notint_case3 s t1 => (* Eop (Onotshift s) (t1:::Enil) *)
Eop (Oshift s) (t1:::Enil)
| notint_default e =>
Eop Onot (e:::Enil)
end.
-(** This programming pattern will be applied systematically for the
- other smart constructors in this file. *)
(** ** Boolean negation *)
-Definition notbool_base (e: expr) :=
- Eop (Ocmp (Ccompuimm Ceq Int.zero)) (e ::: Enil).
-
Fixpoint notbool (e: expr) {struct e} : expr :=
+ let default := Eop (Ocmp (Ccompuimm Ceq Int.zero)) (e ::: Enil) in
match e with
| Eop (Ointconst n) Enil =>
Eop (Ointconst (if Int.eq n Int.zero then Int.one else Int.zero)) Enil
@@ -157,15 +111,14 @@ Fixpoint notbool (e: expr) {struct e} : expr :=
| Econdition e1 e2 e3 =>
Econdition e1 (notbool e2) (notbool e3)
| _ =>
- notbool_base e
+ default
end.
(** ** Integer addition and pointer addition *)
-(** Addition of an integer constant. *)
-
-(*
-Definition addimm (n: int) (e: expr) :=
+(** Original definition:
+<<
+Nondetfunction addimm (n: int) (e: expr) :=
if Int.eq n Int.zero then e else
match e with
| Eop (Ointconst m) Enil => Eop (Ointconst(Int.add n m)) Enil
@@ -174,372 +127,292 @@ Definition addimm (n: int) (e: expr) :=
| Eop (Oaddimm m) (t ::: Enil) => Eop (Oaddimm(Int.add n m)) (t ::: Enil)
| _ => Eop (Oaddimm n) (e ::: Enil)
end.
+>>
*)
Inductive addimm_cases: forall (e: expr), Type :=
- | addimm_case1:
- forall m,
- addimm_cases (Eop (Ointconst m) Enil)
- | addimm_case2:
- forall s m,
- addimm_cases (Eop (Oaddrsymbol s m) Enil)
- | addimm_case3:
- forall m,
- addimm_cases (Eop (Oaddrstack m) Enil)
- | addimm_case4:
- forall m t,
- addimm_cases (Eop (Oaddimm m) (t ::: Enil))
- | addimm_default:
- forall (e: expr),
- addimm_cases e.
+ | addimm_case1: forall m, addimm_cases (Eop (Ointconst m) Enil)
+ | addimm_case2: forall s m, addimm_cases (Eop (Oaddrsymbol s m) Enil)
+ | addimm_case3: forall m, addimm_cases (Eop (Oaddrstack m) Enil)
+ | addimm_case4: forall m t, addimm_cases (Eop (Oaddimm m) (t ::: Enil))
+ | addimm_default: forall (e: expr), addimm_cases e.
Definition addimm_match (e: expr) :=
- match e as z1 return addimm_cases z1 with
- | Eop (Ointconst m) Enil =>
- addimm_case1 m
- | Eop (Oaddrsymbol s m) Enil =>
- addimm_case2 s m
- | Eop (Oaddrstack m) Enil =>
- addimm_case3 m
- | Eop (Oaddimm m) (t ::: Enil) =>
- addimm_case4 m t
- | e =>
- addimm_default e
+ match e as zz1 return addimm_cases zz1 with
+ | Eop (Ointconst m) Enil => addimm_case1 m
+ | Eop (Oaddrsymbol s m) Enil => addimm_case2 s m
+ | Eop (Oaddrstack m) Enil => addimm_case3 m
+ | Eop (Oaddimm m) (t ::: Enil) => addimm_case4 m t
+ | e => addimm_default e
end.
Definition addimm (n: int) (e: expr) :=
- if Int.eq n Int.zero then e else
- match addimm_match e with
- | addimm_case1 m =>
+ if Int.eq n Int.zero then e else match addimm_match e with
+ | addimm_case1 m => (* Eop (Ointconst m) Enil *)
Eop (Ointconst(Int.add n m)) Enil
- | addimm_case2 s m =>
+ | addimm_case2 s m => (* Eop (Oaddrsymbol s m) Enil *)
Eop (Oaddrsymbol s (Int.add n m)) Enil
- | addimm_case3 m =>
+ | addimm_case3 m => (* Eop (Oaddrstack m) Enil *)
Eop (Oaddrstack (Int.add n m)) Enil
- | addimm_case4 m t =>
+ | addimm_case4 m t => (* Eop (Oaddimm m) (t ::: Enil) *)
Eop (Oaddimm(Int.add n m)) (t ::: Enil)
| addimm_default e =>
Eop (Oaddimm n) (e ::: Enil)
end.
-(** Addition of two integer or pointer expressions. *)
-(*
-Definition add (e1: expr) (e2: expr) :=
+(** Original definition:
+<<
+Nondetfunction add (e1: expr) (e2: expr) :=
match e1, e2 with
| Eop (Ointconst n1) Enil, t2 => addimm n1 t2
- | Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) => addimm (Int.add n1 n2) (Eop Oadd (t1:::t2:::Enil))
- | Eop(Oaddimm n1) (t1:::Enil)), t2 => addimm n1 (Eop Oadd (t1:::t2:::Enil))
+ | Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) =>
+ addimm (Int.add n1 n2) (Eop Oadd (t1:::t2:::Enil))
+ | Eop(Oaddimm n1) (t1:::Enil), t2 => addimm n1 (Eop Oadd (t1:::t2:::Enil))
| t1, Eop (Ointconst n2) Enil => addimm n2 t1
| t1, Eop (Oaddimm n2) (t2:::Enil) => addimm n2 (Eop Oadd (t1:::t2:::Enil))
| Eop (Oshift s) (t1:::Enil), t2 => Eop (Oaddshift s) (t2:::t1:::Enil)
| t1, Eop (Oshift s) (t2:::Enil) => Eop (Oaddshift s) (t1:::t2:::Enil)
| _, _ => Eop Oadd (e1:::e2:::Enil)
end.
+>>
*)
Inductive add_cases: forall (e1: expr) (e2: expr), Type :=
- | add_case1:
- forall n1 t2,
- add_cases (Eop (Ointconst n1) Enil) (t2)
- | add_case2:
- forall n1 t1 n2 t2,
- add_cases (Eop (Oaddimm n1) (t1:::Enil)) (Eop (Oaddimm n2) (t2:::Enil))
- | add_case3:
- forall n1 t1 t2,
- add_cases (Eop (Oaddimm n1) (t1:::Enil)) (t2)
- | add_case4:
- forall t1 n2,
- add_cases (t1) (Eop (Ointconst n2) Enil)
- | add_case5:
- forall t1 n2 t2,
- add_cases (t1) (Eop (Oaddimm n2) (t2:::Enil))
- | add_case6:
- forall s t1 t2,
- add_cases (Eop (Oshift s) (t1:::Enil)) (t2)
- | add_case7:
- forall t1 s t2,
- add_cases (t1) (Eop (Oshift s) (t2:::Enil))
- | add_default:
- forall (e1: expr) (e2: expr),
- add_cases e1 e2.
+ | add_case1: forall n1 t2, add_cases (Eop (Ointconst n1) Enil) (t2)
+ | add_case2: forall n1 t1 n2 t2, add_cases (Eop (Oaddimm n1) (t1:::Enil)) (Eop (Oaddimm n2) (t2:::Enil))
+ | add_case3: forall n1 t1 t2, add_cases (Eop(Oaddimm n1) (t1:::Enil)) (t2)
+ | add_case4: forall t1 n2, add_cases (t1) (Eop (Ointconst n2) Enil)
+ | add_case5: forall t1 n2 t2, add_cases (t1) (Eop (Oaddimm n2) (t2:::Enil))
+ | add_case6: forall s t1 t2, add_cases (Eop (Oshift s) (t1:::Enil)) (t2)
+ | add_case7: forall t1 s t2, add_cases (t1) (Eop (Oshift s) (t2:::Enil))
+ | add_default: forall (e1: expr) (e2: expr), add_cases e1 e2.
Definition add_match (e1: expr) (e2: expr) :=
- match e1 as z1, e2 as z2 return add_cases z1 z2 with
- | Eop (Ointconst n1) Enil, t2 =>
- add_case1 n1 t2
- | Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) =>
- add_case2 n1 t1 n2 t2
- | Eop(Oaddimm n1) (t1:::Enil), t2 =>
- add_case3 n1 t1 t2
- | t1, Eop (Ointconst n2) Enil =>
- add_case4 t1 n2
- | t1, Eop (Oaddimm n2) (t2:::Enil) =>
- add_case5 t1 n2 t2
- | Eop (Oshift s) (t1:::Enil), t2 =>
- add_case6 s t1 t2
- | t1, Eop (Oshift s) (t2:::Enil) =>
- add_case7 t1 s t2
- | e1, e2 =>
- add_default e1 e2
+ match e1 as zz1, e2 as zz2 return add_cases zz1 zz2 with
+ | Eop (Ointconst n1) Enil, t2 => add_case1 n1 t2
+ | Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) => add_case2 n1 t1 n2 t2
+ | Eop(Oaddimm n1) (t1:::Enil), t2 => add_case3 n1 t1 t2
+ | t1, Eop (Ointconst n2) Enil => add_case4 t1 n2
+ | t1, Eop (Oaddimm n2) (t2:::Enil) => add_case5 t1 n2 t2
+ | Eop (Oshift s) (t1:::Enil), t2 => add_case6 s t1 t2
+ | t1, Eop (Oshift s) (t2:::Enil) => add_case7 t1 s t2
+ | e1, e2 => add_default e1 e2
end.
Definition add (e1: expr) (e2: expr) :=
match add_match e1 e2 with
- | add_case1 n1 t2 =>
+ | add_case1 n1 t2 => (* Eop (Ointconst n1) Enil, t2 *)
addimm n1 t2
- | add_case2 n1 t1 n2 t2 =>
+ | add_case2 n1 t1 n2 t2 => (* Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) *)
addimm (Int.add n1 n2) (Eop Oadd (t1:::t2:::Enil))
- | add_case3 n1 t1 t2 =>
+ | add_case3 n1 t1 t2 => (* Eop(Oaddimm n1) (t1:::Enil), t2 *)
addimm n1 (Eop Oadd (t1:::t2:::Enil))
- | add_case4 t1 n2 =>
+ | add_case4 t1 n2 => (* t1, Eop (Ointconst n2) Enil *)
addimm n2 t1
- | add_case5 t1 n2 t2 =>
+ | add_case5 t1 n2 t2 => (* t1, Eop (Oaddimm n2) (t2:::Enil) *)
addimm n2 (Eop Oadd (t1:::t2:::Enil))
- | add_case6 s t1 t2 =>
+ | add_case6 s t1 t2 => (* Eop (Oshift s) (t1:::Enil), t2 *)
Eop (Oaddshift s) (t2:::t1:::Enil)
- | add_case7 t1 s t2 =>
+ | add_case7 t1 s t2 => (* t1, Eop (Oshift s) (t2:::Enil) *)
Eop (Oaddshift s) (t1:::t2:::Enil)
| add_default e1 e2 =>
Eop Oadd (e1:::e2:::Enil)
end.
+
(** ** Integer and pointer subtraction *)
-(*
-Definition sub (e1: expr) (e2: expr) :=
+(** Original definition:
+<<
+Nondetfunction sub (e1: expr) (e2: expr) :=
match e1, e2 with
| t1, Eop (Ointconst n2) Enil => addimm (Int.neg n2) t1
- | Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) => addimm (intsub n1 n2) (Eop Osub (t1:::t2:::Enil))
- | Eop (Oaddimm n1) (t1:::Enil), t2 => addimm n1 (Eop Osub (t1:::t2:::Rnil))
- | t1, Eop (Oaddimm n2) (t2:::Enil) => addimm (Int.neg n2) (Eop Osub (t1::::t2:::Enil))
+ | Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) =>
+ addimm (Int.sub n1 n2) (Eop Osub (t1:::t2:::Enil))
+ | Eop (Oaddimm n1) (t1:::Enil), t2 =>
+ addimm n1 (Eop Osub (t1:::t2:::Enil))
+ | t1, Eop (Oaddimm n2) (t2:::Enil) =>
+ addimm (Int.neg n2) (Eop Osub (t1:::t2:::Enil))
| Eop (Ointconst n1) Enil, t2 => Eop (Orsubimm n1) (t2:::Enil)
| Eop (Oshift s) (t1:::Enil), t2 => Eop (Orsubshift s) (t2:::t1:::Enil)
| t1, Eop (Oshift s) (t2:::Enil) => Eop (Osubshift s) (t1:::t2:::Enil)
| _, _ => Eop Osub (e1:::e2:::Enil)
end.
+>>
*)
Inductive sub_cases: forall (e1: expr) (e2: expr), Type :=
- | sub_case1:
- forall t1 n2,
- sub_cases (t1) (Eop (Ointconst n2) Enil)
- | sub_case2:
- forall n1 t1 n2 t2,
- sub_cases (Eop (Oaddimm n1) (t1:::Enil)) (Eop (Oaddimm n2) (t2:::Enil))
- | sub_case3:
- forall n1 t1 t2,
- sub_cases (Eop (Oaddimm n1) (t1:::Enil)) (t2)
- | sub_case4:
- forall t1 n2 t2,
- sub_cases (t1) (Eop (Oaddimm n2) (t2:::Enil))
- | sub_case5:
- forall n1 t2,
- sub_cases (Eop (Ointconst n1) Enil) (t2)
- | sub_case6:
- forall s t1 t2,
- sub_cases (Eop (Oshift s) (t1:::Enil)) (t2)
- | sub_case7:
- forall t1 s t2,
- sub_cases (t1) (Eop (Oshift s) (t2:::Enil))
- | sub_default:
- forall (e1: expr) (e2: expr),
- sub_cases e1 e2.
+ | sub_case1: forall t1 n2, sub_cases (t1) (Eop (Ointconst n2) Enil)
+ | sub_case2: forall n1 t1 n2 t2, sub_cases (Eop (Oaddimm n1) (t1:::Enil)) (Eop (Oaddimm n2) (t2:::Enil))
+ | sub_case3: forall n1 t1 t2, sub_cases (Eop (Oaddimm n1) (t1:::Enil)) (t2)
+ | sub_case4: forall t1 n2 t2, sub_cases (t1) (Eop (Oaddimm n2) (t2:::Enil))
+ | sub_case5: forall n1 t2, sub_cases (Eop (Ointconst n1) Enil) (t2)
+ | sub_case6: forall s t1 t2, sub_cases (Eop (Oshift s) (t1:::Enil)) (t2)
+ | sub_case7: forall t1 s t2, sub_cases (t1) (Eop (Oshift s) (t2:::Enil))
+ | sub_default: forall (e1: expr) (e2: expr), sub_cases e1 e2.
Definition sub_match (e1: expr) (e2: expr) :=
- match e1 as z1, e2 as z2 return sub_cases z1 z2 with
- | t1, Eop (Ointconst n2) Enil =>
- sub_case1 t1 n2
- | Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) =>
- sub_case2 n1 t1 n2 t2
- | Eop (Oaddimm n1) (t1:::Enil), t2 =>
- sub_case3 n1 t1 t2
- | t1, Eop (Oaddimm n2) (t2:::Enil) =>
- sub_case4 t1 n2 t2
- | Eop (Ointconst n1) Enil, t2 =>
- sub_case5 n1 t2
- | Eop (Oshift s) (t1:::Enil), t2 =>
- sub_case6 s t1 t2
- | t1, Eop (Oshift s) (t2:::Enil) =>
- sub_case7 t1 s t2
- | e1, e2 =>
- sub_default e1 e2
+ match e1 as zz1, e2 as zz2 return sub_cases zz1 zz2 with
+ | t1, Eop (Ointconst n2) Enil => sub_case1 t1 n2
+ | Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) => sub_case2 n1 t1 n2 t2
+ | Eop (Oaddimm n1) (t1:::Enil), t2 => sub_case3 n1 t1 t2
+ | t1, Eop (Oaddimm n2) (t2:::Enil) => sub_case4 t1 n2 t2
+ | Eop (Ointconst n1) Enil, t2 => sub_case5 n1 t2
+ | Eop (Oshift s) (t1:::Enil), t2 => sub_case6 s t1 t2
+ | t1, Eop (Oshift s) (t2:::Enil) => sub_case7 t1 s t2
+ | e1, e2 => sub_default e1 e2
end.
Definition sub (e1: expr) (e2: expr) :=
match sub_match e1 e2 with
- | sub_case1 t1 n2 =>
+ | sub_case1 t1 n2 => (* t1, Eop (Ointconst n2) Enil *)
addimm (Int.neg n2) t1
- | sub_case2 n1 t1 n2 t2 =>
+ | sub_case2 n1 t1 n2 t2 => (* Eop (Oaddimm n1) (t1:::Enil), Eop (Oaddimm n2) (t2:::Enil) *)
addimm (Int.sub n1 n2) (Eop Osub (t1:::t2:::Enil))
- | sub_case3 n1 t1 t2 =>
+ | sub_case3 n1 t1 t2 => (* Eop (Oaddimm n1) (t1:::Enil), t2 *)
addimm n1 (Eop Osub (t1:::t2:::Enil))
- | sub_case4 t1 n2 t2 =>
+ | sub_case4 t1 n2 t2 => (* t1, Eop (Oaddimm n2) (t2:::Enil) *)
addimm (Int.neg n2) (Eop Osub (t1:::t2:::Enil))
- | sub_case5 n1 t2 =>
+ | sub_case5 n1 t2 => (* Eop (Ointconst n1) Enil, t2 *)
Eop (Orsubimm n1) (t2:::Enil)
- | sub_case6 s t1 t2 =>
+ | sub_case6 s t1 t2 => (* Eop (Oshift s) (t1:::Enil), t2 *)
Eop (Orsubshift s) (t2:::t1:::Enil)
- | sub_case7 t1 s t2 =>
+ | sub_case7 t1 s t2 => (* t1, Eop (Oshift s) (t2:::Enil) *)
Eop (Osubshift s) (t1:::t2:::Enil)
| sub_default e1 e2 =>
Eop Osub (e1:::e2:::Enil)
end.
+
+Definition negint (e: expr) := Eop (Orsubimm Int.zero) (e ::: Enil).
+
(** ** Immediate shifts *)
-(*
-Definition shlimm (e1: expr) :=
- if Int.eq n Int.zero then e1 else
- match e1 with
- | Eop (Ointconst n1) Enil => Eop (Ointconst(Int.shl n1 n))
- | Eop (Oshift (Olsl n1)) (t1:::Enil) => if Int.ltu (Int.add n n1) Int.iwordsize then Eop (Oshift (Olsl (Int.add n n1))) (t1:::Enil) else Eop (Oshift (Olsl n)) (e1:::Enil)
- | _ => Eop (Oshift (Olsl n)) (e1:::Enil)
- end.
+(** Original definition:
+<<
+Nondetfunction shlimm (e1: expr) (n: int) :=
+ if Int.eq n Int.zero then
+ e1
+ else if negb (Int.ltu n Int.iwordsize) then
+ Eop Oshl (e1 ::: Eop (Ointconst n) Enil ::: Enil)
+ else match e1 with
+ | Eop (Ointconst n1) Enil => Eop (Ointconst(Int.shl n1 n)) Enil
+ | Eop (Oshift (Slsl n1)) (t1:::Enil) =>
+ if Int.ltu (Int.add n n1) Int.iwordsize
+ then Eop (Oshift (Slsl (mk_shift_amount(Int.add n n1)))) (t1:::Enil)
+ else Eop (Oshift (Slsl (mk_shift_amount n))) (e1:::Enil)
+ | _ => Eop (Oshift (Slsl (mk_shift_amount n))) (e1:::Enil)
+ end.
+>>
*)
-Inductive shlimm_cases: forall (e1: expr), Type :=
- | shlimm_case1:
- forall n1,
- shlimm_cases (Eop (Ointconst n1) Enil)
- | shlimm_case2:
- forall n1 t1,
- shlimm_cases (Eop (Oshift (Slsl n1)) (t1:::Enil))
- | shlimm_default:
- forall (e1: expr),
- shlimm_cases e1.
-
-Definition shlimm_match (e1: expr) :=
- match e1 as z1 return shlimm_cases z1 with
- | Eop (Ointconst n1) Enil =>
- shlimm_case1 n1
- | Eop (Oshift (Slsl n1)) (t1:::Enil) =>
- shlimm_case2 n1 t1
- | e1 =>
- shlimm_default e1
+Inductive shlimm_cases: forall (e1: expr) , Type :=
+ | shlimm_case1: forall n1, shlimm_cases (Eop (Ointconst n1) Enil)
+ | shlimm_case2: forall n1 t1, shlimm_cases (Eop (Oshift (Slsl n1)) (t1:::Enil))
+ | shlimm_default: forall (e1: expr) , shlimm_cases e1.
+
+Definition shlimm_match (e1: expr) :=
+ match e1 as zz1 return shlimm_cases zz1 with
+ | Eop (Ointconst n1) Enil => shlimm_case1 n1
+ | Eop (Oshift (Slsl n1)) (t1:::Enil) => shlimm_case2 n1 t1
+ | e1 => shlimm_default e1
end.
Definition shlimm (e1: expr) (n: int) :=
- if Int.eq n Int.zero then e1 else
- match is_shift_amount n with
- | None => Eop Oshl (e1 ::: Eop (Ointconst n) Enil ::: Enil)
- | Some n' =>
- match shlimm_match e1 with
- | shlimm_case1 n1 =>
- Eop (Ointconst(Int.shl n1 n)) Enil
- | shlimm_case2 n1 t1 =>
- match is_shift_amount (Int.add n (s_amount n1)) with
- | None =>
- Eop (Oshift (Slsl n')) (e1:::Enil)
- | Some n'' =>
- Eop (Oshift (Slsl n'')) (t1:::Enil)
- end
- | shlimm_default e1 =>
- Eop (Oshift (Slsl n')) (e1:::Enil)
- end
- end.
-
-(*
-Definition shruimm (e1: expr) :=
- if Int.eq n Int.zero then e1 else
- match e1 with
- | Eop (Ointconst n1) Enil => Eop (Ointconst(Int.shru n1 n))
- | Eop (Oshift (Olsr n1)) (t1:::Enil) => if Int.ltu (Int.add n n1) Int.iwordsize then Eop (Oshift (Olsr (Int.add n n1))) (t1:::Enil) else Eop (Oshift (Olsr n)) (e1:::Enil)
- | _ => Eop (Oshift (Olsr n)) (e1:::Enil)
+ if Int.eq n Int.zero then e1 else if negb (Int.ltu n Int.iwordsize) then Eop Oshl (e1 ::: Eop (Ointconst n) Enil ::: Enil) else match shlimm_match e1 with
+ | shlimm_case1 n1 => (* Eop (Ointconst n1) Enil *)
+ Eop (Ointconst(Int.shl n1 n)) Enil
+ | shlimm_case2 n1 t1 => (* Eop (Oshift (Slsl n1)) (t1:::Enil) *)
+ if Int.ltu (Int.add n n1) Int.iwordsize then Eop (Oshift (Slsl (mk_shift_amount(Int.add n n1)))) (t1:::Enil) else Eop (Oshift (Slsl (mk_shift_amount n))) (e1:::Enil)
+ | shlimm_default e1 =>
+ Eop (Oshift (Slsl (mk_shift_amount n))) (e1:::Enil)
end.
+
+
+(** Original definition:
+<<
+Nondetfunction shruimm (e1: expr) (n: int) :=
+ if Int.eq n Int.zero then
+ e1
+ else if negb (Int.ltu n Int.iwordsize) then
+ Eop Oshru (e1 ::: Eop (Ointconst n) Enil ::: Enil)
+ else match e1 with
+ | Eop (Ointconst n1) Enil => Eop (Ointconst(Int.shru n1 n)) Enil
+ | Eop (Oshift (Slsr n1)) (t1:::Enil) =>
+ if Int.ltu (Int.add n n1) Int.iwordsize
+ then Eop (Oshift (Slsr (mk_shift_amount (Int.add n n1)))) (t1:::Enil)
+ else Eop (Oshift (Slsr (mk_shift_amount n))) (e1:::Enil)
+ | _ => Eop (Oshift (Slsr (mk_shift_amount n))) (e1:::Enil)
+ end.
+>>
*)
-Inductive shruimm_cases: forall (e1: expr), Type :=
- | shruimm_case1:
- forall n1,
- shruimm_cases (Eop (Ointconst n1) Enil)
- | shruimm_case2:
- forall n1 t1,
- shruimm_cases (Eop (Oshift (Slsr n1)) (t1:::Enil))
- | shruimm_default:
- forall (e1: expr),
- shruimm_cases e1.
-
-Definition shruimm_match (e1: expr) :=
- match e1 as z1 return shruimm_cases z1 with
- | Eop (Ointconst n1) Enil =>
- shruimm_case1 n1
- | Eop (Oshift (Slsr n1)) (t1:::Enil) =>
- shruimm_case2 n1 t1
- | e1 =>
- shruimm_default e1
+Inductive shruimm_cases: forall (e1: expr) , Type :=
+ | shruimm_case1: forall n1, shruimm_cases (Eop (Ointconst n1) Enil)
+ | shruimm_case2: forall n1 t1, shruimm_cases (Eop (Oshift (Slsr n1)) (t1:::Enil))
+ | shruimm_default: forall (e1: expr) , shruimm_cases e1.
+
+Definition shruimm_match (e1: expr) :=
+ match e1 as zz1 return shruimm_cases zz1 with
+ | Eop (Ointconst n1) Enil => shruimm_case1 n1
+ | Eop (Oshift (Slsr n1)) (t1:::Enil) => shruimm_case2 n1 t1
+ | e1 => shruimm_default e1
end.
Definition shruimm (e1: expr) (n: int) :=
- if Int.eq n Int.zero then e1 else
- match is_shift_amount n with
- | None => Eop Oshru (e1 ::: Eop (Ointconst n) Enil ::: Enil)
- | Some n' =>
- match shruimm_match e1 with
- | shruimm_case1 n1 =>
- Eop (Ointconst(Int.shru n1 n)) Enil
- | shruimm_case2 n1 t1 =>
- match is_shift_amount (Int.add n (s_amount n1)) with
- | None =>
- Eop (Oshift (Slsr n')) (e1:::Enil)
- | Some n'' =>
- Eop (Oshift (Slsr n'')) (t1:::Enil)
- end
- | shruimm_default e1 =>
- Eop (Oshift (Slsr n')) (e1:::Enil)
- end
- end.
-
-(*
-Definition shrimm (e1: expr) :=
- match e1 with
- | Eop (Ointconst n1) Enil => Eop (Ointconst(Int.shr n1 n))
- | Eop (Oshift (Oasr n1)) (t1:::Enil) => if Int.ltu (Int.add n n1) Int.iwordsize then Eop (Oshift (Oasr (Int.add n n1))) (t1:::Enil) else Eop (Oshift (Oasr n)) (e1:::Enil)
- | _ => Eop (Oshift (Oasr n)) (e1:::Enil)
+ if Int.eq n Int.zero then e1 else if negb (Int.ltu n Int.iwordsize) then Eop Oshru (e1 ::: Eop (Ointconst n) Enil ::: Enil) else match shruimm_match e1 with
+ | shruimm_case1 n1 => (* Eop (Ointconst n1) Enil *)
+ Eop (Ointconst(Int.shru n1 n)) Enil
+ | shruimm_case2 n1 t1 => (* Eop (Oshift (Slsr n1)) (t1:::Enil) *)
+ if Int.ltu (Int.add n n1) Int.iwordsize then Eop (Oshift (Slsr (mk_shift_amount (Int.add n n1)))) (t1:::Enil) else Eop (Oshift (Slsr (mk_shift_amount n))) (e1:::Enil)
+ | shruimm_default e1 =>
+ Eop (Oshift (Slsr (mk_shift_amount n))) (e1:::Enil)
end.
+
+
+(** Original definition:
+<<
+Nondetfunction shrimm (e1: expr) (n: int) :=
+ if Int.eq n Int.zero then
+ e1
+ else if negb (Int.ltu n Int.iwordsize) then
+ Eop Oshr (e1 ::: Eop (Ointconst n) Enil ::: Enil)
+ else
+ match e1 with
+ | Eop (Ointconst n1) Enil => Eop (Ointconst(Int.shr n1 n)) Enil
+ | Eop (Oshift (Sasr n1)) (t1:::Enil) =>
+ if Int.ltu (Int.add n n1) Int.iwordsize
+ then Eop (Oshift (Sasr (mk_shift_amount (Int.add n n1)))) (t1:::Enil)
+ else Eop (Oshift (Sasr (mk_shift_amount n))) (e1:::Enil)
+ | _ => Eop (Oshift (Sasr (mk_shift_amount n))) (e1:::Enil)
+ end.
+>>
*)
-Inductive shrimm_cases: forall (e1: expr), Type :=
- | shrimm_case1:
- forall n1,
- shrimm_cases (Eop (Ointconst n1) Enil)
- | shrimm_case2:
- forall n1 t1,
- shrimm_cases (Eop (Oshift (Sasr n1)) (t1:::Enil))
- | shrimm_default:
- forall (e1: expr),
- shrimm_cases e1.
-
-Definition shrimm_match (e1: expr) :=
- match e1 as z1 return shrimm_cases z1 with
- | Eop (Ointconst n1) Enil =>
- shrimm_case1 n1
- | Eop (Oshift (Sasr n1)) (t1:::Enil) =>
- shrimm_case2 n1 t1
- | e1 =>
- shrimm_default e1
+Inductive shrimm_cases: forall (e1: expr) , Type :=
+ | shrimm_case1: forall n1, shrimm_cases (Eop (Ointconst n1) Enil)
+ | shrimm_case2: forall n1 t1, shrimm_cases (Eop (Oshift (Sasr n1)) (t1:::Enil))
+ | shrimm_default: forall (e1: expr) , shrimm_cases e1.
+
+Definition shrimm_match (e1: expr) :=
+ match e1 as zz1 return shrimm_cases zz1 with
+ | Eop (Ointconst n1) Enil => shrimm_case1 n1
+ | Eop (Oshift (Sasr n1)) (t1:::Enil) => shrimm_case2 n1 t1
+ | e1 => shrimm_default e1
end.
Definition shrimm (e1: expr) (n: int) :=
- if Int.eq n Int.zero then e1 else
- match is_shift_amount n with
- | None => Eop Oshr (e1 ::: Eop (Ointconst n) Enil ::: Enil)
- | Some n' =>
- match shrimm_match e1 with
- | shrimm_case1 n1 =>
- Eop (Ointconst(Int.shr n1 n)) Enil
- | shrimm_case2 n1 t1 =>
- match is_shift_amount (Int.add n (s_amount n1)) with
- | None =>
- Eop (Oshift (Sasr n')) (e1:::Enil)
- | Some n'' =>
- Eop (Oshift (Sasr n'')) (t1:::Enil)
- end
- | shrimm_default e1 =>
- Eop (Oshift (Sasr n')) (e1:::Enil)
- end
+ if Int.eq n Int.zero then e1 else if negb (Int.ltu n Int.iwordsize) then Eop Oshr (e1 ::: Eop (Ointconst n) Enil ::: Enil) else match shrimm_match e1 with
+ | shrimm_case1 n1 => (* Eop (Ointconst n1) Enil *)
+ Eop (Ointconst(Int.shr n1 n)) Enil
+ | shrimm_case2 n1 t1 => (* Eop (Oshift (Sasr n1)) (t1:::Enil) *)
+ if Int.ltu (Int.add n n1) Int.iwordsize then Eop (Oshift (Sasr (mk_shift_amount (Int.add n n1)))) (t1:::Enil) else Eop (Oshift (Sasr (mk_shift_amount n))) (e1:::Enil)
+ | shrimm_default e1 =>
+ Eop (Oshift (Sasr (mk_shift_amount n))) (e1:::Enil)
end.
+
(** ** Integer multiply *)
Definition mulimm_base (n1: int) (e2: expr) :=
@@ -553,170 +426,122 @@ Definition mulimm_base (n1: int) (e2: expr) :=
Eop Omul (Eop (Ointconst n1) Enil ::: e2 ::: Enil)
end.
-(*
-Definition mulimm (n1: int) (e2: expr) :=
- if Int.eq n1 Int.zero then
- Eop (Ointconst Int.zero) Enil
- else if Int.eq n1 Int.one then
- e2
+(** Original definition:
+<<
+Nondetfunction mulimm (n1: int) (e2: expr) :=
+ if Int.eq n1 Int.zero then Eop (Ointconst Int.zero) Enil
+ else if Int.eq n1 Int.one then e2
else match e2 with
- | Eop (Ointconst n2) Enil => Eop (Ointconst(intmul n1 n2)) Enil
- | Eop (Oaddimm n2) (t2:::Enil) => addimm (intmul n1 n2) (mulimm_base n1 t2)
+ | Eop (Ointconst n2) Enil => Eop (Ointconst(Int.mul n1 n2)) Enil
+ | Eop (Oaddimm n2) (t2:::Enil) => addimm (Int.mul n1 n2) (mulimm_base n1 t2)
| _ => mulimm_base n1 e2
end.
+>>
*)
Inductive mulimm_cases: forall (e2: expr), Type :=
- | mulimm_case1:
- forall (n2: int),
- mulimm_cases (Eop (Ointconst n2) Enil)
- | mulimm_case2:
- forall (n2: int) (t2: expr),
- mulimm_cases (Eop (Oaddimm n2) (t2:::Enil))
- | mulimm_default:
- forall (e2: expr),
- mulimm_cases e2.
+ | mulimm_case1: forall n2, mulimm_cases (Eop (Ointconst n2) Enil)
+ | mulimm_case2: forall n2 t2, mulimm_cases (Eop (Oaddimm n2) (t2:::Enil))
+ | mulimm_default: forall (e2: expr), mulimm_cases e2.
Definition mulimm_match (e2: expr) :=
- match e2 as z1 return mulimm_cases z1 with
- | Eop (Ointconst n2) Enil =>
- mulimm_case1 n2
- | Eop (Oaddimm n2) (t2:::Enil) =>
- mulimm_case2 n2 t2
- | e2 =>
- mulimm_default e2
+ match e2 as zz1 return mulimm_cases zz1 with
+ | Eop (Ointconst n2) Enil => mulimm_case1 n2
+ | Eop (Oaddimm n2) (t2:::Enil) => mulimm_case2 n2 t2
+ | e2 => mulimm_default e2
end.
Definition mulimm (n1: int) (e2: expr) :=
- if Int.eq n1 Int.zero then
- Eop (Ointconst Int.zero) Enil
- else if Int.eq n1 Int.one then
- e2
- else match mulimm_match e2 with
- | mulimm_case1 n2 =>
+ if Int.eq n1 Int.zero then Eop (Ointconst Int.zero) Enil else if Int.eq n1 Int.one then e2 else match mulimm_match e2 with
+ | mulimm_case1 n2 => (* Eop (Ointconst n2) Enil *)
Eop (Ointconst(Int.mul n1 n2)) Enil
- | mulimm_case2 n2 t2 =>
+ | mulimm_case2 n2 t2 => (* Eop (Oaddimm n2) (t2:::Enil) *)
addimm (Int.mul n1 n2) (mulimm_base n1 t2)
| mulimm_default e2 =>
mulimm_base n1 e2
end.
-(*
-Definition mul (e1: expr) (e2: expr) :=
+
+(** Original definition:
+<<
+Nondetfunction mul (e1: expr) (e2: expr) :=
match e1, e2 with
| Eop (Ointconst n1) Enil, t2 => mulimm n1 t2
| t1, Eop (Ointconst n2) Enil => mulimm n2 t1
| _, _ => Eop Omul (e1:::e2:::Enil)
end.
+>>
*)
Inductive mul_cases: forall (e1: expr) (e2: expr), Type :=
- | mul_case1:
- forall (n1: int) (t2: expr),
- mul_cases (Eop (Ointconst n1) Enil) (t2)
- | mul_case2:
- forall (t1: expr) (n2: int),
- mul_cases (t1) (Eop (Ointconst n2) Enil)
- | mul_default:
- forall (e1: expr) (e2: expr),
- mul_cases e1 e2.
-
-Definition mul_match_aux (e1: expr) (e2: expr) :=
- match e2 as z2 return mul_cases e1 z2 with
- | Eop (Ointconst n2) Enil =>
- mul_case2 e1 n2
- | e2 =>
- mul_default e1 e2
- end.
+ | mul_case1: forall n1 t2, mul_cases (Eop (Ointconst n1) Enil) (t2)
+ | mul_case2: forall t1 n2, mul_cases (t1) (Eop (Ointconst n2) Enil)
+ | mul_default: forall (e1: expr) (e2: expr), mul_cases e1 e2.
Definition mul_match (e1: expr) (e2: expr) :=
- match e1 as z1 return mul_cases z1 e2 with
- | Eop (Ointconst n1) Enil =>
- mul_case1 n1 e2
- | e1 =>
- mul_match_aux e1 e2
+ match e1 as zz1, e2 as zz2 return mul_cases zz1 zz2 with
+ | Eop (Ointconst n1) Enil, t2 => mul_case1 n1 t2
+ | t1, Eop (Ointconst n2) Enil => mul_case2 t1 n2
+ | e1, e2 => mul_default e1 e2
end.
Definition mul (e1: expr) (e2: expr) :=
match mul_match e1 e2 with
- | mul_case1 n1 t2 =>
+ | mul_case1 n1 t2 => (* Eop (Ointconst n1) Enil, t2 *)
mulimm n1 t2
- | mul_case2 t1 n2 =>
+ | mul_case2 t1 n2 => (* t1, Eop (Ointconst n2) Enil *)
mulimm n2 t1
| mul_default e1 e2 =>
Eop Omul (e1:::e2:::Enil)
end.
-(** ** Integer division and modulus *)
-
-Definition mod_aux (divop: operation) (e1 e2: expr) :=
- Elet e1
- (Elet (lift e2)
- (Eop Osub (Eletvar 1 :::
- Eop Omul (Eop divop (Eletvar 1 ::: Eletvar 0 ::: Enil) :::
- Eletvar 0 :::
- Enil) :::
- Enil))).
-Inductive divu_cases: forall (e2: expr), Type :=
- | divu_case1:
- forall (n2: int),
- divu_cases (Eop (Ointconst n2) Enil)
- | divu_default:
- forall (e2: expr),
- divu_cases e2.
+(** ** Bitwise and, or, xor *)
-Definition divu_match (e2: expr) :=
- match e2 as z1 return divu_cases z1 with
+(** Original definition:
+<<
+Nondetfunction andimm (n1: int) (e2: expr) :=
+ if Int.eq n1 Int.zero then Eop (Ointconst Int.zero) Enil else
+ match e2 with
| Eop (Ointconst n2) Enil =>
- divu_case1 n2
- | e2 =>
- divu_default e2
+ Eop (Ointconst (Int.and n1 n2)) Enil
+ | Eop (Oandimm n2) (t2:::Enil) =>
+ Eop (Oandimm (Int.and n1 n2)) (t2:::Enil)
+ | _ =>
+ Eop (Oandimm n1) (e2:::Enil)
end.
+>>
+*)
-Definition divu (e1: expr) (e2: expr) :=
- match divu_match e2 with
- | divu_case1 n2 =>
- match Int.is_power2 n2 with
- | Some l2 => shruimm e1 l2
- | None => Eop Odivu (e1:::e2:::Enil)
- end
- | divu_default e2 =>
- Eop Odivu (e1:::e2:::Enil)
- end.
+Inductive andimm_cases: forall (e2: expr), Type :=
+ | andimm_case1: forall n2, andimm_cases (Eop (Ointconst n2) Enil)
+ | andimm_case2: forall n2 t2, andimm_cases (Eop (Oandimm n2) (t2:::Enil))
+ | andimm_default: forall (e2: expr), andimm_cases e2.
-Definition modu (e1: expr) (e2: expr) :=
- match divu_match e2 with
- | divu_case1 n2 =>
- match Int.is_power2 n2 with
- | Some l2 => Eop (Oandimm (Int.sub n2 Int.one)) (e1:::Enil)
- | None => mod_aux Odivu e1 e2
- end
- | divu_default e2 =>
- mod_aux Odivu e1 e2
+Definition andimm_match (e2: expr) :=
+ match e2 as zz1 return andimm_cases zz1 with
+ | Eop (Ointconst n2) Enil => andimm_case1 n2
+ | Eop (Oandimm n2) (t2:::Enil) => andimm_case2 n2 t2
+ | e2 => andimm_default e2
end.
-Definition divs (e1: expr) (e2: expr) :=
- match divu_match e2 with
- | divu_case1 n2 =>
- match Int.is_power2 n2 with
- | Some l2 => if Int.ltu l2 (Int.repr 31)
- then Eop (Oshrximm l2) (e1:::Enil)
- else Eop Odiv (e1:::e2:::Enil)
- | None => Eop Odiv (e1:::e2:::Enil)
- end
- | divu_default e2 =>
- Eop Odiv (e1:::e2:::Enil)
+Definition andimm (n1: int) (e2: expr) :=
+ if Int.eq n1 Int.zero then Eop (Ointconst Int.zero) Enil else match andimm_match e2 with
+ | andimm_case1 n2 => (* Eop (Ointconst n2) Enil *)
+ Eop (Ointconst (Int.and n1 n2)) Enil
+ | andimm_case2 n2 t2 => (* Eop (Oandimm n2) (t2:::Enil) *)
+ Eop (Oandimm (Int.and n1 n2)) (t2:::Enil)
+ | andimm_default e2 =>
+ Eop (Oandimm n1) (e2:::Enil)
end.
-Definition mods := mod_aux Odiv. (* could be improved *)
-
-(** ** Bitwise and, or, xor *)
-
-(*
-Definition and (e1: expr) (e2: expr) :=
+(** Original definition:
+<<
+Nondetfunction and (e1: expr) (e2: expr) :=
match e1, e2 with
+ | Eop (Ointconst n1) Enil, t2 => andimm n1 t2
+ | t1, Eop (Ointconst n2) Enil => andimm n2 t1
| Eop (Oshift s) (t1:::Enil), t2 => Eop (Oandshift s) (t2:::t1:::Enil)
| t1, Eop (Oshift s) (t2:::Enil) => Eop (Oandshift s) (t1:::t2:::Enil)
| Eop (Onotshift s) (t1:::Enil), t2 => Eop (Obicshift s) (t2:::t1:::Enil)
@@ -725,362 +550,551 @@ Definition and (e1: expr) (e2: expr) :=
| t1, Eop Onot (t2:::Enil) => Eop Obic (t1:::t2:::Enil)
| _, _ => Eop Oand (e1:::e2:::Enil)
end.
+>>
*)
Inductive and_cases: forall (e1: expr) (e2: expr), Type :=
- | and_case1:
- forall s t1 t2,
- and_cases (Eop (Oshift s) (t1:::Enil)) (t2)
- | and_case2:
- forall t1 s t2,
- and_cases (t1) (Eop (Oshift s) (t2:::Enil))
- | and_case3:
- forall s t1 t2,
- and_cases (Eop (Onotshift s) (t1:::Enil)) (t2)
- | and_case4:
- forall t1 s t2,
- and_cases (t1) (Eop (Onotshift s) (t2:::Enil))
- | and_case5:
- forall t1 t2,
- and_cases (Eop Onot (t1:::Enil)) (t2)
- | and_case6:
- forall t1 t2,
- and_cases (t1) (Eop Onot (t2:::Enil))
- | and_default:
- forall (e1: expr) (e2: expr),
- and_cases e1 e2.
+ | and_case1: forall n1 t2, and_cases (Eop (Ointconst n1) Enil) (t2)
+ | and_case2: forall t1 n2, and_cases (t1) (Eop (Ointconst n2) Enil)
+ | and_case3: forall s t1 t2, and_cases (Eop (Oshift s) (t1:::Enil)) (t2)
+ | and_case4: forall t1 s t2, and_cases (t1) (Eop (Oshift s) (t2:::Enil))
+ | and_case5: forall s t1 t2, and_cases (Eop (Onotshift s) (t1:::Enil)) (t2)
+ | and_case6: forall t1 s t2, and_cases (t1) (Eop (Onotshift s) (t2:::Enil))
+ | and_case7: forall t1 t2, and_cases (Eop Onot (t1:::Enil)) (t2)
+ | and_case8: forall t1 t2, and_cases (t1) (Eop Onot (t2:::Enil))
+ | and_default: forall (e1: expr) (e2: expr), and_cases e1 e2.
Definition and_match (e1: expr) (e2: expr) :=
- match e1 as z1, e2 as z2 return and_cases z1 z2 with
- | Eop (Oshift s) (t1:::Enil), t2 =>
- and_case1 s t1 t2
- | t1, Eop (Oshift s) (t2:::Enil) =>
- and_case2 t1 s t2
- | Eop (Onotshift s) (t1:::Enil), t2 =>
- and_case3 s t1 t2
- | t1, Eop (Onotshift s) (t2:::Enil) =>
- and_case4 t1 s t2
- | Eop Onot (t1:::Enil), t2 =>
- and_case5 t1 t2
- | t1, Eop Onot (t2:::Enil) =>
- and_case6 t1 t2
- | e1, e2 =>
- and_default e1 e2
+ match e1 as zz1, e2 as zz2 return and_cases zz1 zz2 with
+ | Eop (Ointconst n1) Enil, t2 => and_case1 n1 t2
+ | t1, Eop (Ointconst n2) Enil => and_case2 t1 n2
+ | Eop (Oshift s) (t1:::Enil), t2 => and_case3 s t1 t2
+ | t1, Eop (Oshift s) (t2:::Enil) => and_case4 t1 s t2
+ | Eop (Onotshift s) (t1:::Enil), t2 => and_case5 s t1 t2
+ | t1, Eop (Onotshift s) (t2:::Enil) => and_case6 t1 s t2
+ | Eop Onot (t1:::Enil), t2 => and_case7 t1 t2
+ | t1, Eop Onot (t2:::Enil) => and_case8 t1 t2
+ | e1, e2 => and_default e1 e2
end.
Definition and (e1: expr) (e2: expr) :=
match and_match e1 e2 with
- | and_case1 s t1 t2 =>
+ | and_case1 n1 t2 => (* Eop (Ointconst n1) Enil, t2 *)
+ andimm n1 t2
+ | and_case2 t1 n2 => (* t1, Eop (Ointconst n2) Enil *)
+ andimm n2 t1
+ | and_case3 s t1 t2 => (* Eop (Oshift s) (t1:::Enil), t2 *)
Eop (Oandshift s) (t2:::t1:::Enil)
- | and_case2 t1 s t2 =>
+ | and_case4 t1 s t2 => (* t1, Eop (Oshift s) (t2:::Enil) *)
Eop (Oandshift s) (t1:::t2:::Enil)
- | and_case3 s t1 t2 =>
+ | and_case5 s t1 t2 => (* Eop (Onotshift s) (t1:::Enil), t2 *)
Eop (Obicshift s) (t2:::t1:::Enil)
- | and_case4 t1 s t2 =>
+ | and_case6 t1 s t2 => (* t1, Eop (Onotshift s) (t2:::Enil) *)
Eop (Obicshift s) (t1:::t2:::Enil)
- | and_case5 t1 t2 =>
+ | and_case7 t1 t2 => (* Eop Onot (t1:::Enil), t2 *)
Eop Obic (t2:::t1:::Enil)
- | and_case6 t1 t2 =>
+ | and_case8 t1 t2 => (* t1, Eop Onot (t2:::Enil) *)
Eop Obic (t1:::t2:::Enil)
| and_default e1 e2 =>
Eop Oand (e1:::e2:::Enil)
end.
+
Definition same_expr_pure (e1 e2: expr) :=
match e1, e2 with
| Evar v1, Evar v2 => if ident_eq v1 v2 then true else false
| _, _ => false
end.
-(*
-Definition or (e1: expr) (e2: expr) :=
+(** Original definition:
+<<
+Nondetfunction orimm (n1: int) (e2: expr) :=
+ if Int.eq n1 Int.zero then e2 else
+ match e2 with
+ | Eop (Ointconst n2) Enil => Eop (Ointconst (Int.or n1 n2)) Enil
+ | Eop (Oorimm n2) (t2:::Enil) => Eop (Oorimm (Int.or n1 n2)) (t2:::Enil)
+ | _ => Eop (Oorimm n1) (e2:::Enil)
+ end.
+>>
+*)
+
+Inductive orimm_cases: forall (e2: expr), Type :=
+ | orimm_case1: forall n2, orimm_cases (Eop (Ointconst n2) Enil)
+ | orimm_case2: forall n2 t2, orimm_cases (Eop (Oorimm n2) (t2:::Enil))
+ | orimm_default: forall (e2: expr), orimm_cases e2.
+
+Definition orimm_match (e2: expr) :=
+ match e2 as zz1 return orimm_cases zz1 with
+ | Eop (Ointconst n2) Enil => orimm_case1 n2
+ | Eop (Oorimm n2) (t2:::Enil) => orimm_case2 n2 t2
+ | e2 => orimm_default e2
+ end.
+
+Definition orimm (n1: int) (e2: expr) :=
+ if Int.eq n1 Int.zero then e2 else match orimm_match e2 with
+ | orimm_case1 n2 => (* Eop (Ointconst n2) Enil *)
+ Eop (Ointconst (Int.or n1 n2)) Enil
+ | orimm_case2 n2 t2 => (* Eop (Oorimm n2) (t2:::Enil) *)
+ Eop (Oorimm (Int.or n1 n2)) (t2:::Enil)
+ | orimm_default e2 =>
+ Eop (Oorimm n1) (e2:::Enil)
+ end.
+
+
+(** Original definition:
+<<
+Nondetfunction or (e1: expr) (e2: expr) :=
match e1, e2 with
- | Eop (Oshift (Olsl n1) (t1:::Enil), Eop (Oshift (Olsr n2) (t2:::Enil)) => ...
- | Eop (Oshift (Olsr n1) (t1:::Enil), Eop (Oshift (Olsl n2) (t2:::Enil)) => ...
+ | Eop (Ointconst n1) Enil, t2 => orimm n1 t2
+ | t1, Eop (Ointconst n2) Enil => orimm n2 t1
+ | Eop (Oshift (Slsl n1)) (t1:::Enil), Eop (Oshift (Slsr n2)) (t2:::Enil) =>
+ if Int.eq (Int.add n1 n2) Int.iwordsize
+ && same_expr_pure t1 t2
+ then Eop (Oshift (Sror n2)) (t1:::Enil)
+ else Eop (Oorshift (Slsr n2)) (e1:::t2:::Enil)
+ | Eop (Oshift (Slsr n1)) (t1:::Enil), Eop (Oshift (Slsl n2)) (t2:::Enil) =>
+ if Int.eq (Int.add n2 n1) Int.iwordsize
+ && same_expr_pure t1 t2
+ then Eop (Oshift (Sror n1)) (t1:::Enil)
+ else Eop (Oorshift (Slsl n2)) (e1:::t2:::Enil)
| Eop (Oshift s) (t1:::Enil), t2 => Eop (Oorshift s) (t2:::t1:::Enil)
| t1, Eop (Oshift s) (t2:::Enil) => Eop (Oorshift s) (t1:::t2:::Enil)
| _, _ => Eop Oor (e1:::e2:::Enil)
end.
+>>
*)
Inductive or_cases: forall (e1: expr) (e2: expr), Type :=
- | or_case1:
- forall n1 t1 n2 t2,
- or_cases (Eop (Oshift (Slsl n1)) (t1:::Enil)) (Eop (Oshift (Slsr n2)) (t2:::Enil))
- | or_case2:
- forall n1 t1 n2 t2,
- or_cases (Eop (Oshift (Slsr n1)) (t1:::Enil)) (Eop (Oshift (Slsl n2)) (t2:::Enil))
- | or_case3:
- forall s t1 t2,
- or_cases (Eop (Oshift s) (t1:::Enil)) (t2)
- | or_case4:
- forall t1 s t2,
- or_cases (t1) (Eop (Oshift s) (t2:::Enil))
- | or_default:
- forall (e1: expr) (e2: expr),
- or_cases e1 e2.
+ | or_case1: forall n1 t2, or_cases (Eop (Ointconst n1) Enil) (t2)
+ | or_case2: forall t1 n2, or_cases (t1) (Eop (Ointconst n2) Enil)
+ | or_case3: forall n1 t1 n2 t2, or_cases (Eop (Oshift (Slsl n1)) (t1:::Enil)) (Eop (Oshift (Slsr n2)) (t2:::Enil))
+ | or_case4: forall n1 t1 n2 t2, or_cases (Eop (Oshift (Slsr n1)) (t1:::Enil)) (Eop (Oshift (Slsl n2)) (t2:::Enil))
+ | or_case5: forall s t1 t2, or_cases (Eop (Oshift s) (t1:::Enil)) (t2)
+ | or_case6: forall t1 s t2, or_cases (t1) (Eop (Oshift s) (t2:::Enil))
+ | or_default: forall (e1: expr) (e2: expr), or_cases e1 e2.
Definition or_match (e1: expr) (e2: expr) :=
- match e1 as z1, e2 as z2 return or_cases z1 z2 with
- | Eop (Oshift (Slsl n1)) (t1:::Enil), Eop (Oshift (Slsr n2)) (t2:::Enil) =>
- or_case1 n1 t1 n2 t2
- | Eop (Oshift (Slsr n1)) (t1:::Enil), Eop (Oshift (Slsl n2)) (t2:::Enil) =>
- or_case2 n1 t1 n2 t2
- | Eop (Oshift s) (t1:::Enil), t2 =>
- or_case3 s t1 t2
- | t1, Eop (Oshift s) (t2:::Enil) =>
- or_case4 t1 s t2
- | e1, e2 =>
- or_default e1 e2
+ match e1 as zz1, e2 as zz2 return or_cases zz1 zz2 with
+ | Eop (Ointconst n1) Enil, t2 => or_case1 n1 t2
+ | t1, Eop (Ointconst n2) Enil => or_case2 t1 n2
+ | Eop (Oshift (Slsl n1)) (t1:::Enil), Eop (Oshift (Slsr n2)) (t2:::Enil) => or_case3 n1 t1 n2 t2
+ | Eop (Oshift (Slsr n1)) (t1:::Enil), Eop (Oshift (Slsl n2)) (t2:::Enil) => or_case4 n1 t1 n2 t2
+ | Eop (Oshift s) (t1:::Enil), t2 => or_case5 s t1 t2
+ | t1, Eop (Oshift s) (t2:::Enil) => or_case6 t1 s t2
+ | e1, e2 => or_default e1 e2
end.
Definition or (e1: expr) (e2: expr) :=
match or_match e1 e2 with
- | or_case1 n1 t1 n2 t2 =>
- if Int.eq (Int.add (s_amount n1) (s_amount n2)) Int.iwordsize
- && same_expr_pure t1 t2
- then Eop (Oshift (Sror n2)) (t1:::Enil)
- else Eop (Oorshift (Slsr n2)) (e1:::t2:::Enil)
- | or_case2 n1 t1 n2 t2 =>
- if Int.eq (Int.add (s_amount n2) (s_amount n1)) Int.iwordsize
- && same_expr_pure t1 t2
- then Eop (Oshift (Sror n1)) (t1:::Enil)
- else Eop (Oorshift (Slsl n2)) (e1:::t2:::Enil)
- | or_case3 s t1 t2 =>
+ | or_case1 n1 t2 => (* Eop (Ointconst n1) Enil, t2 *)
+ orimm n1 t2
+ | or_case2 t1 n2 => (* t1, Eop (Ointconst n2) Enil *)
+ orimm n2 t1
+ | or_case3 n1 t1 n2 t2 => (* Eop (Oshift (Slsl n1)) (t1:::Enil), Eop (Oshift (Slsr n2)) (t2:::Enil) *)
+ if Int.eq (Int.add n1 n2) Int.iwordsize && same_expr_pure t1 t2 then Eop (Oshift (Sror n2)) (t1:::Enil) else Eop (Oorshift (Slsr n2)) (e1:::t2:::Enil)
+ | or_case4 n1 t1 n2 t2 => (* Eop (Oshift (Slsr n1)) (t1:::Enil), Eop (Oshift (Slsl n2)) (t2:::Enil) *)
+ if Int.eq (Int.add n2 n1) Int.iwordsize && same_expr_pure t1 t2 then Eop (Oshift (Sror n1)) (t1:::Enil) else Eop (Oorshift (Slsl n2)) (e1:::t2:::Enil)
+ | or_case5 s t1 t2 => (* Eop (Oshift s) (t1:::Enil), t2 *)
Eop (Oorshift s) (t2:::t1:::Enil)
- | or_case4 t1 s t2 =>
+ | or_case6 t1 s t2 => (* t1, Eop (Oshift s) (t2:::Enil) *)
Eop (Oorshift s) (t1:::t2:::Enil)
| or_default e1 e2 =>
Eop Oor (e1:::e2:::Enil)
end.
-(*
-Definition xor (e1: expr) (e2: expr) :=
+
+(** Original definition:
+<<
+Nondetfunction xorimm (n1: int) (e2: expr) :=
+ if Int.eq n1 Int.zero then e2 else
+ match e2 with
+ | Eop (Ointconst n2) Enil => Eop (Ointconst (Int.xor n1 n2)) Enil
+ | Eop (Oxorimm n2) (t2:::Enil) => Eop (Oxorimm (Int.xor n1 n2)) (t2:::Enil)
+ | _ => Eop (Oxorimm n1) (e2:::Enil)
+ end.
+>>
+*)
+
+Inductive xorimm_cases: forall (e2: expr), Type :=
+ | xorimm_case1: forall n2, xorimm_cases (Eop (Ointconst n2) Enil)
+ | xorimm_case2: forall n2 t2, xorimm_cases (Eop (Oxorimm n2) (t2:::Enil))
+ | xorimm_default: forall (e2: expr), xorimm_cases e2.
+
+Definition xorimm_match (e2: expr) :=
+ match e2 as zz1 return xorimm_cases zz1 with
+ | Eop (Ointconst n2) Enil => xorimm_case1 n2
+ | Eop (Oxorimm n2) (t2:::Enil) => xorimm_case2 n2 t2
+ | e2 => xorimm_default e2
+ end.
+
+Definition xorimm (n1: int) (e2: expr) :=
+ if Int.eq n1 Int.zero then e2 else match xorimm_match e2 with
+ | xorimm_case1 n2 => (* Eop (Ointconst n2) Enil *)
+ Eop (Ointconst (Int.xor n1 n2)) Enil
+ | xorimm_case2 n2 t2 => (* Eop (Oxorimm n2) (t2:::Enil) *)
+ Eop (Oxorimm (Int.xor n1 n2)) (t2:::Enil)
+ | xorimm_default e2 =>
+ Eop (Oxorimm n1) (e2:::Enil)
+ end.
+
+
+(** Original definition:
+<<
+Nondetfunction xor (e1: expr) (e2: expr) :=
match e1, e2 with
+ | Eop (Ointconst n1) Enil, t2 => xorimm n1 t2
+ | t1, Eop (Ointconst n2) Enil => xorimm n2 t1
| Eop (Oshift s) (t1:::Enil), t2 => Eop (Oxorshift s) (t2:::t1:::Enil)
| t1, Eop (Oshift s) (t2:::Enil) => Eop (Oxorshift s) (t1:::t2:::Enil)
| _, _ => Eop Oxor (e1:::e2:::Enil)
end.
+>>
*)
Inductive xor_cases: forall (e1: expr) (e2: expr), Type :=
- | xor_case1:
- forall s t1 t2,
- xor_cases (Eop (Oshift s) (t1:::Enil)) (t2)
- | xor_case2:
- forall t1 s t2,
- xor_cases (t1) (Eop (Oshift s) (t2:::Enil))
- | xor_default:
- forall (e1: expr) (e2: expr),
- xor_cases e1 e2.
+ | xor_case1: forall n1 t2, xor_cases (Eop (Ointconst n1) Enil) (t2)
+ | xor_case2: forall t1 n2, xor_cases (t1) (Eop (Ointconst n2) Enil)
+ | xor_case3: forall s t1 t2, xor_cases (Eop (Oshift s) (t1:::Enil)) (t2)
+ | xor_case4: forall t1 s t2, xor_cases (t1) (Eop (Oshift s) (t2:::Enil))
+ | xor_default: forall (e1: expr) (e2: expr), xor_cases e1 e2.
Definition xor_match (e1: expr) (e2: expr) :=
- match e1 as z1, e2 as z2 return xor_cases z1 z2 with
- | Eop (Oshift s) (t1:::Enil), t2 =>
- xor_case1 s t1 t2
- | t1, Eop (Oshift s) (t2:::Enil) =>
- xor_case2 t1 s t2
- | e1, e2 =>
- xor_default e1 e2
+ match e1 as zz1, e2 as zz2 return xor_cases zz1 zz2 with
+ | Eop (Ointconst n1) Enil, t2 => xor_case1 n1 t2
+ | t1, Eop (Ointconst n2) Enil => xor_case2 t1 n2
+ | Eop (Oshift s) (t1:::Enil), t2 => xor_case3 s t1 t2
+ | t1, Eop (Oshift s) (t2:::Enil) => xor_case4 t1 s t2
+ | e1, e2 => xor_default e1 e2
end.
Definition xor (e1: expr) (e2: expr) :=
match xor_match e1 e2 with
- | xor_case1 s t1 t2 =>
+ | xor_case1 n1 t2 => (* Eop (Ointconst n1) Enil, t2 *)
+ xorimm n1 t2
+ | xor_case2 t1 n2 => (* t1, Eop (Ointconst n2) Enil *)
+ xorimm n2 t1
+ | xor_case3 s t1 t2 => (* Eop (Oshift s) (t1:::Enil), t2 *)
Eop (Oxorshift s) (t2:::t1:::Enil)
- | xor_case2 t1 s t2 =>
+ | xor_case4 t1 s t2 => (* t1, Eop (Oshift s) (t2:::Enil) *)
Eop (Oxorshift s) (t1:::t2:::Enil)
| xor_default e1 e2 =>
Eop Oxor (e1:::e2:::Enil)
end.
+
+(** ** Integer division and modulus *)
+
+Definition mod_aux (divop: operation) (e1 e2: expr) :=
+ Elet e1
+ (Elet (lift e2)
+ (Eop Osub (Eletvar 1 :::
+ Eop Omul (Eop divop (Eletvar 1 ::: Eletvar 0 ::: Enil) :::
+ Eletvar 0 :::
+ Enil) :::
+ Enil))).
+
+Definition divs (e1: expr) (e2: expr) := Eop Odiv (e1:::e2:::Enil).
+
+Definition mods := mod_aux Odiv.
+
+Definition divuimm (e: expr) (n: int) :=
+ match Int.is_power2 n with
+ | Some l => shruimm e l
+ | None => Eop Odivu (e ::: Eop (Ointconst n) Enil ::: Enil)
+ end.
+
+(** Original definition:
+<<
+Nondetfunction divu (e1: expr) (e2: expr) :=
+ match e2 with
+ | Eop (Ointconst n2) Enil => divuimm e1 n2
+ | _ => Eop Odivu (e1:::e2:::Enil)
+ end.
+>>
+*)
+
+Inductive divu_cases: forall (e2: expr), Type :=
+ | divu_case1: forall n2, divu_cases (Eop (Ointconst n2) Enil)
+ | divu_default: forall (e2: expr), divu_cases e2.
+
+Definition divu_match (e2: expr) :=
+ match e2 as zz1 return divu_cases zz1 with
+ | Eop (Ointconst n2) Enil => divu_case1 n2
+ | e2 => divu_default e2
+ end.
+
+Definition divu (e1: expr) (e2: expr) :=
+ match divu_match e2 with
+ | divu_case1 n2 => (* Eop (Ointconst n2) Enil *)
+ divuimm e1 n2
+ | divu_default e2 =>
+ Eop Odivu (e1:::e2:::Enil)
+ end.
+
+
+Definition moduimm (e: expr) (n: int) :=
+ match Int.is_power2 n with
+ | Some l => Eop (Oandimm (Int.sub n Int.one)) (e ::: Enil)
+ | None => mod_aux Odivu e (Eop (Ointconst n) Enil)
+ end.
+
+(** Original definition:
+<<
+Nondetfunction modu (e1: expr) (e2: expr) :=
+ match e2 with
+ | Eop (Ointconst n2) Enil => moduimm e1 n2
+ | _ => mod_aux Odivu e1 e2
+ end.
+>>
+*)
+
+Inductive modu_cases: forall (e2: expr), Type :=
+ | modu_case1: forall n2, modu_cases (Eop (Ointconst n2) Enil)
+ | modu_default: forall (e2: expr), modu_cases e2.
+
+Definition modu_match (e2: expr) :=
+ match e2 as zz1 return modu_cases zz1 with
+ | Eop (Ointconst n2) Enil => modu_case1 n2
+ | e2 => modu_default e2
+ end.
+
+Definition modu (e1: expr) (e2: expr) :=
+ match modu_match e2 with
+ | modu_case1 n2 => (* Eop (Ointconst n2) Enil *)
+ moduimm e1 n2
+ | modu_default e2 =>
+ mod_aux Odivu e1 e2
+ end.
+
+
(** ** General shifts *)
-Inductive shift_cases: forall (e1: expr), Type :=
- | shift_case1:
- forall (n2: int),
- shift_cases (Eop (Ointconst n2) Enil)
- | shift_default:
- forall (e1: expr),
- shift_cases e1.
+(** Original definition:
+<<
+Nondetfunction shl (e1: expr) (e2: expr) :=
+ match e2 with
+ | Eop (Ointconst n2) Enil => shlimm e1 n2
+ | _ => Eop Oshl (e1:::e2:::Enil)
+ end.
+>>
+*)
+
+Inductive shl_cases: forall (e2: expr), Type :=
+ | shl_case1: forall n2, shl_cases (Eop (Ointconst n2) Enil)
+ | shl_default: forall (e2: expr), shl_cases e2.
-Definition shift_match (e1: expr) :=
- match e1 as z1 return shift_cases z1 with
- | Eop (Ointconst n2) Enil =>
- shift_case1 n2
- | e1 =>
- shift_default e1
+Definition shl_match (e2: expr) :=
+ match e2 as zz1 return shl_cases zz1 with
+ | Eop (Ointconst n2) Enil => shl_case1 n2
+ | e2 => shl_default e2
end.
Definition shl (e1: expr) (e2: expr) :=
- match shift_match e2 with
- | shift_case1 n2 =>
+ match shl_match e2 with
+ | shl_case1 n2 => (* Eop (Ointconst n2) Enil *)
shlimm e1 n2
- | shift_default e2 =>
+ | shl_default e2 =>
Eop Oshl (e1:::e2:::Enil)
end.
-Definition shru (e1: expr) (e2: expr) :=
- match shift_match e2 with
- | shift_case1 n2 =>
- shruimm e1 n2
- | shift_default e2 =>
- Eop Oshru (e1:::e2:::Enil)
+
+(** Original definition:
+<<
+Nondetfunction shr (e1: expr) (e2: expr) :=
+ match e2 with
+ | Eop (Ointconst n2) Enil => shrimm e1 n2
+ | _ => Eop Oshr (e1:::e2:::Enil)
+ end.
+>>
+*)
+
+Inductive shr_cases: forall (e2: expr), Type :=
+ | shr_case1: forall n2, shr_cases (Eop (Ointconst n2) Enil)
+ | shr_default: forall (e2: expr), shr_cases e2.
+
+Definition shr_match (e2: expr) :=
+ match e2 as zz1 return shr_cases zz1 with
+ | Eop (Ointconst n2) Enil => shr_case1 n2
+ | e2 => shr_default e2
end.
Definition shr (e1: expr) (e2: expr) :=
- match shift_match e2 with
- | shift_case1 n2 =>
+ match shr_match e2 with
+ | shr_case1 n2 => (* Eop (Ointconst n2) Enil *)
shrimm e1 n2
- | shift_default e2 =>
+ | shr_default e2 =>
Eop Oshr (e1:::e2:::Enil)
end.
-(** ** Comparisons *)
-(*
-Definition comp (e1: expr) (e2: expr) :=
- match e1, e2 with
- | Eop (Ointconst n1) Enil, t2 => Eop (Ocmp (Ccompimm (swap_comparison c) n1)) (t2:::Enil)
- | t1, Eop (Ointconst n2) Enil => Eop (Ocmp (Ccompimm c n1)) (t1:::Enil)
- | Eop (Oshift s) (t1:::Enil), t2 => Eop (Ocmp (Ccompshift (swap_comparison c) s)) (t2:::t1:::Enil)
- | t1, Eop (Oshift s) (t2:::Enil) => Eop (Ocmp (Ccompshift c s)) (t1:::t2:::Enil)
- | _, _ => Eop (Ocmp (Ccomp c)) (e1:::e2:::Enil)
+(** Original definition:
+<<
+Nondetfunction shru (e1: expr) (e2: expr) :=
+ match e2 with
+ | Eop (Ointconst n2) Enil => shruimm e1 n2
+ | _ => Eop Oshru (e1:::e2:::Enil)
end.
+>>
*)
-
-Inductive comp_cases: forall (e1: expr) (e2: expr), Type :=
- | comp_case1:
- forall n1 t2,
- comp_cases (Eop (Ointconst n1) Enil) (t2)
- | comp_case2:
- forall t1 n2,
- comp_cases (t1) (Eop (Ointconst n2) Enil)
- | comp_case3:
- forall s t1 t2,
- comp_cases (Eop (Oshift s) (t1:::Enil)) (t2)
- | comp_case4:
- forall t1 s t2,
- comp_cases (t1) (Eop (Oshift s) (t2:::Enil))
- | comp_default:
- forall (e1: expr) (e2: expr),
- comp_cases e1 e2.
-Definition comp_match (e1: expr) (e2: expr) :=
- match e1 as z1, e2 as z2 return comp_cases z1 z2 with
+Inductive shru_cases: forall (e2: expr), Type :=
+ | shru_case1: forall n2, shru_cases (Eop (Ointconst n2) Enil)
+ | shru_default: forall (e2: expr), shru_cases e2.
+
+Definition shru_match (e2: expr) :=
+ match e2 as zz1 return shru_cases zz1 with
+ | Eop (Ointconst n2) Enil => shru_case1 n2
+ | e2 => shru_default e2
+ end.
+
+Definition shru (e1: expr) (e2: expr) :=
+ match shru_match e2 with
+ | shru_case1 n2 => (* Eop (Ointconst n2) Enil *)
+ shruimm e1 n2
+ | shru_default e2 =>
+ Eop Oshru (e1:::e2:::Enil)
+ end.
+
+
+(** ** Floating-point arithmetic *)
+
+Definition negf (e: expr) := Eop Onegf (e ::: Enil).
+Definition absf (e: expr) := Eop Oabsf (e ::: Enil).
+Definition addf (e1 e2: expr) := Eop Oaddf (e1 ::: e2 ::: Enil).
+Definition subf (e1 e2: expr) := Eop Osubf (e1 ::: e2 ::: Enil).
+Definition mulf (e1 e2: expr) := Eop Omulf (e1 ::: e2 ::: Enil).
+Definition divf (e1 e2: expr) := Eop Odivf (e1 ::: e2 ::: Enil).
+
+(** ** Comparisons *)
+
+(** Original definition:
+<<
+Nondetfunction comp (c: comparison) (e1: expr) (e2: expr) :=
+ match e1, e2 with
| Eop (Ointconst n1) Enil, t2 =>
- comp_case1 n1 t2
+ Eop (Ocmp (Ccompimm (swap_comparison c) n1)) (t2:::Enil)
| t1, Eop (Ointconst n2) Enil =>
- comp_case2 t1 n2
+ Eop (Ocmp (Ccompimm c n2)) (t1:::Enil)
| Eop (Oshift s) (t1:::Enil), t2 =>
- comp_case3 s t1 t2
+ Eop (Ocmp (Ccompshift (swap_comparison c) s)) (t2:::t1:::Enil)
| t1, Eop (Oshift s) (t2:::Enil) =>
- comp_case4 t1 s t2
- | e1, e2 =>
- comp_default e1 e2
+ Eop (Ocmp (Ccompshift c s)) (t1:::t2:::Enil)
+ | _, _ =>
+ Eop (Ocmp (Ccomp c)) (e1:::e2:::Enil)
+ end.
+>>
+*)
+
+Inductive comp_cases: forall (e1: expr) (e2: expr), Type :=
+ | comp_case1: forall n1 t2, comp_cases (Eop (Ointconst n1) Enil) (t2)
+ | comp_case2: forall t1 n2, comp_cases (t1) (Eop (Ointconst n2) Enil)
+ | comp_case3: forall s t1 t2, comp_cases (Eop (Oshift s) (t1:::Enil)) (t2)
+ | comp_case4: forall t1 s t2, comp_cases (t1) (Eop (Oshift s) (t2:::Enil))
+ | comp_default: forall (e1: expr) (e2: expr), comp_cases e1 e2.
+
+Definition comp_match (e1: expr) (e2: expr) :=
+ match e1 as zz1, e2 as zz2 return comp_cases zz1 zz2 with
+ | Eop (Ointconst n1) Enil, t2 => comp_case1 n1 t2
+ | t1, Eop (Ointconst n2) Enil => comp_case2 t1 n2
+ | Eop (Oshift s) (t1:::Enil), t2 => comp_case3 s t1 t2
+ | t1, Eop (Oshift s) (t2:::Enil) => comp_case4 t1 s t2
+ | e1, e2 => comp_default e1 e2
end.
Definition comp (c: comparison) (e1: expr) (e2: expr) :=
match comp_match e1 e2 with
- | comp_case1 n1 t2 =>
+ | comp_case1 n1 t2 => (* Eop (Ointconst n1) Enil, t2 *)
Eop (Ocmp (Ccompimm (swap_comparison c) n1)) (t2:::Enil)
- | comp_case2 t1 n2 =>
+ | comp_case2 t1 n2 => (* t1, Eop (Ointconst n2) Enil *)
Eop (Ocmp (Ccompimm c n2)) (t1:::Enil)
- | comp_case3 s t1 t2 =>
+ | comp_case3 s t1 t2 => (* Eop (Oshift s) (t1:::Enil), t2 *)
Eop (Ocmp (Ccompshift (swap_comparison c) s)) (t2:::t1:::Enil)
- | comp_case4 t1 s t2 =>
+ | comp_case4 t1 s t2 => (* t1, Eop (Oshift s) (t2:::Enil) *)
Eop (Ocmp (Ccompshift c s)) (t1:::t2:::Enil)
| comp_default e1 e2 =>
Eop (Ocmp (Ccomp c)) (e1:::e2:::Enil)
end.
+
+(** Original definition:
+<<
+Nondetfunction compu (c: comparison) (e1: expr) (e2: expr) :=
+ match e1, e2 with
+ | Eop (Ointconst n1) Enil, t2 =>
+ Eop (Ocmp (Ccompuimm (swap_comparison c) n1)) (t2:::Enil)
+ | t1, Eop (Ointconst n2) Enil =>
+ Eop (Ocmp (Ccompuimm c n2)) (t1:::Enil)
+ | Eop (Oshift s) (t1:::Enil), t2 =>
+ Eop (Ocmp (Ccompushift (swap_comparison c) s)) (t2:::t1:::Enil)
+ | t1, Eop (Oshift s) (t2:::Enil) =>
+ Eop (Ocmp (Ccompushift c s)) (t1:::t2:::Enil)
+ | _, _ =>
+ Eop (Ocmp (Ccompu c)) (e1:::e2:::Enil)
+ end.
+>>
+*)
+
+Inductive compu_cases: forall (e1: expr) (e2: expr), Type :=
+ | compu_case1: forall n1 t2, compu_cases (Eop (Ointconst n1) Enil) (t2)
+ | compu_case2: forall t1 n2, compu_cases (t1) (Eop (Ointconst n2) Enil)
+ | compu_case3: forall s t1 t2, compu_cases (Eop (Oshift s) (t1:::Enil)) (t2)
+ | compu_case4: forall t1 s t2, compu_cases (t1) (Eop (Oshift s) (t2:::Enil))
+ | compu_default: forall (e1: expr) (e2: expr), compu_cases e1 e2.
+
+Definition compu_match (e1: expr) (e2: expr) :=
+ match e1 as zz1, e2 as zz2 return compu_cases zz1 zz2 with
+ | Eop (Ointconst n1) Enil, t2 => compu_case1 n1 t2
+ | t1, Eop (Ointconst n2) Enil => compu_case2 t1 n2
+ | Eop (Oshift s) (t1:::Enil), t2 => compu_case3 s t1 t2
+ | t1, Eop (Oshift s) (t2:::Enil) => compu_case4 t1 s t2
+ | e1, e2 => compu_default e1 e2
+ end.
+
Definition compu (c: comparison) (e1: expr) (e2: expr) :=
- match comp_match e1 e2 with
- | comp_case1 n1 t2 =>
+ match compu_match e1 e2 with
+ | compu_case1 n1 t2 => (* Eop (Ointconst n1) Enil, t2 *)
Eop (Ocmp (Ccompuimm (swap_comparison c) n1)) (t2:::Enil)
- | comp_case2 t1 n2 =>
+ | compu_case2 t1 n2 => (* t1, Eop (Ointconst n2) Enil *)
Eop (Ocmp (Ccompuimm c n2)) (t1:::Enil)
- | comp_case3 s t1 t2 =>
+ | compu_case3 s t1 t2 => (* Eop (Oshift s) (t1:::Enil), t2 *)
Eop (Ocmp (Ccompushift (swap_comparison c) s)) (t2:::t1:::Enil)
- | comp_case4 t1 s t2 =>
+ | compu_case4 t1 s t2 => (* t1, Eop (Oshift s) (t2:::Enil) *)
Eop (Ocmp (Ccompushift c s)) (t1:::t2:::Enil)
- | comp_default e1 e2 =>
+ | compu_default e1 e2 =>
Eop (Ocmp (Ccompu c)) (e1:::e2:::Enil)
end.
+
Definition compf (c: comparison) (e1: expr) (e2: expr) :=
Eop (Ocmp (Ccompf c)) (e1 ::: e2 ::: Enil).
-(** ** Non-optimized operators. *)
+(** ** Integer conversions *)
+
+Definition cast8unsigned (e: expr) := andimm (Int.repr 255) e.
+
+Definition cast8signed (e: expr) := shrimm (shlimm e (Int.repr 24)) (Int.repr 24).
+
+Definition cast16unsigned (e: expr) := andimm (Int.repr 65535) e.
+
+Definition cast16signed (e: expr) := shrimm (shlimm e (Int.repr 16)) (Int.repr 16).
+
+(** ** Floating-point conversions *)
-Definition cast8unsigned (e: expr) := Eop Ocast8unsigned (e ::: Enil).
-Definition cast8signed (e: expr) := Eop Ocast8signed (e ::: Enil).
-Definition cast16unsigned (e: expr) := Eop Ocast16unsigned (e ::: Enil).
-Definition cast16signed (e: expr) := Eop Ocast16signed (e ::: Enil).
Definition singleoffloat (e: expr) := Eop Osingleoffloat (e ::: Enil).
-Definition negint (e: expr) := Eop (Orsubimm Int.zero) (e ::: Enil).
-Definition negf (e: expr) := Eop Onegf (e ::: Enil).
-Definition absf (e: expr) := Eop Oabsf (e ::: Enil).
Definition intoffloat (e: expr) := Eop Ointoffloat (e ::: Enil).
Definition intuoffloat (e: expr) := Eop Ointuoffloat (e ::: Enil).
Definition floatofint (e: expr) := Eop Ofloatofint (e ::: Enil).
Definition floatofintu (e: expr) := Eop Ofloatofintu (e ::: Enil).
-Definition addf (e1 e2: expr) := Eop Oaddf (e1 ::: e2 ::: Enil).
-Definition subf (e1 e2: expr) := Eop Osubf (e1 ::: e2 ::: Enil).
-Definition mulf (e1 e2: expr) := Eop Omulf (e1 ::: e2 ::: Enil).
-Definition divf (e1 e2: expr) := Eop Odivf (e1 ::: e2 ::: Enil).
(** ** Recognition of addressing modes for load and store operations *)
-(*
-Definition addressing (e: expr) :=
- match e with
- | Eop (Oaddrstack n) Enil => (Ainstack n, Enil)
- | Eop (Oaddimm n) (e1:::Enil) => (Aindexed n, e1:::Enil)
- | Eop (Oaddshift s) (e1:::e2:::Enil) => (Aindexed2shift s, e1:::e2:::Enil)
- | Eop Oadd (e1:::e2:::Enil) => (Aindexed2, e1:::e2:::Enil)
- | _ => (Aindexed Int.zero, e:::Enil)
- end.
-*)
-
-Inductive addressing_cases: forall (e: expr), Type :=
- | addressing_case2:
- forall n,
- addressing_cases (Eop (Oaddrstack n) Enil)
- | addressing_case3:
- forall n e1,
- addressing_cases (Eop (Oaddimm n) (e1:::Enil))
- | addressing_case4:
- forall s e1 e2,
- addressing_cases (Eop (Oaddshift s) (e1:::e2:::Enil))
- | addressing_case5:
- forall e1 e2,
- addressing_cases (Eop Oadd (e1:::e2:::Enil))
- | addressing_default:
- forall (e: expr),
- addressing_cases e.
-
-Definition addressing_match (e: expr) :=
- match e as z1 return addressing_cases z1 with
- | Eop (Oaddrstack n) Enil =>
- addressing_case2 n
- | Eop (Oaddimm n) (e1:::Enil) =>
- addressing_case3 n e1
- | Eop (Oaddshift s) (e1:::e2:::Enil) =>
- addressing_case4 s e1 e2
- | Eop Oadd (e1:::e2:::Enil) =>
- addressing_case5 e1 e2
- | e =>
- addressing_default e
- end.
-
(** We do not recognize the [Aindexed2] and [Aindexed2shift] modes
for floating-point accesses, since these are not supported
by the hardware and emulated inefficiently in [Asmgen].
Likewise, [Aindexed2shift] are not supported for halfword
and signed byte accesses. *)
-Definition can_use_Aindexed (chunk: memory_chunk): bool :=
+Definition can_use_Aindexed2 (chunk: memory_chunk): bool :=
match chunk with
| Mint8signed => true
| Mint8unsigned => true
@@ -1091,7 +1105,7 @@ Definition can_use_Aindexed (chunk: memory_chunk): bool :=
| Mfloat64 => false
end.
-Definition can_use_Aindexed2 (chunk: memory_chunk): bool :=
+Definition can_use_Aindexed2shift (chunk: memory_chunk): bool :=
match chunk with
| Mint8signed => false
| Mint8unsigned => true
@@ -1102,22 +1116,54 @@ Definition can_use_Aindexed2 (chunk: memory_chunk): bool :=
| Mfloat64 => false
end.
-Definition addressing (chunk: memory_chunk) (e: expr) :=
- match addressing_match e with
- | addressing_case2 n =>
- (Ainstack n, Enil)
- | addressing_case3 n e1 =>
- (Aindexed n, e1:::Enil)
- | addressing_case4 s e1 e2 =>
- if can_use_Aindexed2 chunk
+(** Original definition:
+<<
+Nondetfunction addressing (chunk: memory_chunk) (e: expr) :=
+ match e with
+ | Eop (Oaddrstack n) Enil => (Ainstack n, Enil)
+ | Eop (Oaddimm n) (e1:::Enil) => (Aindexed n, e1:::Enil)
+ | Eop (Oaddshift s) (e1:::e2:::Enil) =>
+ if can_use_Aindexed2shift chunk
then (Aindexed2shift s, e1:::e2:::Enil)
else (Aindexed Int.zero, Eop (Oaddshift s) (e1:::e2:::Enil) ::: Enil)
- | addressing_case5 e1 e2 =>
- if can_use_Aindexed chunk
+ | Eop Oadd (e1:::e2:::Enil) =>
+ if can_use_Aindexed2 chunk
then (Aindexed2, e1:::e2:::Enil)
else (Aindexed Int.zero, Eop Oadd (e1:::e2:::Enil) ::: Enil)
+ | _ => (Aindexed Int.zero, e:::Enil)
+ end.
+>>
+*)
+
+Inductive addressing_cases: forall (e: expr), Type :=
+ | addressing_case1: forall n, addressing_cases (Eop (Oaddrstack n) Enil)
+ | addressing_case2: forall n e1, addressing_cases (Eop (Oaddimm n) (e1:::Enil))
+ | addressing_case3: forall s e1 e2, addressing_cases (Eop (Oaddshift s) (e1:::e2:::Enil))
+ | addressing_case4: forall e1 e2, addressing_cases (Eop Oadd (e1:::e2:::Enil))
+ | addressing_default: forall (e: expr), addressing_cases e.
+
+Definition addressing_match (e: expr) :=
+ match e as zz1 return addressing_cases zz1 with
+ | Eop (Oaddrstack n) Enil => addressing_case1 n
+ | Eop (Oaddimm n) (e1:::Enil) => addressing_case2 n e1
+ | Eop (Oaddshift s) (e1:::e2:::Enil) => addressing_case3 s e1 e2
+ | Eop Oadd (e1:::e2:::Enil) => addressing_case4 e1 e2
+ | e => addressing_default e
+ end.
+
+Definition addressing (chunk: memory_chunk) (e: expr) :=
+ match addressing_match e with
+ | addressing_case1 n => (* Eop (Oaddrstack n) Enil *)
+ (Ainstack n, Enil)
+ | addressing_case2 n e1 => (* Eop (Oaddimm n) (e1:::Enil) *)
+ (Aindexed n, e1:::Enil)
+ | addressing_case3 s e1 e2 => (* Eop (Oaddshift s) (e1:::e2:::Enil) *)
+ if can_use_Aindexed2shift chunk then (Aindexed2shift s, e1:::e2:::Enil) else (Aindexed Int.zero, Eop (Oaddshift s) (e1:::e2:::Enil) ::: Enil)
+ | addressing_case4 e1 e2 => (* Eop Oadd (e1:::e2:::Enil) *)
+ if can_use_Aindexed2 chunk then (Aindexed2, e1:::e2:::Enil) else (Aindexed Int.zero, Eop Oadd (e1:::e2:::Enil) ::: Enil)
| addressing_default e =>
(Aindexed Int.zero, e:::Enil)
end.
+