(* *********************************************************************)
(*                                                                     *)
(*              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. *)
Require Stacklayout.
(** * 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: Type :=
| Mgetstack: ptrofs -> typ -> mreg -> instruction
| Msetstack: mreg -> ptrofs -> typ -> instruction
| Mgetparam: ptrofs -> 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
| Mbuiltin: external_function -> list (builtin_arg mreg) -> builtin_res mreg -> instruction
| Mlabel: label -> instruction
| Mgoto: label -> instruction
| Mcond: condition -> list mreg -> label -> instruction
| Mjumptable: mreg -> list label -> instruction
| Mreturn: instruction.
Definition code := list instruction.
Record function: Type := mkfunction
{ fn_sig: signature;
fn_code: code;
fn_stacksize: Z;
fn_link_ofs: ptrofs;
fn_retaddr_ofs: ptrofs }.
Definition fundef := AST.fundef function.
Definition program := AST.program fundef unit.
Definition funsig (fd: fundef) :=
match fd with
| Internal f => fn_sig f
| External ef => ef_sig ef
end.
Definition genv := Genv.t fundef unit.
(** * Operational semantics *)
(** The semantics for Mach is close to that of [Linear]: they differ only on the interpretation of stack slot accesses.  In Mach, these accesses are interpreted as memory accesses relative to the stack pointer.  More precisely: - [Mgetstack ofs ty r] is a memory load at offset [ofs * 4] relative to the stack pointer. - [Msetstack r ofs ty] is a memory store at offset [ofs * 4] relative to the stack pointer. - [Mgetparam ofs ty r] is a memory load at offset [ofs * 4] relative to the pointer found at offset 0 from the stack pointer. The semantics maintain a linked structure of activation records, with the current record containing a pointer to the record of the caller function at offset 0.  In addition to this linking of activation records, the semantics also make provisions for storing a back link at offset [f.(fn_link_ofs)] from the stack pointer, and a return address at offset [f.(fn_retaddr_ofs)].  The latter stack location will be used by the Asm code generated by [Asmgen] to save the return address into the caller at the beginning of a function, then restore it and jump to it at the end of a function.  The Mach concrete semantics does not attach any particular meaning to the pointer stored in this reserved location, but makes sure that it is preserved during execution of a function.  The [return_address_offset] parameter is used to guess the value of the return address that the Asm code generated later will store in the reserved location. *)
Definition load_stack (m: mem) (sp: val) (ty: typ) (ofs: ptrofs) :=
Mem.loadv (chunk_of_type ty) m (Val.offset_ptr sp ofs).
Definition store_stack (m: mem) (sp: val) (ty: typ) (ofs: ptrofs) (v: val) :=
Mem.storev (chunk_of_type ty) m (Val.offset_ptr sp ofs) v.
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).
Fixpoint undef_regs (rl: list mreg) (rs: regset) {struct rl} : regset :=
match rl with
| nil => rs
| r1 :: rl' => Regmap.set r1 Vundef (undef_regs rl' rs)
end.

(* Specifications: *)
Lemma undef_regs_other:
forall r rl rs, ~In r rl -> undef_regs rl rs r = rs r.
Lemma undef_regs_same:
forall r rl rs, In r rl -> undef_regs rl rs r = Vundef.