(* *********************************************************************)
(*                                                                     *)
(*              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.     *)
(*                                                                     *)
(* *********************************************************************)
(** Abstract syntax and semantics for PowerPC assembly language *)
(** * Abstract syntax *)
(** Integer registers, floating-point registers. *)
Inductive ireg: Type :=
| GPR0: ireg  | GPR1: ireg  | GPR2: ireg  | GPR3: ireg
| GPR4: ireg  | GPR5: ireg  | GPR6: ireg  | GPR7: ireg
| GPR8: ireg  | GPR9: ireg  | GPR10: ireg | GPR11: ireg
| GPR12: ireg | GPR13: ireg | GPR14: ireg | GPR15: ireg
| GPR16: ireg | GPR17: ireg | GPR18: ireg | GPR19: ireg
| GPR20: ireg | GPR21: ireg | GPR22: ireg | GPR23: ireg
| GPR24: ireg | GPR25: ireg | GPR26: ireg | GPR27: ireg
| GPR28: ireg | GPR29: ireg | GPR30: ireg | GPR31: ireg.
Inductive freg: Type :=
| FPR0: freg  | FPR1: freg  | FPR2: freg  | FPR3: freg
| FPR4: freg  | FPR5: freg  | FPR6: freg  | FPR7: freg
| FPR8: freg  | FPR9: freg  | FPR10: freg | FPR11: freg
| FPR12: freg | FPR13: freg | FPR14: freg | FPR15: freg
| FPR16: freg | FPR17: freg | FPR18: freg | FPR19: freg
| FPR20: freg | FPR21: freg | FPR22: freg | FPR23: freg
| FPR24: freg | FPR25: freg | FPR26: freg | FPR27: freg
| FPR28: freg | FPR29: freg | FPR30: freg | FPR31: freg.
Fixpoint label_pos (lbl: label) (pos: Z) (c: code) {struct c} : option Z :=
match c with
| nil => None
| instr :: c' =>
if is_label lbl instr then Some (pos + 1) else label_pos lbl (pos + 1) c'
end.
(** Some PowerPC instructions treat register GPR0 as the integer literal 0 when that register is used in argument position. *)
Definition gpr_or_zero (rs: regset) (r: ireg) :=
if ireg_eq r GPR0 then Vint Int.zero else rs#r.
Definition gpr_or_zero_l (rs: regset) (r: ireg) :=
if ireg_eq r GPR0 then Vlong Int64.zero else rs#r.
Variable ge: genv.
(** The two functions below axiomatize how the linker processes symbolic references [symbol + offset] and splits their actual values into two 16-bit halves. *)
Parameter low_half: genv -> ident -> ptrofs -> val.
Parameter high_half: genv -> ident -> ptrofs -> val.
(** The fundamental property of these operations is that, when applied to the address of a symbol, their results can be recombined by addition, rebuilding the original address. *)
(** We also axiomatize the small data area.  For simplicity, we claim that small data symbols can be accessed by absolute 16-bit offsets, that is, relative to [GPR0].  In reality, the linker rewrites the object code, transforming [symb@sdarx(r0)] addressings into [offset(rN)] addressings, where [rN] is the reserved register pointing to the base of the small data area containing symbol [symb].  We leave this transformation up to the linker. *)
Parameter symbol_is_small_data: ident -> ptrofs -> bool.
Parameter small_data_area_offset: genv -> ident -> ptrofs -> val.

Axiom small_data_area_addressing:
forall id ofs,
symbol_is_small_data id ofs = true ->
small_data_area_offset ge id ofs = Genv.symbol_address ge id ofs.