From compcert Require Import lib.Integers.
From compcert Require Import lib.Floats.
From Velus Require Import Common.
From Velus Require Import Common.CompCertLib.
From Velus Require Import Operators.
From Velus Require Import Ident.
From compcert Require common.Values.
From compcert Require cfrontend.Cop.
From compcert Require cfrontend.Ctypes.
From compcert Require cfrontend.Ctyping.
From compcert Require common.Memory.
From compcert Require common.Memdata.
From compcert Require lib.Maps.
From Coq Require Import String.
From Coq Require Import ZArith.BinInt.
Open Scope bool_scope.
Hint Resolve Z.divide_refl.
Definition empty_composite_env :
Ctypes.composite_env := (
Maps.PTree.empty _).
Module Export Op <:
OPERATORS.
Definition val:
Type :=
Values.val.
Inductive type' :
Type :=
|
Tint:
Ctypes.intsize ->
Ctypes.signedness ->
type'
|
Tlong:
Ctypes.signedness ->
type'
|
Tfloat:
Ctypes.floatsize ->
type'.
Definition type :=
type'.
Definition cltype (
ty:
type) :
Ctypes.type :=
match ty with
|
Tint sz sg =>
Ctypes.Tint sz sg Ctypes.noattr
|
Tlong sg =>
Ctypes.Tlong sg (
Ctypes.mk_attr false (
Some (
Npos 3)))
|
Tfloat sz =>
Ctypes.Tfloat sz Ctypes.noattr
end.
Definition typecl (
ty:
Ctypes.type) :
option type :=
match ty with
|
Ctypes.Tint sz sg attr =>
Some (
Tint sz sg)
|
Ctypes.Tlong sg attr =>
Some (
Tlong sg)
|
Ctypes.Tfloat sz attr =>
Some (
Tfloat sz)
|
_ =>
None
end.
Definition type_chunk (
ty:
type) :
AST.memory_chunk :=
match ty with
|
Tint Ctypes.I8 Ctypes.Signed =>
AST.Mint8signed
|
Tint Ctypes.I8 Ctypes.Unsigned =>
AST.Mint8unsigned
|
Tint Ctypes.I16 Ctypes.Signed =>
AST.Mint16signed
|
Tint Ctypes.I16 Ctypes.Unsigned =>
AST.Mint16unsigned
|
Tint Ctypes.I32 _ =>
AST.Mint32
|
Tint Ctypes.IBool _ =>
AST.Mint8unsigned
|
Tlong _ =>
AST.Mint64
|
Tfloat Ctypes.F32 =>
AST.Mfloat32
|
Tfloat Ctypes.F64 =>
AST.Mfloat64
end.
Lemma cltype_align:
forall gcenv ty,
(
Memdata.align_chunk (
type_chunk ty) |
Ctypes.alignof gcenv (
cltype ty))%
Z.
Proof.
Lemma cltype_access_by_value:
forall ty,
Ctypes.access_mode (
cltype ty) =
Ctypes.By_value (
type_chunk ty).
Proof.
destruct ty; simpl; cases.
Qed.
Lemma sizeof_translate_chunk:
forall gcenv t,
Ctypes.sizeof gcenv (
cltype t) =
Memdata.size_chunk (
type_chunk t).
Proof.
Definition true_val :=
Values.Vtrue.
Definition false_val :=
Values.Vfalse.
Lemma true_not_false_val:
true_val <>
false_val.
Proof.
discriminate. Qed.
Definition bool_type :
type :=
Tint Ctypes.IBool Ctypes.Signed.
Inductive constant :
Type :=
|
Cint:
Integers.int ->
Ctypes.intsize ->
Ctypes.signedness ->
constant
|
Clong:
Integers.int64 ->
Ctypes.signedness ->
constant
|
Cfloat:
Floats.float ->
constant
|
Csingle:
Floats.float32 ->
constant.
Definition const :=
constant.
Definition type_const (
c:
const) :
type :=
match c with
|
Cint _ sz sg =>
Tint sz sg
|
Clong _ sg =>
Tlong sg
|
Cfloat _ =>
Tfloat Ctypes.F64
|
Csingle _ =>
Tfloat Ctypes.F32
end.
Definition sem_const (
c:
const) :
val :=
match c with
|
Cint i sz sg =>
Values.Vint (
Cop.cast_int_int sz sg i)
|
Clong i sg =>
Values.Vlong i
|
Cfloat f =>
Values.Vfloat f
|
Csingle f =>
Values.Vsingle f
end.
Definition init_type (
ty:
type) :
const :=
match ty with
|
Tint sz sg =>
Cint Integers.Int.zero sz sg
|
Tlong sg =>
Clong Integers.Int64.zero sg
|
Tfloat Ctypes.F64 =>
Cfloat Floats.Float.zero
|
Tfloat Ctypes.F32 =>
Csingle Floats.Float32.zero
end.
Definition true_const :
const :=
Cint Int.one Ctypes.IBool Ctypes.Signed.
Definition false_const :
const :=
Cint Int.zero Ctypes.IBool Ctypes.Signed.
Definition sem_true_const :
sem_const true_const =
true_val :=
eq_refl.
Definition sem_false_const :
sem_const false_const =
false_val :=
eq_refl.
Definition type_true_const :
type_const true_const =
bool_type :=
eq_refl.
Definition type_false_const :
type_const false_const =
bool_type :=
eq_refl.
Inductive unop' :
Type :=
|
UnaryOp:
Cop.unary_operation ->
unop'
|
CastOp:
type ->
unop'.
Definition unop :=
unop'.
Definition binop :=
Cop.binary_operation.
Definition sem_unop (
uop:
unop) (
v:
val) (
ty:
type) :
option val :=
match uop with
|
UnaryOp op =>
Cop.sem_unary_operation op v (
cltype ty)
Memory.Mem.empty
|
CastOp ty' =>
Cop.sem_cast v (
cltype ty) (
cltype ty')
Memory.Mem.empty
end.
Definition sem_binop (
op:
binop) (
v1:
val) (
ty1:
type)
(
v2:
val) (
ty2:
type) :
option val :=
Cop.sem_binary_operation
empty_composite_env op v1 (
cltype ty1)
v2 (
cltype ty2)
Memory.Mem.empty.
Definition is_bool_type (
ty:
type) :
bool :=
match ty with
|
Tint Ctypes.IBool sg =>
true
|
_ =>
false
end.
Definition unop_always_returns_bool (
op:
Cop.unary_operation) :
bool :=
match op with
|
Cop.Onotbool =>
true
|
_ =>
false
end.
Definition type_unop (
uop:
unop) (
ty:
type) :
option type :=
match uop with
|
UnaryOp op =>
if unop_always_returns_bool op then Some bool_type
else match Ctyping.type_unop op (
cltype ty)
with
|
Errors.OK ty' =>
typecl ty'
|
Errors.Error _ =>
None
end
|
CastOp ty' =>
match Ctyping.check_cast (
cltype ty) (
cltype ty')
with
|
Errors.OK _ =>
Some ty'
|
Errors.Error _ =>
None
end
end.
Definition binop_always_returns_bool (
op:
binop) :
bool :=
match op with
|
Cop.Oeq =>
true
|
Cop.One =>
true
|
Cop.Olt =>
true
|
Cop.Ogt =>
true
|
Cop.Ole =>
true
|
Cop.Oge =>
true
|
_ =>
false
end.
Definition is_bool_binop (
op:
binop) :
bool :=
match op with
|
Cop.Oand =>
true
|
Cop.Oor =>
true
|
Cop.Oxor =>
true
|
_ =>
false
end.
Open Scope bool.
Definition type_binop (
op:
binop) (
ty1 ty2:
type) :
option type :=
if binop_always_returns_bool op
|| (
is_bool_binop op && (
is_bool_type ty1 &&
is_bool_type ty2))
then Some bool_type
else match Ctyping.type_binop op (
cltype ty1) (
cltype ty2)
with
|
Errors.OK ty' =>
typecl ty'
|
Errors.Error _ =>
None
end.
Inductive wt_val' :
val ->
type ->
Prop :=
|
wt_val_int:
forall n sz sg,
Ctyping.wt_int n sz sg ->
(
sz =
Ctypes.IBool -> (
n =
Int.zero \/
n =
Int.one)) ->
wt_val' (
Values.Vint n) (
Tint sz sg)
|
wt_val_long:
forall n sg,
wt_val' (
Values.Vlong n) (
Tlong sg)
|
wt_val_float:
forall f,
wt_val' (
Values.Vfloat f) (
Tfloat Ctypes.F64)
|
wt_val_single:
forall f,
wt_val' (
Values.Vsingle f) (
Tfloat Ctypes.F32).
Definition wt_val :
val ->
type ->
Prop :=
wt_val'.
Hint Unfold wt_val.
Hint Constructors wt_val'.
Lemma wt_val_bool:
forall v, (
v =
true_val \/
v =
false_val) <->
wt_val v bool_type.
Proof.
split;
intro HH.
-
destruct HH as [
HH|
HH];
subst;
apply wt_val_int;
intuition.
-
inversion_clear HH as [???
WT Hbool Hv| | |].
specialize (
Hbool eq_refl)
as [
Hbool|
Hbool];
subst;
auto.
Qed.
Lemma wt_val_const:
forall c,
wt_val (
sem_const c) (
type_const c).
Proof.
Lemma wt_init_type:
forall ty,
wt_val (
sem_const (
init_type ty))
ty.
Proof.
Lemma type_init_type:
forall ty,
type_const (
init_type ty) =
ty.
Proof.
destruct ty; auto.
destruct f; auto.
Qed.
Ltac DestructCases :=
match goal with
|
H: ?
x <> ?
x |-
_ =>
now contradiction H
|
_ =>
Ctyping.DestructCases
end.
Definition good_bool (
v:
Values.val) (
ty:
Ctypes.type) :=
match ty,
v with
|
Ctypes.Tint Ctypes.IBool sg a,
Values.Vint v =>
(
v =
Int.zero \/
v =
Int.one)
|
_,
_ =>
True
end.
Lemma wt_value_good_bool:
forall v ty,
wt_val v ty ->
good_bool v (
cltype ty).
Proof.
intros *
WTv.
unfold good_bool.
inv WTv;
simpl;
auto.
match goal with H:
sz =
Ctypes.IBool ->
_ |-
_ =>
destruct sz;
auto;
destruct H;
subst;
auto
end.
Qed.
Lemma good_bool_vtrue:
forall ty,
good_bool Values.Vtrue ty.
Proof.
intros; destruct ty; simpl; try destruct i; auto.
Qed.
Lemma good_bool_vfalse:
forall ty,
good_bool Values.Vfalse ty.
Proof.
intros; destruct ty; simpl; try destruct i; auto.
Qed.
Lemma good_bool_vlong:
forall ty i,
good_bool (
Values.Vlong i)
ty.
Proof.
intros; destruct ty; simpl; try destruct i0; auto.
Qed.
Lemma good_bool_vfloat:
forall ty f,
good_bool (
Values.Vfloat f)
ty.
Proof.
intros; destruct ty; simpl; try destruct i; auto.
Qed.
Lemma good_bool_vsingle:
forall ty f,
good_bool (
Values.Vsingle f)
ty.
Proof.
intros; destruct ty; simpl; try destruct i; auto.
Qed.
Lemma good_bool_tint:
forall v sz sg a,
sz <>
Ctypes.IBool ->
good_bool v (
Ctypes.Tint sz sg a).
Proof.
intros; destruct v, sz; simpl; intuition.
Qed.
Lemma good_bool_tlong:
forall v sg a,
good_bool v (
Ctypes.Tlong sg a).
Proof.
intros; destruct v; simpl; auto.
Qed.
Lemma good_bool_tfloat:
forall v sz a,
good_bool v (
Ctypes.Tfloat sz a).
Proof.
intros; destruct v; simpl; auto.
Qed.
Local Hint Immediate good_bool_vtrue good_bool_vfalse good_bool_vlong
good_bool_vfloat good_bool_vsingle good_bool_tlong
good_bool_tfloat.
Lemma good_bool_not_bool:
forall v ty,
(
forall sg a,
ty <>
Ctypes.Tint Ctypes.IBool sg a) ->
good_bool v ty.
Proof.
intros v ty Hty.
destruct ty; simpl; eauto.
destruct i, v; auto.
now contradiction (Hty s a).
Qed.
Local Hint Resolve good_bool_not_bool.
Opaque good_bool.
Lemma good_bool_zero_or_one:
forall i sz sg a,
good_bool (
Values.Vint i) (
Ctypes.Tint sz sg a) ->
sz =
Ctypes.IBool ->
i =
Int.zero \/
i =
Int.one.
Proof.
intros * Hgb Hsz; subst; inversion_clear Hgb; auto.
Qed.
Local Hint Resolve good_bool_zero_or_one.
Lemma wt_val_Vfalse_bool_type:
wt_val (
Values.Vfalse)
bool_type.
Proof.
Lemma wt_val_Vtrue_bool_type:
wt_val (
Values.Vtrue)
bool_type.
Proof.
Local Hint Resolve wt_val_Vfalse_bool_type wt_val_Vtrue_bool_type.
Lemma wt_val_of_bool_bool_type:
forall v,
wt_val (
Values.Val.of_bool v)
bool_type.
Proof.
destruct v; simpl; auto.
Qed.
Local Hint Resolve wt_val_of_bool_bool_type.
Lemma typecl_wt_val_wt_val:
forall cty ty v,
typecl cty =
Some ty ->
Ctyping.wt_val v cty ->
v <>
Values.Vundef ->
(
forall b ofs,
v <>
Values.Vptr b ofs) ->
good_bool v cty ->
wt_val v ty.
Proof.
intros * Htcl Hcty Hnun Hnptr Hgb.
destruct cty;
simpl in *;
destruct v;
DestructCases;
inversion Hcty;
subst;
eauto.
exfalso; now eapply Hnptr.
exfalso; now eapply Hnptr.
Qed.
Lemma wt_val_not_vundef_nor_vptr:
forall v ty,
wt_val v ty ->
v <>
Values.Vundef /\ (
forall b ofs,
v <>
Values.Vptr b ofs).
Proof.
intros * Hwt.
destruct ty; inversion Hwt; subst;
split; discriminate.
Qed.
Lemma wt_val_wt_val_cltype:
forall v ty,
wt_val v ty ->
Ctyping.wt_val v (
cltype ty).
Proof.
intros *
Hwt.
destruct ty;
inversion_clear Hwt;
eauto using Ctyping.wt_val.
Qed.
Lemma is_bool_type_true:
forall ty,
is_bool_type ty =
true ->
exists sg,
ty =
Tint Ctypes.IBool sg.
Proof.
Lemma type_castop:
forall ty ty',
type_unop (
CastOp ty')
ty =
Some ty'.
Proof.
intros ty ty'.
destruct ty, ty';
try destruct i, s; try destruct i0; try destruct s0;
try destruct f; try destruct f0; auto.
Qed.
Ltac GoalMatchMatch :=
repeat match goal with
| |-
match match ?
x with _ =>
_ end with _ =>
_ end =
_ =>
destruct x
end;
auto.
Lemma check_cltype_cast:
forall ty ty',
Ctyping.check_cast (
cltype ty) (
cltype ty') =
Errors.OK tt.
Proof.
Lemma pres_sem_unop:
forall op ty1 ty v1 v,
type_unop op ty1 =
Some ty ->
sem_unop op v1 ty1 =
Some v ->
wt_val v1 ty1 ->
wt_val v ty.
Proof.
Lemma sem_cast_same:
forall m v t,
wt_val v t ->
Cop.sem_cast v (
cltype t) (
cltype t)
m =
Some v.
Proof.
Ltac ContradictNotVptr :=
match goal with
|
H:
context [
Values.Vptr ?
b ?
i <>
Values.Vptr _ _] |-
_ =>
contradiction (
H b i)
end.
Lemma cases_of_bool:
forall P b,
P Values.Vtrue ->
P Values.Vfalse ->
P (
Values.Val.of_bool b).
Proof.
destruct b; auto.
Qed.
Lemma option_map_of_bool_true_false:
forall e x,
Coqlib.option_map Values.Val.of_bool e =
Some x ->
x =
Values.Vtrue \/
x =
Values.Vfalse.
Proof.
intros e x Hom.
destruct e as [b|]; [destruct b|].
- injection Hom; intro; subst; intuition.
- injection Hom; intro; subst; intuition.
- discriminate Hom.
Qed.
Lemma sem_cmp_not_vundef_nor_vptr:
forall cop v1 ty1 v2 ty2 m v,
Cop.sem_cmp cop v1 ty1 v2 ty2 m =
Some v ->
v <>
Values.Vundef /\ (
forall b ofs,
v <>
Values.Vptr b ofs).
Proof.
Lemma classify_add_cltypes:
forall ty1 ty2,
Cop.classify_add (
cltype ty1) (
cltype ty2) =
Cop.add_default.
Proof.
Lemma classify_sub_cltypes:
forall ty1 ty2,
Cop.classify_sub (
cltype ty1) (
cltype ty2) =
Cop.sub_default.
Proof.
Lemma classify_cmp_cltypes:
forall ty1 ty2,
Cop.classify_cmp (
cltype ty1) (
cltype ty2) =
Cop.cmp_default.
Proof.
Lemma sem_cmp_true_or_false:
forall cop v1 ty1 v2 ty2 m v,
Cop.sem_cmp cop v1 ty1 v2 ty2 m =
Some v ->
v =
Values.Vtrue \/
v =
Values.Vfalse.
Proof.
Lemma binop_never_bool:
forall op ty1 ty2 ty,
Ctyping.type_binop op ty1 ty2 =
Errors.OK ty ->
forall sz a,
ty <>
Ctypes.Tint Ctypes.IBool sz a.
Proof.
Lemma pres_sem_binop:
forall op ty1 ty2 ty v1 v2 v,
type_binop op ty1 ty2 =
Some ty ->
sem_binop op v1 ty1 v2 ty2 =
Some v ->
wt_val v1 ty1 ->
wt_val v2 ty2 ->
wt_val v ty.
Proof.
unfold type_binop,
sem_binop.
intros *
Hty Hsem Hwt1 Hwt2.
destruct (
binop_always_returns_bool op)
eqn:
Heq1;
simpl in Hty;
[|
destruct
(
is_bool_binop op && (
is_bool_type ty1 &&
is_bool_type ty2))
eqn:
Heq2];
simpl in Hty.
-
injection Hty;
intro;
subst.
destruct op;
try discriminate Heq1;
unfold Cop.sem_binary_operation in Hsem;
destruct (
sem_cmp_true_or_false _ _ _ _ _ _ _ Hsem);
subst;
auto.
-
injection Hty;
intro;
subst;
clear Hty.
apply andb_prop in Heq2;
destruct Heq2 as (
Hbop &
Heq2).
apply andb_prop in Heq2;
destruct Heq2 as (
Hbty1 &
Hbty2).
destruct (
is_bool_type_true _ Hbty1)
as (
sg1 &
Hty1).
destruct (
is_bool_type_true _ Hbty2)
as (
sg2 &
Hty2).
subst;
clear Hbty1 Hbty2 Heq1.
destruct op;
try discriminate Hbop;
destruct v1,
v2;
inv Hwt1;
inv Hwt2;
repeat match goal with H:?
x = ?
x ->
_ \/
_ |-
_ =>
destruct (
H eq_refl);
clear H end;
subst;
vm_compute in Hsem;
injection Hsem;
intro;
subst v;
auto.
-
destruct (
Ctyping.type_binop op (
cltype ty1) (
cltype ty2))
eqn:
Hok;
[|
discriminate].
pose proof (
binop_never_bool _ _ _ _ Hok)
as Hnbool.
pose proof (
wt_val_not_vundef_nor_vptr _ _ Hwt1)
as (
Hnun1 &
Hnptr1).
pose proof (
wt_val_not_vundef_nor_vptr _ _ Hwt2)
as (
Hnun2 &
Hnptr2).
apply wt_val_wt_val_cltype in Hwt1.
apply wt_val_wt_val_cltype in Hwt2.
pose proof (
Ctyping.pres_sem_binop _ _ _ _ _ _ _ _ _ Hok Hsem Hwt1 Hwt2)
as Hwt.
cut (
v <>
Values.Vundef
/\ (
forall b ofs,
v <>
Values.Vptr b ofs)
/\
good_bool v t).
{
destruct 1
as (
Hnun' &
Hnptr' &
Hgb).
eauto using typecl_wt_val_wt_val. }
destruct op;
simpl in Hsem;
try discriminate Heq1.
+
unfold Cop.sem_add,
Cop.sem_binarith in Hsem.
rewrite classify_add_cltypes in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
+
unfold Cop.sem_sub,
Cop.sem_binarith in Hsem.
rewrite classify_sub_cltypes in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
+
unfold Cop.sem_mul,
Cop.sem_binarith in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
+
unfold Cop.sem_div,
Cop.sem_binarith in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
+
unfold Cop.sem_mod,
Cop.sem_binarith in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
+
unfold Cop.sem_and,
Cop.sem_binarith in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
+
unfold Cop.sem_or,
Cop.sem_binarith in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
+
unfold Cop.sem_xor,
Cop.sem_binarith in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
+
unfold Cop.sem_shl,
Cop.sem_shift in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
+
unfold Cop.sem_shr,
Cop.sem_shift in Hsem.
DestructCases;
repeat split;
try discriminate;
try ContradictNotVptr;
auto.
Qed.
Lemma val_dec :
forall v1 v2 :
val, {
v1 =
v2} + {
v1 <>
v2}.
Proof Values.Val.eq.
Lemma type_dec :
forall t1 t2 :
type, {
t1 =
t2} + {
t1 <>
t2}.
Proof.
Lemma const_dec :
forall c1 c2 :
const, {
c1 =
c2} + {
c1 <>
c2}.
Proof.
Lemma unop_dec :
forall op1 op2 :
unop, {
op1 =
op2} + {
op1 <>
op2}.
Proof.
Lemma binop_dec :
forall op1 op2 :
binop, {
op1 =
op2} + {
op1 <>
op2}.
Proof.
decide equality.
Qed.
Lemma sem_unary_operation_any_mem:
forall op v ty M1 M2,
(
forall b ofs,
v <>
Values.Vptr b ofs) ->
Cop.sem_unary_operation op v ty M1
=
Cop.sem_unary_operation op v ty M2.
Proof.
intros *
Hnptr.
destruct op,
v;
simpl;
unfold Cop.sem_notbool,
Cop.sem_notint,
Cop.sem_neg,
Cop.sem_absfloat;
repeat match goal with
| |- (
match ?
x with _ =>
_ end) =
_ =>
destruct x;
auto
|
_ =>
ContradictNotVptr
end;
try (
now destruct ty;
auto).
specialize (
Hnptr b i);
contradiction.
Qed.
Lemma sem_cast_any_mem:
forall v ty1 ty2 M1 M2,
(
forall b ofs,
v <>
Values.Vptr b ofs) ->
Cop.sem_cast v ty1 ty2 M1 =
Cop.sem_cast v ty1 ty2 M2.
Proof.
Lemma sem_binary_operation_any_cenv_mem:
forall op v1 ty1 v2 ty2 M1 M2 cenv1 cenv2,
(
forall b ofs,
v1 <>
Values.Vptr b ofs) ->
(
forall b ofs,
v2 <>
Values.Vptr b ofs) ->
Cop.sem_binary_operation cenv1 op v1 (
cltype ty1)
v2 (
cltype ty2)
M1
=
Cop.sem_binary_operation cenv2 op v1 (
cltype ty1)
v2 (
cltype ty2)
M2.
Proof.
intros *
Hnptr1 Hnptr2.
destruct op;
simpl;
unfold Cop.sem_add,
Cop.sem_sub,
Cop.sem_mul,
Cop.sem_div,
Cop.sem_mod,
Cop.sem_and,
Cop.sem_or,
Cop.sem_xor,
Cop.sem_shl,
Cop.sem_shr,
Cop.sem_cmp,
Cop.sem_binarith;
try rewrite classify_add_cltypes;
try rewrite classify_sub_cltypes;
try rewrite classify_cmp_cltypes;
try rewrite (
sem_cast_any_mem v1 (
cltype ty1)
_ M1 M2 Hnptr1);
try rewrite (
sem_cast_any_mem v2 (
cltype ty2)
_ M1 M2 Hnptr2);
GoalMatchMatch.
Qed.
Lemma access_mode_cltype:
forall ty,
Ctypes.access_mode (
cltype ty) =
Ctypes.By_value (
type_chunk ty).
Proof.
destruct ty as [sz sg|sz|f].
- destruct sz, sg; auto.
- destruct sz; auto.
- destruct f; auto.
Qed.
Lemma wt_val_load_result:
forall ty v,
wt_val v ty ->
v =
Values.Val.load_result (
type_chunk ty)
v.
Proof.
intros *
Hwt.
destruct ty as [
sz sg|
sz|
sz].
-
destruct sz,
sg;
simpl;
inv Hwt;
auto;
match goal with
|
H:
Ctyping.wt_int _ _ _ |-
_ =>
rewrite <-
H
end;
try rewrite Int.sign_ext_idem;
try rewrite Int.zero_ext_idem;
intuition.
-
destruct sz;
inv Hwt;
auto.
-
destruct sz;
inv Hwt;
auto.
Qed.
Definition type_unop' (
uop:
unop) (
ty:
type) :
option type :=
match uop with
|
UnaryOp op =>
match op with
|
Cop.Onotbool =>
Some bool_type
|
Cop.Onotint =>
match ty with
|
Tint Ctypes.I32 sg =>
Some ty
|
Tlong sg =>
Some ty
|
Tint _ _ =>
Some (
Tint Ctypes.I32 Ctypes.Signed)
|
_ =>
None
end
|
Cop.Oneg =>
match ty with
|
Tint Ctypes.I32 sg =>
Some ty
|
Tlong sg =>
Some ty
|
Tint _ _ =>
Some (
Tint Ctypes.I32 Ctypes.Signed)
|
Tfloat sz =>
Some ty
end
|
Cop.Oabsfloat =>
Some (
Tfloat Ctypes.F64)
end
|
CastOp ty' =>
Some ty'
end.
Definition type_binop' (
op:
binop) (
ty1 ty2:
type) :
option type :=
match op with
|
Cop.Oadd |
Cop.Osub |
Cop.Omul |
Cop.Odiv =>
match ty1,
ty2 with
|
Tfloat Ctypes.F64 ,
_ =>
Some (
Tfloat Ctypes.F64)
|
_ ,
Tfloat Ctypes.F64 =>
Some (
Tfloat Ctypes.F64)
|
Tfloat Ctypes.F32 ,
_ =>
Some (
Tfloat Ctypes.F32)
|
_ ,
Tfloat Ctypes.F32 =>
Some (
Tfloat Ctypes.F32)
|
Tlong Ctypes.Unsigned ,
_ =>
Some (
Tlong Ctypes.Unsigned)
|
_ ,
Tlong Ctypes.Unsigned =>
Some (
Tlong Ctypes.Unsigned)
|
Tlong Ctypes.Signed ,
_ =>
Some (
Tlong Ctypes.Signed)
|
_ ,
Tlong Ctypes.Signed =>
Some (
Tlong Ctypes.Signed)
|
Tint Ctypes.I32 Ctypes.Unsigned,
_ =>
Some (
Tint Ctypes.I32 Ctypes.Unsigned)
|
_ ,
Tint Ctypes.I32 Ctypes.Unsigned =>
Some (
Tint Ctypes.I32 Ctypes.Unsigned)
|
Tint _ _ ,
Tint _ _ =>
Some (
Tint Ctypes.I32 Ctypes.Signed)
end
|
Cop.Omod =>
match ty1,
ty2 with
|
Tfloat _ ,
_ =>
None
|
_ ,
Tfloat _ =>
None
|
Tlong Ctypes.Unsigned ,
_ =>
Some (
Tlong Ctypes.Unsigned)
|
_ ,
Tlong Ctypes.Unsigned =>
Some (
Tlong Ctypes.Unsigned)
|
Tlong Ctypes.Signed ,
_ =>
Some (
Tlong Ctypes.Signed)
|
_ ,
Tlong Ctypes.Signed =>
Some (
Tlong Ctypes.Signed)
|
Tint Ctypes.I32 Ctypes.Unsigned,
_ =>
Some (
Tint Ctypes.I32 Ctypes.Unsigned)
|
_ ,
Tint Ctypes.I32 Ctypes.Unsigned =>
Some (
Tint Ctypes.I32 Ctypes.Unsigned)
|
Tint _ _ ,
Tint _ _ =>
Some (
Tint Ctypes.I32 Ctypes.Signed)
end
|
Cop.Oand |
Cop.Oor |
Cop.Oxor =>
match ty1,
ty2 with
|
Tfloat _ ,
_ =>
None
|
_ ,
Tfloat _ =>
None
|
Tlong Ctypes.Unsigned ,
_ =>
Some (
Tlong Ctypes.Unsigned)
|
_ ,
Tlong Ctypes.Unsigned =>
Some (
Tlong Ctypes.Unsigned)
|
Tlong Ctypes.Signed ,
_ =>
Some (
Tlong Ctypes.Signed)
|
_ ,
Tlong Ctypes.Signed =>
Some (
Tlong Ctypes.Signed)
|
Tint Ctypes.IBool sg1 ,
Tint Ctypes.IBool sg2 =>
Some (
Tint Ctypes.IBool Ctypes.Signed)
|
Tint Ctypes.I32 Ctypes.Unsigned,
_ =>
Some (
Tint Ctypes.I32 Ctypes.Unsigned)
|
_ ,
Tint Ctypes.I32 Ctypes.Unsigned =>
Some (
Tint Ctypes.I32 Ctypes.Unsigned)
|
Tint _ _ ,
Tint _ _ =>
Some (
Tint Ctypes.I32 Ctypes.Signed)
end
|
Cop.Oshl |
Cop.Oshr =>
match ty1,
ty2 with
|
Tfloat _ ,
_ =>
None
|
_ ,
Tfloat _ =>
None
|
Tlong sg ,
_ =>
Some (
Tlong sg)
|
Tint Ctypes.I32 Ctypes.Unsigned,
_ =>
Some (
Tint Ctypes.I32 Ctypes.Unsigned)
|
Tint _ _ ,
_ =>
Some (
Tint Ctypes.I32 Ctypes.Signed)
end
|
Cop.Oeq |
Cop.One |
Cop.Olt |
Cop.Ogt |
Cop.Ole |
Cop.Oge =>
Some bool_type
end.
Lemma type_unop'
_correct:
forall op ty,
type_unop'
op ty =
type_unop op ty.
Proof.
intros. destruct op.
- destruct u, ty; try destruct i; try destruct s; try destruct f;
simpl in *; now DestructCases.
- destruct t, ty; try destruct i; try destruct s; try destruct f;
try destruct f0; simpl in *; DestructCases; auto.
Qed.
Lemma type_binop'
_correct:
forall op ty1 ty2,
type_binop'
op ty1 ty2 =
type_binop op ty1 ty2.
Proof.
intros.
unfold type_binop.
destruct (
binop_always_returns_bool op)
eqn:
Heq1;
simpl;
[|
destruct
(
is_bool_binop op && (
is_bool_type ty1 &&
is_bool_type ty2))
eqn:
Heq2].
-
destruct op;
simpl in *;
try discriminate;
auto.
-
unfold type_binop'.
repeat rewrite Bool.andb_true_iff in Heq2.
destruct Heq2 as (
Heq2 &
Heq3 &
Heq4).
apply is_bool_type_true in Heq3;
destruct Heq3 as (
sg1 &
Heq3).
apply is_bool_type_true in Heq4;
destruct Heq4 as (
sg2 &
Heq4).
subst;
destruct op;
try discriminate;
auto.
-
repeat rewrite Bool.andb_false_iff in Heq2.
destruct op;
simpl in *;
try discriminate Heq1;
(
destruct ty1,
ty2;
try destruct i;
try destruct i0;
try destruct s;
try destruct s0;
try destruct f;
try destruct f0;
auto);
(
destruct Heq2 as [
Heq2|[
Heq2|
Heq2]];
discriminate).
Qed.
Open Scope string_scope.
Definition string_of_type (
ty:
type) :
String.string :=
match ty with
|
Tint Ctypes.IBool sg => "
bool"
|
Tint Ctypes.I8 Ctypes.Signed => "
int8"
|
Tint Ctypes.I8 Ctypes.Unsigned => "
uint8"
|
Tint Ctypes.I16 Ctypes.Signed => "
int16"
|
Tint Ctypes.I16 Ctypes.Unsigned => "
uint16"
|
Tint Ctypes.I32 Ctypes.Signed => "
int32"
|
Tint Ctypes.I32 Ctypes.Unsigned => "
uint32"
|
Tlong Ctypes.Signed => "
int64"
|
Tlong Ctypes.Unsigned => "
uint64"
|
Tfloat Ctypes.F32 => "
float32"
|
Tfloat Ctypes.F64 => "
float64"
end.
End Op.
Hint Resolve cltype_access_by_value cltype_align wt_val_load_result sem_cast_same.
Module OpAux :=
OperatorsAux Op.
Lemma val_to_bool_bool_val:
forall v b m,
OpAux.val_to_bool v =
Some b ->
Cop.bool_val v (
cltype bool_type)
m =
Some b.
Proof.
intros *
Vtb.
unfold Cop.bool_val;
simpl.
destruct b.
-
apply OpAux.val_to_bool_true'
in Vtb;
subst;
simpl.
rewrite Int.eq_false;
auto;
discriminate.
-
apply OpAux.val_to_bool_false'
in Vtb;
subst;
simpl.
rewrite Int.eq_true;
auto.
Qed.
Hint Resolve val_to_bool_bool_val.
From Velus Require Import IndexedStreams.
From Velus Require Import CoindStreams.
From Velus Require Import Obc.
Module IStr :=
IndexedStreamsFun Op OpAux.
Module CStr :=
CoindStreamsFun Op OpAux.
Module Obc :=
ObcFun Ids Op OpAux.