(* *********************************************************************) (* *) (* 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. *) (* *) (* *********************************************************************) (** The Mach intermediate language: abstract syntax. Mach is the last intermediate language before generation of assembly code. This file defines the abstract syntax for Mach; two dynamic semantics are given in modules [Machabstr] and [Machconcr]. *) Require Import Coqlib. Require Import Maps. Require Import AST. Require Import Integers. Require Import Values. Require Import Mem. Require Import Events. Require Import Globalenvs. Require Import Op. Require Import Locations. (** * Abstract syntax *) (** Like Linear, the Mach language is organized as lists of instructions operating over machine registers, with default fall-through behaviour and explicit labels and branch instructions. The main difference with Linear lies in the instructions used to access the activation record. Mach has three such instructions: [Mgetstack] and [Msetstack] to read and write within the activation record for the current function, at a given word offset and with a given type; and [Mgetparam], to read within the activation record of the caller. These instructions implement a more concrete view of the activation record than the the [Lgetstack] and [Lsetstack] instructions of Linear: actual offsets are used instead of abstract stack slots, and the distinction between the caller's frame and the callee's frame is made explicit. *) Definition label := positive. Inductive instruction: Set := | Mgetstack: int -> typ -> mreg -> instruction | Msetstack: mreg -> int -> typ -> instruction | Mgetparam: int -> typ -> mreg -> instruction | Mop: operation -> list mreg -> mreg -> instruction | Mload: memory_chunk -> addressing -> list mreg -> mreg -> instruction | Mstore: memory_chunk -> addressing -> list mreg -> mreg -> instruction | Mcall: signature -> mreg + ident -> instruction | Mtailcall: signature -> mreg + ident -> instruction | Malloc: instruction | Mlabel: label -> instruction | Mgoto: label -> instruction | Mcond: condition -> list mreg -> label -> instruction | Mreturn: instruction. Definition code := list instruction. Record function: Set := mkfunction { fn_sig: signature; fn_code: code; fn_stacksize: Z; fn_framesize: Z; fn_link_ofs: int; fn_retaddr_ofs: int }. Definition fundef := AST.fundef function. Definition program := AST.program fundef unit. Definition funsig (fd: fundef) := match fd with | Internal f => f.(fn_sig) | External ef => ef.(ef_sig) end. Definition genv := Genv.t fundef. (** * Dynamic semantics *) Module RegEq. Definition t := mreg. Definition eq := mreg_eq. End RegEq. Module Regmap := EMap(RegEq). Definition regset := Regmap.t val. Notation "a ## b" := (List.map a b) (at level 1). Notation "a # b <- c" := (Regmap.set b c a) (at level 1, b at next level). Definition is_label (lbl: label) (instr: instruction) : bool := match instr with | Mlabel lbl' => if peq lbl lbl' then true else false | _ => false end. Lemma is_label_correct: forall lbl instr, if is_label lbl instr then instr = Mlabel lbl else instr <> Mlabel lbl. Proof. intros. destruct instr; simpl; try discriminate. case (peq lbl l); intro; congruence. Qed. Fixpoint find_label (lbl: label) (c: code) {struct c} : option code := match c with | nil => None | i1 :: il => if is_label lbl i1 then Some il else find_label lbl il end. Lemma find_label_incl: forall lbl c c', find_label lbl c = Some c' -> incl c' c. Proof. induction c; simpl; intros. discriminate. destruct (is_label lbl a). inv H. auto with coqlib. eauto with coqlib. Qed. Definition find_function_ptr (ge: genv) (ros: mreg + ident) (rs: regset) : option block := match ros with | inl r => match rs r with | Vptr b ofs => if Int.eq ofs Int.zero then Some b else None | _ => None end | inr symb => Genv.find_symbol ge symb end.