(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*           Prashanth Mundkur, SRI International                      *)
(*                                                                     *)
(*  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 contributions by Prashanth Mundkur are reused and adapted      *)
(*  under the terms of a Contributor License Agreement between         *)
(*  SRI International and INRIA.                                       *)
(*                                                                     *)
(* *********************************************************************)
(** Abstract syntax and semantics for RISC-V assembly language. *)
Require Stacklayout.
(** * Abstract syntax *)
(** Integer registers.  X0 is treated specially because it always reads as zero and is never used as a destination of an instruction. *)
Inductive ireg: Type :=
| X1:  ireg | X2:  ireg | X3:  ireg | X4:  ireg | X5:  ireg
| X6:  ireg | X7:  ireg | X8:  ireg | X9:  ireg | X10: ireg
| X11: ireg | X12: ireg | X13: ireg | X14: ireg | X15: ireg
| X16: ireg | X17: ireg | X18: ireg | X19: ireg | X20: ireg
| X21: ireg | X22: ireg | X23: ireg | X24: ireg | X25: ireg
| X26: ireg | X27: ireg | X28: ireg | X29: ireg | X30: ireg
| X31: ireg.
Inductive ireg0: Type :=
| X0: ireg0 | X: ireg -> ireg0.
Coercion X: ireg >-> ireg0.
(** Floating-point registers *)
Inductive freg: Type :=
| F0: freg  | F1: freg  | F2: freg  | F3: freg
| F4: freg  | F5: freg  | F6: freg  | F7: freg
| F8: freg  | F9: freg  | F10: freg | F11: freg
| F12: freg | F13: freg | F14: freg | F15: freg
| F16: freg | F17: freg | F18: freg | F19: freg
| F20: freg | F21: freg | F22: freg | F23: freg
| F24: freg | F25: freg | F26: freg | F27: freg
| F28: freg | F29: freg | F30: freg | F31: 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.
Variable ge: genv.
(** The two functions below axiomatize how the linker processes symbolic references [symbol + offset)] and splits their actual values into a 20-bit high part [%hi(symbol + offset)] and a 12-bit low part [%lo(symbol + offset)]. *)
Parameter low_half: genv -> ident -> ptrofs -> ptrofs.
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. *)

Axiom low_high_half:
forall id ofs,
Val.offset_ptr (high_half ge id ofs) (low_half ge id ofs) = Genv.symbol_address ge id ofs.