Instruction selection for 64-bit integer operations
From Coq Require Import String.
Require Import Coqlib Maps Integers Floats Errors.
Require Archi.
Require Import AST Values Memory Globalenvs Builtins Events.
Require Import Cminor Op CminorSel.
Require Import OpHelpers OpHelpersproof.
Require Import SelectOp SelectOpproof SplitLong SplitLongproof.
Require Import SelectLong.
Local Open Scope cminorsel_scope.
Local Open Scope string_scope.
Section CMCONSTR.
Variable prog:
program.
Variable hf:
helper_functions.
Hypothesis HELPERS:
helper_functions_declared prog hf.
Let ge :=
Genv.globalenv prog.
Variable sp:
val.
Variable e:
env.
Variable m:
mem.
Definition binary_constructor_sound (
cstr:
expr ->
expr ->
expr) (
sem:
val ->
val ->
val) :
Prop :=
forall le a x b y,
eval_expr ge sp e m le a x ->
eval_expr ge sp e m le b y ->
exists v,
eval_expr ge sp e m le (
cstr a b)
v /\
Val.lessdef (
sem x y)
v.
Semantic equivalence between Val.longofwords (Val.shr v 31) v
and Val.longofint v. Borrowed from SplitLongproof.eval_longofint.
Lemma val_longofwords_shr31_eq:
forall v,
Val.longofwords (
Val.shr v (
Vint (
Int.repr 31)))
v =
Val.longofint v.
Proof.
If is_longofint_signed e = Some a and eval_expr e v, then
v = Val.longofint va for some va which a evaluates to.
Lemma is_longofint_signed_correct:
forall le e' a v,
is_longofint_signed e' =
Some a ->
eval_expr ge sp e m le e' v ->
exists va,
eval_expr ge sp e m le a va /\
v =
Val.longofint va.
Proof.
intros le e' a v HS HE.
unfold is_longofint_signed in HS.
destruct e' as [
i|
op args|
chk addr al|
c b1 b2|
a' body|
n|
ef al|
id sg al];
try discriminate.
destruct body as [
i|
op args|
chk addr al|
c b1 b2|
a'' body'|
n|
ef al|
id sg al];
try discriminate.
destruct op;
try discriminate.
destruct args as [|
h tl];
try discriminate.
destruct h as [
i|
opH argsH|
chk addr al|
c b1 b2|
a'' body'|
n|
ef al|
id sg al];
try discriminate.
destruct opH;
try discriminate.
destruct s as [
s|
s|
s|
s];
try discriminate.
destruct argsH as [|
hh ttl];
try discriminate.
destruct hh as [
i|
op args|
chk addr al|
c b1 b2|
a'' body'|
n|
ef al|
id sg al];
try discriminate.
destruct n;
try discriminate.
destruct ttl;
try discriminate.
destruct tl as [|
ll lll];
try discriminate.
destruct ll as [
i|
op args|
chk addr al|
c b1 b2|
a'' body'|
n|
ef al|
id sg al];
try discriminate.
destruct n;
try discriminate.
destruct lll;
try discriminate.
destruct (
Int.eq (
s_amount s) (
Int.repr 31))
eqn:
HC;
try discriminate.
inv HS.
inv HE.
match goal with
| [
H :
eval_expr _ _ _ _ _
a ?
v1 |- _ ] =>
exists v1;
split; [
exact H|];
match goal with
| [
H' :
eval_expr _ _ _ _ (
v1 ::
le) _
v |- _ ] =>
inv H'
end
end.
repeat match goal with
| [
H :
eval_exprlist _ _ _ _ _
Enil _ |- _ ] =>
inv H
| [
H :
eval_exprlist _ _ _ _ _ (_ ::: _) _ |- _ ] =>
inv H
| [
H :
eval_expr _ _ _ _ _ (
Eop _ _) _ |- _ ] =>
inv H
| [
H :
eval_expr _ _ _ _ _ (
Eletvar _) _ |- _ ] =>
inv H
end.
cbn in *.
repeat match goal with
| [
H :
Some _ =
Some _ |- _ ] =>
inv H
end.
generalize (
Int.eq_spec (
s_amount s) (
Int.repr 31));
rewrite HC;
intros HEQ.
destruct s as [
sa pf].
cbn in HEQ.
subst sa.
rewrite <-
val_longofwords_shr31_eq.
cbn.
reflexivity.
Qed.
Theorem eval_mull:
binary_constructor_sound mull Val.mull.
Proof.
End CMCONSTR.
Soundness of the cmplu/cmpl overrides for ordered comparisons.
The override is a syntactic rewrite from SplitLong's
Econdition-tree to a single Eop (Ocmpcarryu c)/Eop (Ocmpcarry c)
node with the four split halves; the eval semantics of
Ocmpcarryu/Ocmpcarry in arm/Op.v is defined to return the same
value as SplitLong's tree.
Stated in a separate section without the HELPERS hypothesis so
that the proof terms do not silently generalize over
helper_functions_declared — that would change their type
signatures in a way that breaks Selectionproof's eapply
eval_cmpl / eapply eval_cmplu.
Section CMPL_VIA_CARRY.
Variable prog:
program.
Let ge :=
Genv.globalenv prog.
Variable sp:
val.
Variable e:
env.
Variable m:
mem.
Theorem eval_cmplu_via_carry:
forall c le a x b y v,
eval_expr ge sp e m le a x ->
eval_expr ge sp e m le b y ->
Val.cmplu (
Mem.valid_pointer m)
c x y =
Some v ->
Archi.ptr64 =
false ->
eval_expr ge sp e m le (
cmplu_via_carry c a b)
v.
Proof.
Theorem eval_cmpl_via_carry:
forall c le a x b y v,
eval_expr ge sp e m le a x ->
eval_expr ge sp e m le b y ->
Val.cmpl c x y =
Some v ->
eval_expr ge sp e m le (
cmpl_via_carry c a b)
v.
Proof.
Top-level cmplu/cmpl correctness — dispatches according to c.
Theorem eval_cmplu:
forall c le a x b y v,
eval_expr ge sp e m le a x ->
eval_expr ge sp e m le b y ->
Val.cmplu (
Mem.valid_pointer m)
c x y =
Some v ->
Archi.ptr64 =
false ->
eval_expr ge sp e m le (
cmplu c a b)
v.
Proof.
Theorem eval_cmpl:
forall c le a x b y v,
eval_expr ge sp e m le a x ->
eval_expr ge sp e m le b y ->
Val.cmpl c x y =
Some v ->
eval_expr ge sp e m le (
cmpl c a b)
v.
Proof.
End CMPL_VIA_CARRY.