summaryrefslogtreecommitdiff
path: root/ia32/Asmgenretaddr.v
diff options
context:
space:
mode:
Diffstat (limited to 'ia32/Asmgenretaddr.v')
-rw-r--r--ia32/Asmgenretaddr.v244
1 files changed, 244 insertions, 0 deletions
diff --git a/ia32/Asmgenretaddr.v b/ia32/Asmgenretaddr.v
new file mode 100644
index 0000000..048f5a2
--- /dev/null
+++ b/ia32/Asmgenretaddr.v
@@ -0,0 +1,244 @@
+(* *********************************************************************)
+(* *)
+(* The Compcert verified compiler *)
+(* *)
+(* Xavier Leroy, INRIA Paris-Rocquencourt *)
+(* *)
+(* Copyright Institut National de Recherche en Informatique et en *)
+(* Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* *)
+(* *********************************************************************)
+
+(** Predictor for return addresses in generated IA32 code.
+
+ The [return_address_offset] predicate defined here is used in the
+ concrete semantics for Mach (module [Machconcr]) to determine the
+ return addresses that are stored in activation records. *)
+
+Require Import Coqlib.
+Require Import Maps.
+Require Import AST.
+Require Import Errors.
+Require Import Integers.
+Require Import Floats.
+Require Import Values.
+Require Import Memory.
+Require Import Globalenvs.
+Require Import Op.
+Require Import Locations.
+Require Import Mach.
+Require Import Asm.
+Require Import Asmgen.
+
+(** The ``code tail'' of an instruction list [c] is the list of instructions
+ starting at PC [pos]. *)
+
+Inductive code_tail: Z -> code -> code -> Prop :=
+ | code_tail_0: forall c,
+ code_tail 0 c c
+ | code_tail_S: forall pos i c1 c2,
+ code_tail pos c1 c2 ->
+ code_tail (pos + 1) (i :: c1) c2.
+
+Lemma code_tail_pos:
+ forall pos c1 c2, code_tail pos c1 c2 -> pos >= 0.
+Proof.
+ induction 1. omega. omega.
+Qed.
+
+(** Consider a Mach function [f] and a sequence [c] of Mach instructions
+ representing the Mach code that remains to be executed after a
+ function call returns. The predicate [return_address_offset f c ofs]
+ holds if [ofs] is the integer offset of the PPC instruction
+ following the call in the Asm code obtained by translating the
+ code of [f]. Graphically:
+<<
+ Mach function f |--------- Mcall ---------|
+ Mach code c | |--------|
+ | \ \
+ | \ \
+ | \ \
+ Asm code | |--------|
+ Asm function |------------- Pcall ---------|
+
+ <-------- ofs ------->
+>>
+*)
+
+Inductive return_address_offset: Mach.function -> Mach.code -> int -> Prop :=
+ | return_address_offset_intro:
+ forall f c ofs,
+ (forall tf tc,
+ transf_function f = OK tf ->
+ transl_code f c = OK tc ->
+ code_tail ofs tf tc) ->
+ return_address_offset f c (Int.repr ofs).
+
+(** We now show that such an offset always exists if the Mach code [c]
+ is a suffix of [f.(fn_code)]. This holds because the translation
+ from Mach to PPC is compositional: each Mach instruction becomes
+ zero, one or several PPC instructions, but the order of instructions
+ is preserved. *)
+
+Lemma is_tail_code_tail:
+ forall c1 c2, is_tail c1 c2 -> exists ofs, code_tail ofs c2 c1.
+Proof.
+ induction 1. exists 0; constructor.
+ destruct IHis_tail as [ofs CT]. exists (ofs + 1); constructor; auto.
+Qed.
+
+Hint Resolve is_tail_refl: ppcretaddr.
+
+(*
+Ltac IsTail :=
+ auto with ppcretaddr;
+ match goal with
+ | [ |- is_tail _ (_ :: _) ] => constructor; IsTail
+ | [ |- is_tail _ (match ?x with true => _ | false => _ end) ] => destruct x; IsTail
+ | [ |- is_tail _ (match ?x with left _ => _ | right _ => _ end) ] => destruct x; IsTail
+ | [ |- is_tail _ (match ?x with nil => _ | _ :: _ => _ end) ] => destruct x; IsTail
+ | [ |- is_tail _ (match ?x with Tint => _ | Tfloat => _ end) ] => destruct x; IsTail
+ | [ |- is_tail _ (?f _ _ _ _ _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | [ |- is_tail _ (?f _ _ _ _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | [ |- is_tail _ (?f _ _ _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | [ |- is_tail _ (?f _ _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | [ |- is_tail _ (?f _ _ ?k) ] => apply is_tail_trans with k; IsTail
+ | _ => idtac
+ end.
+*)
+Ltac IsTail :=
+ eauto with ppcretaddr;
+ match goal with
+ | [ |- is_tail _ (_ :: _) ] => constructor; IsTail
+ | [ H: Error _ = OK _ |- _ ] => discriminate
+ | [ H: OK _ = OK _ |- _ ] => inversion H; subst; IsTail
+ | [ H: bind _ _ = OK _ |- _ ] => monadInv H; IsTail
+ | [ H: (if ?x then _ else _) = OK _ |- _ ] => destruct x; IsTail
+ | [ H: match ?x with nil => _ | _ :: _ => _ end = OK _ |- _ ] => destruct x; IsTail
+ | _ => idtac
+ end.
+
+Lemma mk_mov_tail:
+ forall rd rs k c, mk_mov rd rs k = OK c -> is_tail k c.
+Proof.
+ unfold mk_mov; intros. destruct rd; IsTail; destruct rs; IsTail.
+Qed.
+
+Lemma mk_shift_tail:
+ forall si r1 r2 k c, mk_shift si r1 r2 k = OK c -> is_tail k c.
+Proof.
+ unfold mk_shift; intros; IsTail.
+Qed.
+
+Lemma mk_div_tail:
+ forall di r1 r2 k c, mk_div di r1 r2 k = OK c -> is_tail k c.
+Proof.
+ unfold mk_div; intros; IsTail.
+Qed.
+
+Lemma mk_mod_tail:
+ forall di r1 r2 k c, mk_mod di r1 r2 k = OK c -> is_tail k c.
+Proof.
+ unfold mk_mod; intros; IsTail.
+Qed.
+
+Lemma mk_shrximm_tail:
+ forall r n k c, mk_shrximm r n k = OK c -> is_tail k c.
+Proof.
+ unfold mk_shrximm; intros; IsTail.
+Qed.
+
+Lemma mk_intconv_tail:
+ forall mk rd rs k c, mk_intconv mk rd rs k = OK c -> is_tail k c.
+Proof.
+ unfold mk_intconv; intros; IsTail.
+Qed.
+
+Lemma mk_smallstore_tail:
+ forall sto addr rs k c, mk_smallstore sto addr rs k = OK c -> is_tail k c.
+Proof.
+ unfold mk_smallstore; intros; IsTail.
+Qed.
+
+Lemma loadind_tail:
+ forall base ofs ty dst k c, loadind base ofs ty dst k = OK c -> is_tail k c.
+Proof.
+ unfold loadind; intros. destruct ty; IsTail. destruct (preg_of dst); IsTail.
+Qed.
+
+Lemma storeind_tail:
+ forall src base ofs ty k c, storeind src base ofs ty k = OK c -> is_tail k c.
+Proof.
+ unfold storeind; intros. destruct ty; IsTail. destruct (preg_of src); IsTail.
+Qed.
+
+Hint Resolve mk_mov_tail mk_shift_tail mk_div_tail mk_mod_tail mk_shrximm_tail
+ mk_intconv_tail mk_smallstore_tail loadind_tail storeind_tail : ppcretaddr.
+
+Lemma transl_cond_tail:
+ forall cond args k c, transl_cond cond args k = OK c -> is_tail k c.
+Proof.
+ unfold transl_cond; intros. destruct cond; IsTail; destruct (Int.eq_dec i Int.zero); IsTail.
+Qed.
+
+Lemma transl_op_tail:
+ forall op args res k c, transl_op op args res k = OK c -> is_tail k c.
+Proof.
+ unfold transl_op; intros. destruct op; IsTail.
+ eapply is_tail_trans. 2: eapply transl_cond_tail; eauto. IsTail.
+Qed.
+
+Lemma transl_load_tail:
+ forall chunk addr args dest k c, transl_load chunk addr args dest k = OK c -> is_tail k c.
+Proof.
+ unfold transl_load; intros. IsTail. destruct chunk; IsTail.
+Qed.
+
+Lemma transl_store_tail:
+ forall chunk addr args src k c, transl_store chunk addr args src k = OK c -> is_tail k c.
+Proof.
+ unfold transl_store; intros. IsTail. destruct chunk; IsTail.
+Qed.
+
+Lemma transl_instr_tail:
+ forall f i k c, transl_instr f i k = OK c -> is_tail k c.
+Proof.
+ unfold transl_instr; intros. destruct i; IsTail.
+ eapply is_tail_trans; eapply loadind_tail; eauto.
+ eapply transl_op_tail; eauto.
+ eapply transl_load_tail; eauto.
+ eapply transl_store_tail; eauto.
+ destruct s0; IsTail.
+ destruct s0; IsTail.
+ eapply is_tail_trans. 2: eapply transl_cond_tail; eauto. IsTail.
+Qed.
+
+Lemma transl_code_tail:
+ forall f c1 c2, is_tail c1 c2 ->
+ forall tc1 tc2, transl_code f c1 = OK tc1 -> transl_code f c2 = OK tc2 ->
+ is_tail tc1 tc2.
+Proof.
+ induction 1; simpl; intros.
+ replace tc2 with tc1 by congruence. constructor.
+ IsTail. apply is_tail_trans with x. eauto. eapply transl_instr_tail; eauto.
+Qed.
+
+Lemma return_address_exists:
+ forall f c, is_tail c f.(fn_code) ->
+ exists ra, return_address_offset f c ra.
+Proof.
+ intros.
+ caseEq (transf_function f). intros tf TF.
+ caseEq (transl_code f c). intros tc TC.
+ assert (is_tail tc tf).
+ unfold transf_function in TF. monadInv TF.
+ destruct (zlt (list_length_z x) Int.max_unsigned); monadInv EQ0.
+ IsTail. eapply transl_code_tail; eauto.
+ destruct (is_tail_code_tail _ _ H0) as [ofs A].
+ exists (Int.repr ofs). constructor; intros. congruence.
+ intros. exists (Int.repr 0). constructor; intros; congruence.
+ intros. exists (Int.repr 0). constructor; intros; congruence.
+Qed.
+
+