(* *********************************************************************)
(*                                                                     *)
(*              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.     *)
(*                                                                     *)
(* *********************************************************************)
(** Function calling conventions and other conventions regarding the use of machine registers and stack slots. *)
Require Export Conventions1.
(** The processor-dependent and EABI-dependent definitions are in [arch/abi/Conventions1.v].  This file adds various processor-independent definitions and lemmas. *)
(** ** Location of function parameters *)
(** A function finds the values of its parameter in the same locations where its caller stored them, except that the stack-allocated arguments, viewed as [Outgoing] slots by the caller, are accessed via [Incoming] slots (at the same offsets and types) in the callee. *)
Definition parameter_of_argument (l: loc) : loc :=
match l with
| S Outgoing n ty => S Incoming n ty
| _ => l
end.
Definition loc_parameters (s: signature) : list (rpair loc) :=
List.map (map_rpair parameter_of_argument) (loc_arguments s).
(** * Tail calls *)
(** A tail-call is possible for a signature if the corresponding arguments are all passed in registers. *)
(** A tail-call is possible for a signature if the corresponding arguments are all passed in registers. *)
Definition tailcall_possible (s: signature) : Prop :=
forall l, In l (regs_of_rpairs (loc_arguments s)) ->
match l with R _ => True | S _ _ _ => False end.
(** Decide whether a tailcall is possible. *)
Definition tailcall_is_possible (sg: signature) : bool :=
List.forallb
(fun l => match l with R _ => true | S _ _ _ => false end)
(regs_of_rpairs (loc_arguments sg)).

Lemma tailcall_is_possible_correct:
forall s, tailcall_is_possible s = true -> tailcall_possible s.