include "basics/logic.ma". include "common/AST.ma". include "common/CostLabel.ma". include "common/FrontEndOps.ma". include "common/Registers.ma". include "ASM/Vector.ma". include "common/Graphs.ma". inductive statement : Type[0] ≝ | St_skip : label → statement | St_cost : costlabel → label → statement | St_const : ∀t. register → constant t → label → statement | St_op1 : ∀t',t. unary_operation t t' → register → register → label → statement (* destination source *) | St_op2 : ∀t',t1,t2. binary_operation t1 t2 t' → register → register → register → label → statement (* destination source1 source2 *) | St_load : typ → register → register → label → statement | St_store : typ → register → register → label → statement | St_call_id : ident → list register → option register → label → statement | St_call_ptr : register → list register → option register → label → statement (* We're not using these just now, and they'd make the Traces.ma proofs more difficult. | St_tailcall_id : ident → list register → statement | St_tailcall_ptr : register → list register → statement *) | St_cond : register → label → label → statement | St_return : statement . definition env_has : list (register × typ) → register → typ → Prop ≝ λl,r,t. Exists ? (λx. 〈r,t〉 = x) l. definition statement_typed : list (register × typ) → statement → Prop ≝ λe,s. match s with [ St_const t r _ _ ⇒ env_has e r t | St_op1 t' t _ r' r _ ⇒ env_has e r' t' ∧ env_has e r t | St_op2 t' t1 t2 _ r' r1 r2 _ ⇒ env_has e r1 t1 ∧ env_has e r2 t2 ∧ env_has e r' t' | St_load t' addr dst _ ⇒ env_has e dst t' ∧ env_has e addr ASTptr | St_store t' addr src _ ⇒ env_has e src t' ∧ env_has e addr ASTptr | St_call_id id args dst _ ⇒ All ? (λr. ∃t'.env_has e r t') args ∧ (match dst with [ Some r ⇒ ∃t'.env_has e r t' | _ ⇒ True]) | St_call_ptr fnptr args dst _ ⇒ env_has e fnptr ASTptr ∧ All ? (λr. ∃t'.env_has e r t') args ∧ (match dst with [ Some r ⇒ ∃t'.env_has e r t' | _ ⇒ True]) | St_cond r _ _ ⇒ ∃t. env_has e r t | _ ⇒ True ]. definition labels_P : (label → Prop) → statement → Prop ≝ λP,s. match s with [ St_skip l ⇒ P l | St_cost _ l ⇒ P l | St_const _ _ _ l ⇒ P l | St_op1 _ _ _ _ _ l ⇒ P l | St_op2 _ _ _ _ _ _ _ l ⇒ P l | St_load _ _ _ l ⇒ P l | St_store _ _ _ l ⇒ P l | St_call_id _ _ _ l ⇒ P l | St_call_ptr _ _ _ l ⇒ P l (* | St_tailcall_id _ _ ⇒ True | St_tailcall_ptr _ _ ⇒ True *) | St_cond _ l1 l2 ⇒ P l1 ∧ P l2 | St_return ⇒ True ]. lemma labels_P_mp : ∀P,Q. (∀l. P l → Q l) → ∀s.labels_P P s → labels_P Q s. #P #Q #H * /3/ #r #l #l' * /3/ qed. definition labels_present : graph statement → statement → Prop ≝ λg,s. labels_P (present ?? g) s. definition forall_nodes : ∀A.∀P:A → Prop. graph A → Prop ≝ λA,P,g. ∀l,n. lookup ?? g l = Some ? n → P n. definition graph_closed : graph statement → Prop ≝ λg. forall_nodes ? (labels_present g) g. definition graph_typed : list (register × typ) → graph statement → Prop ≝ λe. forall_nodes ? (statement_typed e). record internal_function : Type[0] ≝ { f_labgen : universe LabelTag ; f_reggen : universe RegisterTag ; f_result : option (register × typ) ; f_params : list (register × typ) ; f_locals : list (register × typ) ; f_stacksize : nat ; f_graph : graph statement ; f_closed : graph_closed f_graph ; f_typed : graph_typed (f_locals @ f_params) f_graph ; f_entry : Σl:label. present ?? f_graph l ; f_exit : Σl:label. present ?? f_graph l }. (* Note that the global variables will be initialised by the code in main by this stage, so the only initialisation data is the amount of space to allocate. *) definition RTLabs_program ≝ program (λ_.fundef internal_function) nat.