aboutsummaryrefslogtreecommitdiffstats
path: root/riscV/Op.v
diff options
context:
space:
mode:
Diffstat (limited to 'riscV/Op.v')
-rw-r--r--riscV/Op.v275
1 files changed, 153 insertions, 122 deletions
diff --git a/riscV/Op.v b/riscV/Op.v
index d819ee32..2271ecd2 100644
--- a/riscV/Op.v
+++ b/riscV/Op.v
@@ -241,10 +241,10 @@ Definition eval_operation
| Omul, v1 :: v2 :: nil => Some (Val.mul v1 v2)
| Omulhs, v1::v2::nil => Some (Val.mulhs v1 v2)
| Omulhu, v1::v2::nil => Some (Val.mulhu v1 v2)
- | Odiv, v1 :: v2 :: nil => Val.divs v1 v2
- | Odivu, v1 :: v2 :: nil => Val.divu v1 v2
- | Omod, v1 :: v2 :: nil => Val.mods v1 v2
- | Omodu, v1 :: v2 :: nil => Val.modu v1 v2
+ | Odiv, v1 :: v2 :: nil => Some (Val.maketotal (Val.divs v1 v2))
+ | Odivu, v1 :: v2 :: nil => Some (Val.maketotal (Val.divu v1 v2))
+ | Omod, v1 :: v2 :: nil => Some (Val.maketotal (Val.mods v1 v2))
+ | Omodu, v1 :: v2 :: nil => Some (Val.maketotal (Val.modu v1 v2))
| Oand, v1 :: v2 :: nil => Some (Val.and v1 v2)
| Oandimm n, v1 :: nil => Some (Val.and v1 (Vint n))
| Oor, v1 :: v2 :: nil => Some (Val.or v1 v2)
@@ -257,7 +257,7 @@ Definition eval_operation
| Oshrimm n, v1 :: nil => Some (Val.shr v1 (Vint n))
| Oshru, v1 :: v2 :: nil => Some (Val.shru v1 v2)
| Oshruimm n, v1 :: nil => Some (Val.shru v1 (Vint n))
- | Oshrximm n, v1::nil => Val.shrx v1 (Vint n)
+ | Oshrximm n, v1::nil => Some (Val.maketotal (Val.shrx v1 (Vint n)))
| Omakelong, v1::v2::nil => Some (Val.longofwords v1 v2)
| Olowlong, v1::nil => Some (Val.loword v1)
| Ohighlong, v1::nil => Some (Val.hiword v1)
@@ -270,10 +270,10 @@ Definition eval_operation
| Omull, v1::v2::nil => Some (Val.mull v1 v2)
| Omullhs, v1::v2::nil => Some (Val.mullhs v1 v2)
| Omullhu, v1::v2::nil => Some (Val.mullhu v1 v2)
- | Odivl, v1::v2::nil => Val.divls v1 v2
- | Odivlu, v1::v2::nil => Val.divlu v1 v2
- | Omodl, v1::v2::nil => Val.modls v1 v2
- | Omodlu, v1::v2::nil => Val.modlu v1 v2
+ | Odivl, v1::v2::nil => Some (Val.maketotal (Val.divls v1 v2))
+ | Odivlu, v1::v2::nil => Some (Val.maketotal (Val.divlu v1 v2))
+ | Omodl, v1::v2::nil => Some (Val.maketotal (Val.modls v1 v2))
+ | Omodlu, v1::v2::nil => Some (Val.maketotal (Val.modlu v1 v2))
| Oandl, v1::v2::nil => Some(Val.andl v1 v2)
| Oandlimm n, v1::nil => Some (Val.andl v1 (Vlong n))
| Oorl, v1::v2::nil => Some(Val.orl v1 v2)
@@ -286,7 +286,7 @@ Definition eval_operation
| Oshrlimm n, v1::nil => Some (Val.shrl v1 (Vint n))
| Oshrlu, v1::v2::nil => Some (Val.shrlu v1 v2)
| Oshrluimm n, v1::nil => Some (Val.shrlu v1 (Vint n))
- | Oshrxlimm n, v1::nil => Val.shrxl v1 (Vint n)
+ | Oshrxlimm n, v1::nil => Some (Val.maketotal (Val.shrxl v1 (Vint n)))
| Onegf, v1::nil => Some (Val.negf v1)
| Oabsf, v1::nil => Some (Val.absf v1)
| Oaddf, v1::v2::nil => Some (Val.addf v1 v2)
@@ -301,22 +301,22 @@ Definition eval_operation
| Odivfs, v1::v2::nil => Some (Val.divfs v1 v2)
| Osingleoffloat, v1::nil => Some (Val.singleoffloat v1)
| Ofloatofsingle, v1::nil => Some (Val.floatofsingle v1)
- | Ointoffloat, v1::nil => Val.intoffloat v1
- | Ointuoffloat, v1::nil => Val.intuoffloat v1
- | Ofloatofint, v1::nil => Val.floatofint v1
- | Ofloatofintu, v1::nil => Val.floatofintu v1
- | Ointofsingle, v1::nil => Val.intofsingle v1
- | Ointuofsingle, v1::nil => Val.intuofsingle v1
- | Osingleofint, v1::nil => Val.singleofint v1
- | Osingleofintu, v1::nil => Val.singleofintu v1
- | Olongoffloat, v1::nil => Val.longoffloat v1
- | Olonguoffloat, v1::nil => Val.longuoffloat v1
- | Ofloatoflong, v1::nil => Val.floatoflong v1
- | Ofloatoflongu, v1::nil => Val.floatoflongu v1
- | Olongofsingle, v1::nil => Val.longofsingle v1
- | Olonguofsingle, v1::nil => Val.longuofsingle v1
- | Osingleoflong, v1::nil => Val.singleoflong v1
- | Osingleoflongu, v1::nil => Val.singleoflongu v1
+ | Ointoffloat, v1::nil => Some (Val.maketotal (Val.intoffloat v1))
+ | Ointuoffloat, v1::nil => Some (Val.maketotal (Val.intuoffloat v1))
+ | Ofloatofint, v1::nil => Some (Val.maketotal (Val.floatofint v1))
+ | Ofloatofintu, v1::nil => Some (Val.maketotal (Val.floatofintu v1))
+ | Ointofsingle, v1::nil => Some (Val.maketotal (Val.intofsingle v1))
+ | Ointuofsingle, v1::nil => Some (Val.maketotal (Val.intuofsingle v1))
+ | Osingleofint, v1::nil => Some (Val.maketotal (Val.singleofint v1))
+ | Osingleofintu, v1::nil => Some (Val.maketotal (Val.singleofintu v1))
+ | Olongoffloat, v1::nil => Some (Val.maketotal (Val.longoffloat v1))
+ | Olonguoffloat, v1::nil => Some (Val.maketotal (Val.longuoffloat v1))
+ | Ofloatoflong, v1::nil => Some (Val.maketotal (Val.floatoflong v1))
+ | Ofloatoflongu, v1::nil => Some (Val.maketotal (Val.floatoflongu v1))
+ | Olongofsingle, v1::nil => Some (Val.maketotal (Val.longofsingle v1))
+ | Olonguofsingle, v1::nil => Some (Val.maketotal (Val.longuofsingle v1))
+ | Osingleoflong, v1::nil => Some (Val.maketotal (Val.singleoflong v1))
+ | Osingleoflongu, v1::nil => Some (Val.maketotal (Val.singleoflongu v1))
| Ocmp c, _ => Some (Val.of_optbool (eval_condition c vl m))
| _, _ => None
end.
@@ -539,15 +539,17 @@ Proof with (try exact I; try reflexivity; auto using Val.Vptr_has_type).
- destruct v0; destruct v1...
- destruct v0; destruct v1...
(* div, divu *)
- - destruct v0; destruct v1; simpl in *; inv H0.
- destruct (Int.eq i0 Int.zero || Int.eq i (Int.repr Int.min_signed) && Int.eq i0 Int.mone); inv H2...
- - destruct v0; destruct v1; simpl in *; inv H0.
- destruct (Int.eq i0 Int.zero); inv H2...
+ - destruct v0; destruct v1; cbn; trivial.
+ destruct (Int.eq i0 Int.zero
+ || Int.eq i (Int.repr (-2147483648)) && Int.eq i0 Int.mone); cbn; trivial.
+ - destruct v0; destruct v1; cbn; trivial.
+ destruct (Int.eq i0 Int.zero); cbn; trivial.
(* mod, modu *)
- - destruct v0; destruct v1; simpl in *; inv H0.
- destruct (Int.eq i0 Int.zero || Int.eq i (Int.repr Int.min_signed) && Int.eq i0 Int.mone); inv H2...
- - destruct v0; destruct v1; simpl in *; inv H0.
- destruct (Int.eq i0 Int.zero); inv H2...
+ - destruct v0; destruct v1; cbn; trivial.
+ destruct (Int.eq i0 Int.zero
+ || Int.eq i (Int.repr (-2147483648)) && Int.eq i0 Int.mone); cbn; trivial.
+ - destruct v0; destruct v1; cbn; trivial.
+ destruct (Int.eq i0 Int.zero); cbn; trivial.
(* and, andimm *)
- destruct v0; destruct v1...
- destruct v0...
@@ -567,7 +569,8 @@ Proof with (try exact I; try reflexivity; auto using Val.Vptr_has_type).
- destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
- destruct v0; simpl... destruct (Int.ltu n Int.iwordsize)...
(* shrx *)
- - destruct v0; simpl in H0; try discriminate. destruct (Int.ltu n (Int.repr 31)); inv H0...
+ - destruct v0; cbn; trivial.
+ destruct (Int.ltu n (Int.repr 31)); cbn; trivial.
(* makelong, lowlong, highlong *)
- destruct v0; destruct v1...
- destruct v0...
@@ -588,15 +591,19 @@ Proof with (try exact I; try reflexivity; auto using Val.Vptr_has_type).
- destruct v0; destruct v1...
- destruct v0; destruct v1...
(* divl, divlu *)
- - destruct v0; destruct v1; simpl in *; inv H0.
- destruct (Int64.eq i0 Int64.zero || Int64.eq i (Int64.repr Int64.min_signed) && Int64.eq i0 Int64.mone); inv H2...
- - destruct v0; destruct v1; simpl in *; inv H0.
- destruct (Int64.eq i0 Int64.zero); inv H2...
+ - destruct v0; destruct v1; cbn; trivial.
+ destruct (Int64.eq i0 Int64.zero
+ || Int64.eq i (Int64.repr (-9223372036854775808)) &&
+ Int64.eq i0 Int64.mone); cbn; trivial.
+ - destruct v0; destruct v1; cbn; trivial.
+ destruct (Int64.eq i0 Int64.zero); cbn; trivial.
(* modl, modlu *)
- - destruct v0; destruct v1; simpl in *; inv H0.
- destruct (Int64.eq i0 Int64.zero || Int64.eq i (Int64.repr Int64.min_signed) && Int64.eq i0 Int64.mone); inv H2...
- - destruct v0; destruct v1; simpl in *; inv H0.
- destruct (Int64.eq i0 Int64.zero); inv H2...
+ - destruct v0; destruct v1; cbn; trivial.
+ destruct (Int64.eq i0 Int64.zero
+ || Int64.eq i (Int64.repr (-9223372036854775808)) &&
+ Int64.eq i0 Int64.mone); cbn; trivial.
+ - destruct v0; destruct v1; cbn; trivial.
+ destruct (Int64.eq i0 Int64.zero); cbn; trivial.
(* andl, andlimm *)
- destruct v0; destruct v1...
- destruct v0...
@@ -616,7 +623,8 @@ Proof with (try exact I; try reflexivity; auto using Val.Vptr_has_type).
- destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int64.iwordsize')...
- destruct v0; simpl... destruct (Int.ltu n Int64.iwordsize')...
(* shrxl *)
- - destruct v0; simpl in H0; try discriminate. destruct (Int.ltu n (Int.repr 63)); inv H0...
+ - destruct v0; cbn; trivial.
+ destruct (Int.ltu n (Int.repr 63)); cbn; trivial.
(* negf, absf *)
- destruct v0...
- destruct v0...
@@ -639,50 +647,47 @@ Proof with (try exact I; try reflexivity; auto using Val.Vptr_has_type).
- destruct v0...
- destruct v0...
(* intoffloat, intuoffloat *)
- - destruct v0; simpl in H0; inv H0. destruct (Float.to_int f); inv H2...
- - destruct v0; simpl in H0; inv H0. destruct (Float.to_intu f); inv H2...
+ - destruct v0; cbn; trivial.
+ destruct (Float.to_int f); cbn; trivial.
+ - destruct v0; cbn; trivial.
+ destruct (Float.to_intu f); cbn; trivial.
(* floatofint, floatofintu *)
- - destruct v0; simpl in H0; inv H0...
- - destruct v0; simpl in H0; inv H0...
+ - destruct v0; cbn; trivial.
+ - destruct v0; cbn; trivial.
(* intofsingle, intuofsingle *)
- - destruct v0; simpl in H0; inv H0. destruct (Float32.to_int f); inv H2...
- - destruct v0; simpl in H0; inv H0. destruct (Float32.to_intu f); inv H2...
+ - destruct v0; cbn; trivial.
+ destruct (Float32.to_int f); cbn; trivial.
+ - destruct v0; cbn; trivial.
+ destruct (Float32.to_intu f); cbn; trivial.
(* singleofint, singleofintu *)
- - destruct v0; simpl in H0; inv H0...
- - destruct v0; simpl in H0; inv H0...
+ - destruct v0; cbn; trivial.
+ - destruct v0; cbn; trivial.
(* longoffloat, longuoffloat *)
- - destruct v0; simpl in H0; inv H0. destruct (Float.to_long f); inv H2...
- - destruct v0; simpl in H0; inv H0. destruct (Float.to_longu f); inv H2...
+ - destruct v0; cbn; trivial.
+ destruct (Float.to_long f); cbn; trivial.
+ - destruct v0; cbn; trivial.
+ destruct (Float.to_longu f); cbn; trivial.
(* floatoflong, floatoflongu *)
- - destruct v0; simpl in H0; inv H0...
- - destruct v0; simpl in H0; inv H0...
+ - destruct v0; cbn; trivial.
+ - destruct v0; cbn; trivial.
(* longofsingle, longuofsingle *)
- - destruct v0; simpl in H0; inv H0. destruct (Float32.to_long f); inv H2...
- - destruct v0; simpl in H0; inv H0. destruct (Float32.to_longu f); inv H2...
+ - destruct v0; cbn; trivial.
+ destruct (Float32.to_long f); cbn; trivial.
+ - destruct v0; cbn; trivial.
+ destruct (Float32.to_longu f); cbn; trivial.
(* singleoflong, singleoflongu *)
- - destruct v0; simpl in H0; inv H0...
- - destruct v0; simpl in H0; inv H0...
+ - destruct v0; cbn; trivial.
+ - destruct v0; cbn; trivial.
(* cmp *)
- destruct (eval_condition cond vl m)... destruct b...
Qed.
-
+(* This should not be simplified to "false" because it breaks proofs elsewhere. *)
Definition is_trapping_op (op : operation) :=
match op with
- | Odiv | Odivl | Odivu | Odivlu
- | Omod | Omodl | Omodu | Omodlu
- | Oshrximm _ | Oshrxlimm _
- | Ointoffloat | Ointuoffloat
- | Ointofsingle | Ointuofsingle
- | Olongoffloat | Olonguoffloat
- | Olongofsingle | Olonguofsingle
- | Osingleofint | Osingleofintu
- | Osingleoflong | Osingleoflongu
- | Ofloatofint | Ofloatofintu
- | Ofloatoflong | Ofloatoflongu => true
+ | Omove => false
| _ => false
end.
-
Definition args_of_operation op :=
if eq_operation op Omove
@@ -1071,19 +1076,29 @@ Proof.
- inv H4; inv H2; simpl; auto.
- inv H4; inv H2; simpl; auto.
(* div, divu *)
- - inv H4; inv H3; simpl in H1; inv H1. simpl.
+ - inv H4; inv H2; cbn.
+ all: try apply Val.val_inject_undef.
destruct (Int.eq i0 Int.zero
- || Int.eq i (Int.repr Int.min_signed) && Int.eq i0 Int.mone); inv H2.
- TrivialExists.
- - inv H4; inv H3; simpl in H1; inv H1. simpl.
- destruct (Int.eq i0 Int.zero); inv H2. TrivialExists.
+ || Int.eq i (Int.repr (-2147483648)) && Int.eq i0 Int.mone); cbn.
+ apply Val.val_inject_undef.
+ apply Val.inject_int.
+ - inv H4; inv H2; cbn.
+ all: try apply Val.val_inject_undef.
+ destruct (Int.eq i0 Int.zero); cbn.
+ apply Val.val_inject_undef.
+ apply Val.inject_int.
(* mod, modu *)
- - inv H4; inv H3; simpl in H1; inv H1. simpl.
+ - inv H4; inv H2; cbn.
+ all: try apply Val.val_inject_undef.
destruct (Int.eq i0 Int.zero
- || Int.eq i (Int.repr Int.min_signed) && Int.eq i0 Int.mone); inv H2.
- TrivialExists.
- - inv H4; inv H3; simpl in H1; inv H1. simpl.
- destruct (Int.eq i0 Int.zero); inv H2. TrivialExists.
+ || Int.eq i (Int.repr (-2147483648)) && Int.eq i0 Int.mone); cbn.
+ apply Val.val_inject_undef.
+ apply Val.inject_int.
+ - inv H4; inv H2; cbn.
+ all: try apply Val.val_inject_undef.
+ destruct (Int.eq i0 Int.zero); cbn.
+ apply Val.val_inject_undef.
+ apply Val.inject_int.
(* and, andimm *)
- inv H4; inv H2; simpl; auto.
- inv H4; simpl; auto.
@@ -1103,8 +1118,10 @@ Proof.
- inv H4; inv H2; simpl; auto. destruct (Int.ltu i0 Int.iwordsize); auto.
- inv H4; simpl; auto. destruct (Int.ltu n Int.iwordsize); auto.
(* shrx *)
- - inv H4; simpl in H1; try discriminate. simpl.
- destruct (Int.ltu n (Int.repr 31)); inv H1. TrivialExists.
+ - inv H4; cbn; try apply Val.val_inject_undef.
+ destruct (Int.ltu n (Int.repr 31)); cbn.
+ apply Val.inject_int.
+ apply Val.val_inject_undef.
(* makelong, highlong, lowlong *)
- inv H4; inv H2; simpl; auto.
- inv H4; simpl; auto.
@@ -1123,19 +1140,31 @@ Proof.
- inv H4; inv H2; simpl; auto.
- inv H4; inv H2; simpl; auto.
(* divl, divlu *)
- - inv H4; inv H3; simpl in H1; inv H1. simpl.
+ - inv H4; inv H2; cbn.
+ all: try apply Val.val_inject_undef.
destruct (Int64.eq i0 Int64.zero
- || Int64.eq i (Int64.repr Int64.min_signed) && Int64.eq i0 Int64.mone); inv H2.
- TrivialExists.
- - inv H4; inv H3; simpl in H1; inv H1. simpl.
- destruct (Int64.eq i0 Int64.zero); inv H2. TrivialExists.
+ || Int64.eq i (Int64.repr (-9223372036854775808)) &&
+ Int64.eq i0 Int64.mone); cbn.
+ apply Val.val_inject_undef.
+ apply Val.inject_long.
+ - inv H4; inv H2; cbn.
+ all: try apply Val.val_inject_undef.
+ destruct (Int64.eq i0 Int64.zero); cbn.
+ apply Val.val_inject_undef.
+ apply Val.inject_long.
(* modl, modlu *)
- - inv H4; inv H3; simpl in H1; inv H1. simpl.
+ - inv H4; inv H2; cbn.
+ all: try apply Val.val_inject_undef.
destruct (Int64.eq i0 Int64.zero
- || Int64.eq i (Int64.repr Int64.min_signed) && Int64.eq i0 Int64.mone); inv H2.
- TrivialExists.
- - inv H4; inv H3; simpl in H1; inv H1. simpl.
- destruct (Int64.eq i0 Int64.zero); inv H2. TrivialExists.
+ || Int64.eq i (Int64.repr (-9223372036854775808)) &&
+ Int64.eq i0 Int64.mone); cbn.
+ apply Val.val_inject_undef.
+ apply Val.inject_long.
+ - inv H4; inv H2; cbn.
+ all: try apply Val.val_inject_undef.
+ destruct (Int64.eq i0 Int64.zero); cbn.
+ apply Val.val_inject_undef.
+ apply Val.inject_long.
(* andl, andlimm *)
- inv H4; inv H2; simpl; auto.
- inv H4; simpl; auto.
@@ -1154,9 +1183,11 @@ Proof.
(* shru, shruimm *)
- inv H4; inv H2; simpl; auto. destruct (Int.ltu i0 Int64.iwordsize'); auto.
- inv H4; simpl; auto. destruct (Int.ltu n Int64.iwordsize'); auto.
- (* shrx *)
- - inv H4; simpl in H1; try discriminate. simpl.
- destruct (Int.ltu n (Int.repr 63)); inv H1. TrivialExists.
+ (* shrx *)
+ - inv H4; cbn; try apply Val.val_inject_undef.
+ destruct (Int.ltu n (Int.repr 63)); cbn.
+ apply Val.inject_long.
+ apply Val.val_inject_undef.
(* negf, absf *)
- inv H4; simpl; auto.
- inv H4; simpl; auto.
@@ -1179,37 +1210,37 @@ Proof.
- inv H4; simpl; auto.
- inv H4; simpl; auto.
(* intoffloat, intuoffloat *)
- - inv H4; simpl in H1; inv H1. simpl. destruct (Float.to_int f0); simpl in H2; inv H2.
- exists (Vint i); auto.
- - inv H4; simpl in H1; inv H1. simpl. destruct (Float.to_intu f0); simpl in H2; inv H2.
- exists (Vint i); auto.
+ - inv H4; cbn; auto.
+ destruct (Float.to_int f0); cbn; auto.
+ - inv H4; cbn; auto.
+ destruct (Float.to_intu f0); cbn; auto.
(* floatofint, floatofintu *)
- - inv H4; simpl in H1; inv H1. simpl. TrivialExists.
- - inv H4; simpl in H1; inv H1. simpl. TrivialExists.
+ - inv H4; cbn; auto.
+ - inv H4; cbn; auto.
(* intofsingle, intuofsingle *)
- - inv H4; simpl in H1; inv H1. simpl. destruct (Float32.to_int f0); simpl in H2; inv H2.
- exists (Vint i); auto.
- - inv H4; simpl in H1; inv H1. simpl. destruct (Float32.to_intu f0); simpl in H2; inv H2.
- exists (Vint i); auto.
+ - inv H4; cbn; auto.
+ destruct (Float32.to_int f0); cbn; auto.
+ - inv H4; cbn; auto.
+ destruct (Float32.to_intu f0); cbn; auto.
(* singleofint, singleofintu *)
- - inv H4; simpl in H1; inv H1. simpl. TrivialExists.
- - inv H4; simpl in H1; inv H1. simpl. TrivialExists.
+ - inv H4; cbn; auto.
+ - inv H4; cbn; auto.
(* longoffloat, longuoffloat *)
- - inv H4; simpl in H1; inv H1. simpl. destruct (Float.to_long f0); simpl in H2; inv H2.
- exists (Vlong i); auto.
- - inv H4; simpl in H1; inv H1. simpl. destruct (Float.to_longu f0); simpl in H2; inv H2.
- exists (Vlong i); auto.
+ - inv H4; cbn; auto.
+ destruct (Float.to_long f0); cbn; auto.
+ - inv H4; cbn; auto.
+ destruct (Float.to_longu f0); cbn; auto.
(* floatoflong, floatoflongu *)
- - inv H4; simpl in H1; inv H1. simpl. TrivialExists.
- - inv H4; simpl in H1; inv H1. simpl. TrivialExists.
+ - inv H4; cbn; auto.
+ - inv H4; cbn; auto.
(* longofsingle, longuofsingle *)
- - inv H4; simpl in H1; inv H1. simpl. destruct (Float32.to_long f0); simpl in H2; inv H2.
- exists (Vlong i); auto.
- - inv H4; simpl in H1; inv H1. simpl. destruct (Float32.to_longu f0); simpl in H2; inv H2.
- exists (Vlong i); auto.
+ - inv H4; cbn; auto.
+ destruct (Float32.to_long f0); cbn; auto.
+ - inv H4; cbn; auto.
+ destruct (Float32.to_longu f0); cbn; auto.
(* singleoflong, singleoflongu *)
- - inv H4; simpl in H1; inv H1. simpl. TrivialExists.
- - inv H4; simpl in H1; inv H1. simpl. TrivialExists.
+ - inv H4; cbn; auto.
+ - inv H4; cbn; auto.
(* cmp *)
- subst v1. destruct (eval_condition cond vl1 m1) eqn:?.
exploit eval_condition_inj; eauto. intros EQ; rewrite EQ.