summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--snapshots/coq-riscv/README.md34
-rw-r--r--snapshots/coq-riscv/bbv/.gitignore10
-rw-r--r--snapshots/coq-riscv/bbv/.travis.yml5
-rw-r--r--snapshots/coq-riscv/bbv/CONTRIBUTORS19
-rw-r--r--snapshots/coq-riscv/bbv/LICENSE21
-rw-r--r--snapshots/coq-riscv/bbv/Makefile26
-rw-r--r--snapshots/coq-riscv/bbv/README.md11
-rwxr-xr-xsnapshots/coq-riscv/bbv/print_assumptions.sh14
-rw-r--r--snapshots/coq-riscv/bbv/theories/BinNotation.v58
-rw-r--r--snapshots/coq-riscv/bbv/theories/BinNotationZ.v7
-rw-r--r--snapshots/coq-riscv/bbv/theories/DepEq.v75
-rw-r--r--snapshots/coq-riscv/bbv/theories/DepEqNat.v66
-rw-r--r--snapshots/coq-riscv/bbv/theories/HexNotation.v75
-rw-r--r--snapshots/coq-riscv/bbv/theories/HexNotationWord.v12
-rw-r--r--snapshots/coq-riscv/bbv/theories/HexNotationZ.v7
-rw-r--r--snapshots/coq-riscv/bbv/theories/NLib.v12
-rw-r--r--snapshots/coq-riscv/bbv/theories/NatLib.v558
-rw-r--r--snapshots/coq-riscv/bbv/theories/Nomega.v71
-rw-r--r--snapshots/coq-riscv/bbv/theories/Word.v7283
-rw-r--r--snapshots/coq-riscv/bbv/theories/WordScope.v10
-rw-r--r--snapshots/coq-riscv/bbv/theories/ZLib.v25
-rwxr-xr-xsnapshots/coq-riscv/build16
-rwxr-xr-xsnapshots/coq-riscv/clean13
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/.gitignore1
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Makefile24
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_impl_base.v1103
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_instr_kinds.v302
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_operators.v232
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_operators_bitlists.v182
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_operators_mwords.v433
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_prompt.v127
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_prompt_monad.v247
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_state.v69
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_state_monad.v253
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_string.v35
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/Sail2_values.v1643
-rw-r--r--snapshots/coq-riscv/sail/lib/coq/_CoqProject2
-rw-r--r--snapshots/coq-riscv/sail/riscv/coq.patch431
-rw-r--r--snapshots/coq-riscv/sail/riscv/riscv.v33165
-rw-r--r--snapshots/coq-riscv/sail/riscv/riscv_extras.v162
-rw-r--r--snapshots/coq-riscv/sail/riscv/riscv_types.v1387
41 files changed, 48226 insertions, 0 deletions
diff --git a/snapshots/coq-riscv/README.md b/snapshots/coq-riscv/README.md
new file mode 100644
index 00000000..ee70b593
--- /dev/null
+++ b/snapshots/coq-riscv/README.md
@@ -0,0 +1,34 @@
+# Sail RISC-V model for Coq
+
+This directory contains the Coq files for the Sail RISC-V model, in
+`sail/riscv`, along with the Sail Coq library (`sail/lib/coq`) and the
+MIT BBV library for bitvector support. The `build` script checks all
+of the files, and `clean` removes the generated files. The main model
+is in `sail/riscv/riscv.v`.
+
+The Coq version of the model was generated from the Sail sources
+available at <https://github.com/rems-project/sail/tree/sail2/riscv>,
+commit `b73f6d13b4bf2291f71616abdb046e2ca657d868`, and were manually
+patched to deal with parts of the model that the tool does not fully
+deal with, mostly due to recursive functions. The manual changes can
+be found in `sail/riscv/coq.patch`.
+
+To reproduce the output from that particular commit of Sail, a small
+change is needed in the type checker, given below. This will be fixed
+in the trunk shortly.
+
+```
+diff --git a/src/type_check.ml b/src/type_check.ml
+index f98ddb9..9a7ae61 100644
+--- a/src/type_check.ml
++++ b/src/type_check.ml
+@@ -2560,7 +2560,7 @@ and type_coercion env (E_aux (_, (l, _)) as annotated_exp) typ =
+ begin
+ try
+ typ_debug (lazy ("PERFORMING TYPE COERCION: from " ^ string_of_typ (typ_of annotated_exp) ^ " to " ^ string_of_typ typ));
+- subtyp l env (typ_of annotated_exp) typ; annotated_exp
++ subtyp l env (typ_of annotated_exp) typ; switch_typ annotated_exp typ
+ with
+ | Type_error (_, trigger) when Env.allow_casts env ->
+ let casts = filter_casts env (typ_of annotated_exp) typ (Env.get_casts env) in
+```
diff --git a/snapshots/coq-riscv/bbv/.gitignore b/snapshots/coq-riscv/bbv/.gitignore
new file mode 100644
index 00000000..fb3dc885
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/.gitignore
@@ -0,0 +1,10 @@
+*.vo
+*.glob
+*.aux
+*.d
+.depend
+.*.cache
+_CoqProject
+Makefile.coq.conf
+Makefile.coq
+html/
diff --git a/snapshots/coq-riscv/bbv/.travis.yml b/snapshots/coq-riscv/bbv/.travis.yml
new file mode 100644
index 00000000..09ff7977
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/.travis.yml
@@ -0,0 +1,5 @@
+# we don't use travis, but the mit-plv organization enabled it for all repos by default,
+# so we blacklist all branches:
+branches:
+ except:
+ - /.*/
diff --git a/snapshots/coq-riscv/bbv/CONTRIBUTORS b/snapshots/coq-riscv/bbv/CONTRIBUTORS
new file mode 100644
index 00000000..e134ab51
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/CONTRIBUTORS
@@ -0,0 +1,19 @@
+Contributors (in alphabetical order):
+
+Tej Chajed
+Haogang Chen
+Adam Chlipala
+Joonwon Choi
+Andres Erbsen
+Jason Gross
+Samuel Gruetter
+Frans Kaashoek
+Alex Konradi
+Gregory Malecha
+Duckki Oe
+Murali Vijayaraghavan
+Nickolai Zeldovich
+Daniel Ziegler
+
+This list was generated from the commit history of the various projects from which bbv was merged, so it's likely that some people are missing. If you think someone should be added, please make a pull request!
+
diff --git a/snapshots/coq-riscv/bbv/LICENSE b/snapshots/coq-riscv/bbv/LICENSE
new file mode 100644
index 00000000..4d718ec2
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2011-2018, Massachusetts Institute of Technology
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/snapshots/coq-riscv/bbv/Makefile b/snapshots/coq-riscv/bbv/Makefile
new file mode 100644
index 00000000..f877aedf
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/Makefile
@@ -0,0 +1,26 @@
+default_target: all
+
+COQMAKEFILE=$(COQBIN)coq_makefile
+
+all: Makefile.coq
+ $(MAKE) -f Makefile.coq
+
+doc: all
+ $(MAKE) -f Makefile.coq html
+
+html: doc
+
+clean: Makefile.coq
+ $(MAKE) -f Makefile.coq clean
+ rm -f Makefile.coq Makefile.coq.conf _CoqProject
+
+install: Makefile.coq
+ $(MAKE) -f Makefile.coq install
+
+Makefile.coq: _CoqProject
+ $(COQMAKEFILE) -f _CoqProject -o Makefile.coq
+
+_CoqProject::
+ rm -f _CoqProject
+ echo "-Q theories bbv" > _CoqProject
+ find theories -type f -name '*.v' | sort >> _CoqProject
diff --git a/snapshots/coq-riscv/bbv/README.md b/snapshots/coq-riscv/bbv/README.md
new file mode 100644
index 00000000..7bb553bf
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/README.md
@@ -0,0 +1,11 @@
+# bbv - Bedrock Bit Vectors
+
+Several Coq projects at MIT use a file called Word.v, defining bit vectors and lemmas about them.
+
+This repo unifies the different versions of this file into one repository, so that everyone can benefit from additions made by other projects.
+
+Suggested collaboration protocol:
+
+- For non-breaking, backwards-compatible (i.e. just additions) changes you just push to master, to keep the workflow as lightweight as possible.
+- For more "controversial" changes which might break something, make a PR.
+
diff --git a/snapshots/coq-riscv/bbv/print_assumptions.sh b/snapshots/coq-riscv/bbv/print_assumptions.sh
new file mode 100755
index 00000000..c0fb4ba6
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/print_assumptions.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+if [ "$#" -ne 1 ]; then
+ echo "Illegal number of parameters"
+ echo "Usage: 1 arg (name of coq module to consider without .v extension)"
+ exit 1
+fi
+
+infile="theories/$1.v"
+outfile="$1_print_assumptions.v"
+
+echo "Require Import bbv.$1." > "$outfile"
+
+grep -E "$infile" -e '^ *(Lemma|Theorem|Corollary)' | grep -v 'Note: not axiom free' | sed -E -e 's/ *(Lemma|Theorem|Corollary) //g' -e 's/^([^ :]+).*/About \1. Print Assumptions \1./g' >> "$outfile"
diff --git a/snapshots/coq-riscv/bbv/theories/BinNotation.v b/snapshots/coq-riscv/bbv/theories/BinNotation.v
new file mode 100644
index 00000000..40763711
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/BinNotation.v
@@ -0,0 +1,58 @@
+
+(* Adapted from http://poleiro.info/posts/2013-04-03-parse-errors-as-type-errors.html,
+ https://github.com/arthuraa/poleiro/blob/master/theories/ForceOption.v
+ to produce N instead of nat *)
+
+Require Import Coq.Strings.String.
+Require Import Coq.Strings.Ascii.
+Require Import Coq.NArith.NArith.
+
+Local Open Scope char_scope.
+
+Local Open Scope N_scope.
+
+Definition binDigitToN (c : ascii) : option N :=
+ match c with
+ | "0" => Some 0
+ | "1" => Some 1
+ | _ => None
+ end.
+
+Open Scope string_scope.
+
+Fixpoint readBinNAux (s : string) (acc : N) : option N :=
+ match s with
+ | "" => Some acc
+ | String c s' =>
+ match binDigitToN c with
+ | Some n => readBinNAux s' (2 * acc + n)
+ | None => None
+ end
+ end.
+
+Definition readBinN (s : string) : option N := readBinNAux s 0.
+
+Goal readBinN "11111111" = Some 255.
+Proof. reflexivity. Qed.
+
+Definition forceOption A Err (o : option A) (err : Err) : match o with
+ | Some _ => A
+ | None => Err
+ end :=
+ match o with
+ | Some a => a
+ | None => err
+ end.
+
+Inductive parseError := ParseError.
+
+Definition bin (s : string) := forceOption N parseError (readBinN s) ParseError.
+
+Goal bin"11111111" = 255.
+Proof. reflexivity. Qed.
+
+Goal bin"1011" = 11.
+Proof. reflexivity. Qed.
+
+Goal bin"1O" = ParseError.
+Proof. reflexivity. Qed.
diff --git a/snapshots/coq-riscv/bbv/theories/BinNotationZ.v b/snapshots/coq-riscv/bbv/theories/BinNotationZ.v
new file mode 100644
index 00000000..c06166d7
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/BinNotationZ.v
@@ -0,0 +1,7 @@
+Require Export bbv.BinNotation.
+Require Import Coq.ZArith.BinInt.
+
+Notation "'Ob' a" := (Z.of_N (bin a)) (at level 50).
+
+Goal Ob"01000001" = 65%Z.
+Proof. reflexivity. Qed.
diff --git a/snapshots/coq-riscv/bbv/theories/DepEq.v b/snapshots/coq-riscv/bbv/theories/DepEq.v
new file mode 100644
index 00000000..83e9cbad
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/DepEq.v
@@ -0,0 +1,75 @@
+Require Import Coq.Arith.Peano_dec.
+Require Import Coq.Logic.Eqdep Coq.Logic.Eqdep_dec Coq.Program.Equality.
+
+(** * Equalities on dependent types *)
+
+Theorem eq_rect_nat_double : forall T (a b c : nat) x ab bc,
+ eq_rect b T (eq_rect a T x b ab) c bc = eq_rect a T x c (eq_trans ab bc).
+Proof.
+ intros.
+ destruct ab.
+ destruct bc.
+ rewrite (UIP_dec eq_nat_dec (eq_trans eq_refl eq_refl) eq_refl).
+ simpl.
+ auto.
+Qed.
+
+Hint Rewrite eq_rect_nat_double.
+Hint Rewrite <- (eq_rect_eq_dec eq_nat_dec).
+
+Ltac generalize_proof :=
+ match goal with
+ | [ |- context[eq_rect _ _ _ _ ?H ] ] => generalize H
+ end.
+
+Ltac eq_rect_simpl :=
+ unfold eq_rec_r, eq_rec;
+ repeat rewrite eq_rect_nat_double;
+ repeat rewrite <- (eq_rect_eq_dec eq_nat_dec).
+
+Ltac destruct_existT :=
+ repeat match goal with
+ | [H: existT _ _ _ = existT _ _ _ |- _] =>
+ (apply Eqdep.EqdepTheory.inj_pair2 in H; subst)
+ end.
+
+Lemma eq_rect_word_offset_helper : forall a b c,
+ a = b -> c + a = c + b.
+Proof.
+ intros; congruence.
+Qed.
+
+Lemma eq_rect_word_mult_helper : forall a b c,
+ a = b -> a * c = b * c.
+Proof.
+ intros; congruence.
+Qed.
+
+Lemma existT_eq_rect:
+ forall (X: Type) (P: X -> Type) (x1 x2: X) (H1: P x1) (Hx: x1 = x2),
+ existT P x2 (eq_rect x1 P H1 x2 Hx) =
+ existT P x1 H1.
+Proof.
+ intros; subst; reflexivity.
+Qed.
+
+Lemma existT_eq_rect_eq:
+ forall (X: Type) (P: X -> Type) (x1 x2: X)
+ (H1: P x1) (H2: P x2) (Hx: x1 = x2),
+ H2 = eq_rect _ P H1 _ Hx ->
+ existT P x1 H1 = existT P x2 H2.
+Proof.
+ intros; subst; reflexivity.
+Qed.
+
+Lemma eq_rect_existT_eq:
+ forall (X: Type) (P: X -> Type) (x1 x2: X)
+ (H1: P x1) (H2: P x2) (Hx: x1 = x2)
+ (Hex: existT P x1 H1 = existT P x2 H2),
+ H2 = eq_rect _ P H1 _ Hx.
+Proof.
+ intros; subst.
+ subst; destruct_existT.
+ reflexivity.
+Qed.
+
diff --git a/snapshots/coq-riscv/bbv/theories/DepEqNat.v b/snapshots/coq-riscv/bbv/theories/DepEqNat.v
new file mode 100644
index 00000000..b68c7e34
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/DepEqNat.v
@@ -0,0 +1,66 @@
+
+(* This file defines nat_cast, an alternative to eq_rect which works only for type nat instead
+ of any type A.
+ The motivation behind nat_cast is that it only matches on proofs in contradictory cases,
+ so functions using nat_cast can always be run inside Coq using cbv, whereas function using
+ eq_rect cannot. *)
+
+Arguments id {A} x.
+
+(* Transport equality, only matching on eq_refl in contradictory cases, to make sure
+ terms using this function reduce *)
+Fixpoint nat_cast (P : nat -> Type) {n m} : n = m -> P n -> P m.
+ refine match n, m return n = m -> P n -> P m with
+ | O, O => fun _ => id
+ | S n, S m => fun pf => @nat_cast (fun n => P (S n)) n m (f_equal pred pf)
+ | _, _ => fun pf => match _ pf : False with end
+ end;
+ clear; abstract congruence.
+Defined. (* thx Jason *)
+
+Lemma nat_cast_eq_rect: forall (P : nat -> Type),
+ forall (n m : nat) (e: n = m) (pn: P n),
+ nat_cast P e pn = eq_rect n P pn m e.
+Proof.
+ destruct e.
+ revert dependent P; induction n; simpl; intros.
+ - reflexivity.
+ - rewrite IHn. reflexivity.
+Qed. (* thx Clement *)
+
+Lemma nat_cast_proof_irrel: forall (P : nat -> Type),
+ forall (n m : nat) (e1 e2: n = m) (pn: P n),
+ nat_cast P e1 pn = nat_cast P e2 pn.
+Proof.
+ destruct e1.
+ revert dependent P; induction n; simpl; intros.
+ - reflexivity.
+ - erewrite IHn. reflexivity.
+Qed.
+
+Lemma nat_cast_same: forall (P: nat -> Type) (s: nat) (n: P s),
+ nat_cast P eq_refl n = n.
+Proof.
+ intros. rewrite nat_cast_eq_rect. reflexivity.
+Qed.
+
+Lemma nat_cast_fuse: forall (P: nat -> Type) (n1 n2 n3: nat) (e12: n1 = n2) (e23: n2 = n3) (x: P n1),
+ nat_cast P e23 (nat_cast P e12 x) = nat_cast P (eq_trans e12 e23) x.
+Proof.
+ destruct e12.
+ destruct e23.
+ intros.
+ rewrite nat_cast_same.
+ reflexivity.
+Qed.
+
+Lemma nat_cast_cast ni no (pf: ni = no) (P: nat -> Type) (x : P ni):
+ nat_cast P pf x = match pf in _ = Y return P Y with
+ | eq_refl => x
+ end.
+Proof.
+ destruct pf.
+ rewrite nat_cast_same.
+ auto.
+Qed.
+ \ No newline at end of file
diff --git a/snapshots/coq-riscv/bbv/theories/HexNotation.v b/snapshots/coq-riscv/bbv/theories/HexNotation.v
new file mode 100644
index 00000000..e6f5abfb
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/HexNotation.v
@@ -0,0 +1,75 @@
+
+(* Adapted from http://poleiro.info/posts/2013-04-03-parse-errors-as-type-errors.html,
+ https://github.com/arthuraa/poleiro/blob/master/theories/ForceOption.v
+ to produce N instead of nat *)
+
+Require Import Coq.Strings.String.
+Require Import Coq.Strings.Ascii.
+Require Import Coq.NArith.NArith.
+
+Local Open Scope char_scope.
+
+Local Open Scope N_scope.
+
+Definition hexDigitToN (c : ascii) : option N :=
+ match c with
+ | "0" => Some 0
+ | "1" => Some 1
+ | "2" => Some 2
+ | "3" => Some 3
+ | "4" => Some 4
+ | "5" => Some 5
+ | "6" => Some 6
+ | "7" => Some 7
+ | "8" => Some 8
+ | "9" => Some 9
+ | "a" | "A" => Some 10
+ | "b" | "B" => Some 11
+ | "c" | "C" => Some 12
+ | "d" | "D" => Some 13
+ | "e" | "E" => Some 14
+ | "f" | "F" => Some 15
+ | _ => None
+ end.
+
+Open Scope string_scope.
+
+Fixpoint readHexNAux (s : string) (acc : N) : option N :=
+ match s with
+ | "" => Some acc
+ | String c s' =>
+ match hexDigitToN c with
+ | Some n => readHexNAux s' (16 * acc + n)
+ | None => None
+ end
+ end.
+
+Definition readHexN (s : string) : option N := readHexNAux s 0.
+
+Goal readHexN "ff" = Some 255.
+Proof. reflexivity. Qed.
+
+Definition forceOption A Err (o : option A) (err : Err) : match o with
+ | Some _ => A
+ | None => Err
+ end :=
+ match o with
+ | Some a => a
+ | None => err
+ end.
+
+Inductive parseError := ParseError.
+
+Definition hex (s : string) := forceOption N parseError (readHexN s) ParseError.
+
+Goal hex"ff" = 255.
+Proof. reflexivity. Qed.
+
+Goal hex"a0f" = 2575.
+Proof. reflexivity. Qed.
+
+Goal hex"1O" = ParseError.
+Proof. reflexivity. Qed.
+
+Goal hex"ff34c8e3" = 4281649379.
+Proof. reflexivity. Qed.
diff --git a/snapshots/coq-riscv/bbv/theories/HexNotationWord.v b/snapshots/coq-riscv/bbv/theories/HexNotationWord.v
new file mode 100644
index 00000000..1b32427e
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/HexNotationWord.v
@@ -0,0 +1,12 @@
+Require Export bbv.HexNotation.
+Require Import bbv.WordScope.
+
+Notation "'Ox' a" := (NToWord _ (hex a)) (at level 50).
+
+Notation "sz ''h' a" := (NToWord sz (hex a)) (at level 50).
+
+Goal 8'h"a" = WO~0~0~0~0~1~0~1~0.
+Proof. reflexivity. Qed.
+
+Goal Ox"41" = WO~1~0~0~0~0~0~1.
+Proof. reflexivity. Qed.
diff --git a/snapshots/coq-riscv/bbv/theories/HexNotationZ.v b/snapshots/coq-riscv/bbv/theories/HexNotationZ.v
new file mode 100644
index 00000000..528f32fb
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/HexNotationZ.v
@@ -0,0 +1,7 @@
+Require Export bbv.HexNotation.
+Require Import Coq.ZArith.BinInt.
+
+Notation "'Ox' a" := (Z.of_N (hex a)) (at level 50).
+
+Goal Ox"41" = 65%Z.
+Proof. reflexivity. Qed.
diff --git a/snapshots/coq-riscv/bbv/theories/NLib.v b/snapshots/coq-riscv/bbv/theories/NLib.v
new file mode 100644
index 00000000..9def8f83
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/NLib.v
@@ -0,0 +1,12 @@
+Require Import Coq.NArith.NArith.
+
+Local Open Scope N_scope.
+
+Definition Nlt_dec: forall (l r : N), {l < r} + {l >= r}.
+ refine (fun l r =>
+ match N.compare l r as k return N.compare l r = k -> _ with
+ | Lt => fun pf => left _ _
+ | _ => fun pf => right _ _
+ end (refl_equal _));
+ abstract congruence.
+Defined.
diff --git a/snapshots/coq-riscv/bbv/theories/NatLib.v b/snapshots/coq-riscv/bbv/theories/NatLib.v
new file mode 100644
index 00000000..e8bd7c44
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/NatLib.v
@@ -0,0 +1,558 @@
+Require Import Coq.Arith.Div2.
+Require Import Coq.omega.Omega.
+Require Import Coq.NArith.NArith.
+Require Import Coq.ZArith.ZArith.
+
+Require Export bbv.Nomega.
+
+Set Implicit Arguments.
+
+Fixpoint mod2 (n : nat) : bool :=
+ match n with
+ | 0 => false
+ | 1 => true
+ | S (S n') => mod2 n'
+ end.
+
+Ltac rethink :=
+ match goal with
+ | [ H : ?f ?n = _ |- ?f ?m = _ ] => replace m with n; simpl; auto
+ end.
+
+Theorem mod2_S_double : forall n, mod2 (S (2 * n)) = true.
+ induction n; simpl; intuition; rethink.
+Qed.
+
+Theorem mod2_double : forall n, mod2 (2 * n) = false.
+ induction n; simpl; intuition; rewrite <- plus_n_Sm; rethink.
+Qed.
+
+Theorem div2_double : forall n, div2 (2 * n) = n.
+ induction n; simpl; intuition; rewrite <- plus_n_Sm; f_equal; rethink.
+Qed.
+
+Theorem div2_S_double : forall n, div2 (S (2 * n)) = n.
+ induction n; simpl; intuition; f_equal; rethink.
+Qed.
+
+Notation pow2 := (Nat.pow 2).
+
+Fixpoint Npow2 (n : nat) : N :=
+ match n with
+ | O => 1
+ | S n' => 2 * Npow2 n'
+ end%N.
+
+Theorem untimes2 : forall n, n + (n + 0) = 2 * n.
+ auto.
+Qed.
+
+Section strong.
+ Variable P : nat -> Prop.
+
+ Hypothesis PH : forall n, (forall m, m < n -> P m) -> P n.
+
+ Lemma strong' : forall n m, m <= n -> P m.
+ induction n; simpl; intuition; apply PH; intuition.
+ elimtype False; omega.
+ Qed.
+
+ Theorem strong : forall n, P n.
+ intros; eapply strong'; eauto.
+ Qed.
+End strong.
+
+Theorem div2_odd : forall n,
+ mod2 n = true
+ -> n = S (2 * div2 n).
+ induction n as [n] using strong; simpl; intuition.
+
+ destruct n as [|n]; simpl in *; intuition.
+ discriminate.
+ destruct n as [|n]; simpl in *; intuition.
+ do 2 f_equal.
+ replace (div2 n + S (div2 n + 0)) with (S (div2 n + (div2 n + 0))); auto.
+Qed.
+
+Theorem div2_even : forall n,
+ mod2 n = false
+ -> n = 2 * div2 n.
+ induction n as [n] using strong; simpl; intuition.
+
+ destruct n as [|n]; simpl in *; intuition.
+ destruct n as [|n]; simpl in *; intuition.
+ discriminate.
+ f_equal.
+ replace (div2 n + S (div2 n + 0)) with (S (div2 n + (div2 n + 0))); auto.
+Qed.
+
+Theorem drop_mod2 : forall n k,
+ 2 * k <= n
+ -> mod2 (n - 2 * k) = mod2 n.
+ induction n as [n] using strong; intros.
+
+ do 2 (destruct n; simpl in *; repeat rewrite untimes2 in *; intuition).
+
+ destruct k; simpl in *; intuition.
+
+ destruct k; simpl; intuition.
+ rewrite <- plus_n_Sm.
+ repeat rewrite untimes2 in *.
+ simpl; auto.
+ apply H; omega.
+Qed.
+
+Theorem div2_minus_2 : forall n k,
+ 2 * k <= n
+ -> div2 (n - 2 * k) = div2 n - k.
+ induction n as [n] using strong; intros.
+
+ do 2 (destruct n; simpl in *; intuition; repeat rewrite untimes2 in *).
+ destruct k; simpl in *; intuition.
+
+ destruct k; simpl in *; intuition.
+ rewrite <- plus_n_Sm.
+ apply H; omega.
+Qed.
+
+Theorem div2_bound : forall k n,
+ 2 * k <= n
+ -> k <= div2 n.
+ intros ? n H; case_eq (mod2 n); intro Heq.
+
+ rewrite (div2_odd _ Heq) in H.
+ omega.
+
+ rewrite (div2_even _ Heq) in H.
+ omega.
+Qed.
+
+Lemma two_times_div2_bound: forall n, 2 * Nat.div2 n <= n.
+Proof.
+ eapply strong. intros n IH.
+ destruct n.
+ - constructor.
+ - destruct n.
+ + simpl. constructor. constructor.
+ + simpl (Nat.div2 (S (S n))).
+ specialize (IH n). omega.
+Qed.
+
+Lemma div2_compat_lt_l: forall a b, b < 2 * a -> Nat.div2 b < a.
+Proof.
+ induction a; intros.
+ - omega.
+ - destruct b.
+ + simpl. omega.
+ + destruct b.
+ * simpl. omega.
+ * simpl. apply lt_n_S. apply IHa. omega.
+Qed.
+
+(* otherwise b is made implicit, while a isn't, which is weird *)
+Arguments div2_compat_lt_l {_} {_} _.
+
+Lemma pow2_add_mul: forall a b,
+ pow2 (a + b) = (pow2 a) * (pow2 b).
+Proof.
+ induction a; destruct b; firstorder; simpl.
+ repeat rewrite Nat.add_0_r.
+ rewrite Nat.mul_1_r; auto.
+ repeat rewrite Nat.add_0_r.
+ rewrite IHa.
+ simpl.
+ repeat rewrite Nat.add_0_r.
+ rewrite Nat.mul_add_distr_r; auto.
+Qed.
+
+Lemma mult_pow2_bound: forall a b x y,
+ x < pow2 a -> y < pow2 b -> x * y < pow2 (a + b).
+Proof.
+ intros.
+ rewrite pow2_add_mul.
+ apply Nat.mul_lt_mono_nonneg; omega.
+Qed.
+
+Lemma mult_pow2_bound_ex: forall a c x y,
+ x < pow2 a -> y < pow2 (c - a) -> c >= a -> x * y < pow2 c.
+Proof.
+ intros.
+ replace c with (a + (c - a)) by omega.
+ apply mult_pow2_bound; auto.
+Qed.
+
+Lemma lt_mul_mono' : forall c a b,
+ a < b -> a < b * (S c).
+Proof.
+ induction c; intros.
+ rewrite Nat.mul_1_r; auto.
+ rewrite Nat.mul_succ_r.
+ apply lt_plus_trans.
+ apply IHc; auto.
+Qed.
+
+Lemma lt_mul_mono : forall a b c,
+ c <> 0 -> a < b -> a < b * c.
+Proof.
+ intros.
+ replace c with (S (c - 1)) by omega.
+ apply lt_mul_mono'; auto.
+Qed.
+
+Lemma zero_lt_pow2 : forall sz, 0 < pow2 sz.
+Proof.
+ induction sz; simpl; omega.
+Qed.
+
+Lemma one_lt_pow2:
+ forall n,
+ 1 < pow2 (S n).
+Proof.
+ intros.
+ induction n.
+ simpl; omega.
+ remember (S n); simpl.
+ omega.
+Qed.
+
+Lemma one_le_pow2 : forall sz, 1 <= pow2 sz.
+Proof.
+ intros. pose proof (zero_lt_pow2 sz). omega.
+Qed.
+
+Lemma pow2_ne_zero: forall n, pow2 n <> 0.
+Proof.
+ intros.
+ pose proof (zero_lt_pow2 n).
+ omega.
+Qed.
+
+Lemma mul2_add : forall n, n * 2 = n + n.
+Proof.
+ induction n; firstorder.
+Qed.
+
+Lemma pow2_le_S : forall sz, (pow2 sz) + 1 <= pow2 (sz + 1).
+Proof.
+ induction sz; simpl; auto.
+ repeat rewrite Nat.add_0_r.
+ rewrite pow2_add_mul.
+ repeat rewrite mul2_add.
+ pose proof (zero_lt_pow2 sz).
+ omega.
+Qed.
+
+Lemma pow2_bound_mono: forall a b x,
+ x < pow2 a -> a <= b -> x < pow2 b.
+Proof.
+ intros.
+ replace b with (a + (b - a)) by omega.
+ rewrite pow2_add_mul.
+ apply lt_mul_mono; auto.
+ pose proof (zero_lt_pow2 (b - a)).
+ omega.
+Qed.
+
+Lemma pow2_inc : forall n m,
+ 0 < n -> n < m ->
+ pow2 n < pow2 m.
+Proof.
+ intros.
+ generalize dependent n; intros.
+ induction m; simpl.
+ intros. inversion H0.
+ unfold lt in H0.
+ rewrite Nat.add_0_r.
+ inversion H0.
+ apply Nat.lt_add_pos_r.
+ apply zero_lt_pow2.
+ apply Nat.lt_trans with (pow2 m).
+ apply IHm.
+ exact H2.
+ apply Nat.lt_add_pos_r.
+ apply zero_lt_pow2.
+Qed.
+
+Lemma pow2_S: forall x, pow2 (S x) = 2 * pow2 x.
+Proof. intros. reflexivity. Qed.
+
+Lemma mod2_S_S : forall n,
+ mod2 (S (S n)) = mod2 n.
+Proof.
+ intros.
+ destruct n; auto; destruct n; auto.
+Qed.
+
+Lemma mod2_S_not : forall n,
+ mod2 (S n) = if (mod2 n) then false else true.
+Proof.
+ intros.
+ induction n; auto.
+ rewrite mod2_S_S.
+ destruct (mod2 n); replace (mod2 (S n)); auto.
+Qed.
+
+Lemma mod2_S_eq : forall n k,
+ mod2 n = mod2 k ->
+ mod2 (S n) = mod2 (S k).
+Proof.
+ intros.
+ do 2 rewrite mod2_S_not.
+ rewrite H.
+ auto.
+Qed.
+
+Theorem drop_mod2_add : forall n k,
+ mod2 (n + 2 * k) = mod2 n.
+Proof.
+ intros.
+ induction n.
+ simpl.
+ rewrite Nat.add_0_r.
+ replace (k + k) with (2 * k) by omega.
+ apply mod2_double.
+ replace (S n + 2 * k) with (S (n + 2 * k)) by omega.
+ apply mod2_S_eq; auto.
+Qed.
+
+Lemma mod2sub: forall a b,
+ b <= a ->
+ mod2 (a - b) = xorb (mod2 a) (mod2 b).
+Proof.
+ intros. remember (a - b) as c. revert dependent b. revert a. revert c.
+ change (forall c,
+ (fun c => forall a b, b <= a -> c = a - b -> mod2 c = xorb (mod2 a) (mod2 b)) c).
+ apply strong.
+ intros c IH a b AB N.
+ destruct c.
+ - assert (a=b) by omega. subst. rewrite Bool.xorb_nilpotent. reflexivity.
+ - destruct c.
+ + assert (a = S b) by omega. subst a. simpl (mod2 1). rewrite mod2_S_not.
+ destruct (mod2 b); reflexivity.
+ + destruct a; [omega|].
+ destruct a; [omega|].
+ simpl.
+ apply IH; omega.
+Qed.
+
+Theorem mod2_pow2_twice: forall n,
+ mod2 (pow2 n + (pow2 n + 0)) = false.
+Proof.
+ intros.
+ replace (pow2 n + (pow2 n + 0)) with (2 * pow2 n) by omega.
+ apply mod2_double.
+Qed.
+
+Theorem div2_plus_2 : forall n k,
+ div2 (n + 2 * k) = div2 n + k.
+Proof.
+ induction n; intros.
+ simpl.
+ rewrite Nat.add_0_r.
+ replace (k + k) with (2 * k) by omega.
+ apply div2_double.
+ replace (S n + 2 * k) with (S (n + 2 * k)) by omega.
+ destruct (Even.even_or_odd n).
+ - rewrite <- even_div2.
+ rewrite <- even_div2 by auto.
+ apply IHn.
+ apply Even.even_even_plus; auto.
+ apply Even.even_mult_l; repeat constructor.
+
+ - rewrite <- odd_div2.
+ rewrite <- odd_div2 by auto.
+ rewrite IHn.
+ omega.
+ apply Even.odd_plus_l; auto.
+ apply Even.even_mult_l; repeat constructor.
+Qed.
+
+Lemma pred_add:
+ forall n, n <> 0 -> pred n + 1 = n.
+Proof.
+ intros; rewrite pred_of_minus; omega.
+Qed.
+
+Lemma pow2_zero: forall sz, (pow2 sz > 0)%nat.
+Proof.
+ induction sz; simpl; auto; omega.
+Qed.
+
+Theorem Npow2_nat : forall n, nat_of_N (Npow2 n) = pow2 n.
+ induction n as [|n IHn]; simpl; intuition.
+ rewrite <- IHn; clear IHn.
+ case_eq (Npow2 n); intuition.
+ rewrite untimes2.
+ match goal with
+ | [ |- context[Npos ?p~0] ]
+ => replace (Npos p~0) with (N.double (Npos p)) by reflexivity
+ end.
+ apply nat_of_Ndouble.
+Qed.
+
+Theorem pow2_N : forall n, Npow2 n = N.of_nat (pow2 n).
+Proof.
+ intro n. apply nat_of_N_eq. rewrite Nat2N.id. apply Npow2_nat.
+Qed.
+
+Lemma pow2_S_z:
+ forall n, Z.of_nat (pow2 (S n)) = (2 * Z.of_nat (pow2 n))%Z.
+Proof.
+ intros.
+ replace (2 * Z.of_nat (pow2 n))%Z with
+ (Z.of_nat (pow2 n) + Z.of_nat (pow2 n))%Z by omega.
+ simpl.
+ repeat rewrite Nat2Z.inj_add.
+ ring.
+Qed.
+
+Lemma pow2_le:
+ forall n m, (n <= m)%nat -> (pow2 n <= pow2 m)%nat.
+Proof.
+ intros.
+ assert (exists s, n + s = m) by (exists (m - n); omega).
+ destruct H0; subst.
+ rewrite pow2_add_mul.
+ pose proof (pow2_zero x).
+ replace (pow2 n) with (pow2 n * 1) at 1 by omega.
+ apply mult_le_compat_l.
+ omega.
+Qed.
+
+Lemma Zabs_of_nat:
+ forall n, Z.abs (Z.of_nat n) = Z.of_nat n.
+Proof.
+ unfold Z.of_nat; intros.
+ destruct n; auto.
+Qed.
+
+Lemma Npow2_not_zero:
+ forall n, Npow2 n <> 0%N.
+Proof.
+ induction n; simpl; intros; [discriminate|].
+ destruct (Npow2 n); auto.
+ discriminate.
+Qed.
+
+Lemma Npow2_S:
+ forall n, Npow2 (S n) = (Npow2 n + Npow2 n)%N.
+Proof.
+ simpl; intros.
+ destruct (Npow2 n); auto.
+ rewrite <-Pos.add_diag.
+ reflexivity.
+Qed.
+
+Lemma Npow2_pos: forall a,
+ (0 < Npow2 a)%N.
+Proof.
+ intros.
+ destruct (Npow2 a) eqn: E.
+ - exfalso. apply (Npow2_not_zero a). assumption.
+ - constructor.
+Qed.
+
+Lemma minus_minus: forall a b c,
+ c <= b <= a ->
+ a - (b - c) = a - b + c.
+Proof. intros. omega. Qed.
+
+Lemma even_odd_destruct: forall n,
+ (exists a, n = 2 * a) \/ (exists a, n = 2 * a + 1).
+Proof.
+ induction n.
+ - left. exists 0. reflexivity.
+ - destruct IHn as [[a E] | [a E]].
+ + right. exists a. omega.
+ + left. exists (S a). omega.
+Qed.
+
+Lemma mul_div_undo: forall i c,
+ c <> 0 ->
+ c * i / c = i.
+Proof.
+ intros.
+ pose proof (Nat.div_mul_cancel_l i 1 c) as P.
+ rewrite Nat.div_1_r in P.
+ rewrite Nat.mul_1_r in P.
+ apply P; auto.
+Qed.
+
+Lemma mod_add_r: forall a b,
+ b <> 0 ->
+ (a + b) mod b = a mod b.
+Proof.
+ intros. rewrite <- Nat.add_mod_idemp_r by omega.
+ rewrite Nat.mod_same by omega.
+ rewrite Nat.add_0_r.
+ reflexivity.
+Qed.
+
+Lemma mod2_cases: forall (n: nat), n mod 2 = 0 \/ n mod 2 = 1.
+Proof.
+ intros.
+ assert (n mod 2 < 2). {
+ apply Nat.mod_upper_bound. congruence.
+ }
+ omega.
+Qed.
+
+Lemma div_mul_undo: forall a b,
+ b <> 0 ->
+ a mod b = 0 ->
+ a / b * b = a.
+Proof.
+ intros.
+ pose proof Nat.div_mul_cancel_l as A. specialize (A a 1 b).
+ replace (b * 1) with b in A by omega.
+ rewrite Nat.div_1_r in A.
+ rewrite mult_comm.
+ rewrite <- Nat.divide_div_mul_exact; try assumption.
+ - apply A; congruence.
+ - apply Nat.mod_divide; assumption.
+Qed.
+
+Lemma Smod2_1: forall k, S k mod 2 = 1 -> k mod 2 = 0.
+Proof.
+ intros k C.
+ change (S k) with (1 + k) in C.
+ rewrite Nat.add_mod in C by congruence.
+ pose proof (Nat.mod_upper_bound k 2).
+ assert (k mod 2 = 0 \/ k mod 2 = 1) as E by omega.
+ destruct E as [E | E]; [assumption|].
+ rewrite E in C. simpl in C. discriminate.
+Qed.
+
+Lemma mod_0_r: forall (m: nat),
+ m mod 0 = 0.
+Proof.
+ intros. reflexivity.
+Qed.
+
+Lemma sub_mod_0: forall (a b m: nat),
+ a mod m = 0 ->
+ b mod m = 0 ->
+ (a - b) mod m = 0.
+Proof.
+ intros. assert (m = 0 \/ m <> 0) as C by omega. destruct C as [C | C].
+ - subst. apply mod_0_r.
+ - assert (a - b = 0 \/ b < a) as D by omega. destruct D as [D | D].
+ + rewrite D. apply Nat.mod_0_l. assumption.
+ + apply Nat2Z.inj. simpl.
+ rewrite Zdiv.mod_Zmod by assumption.
+ rewrite Nat2Z.inj_sub by omega.
+ rewrite Zdiv.Zminus_mod.
+ rewrite <-! Zdiv.mod_Zmod by assumption.
+ rewrite H. rewrite H0.
+ apply Z.mod_0_l.
+ omega.
+Qed.
+
+Lemma mul_div_exact: forall (a b: nat),
+ b <> 0 ->
+ a mod b = 0 ->
+ b * (a / b) = a.
+Proof.
+ intros. edestruct Nat.div_exact as [_ P]; [eassumption|].
+ specialize (P H0). symmetry. exact P.
+Qed.
diff --git a/snapshots/coq-riscv/bbv/theories/Nomega.v b/snapshots/coq-riscv/bbv/theories/Nomega.v
new file mode 100644
index 00000000..9b284f15
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/Nomega.v
@@ -0,0 +1,71 @@
+(* Make [omega] work for [N] *)
+
+Require Import Coq.Arith.Arith Coq.omega.Omega Coq.NArith.NArith.
+
+Local Open Scope N_scope.
+
+Hint Rewrite Nplus_0_r nat_of_Nsucc nat_of_Nplus nat_of_Nminus
+ N_of_nat_of_N nat_of_N_of_nat
+ nat_of_P_o_P_of_succ_nat_eq_succ nat_of_P_succ_morphism : N.
+
+Theorem nat_of_N_eq : forall n m,
+ nat_of_N n = nat_of_N m
+ -> n = m.
+ intros ? ? H; apply (f_equal N_of_nat) in H;
+ autorewrite with N in *; assumption.
+Qed.
+
+Theorem Nneq_in : forall n m,
+ nat_of_N n <> nat_of_N m
+ -> n <> m.
+ congruence.
+Qed.
+
+Theorem Nneq_out : forall n m,
+ n <> m
+ -> nat_of_N n <> nat_of_N m.
+ intuition.
+ match goal with H0 : _ |- _ => apply nat_of_N_eq in H0; tauto end.
+Qed.
+
+Theorem Nlt_out : forall n m, n < m
+ -> (nat_of_N n < nat_of_N m)%nat.
+ unfold N.lt; intros ?? H.
+ rewrite nat_of_Ncompare in H.
+ apply nat_compare_Lt_lt; assumption.
+Qed.
+
+Theorem Nlt_in : forall n m, (nat_of_N n < nat_of_N m)%nat
+ -> n < m.
+ unfold N.lt; intros.
+ rewrite nat_of_Ncompare.
+ apply (proj1 (nat_compare_lt _ _)); assumption.
+Qed.
+
+Theorem Nge_out : forall n m, n >= m
+ -> (nat_of_N n >= nat_of_N m)%nat.
+ unfold N.ge; intros ?? H.
+ rewrite nat_of_Ncompare in H.
+ apply nat_compare_ge; assumption.
+Qed.
+
+Theorem Nge_in : forall n m, (nat_of_N n >= nat_of_N m)%nat
+ -> n >= m.
+ unfold N.ge; intros.
+ rewrite nat_of_Ncompare.
+ apply nat_compare_ge; assumption.
+Qed.
+
+Ltac nsimp H := simpl in H; repeat progress (autorewrite with N in H; simpl in H).
+
+Ltac pre_nomega :=
+ try (apply nat_of_N_eq || apply Nneq_in || apply Nlt_in || apply Nge_in); simpl;
+ repeat (progress autorewrite with N; simpl);
+ repeat match goal with
+ | [ H : _ <> _ |- _ ] => apply Nneq_out in H; nsimp H
+ | [ H : _ = _ -> False |- _ ] => apply Nneq_out in H; nsimp H
+ | [ H : _ |- _ ] => (apply (f_equal nat_of_N) in H
+ || apply Nlt_out in H || apply Nge_out in H); nsimp H
+ end.
+
+Ltac nomega := pre_nomega; omega || (unfold nat_of_P in *; simpl in *; omega).
diff --git a/snapshots/coq-riscv/bbv/theories/Word.v b/snapshots/coq-riscv/bbv/theories/Word.v
new file mode 100644
index 00000000..672c2254
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/Word.v
@@ -0,0 +1,7283 @@
+(** Fixed precision machine words *)
+
+Require Import Coq.Arith.Arith Coq.Arith.Div2 Coq.NArith.NArith Coq.Bool.Bool Coq.omega.Omega.
+Require Import Coq.Logic.Eqdep_dec Coq.Logic.EqdepFacts.
+Require Import Coq.Program.Tactics Coq.Program.Equality.
+Require Import Coq.setoid_ring.Ring.
+Require Import Coq.setoid_ring.Ring_polynom.
+Require Import bbv.Nomega.
+Require Export bbv.ZLib bbv.NatLib bbv.NLib.
+Require Export bbv.DepEq bbv.DepEqNat.
+
+Require Import Coq.micromega.Lia.
+(* for nia (integer arithmetic with multiplications that omega cannot solve *)
+
+Set Implicit Arguments.
+
+(*! Definitions *)
+
+(** * [word] *)
+
+Inductive word : nat -> Set :=
+| WO : word O
+| WS : bool -> forall n, word n -> word (S n).
+
+Delimit Scope word_scope with word.
+Bind Scope word_scope with word.
+
+(* This scope will be closed at the end of the file. *)
+(* Coq trunk seems to inherit open scopes across imports? *)
+Open Scope word_scope.
+
+(** * Conversion to and from [nat] (or [N]), zero and one *)
+
+Fixpoint wordToNat sz (w : word sz) : nat :=
+ match w with
+ | WO => O
+ | WS false w' => (wordToNat w') * 2
+ | WS true w' => S (wordToNat w' * 2)
+ end.
+
+Fixpoint wordToNat' sz (w : word sz) : nat :=
+ match w with
+ | WO => O
+ | WS false w' => 2 * wordToNat w'
+ | WS true w' => S (2 * wordToNat w')
+ end.
+
+Fixpoint natToWord (sz n : nat) : word sz :=
+ match sz with
+ | O => WO
+ | S sz' => WS (mod2 n) (natToWord sz' (div2 n))
+ end.
+
+Fixpoint wordToN sz (w : word sz) : N :=
+ match w with
+ | WO => 0
+ | WS false w' => 2 * wordToN w'
+ | WS true w' => N.succ (2 * wordToN w')
+ end%N.
+
+Definition wzero sz := natToWord sz 0.
+
+Fixpoint wzero' (sz : nat) : word sz :=
+ match sz with
+ | O => WO
+ | S sz' => WS false (wzero' sz')
+ end.
+
+Fixpoint posToWord (sz : nat) (p : positive) {struct p} : word sz :=
+ match sz with
+ | O => WO
+ | S sz' =>
+ match p with
+ | xI p' => WS true (posToWord sz' p')
+ | xO p' => WS false (posToWord sz' p')
+ | xH => WS true (wzero' sz')
+ end
+ end.
+
+Definition NToWord (sz : nat) (n : N) : word sz :=
+ match n with
+ | N0 => wzero' sz
+ | Npos p => posToWord sz p
+ end.
+
+Definition wone sz := natToWord sz 1.
+
+Fixpoint wones (sz : nat) : word sz :=
+ match sz with
+ | O => WO
+ | S sz' => WS true (wones sz')
+ end.
+
+(** * MSB, LSB, head, and tail *)
+
+Fixpoint wmsb sz (w : word sz) (a : bool) : bool :=
+ match w with
+ | WO => a
+ | WS b x => wmsb x b
+ end.
+
+Definition wlsb sz (w: word (S sz)) :=
+ match w with
+ | WO => idProp
+ | WS b _ => b
+ end.
+
+Definition whd sz (w : word (S sz)) : bool :=
+ match w in word sz' return match sz' with
+ | O => unit
+ | S _ => bool
+ end with
+ | WO => tt
+ | WS b _ => b
+ end.
+
+Definition wtl sz (w : word (S sz)) : word sz :=
+ match w in word sz' return match sz' with
+ | O => unit
+ | S sz'' => word sz''
+ end with
+ | WO => tt
+ | WS _ w' => w'
+ end.
+
+Fixpoint rep_bit (n : nat) (b : word 1) : word n :=
+ match n as n0 return (word n0) with
+ | 0 => WO
+ | S n0 => WS (whd b) (rep_bit n0 b)
+ end.
+
+(** * Shattering (to define [weq]) and decidable equality **)
+
+Lemma shatter_word : forall n (a : word n),
+ match n return word n -> Prop with
+ | O => fun a => a = WO
+ | S _ => fun a => a = WS (whd a) (wtl a)
+ end a.
+ destruct a; eauto.
+Qed.
+
+Lemma shatter_word_S : forall n (a : word (S n)),
+ exists b, exists c, a = WS b c.
+Proof.
+ intros n a; repeat eexists; apply (shatter_word a).
+Qed.
+Lemma shatter_word_0 : forall a : word 0,
+ a = WO.
+Proof.
+ intros a; apply (shatter_word a).
+Qed.
+
+Hint Resolve shatter_word_0.
+
+Definition weq : forall sz (x y : word sz), {x = y} + {x <> y}.
+ refine (fix weq sz (x : word sz) : forall y : word sz, {x = y} + {x <> y} :=
+ match x in word sz return forall y : word sz, {x = y} + {x <> y} with
+ | WO => fun _ => left _ _
+ | WS b x' => fun y => if bool_dec b (whd y)
+ then if weq _ x' (wtl y) then left _ _ else right _ _
+ else right _ _
+ end); clear weq.
+
+ abstract (symmetry; apply shatter_word_0).
+
+ abstract (subst; symmetry; apply (shatter_word (n:=S _) _)).
+
+ let y' := y in (* kludge around warning of mechanically generated names not playing well with [abstract] *)
+ abstract (rewrite (shatter_word y'); simpl; intro H; injection H; intros;
+ eauto using inj_pair2_eq_dec, eq_nat_dec).
+
+ let y' := y in (* kludge around warning of mechanically generated names not playing well with [abstract] *)
+ abstract (rewrite (shatter_word y'); simpl; intro H; injection H; auto).
+Defined.
+
+Fixpoint weqb sz (x : word sz) : word sz -> bool :=
+ match x in word sz return word sz -> bool with
+ | WO => fun _ => true
+ | WS b x' => fun y =>
+ if eqb b (whd y)
+ then if @weqb _ x' (wtl y) then true else false
+ else false
+ end.
+
+(** * Combining and splitting *)
+
+Fixpoint combine (sz1 : nat) (w : word sz1) : forall sz2, word sz2 -> word (sz1 + sz2) :=
+ match w in word sz1 return forall sz2, word sz2 -> word (sz1 + sz2) with
+ | WO => fun _ w' => w'
+ | WS b w' => fun _ w'' => WS b (combine w' w'')
+ end.
+
+Fixpoint split1 (sz1 sz2 : nat) : word (sz1 + sz2) -> word sz1 :=
+ match sz1 with
+ | O => fun _ => WO
+ | S sz1' => fun w => WS (whd w) (split1 sz1' sz2 (wtl w))
+ end.
+
+Fixpoint split2 (sz1 sz2 : nat) : word (sz1 + sz2) -> word sz2 :=
+ match sz1 with
+ | O => fun w => w
+ | S sz1' => fun w => split2 sz1' sz2 (wtl w)
+ end.
+
+(** * Extension operators *)
+
+Definition sext (sz : nat) (w : word sz) (sz' : nat) : word (sz + sz') :=
+ if wmsb w false then
+ combine w (wones sz')
+ else
+ combine w (wzero sz').
+
+Definition zext (sz : nat) (w : word sz) (sz' : nat) : word (sz + sz') :=
+ combine w (wzero sz').
+
+(** * Arithmetic *)
+
+Definition wneg sz (x : word sz) : word sz :=
+ NToWord sz (Npow2 sz - wordToN x).
+
+Definition wordBin (f : N -> N -> N) sz (x y : word sz) : word sz :=
+ NToWord sz (f (wordToN x) (wordToN y)).
+
+Definition wplus := wordBin Nplus.
+Definition wmult := wordBin Nmult.
+Definition wdiv := wordBin N.div.
+Definition wmod := wordBin Nmod.
+Definition wmult' sz (x y : word sz) : word sz :=
+ split2 sz sz (NToWord (sz + sz) (Nmult (wordToN x) (wordToN y))).
+Definition wminus sz (x y : word sz) : word sz := wplus x (wneg y).
+Definition wnegN sz (x : word sz) : word sz :=
+ natToWord sz (pow2 sz - wordToNat x).
+
+Definition wordBinN (f : nat -> nat -> nat) sz (x y : word sz) : word sz :=
+ natToWord sz (f (wordToNat x) (wordToNat y)).
+
+Definition wplusN := wordBinN plus.
+
+Definition wmultN := wordBinN mult.
+Definition wmultN' sz (x y : word sz) : word sz :=
+ split2 sz sz (natToWord (sz + sz) (mult (wordToNat x) (wordToNat y))).
+
+Definition wminusN sz (x y : word sz) : word sz := wplusN x (wnegN y).
+
+Notation "w ~ 1" := (WS true w)
+ (at level 7, left associativity, format "w '~' '1'") : word_scope.
+Notation "w ~ 0" := (WS false w)
+ (at level 7, left associativity, format "w '~' '0'") : word_scope.
+
+Notation "^~" := wneg.
+Notation "l ^+ r" := (@wplus _ l%word r%word) (at level 50, left associativity).
+Notation "l ^* r" := (@wmult _ l%word r%word) (at level 40, left associativity).
+Notation "l ^- r" := (@wminus _ l%word r%word) (at level 50, left associativity).
+Notation "l ^/ r" := (@wdiv _ l%word r%word) (at level 50, left associativity).
+Notation "l ^% r" := (@wmod _ l%word r%word) (at level 50, left associativity).
+
+(** * Bitwise operators *)
+
+Fixpoint wnot sz (w : word sz) : word sz :=
+ match w with
+ | WO => WO
+ | WS b w' => WS (negb b) (wnot w')
+ end.
+
+Fixpoint bitwp (f : bool -> bool -> bool) sz (w1 : word sz) : word sz -> word sz :=
+ match w1 with
+ | WO => fun _ => WO
+ | WS b w1' => fun w2 => WS (f b (whd w2)) (bitwp f w1' (wtl w2))
+ end.
+
+Definition wnot' sz := bitwp xorb (wones sz).
+
+Definition wor := bitwp orb.
+Definition wand := bitwp andb.
+Definition wxor := bitwp xorb.
+
+Notation "l ^| r" := (@wor _ l%word r%word) (at level 50, left associativity).
+Notation "l ^& r" := (@wand _ l%word r%word) (at level 40, left associativity).
+
+(** * Conversion to and from [Z] *)
+
+Definition wordToZ sz (w : word sz) : Z :=
+ if wmsb w false then
+ (** Negative **)
+ match wordToN (wneg w) with
+ | N0 => 0%Z
+ | Npos x => Zneg x
+ end
+ else
+ (** Positive **)
+ match wordToN w with
+ | N0 => 0%Z
+ | Npos x => Zpos x
+ end.
+
+Definition uwordToZ sz (w : word sz) : Z := Z.of_N (wordToN w).
+
+Definition ZToWord (sz : nat) (z : Z) : word sz :=
+ match z with
+ | Z0 => wzero' sz
+ | Zpos x => posToWord sz x
+ | Zneg x => wneg (posToWord sz x)
+ end.
+
+(** * Arithmetic by [Z] *)
+
+Definition wordBinZ (f : Z -> Z -> Z) sz (x y : word sz) : word sz :=
+ ZToWord sz (f (wordToZ x) (wordToZ y)).
+
+Definition wplusZ := wordBinZ Z.add.
+Definition wminusZ := wordBinZ Z.sub.
+Definition wmultZ := wordBinZ Z.mul.
+Definition wmultZsu sz (x y : word sz) :=
+ ZToWord sz (Z.mul (wordToZ x) (Z.of_N (wordToN y))).
+Definition wdivZ := wordBinZ Z.quot.
+Definition wdivZsu sz (x y : word sz) :=
+ ZToWord sz (Z.div (wordToZ x) (Z.of_N (wordToN y))).
+Definition wremZ := wordBinZ Z.rem.
+Definition wremZsu sz (x y : word sz) :=
+ ZToWord sz (Z.modulo (wordToZ x) (Z.of_N (wordToN y))).
+
+(** * Comparison predicates and deciders *)
+
+Definition wlt sz (l r : word sz) : Prop :=
+ N.lt (wordToN l) (wordToN r).
+Definition wslt sz (l r : word sz) : Prop :=
+ Z.lt (wordToZ l) (wordToZ r).
+
+Notation "w1 > w2" := (@wlt _ w2%word w1%word) : word_scope.
+Notation "w1 >= w2" := (~(@wlt _ w1%word w2%word)) : word_scope.
+Notation "w1 < w2" := (@wlt _ w1%word w2%word) : word_scope.
+Notation "w1 <= w2" := (~(@wlt _ w2%word w1%word)) : word_scope.
+
+Notation "w1 '>s' w2" := (@wslt _ w2%word w1%word) (at level 70, w2 at next level) : word_scope.
+Notation "w1 '>s=' w2" := (~(@wslt _ w1%word w2%word)) (at level 70, w2 at next level) : word_scope.
+Notation "w1 '<s' w2" := (@wslt _ w1%word w2%word) (at level 70, w2 at next level) : word_scope.
+Notation "w1 '<s=' w2" := (~(@wslt _ w2%word w1%word)) (at level 70, w2 at next level) : word_scope.
+
+Definition wlt_dec : forall sz (l r : word sz), {l < r} + {l >= r}.
+ refine (fun sz l r =>
+ match N.compare (wordToN l) (wordToN r) as k return N.compare (wordToN l) (wordToN r) = k -> _ with
+ | Lt => fun pf => left _ _
+ | _ => fun pf => right _ _
+ end (refl_equal _));
+ abstract congruence.
+Defined.
+
+Definition wslt_dec : forall sz (l r : word sz), {l <s r} + {l >s= r}.
+ refine (fun sz l r =>
+ match Z.compare (wordToZ l) (wordToZ r) as c return Z.compare (wordToZ l) (wordToZ r) = c -> _ with
+ | Lt => fun pf => left _ _
+ | _ => fun pf => right _ _
+ end (refl_equal _));
+ abstract congruence.
+Defined.
+
+Definition wltb{sz: nat}(l r: word sz): bool := BinNat.N.ltb (wordToN l) (wordToN r).
+
+Definition wsltb{sz: nat}(l r: word sz): bool := Z.ltb (wordToZ l) (wordToZ r).
+
+Notation "$ n" := (natToWord _ n) (at level 0).
+Notation "# n" := (wordToNat n) (at level 0).
+
+(** * Bit shifting *)
+
+Fact sz_minus_nshift : forall sz nshift, (nshift < sz)%nat -> sz = sz - nshift + nshift.
+Proof.
+ intros; omega.
+Qed.
+
+Fact nshift_plus_nkeep : forall sz nshift, (nshift < sz)%nat -> nshift + (sz - nshift) = sz.
+Proof.
+ intros; omega.
+Qed.
+
+Definition wlshift (sz : nat) (w : word sz) (n : nat) : word sz.
+ refine (split1 sz n _).
+ rewrite plus_comm.
+ exact (combine (wzero n) w).
+Defined.
+
+Definition wrshift (sz : nat) (w : word sz) (n : nat) : word sz.
+ refine (split2 n sz _).
+ rewrite plus_comm.
+ exact (combine w (wzero n)).
+Defined.
+
+Definition wrshifta (sz : nat) (w : word sz) (n : nat) : word sz.
+ refine (split2 n sz _).
+ rewrite plus_comm.
+ exact (sext w _).
+Defined.
+
+(* Redefine shifts so that they do not use eq_rect, which matches on add_comm,
+ which is an opaque proof, which makes cbv blow up.
+ If you ever want to reduce terms inside Coq with cbv, you should use the
+ shifts below! *)
+
+Definition wlshift' {sz : nat} (w : word sz) (n : nat) : word sz.
+ refine (split1 sz n (nat_cast _ _ _)).
+ apply PeanoNat.Nat.add_comm.
+ exact (combine (wzero n) w).
+Defined.
+
+Definition wrshift' {sz : nat} (w : word sz) (n : nat) : word sz.
+ refine (split2 n sz (nat_cast _ _ _)).
+ apply PeanoNat.Nat.add_comm.
+ exact (combine w (wzero n)).
+Defined.
+
+Definition wrshifta' {sz : nat} (w : word sz) (n : nat) : word sz.
+ refine (split2 n sz (nat_cast _ _ _)).
+ apply PeanoNat.Nat.add_comm.
+ exact (sext w _).
+Defined.
+
+Definition extz {sz} (w: word sz) (n: nat) := combine (wzero n) w.
+
+Fixpoint wpow2 sz: word (S sz) :=
+ match sz with
+ | O => WO~1
+ | S sz' => (wpow2 sz')~0
+ end.
+
+Notation "l ^<< r" := (@wlshift _ _ l%word r%word) (at level 35).
+Notation "l ^>> r" := (@wrshift _ _ l%word r%word) (at level 35).
+
+(** * Setting an individual bit *)
+
+Definition wbit sz sz' (n : word sz') := natToWord sz (pow2 (wordToNat n)).
+
+
+(*! Facts *)
+
+Hint Rewrite div2_double div2_S_double: div2.
+Local Hint Resolve mod2_S_double mod2_double.
+
+Theorem eq_rect_word_offset : forall n n' offset w Heq,
+ eq_rect n (fun n => word (offset + n)) w n' Heq =
+ eq_rect (offset + n) (fun n => word n) w (offset + n') (eq_rect_word_offset_helper _ _ _ Heq).
+Proof.
+ intros.
+ destruct Heq.
+ rewrite (UIP_dec eq_nat_dec (eq_rect_word_offset_helper _ _ offset eq_refl) eq_refl).
+ reflexivity.
+Qed.
+
+Theorem eq_rect_word_mult : forall n n' scale w Heq,
+ eq_rect n (fun n => word (n * scale)) w n' Heq =
+ eq_rect (n * scale) (fun n => word n) w (n' * scale) (eq_rect_word_mult_helper _ _ _ Heq).
+Proof.
+ intros.
+ destruct Heq.
+ rewrite (UIP_dec eq_nat_dec (eq_rect_word_mult_helper _ _ scale eq_refl) eq_refl).
+ reflexivity.
+Qed.
+
+Theorem eq_rect_word_match : forall n n' (w : word n) (H : n = n'),
+ match H in (_ = N) return (word N) with
+ | eq_refl => w
+ end = eq_rect n (fun n => word n) w n' H.
+Proof.
+ intros.
+ destruct H.
+ rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Theorem whd_match : forall n n' (w : word (S n)) (Heq : S n = S n'),
+ whd w = whd (match Heq in (_ = N) return (word N) with
+ | eq_refl => w
+ end).
+Proof.
+ intros.
+ rewrite eq_rect_word_match.
+ generalize dependent w.
+ remember Heq as Heq'. clear HeqHeq'.
+ generalize dependent Heq'.
+ replace (n') with (n) by omega.
+ intros. rewrite <- (eq_rect_eq_dec eq_nat_dec). reflexivity.
+Qed.
+
+Theorem wtl_match : forall n n' (w : word (S n)) (Heq : S n = S n') (Heq' : n = n'),
+ (match Heq' in (_ = N) return (word N) with
+ | eq_refl => wtl w
+ end) = wtl (match Heq in (_ = N) return (word N) with
+ | eq_refl => w
+ end).
+Proof.
+ intros.
+ repeat match goal with
+ | [ |- context[match ?pf with refl_equal => _ end] ] => generalize pf
+ end.
+ generalize dependent w; clear.
+ intros.
+ generalize Heq Heq'.
+ subst.
+ intros.
+ rewrite (UIP_dec eq_nat_dec Heq' (refl_equal _)).
+ rewrite (UIP_dec eq_nat_dec Heq0 (refl_equal _)).
+ reflexivity.
+Qed.
+
+Theorem word0: forall (w : word 0), w = WO.
+Proof.
+ firstorder.
+Qed.
+
+Theorem wordToNat_wordToNat' : forall sz (w : word sz),
+ wordToNat w = wordToNat' w.
+Proof.
+ induction w. auto. unfold wordToNat. simpl. rewrite mult_comm. reflexivity.
+Qed.
+
+Theorem natToWord_wordToNat : forall sz w, natToWord sz (wordToNat w) = w.
+ induction w as [|b]; rewrite wordToNat_wordToNat'; intuition; f_equal; unfold natToWord, wordToNat'; fold natToWord; fold wordToNat';
+ destruct b; f_equal; autorewrite with div2; intuition.
+Qed.
+
+Theorem roundTrip_0 : forall sz, wordToNat (natToWord sz 0) = 0.
+ induction sz; simpl; intuition.
+Qed.
+
+Hint Rewrite roundTrip_0 : wordToNat.
+
+Lemma wordToNat_natToWord' : forall sz w, exists k, wordToNat (natToWord sz w) + k * pow2 sz = w.
+ induction sz as [|sz IHsz]; simpl; intro w; intuition; repeat rewrite untimes2.
+
+ exists w; intuition.
+
+ case_eq (mod2 w); intro Hmw.
+
+ specialize (IHsz (div2 w)); firstorder.
+ rewrite wordToNat_wordToNat' in *.
+ let x' := match goal with H : _ + ?x * _ = _ |- _ => x end in
+ rename x' into x. (* force non-auto-generated name *)
+ exists x; intuition.
+ rewrite mult_assoc.
+ rewrite (mult_comm x 2).
+ rewrite mult_comm. simpl mult at 1.
+ rewrite (plus_Sn_m (2 * wordToNat' (natToWord sz (div2 w)))).
+ rewrite <- mult_assoc.
+ rewrite <- mult_plus_distr_l.
+ rewrite H; clear H.
+ symmetry; apply div2_odd; auto.
+
+ specialize (IHsz (div2 w)); firstorder.
+ let x' := match goal with H : _ + ?x * _ = _ |- _ => x end in
+ rename x' into x. (* force non-auto-generated name *)
+ exists x; intuition.
+ rewrite mult_assoc.
+ rewrite (mult_comm x 2).
+ rewrite <- mult_assoc.
+ rewrite mult_comm.
+ rewrite <- mult_plus_distr_l.
+ match goal with H : _ |- _ => rewrite H; clear H end.
+ symmetry; apply div2_even; auto.
+Qed.
+
+Theorem wordToNat_natToWord:
+ forall sz w, exists k, wordToNat (natToWord sz w) = w - k * pow2 sz /\ (k * pow2 sz <= w)%nat.
+Proof.
+ intros sz w; destruct (wordToNat_natToWord' sz w) as [k]; exists k; intuition.
+Qed.
+
+Lemma wordToNat_natToWord_2: forall sz w : nat,
+ (w < pow2 sz)%nat -> wordToNat (natToWord sz w) = w.
+Proof.
+ intros.
+ pose proof (wordToNat_natToWord sz w).
+ destruct H0; destruct H0.
+ rewrite H0 in *; clear H0.
+ destruct x; try omega.
+ exfalso; simpl in H1.
+
+ pose proof (Lt.le_lt_trans _ _ _ H1 H).
+ pose proof (Plus.le_plus_l (pow2 sz) (x * pow2 sz)).
+ pose proof (Lt.le_lt_trans _ _ _ H2 H0).
+ omega.
+Qed.
+
+Lemma natToWord_times2: forall sz x,
+ ((natToWord sz x)~0)%word = natToWord (S sz) (2 * x).
+Proof.
+ intros. unfold natToWord. fold natToWord. f_equal.
+ - symmetry. apply mod2_double.
+ - rewrite div2_double. reflexivity.
+Qed.
+
+Theorem WS_neq : forall b1 b2 sz (w1 w2 : word sz),
+ (b1 <> b2 \/ w1 <> w2)
+ -> WS b1 w1 <> WS b2 w2.
+ intros b1 b2 sz w1 w2 ? H0; intuition.
+ apply (f_equal (@whd _)) in H0; tauto.
+ apply (f_equal (@wtl _)) in H0; tauto.
+Qed.
+
+Theorem weqb_true_iff : forall sz x y,
+ @weqb sz x y = true <-> x = y.
+Proof.
+ induction x as [|b ? x IHx]; simpl; intros y.
+ { split; auto. }
+ { rewrite (shatter_word y) in *. simpl in *.
+ case_eq (eqb b (whd y)); intros H.
+ case_eq (weqb x (wtl y)); intros H0.
+ split; auto; intros. rewrite eqb_true_iff in H. f_equal; eauto. eapply IHx; eauto.
+ split; intros H1; try congruence. inversion H1; clear H1; subst.
+ eapply inj_pair2_eq_dec in H4. eapply IHx in H4. congruence.
+ eapply Peano_dec.eq_nat_dec.
+ split; intros; try congruence.
+ inversion H0. apply eqb_false_iff in H. congruence. }
+Qed.
+
+Ltac shatterer := simpl; intuition;
+ match goal with
+ | [ w : _ |- _ ] => rewrite (shatter_word w); simpl
+ end; f_equal; auto.
+
+Theorem combine_split : forall sz1 sz2 (w : word (sz1 + sz2)),
+ combine (split1 sz1 sz2 w) (split2 sz1 sz2 w) = w.
+ induction sz1; shatterer.
+Qed.
+
+Theorem split1_combine : forall sz1 sz2 (w : word sz1) (z : word sz2),
+ split1 sz1 sz2 (combine w z) = w.
+ induction sz1; shatterer.
+Qed.
+
+Theorem split2_combine : forall sz1 sz2 (w : word sz1) (z : word sz2),
+ split2 sz1 sz2 (combine w z) = z.
+ induction sz1; shatterer.
+Qed.
+
+Hint Rewrite combine_split.
+Hint Rewrite split1_combine.
+Hint Rewrite split2_combine.
+
+Theorem combine_assoc : forall n1 (w1 : word n1) n2 n3 (w2 : word n2) (w3 : word n3) Heq,
+ combine (combine w1 w2) w3
+ = match Heq in _ = N return word N with
+ | refl_equal => combine w1 (combine w2 w3)
+ end.
+ induction w1 as [|?? w1 IHw1]; simpl; intros n2 n3 w2 w3 Heq; intuition.
+
+ rewrite (UIP_dec eq_nat_dec Heq (refl_equal _)); reflexivity.
+
+ rewrite (IHw1 _ _ _ _ (plus_assoc _ _ _)); clear IHw1.
+ repeat match goal with
+ | [ |- context[match ?pf with refl_equal => _ end] ] => generalize pf
+ end.
+ generalize dependent (combine w1 (combine w2 w3)).
+ rewrite plus_assoc; intros w Heq0 e.
+ rewrite (UIP_dec eq_nat_dec e (refl_equal _)).
+ rewrite (UIP_dec eq_nat_dec Heq0 (refl_equal _)).
+ reflexivity.
+Qed.
+
+Theorem split1_iter : forall n1 n2 n3 Heq w,
+ split1 n1 n2 (split1 (n1 + n2) n3 w)
+ = split1 n1 (n2 + n3) (match Heq in _ = N return word N with
+ | refl_equal => w
+ end).
+Proof.
+ induction n1; simpl; intuition.
+
+ f_equal.
+ apply whd_match.
+ assert (n1 + n2 + n3 = n1 + (n2 + n3)) as Heq' by omega.
+ rewrite IHn1 with (Heq:=Heq').
+ f_equal.
+ apply wtl_match.
+Qed.
+
+Theorem split2_iter : forall n1 n2 n3 Heq w,
+ split2 n2 n3 (split2 n1 (n2 + n3) w)
+ = split2 (n1 + n2) n3 (match Heq in _ = N return word N with
+ | refl_equal => w
+ end).
+ induction n1 as [|n1 IHn1]; simpl; intros n2 n3 Heq w; intuition.
+
+ rewrite (UIP_dec eq_nat_dec Heq (refl_equal _)); reflexivity.
+
+ rewrite (IHn1 _ _ (plus_assoc _ _ _)).
+ f_equal.
+ apply wtl_match.
+Qed.
+
+Theorem split1_split2 : forall n1 n2 n3 Heq w,
+ split1 n2 n3 (split2 n1 (n2 + n3) w) =
+ split2 n1 n2 (split1 (n1 + n2) n3 (match Heq in _ = N return word N with
+ | refl_equal => w
+ end)).
+Proof.
+ induction n1; simpl; intros.
+
+ rewrite (UIP_dec eq_nat_dec Heq (refl_equal _)).
+ reflexivity.
+
+ rewrite (shatter_word w).
+ simpl.
+ assert (n1 + (n2 + n3) = n1 + n2 + n3) as Heq' by omega.
+ rewrite <- wtl_match with (Heq':=Heq').
+ rewrite <- IHn1.
+ f_equal.
+Qed.
+
+Theorem split2_split1 : forall n1 n2 n3 Heq w,
+ split2 n1 n2 (split1 (n1+n2) n3 w) =
+ split1 n2 n3 (split2 n1 (n2+n3) (match Heq in _ = N return word N with
+ | refl_equal => w
+ end)).
+Proof.
+ induction n1; simpl; intros.
+
+ rewrite (UIP_dec eq_nat_dec Heq (refl_equal _)).
+ reflexivity.
+
+ rewrite (shatter_word w).
+ simpl.
+ assert (n1 + n2 + n3 = n1 + (n2 + n3)) as Heq' by omega.
+ rewrite <- wtl_match with (Heq':=Heq').
+ rewrite <- IHn1.
+ f_equal.
+Qed.
+
+Theorem combine_0_n : forall sz2 (w: word 0) (v: word sz2),
+ combine w v = v.
+Proof.
+ intros.
+ replace w with WO.
+ auto.
+ rewrite word0; auto.
+Qed.
+
+Lemma WS_eq_rect : forall b n (w: word n) n' H H',
+ eq_rect _ word (@WS b n w) _ H = @WS b n' (eq_rect _ word w _ H').
+Proof.
+ destruct n; intros; subst;
+ eq_rect_simpl; auto.
+Qed.
+
+Theorem combine_eq_rect2 : forall sz n n'
+ (H: n = n') H'
+ (a: word sz) (b: word n),
+ combine a b =
+ eq_rect _ word (combine a (eq_rect _ word b _ H)) _ H'.
+Proof.
+ induction a; simpl; intros.
+ eq_rect_simpl; auto.
+ erewrite WS_eq_rect.
+ erewrite IHa.
+ auto.
+
+ Grab Existential Variables.
+ omega.
+Qed.
+
+Theorem combine_n_0 : forall sz1 (w : word sz1) (v : word 0),
+ combine w v = eq_rect _ word w _ (plus_n_O sz1).
+Proof.
+ induction w; intros.
+ - replace v with WO; auto.
+ - simpl; rewrite IHw.
+ erewrite WS_eq_rect.
+ reflexivity.
+Qed.
+
+Lemma whd_eq_rect : forall n w Heq,
+ whd (eq_rect (S n) word w (S (n + 0)) Heq) =
+ whd w.
+Proof.
+ intros.
+ generalize Heq.
+ replace (n + 0) with n by omega.
+ intros.
+ f_equal.
+ eq_rect_simpl.
+ reflexivity.
+Qed.
+
+Lemma wtl_eq_rect : forall n w Heq Heq',
+ wtl (eq_rect (S n) word w (S (n + 0)) Heq) =
+ eq_rect n word (wtl w) (n + 0) Heq'.
+Proof.
+ intros.
+ generalize dependent Heq.
+ rewrite <- Heq'; simpl; intros.
+ rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Lemma whd_eq_rect_mul : forall n w Heq,
+ whd (eq_rect (S n) word w (S (n * 1)) Heq) =
+ whd w.
+Proof.
+ intros.
+ generalize Heq.
+ replace (n * 1) with n by auto.
+ intros.
+ eq_rect_simpl.
+ reflexivity.
+Qed.
+
+Lemma wtl_eq_rect_mul : forall n w b Heq Heq',
+ wtl (eq_rect (S n) word (WS b w) (S (n * 1)) Heq) =
+ eq_rect _ word w _ Heq'.
+Proof.
+ intros.
+ generalize Heq.
+ rewrite <- Heq'.
+ intros. eq_rect_simpl.
+ reflexivity.
+Qed.
+
+Theorem split1_0 : forall n w Heq,
+ split1 n 0 (eq_rect _ word w _ Heq) = w.
+Proof.
+ intros.
+ induction n; intros.
+ shatterer.
+ simpl.
+ erewrite wtl_eq_rect.
+ rewrite IHn.
+ rewrite whd_eq_rect.
+ simpl.
+ shatterer.
+
+ Grab Existential Variables.
+ omega.
+Qed.
+
+Theorem split2_0 : forall n w Heq,
+ split2 0 n (eq_rect _ word w _ Heq) = w.
+Proof.
+ intros.
+ simpl.
+ eq_rect_simpl.
+ reflexivity.
+Qed.
+
+Theorem combine_end : forall n1 n2 n3 Heq w,
+ combine (split1 n2 n3 (split2 n1 (n2 + n3) w))
+ (split2 (n1 + n2) n3 (match Heq in _ = N return word N with
+ | refl_equal => w
+ end))
+ = split2 n1 (n2 + n3) w.
+ induction n1 as [|n1 IHn1]; simpl; intros n2 n3 Heq w.
+
+ rewrite (UIP_dec eq_nat_dec Heq (refl_equal _)).
+ apply combine_split.
+
+ rewrite (shatter_word w) in *.
+ simpl.
+ eapply trans_eq; [ | apply IHn1 with (Heq := plus_assoc _ _ _) ]; clear IHn1.
+ repeat f_equal.
+ repeat match goal with
+ | [ |- context[match ?pf with refl_equal => _ end] ] => generalize pf
+ end.
+ simpl.
+ generalize dependent w.
+ rewrite plus_assoc.
+ intros.
+ rewrite (UIP_dec eq_nat_dec e (refl_equal _)).
+ rewrite (UIP_dec eq_nat_dec Heq0 (refl_equal _)).
+ reflexivity.
+Qed.
+
+Theorem eq_rect_combine : forall n1 n2 n2' (w1 : word n1) (w2 : word n2') Heq,
+ eq_rect (n1 + n2') (fun n => word n)
+ (combine w1 w2) (n1 + n2) Heq =
+ combine w1 (eq_rect n2' (fun n => word n) w2 n2 (plus_reg_l _ _ _ Heq)).
+Proof.
+ intros.
+ generalize (plus_reg_l n2' n2 n1 Heq); intros.
+ generalize dependent Heq.
+ generalize dependent w2.
+ rewrite e; intros.
+ repeat rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Lemma eq_rect_combine_assoc' : forall a b c H wa wb wc,
+ eq_rect (a + (b + c)) word (combine wa (combine wb wc)) _ H = combine (combine wa wb) wc.
+Proof.
+ intros.
+ erewrite combine_assoc, eq_rect_word_match.
+ reflexivity.
+Qed.
+
+Lemma eq_rect_split2_helper : forall a b c,
+ a = b -> c + a = c + b.
+Proof.
+ intros; omega.
+Qed.
+
+Theorem eq_rect_split2 : forall n1 n2 n2' (w : word (n1 + n2')) Heq,
+ eq_rect n2' (fun n => word n)
+ (split2 n1 n2' w) n2 Heq =
+ split2 n1 n2 (eq_rect (n1+n2') (fun n => word n) w (n1+n2) (eq_rect_split2_helper _ Heq)).
+Proof.
+ intros.
+ generalize (eq_rect_split2_helper n1 Heq); intros.
+ generalize dependent Heq.
+ generalize dependent w.
+ assert (n2' = n2) as H' by omega.
+ generalize dependent e.
+ rewrite H'; intros.
+ repeat rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Theorem eq_rect_split2_eq2 : forall n1 n2 n2' (w : word (n1 + n2)) Heq Heq2,
+ eq_rect n2 (fun n => word n)
+ (split2 n1 n2 w) n2' Heq =
+ split2 n1 n2' (eq_rect (n1+n2) (fun n => word n) w (n1+n2') Heq2).
+Proof.
+ intros.
+ assert (H' := Heq).
+ generalize dependent w.
+ generalize dependent Heq.
+ generalize dependent Heq2.
+ rewrite H'; intros.
+ repeat rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Theorem eq_rect_split2_eq1 : forall n1 n1' n2 (w: word (n1 + n2)) Heq,
+ split2 n1 n2 w = split2 n1' n2
+ (eq_rect (n1 + n2) (fun y : nat => word y) w
+ (n1' + n2) Heq).
+Proof.
+ intros.
+ assert (n1 = n1') as H' by omega.
+ generalize dependent w.
+ generalize dependent Heq.
+ rewrite H'; intros.
+ rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Theorem combine_split_eq_rect2 : forall n1 n2 n2' (w : word (n1 + n2)) Heq,
+ combine (split1 n1 n2 w)
+ (eq_rect n2 (fun n => word n) (split2 n1 n2 w)
+ n2' Heq) =
+ eq_rect (n1 + n2) (fun n => word n) w
+ (n1 + n2') (eq_rect_split2_helper _ Heq).
+Proof.
+ intros.
+ assert (n2 = n2') by omega.
+ generalize dependent Heq.
+ generalize dependent w.
+ rewrite <- H; intros.
+ repeat rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ apply combine_split.
+Qed.
+
+Lemma eq_rect_split1_helper : forall a b c,
+ a = b -> a + c = b + c.
+Proof.
+ intros; omega.
+Qed.
+
+Lemma eq_rect_split1_eq2_helper : forall a b c,
+ a = b -> c + a = c + b.
+Proof.
+ intros; omega.
+Qed.
+
+Theorem eq_rect_split1 : forall n1 n1' n2 (w : word (n1' + n2)) Heq,
+ eq_rect n1' (fun n => word n)
+ (split1 n1' n2 w) n1 Heq =
+ split1 n1 n2 (eq_rect (n1'+n2) (fun n => word n) w (n1+n2) (eq_rect_split1_helper _ Heq)).
+Proof.
+ intros.
+ generalize (eq_rect_split1_helper n2 Heq); intros.
+ generalize dependent Heq.
+ generalize dependent w.
+ assert (n1' = n1) as H' by omega.
+ generalize dependent e.
+ rewrite H'; intros.
+ repeat rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Theorem eq_rect_split1_eq1 : forall n1 n1' n2 (w : word (n1 + n2)) Heq Heq1,
+ eq_rect n1 (fun n => word n)
+ (split1 n1 n2 w) n1' Heq =
+ split1 n1' n2 (eq_rect (n1+n2) (fun n => word n) w (n1'+n2) Heq1).
+Proof.
+ intros.
+ generalize dependent w.
+ generalize dependent Heq1.
+ rewrite Heq; intros.
+ repeat rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Lemma split1_eq_rect_eq1_helper : forall a b c, b = a -> a + c = b + c.
+Proof. intros. subst. reflexivity. Qed.
+
+Theorem split1_eq_rect_eq1 : forall a a' b H w,
+ split1 a b w = eq_rect _ word (split1 a' b
+ (eq_rect _ word w _ (split1_eq_rect_eq1_helper b H))) _ H.
+Proof.
+ intros a a' b H.
+ subst a'; intros; eq_rect_simpl; auto.
+Qed.
+
+Theorem eq_rect_split1_eq2 : forall n1 n2 n2' (w: word (n1 + n2)) Heq,
+ split1 n1 n2 w = split1 n1 n2'
+ (eq_rect (n1 + n2) (fun y : nat => word y) w
+ (n1 + n2') Heq).
+Proof.
+ intros.
+ assert (n2 = n2') as H' by omega.
+ generalize dependent w.
+ generalize dependent Heq.
+ rewrite H'; intros.
+ rewrite <- (eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Fact eq_rect_combine_dist_helper1 : forall a b c d, b * c = d -> (a + b) * c = a * c + d.
+Proof. intros; subst. apply Nat.mul_add_distr_r. Qed.
+
+Fact eq_rect_combine_dist_helper2 : forall a b c d, b * c = d -> a * c + d = (a + b) * c.
+Proof. intros; subst. symmetry; apply Nat.mul_add_distr_r. Qed.
+
+Theorem eq_rect_combine_dist : forall a b c d (w : word ((a + b) * c)) (H : b * c = d),
+ b * c = d ->
+ let H1 := (eq_rect_combine_dist_helper1 a b c H) in
+ let H2 := (eq_rect_combine_dist_helper2 a b c H) in
+ let w' := eq_rec ((a + b) * c) word w _ H1 in
+ w = eq_rec _ word (combine (split1 (a * c) d w') (split2 (a * c) d w')) _ H2.
+Proof.
+ intros.
+ subst d.
+ rewrite combine_split.
+ eq_rect_simpl.
+ generalize dependent w.
+ generalize dependent H2.
+ rewrite H1.
+ intros.
+ eq_rect_simpl; auto.
+Qed.
+
+Lemma wzero_dist : forall a b c H,
+ wzero ((a + b) * c) = eq_rect _ word (wzero (a * c + b * c)) _ H.
+Proof.
+ intros a b c H.
+ rewrite H.
+ reflexivity.
+Qed.
+
+Lemma wzero_rev : forall (a b : nat) H,
+ wzero (a + b) = eq_rect _ word (wzero (b + a)) _ H.
+Proof. intros a b H. rewrite H. auto. Qed.
+
+Lemma split1_zero : forall sz1 sz2, split1 sz1 sz2 (natToWord _ O) = natToWord _ O.
+Proof.
+ induction sz1; auto; simpl; intros.
+ f_equal. eauto.
+Qed.
+
+Lemma split2_zero : forall sz1 sz2, split2 sz1 sz2 (natToWord _ O) = natToWord _ O.
+Proof.
+ induction sz1; auto.
+Qed.
+
+Theorem combine_inj : forall sz1 sz2 a b c d,
+ @combine sz1 a sz2 b = @combine sz1 c sz2 d -> a = c /\ b = d.
+Proof.
+ induction sz1; simpl; intros.
+ - rewrite (word0 a) in *.
+ rewrite (word0 c) in *.
+ simpl in *.
+ intuition.
+ - rewrite (shatter_word a) in *.
+ rewrite (shatter_word c) in *.
+ simpl in *.
+ inversion H.
+ apply (inj_pair2_eq_dec _ eq_nat_dec) in H2.
+ destruct (IHsz1 _ _ _ _ _ H2).
+ intuition.
+ f_equal; auto.
+Qed.
+
+Theorem combine_wzero : forall sz1 sz2, combine (wzero sz1) (wzero sz2) = wzero (sz1 + sz2).
+Proof.
+ induction sz1; auto.
+ unfold wzero in *.
+ intros; simpl; f_equal; auto.
+Qed.
+
+Theorem combine_wones : forall sz1 sz2, combine (wones sz1) (wones sz2) = wones (sz1 + sz2).
+Proof.
+ induction sz1; auto.
+ intros; simpl; f_equal; auto.
+Qed.
+
+Theorem wordToN_nat : forall sz (w : word sz), wordToN w = N_of_nat (wordToNat w).
+Proof.
+ induction w; intuition.
+ destruct b; unfold wordToN, wordToNat; fold wordToN; fold wordToNat.
+
+ rewrite N_of_S.
+ rewrite N_of_mult.
+ rewrite <- IHw.
+ rewrite Nmult_comm.
+ reflexivity.
+
+ rewrite N_of_mult.
+ rewrite <- IHw.
+ rewrite Nmult_comm.
+ reflexivity.
+Qed.
+
+Lemma wordToN_to_nat sz: forall (w: word sz), BinNat.N.to_nat (wordToN w) = wordToNat w.
+Proof.
+ intros.
+ rewrite wordToN_nat.
+ rewrite Nnat.Nat2N.id.
+ reflexivity.
+Qed.
+
+Local Hint Extern 1 (@eq nat _ _) => omega.
+
+Theorem mod2_S : forall n k,
+ 2 * k = S n
+ -> mod2 n = true.
+ induction n as [n] using strong; intros.
+ destruct n; simpl in *.
+ elimtype False; omega.
+ destruct n; simpl in *; auto.
+ destruct k as [|k]; simpl in *.
+ discriminate.
+ apply H with k; auto.
+Qed.
+
+Theorem wzero'_def : forall sz, wzero' sz = wzero sz.
+ unfold wzero; induction sz; simpl; intuition.
+ congruence.
+Qed.
+
+Theorem posToWord_nat : forall p sz, posToWord sz p = natToWord sz (nat_of_P p).
+ induction p as [ p IHp | p IHp | ]; destruct sz; simpl; intuition; f_equal; try rewrite wzero'_def in *.
+
+ rewrite ZL6.
+ destruct (ZL4 p) as [x Heq]; rewrite Heq; simpl.
+ replace (x + S x) with (S (2 * x)) by omega.
+ symmetry; apply mod2_S_double.
+
+ rewrite IHp.
+ rewrite ZL6.
+ destruct (nat_of_P p); simpl; intuition.
+ replace (n + S n) with (S (2 * n)) by omega.
+ rewrite div2_S_double; auto.
+
+ unfold nat_of_P; simpl.
+ rewrite ZL6.
+ replace (nat_of_P p + nat_of_P p) with (2 * nat_of_P p) by omega.
+ symmetry; apply mod2_double.
+
+ rewrite IHp.
+ unfold nat_of_P; simpl.
+ rewrite ZL6.
+ replace (nat_of_P p + nat_of_P p) with (2 * nat_of_P p) by omega.
+ rewrite div2_double.
+ auto.
+ auto.
+Qed.
+
+Lemma posToWord_sz0: forall p, posToWord 0 p = $0.
+Proof.
+ intros. unfold posToWord. destruct p; reflexivity.
+Qed.
+
+Theorem NToWord_nat : forall sz n, NToWord sz n = natToWord sz (nat_of_N n).
+ destruct n; simpl; intuition; try rewrite wzero'_def in *.
+ auto.
+ apply posToWord_nat.
+Qed.
+
+Theorem wplus_alt : forall sz (x y : word sz), wplus x y = wplusN x y.
+ unfold wplusN, wplus, wordBinN, wordBin; intros.
+
+ repeat rewrite wordToN_nat; repeat rewrite NToWord_nat.
+ rewrite nat_of_Nplus.
+ repeat rewrite nat_of_N_of_nat.
+ reflexivity.
+Qed.
+
+Theorem wmult_alt : forall sz (x y : word sz), wmult x y = wmultN x y.
+ unfold wmultN, wmult, wordBinN, wordBin; intros.
+
+ repeat rewrite wordToN_nat; repeat rewrite NToWord_nat.
+ rewrite nat_of_Nmult.
+ repeat rewrite nat_of_N_of_nat.
+ reflexivity.
+Qed.
+
+Theorem wneg_alt : forall sz (x : word sz), wneg x = wnegN x.
+ unfold wnegN, wneg; intros.
+ repeat rewrite wordToN_nat; repeat rewrite NToWord_nat.
+ rewrite nat_of_Nminus.
+ do 2 f_equal.
+ apply Npow2_nat.
+ apply nat_of_N_of_nat.
+Qed.
+
+Theorem wminus_Alt : forall sz (x y : word sz), wminus x y = wminusN x y.
+ intros; unfold wminusN, wminus; rewrite wneg_alt; apply wplus_alt.
+Qed.
+
+Theorem wplus_unit : forall sz (x : word sz), natToWord sz 0 ^+ x = x.
+ intros; rewrite wplus_alt; unfold wplusN, wordBinN; intros.
+ rewrite roundTrip_0; apply natToWord_wordToNat.
+Qed.
+
+Theorem wplus_comm : forall sz (x y : word sz), x ^+ y = y ^+ x.
+ intros; repeat rewrite wplus_alt; unfold wplusN, wordBinN; f_equal; auto.
+Qed.
+
+Theorem drop_sub :
+ forall sz n k,
+ (k * pow2 sz <= n)%nat ->
+ natToWord sz (n - k * pow2 sz) = natToWord sz n.
+Proof.
+ induction sz as [|sz IHsz]; simpl; intros n k *; intuition; repeat rewrite untimes2 in *; f_equal.
+
+ rewrite mult_assoc.
+ rewrite (mult_comm k).
+ rewrite <- mult_assoc.
+ apply drop_mod2.
+ rewrite mult_assoc.
+ rewrite (mult_comm 2).
+ rewrite <- mult_assoc.
+ auto.
+
+ rewrite <- (IHsz (div2 n) k).
+ rewrite mult_assoc.
+ rewrite (mult_comm k).
+ rewrite <- mult_assoc.
+ rewrite div2_minus_2.
+ reflexivity.
+ rewrite mult_assoc.
+ rewrite (mult_comm 2).
+ rewrite <- mult_assoc.
+ auto.
+
+ apply div2_bound.
+ rewrite mult_assoc.
+ rewrite (mult_comm 2).
+ rewrite <- mult_assoc.
+ auto.
+Qed.
+
+Local Hint Extern 1 (_ <= _)%nat => omega.
+
+Theorem wplus_assoc : forall sz (x y z : word sz), x ^+ (y ^+ z) = x ^+ y ^+ z.
+ intros sz x y z *; repeat rewrite wplus_alt; unfold wplusN, wordBinN; intros.
+
+ repeat match goal with
+ | [ |- context[wordToNat (natToWord ?sz ?w)] ] =>
+ let Heq := fresh "Heq" in
+ destruct (wordToNat_natToWord sz w) as [? [Heq ?]]; rewrite Heq
+ end.
+
+ match goal with
+ | [ |- context[wordToNat ?x + wordToNat ?y - ?x1 * pow2 ?sz + wordToNat ?z] ]
+ => replace (wordToNat x + wordToNat y - x1 * pow2 sz + wordToNat z)
+ with (wordToNat x + wordToNat y + wordToNat z - x1 * pow2 sz) by auto
+ end.
+ match goal with
+ | [ |- context[wordToNat ?x + (wordToNat ?y + wordToNat ?z - ?x0 * pow2 ?sz)] ]
+ => replace (wordToNat x + (wordToNat y + wordToNat z - x0 * pow2 sz))
+ with (wordToNat x + wordToNat y + wordToNat z - x0 * pow2 sz) by auto
+ end.
+ repeat rewrite drop_sub; auto.
+Qed.
+
+Theorem roundTrip_1 : forall sz, wordToNat (natToWord (S sz) 1) = 1.
+ induction sz; simpl in *; intuition.
+Qed.
+
+Theorem mod2_WS : forall sz (x : word sz) b, mod2 (wordToNat (WS b x)) = b.
+ intros sz x b. rewrite wordToNat_wordToNat'.
+ destruct b; simpl.
+
+ rewrite untimes2.
+ case_eq (2 * wordToNat x); intuition.
+ eapply mod2_S; eauto.
+ rewrite <- (mod2_double (wordToNat x)); f_equal; omega.
+Qed.
+
+Theorem div2_WS : forall sz (x : word sz) b, div2 (wordToNat (WS b x)) = wordToNat x.
+ destruct b; rewrite wordToNat_wordToNat'; unfold wordToNat'; fold wordToNat'.
+ apply div2_S_double.
+ apply div2_double.
+Qed.
+
+Theorem wmult_unit : forall sz (x : word sz), natToWord sz 1 ^* x = x.
+ intros sz x; rewrite wmult_alt; unfold wmultN, wordBinN; intros.
+ destruct sz; simpl.
+ rewrite (shatter_word x); reflexivity.
+ rewrite roundTrip_0; simpl.
+ rewrite plus_0_r.
+ rewrite (shatter_word x).
+ f_equal.
+
+ apply mod2_WS.
+
+ rewrite div2_WS.
+ apply natToWord_wordToNat.
+Qed.
+
+Theorem wmult_comm : forall sz (x y : word sz), x ^* y = y ^* x.
+ intros; repeat rewrite wmult_alt; unfold wmultN, wordBinN; auto with arith.
+Qed.
+
+Theorem wmult_unit_r : forall sz (x : word sz), x ^* natToWord sz 1 = x.
+Proof.
+ intros.
+ rewrite wmult_comm.
+ apply wmult_unit.
+Qed.
+
+Lemma wmult_neut_l: forall (sz : nat) (x : word sz), $0 ^* x = $0.
+Proof.
+ intros. unfold wmult. unfold wordBin. do 2 rewrite wordToN_nat.
+ rewrite <- Nnat.Nat2N.inj_mul. rewrite roundTrip_0.
+ rewrite Nat.mul_0_l. simpl. rewrite wzero'_def. reflexivity.
+Qed.
+
+Lemma wmult_neut_r: forall (sz : nat) (x : word sz), x ^* $0 = $0.
+Proof.
+ intros. unfold wmult. unfold wordBin. do 2 rewrite wordToN_nat.
+ rewrite <- Nnat.Nat2N.inj_mul. rewrite roundTrip_0.
+ rewrite Nat.mul_0_r. simpl. rewrite wzero'_def. reflexivity.
+Qed.
+
+Theorem wmult_assoc : forall sz (x y z : word sz), x ^* (y ^* z) = x ^* y ^* z.
+ intros sz x y z; repeat rewrite wmult_alt; unfold wmultN, wordBinN; intros.
+
+ repeat match goal with
+ | [ |- context[wordToNat (natToWord ?sz ?w)] ] =>
+ let Heq := fresh "Heq" in
+ destruct (wordToNat_natToWord sz w) as [? [Heq ?]]; rewrite Heq
+ end.
+
+ rewrite mult_minus_distr_l.
+ rewrite mult_minus_distr_r.
+ match goal with
+ | [ |- natToWord _ (_ - _ * (?x0' * _)) = natToWord _ (_ - ?x1' * _ * _) ]
+ => rename x0' into x0, x1' into x1 (* force the names to not be autogenerated *)
+ end.
+ rewrite (mult_assoc (wordToNat x) x0).
+ rewrite <- (mult_assoc x1).
+ rewrite (mult_comm (pow2 sz)).
+ rewrite (mult_assoc x1).
+ repeat rewrite drop_sub; auto with arith.
+ rewrite (mult_comm x1).
+ rewrite <- (mult_assoc (wordToNat x)).
+ rewrite (mult_comm (wordToNat y)).
+ rewrite mult_assoc.
+ rewrite (mult_comm (wordToNat x)).
+ repeat rewrite <- mult_assoc.
+ auto with arith.
+ repeat rewrite <- mult_assoc.
+ auto with arith.
+Qed.
+
+Theorem wmult_plus_distr : forall sz (x y z : word sz), (x ^+ y) ^* z = (x ^* z) ^+ (y ^* z).
+ intros sz x y z; repeat rewrite wmult_alt; repeat rewrite wplus_alt; unfold wmultN, wplusN, wordBinN; intros.
+
+ repeat match goal with
+ | [ |- context[wordToNat (natToWord ?sz ?w)] ] =>
+ let Heq := fresh "Heq" in
+ destruct (wordToNat_natToWord sz w) as [? [Heq ?]]; rewrite Heq
+ end.
+
+ rewrite mult_minus_distr_r.
+ match goal with
+ | [ |- natToWord _ (_ - ?x0' * _ * _) = natToWord _ (_ - ?x1' * _ + (_ - ?x2' * _)) ]
+ => rename x0' into x0, x1' into x1, x2' into x2 (* force the names to not be autogenerated *)
+ end.
+ rewrite <- (mult_assoc x0).
+ rewrite (mult_comm (pow2 sz)).
+ rewrite (mult_assoc x0).
+
+ replace (wordToNat x * wordToNat z - x1 * pow2 sz +
+ (wordToNat y * wordToNat z - x2 * pow2 sz))
+ with (wordToNat x * wordToNat z + wordToNat y * wordToNat z - x1 * pow2 sz - x2 * pow2 sz).
+ repeat rewrite drop_sub; auto with arith.
+ rewrite (mult_comm x0).
+ rewrite (mult_comm (wordToNat x + wordToNat y)).
+ rewrite <- (mult_assoc (wordToNat z)).
+ auto with arith.
+ generalize dependent (wordToNat x * wordToNat z).
+ generalize dependent (wordToNat y * wordToNat z).
+ intros.
+ omega.
+Qed.
+
+Theorem wminus_def : forall sz (x y : word sz), x ^- y = x ^+ ^~ y.
+ reflexivity.
+Qed.
+
+Theorem wordToNat_bound : forall sz (w : word sz), (wordToNat w < pow2 sz)%nat.
+ induction w as [|b]; simpl; intuition.
+ destruct b; simpl; omega.
+Qed.
+
+Theorem natToWord_pow2 : forall sz, natToWord sz (pow2 sz) = natToWord sz 0.
+ induction sz as [|sz]; simpl; intuition.
+
+ generalize (div2_double (pow2 sz)); simpl; intro Hr; rewrite Hr; clear Hr.
+ f_equal.
+ generalize (mod2_double (pow2 sz)); auto.
+ auto.
+Qed.
+
+Theorem wminus_inv : forall sz (x : word sz), x ^+ ^~ x = wzero sz.
+ intros sz x; rewrite wneg_alt; rewrite wplus_alt; unfold wnegN, wplusN, wzero, wordBinN; intros.
+
+ repeat match goal with
+ | [ |- context[wordToNat (natToWord ?sz ?w)] ] =>
+ let Heq := fresh "Heq" in
+ destruct (wordToNat_natToWord sz w) as [? [Heq ?]]; rewrite Heq
+ end.
+
+ match goal with
+ | [ |- context[wordToNat ?x + (pow2 ?sz - wordToNat ?x - ?x0 * pow2 ?sz)] ]
+ => replace (wordToNat x + (pow2 sz - wordToNat x - x0 * pow2 sz))
+ with (pow2 sz - x0 * pow2 sz)
+ end.
+ rewrite drop_sub; auto with arith.
+ apply natToWord_pow2.
+ generalize (wordToNat_bound x).
+ omega.
+Qed.
+
+Definition wring (sz : nat) : ring_theory (wzero sz) (wone sz) (@wplus sz) (@wmult sz) (@wminus sz) (@wneg sz) (@eq _) :=
+ mk_rt _ _ _ _ _ _ _
+ (@wplus_unit _) (@wplus_comm _) (@wplus_assoc _)
+ (@wmult_unit _) (@wmult_comm _) (@wmult_assoc _)
+ (@wmult_plus_distr _) (@wminus_def _) (@wminus_inv _).
+
+Theorem weqb_sound : forall sz (x y : word sz), weqb x y = true -> x = y.
+Proof.
+ eapply weqb_true_iff.
+Qed.
+
+Arguments weqb_sound : clear implicits.
+
+Lemma weqb_eq: forall sz (a b: word sz), a = b -> weqb a b = true.
+Proof. intros. rewrite weqb_true_iff. assumption. Qed.
+
+Lemma weqb_ne: forall sz (a b: word sz), a <> b -> weqb a b = false.
+Proof.
+ intros. destruct (weqb a b) eqn: E.
+ - rewrite weqb_true_iff in E. contradiction.
+ - reflexivity.
+Qed.
+
+Ltac is_nat_cst n :=
+ match eval hnf in n with
+ | O => constr:(true)
+ | S ?n' => is_nat_cst n'
+ | _ => constr:(false)
+ end.
+
+Ltac isWcst w :=
+ match eval hnf in w with
+ | WO => constr:(true)
+ | WS ?b ?w' =>
+ match eval hnf in b with
+ | true => isWcst w'
+ | false => isWcst w'
+ | _ => constr:(false)
+ end
+ | natToWord _ ?n => is_nat_cst n
+ | _ => constr:(false)
+ end.
+
+Ltac wcst w :=
+ let b := isWcst w in
+ match b with
+ | true => w
+ | _ => constr:(NotConstant)
+ end.
+
+(* Here's how you can add a ring for a specific bit-width.
+ There doesn't seem to be a polymorphic method, so this code really does need to be copied. *)
+
+(*
+Definition wring8 := wring 8.
+Add Ring wring8 : wring8 (decidable (weqb_sound 8), constants [wcst]).
+*)
+
+Ltac noptac x := idtac.
+
+Ltac PackWring sz F :=
+ let RNG := (fun proj => proj
+ inv_morph_nothing inv_morph_nothing noptac noptac
+ (word sz) (@eq (word sz)) (wzero sz) (wone sz)
+ (@wplus sz) (@wmult sz) (@wminus sz) (@wneg sz)
+ (BinNums.Z) (BinNums.N) (id_phi_N)
+ (pow_N (wone sz) (@wmult sz))
+ (ring_correct (@Eqsth (word sz))
+ (Eq_ext _ _ _)
+ (Rth_ARth (@Eqsth (word sz)) (Eq_ext _ _ _) (wring sz))
+ (gen_phiZ_morph (@Eqsth (word sz)) (Eq_ext _ _ _) (wring sz))
+ (pow_N_th _ _ (@Eqsth (word sz)))
+ (triv_div_th (@Eqsth (word sz))
+ (Eq_ext _ _ _)
+ (Rth_ARth (@Eqsth (word sz)) (Eq_ext _ _ _) (wring sz))
+ (gen_phiZ_morph (@Eqsth (word sz)) (Eq_ext _ _ _) (wring sz)))
+ )
+ tt) in
+ F RNG (@nil (word sz)) (@nil (word sz)).
+
+Ltac ring_sz sz := PackWring sz Ring_gen.
+
+Fact bitwp_wtl : forall sz (w w' : word (S sz)) op, bitwp op (wtl w) (wtl w') = wtl (bitwp op w w').
+Proof.
+ intros.
+ rewrite (shatter_word w), (shatter_word w').
+ auto.
+Qed.
+
+Lemma split1_bitwp_dist : forall sz1 sz2 w w' op,
+ split1 sz1 sz2 (bitwp op w w') = bitwp op (split1 sz1 sz2 w) (split1 sz1 sz2 w').
+Proof.
+ induction sz1; intros; auto.
+ simpl.
+ f_equal.
+ rewrite (shatter_word w), (shatter_word w'); auto.
+ rewrite <- IHsz1, bitwp_wtl.
+ reflexivity.
+Qed.
+
+Lemma split2_bitwp_dist : forall sz1 sz2 w w' op,
+ split2 sz1 sz2 (bitwp op w w') = bitwp op (split2 sz1 sz2 w) (split2 sz1 sz2 w').
+Proof.
+ induction sz1; intros; auto.
+ simpl; rewrite <- IHsz1, bitwp_wtl.
+ reflexivity.
+Qed.
+
+Lemma combine_bitwp : forall sz1 sz2 (wa wa' : word sz1) (wb wb' : word sz2) op,
+ combine (bitwp op wa wa') (bitwp op wb wb') = bitwp op (combine wa wb) (combine wa' wb').
+Proof.
+ induction sz1; intros; rewrite (shatter_word wa), (shatter_word wa'); simpl; f_equal; auto.
+Qed.
+
+Lemma eq_rect_bitwp : forall a b Heq f w1 w2,
+ bitwp f w1 w2 = eq_rect a word (
+ bitwp f (eq_rect b word w1 a Heq) (eq_rect b word w2 a Heq)) b (eq_sym Heq).
+Proof.
+ intros a b H; subst a.
+ intros; eq_rect_simpl; reflexivity.
+Qed.
+
+Fact eq_rect_bitwp' : forall a b Heq f w1 w2,
+ eq_rect b word (bitwp f w1 w2) a Heq = bitwp f (eq_rect b word w1 a Heq) (eq_rect b word w2 a Heq).
+Proof.
+ intros a b H1; subst a.
+ intros; eq_rect_simpl; reflexivity.
+Qed.
+
+Fact eq_rect_bitwp_1 : forall a b Heq f w1 w2,
+ bitwp f (eq_rect a word w1 b Heq) w2 = eq_rect a word (bitwp f w1 (eq_rect b word w2 a (eq_sym Heq))) b Heq.
+Proof.
+ intros a b H.
+ subst a; intros; eq_rect_simpl; auto.
+Qed.
+
+Theorem wnot_wnot'_equiv : forall sz (w : word sz), wnot w = wnot' w.
+Proof.
+ unfold wnot'.
+ induction sz; intros w; shatterer.
+Qed.
+
+Theorem wnot_split1 : forall sz1 sz2 w, wnot (split1 sz1 sz2 w) = split1 sz1 sz2 (wnot w).
+Proof.
+ intros.
+ repeat rewrite wnot_wnot'_equiv.
+ unfold wnot'.
+ erewrite <- split1_combine with (w := wones _).
+ rewrite <- split1_bitwp_dist, combine_wones.
+ reflexivity.
+Qed.
+
+Theorem wnot_split2 : forall sz1 sz2 w, wnot (split2 sz1 sz2 w) = split2 sz1 sz2 (wnot w).
+Proof.
+ intros.
+ repeat rewrite wnot_wnot'_equiv.
+ unfold wnot'.
+ erewrite <- split2_combine with (z := wones _).
+ rewrite <- split2_bitwp_dist, combine_wones.
+ reflexivity.
+Qed.
+
+Theorem wnot_combine : forall sz1 sz2 (w1 : word sz1) (w2 : word sz2),
+ wnot (combine w1 w2) = combine (wnot w1) (wnot w2).
+Proof.
+ intros.
+ repeat rewrite wnot_wnot'_equiv.
+ unfold wnot'.
+ rewrite <- combine_wones, combine_bitwp.
+ reflexivity.
+Qed.
+
+Theorem wnot_zero: forall sz, wnot (wzero sz) = wones sz.
+Proof.
+ induction sz; simpl; f_equal; eauto.
+Qed.
+
+Theorem wnot_ones : forall sz, wnot (wones sz) = wzero sz.
+Proof.
+ induction sz; simpl; f_equal; try rewrite IHsz; eauto.
+Qed.
+
+Theorem wnot_eq_rect : forall a b H (w : word a), wnot (eq_rect a word w b H) = eq_rect a word (wnot w) b H.
+Proof.
+ intros.
+ subst b; eq_rect_simpl; auto.
+Qed.
+
+Theorem wor_unit : forall sz (x : word sz), wzero sz ^| x = x.
+Proof.
+ unfold wzero, wor; induction x; simpl; intuition congruence.
+Qed.
+
+Theorem wor_comm : forall sz (x y : word sz), x ^| y = y ^| x.
+Proof.
+ unfold wor; induction x; intro y; rewrite (shatter_word y); simpl; intuition; f_equal; auto with bool.
+Qed.
+
+Theorem wor_assoc : forall sz (x y z : word sz), x ^| (y ^| z) = x ^| y ^| z.
+Proof.
+ unfold wor; induction x; intro y; rewrite (shatter_word y); simpl; intuition; f_equal; auto with bool.
+Qed.
+
+Theorem wand_unit : forall sz (x : word sz), wones sz ^& x = x.
+Proof.
+ unfold wand; induction x; simpl; intuition congruence.
+Qed.
+
+Theorem wand_kill : forall sz (x : word sz), wzero sz ^& x = wzero sz.
+Proof.
+ unfold wzero, wand; induction x; simpl; intuition congruence.
+Qed.
+
+Theorem wand_comm : forall sz (x y : word sz), x ^& y = y ^& x.
+Proof.
+ unfold wand; induction x; intro y; rewrite (shatter_word y); simpl; intuition; f_equal; auto with bool.
+Qed.
+
+Theorem wand_assoc : forall sz (x y z : word sz), x ^& (y ^& z) = x ^& y ^& z.
+Proof.
+ unfold wand; induction x; intro y; rewrite (shatter_word y); simpl; intuition; f_equal; auto with bool.
+Qed.
+
+Theorem wand_or_distr : forall sz (x y z : word sz), (x ^| y) ^& z = (x ^& z) ^| (y ^& z).
+Proof.
+ unfold wand, wor; induction x; intro y; rewrite (shatter_word y); intro z; rewrite (shatter_word z); simpl; intuition; f_equal; auto with bool.
+ destruct (whd y); destruct (whd z); destruct b; reflexivity.
+Qed.
+
+Lemma wor_wones : forall sz w, wones sz ^| w = wones sz.
+Proof.
+ unfold wor; induction sz; intros; simpl; auto.
+ rewrite IHsz; auto.
+Qed.
+
+Lemma wor_wzero : forall sz w, wzero sz ^| w = w.
+Proof.
+ unfold wor; induction sz; shatterer.
+Qed.
+
+Lemma wand_wones : forall sz w, wones sz ^& w = w.
+Proof.
+ unfold wand; induction sz; shatterer.
+Qed.
+
+Lemma wand_wzero : forall sz w, wzero sz ^& w = wzero sz.
+Proof.
+ intros. rewrite <- wzero'_def.
+ unfold wand; induction sz; shatterer.
+Qed.
+
+Lemma wxor_wones : forall sz w, wxor (wones sz) w = wnot w.
+Proof.
+ unfold wxor; induction sz; shatterer.
+Qed.
+
+Lemma wxor_wzero : forall sz w, wxor (wzero sz) w = w.
+Proof.
+ unfold wxor; induction sz; shatterer; destruct (whd w); auto.
+Qed.
+
+Lemma wxor_comm : forall sz (w1 w2 : word sz), wxor w1 w2 = wxor w2 w1.
+Proof.
+ unfold wxor; induction sz. shatterer.
+ intros. rewrite (shatter_word w1), (shatter_word w2).
+ simpl.
+ rewrite xorb_comm, IHsz.
+ reflexivity.
+Qed.
+
+Lemma wxor_assoc : forall sz (w1 w2 w3 : word sz), wxor w1 (wxor w2 w3) = wxor (wxor w1 w2) w3.
+Proof.
+ unfold wxor.
+ induction sz; intros; rewrite (shatter_word w1), (shatter_word w2), (shatter_word w3); auto.
+ simpl; f_equal.
+ rewrite xorb_assoc_reverse; auto.
+ rewrite IHsz.
+ reflexivity.
+Qed.
+
+Lemma wor_wone : forall sz (w : word sz) b,
+ WS b w ^| wone _ = WS true w.
+Proof.
+ intros.
+ compute [wone natToWord wor]. simpl.
+ fold natToWord.
+ change (natToWord sz 0) with (wzero sz).
+ rewrite orb_true_r.
+ rewrite wor_comm, wor_wzero.
+ reflexivity.
+Qed.
+
+Lemma wand_wone : forall sz (w : word sz) b,
+ WS b w ^& wone _ = WS b (wzero _).
+Proof.
+ intros.
+ compute [wone natToWord wand]. simpl.
+ fold natToWord.
+ change (natToWord sz 0) with (wzero sz).
+ rewrite andb_true_r.
+ rewrite wand_comm, wand_wzero.
+ reflexivity.
+Qed.
+
+Lemma wxor_wone : forall sz (w : word sz) b,
+ wxor (WS b w) (wone _) = WS (negb b) w.
+Proof.
+ intros.
+ compute [wone natToWord wxor]. simpl.
+ fold natToWord.
+ change (natToWord sz 0) with (wzero sz).
+ rewrite xorb_true_r.
+ rewrite wxor_comm, wxor_wzero.
+ reflexivity.
+Qed.
+
+Definition wbring (sz : nat) : semi_ring_theory (wzero sz) (wones sz) (@wor sz) (@wand sz) (@eq _) :=
+ mk_srt _ _ _ _ _
+ (@wor_unit _) (@wor_comm _) (@wor_assoc _)
+ (@wand_unit _) (@wand_kill _) (@wand_comm _) (@wand_assoc _)
+ (@wand_or_distr _).
+
+(** * Inequality proofs *)
+
+Ltac word_simpl := unfold sext, zext, wzero in *; simpl in *.
+
+Ltac word_eq := ring.
+
+Ltac word_eq1 := match goal with
+ | _ => ring
+ | [ H : _ = _ |- _ ] => ring [H]
+ end.
+
+Theorem word_neq : forall sz (w1 w2 : word sz),
+ w1 ^- w2 <> wzero sz
+ -> w1 <> w2.
+ intros; intro; subst.
+ unfold wminus in H.
+ rewrite wminus_inv in H.
+ tauto.
+Qed.
+
+Ltac word_neq := apply word_neq; let H := fresh "H" in intro H; simpl in H; ring_simplify in H; try discriminate.
+
+Ltac word_contra := match goal with
+ | [ H : _ <> _ |- False ] => apply H; ring
+ end.
+
+Ltac word_contra1 := match goal with
+ | [ H : _ <> _ |- False ] => apply H;
+ match goal with
+ | _ => ring
+ | [ H' : _ = _ |- _ ] => ring [H']
+ end
+ end.
+
+Lemma not_wlt_ge : forall sz (l r : word sz),
+ ((l < r) -> False) -> (r <= l).
+Proof.
+ intros.
+ case_eq (wlt_dec l r); intros;
+ try contradiction;
+ auto.
+Qed.
+
+Lemma not_wle_gt : forall sz (l r : word sz),
+ ((l <= r) -> False) -> (r < l).
+Proof.
+ intros.
+ case_eq (wlt_dec r l); intros;
+ try contradiction;
+ auto.
+Qed.
+
+Lemma lt_le : forall sz (a b : word sz),
+ a < b -> a <= b.
+Proof.
+ unfold wlt, N.lt. intros sz a b H H0. rewrite N.compare_antisym in H0. rewrite H in H0. simpl in *. congruence.
+Qed.
+
+Lemma eq_le : forall sz (a b : word sz),
+ a = b -> a <= b.
+Proof.
+ intros; subst. unfold wlt, N.lt. rewrite N.compare_refl. congruence.
+Qed.
+
+Lemma wordToN_inj : forall sz (a b : word sz),
+ wordToN a = wordToN b -> a = b.
+Proof.
+ induction a; intro b0; rewrite (shatter_word b0); intuition.
+ simpl in H.
+ destruct b; destruct (whd b0); intros.
+ f_equal. eapply IHa. eapply N.succ_inj in H.
+ destruct (wordToN a); destruct (wordToN (wtl b0)); try congruence.
+ destruct (wordToN (wtl b0)); destruct (wordToN a); inversion H.
+ destruct (wordToN (wtl b0)); destruct (wordToN a); inversion H.
+ f_equal. eapply IHa.
+ destruct (wordToN a); destruct (wordToN (wtl b0)); try congruence.
+Qed.
+
+Lemma wordToNat_inj : forall sz (a b : word sz),
+ wordToNat a = wordToNat b -> a = b.
+Proof.
+ intros; apply wordToN_inj.
+ repeat rewrite wordToN_nat.
+ apply Nat2N.inj_iff; auto.
+Qed.
+
+Lemma unique_inverse : forall sz (a b1 b2 : word sz),
+ a ^+ b1 = wzero _ ->
+ a ^+ b2 = wzero _ ->
+ b1 = b2.
+Proof.
+ intros sz a b1 b2 H *.
+ transitivity (b1 ^+ wzero _).
+ rewrite wplus_comm. rewrite wplus_unit. auto.
+ transitivity (b1 ^+ (a ^+ b2)). congruence.
+ rewrite wplus_assoc.
+ rewrite (wplus_comm b1). rewrite H. rewrite wplus_unit. auto.
+Qed.
+
+Lemma sub_0_eq : forall sz (a b : word sz),
+ a ^- b = wzero _ -> a = b.
+Proof.
+ intros sz a b H. destruct (weq (wneg b) (wneg a)) as [e|n].
+ transitivity (a ^+ (^~ b ^+ b)).
+ rewrite (wplus_comm (^~ b)). rewrite wminus_inv.
+ rewrite wplus_comm. rewrite wplus_unit. auto.
+ rewrite e. rewrite wplus_assoc. rewrite wminus_inv. rewrite wplus_unit. auto.
+ unfold wminus in H.
+ generalize (unique_inverse a (wneg a) (^~ b)).
+ intro H0. elimtype False. apply n. symmetry; apply H0.
+ apply wminus_inv.
+ auto.
+Qed.
+
+Lemma le_neq_lt : forall sz (a b : word sz),
+ b <= a -> a <> b -> b < a.
+Proof.
+ intros sz a b H H0; destruct (wlt_dec b a) as [?|n]; auto.
+ elimtype False. apply H0. unfold wlt, N.lt in *.
+ eapply wordToN_inj. eapply Ncompare_eq_correct.
+ case_eq ((wordToN a ?= wordToN b)%N); auto; try congruence.
+ intros H1. rewrite N.compare_antisym in n. rewrite H1 in n. simpl in *. congruence.
+Qed.
+
+
+Hint Resolve word_neq lt_le eq_le sub_0_eq le_neq_lt : worder.
+
+Ltac shatter_word x :=
+ match type of x with
+ | word 0 => try rewrite (shatter_word_0 x) in *
+ | word (S ?N) =>
+ let x' := fresh in
+ let H := fresh in
+ destruct (@shatter_word_S N x) as [ ? [ x' H ] ];
+ rewrite H in *; clear H; shatter_word x'
+ end.
+
+
+(** Uniqueness of equality proofs **)
+Lemma rewrite_weq : forall sz (a b : word sz)
+ (pf : a = b),
+ weq a b = left _ pf.
+Proof.
+ intros sz a b *; destruct (weq a b); try solve [ elimtype False; auto ].
+ f_equal.
+ eapply UIP_dec. eapply weq.
+Qed.
+
+
+(** * Some more useful derived facts *)
+
+Lemma natToWord_plus : forall sz n m, natToWord sz (n + m) = natToWord _ n ^+ natToWord _ m.
+ destruct sz as [|sz]; intros n m; intuition.
+ rewrite wplus_alt.
+ unfold wplusN, wordBinN.
+ destruct (wordToNat_natToWord (S sz) n); intuition.
+ destruct (wordToNat_natToWord (S sz) m); intuition.
+ do 2 match goal with H : _ |- _ => rewrite H; clear H end.
+ match goal with
+ | [ |- context[?n - ?x * pow2 (S ?sz) + (?m - ?x0 * pow2 (S ?sz))] ]
+ => replace (n - x * pow2 (S sz) + (m - x0 * pow2 (S sz))) with (n + m - x * pow2 (S sz) - x0 * pow2 (S sz))
+ by omega
+ end.
+ repeat rewrite drop_sub; auto; omega.
+Qed.
+
+Lemma natToWord_S : forall sz n, natToWord sz (S n) = natToWord _ 1 ^+ natToWord _ n.
+ intros sz n; change (S n) with (1 + n); apply natToWord_plus.
+Qed.
+
+Theorem natToWord_inj : forall sz n m, natToWord sz n = natToWord sz m
+ -> (n < pow2 sz)%nat
+ -> (m < pow2 sz)%nat
+ -> n = m.
+ intros sz n m H H0 H1.
+ apply (f_equal (@wordToNat _)) in H.
+ destruct (wordToNat_natToWord sz n) as [x H2].
+ destruct (wordToNat_natToWord sz m) as [x0 H3].
+ intuition.
+ match goal with
+ | [ H : wordToNat ?x = wordToNat ?y, H' : wordToNat ?x = ?a, H'' : wordToNat ?y = ?b |- _ ]
+ => let H0 := fresh in assert (H0 : a = b) by congruence; clear H H' H''; rename H0 into H
+ end.
+ assert (x = 0).
+ destruct x; auto.
+ simpl in *.
+ generalize dependent (x * pow2 sz).
+ intros.
+ omega.
+ assert (x0 = 0).
+ destruct x0; auto.
+ simpl in *.
+ generalize dependent (x0 * pow2 sz).
+ intros.
+ omega.
+ subst; simpl in *; omega.
+Qed.
+
+Lemma wordToNat_natToWord_idempotent : forall sz n,
+ (N.of_nat n < Npow2 sz)%N
+ -> wordToNat (natToWord sz n) = n.
+ intros sz n H.
+ destruct (wordToNat_natToWord sz n) as [x]; intuition.
+ destruct x as [|x].
+ simpl in *; omega.
+ simpl in *.
+ apply Nlt_out in H.
+ autorewrite with N in *.
+ rewrite Npow2_nat in *.
+ generalize dependent (x * pow2 sz).
+ intros; omega.
+Qed.
+
+Lemma wplus_cancel : forall sz (a b c : word sz),
+ a ^+ c = b ^+ c
+ -> a = b.
+ intros sz a b c H.
+ apply (f_equal (fun x => x ^+ ^~ c)) in H.
+ repeat rewrite <- wplus_assoc in H.
+ rewrite wminus_inv in H.
+ repeat rewrite (wplus_comm _ (wzero sz)) in H.
+ repeat rewrite wplus_unit in H.
+ assumption.
+Qed.
+
+Lemma wminus_plus_distr:
+ forall {sz} (x y z: word sz), x ^- (y ^+ z) = x ^- y ^- z.
+Proof.
+ intros.
+ apply wplus_cancel with (c:= y ^+ z).
+ rewrite wminus_def, <-wplus_assoc.
+ rewrite wplus_comm with (y:= y ^+ z), wminus_inv.
+ rewrite wplus_comm with (x:= x), wplus_unit.
+ rewrite !wminus_def, <-wplus_assoc.
+ rewrite wplus_assoc with (x:= ^~ z).
+ rewrite wplus_comm with (x:= ^~ z).
+ rewrite <-wplus_assoc with (x:= y).
+ rewrite wplus_comm with (x:= ^~ z), wminus_inv.
+ rewrite wplus_comm with (x:= y), wplus_unit.
+ rewrite <-wplus_assoc.
+ rewrite wplus_comm with (x:= ^~ y), wminus_inv.
+ rewrite wplus_comm, wplus_unit.
+ reflexivity.
+Qed.
+
+Lemma wminus_wplus_undo: forall sz (a b: word sz),
+ a ^- b ^+ b = a.
+Proof.
+ intros.
+ rewrite wminus_def.
+ rewrite <- wplus_assoc.
+ rewrite (wplus_comm (^~ b)).
+ rewrite wminus_inv.
+ rewrite wplus_comm.
+ rewrite wplus_unit.
+ reflexivity.
+Qed.
+
+Lemma wneg_zero:
+ forall {sz} (w: word sz), ^~ w = (natToWord sz 0) -> w = natToWord sz 0.
+Proof.
+ intros.
+ apply wplus_cancel with (c:= ^~ w).
+ rewrite wminus_inv, wplus_unit; auto.
+Qed.
+
+Lemma wneg_idempotent:
+ forall {sz} (w: word sz), ^~ (^~ w) = w.
+Proof.
+ intros.
+ apply sub_0_eq.
+ rewrite wminus_def.
+ rewrite wplus_comm.
+ apply wminus_inv.
+Qed.
+
+Lemma wneg_zero': forall sz,
+ wneg (natToWord sz 0) = natToWord sz 0.
+Proof.
+ intros. apply wneg_zero. apply wneg_idempotent.
+Qed.
+
+Lemma wplus_one_neq: forall {sz} (w: word (S sz)), w ^+ (natToWord (S sz) 1) <> w.
+Proof.
+ intros; intro Hx.
+ rewrite wplus_comm in Hx.
+ assert ((natToWord (S sz) 1) ^+ w ^- w = w ^- w) by (rewrite Hx; reflexivity).
+ clear Hx.
+ do 2 rewrite wminus_def in H.
+ rewrite <-wplus_assoc in H.
+ rewrite wminus_inv in H.
+ rewrite wplus_comm, wplus_unit in H.
+ inversion H.
+Qed.
+
+Lemma wneg_one_pow2_minus_one: forall {sz}, wordToNat (^~ (natToWord sz 1)) = pow2 sz - 1.
+Proof.
+ destruct sz; auto.
+ unfold wneg; intros.
+ rewrite wordToN_nat, roundTrip_1.
+ simpl BinNat.N.of_nat.
+ rewrite NToWord_nat, Nnat.N2Nat.inj_sub, Npow2_nat.
+ apply wordToNat_natToWord_2.
+ pose (pow2_zero (S sz)).
+ omega.
+Qed.
+
+Lemma wones_pow2_minus_one: forall {sz}, wordToNat (wones sz) = pow2 sz - 1.
+Proof.
+ induction sz; simpl; auto.
+ rewrite IHsz; pose (pow2_zero sz).
+ omega.
+Qed.
+
+Lemma pow2_minus_one_wones: forall {sz} (w: word sz),
+ wordToNat w = pow2 sz - 1 -> w = wones sz.
+Proof.
+ intros; rewrite <-wones_pow2_minus_one in H.
+ apply wordToNat_inj; auto.
+Qed.
+
+Lemma wones_natToWord: forall sz,
+ wones sz = $ (pow2 sz - 1).
+Proof.
+ induction sz.
+ - reflexivity.
+ - unfold wones. fold wones. rewrite IHsz.
+ unfold natToWord at 2. fold natToWord. f_equal.
+ + rewrite mod2sub.
+ * simpl. rewrite mod2_pow2_twice. reflexivity.
+ * pose proof (zero_lt_pow2 (S sz)). omega.
+ + f_equal. unfold pow2 at 2. fold pow2.
+ rewrite <- (div2_S_double (pow2 sz - 1)). f_equal.
+ pose proof (zero_lt_pow2 sz). omega.
+Qed.
+
+Lemma wones_wneg_one: forall {sz}, wones sz = ^~ (natToWord sz 1).
+Proof.
+ intros; apply wordToNat_inj.
+ rewrite wneg_one_pow2_minus_one.
+ rewrite wones_pow2_minus_one.
+ reflexivity.
+Qed.
+
+Lemma wordToNat_natToWord_pred:
+ forall {sz} (w: word sz), w <> wzero sz ->
+ pred (wordToNat w) =
+ wordToNat (w ^- (natToWord sz 1)).
+Proof.
+ intros; remember (wordToNat w) as wn; destruct wn; simpl in *.
+ - elim H.
+ apply wordToNat_inj.
+ rewrite roundTrip_0; auto.
+ - apply natToWord_inj with (sz:= sz).
+ + rewrite natToWord_wordToNat.
+ apply wplus_cancel with (c:= (natToWord sz 1)).
+ rewrite wminus_def, <-wplus_assoc.
+ rewrite wplus_comm with (x:= ^~ (natToWord sz 1)).
+ rewrite wminus_inv.
+ rewrite wplus_comm with (x:= w).
+ rewrite wplus_unit.
+ rewrite wplus_comm, <-natToWord_S.
+ apply wordToNat_inj.
+ rewrite wordToNat_natToWord_2; auto.
+ rewrite Heqwn.
+ apply wordToNat_bound.
+ + pose proof (wordToNat_bound w); omega.
+ + apply wordToNat_bound.
+Qed.
+
+Lemma natToWord_mult : forall sz n m, natToWord sz (n * m) = natToWord _ n ^* natToWord _ m.
+Proof.
+ destruct sz; intuition.
+ rewrite wmult_alt.
+ unfold wmultN, wordBinN.
+ destruct (wordToNat_natToWord (S sz) n); intuition.
+ destruct (wordToNat_natToWord (S sz) m); intuition.
+ rewrite H0; rewrite H2; clear H0 H2.
+ replace ((n - x * pow2 (S sz)) * (m - x0 * pow2 (S sz)))
+ with ((n - x * pow2 (S sz)) * m - (n - x * pow2 (S sz)) * (x0 * pow2 (S sz)))
+ by (rewrite Nat.mul_sub_distr_l; auto).
+ rewrite mult_assoc; rewrite drop_sub.
+ repeat rewrite mult_comm with (m:=m).
+ replace (m * (n - x * pow2 (S sz)))
+ with (m * n - m * (x * pow2 (S sz)))
+ by (rewrite Nat.mul_sub_distr_l; auto).
+ rewrite mult_assoc; rewrite drop_sub.
+ auto.
+ rewrite <- mult_assoc; apply Nat.mul_le_mono_l; auto.
+ rewrite <- mult_assoc; apply Nat.mul_le_mono_l; auto.
+Qed.
+
+Lemma wlt_lt: forall sz (a b : word sz), a < b ->
+ (wordToNat a < wordToNat b)%nat.
+Proof.
+ intros.
+ unfold wlt in H.
+ repeat rewrite wordToN_nat in *.
+ apply Nlt_out in H.
+ repeat rewrite Nat2N.id in *.
+ auto.
+Qed.
+
+Lemma wle_le: forall sz (a b : word sz), (a <= b)%word ->
+ (wordToNat a <= wordToNat b)%nat.
+Proof.
+ intros.
+ unfold wlt in H.
+ repeat rewrite wordToN_nat in *.
+ apply Nge_out in H.
+ repeat rewrite Nat2N.id in *.
+ auto.
+Qed.
+
+Lemma wlt_lt': forall sz a b, (a < pow2 sz)%nat
+ -> natToWord sz a < b
+ -> (wordToNat (natToWord sz a) < wordToNat b)%nat.
+Proof.
+ intros.
+ apply wlt_lt.
+ auto.
+Qed.
+
+Lemma lt_word_lt_nat : forall (sz:nat) (n:word sz) (m:nat),
+ (n < (natToWord sz m))%word ->
+ (wordToNat n < m)%nat.
+Proof.
+ intros.
+ apply wlt_lt in H.
+ destruct (wordToNat_natToWord' sz m).
+ rewrite <- H0.
+ apply lt_plus_trans with (p := x * pow2 sz).
+ assumption.
+Qed.
+
+Lemma le_word_le_nat : forall (sz:nat) (n:word sz) (m:nat),
+ (n <= (natToWord sz m))%word ->
+ (wordToNat n <= m)%nat.
+Proof.
+ intros.
+ apply wle_le in H.
+ destruct (wordToNat_natToWord' sz m).
+ rewrite <- H0.
+ apply le_plus_trans with (p := x * pow2 sz).
+ assumption.
+Qed.
+
+(* Chain [lt_word_lt_nat] and [Nat.lt_le_incl]
+ Avoids using [Hint Resolve Nat.lt_le_incl] for this specific lemma,
+ though this may be a premature optimization. *)
+Lemma lt_word_le_nat : forall (sz:nat) (n:word sz) (m:nat),
+ (n < (natToWord sz m))%word ->
+ (wordToNat n <= m)%nat.
+Proof.
+ intros.
+ apply lt_word_lt_nat in H.
+ apply Nat.lt_le_incl.
+ assumption.
+Qed.
+
+Hint Resolve lt_word_le_nat.
+
+Lemma wordToNat_natToWord_idempotent' : forall sz n,
+ (n < pow2 sz)%nat
+ -> wordToNat (natToWord sz n) = n.
+Proof.
+ intros.
+ destruct (wordToNat_natToWord sz n); intuition.
+ destruct x.
+ simpl in *; omega.
+ simpl in *.
+ generalize dependent (x * pow2 sz).
+ intros; omega.
+Qed.
+
+Lemma le_word_le_nat': forall (sz:nat) n m,
+ (n < pow2 sz)%nat ->
+ (natToWord sz n <= m)%word ->
+ (n <= wordToNat m)%nat.
+Proof.
+ intros.
+ apply wle_le in H0.
+ rewrite wordToNat_natToWord_idempotent' in H0; auto.
+Qed.
+
+Lemma wordToNat_natToWord_bound : forall sz n (bound : word sz),
+ (n <= wordToNat bound)%nat
+ -> wordToNat (natToWord sz n) = n.
+Proof.
+ intros.
+ apply wordToNat_natToWord_idempotent'.
+ eapply le_lt_trans; eauto.
+ apply wordToNat_bound.
+Qed.
+
+Lemma wordToNat_natToWord_le : forall sz n,
+ (wordToNat (natToWord sz n) <= n)%nat.
+Proof.
+ intros.
+ case_eq (lt_dec n (pow2 sz)); intros.
+ rewrite wordToNat_natToWord_idempotent'; auto.
+ eapply le_trans.
+ apply Nat.lt_le_incl.
+ apply wordToNat_bound.
+ omega.
+Qed.
+
+Lemma wordToNat_natToWord_lt : forall sz n b,
+ (n < b -> wordToNat (natToWord sz n) < b)%nat.
+Proof.
+ intros.
+ eapply le_lt_trans.
+ apply wordToNat_natToWord_le.
+ auto.
+Qed.
+
+Lemma wordToNat_eq_natToWord : forall sz (w : word sz) n,
+ wordToNat w = n
+ -> w = natToWord sz n.
+Proof.
+ intros. rewrite <- H. rewrite natToWord_wordToNat. auto.
+Qed.
+
+Lemma wlt_lt_bound: forall sz (a : word sz) (b bound : nat),
+ (a < natToWord sz b)%word
+ -> (b <= wordToNat (natToWord sz bound))%nat
+ -> (wordToNat a < b)%nat.
+Proof.
+ intros.
+ apply wlt_lt in H.
+ erewrite wordToNat_natToWord_bound in H; eauto.
+Qed.
+
+Lemma natplus1_wordplus1_eq:
+ forall sz (a bound : word sz),
+ (0 < sz)%nat ->
+ (a < bound)%word ->
+ (wordToNat a) + 1 = wordToNat (a ^+ (natToWord sz 1)).
+Proof.
+ intros.
+ rewrite wplus_alt. unfold wplusN, wordBinN. simpl.
+ assert ((1 < pow2 sz)%nat).
+ inversion H.
+ simpl; auto.
+ apply one_lt_pow2.
+ erewrite wordToNat_natToWord_bound.
+ rewrite wordToNat_natToWord_idempotent' by auto.
+ reflexivity.
+ apply wlt_lt in H0.
+ rewrite wordToNat_natToWord_idempotent' by auto.
+ instantiate (1:=bound). omega.
+Qed.
+
+Lemma lt_wlt: forall sz (n : word sz) m, (wordToNat n < wordToNat m)%nat ->
+ n < m.
+Proof.
+ intros.
+ unfold wlt.
+ repeat rewrite wordToN_nat.
+ apply Nlt_in.
+ repeat rewrite Nat2N.id.
+ auto.
+Qed.
+
+Lemma le_wle: forall sz (n : word sz) m, (wordToNat n <= wordToNat m)%nat ->
+ n <= m.
+Proof.
+ intros.
+ unfold wlt.
+ repeat rewrite wordToN_nat.
+ apply N.le_ngt.
+ apply N.ge_le.
+ apply Nge_in.
+ repeat rewrite Nat2N.id.
+ auto.
+Qed.
+
+Lemma wlt_wle_incl : forall sz (a b : word sz),
+ (a < b)%word -> (a <= b)%word.
+Proof.
+ intros.
+ apply wlt_lt in H.
+ apply le_wle.
+ omega.
+Qed.
+
+Lemma wminus_Alt2: forall sz x y, y <= x ->
+ @wminusN sz x y = wordBinN minus x y.
+Proof.
+ intros.
+ unfold wminusN, wplusN, wnegN, wordBinN.
+ destruct (weq y (natToWord sz 0)); subst.
+
+ rewrite roundTrip_0.
+ repeat rewrite <- minus_n_O.
+ rewrite <- drop_sub with (k:=1) (n:=pow2 sz); try omega.
+ replace (pow2 sz - 1 * pow2 sz) with (0) by omega.
+ rewrite roundTrip_0.
+ rewrite <- plus_n_O.
+ reflexivity.
+
+ rewrite wordToNat_natToWord_idempotent' with (n:=pow2 sz - wordToNat y).
+ rewrite <- drop_sub with (k:=1).
+ simpl.
+ rewrite <- plus_n_O.
+ replace (wordToNat x + (pow2 sz - wordToNat y) - pow2 sz) with (wordToNat x - wordToNat y).
+ auto.
+ rewrite Nat.add_sub_assoc.
+ omega.
+
+ remember (wordToNat_bound y); omega.
+
+ simpl. rewrite <- plus_n_O.
+ rewrite Nat.add_sub_assoc; [| remember (wordToNat_bound y); omega ].
+ rewrite plus_comm.
+ rewrite <- Nat.add_sub_assoc.
+ omega.
+
+ apply Nat.nlt_ge.
+ unfold not in *; intros.
+ apply H.
+ apply lt_wlt; auto.
+
+ apply Nat.sub_lt.
+ remember (wordToNat_bound y); omega.
+
+ assert (wordToNat y <> 0); try omega.
+
+ assert (wordToN y <> wordToN (natToWord sz 0)).
+ unfold not in *. intros. apply n.
+ apply wordToN_inj.
+ auto.
+
+ repeat rewrite wordToN_nat in H0.
+ unfold not in *. intros. apply H0.
+ apply N2Nat.inj.
+ repeat rewrite Nat2N.id.
+ rewrite roundTrip_0.
+ auto.
+Qed.
+
+Theorem wlt_wf:
+ forall sz, well_founded (@wlt sz).
+Proof.
+ intros.
+ eapply well_founded_lt_compat with (f:=@wordToNat sz).
+ apply wlt_lt.
+Qed.
+
+Ltac wlt_ind :=
+ match goal with
+ | [ |- forall (n: word ?len), ?P ] =>
+ refine (well_founded_ind (@wlt_wf len) (fun n => P) _)
+ end.
+
+Theorem wordToNat_plusone: forall sz w w', w < w' ->
+ wordToNat (w ^+ natToWord sz 1) = S (wordToNat w).
+Proof.
+ intros.
+
+ destruct sz.
+ exfalso.
+ rewrite word0 with (w:=w') in H.
+ rewrite word0 with (w:=w) in H.
+ apply wlt_lt in H.
+ omega.
+
+ rewrite wplus_alt.
+ unfold wplusN, wordBinN.
+ rewrite wordToNat_natToWord_idempotent'.
+
+ rewrite roundTrip_1.
+ omega.
+
+ eapply Nat.le_lt_trans; [| apply wordToNat_bound ].
+ rewrite wordToNat_natToWord_idempotent';
+ [| erewrite <- roundTrip_1 at 1; apply wordToNat_bound ].
+ apply wlt_lt in H.
+ instantiate (1:=w').
+ omega.
+Qed.
+
+
+Theorem wordToNat_minus_one': forall sz n, n <> natToWord sz 0 ->
+ S (wordToNat (n ^- natToWord sz 1)) = wordToNat n.
+Proof.
+ intros.
+ destruct sz.
+ rewrite word0 with (w:=n) in H.
+ rewrite word0 with (w:=natToWord 0 0) in H.
+ exfalso; auto.
+
+ destruct (weq n (natToWord (S sz) 0)); intuition.
+ rewrite wminus_Alt.
+ rewrite wminus_Alt2.
+ unfold wordBinN.
+ rewrite roundTrip_1.
+ erewrite wordToNat_natToWord_bound with (bound:=n); try omega.
+ assert (wordToNat n <> 0); try omega.
+ unfold not; intros; apply n0; clear n0.
+ rewrite <- H0; rewrite natToWord_wordToNat; auto.
+ unfold not; intros; apply n0; clear n0.
+ apply wlt_lt in H0.
+ replace n with (natToWord (S sz) (wordToNat n)) by (rewrite natToWord_wordToNat; auto).
+ f_equal; rewrite roundTrip_1 in *.
+ omega.
+Qed.
+
+Theorem wordToNat_minus_one: forall sz n, n <> natToWord sz 0 ->
+ wordToNat (n ^- natToWord sz 1) = wordToNat n - 1.
+Proof.
+ intros.
+ erewrite Nat.succ_inj with (n2 := wordToNat (n ^- (natToWord sz 1))); auto.
+ rewrite wordToNat_minus_one'; auto.
+ assert (wordToNat n <> 0).
+ intuition.
+ erewrite <- roundTrip_0 with (sz := sz) in H0.
+ apply wordToNat_inj in H0; tauto.
+ omega.
+Qed.
+
+Lemma lt_minus : forall a b c,
+ (b <= a -> b < c -> a < c -> a - b < c)%nat.
+Proof.
+ intros; omega.
+Qed.
+
+Lemma wminus_minus : forall sz (a b : word sz),
+ b <= a
+ -> wordToNat (a ^- b) = wordToNat a - wordToNat b.
+Proof.
+ intros.
+ rewrite wminus_Alt.
+ rewrite wminus_Alt2; auto.
+ unfold wordBinN.
+ eapply wordToNat_natToWord_idempotent'.
+ apply lt_minus.
+ apply wle_le; auto.
+ apply wordToNat_bound.
+ apply wordToNat_bound.
+Qed.
+
+Lemma wminus_minus': forall (sz : nat) (a b : word sz),
+ (#b <= #a)%nat ->
+ #(a ^- b) = #a - #b.
+Proof.
+ intros. apply wminus_minus.
+ unfold wlt. intro C.
+ apply Nlt_out in C.
+ rewrite! wordToN_to_nat in *.
+ omega.
+Qed.
+
+Lemma wordToNat_neq_inj: forall sz (a b : word sz),
+ a <> b <-> wordToNat a <> wordToNat b.
+Proof.
+ split; intuition.
+ apply wordToNat_inj in H0; auto.
+ subst; auto.
+Qed.
+
+Lemma natToWord_discriminate: forall sz, (sz > 0)%nat -> natToWord sz 0 <> natToWord sz 1.
+Proof.
+ unfold not.
+ intros.
+ induction sz.
+ omega.
+ unfold natToWord in H0; fold natToWord in H0.
+ discriminate H0.
+Qed.
+
+Definition bit_dec : forall (a : word 1), {a = $0} + {a = $1}.
+ intro.
+ rewrite (shatter_word a).
+ replace (wtl a) with WO by auto.
+ destruct (whd a).
+ right; apply eq_refl.
+ left; apply eq_refl.
+Defined.
+
+Lemma neq0_wneq0: forall sz (n : word sz),
+ wordToNat n <> 0 <-> n <> $0.
+Proof.
+ split; intros.
+ apply wordToNat_neq_inj.
+ rewrite roundTrip_0; auto.
+ apply wordToNat_neq_inj in H.
+ rewrite roundTrip_0 in H; auto.
+Qed.
+
+Lemma gt0_wneq0: forall sz (n : word sz),
+ (wordToNat n > 0)%nat <-> n <> $0.
+Proof.
+ split; intros.
+ apply neq0_wneq0; omega.
+ apply wordToNat_neq_inj in H.
+ rewrite roundTrip_0 in H; omega.
+Qed.
+
+Lemma weq_minus1_wlt: forall sz (a b : word sz),
+ (a <> $0 -> a ^- $1 = b -> a > b)%word.
+Proof.
+ intros.
+ apply lt_wlt; subst.
+ rewrite wordToNat_minus_one; auto.
+ apply gt0_wneq0 in H.
+ omega.
+Qed.
+
+Lemma wordnat_minus1_eq : forall sz n (w : word sz),
+ (n > 0)%nat
+ -> n = wordToNat w
+ -> n - 1 = wordToNat (w ^- $1).
+Proof.
+ intros; rewrite wordToNat_minus_one; auto.
+ apply gt0_wneq0; subst; auto.
+Qed.
+
+Theorem wlshift_0 : forall sz (w : word sz), @wlshift sz w 0 = w.
+Proof.
+ intros.
+ unfold wlshift.
+ eapply split1_0.
+Qed.
+
+Theorem wrshift_0 : forall sz (w : word sz), @wrshift sz w 0 = w.
+Proof.
+ intros.
+ unfold wrshift.
+ simpl.
+ rewrite combine_n_0.
+ eq_rect_simpl. reflexivity.
+Qed.
+
+Theorem wlshift_gt : forall sz n (w : word sz), (n > sz)%nat ->
+ wlshift w n = wzero sz.
+Proof.
+ intros sz n w H.
+ generalize dependent w.
+ remember (n - sz) as e.
+ assert (n = sz + e) by omega; subst n.
+ intros w.
+ unfold wlshift.
+ rewrite <- combine_wzero.
+ erewrite combine_assoc, eq_rect_word_match.
+ eq_rect_simpl.
+ rewrite eq_rect_combine.
+ apply split1_combine.
+ Grab Existential Variables. omega.
+Qed.
+
+Theorem wrshift_gt : forall sz n (w : word sz), (n > sz)%nat ->
+ wrshift w n = wzero sz.
+Proof.
+ intros sz n w H.
+ generalize dependent w.
+ remember (n - sz) as e.
+ assert (n = sz + e) by omega; subst n.
+ intros w.
+ unfold wrshift.
+ erewrite wzero_rev, <- combine_wzero.
+ eq_rect_simpl.
+ rewrite <- eq_rect_word_match, <- eq_rect_combine, eq_rect_word_match.
+ eq_rect_simpl.
+ rewrite eq_rect_combine_assoc', split2_combine.
+ reflexivity.
+ Grab Existential Variables. omega.
+Qed.
+
+Theorem wlshift_bitwp : forall sz (w1 w2 : word sz) f n,
+ wlshift (bitwp f w1 w2) n = split1 sz n (
+ eq_rec _ word (combine (wzero n) (bitwp f w1 w2)) _ (eq_sym (Nat.add_comm sz n))).
+Proof.
+ intros.
+ unfold wlshift.
+ eq_rect_simpl.
+ reflexivity.
+Qed.
+
+Theorem wrshift_bitwp : forall sz (w1 w2 : word sz) f n,
+ wrshift (bitwp f w1 w2) n = split2 n sz (
+ eq_rect _ word (combine (bitwp f w1 w2) (wzero n)) _ (eq_sym (Nat.add_comm n sz))).
+Proof.
+ intros.
+ unfold wrshift.
+ eq_rect_simpl.
+ reflexivity.
+Qed.
+
+Theorem wnot_wlshift : forall sz (w : word sz) n,
+ wnot (wlshift w n) = split1 sz n (eq_rect _ word (combine (wones n) (wnot w)) _ (eq_sym (Nat.add_comm sz n))).
+Proof.
+ intros.
+ unfold wlshift.
+ rewrite wnot_split1.
+ eq_rect_simpl.
+ rewrite wnot_eq_rect.
+ rewrite wnot_combine.
+ rewrite wnot_zero.
+ reflexivity.
+Qed.
+
+Theorem wnot_wrshift : forall sz (w : word sz) n,
+ wnot (wrshift w n) = split2 n sz (eq_rect _ word (combine (wnot w) (wones n)) _ (eq_sym (Nat.add_comm n sz))).
+Proof.
+ intros.
+ unfold wrshift.
+ rewrite wnot_split2.
+ eq_rect_simpl.
+ rewrite wnot_eq_rect.
+ rewrite wnot_combine.
+ rewrite wnot_zero.
+ reflexivity.
+Qed.
+
+Lemma wlshift_alt: forall sz n (a: word sz),
+ wlshift' a n = wlshift a n.
+Proof.
+ intros. unfold wlshift, wlshift'.
+ unfold eq_rec_r.
+ unfold eq_rec.
+ erewrite nat_cast_proof_irrel.
+ rewrite nat_cast_eq_rect.
+ reflexivity.
+Qed.
+
+Theorem div2_pow2_twice: forall n,
+ Nat.div2 (pow2 n + (pow2 n + 0)) = pow2 n.
+Proof.
+ intros.
+ replace (pow2 n + (pow2 n + 0)) with (2 * pow2 n) by omega.
+ rewrite Nat.div2_double.
+ auto.
+Qed.
+
+Theorem zero_or_wordToNat_S: forall sz (n : word sz),
+ n = $0 \/
+ exists nn, wordToNat n = S nn /\ wordToNat (n ^- $1) = nn.
+Proof.
+ intros.
+ destruct sz.
+ left. rewrite (word0 n). auto.
+ destruct (weq n $0); intuition.
+ right.
+ exists (wordToNat (n ^- $1)); intuition.
+ rewrite wminus_Alt.
+ rewrite wminus_Alt2.
+ unfold wordBinN.
+ rewrite roundTrip_1.
+ erewrite wordToNat_natToWord_bound with (bound:=n); try omega.
+ assert (wordToNat n <> 0); try omega.
+ unfold not; intros; apply n0; clear n0.
+ rewrite <- H. rewrite natToWord_wordToNat; auto.
+ unfold not; intros; apply n0; clear n0.
+ apply wlt_lt in H.
+ replace n with (natToWord (S sz) (wordToNat n)) by (rewrite natToWord_wordToNat; auto).
+ f_equal.
+ rewrite roundTrip_1 in *.
+ omega.
+Qed.
+
+Theorem wbit_or_same : forall sz sz' (n : word sz'), (wordToNat n < sz)%nat
+ -> (wbit sz n) ^| (wbit sz n) <> wzero sz.
+Proof.
+ unfold not.
+ induction sz; intros; try omega.
+ unfold wbit, wzero, wor in *.
+ simpl in *.
+ destruct (zero_or_wordToNat_S n).
+ subst; rewrite roundTrip_0 in *. discriminate.
+ destruct H1. destruct H1.
+ rewrite H1 in *.
+ inversion H0.
+ apply (inj_pair2_eq_dec _ eq_nat_dec) in H5.
+ rewrite div2_pow2_twice in H5.
+ repeat rewrite <- H2 in H5.
+ eapply IHsz; eauto.
+ omega.
+Qed.
+
+Theorem wbit_or_other : forall sz sz' (n1 n2 : word sz'), (wordToNat n1 < sz)%nat
+ -> (wordToNat n2 < sz)%nat
+ -> (n1 <> n2)
+ -> (wbit sz n1) ^& (wbit sz n2) = wzero sz.
+Proof.
+ induction sz; intros; try omega.
+ unfold wbit, wzero, wand.
+ simpl.
+ destruct (zero_or_wordToNat_S n1); destruct (zero_or_wordToNat_S n2);
+ try congruence; destruct_conjs; subst; try rewrite roundTrip_0.
+
+ repeat rewrite H4; simpl; repeat rewrite mod2_pow2_twice; f_equal.
+ rewrite wand_kill; auto.
+
+ repeat rewrite H4; simpl; repeat rewrite mod2_pow2_twice; f_equal.
+ rewrite wand_comm; rewrite wand_kill; auto.
+
+ repeat rewrite H4; repeat rewrite H6; simpl.
+ repeat rewrite mod2_pow2_twice; f_equal.
+ repeat rewrite div2_pow2_twice.
+ eapply IHsz; try omega.
+
+ apply word_neq.
+ unfold not in *; intros; apply H1; clear H1.
+ apply sub_0_eq; rewrite <- H2.
+ ring_sz sz'.
+Qed.
+
+Theorem wbit_and_not: forall sz sz' (n : word sz'), (wordToNat n < sz)%nat
+ -> (wbit sz n) ^& wnot (wbit sz n) = wzero sz.
+Proof.
+ induction sz; intros; try omega.
+ unfold wbit, wzero, wand, wnot.
+ simpl.
+ f_equal.
+ apply andb_negb_r.
+
+ destruct (zero_or_wordToNat_S n); subst.
+ rewrite roundTrip_0; simpl.
+ apply wand_kill.
+
+ do 2 destruct H0.
+ rewrite H0; simpl.
+ rewrite div2_pow2_twice.
+ fold wnot.
+ rewrite <- H1.
+ eapply IHsz.
+ omega.
+Qed.
+
+Theorem wbit_and_not_other: forall sz sz' (n1 n2 : word sz'), (wordToNat n1 < sz)%nat
+ -> (wordToNat n2 < sz)%nat
+ -> n1 <> n2
+ -> (wbit sz n1) ^& wnot (wbit sz n2) = wbit sz n1.
+Proof.
+ induction sz; intros; try omega.
+ unfold wbit, wzero, wand, wnot.
+ simpl.
+ destruct (zero_or_wordToNat_S n1); destruct (zero_or_wordToNat_S n2);
+ try congruence; destruct_conjs; subst; fold wnot; try rewrite roundTrip_0; simpl;
+ f_equal.
+
+ rewrite H4; simpl; rewrite mod2_pow2_twice; auto.
+ rewrite H4; simpl; rewrite div2_pow2_twice; apply wand_kill.
+
+ rewrite H4; simpl; rewrite mod2_pow2_twice; auto.
+ rewrite H4; simpl; rewrite div2_pow2_twice.
+ rewrite wnot_zero. rewrite wand_comm. apply wand_unit.
+
+ rewrite H4; simpl; rewrite mod2_pow2_twice; simpl; apply andb_true_r.
+ rewrite H4; rewrite H6; simpl.
+ repeat rewrite div2_pow2_twice.
+ apply IHsz; try omega.
+
+ apply word_neq.
+ unfold not in *; intros; apply H1.
+ apply sub_0_eq.
+ rewrite <- H2.
+ ring_sz sz'.
+Qed.
+
+Lemma wordToNat_wzero:
+ forall sz, wordToNat (wzero sz) = 0.
+Proof.
+ unfold wzero; intros.
+ apply roundTrip_0.
+Qed.
+
+Lemma wordToN_wzero:
+ forall sz, wordToN (wzero sz) = 0%N.
+Proof.
+ intros; rewrite wordToN_nat.
+ rewrite wordToNat_wzero.
+ reflexivity.
+Qed.
+
+Lemma combine_zero:
+ forall n m, combine (natToWord n 0) (natToWord m 0) = natToWord _ 0.
+Proof.
+ induction n; simpl; intros; [reflexivity|].
+ rewrite IHn; reflexivity.
+Qed.
+
+Lemma combine_one:
+ forall n m, combine (natToWord (S n) 1) (natToWord m 0) = natToWord _ 1.
+Proof.
+ cbn; intros.
+ rewrite combine_zero; reflexivity.
+Qed.
+
+Lemma wmsb_wzero':
+ forall sz, wmsb (wzero' sz) false = false.
+Proof. induction sz; auto. Qed.
+
+Lemma wmsb_wzero:
+ forall sz, wmsb (wzero sz) false = false.
+Proof.
+ intros.
+ rewrite <-wzero'_def.
+ apply wmsb_wzero'.
+Qed.
+
+Lemma wmsb_wones:
+ forall sz, wmsb (wones (S sz)) false = true.
+Proof.
+ induction sz; cbn; auto.
+Qed.
+
+Lemma wmsb_0: forall sz (m: word (S sz)) default,
+ (# m < pow2 sz)%nat ->
+ @wmsb (S sz) m default = false.
+Proof.
+ induction sz; intros.
+ - simpl in *. assert (#m = 0) as N by omega.
+ rewrite <- (roundTrip_0 1) in N.
+ apply wordToNat_inj in N. subst m.
+ simpl. reflexivity.
+ - pose proof (shatter_word_S m) as P.
+ destruct P as [b [m0 E]]. subst.
+ unfold wmsb. fold wmsb.
+ apply IHsz.
+ simpl in H. destruct b; omega.
+Qed.
+
+Lemma wmsb_1: forall sz (m: word (S sz)) default,
+ pow2 sz <= # m < 2 * pow2 sz ->
+ @wmsb (S sz) m default = true.
+Proof.
+ induction sz; intros.
+ - simpl in *. assert (#m = 1) as N by omega.
+ rewrite <- (roundTrip_1 1) in N.
+ apply (wordToNat_inj m ($ 1)) in N. subst m.
+ simpl. reflexivity.
+ - pose proof (shatter_word_S m) as P.
+ destruct P as [b [m0 E]]. subst.
+ unfold wmsb. fold wmsb.
+ apply IHsz.
+ simpl in H. destruct b; omega.
+Qed.
+
+Lemma wmsb_0_natToWord: forall sz n default,
+ (2 * n < pow2 (S sz))%nat ->
+ @wmsb (S sz) (natToWord (S sz) n) default = false.
+Proof.
+ intros. apply wmsb_0.
+ pose proof (wordToNat_natToWord_le (S sz) n). unfold pow2 in H. fold pow2 in H. omega.
+Qed.
+
+Lemma wmsb_1_natToWord: forall sz n default,
+ pow2 sz <= n < 2 * pow2 sz ->
+ @wmsb (S sz) (natToWord (S sz) n) default = true.
+Proof.
+ intros. apply wmsb_1.
+ rewrite wordToNat_natToWord_idempotent'; simpl; omega.
+Qed.
+
+Lemma wordToN_wzero':
+ forall sz, wordToN (wzero' sz) = 0%N.
+Proof.
+ induction sz; simpl; auto.
+ rewrite IHsz; auto.
+Qed.
+
+Lemma wordToZ_wzero':
+ forall sz, wordToZ (wzero' sz) = 0%Z.
+Proof.
+ unfold wordToZ; intros.
+ rewrite wmsb_wzero'.
+ rewrite wordToN_wzero'.
+ reflexivity.
+Qed.
+
+Lemma wordToZ_wzero:
+ forall sz, wordToZ (wzero sz) = 0%Z.
+Proof.
+ unfold wordToZ; intros.
+ rewrite wmsb_wzero.
+ rewrite wordToN_wzero.
+ reflexivity.
+Qed.
+
+Lemma wmsb_existT: (* Note: not axiom free *)
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2),
+ existT word _ w1 = existT word _ w2 ->
+ forall b, wmsb w1 b = wmsb w2 b.
+Proof.
+ intros.
+ assert (sz1 = sz2) by (apply eq_sigT_fst in H; auto); subst.
+ destruct_existT; reflexivity.
+Qed.
+
+Lemma destruct_word_S: forall sz (w: word (S sz)),
+ exists v b, w = WS b v.
+Proof.
+ intros.
+ refine (match w with
+ | WO => _
+ | WS b v => _
+ end); unfold IDProp; eauto.
+Qed.
+
+Lemma induct_word_S: forall (P : forall n : nat, word (S n) -> Prop),
+ (forall b, P 0 (WS b WO)) ->
+ (forall b b0 n (w : word n), P n (WS b0 w) -> P (S n) (WS b (WS b0 w))) ->
+ forall (n : nat) (w : word (S n)), P n w.
+Proof.
+ induction n; intros.
+ - destruct (destruct_word_S w) as [v [b E]]. subst w.
+ rewrite (word0 v).
+ apply H.
+ - destruct (destruct_word_S w) as [v [b E]]. subst w.
+ destruct (destruct_word_S v) as [w [b0 E]]. subst v.
+ apply H0.
+ apply IHn.
+Qed.
+
+Lemma wmsb_ws:
+ forall sz (w: word (S sz)) b a, wmsb (WS b w) a = wmsb w a.
+Proof.
+ intros. cbn.
+ destruct (destruct_word_S w) as [v [c E]].
+ rewrite E.
+ reflexivity.
+Qed.
+
+Lemma wmsb_extz:
+ forall sz (w: word sz) n,
+ wmsb (extz w n) false = wmsb w false.
+Proof.
+ induction n; intros; auto.
+Qed.
+
+Lemma wmsb_default:
+ forall sz (w: word sz) b1 b2,
+ sz <> 0 -> wmsb w b1 = wmsb w b2.
+Proof.
+ dependent induction w; intros; intuition idtac.
+Qed.
+
+Lemma wmsb_nat_cast:
+ forall sz1 (w: word sz1) sz2 (Hsz: sz1 = sz2) b,
+ wmsb w b = wmsb (nat_cast word Hsz w) b.
+Proof.
+ destruct sz1; intros.
+ - subst sz2. reflexivity.
+ - destruct sz2; [discriminate|].
+ destruct (destruct_word_S w) as [v [b0 E]]. subst w.
+ pose proof (eq_add_S sz1 sz2 Hsz) as Hsz'.
+ subst sz2.
+ rewrite nat_cast_eq_rect.
+ f_equal.
+ erewrite (WS_eq_rect _ _ _ eq_refl).
+ reflexivity.
+Qed.
+
+Lemma wmsb_eq_rect:
+ forall sz1 (w: word sz1) sz2 (Hsz: sz1 = sz2) b,
+ wmsb w b = wmsb (eq_rect _ word w _ Hsz) b.
+Proof.
+ intros. rewrite <- nat_cast_eq_rect. apply wmsb_nat_cast.
+Qed.
+
+Local Arguments nat_cast: simpl never.
+
+Lemma nat_cast_inj: forall sz sz' (p: sz = sz') (w1 w2: word sz),
+ nat_cast word p w1 = nat_cast word p w2 ->
+ w1 = w2.
+Proof.
+ intros. destruct p. rewrite? nat_cast_same in H. assumption.
+Qed.
+
+Lemma wtl_nat_cast_WS: forall n m (q: n = m) (p: S n = S m) (w: word n) (b: bool),
+ wtl (nat_cast word p (WS b w)) =
+ nat_cast word q w.
+Proof.
+ intros n m. destruct q. intros.
+ rewrite nat_cast_same.
+ transitivity (wtl (WS b w)); [|reflexivity].
+ f_equal.
+ rewrite <- nat_cast_same.
+ apply nat_cast_proof_irrel.
+Qed.
+
+Lemma wmsb_split2': forall sz (w: word (S sz)) b,
+ wmsb w b = negb (weqb (split2 sz 1 (nat_cast _ (eq_sym (Nat.add_1_r sz)) w)) (natToWord _ 0)).
+Proof.
+ apply (induct_word_S (fun sz w => forall b, wmsb w b =
+ negb (weqb (split2 sz 1 (nat_cast _ (eq_sym (Nat.add_1_r sz)) w)) (natToWord _ 0))));
+ intros.
+ - destruct b; reflexivity.
+ - cbn in *. rewrite (H false). repeat f_equal.
+ clear.
+ apply (nat_cast_inj (Nat.add_1_r n)).
+ erewrite wtl_nat_cast_WS.
+ reflexivity.
+Qed.
+
+Lemma wmsb_split2:
+ forall sz (w: word (sz + 1)) b,
+ wmsb w b = if weq (split2 _ 1 w) (natToWord _ 0) then false else true.
+Proof.
+ intros.
+ pose proof (@wmsb_split2' sz). specialize (H (nat_cast _ (Nat.add_1_r sz) w) b).
+ simpl in H.
+ rewrite nat_cast_fuse in H.
+ rewrite <- (nat_cast_proof_irrel word _ _ eq_refl) in H.
+ rewrite nat_cast_same in H.
+ destruct (weq (split2 sz 1 w) $ (0)).
+ - rewrite e in H. simpl in H. rewrite <- H. clear.
+ apply wmsb_nat_cast.
+ - simpl in n. apply weqb_ne in n. rewrite n in H. simpl in H. rewrite <- H. clear.
+ apply wmsb_nat_cast.
+Qed.
+
+Lemma wmsb_true_split2_wones:
+ forall sz (w: word (sz + 1)) b,
+ wmsb w b = true ->
+ wones 1 = split2 sz 1 w.
+Proof.
+ intros.
+ pose proof (wmsb_split2 _ w b).
+ destruct (weq _ _).
+ - rewrite H in H0; discriminate.
+ - clear -n.
+ remember (split2 sz 1 w) as ww; clear Heqww w.
+ destruct (destruct_word_S ww) as [w [b E]]. subst ww.
+ rewrite (word0 w) in *. clear w. simpl in *. destruct b; congruence.
+Qed.
+
+Lemma wmsb_false_split2_wzero:
+ forall sz (w: word (sz + 1)) b,
+ wmsb w b = false ->
+ wzero 1 = split2 sz 1 w.
+Proof.
+ intros.
+ pose proof (wmsb_split2 _ w b).
+ destruct (weq _ _); auto.
+ rewrite H in H0; discriminate.
+Qed.
+
+Lemma wmsb_split1_sext:
+ forall sz (w: word (sz + 1)),
+ wmsb w false = wmsb (split1 _ 1 w) false ->
+ exists sw, sext sw 1 = w.
+Proof.
+ unfold sext; intros.
+ pose proof (combine_split _ _ w) as Hw.
+ rewrite <-Hw; rewrite <-Hw in H at 2; clear Hw.
+ rewrite split1_combine in H.
+ exists (split1 sz 1 w).
+ destruct (wmsb (split1 sz 1 w) false).
+ - rewrite <-wmsb_true_split2_wones with (b:= false) by assumption.
+ reflexivity.
+ - rewrite <-wmsb_false_split2_wzero with (b:= false) by assumption.
+ reflexivity.
+Qed.
+
+Lemma wmsb_combine_WO:
+ forall sz (w: word sz) b,
+ wmsb (combine w WO) b = wmsb w b.
+Proof.
+ dependent induction w; cbn; intros; auto.
+Qed.
+
+Lemma wmsb_combine:
+ forall sz1 sz2 (w1: word sz1) (w2: word sz2) b1 b2,
+ sz2 <> 0 ->
+ wmsb (combine w1 w2) b1 = wmsb w2 b2.
+Proof.
+ dependent induction w1; cbn; intros.
+ - auto using wmsb_default.
+ - auto using IHw1.
+Qed.
+
+Lemma wmsb_combine_existT: (* Note: not axiom free *)
+ forall sz (w: word sz) sz1 (w1: word sz1) sz2 (w2: word sz2) b1 b2,
+ sz2 <> 0 ->
+ existT word _ w = existT word _ (combine w1 w2) ->
+ wmsb w b1 = wmsb w2 b2.
+Proof.
+ intros.
+ pose proof (eq_sigT_fst H0); subst.
+ destruct_existT.
+ auto using wmsb_combine.
+Qed.
+
+Lemma wmsb_zext:
+ forall sz (w: word sz) b n, n <> 0 -> wmsb (zext w n) b = false.
+Proof.
+ destruct n; cbn; intros; [elim H; reflexivity|].
+ unfold zext.
+ erewrite wmsb_combine with (b2:= false) by discriminate.
+ apply wmsb_wzero.
+Qed.
+
+Lemma wordToN_zext:
+ forall sz (w: word sz) n,
+ wordToN (zext w n) = wordToN w.
+Proof.
+ dependent induction w; cbn; intros.
+ - induction n; cbn; intros; [reflexivity|].
+ unfold wzero in IHn; rewrite IHn; reflexivity.
+ - rewrite IHw; reflexivity.
+Qed.
+
+Lemma wordToNat_zext:
+ forall sz (w: word sz) n,
+ wordToNat (zext w n) = wordToNat w.
+Proof.
+ dependent induction w; cbn; intros.
+ - induction n; cbn; intros; [reflexivity|].
+ unfold wzero in IHn; rewrite IHn; reflexivity.
+ - rewrite IHw; reflexivity.
+Qed.
+
+Lemma zext_wordToNat_equal_Z:
+ forall sz (w: word sz) n,
+ n <> 0 -> wordToZ (zext w n) = Z.of_nat (wordToNat w).
+Proof.
+ unfold wordToZ, zext; intros.
+ rewrite wmsb_combine with (b2:= false) by assumption.
+ rewrite wmsb_wzero.
+ replace (combine w (wzero n)) with (zext w n) by reflexivity.
+ rewrite wordToN_zext.
+ rewrite wordToN_nat.
+ rewrite <-nat_N_Z.
+ unfold Z.of_N; reflexivity.
+Qed.
+
+Lemma wordToN_WS_0:
+ forall sz (w: word sz), wordToN w~0 = (2 * wordToN w)%N.
+Proof. reflexivity. Qed.
+
+Lemma wordToN_WS_1:
+ forall sz (w: word sz), wordToN w~1 = (2 * wordToN w + 1)%N.
+Proof.
+ intros; cbn.
+ unfold N.succ_double.
+ destruct (wordToN w); reflexivity.
+Qed.
+
+Lemma NToWord_WS_0:
+ forall sz n, NToWord (S sz) (2 * n) = (NToWord sz n)~0.
+Proof.
+ destruct n; intros; [reflexivity|].
+ replace (2 * N.pos p)%N with (N.pos (p~0)) by reflexivity.
+ reflexivity.
+Qed.
+
+Lemma NToWord_WS_1:
+ forall sz n, NToWord (S sz) (2 * n + 1) = (NToWord sz n)~1.
+Proof.
+ destruct n; intros; [reflexivity|].
+ replace (2 * N.pos p)%N with (N.pos (p~0)) by reflexivity.
+ reflexivity.
+Qed.
+
+Lemma wneg_WS_0:
+ forall sz (w: word sz), wneg w~0 = (wneg w)~0.
+Proof.
+ unfold wneg; intros.
+ rewrite wordToN_WS_0.
+ replace (Npow2 (S sz)) with (2 * Npow2 sz)%N by reflexivity.
+ rewrite <-N.mul_sub_distr_l.
+ apply NToWord_WS_0.
+Qed.
+
+Lemma NToWord_wordToN:
+ forall sz (w: word sz), NToWord sz (wordToN w) = w.
+Proof.
+ intros.
+ rewrite wordToN_nat, NToWord_nat.
+ rewrite Nat2N.id.
+ apply natToWord_wordToNat.
+Qed.
+
+Lemma roundTripN_0:
+ forall sz, wordToN (NToWord sz 0) = 0%N.
+Proof.
+ intros.
+ rewrite wordToN_nat, NToWord_nat.
+ rewrite roundTrip_0; reflexivity.
+Qed.
+
+Lemma wordToN_NToWord:
+ forall sz n,
+ exists k, wordToN (NToWord sz n) = (n - k * Npow2 sz)%N /\ (k * Npow2 sz <= n)%N.
+Proof.
+ intros.
+ rewrite wordToN_nat, NToWord_nat.
+ pose proof (wordToNat_natToWord sz (N.to_nat n)).
+ destruct H as [k [? ?]].
+ exists (N.of_nat k).
+ split.
+ - apply N2Nat.inj.
+ rewrite Nat2N.id, N2Nat.inj_sub, N2Nat.inj_mul.
+ rewrite Nat2N.id.
+ rewrite Npow2_nat.
+ assumption.
+ - rewrite nat_compare_le, Nat2N.inj_compare in H0.
+ rewrite Nat2N.inj_mul, <-Npow2_nat in H0.
+ do 2 rewrite N2Nat.id in H0.
+ assumption.
+Qed.
+
+Lemma wordToN_NToWord_2:
+ forall sz n, (n < Npow2 sz)%N -> wordToN (NToWord sz n) = n.
+Proof.
+ intros.
+ rewrite wordToN_nat, NToWord_nat.
+ rewrite wordToNat_natToWord_2.
+ - apply N2Nat.id.
+ - rewrite <-Npow2_nat.
+ apply Nlt_out; auto.
+Qed.
+
+Lemma wordToN_bound:
+ forall sz (w: word sz), (wordToN w < Npow2 sz)%N.
+Proof.
+ intros.
+ rewrite wordToN_nat.
+ apply Nlt_in.
+ rewrite Npow2_nat, Nat2N.id.
+ apply wordToNat_bound.
+Qed.
+
+Lemma wordToN_plus: forall sz (a b: word sz),
+ (wordToN a + wordToN b < Npow2 sz)%N ->
+ wordToN (a ^+ b) = (wordToN a + wordToN b)%N.
+Proof.
+ intros. unfold wplus, wordBin.
+ rewrite wordToN_NToWord_2 by assumption.
+ reflexivity.
+Qed.
+
+Lemma wordToN_mult: forall sz (a b: word sz),
+ (wordToN a * wordToN b < Npow2 sz)%N ->
+ wordToN (a ^* b) = (wordToN a * wordToN b)%N.
+Proof.
+ intros. unfold wmult, wordBin.
+ rewrite wordToN_NToWord_2 by assumption.
+ reflexivity.
+Qed.
+
+Lemma wnot_def:
+ forall sz (w: word sz), wnot w = NToWord sz (Npow2 sz - wordToN w - 1).
+Proof.
+ dependent induction w; cbn; [reflexivity|].
+ destruct b; cbn.
+ - rewrite IHw; clear IHw.
+ rewrite <-NToWord_WS_0.
+ f_equal.
+ destruct (Npow2 n); [reflexivity|].
+ destruct (wordToN w).
+ + change (N.pos p~0) with (2 * N.pos p)%N.
+ do 2 rewrite N.mul_sub_distr_l.
+ do 2 rewrite <-N.sub_add_distr.
+ reflexivity.
+ + change (N.pos p~0) with (2 * N.pos p)%N.
+ change (N.pos p0~0) with (2 * N.pos p0)%N.
+ rewrite <-N.add_1_l.
+ do 2 rewrite N.mul_sub_distr_l.
+ do 2 rewrite <-N.sub_add_distr.
+ rewrite N.add_comm with (n:= 1%N).
+ rewrite <-N.add_assoc.
+ reflexivity.
+ - rewrite IHw; clear IHw.
+ rewrite <-NToWord_WS_1.
+ f_equal.
+ pose proof (wordToN_bound w).
+ remember (Npow2 n) as pn; destruct pn;
+ [exfalso; eapply Npow2_not_zero; eauto|clear Heqpn].
+ destruct (wordToN w).
+ + change (N.pos p~0) with (2 * N.pos p)%N.
+ do 2 rewrite N.mul_sub_distr_l.
+ do 2 rewrite <-N.sub_add_distr.
+ destruct p; cbn; reflexivity.
+ + change (N.pos p~0) with (2 * N.pos p)%N.
+ change (N.pos p0~0) with (2 * N.pos p0)%N.
+ rewrite N.mul_sub_distr_l.
+ rewrite <-N.mul_sub_distr_l with (n:= N.pos p).
+ assert (exists pp, N.pos p - N.pos p0 = N.pos pp)%N.
+ { apply N.sub_gt in H.
+ destruct (N.pos p - N.pos p0)%N; [intuition idtac|].
+ eexists; reflexivity.
+ }
+ destruct H0; rewrite H0.
+ destruct x; cbn; reflexivity.
+Qed.
+
+Lemma wneg_wnot:
+ forall sz (w: word sz), wnot w = wneg w ^- (natToWord _ 1).
+Proof.
+ unfold wneg; intros.
+ rewrite wnot_def.
+
+ destruct (weq w (wzero _)); subst.
+
+ - rewrite wordToN_nat.
+ unfold wzero; rewrite roundTrip_0; cbn.
+ rewrite N.sub_0_r.
+ do 2 rewrite NToWord_nat.
+ rewrite Npow2_nat, natToWord_pow2, N2Nat.inj_sub.
+ change (N.to_nat 1%N) with 1.
+ rewrite Npow2_nat.
+ apply wordToNat_inj.
+ rewrite wordToNat_natToWord_2 by (pose proof (zero_lt_pow2 sz); omega).
+ unfold wminus.
+ rewrite wplus_unit, <-wones_wneg_one.
+ apply eq_sym, wones_pow2_minus_one.
+
+ - pose proof (wordToN_bound w).
+ assert (Npow2 sz - wordToN w < Npow2 sz)%N.
+ { apply N.sub_lt.
+ { apply N.lt_le_incl; auto. }
+ { assert (wordToN w <> 0)%N.
+ { replace 0%N with (wordToN (wzero sz)).
+ { intro Hx; elim n.
+ apply wordToN_inj; auto.
+ }
+ { rewrite wordToN_nat.
+ unfold wzero; rewrite roundTrip_0; reflexivity.
+ }
+ }
+ nomega.
+ }
+ }
+ apply N.sub_gt in H.
+ remember (Npow2 sz - wordToN w)%N as p; clear Heqp.
+ do 2 rewrite NToWord_nat.
+ rewrite N2Nat.inj_sub.
+ change (N.to_nat 1%N) with 1.
+ assert (N.to_nat p < pow2 sz)%nat
+ by (rewrite <-Npow2_nat; apply Nlt_out; auto); clear H0.
+ assert (N.to_nat p <> 0)
+ by (change 0 with (N.to_nat 0%N); intro Hx; elim H; apply N2Nat.inj; auto); clear H.
+ apply wordToNat_inj.
+ rewrite <-wordToNat_natToWord_pred.
+ + do 2 rewrite wordToNat_natToWord_2 by omega.
+ omega.
+ + intro Hx; elim H0.
+ apply natToWord_inj with (sz:= sz); try omega.
+ assumption.
+Qed.
+
+Lemma wzero_wneg:
+ forall n, wneg (wzero n) = wzero n.
+Proof.
+ intros.
+ pose proof (wminus_inv (wzero n)).
+ rewrite wplus_unit in H; auto.
+Qed.
+
+Lemma pow2_wneg:
+ forall sz, wneg (natToWord (S sz) (pow2 sz)) = natToWord (S sz) (pow2 sz).
+Proof.
+ unfold wneg; intros.
+ rewrite <-Npow2_nat, <-NToWord_nat.
+ rewrite wordToN_NToWord_2
+ by (apply Nlt_in; do 2 rewrite Npow2_nat;
+ pose proof (zero_lt_pow2 sz); simpl; omega).
+ rewrite Npow2_S.
+ f_equal; nomega.
+Qed.
+
+Lemma wneg_WS_1:
+ forall sz (w: word sz), wneg w~1 = (wnot w)~1.
+Proof.
+ intros.
+ apply wordToN_inj.
+ simpl; rewrite wnot_def.
+ unfold wneg.
+ rewrite wordToN_NToWord_2
+ by (apply N.sub_lt; [apply N.lt_le_incl, wordToN_bound|nomega]).
+ rewrite wordToN_NToWord_2.
+ - rewrite wordToN_WS_1.
+ change (Npow2 (S sz)) with (2 * Npow2 sz)%N.
+ rewrite N.sub_add_distr.
+ rewrite <-N.mul_sub_distr_l.
+ assert (Npow2 sz - wordToN w <> 0)%N
+ by (pose proof (wordToN_bound w); nomega).
+ remember (Npow2 sz - wordToN w)%N as n; clear Heqn.
+ destruct n; [intuition idtac|].
+ remember (N.pos p - 1)%N as pp; destruct pp.
+ + apply eq_sym, N.sub_0_le in Heqpp.
+ apply N.le_1_r in Heqpp; destruct Heqpp; [discriminate|].
+ rewrite H0; reflexivity.
+ + change (N.pos p0~0) with (2 * N.pos p0)%N.
+ rewrite Heqpp.
+ rewrite <-N.add_1_r.
+ rewrite N.mul_sub_distr_l.
+ clear; destruct p; cbn; reflexivity.
+ - rewrite <-N.sub_add_distr.
+ apply N.sub_lt; [|nomega].
+ pose proof (wordToN_bound w).
+ apply N.le_succ_l in H.
+ rewrite N.add_1_r; assumption.
+Qed.
+
+Lemma wordToZ_WS_0:
+ forall sz (w: word sz), wordToZ w~0 = (2 * wordToZ w)%Z.
+Proof.
+ dependent destruction w; [reflexivity|].
+ unfold wordToZ.
+ rewrite wmsb_ws.
+ destruct (wmsb (WS b w) false).
+ - rewrite wneg_WS_0.
+ rewrite wordToN_WS_0.
+ destruct (wordToN (wneg (WS b w))); cbn; omega.
+ - rewrite wordToN_WS_0.
+ destruct (wordToN (WS b w)); cbn; omega.
+Qed.
+
+Lemma wordToZ_WS_1:
+ forall sz (w: word (S sz)), wordToZ w~1 = (2 * wordToZ w + 1)%Z.
+Proof.
+ intros. destruct (destruct_word_S w) as [v [b E]]. rewrite E. clear w E. rename v into w.
+ unfold wordToZ.
+ rewrite wmsb_ws.
+ remember (wmsb (WS b w) false) as msb.
+ destruct msb.
+ - rewrite wneg_WS_1.
+ rewrite wordToN_WS_1.
+ rewrite wnot_def.
+ unfold wneg.
+
+ assert (Npow2 (S sz) - wordToN (WS b w) <> 0)%N.
+ { pose proof (wordToN_bound (WS b w)); nomega. }
+ assert (Npow2 (S sz) - wordToN (WS b w) < Npow2 (S sz))%N.
+ { apply N.sub_lt.
+ { apply N.lt_le_incl, wordToN_bound. }
+ { assert (wordToN (WS b w) <> 0)%N.
+ { replace 0%N with (wordToN (wzero (S sz))).
+ { intro Hx.
+ apply wordToN_inj in Hx.
+ rewrite Hx in Heqmsb.
+ rewrite wmsb_wzero in Heqmsb; discriminate.
+ }
+ { rewrite wordToN_nat.
+ unfold wzero; rewrite roundTrip_0; reflexivity.
+ }
+ }
+ nomega.
+ }
+ }
+ remember (Npow2 (S sz) - wordToN (WS b w))%N as n; clear Heqn.
+
+ rewrite wordToN_NToWord_2 by nomega.
+ rewrite wordToN_NToWord_2 by nomega.
+ destruct n; [intuition idtac|].
+ destruct p; cbn; reflexivity.
+
+ - rewrite wordToN_WS_1.
+ destruct (wordToN (WS b w)); cbn; omega.
+Qed.
+
+Lemma wordToZ_WS_1':
+ forall sz (w: word (sz + 1)), wordToZ w~1 = (2 * wordToZ w + 1)%Z.
+Proof.
+ intro sz.
+ replace (sz + 1) with (S sz) by omega.
+ intros.
+ apply wordToZ_WS_1.
+Qed.
+
+Lemma wordToZ_inj:
+ forall sz (w1 w2: word sz),
+ wordToZ w1 = wordToZ w2 -> w1 = w2.
+Proof.
+ unfold wordToZ; intros.
+ remember (wmsb w1 false) as msb1.
+ remember (wmsb w2 false) as msb2.
+ destruct msb1, msb2.
+ - remember (wordToN (wneg w1)) as wn1.
+ remember (wordToN (wneg w2)) as wn2.
+ destruct wn1, wn2; try discriminate.
+ + assert (wneg w1 = wneg w2).
+ { apply wordToN_inj.
+ rewrite <-Heqwn1, <-Heqwn2; reflexivity.
+ }
+ rewrite <-wneg_idempotent with (w:= w1).
+ rewrite <-wneg_idempotent with (w:= w2).
+ rewrite H0; reflexivity.
+ + inversion H; subst; clear H.
+ assert (wneg w1 = wneg w2).
+ { apply wordToN_inj.
+ rewrite <-Heqwn1, <-Heqwn2; reflexivity.
+ }
+ rewrite <-wneg_idempotent with (w:= w1).
+ rewrite <-wneg_idempotent with (w:= w2).
+ rewrite H; reflexivity.
+ - remember (wordToN (wneg w1)) as wn1.
+ remember (wordToN w2) as wn2.
+ destruct wn1, wn2; try discriminate.
+ rewrite <-wordToN_wzero with (sz:= sz) in Heqwn1, Heqwn2.
+ apply wordToN_inj in Heqwn1.
+ apply wordToN_inj in Heqwn2.
+ assert (w1 = wzero sz).
+ { rewrite <-wneg_idempotent with (w:= w1), <-Heqwn1.
+ apply wzero_wneg.
+ }
+ subst; reflexivity.
+ - remember (wordToN w1) as wn1.
+ remember (wordToN (wneg w2)) as wn2.
+ destruct wn1, wn2; try discriminate.
+ rewrite <-wordToN_wzero with (sz:= sz) in Heqwn1, Heqwn2.
+ apply wordToN_inj in Heqwn1.
+ apply wordToN_inj in Heqwn2.
+ assert (w2 = wzero sz).
+ { rewrite <-wneg_idempotent with (w:= w2), <-Heqwn2.
+ apply wzero_wneg.
+ }
+ subst; reflexivity.
+ - remember (wordToN w1) as wn1.
+ remember (wordToN w2) as wn2.
+ destruct wn1, wn2; try discriminate.
+ + rewrite <-wordToN_wzero with (sz:= sz) in Heqwn1, Heqwn2.
+ rewrite Heqwn1 in Heqwn2.
+ apply wordToN_inj in Heqwn2; auto.
+ + inversion H; subst; clear H.
+ rewrite Heqwn1 in Heqwn2.
+ apply wordToN_inj in Heqwn2; auto.
+Qed.
+
+Lemma wordToZ_wones:
+ forall sz, sz <> 0 -> wordToZ (wones sz) = (-1)%Z.
+Proof.
+ induction sz; intros; [elim H; reflexivity|].
+ simpl; destruct sz; [reflexivity|].
+ rewrite wordToZ_WS_1.
+ rewrite IHsz by discriminate.
+ reflexivity.
+Qed.
+
+Lemma wordToNat_eq_rect:
+ forall sz (w: word sz) nsz Hsz,
+ wordToNat (eq_rect _ word w nsz Hsz) = wordToNat w.
+Proof.
+ intros; subst; simpl; reflexivity.
+Qed.
+
+Lemma wordToNat_existT:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2) (Hsz: sz1 = sz2),
+ wordToNat w1 = wordToNat w2 ->
+ existT word _ w1 = existT word _ w2.
+Proof.
+ intros; subst.
+ apply wordToNat_inj in H; subst.
+ reflexivity.
+Qed.
+
+Lemma existT_wordToNat: (* Note: not axiom free *)
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2),
+ existT word _ w1 = existT word _ w2 ->
+ wordToNat w1 = wordToNat w2.
+Proof.
+ intros.
+ pose proof (eq_sigT_fst H); subst.
+ destruct_existT; reflexivity.
+Qed.
+
+Lemma wordToZ_eq_rect:
+ forall sz (w: word sz) nsz Hsz,
+ wordToZ (eq_rect _ word w nsz Hsz) = wordToZ w.
+Proof.
+ intros; subst; simpl; reflexivity.
+Qed.
+
+Lemma wordToZ_existT:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2) (Hsz: sz1 = sz2),
+ wordToZ w1 = wordToZ w2 ->
+ existT word _ w1 = existT word _ w2.
+Proof.
+ intros; subst.
+ apply wordToZ_inj in H; subst.
+ reflexivity.
+Qed.
+
+Lemma existT_wordToZ: (* Note: not axiom free *)
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2),
+ existT word _ w1 = existT word _ w2 ->
+ wordToZ w1 = wordToZ w2.
+Proof.
+ intros.
+ pose proof (eq_sigT_fst H); subst.
+ destruct_existT.
+ reflexivity.
+Qed.
+
+Lemma wplus_WS_0:
+ forall sz (w1 w2: word sz) b, WS b (w1 ^+ w2) = WS b w1 ^+ w2~0.
+Proof.
+ intros.
+ unfold wplus, wordBin; intros.
+ rewrite wordToN_WS_0.
+ destruct b.
+ - rewrite wordToN_WS_1.
+ rewrite <-N.add_assoc.
+ rewrite N.add_comm with (n:= 1%N).
+ rewrite N.add_assoc.
+ rewrite <-N.mul_add_distr_l.
+ apply eq_sym, NToWord_WS_1.
+ - rewrite wordToN_WS_0.
+ rewrite <-N.mul_add_distr_l.
+ apply eq_sym, NToWord_WS_0.
+Qed.
+
+Corollary wplus_WS_0':
+ forall sz (w1 w2: word sz) b, WS b (w1 ^+ w2) = w1~0 ^+ WS b w2.
+Proof.
+ intros.
+ rewrite wplus_comm with (x:= w1).
+ rewrite wplus_comm with (x:= w1~0).
+ apply wplus_WS_0.
+Qed.
+
+Lemma wpow2_pow2:
+ forall sz, wordToNat (wpow2 sz) = pow2 sz.
+Proof.
+ induction sz; simpl; intros; [reflexivity|].
+ rewrite IHsz.
+ omega.
+Qed.
+
+Lemma wpow2_Npow2:
+ forall sz, wordToN (wpow2 sz) = Npow2 sz.
+Proof.
+ induction sz; simpl; intros; [reflexivity|].
+ rewrite IHsz; reflexivity.
+Qed.
+
+Lemma wpow2_wneg:
+ forall sz, wneg (wpow2 sz) = wpow2 sz.
+Proof.
+ induction sz; simpl; intros; [reflexivity|].
+ rewrite wneg_WS_0.
+ rewrite IHsz; reflexivity.
+Qed.
+
+Lemma wpow2_wmsb:
+ forall sz, wmsb (wpow2 sz) false = true.
+Proof.
+ induction sz; simpl; intros; auto.
+Qed.
+
+Lemma wmsb_wnot:
+ forall sz (w: word (S sz)) b1 b2,
+ wmsb (wnot w) b1 = negb (wmsb w b2).
+Proof.
+ apply (induct_word_S (fun sz w => forall b1 b2, wmsb (wnot w) b1 = negb (wmsb w b2))); intros.
+ - reflexivity.
+ - simpl. apply (H true true).
+Qed.
+
+Lemma wmsb_wneg_true:
+ forall sz (w: word (S sz)),
+ w <> wpow2 sz ->
+ forall b1 b2,
+ wmsb w b1 = true ->
+ wmsb (wneg w) b2 = false.
+Proof.
+ apply (induct_word_S (fun sz w => w <> wpow2 sz -> forall b1 b2, wmsb w b1 = true ->
+ wmsb (^~ w) b2 = false)); intros;
+ [simpl in *; subst; elim H; reflexivity|].
+ destruct b.
+ - rewrite wneg_WS_1.
+ rewrite wmsb_ws.
+ rewrite wmsb_wnot with (b2:= false).
+ simpl; apply negb_false_iff; assumption.
+ - rewrite wneg_WS_0.
+ eapply H with (b1 := false); eauto.
+ intro Hx. elim H0.
+ clear -Hx.
+ simpl; rewrite Hx; reflexivity.
+Qed.
+
+Lemma wmsb_wneg_false:
+ forall sz (w: word (S sz)),
+ wordToNat w <> 0 ->
+ forall b1 b2,
+ wmsb w b1 = false ->
+ wmsb (wneg w) b2 = true.
+Proof.
+ apply (induct_word_S (fun sz w => #w <> 0 -> forall b1 b2, wmsb w b1 = false ->
+ wmsb (^~ w) b2 = true)); intros;
+ [simpl in *; subst; elim H; reflexivity|].
+ destruct b.
+ - rewrite wneg_WS_1.
+ rewrite wmsb_ws.
+ rewrite wmsb_ws in H1.
+ rewrite wmsb_wnot with (b2:= false).
+ apply negb_true_iff; assumption.
+ - rewrite wneg_WS_0.
+ eapply H with (b1:= false); eauto.
+ intro Hx; elim H0.
+ clear -Hx.
+ simpl in *; omega.
+Qed.
+
+Lemma zext_WO_wzero:
+ forall n, zext WO n = wzero n.
+Proof.
+ reflexivity.
+Qed.
+
+Lemma wmsb_wneg_zext: (* Note: not axiom free *)
+ forall sz (w: word sz) b n,
+ n <> 0 -> wordToNat w <> 0 ->
+ wmsb (wneg (zext w n)) b = true.
+Proof.
+ intros.
+ dependent destruction w; [elim H0; reflexivity|].
+ apply wmsb_wneg_false with (b1:= false).
+ - rewrite <-wordToNat_zext with (n:= n0) in H0.
+ assumption.
+ - apply wmsb_zext; assumption.
+Qed.
+
+Lemma wminus_WS_pos:
+ forall sz (w1 w2: word (S sz)),
+ wordToZ (WS true w1 ^- WS false w2) =
+ (2 * wordToZ (w1 ^- w2) + 1)%Z.
+Proof.
+ unfold wminus; intros.
+ cbn.
+ rewrite wneg_WS_0.
+ rewrite <-wplus_WS_0.
+ rewrite wordToZ_WS_1.
+ reflexivity.
+Qed.
+
+Lemma wminus_WS_pos':
+ forall sz (w1 w2: word (sz + 1)),
+ wordToZ (WS true w1 ^- WS false w2) =
+ (2 * wordToZ (w1 ^- w2) + 1)%Z.
+Proof.
+ intro sz.
+ replace (sz + 1) with (S sz) by omega.
+ intros.
+ apply wminus_WS_pos.
+Qed.
+
+Lemma wtl_combine:
+ forall (x: word 1) sz (y: word sz),
+ wtl (combine x y) = y.
+Proof.
+ intros.
+ destruct (destruct_word_S x) as [v [b E]]. subst x.
+ rewrite (word0 v).
+ reflexivity.
+Qed.
+
+Lemma extz_combine:
+ forall sz (w: word sz) n, extz w n = combine (natToWord n 0) w.
+Proof.
+ reflexivity.
+Qed.
+
+Lemma combine_assoc_existT:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2) sz3 (w3: word sz3),
+ existT word (sz1 + (sz2 + sz3)) (combine w1 (combine w2 w3)) =
+ existT word (sz1 + sz2 + sz3) (combine (combine w1 w2) w3).
+Proof.
+ intros; apply EqdepFacts.eq_sigT_sig_eq.
+ assert (Hsz: sz1 + (sz2 + sz3) = sz1 + sz2 + sz3) by omega.
+ exists Hsz.
+ rewrite (combine_assoc w1 w2 w3 Hsz).
+ reflexivity.
+Qed.
+
+Lemma sext_combine: (* Note: not axiom free *)
+ forall sz n (w: word (sz + n)) sz1 (w1: word sz1)
+ sz2 (Hsz2: sz2 <> 0) (w2: word sz2),
+ existT word _ w = existT word _ (combine w1 (sext w2 n)) ->
+ exists sw, w = sext sw n /\ existT word _ sw = existT word _ (combine w1 w2).
+Proof.
+ intros; unfold sext in H.
+ remember (wmsb w2 false) as msb2; destruct msb2.
+ - rewrite combine_assoc_existT in H.
+ assert (sz = sz1 + sz2) by (apply eq_sigT_fst in H; omega); subst.
+ destruct_existT.
+ exists (combine w1 w2).
+ split; [|reflexivity].
+ unfold sext.
+ dependent destruction w2; [discriminate|].
+ rewrite wmsb_combine with (b2:= false) by discriminate.
+ rewrite <-Heqmsb2.
+ reflexivity.
+ - rewrite combine_assoc_existT in H.
+ assert (sz = sz1 + sz2) by (apply eq_sigT_fst in H; omega); subst.
+ destruct_existT.
+ exists (combine w1 w2).
+ split; [|reflexivity].
+ unfold sext.
+ dependent destruction w2; [intuition idtac|].
+ rewrite wmsb_combine with (b2:= false) by discriminate.
+ rewrite <-Heqmsb2.
+ reflexivity.
+Qed.
+
+Lemma wplus_wzero_1:
+ forall sz (w: word sz), w ^+ (wzero _) = w.
+Proof.
+ unfold wplus, wordBin; intros.
+ rewrite wordToN_wzero.
+ rewrite N.add_0_r.
+ apply NToWord_wordToN.
+Qed.
+
+Lemma wplus_wzero_2:
+ forall sz (w: word sz), (wzero _) ^+ w = w.
+Proof.
+ unfold wplus, wordBin; intros.
+ rewrite wordToN_wzero.
+ rewrite N.add_0_l.
+ apply NToWord_wordToN.
+Qed.
+
+Lemma combine_wplus_1:
+ forall sl (w1: word sl) su (w2 w3: word su),
+ combine w1 (w2 ^+ w3) = combine w1 w2 ^+ extz w3 sl.
+Proof.
+ dependent induction w1; intros; [reflexivity|].
+ cbn; rewrite IHw1.
+ rewrite <-wplus_WS_0.
+ rewrite extz_combine; reflexivity.
+Qed.
+
+Lemma combine_wplus_2:
+ forall sl (w1: word sl) su (w2 w3: word su),
+ combine w1 (w2 ^+ w3) = extz w2 sl ^+ combine w1 w3.
+Proof.
+ intros.
+ rewrite wplus_comm.
+ rewrite combine_wplus_1.
+ apply wplus_comm.
+Qed.
+
+Lemma existT_wplus:
+ forall sz (w1 w2: word sz) sz' (w3 w4: word sz'),
+ existT word _ w1 = existT word _ w3 ->
+ existT word _ w2 = existT word _ w4 ->
+ existT word _ (w1 ^+ w2) = existT word _ (w3 ^+ w4).
+Proof.
+ intros.
+ rewrite eq_sigT_sig_eq in H; destruct H as [Hsz1 ?].
+ rewrite eq_sigT_sig_eq in H0; destruct H0 as [Hsz2 ?].
+ subst; do 2 rewrite <-(eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Lemma existT_wminus:
+ forall sz (w1 w2: word sz) sz' (w3 w4: word sz'),
+ existT word _ w1 = existT word _ w3 ->
+ existT word _ w2 = existT word _ w4 ->
+ existT word _ (w1 ^- w2) = existT word _ (w3 ^- w4).
+Proof.
+ intros.
+ rewrite eq_sigT_sig_eq in H; destruct H as [Hsz1 ?].
+ rewrite eq_sigT_sig_eq in H0; destruct H0 as [Hsz2 ?].
+ subst; do 2 rewrite <-(eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+
+Lemma existT_sext:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2) n,
+ existT word _ w1 = existT word _ w2 ->
+ existT word _ (sext w1 n) = existT word _ (sext w2 n).
+Proof.
+ intros; inversion H; reflexivity.
+Qed.
+
+Lemma existT_extz:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2) n,
+ existT word _ w1 = existT word _ w2 ->
+ existT word _ (extz w1 n) = existT word _ (extz w2 n).
+Proof.
+ intros; inversion H; reflexivity.
+Qed.
+
+Lemma existT_wrshifta:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2) n,
+ existT word _ w1 = existT word _ w2 ->
+ existT word _ (wrshifta w1 n) = existT word _ (wrshifta w2 n).
+Proof.
+ intros; inversion H; reflexivity.
+Qed.
+
+Lemma existT_wlshift:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2) n,
+ existT word _ w1 = existT word _ w2 ->
+ existT word _ (wlshift w1 n) = existT word _ (wlshift w2 n).
+Proof.
+ intros; inversion H; reflexivity.
+Qed.
+
+Lemma eq_rect_wplus:
+ forall sz (w1 w2: word sz) sz' Hsz,
+ eq_rect sz word (w1 ^+ w2) sz' Hsz =
+ (eq_rect sz word w1 sz' Hsz) ^+ (eq_rect sz word w2 sz' Hsz).
+Proof.
+ intros; subst.
+ eq_rect_simpl; reflexivity.
+Qed.
+
+Lemma eq_rect_2:
+ forall sz (pa: word sz) sz' Heq1 Heq2,
+ eq_rect sz' word (eq_rect sz word pa sz' Heq1) sz Heq2 = pa.
+Proof.
+ intros; subst.
+ do 2 rewrite <-(eq_rect_eq_dec eq_nat_dec).
+ reflexivity.
+Qed.
+
+Lemma wzero_eq_rect:
+ forall sz1 sz2 Heq,
+ eq_rect sz1 word (wzero sz1) sz2 Heq = wzero sz2.
+Proof.
+ intros; subst.
+ apply eq_sym, (eq_rect_eq_dec eq_nat_dec).
+Qed.
+
+Lemma wrshifta_0:
+ forall sz (w: word sz), wrshifta w 0 = w.
+Proof.
+ unfold wrshifta; intros; simpl.
+ unfold eq_rec_r, eq_rec.
+ unfold sext.
+ destruct (wmsb w false).
+ - cbn; rewrite combine_n_0.
+ rewrite eq_rect_2; reflexivity.
+ - cbn; rewrite combine_n_0.
+ rewrite eq_rect_2; reflexivity.
+Qed.
+
+Lemma wrshifta_WO:
+ forall n, wrshifta WO n = WO.
+Proof.
+ unfold wrshifta; cbn; intros.
+ unfold eq_rec_r, eq_rec.
+ rewrite wzero_eq_rect.
+ rewrite <-combine_wzero.
+ rewrite split2_combine.
+ reflexivity.
+Qed.
+
+Lemma split2_WO:
+ forall n w, split2 n 0 w = WO.
+Proof.
+ induction n; cbn; intros; auto.
+Qed.
+
+Lemma sext_wzero:
+ forall sz n, sext (wzero sz) n = wzero (sz + n).
+Proof.
+ unfold sext; intros.
+ rewrite wmsb_wzero.
+ apply combine_wzero.
+Qed.
+
+Lemma wrshifta_wzero:
+ forall sz n, wrshifta (wzero sz) n = wzero _.
+Proof.
+ intros.
+ unfold wrshifta; cbn.
+ rewrite sext_wzero.
+ unfold eq_rec_r, eq_rec.
+ rewrite wzero_eq_rect.
+ rewrite <-combine_wzero.
+ rewrite split2_combine.
+ reflexivity.
+Qed.
+
+Lemma extz_sext:
+ forall sz (w: word sz) n1 n2,
+ existT word _ (extz (sext w n1) n2) =
+ existT word _ (sext (extz w n2) n1).
+Proof.
+ dependent destruction w; cbn; intros.
+ - unfold wzero, extz, sext.
+ rewrite combine_wzero.
+ rewrite combine_wzero.
+ rewrite wmsb_wzero.
+ rewrite combine_wzero.
+ replace (n2 + 0 + n1) with (n2 + n1) by omega.
+ reflexivity.
+ - unfold wzero, extz, sext.
+ rewrite wmsb_combine with (b2:= false) by discriminate.
+ destruct (wmsb (WS b w) false);
+ try (rewrite <-combine_assoc_existT; reflexivity).
+Qed.
+
+Lemma sext_WS:
+ forall sz (w: word (S sz)) b n,
+ sext (WS b w) n = WS b (sext w n).
+Proof.
+ unfold sext; intros.
+ rewrite wmsb_ws.
+ destruct (wmsb w false); reflexivity.
+Qed.
+
+Lemma sext_wordToZ:
+ forall sz n (w: word sz),
+ wordToZ (sext w n) = wordToZ w.
+Proof.
+ dependent induction w; cbn; intros; [apply wordToZ_wzero|].
+ dependent destruction w.
+ - unfold sext; simpl.
+ destruct b; cbn.
+ + rewrite wordToZ_wones by discriminate.
+ reflexivity.
+ + rewrite wordToZ_wzero; reflexivity.
+ - remember (WS b0 w) as ww; clear Heqww.
+ rewrite sext_WS.
+ destruct b.
+ + change (S n0 + n) with (S (n0 + n)) in *.
+ repeat rewrite wordToZ_WS_1.
+ rewrite IHw.
+ reflexivity.
+ + change (S n0 + n) with (S (n0 + n)) in *.
+ repeat rewrite wordToZ_WS_0.
+ rewrite IHw.
+ reflexivity.
+Qed.
+
+Lemma sext_natToWord': forall sz1 sz2 n,
+ (2 * n < pow2 sz1)%nat ->
+ sext (natToWord sz1 n) sz2 = natToWord (sz1 + sz2) n.
+Proof.
+ induction sz1; intros.
+ - simpl. unfold sext. simpl. unfold wzero. unfold pow2 in *.
+ assert (n=0) by omega. subst n. reflexivity.
+ - unfold sext in *.
+ assert (@wmsb (S sz1) (natToWord (S sz1) n) false = false) as E by
+ (apply wmsb_0_natToWord; assumption).
+ rewrite E. clear E.
+ simpl. unfold natToWord. f_equal. fold natToWord.
+ specialize (IHsz1 sz2 (Nat.div2 n)).
+ rewrite <- IHsz1.
+ + assert (@wmsb sz1 (natToWord sz1 (Nat.div2 n)) false = false) as E. {
+ destruct sz1.
+ - reflexivity.
+ - apply wmsb_0_natToWord. unfold pow2 in *. fold pow2 in *.
+ assert ((2 * Nat.div2 n <= n)%nat) by apply two_times_div2_bound. omega.
+ }
+ rewrite E. clear E. reflexivity.
+ + replace (pow2 (S sz1)) with (2 * (pow2 sz1)) in H.
+ * assert ((2 * Nat.div2 n <= n)%nat) by apply two_times_div2_bound. omega.
+ * reflexivity.
+Qed.
+
+Lemma sext_natToWord: forall sz2 sz1 sz n (e: sz1 + sz2 = sz),
+ (2 * n < pow2 sz1)%nat ->
+ eq_rect (sz1 + sz2) word (sext (natToWord sz1 n) sz2) sz e = natToWord sz n.
+Proof.
+ intros. rewrite sext_natToWord' by assumption. rewrite e. reflexivity.
+Qed.
+
+Lemma sext_wneg_natToWord'': forall sz1 sz2 n,
+ pow2 sz1 <= 2 * n < pow2 (S sz1) ->
+ sext (natToWord sz1 n) sz2 = natToWord (sz1 + sz2) (pow2 (sz1+sz2) - (pow2 sz1 - n)).
+Proof.
+ induction sz1; intros.
+ - unfold pow2 in H. omega. (* contradiction *)
+ - unfold sext in *.
+ assert (@wmsb (S sz1) (natToWord (S sz1) n) false = true) as E. {
+ apply wmsb_1.
+ rewrite wordToNat_natToWord_idempotent';
+ (unfold pow2 in *; fold pow2 in *; omega).
+ }
+ rewrite E.
+ match goal with
+ | |- _ = $ ?a => remember a as b
+ end.
+ simpl. unfold natToWord. f_equal.
+ + subst b. rewrite mod2sub.
+ * rewrite mod2sub.
+ { replace (S sz1 + sz2) with (S (sz1 + sz2)) by omega.
+ simpl.
+ do 2 rewrite mod2_pow2_twice.
+ do 2 rewrite Bool.xorb_false_l.
+ reflexivity.
+ }
+ simpl in *. omega.
+ * rewrite pow2_add_mul in *. unfold pow2 in *. fold pow2 in *.
+ apply Nat.le_trans with (m := 2 * pow2 sz1); [omega|].
+ rewrite <- mult_assoc.
+ apply mult_le_compat_l.
+ rewrite <- Nat.mul_1_r at 1.
+ apply mult_le_compat_l.
+ apply one_le_pow2.
+ + fold natToWord.
+ specialize (IHsz1 sz2 (Nat.div2 n)).
+ assert (Nat.div2 b = pow2 (sz1 + sz2) - (pow2 sz1 - (Nat.div2 n))) as D2. {
+ rewrite minus_minus.
+ - subst b. replace (S sz1 + sz2) with (S (sz1 + sz2)) by omega.
+ unfold pow2. fold pow2.
+ rewrite minus_minus.
+ * rewrite <- Nat.mul_sub_distr_l.
+ rewrite <- (Nat.add_comm n).
+ rewrite div2_plus_2.
+ apply Nat.add_comm.
+ * rewrite pow2_add_mul. clear IHsz1. unfold pow2 in *. fold pow2 in *.
+ split; [omega|].
+ apply mult_le_compat_l.
+ rewrite <- Nat.mul_1_r at 1.
+ apply mult_le_compat_l.
+ apply one_le_pow2.
+ - unfold pow2 in H. fold pow2 in H.
+ split.
+ * pose proof (@div2_compat_lt_l (pow2 sz1) n) as P. omega.
+ * rewrite pow2_add_mul. clear IHsz1.
+ rewrite <- Nat.mul_1_r at 1.
+ apply mult_le_compat_l.
+ apply one_le_pow2.
+ }
+ rewrite D2.
+ destruct sz1 as [|sz1'].
+ * simpl in H. assert (n=1) by omega. subst n. simpl in D2. simpl.
+ apply wones_natToWord.
+ * assert (n <= S (2 * Nat.div2 n))%nat. {
+ destruct (even_odd_destruct n) as [[m C]|[m C]]; subst n.
+ - rewrite Nat.div2_double. constructor. constructor.
+ - replace (2 * m + 1) with (S (2 * m)) by omega. rewrite Nat.div2_succ_double.
+ constructor.
+ }
+ rewrite <- IHsz1.
+ { assert (@wmsb (S sz1') (natToWord (S sz1') (Nat.div2 n)) false = true) as F. {
+ apply wmsb_1_natToWord.
+ unfold pow2 in *. fold pow2 in *.
+ assert (2 * Nat.div2 n <= n)%nat by apply two_times_div2_bound.
+ clear -H H0 H1.
+ omega. }
+ { rewrite F. reflexivity. }
+ }
+ { assert (2 * Nat.div2 n <= n)%nat by apply two_times_div2_bound.
+ clear -H H0 H1.
+ unfold pow2 in *. fold pow2 in *.
+ omega. }
+Qed.
+
+Lemma sext_wneg_natToWord': forall sz1 sz2 n,
+ (2 * n < pow2 sz1)%nat ->
+ sext (wneg (natToWord sz1 n)) sz2 = wneg (natToWord (sz1 + sz2) n).
+Proof.
+ intros. rewrite wneg_alt. unfold wnegN.
+ destruct n as [|n].
+ - rewrite roundTrip_0. rewrite Nat.sub_0_r. rewrite natToWord_pow2.
+ unfold sext.
+ assert (wmsb (natToWord sz1 0) false = false) as W. {
+ destruct sz1.
+ + simpl. reflexivity.
+ + apply wmsb_0_natToWord. assumption.
+ }
+ rewrite W.
+ rewrite combine_wzero.
+ symmetry.
+ apply wneg_zero'.
+ - rewrite sext_wneg_natToWord''.
+ + rewrite wneg_alt. unfold wnegN.
+ rewrite wordToNat_natToWord_idempotent' by omega.
+ rewrite wordToNat_natToWord_idempotent'.
+ * replace (pow2 sz1 - (pow2 sz1 - S n)) with (S n) by omega.
+ reflexivity.
+ * rewrite pow2_add_mul.
+ apply Nat.le_trans with (m := pow2 sz1); [omega|].
+ rewrite <- Nat.mul_1_r at 1.
+ apply mult_le_compat_l.
+ apply one_le_pow2.
+ + rewrite wordToNat_natToWord_idempotent' by omega.
+ simpl. omega.
+Qed.
+
+Lemma sext_wneg_natToWord: forall sz2 sz1 sz n (e: sz1 + sz2 = sz),
+ (2 * n < pow2 sz1)%nat ->
+ eq_rect (sz1 + sz2) word (sext (wneg (natToWord sz1 n)) sz2) sz e = wneg (natToWord sz n).
+Proof.
+ intros. rewrite sext_wneg_natToWord' by assumption. rewrite e. reflexivity.
+Qed.
+
+Lemma wordToNat_split1:
+ forall sz1 sz2 (w: word (sz1 + sz2)),
+ wordToNat (split1 _ _ w) =
+ Nat.modulo (wordToNat w) (pow2 sz1).
+Proof.
+ induction sz1; intros; [reflexivity|].
+ destruct (destruct_word_S w) as [v [b E]].
+ match type of v with
+ | word ?x => change x with (sz1 + sz2) in *
+ end.
+ subst w. rename v into w.
+ simpl; rewrite IHsz1.
+ pose proof (zero_lt_pow2 sz1).
+ destruct b.
+ - change (pow2 sz1 + (pow2 sz1 + 0)) with (2 * pow2 sz1).
+ replace (S (wordToNat w * 2)) with (1 + 2 * wordToNat w) by omega.
+ rewrite Nat.add_mod by omega.
+ rewrite Nat.mul_mod_distr_l; [|omega|discriminate].
+ rewrite Nat.mod_1_l by omega.
+ rewrite Nat.mul_comm with (n:= 2).
+ change (1 + wordToNat w mod pow2 sz1 * 2) with (S (wordToNat w mod pow2 sz1 * 2)).
+ apply eq_sym, Nat.mod_small.
+ assert (pow2 sz1 <> 0) by omega.
+ pose proof (Nat.mod_upper_bound (wordToNat w) (pow2 sz1) H0).
+ omega.
+ - change (pow2 sz1 + (pow2 sz1 + 0)) with (2 * pow2 sz1).
+ rewrite Nat.mul_comm with (n:= 2).
+ rewrite Nat.mul_mod_distr_r; [|omega|discriminate].
+ reflexivity.
+Qed.
+
+Lemma wordToNat_split2:
+ forall sz1 sz2 (w: word (sz1 + sz2)),
+ wordToNat (split2 _ _ w) =
+ Nat.div (wordToNat w) (pow2 sz1).
+Proof.
+ induction sz1; intros;
+ [rewrite Nat.div_1_r; reflexivity|].
+ destruct (destruct_word_S w) as [v [b E]].
+ match type of v with
+ | word ?x => change x with (sz1 + sz2) in *
+ end.
+ subst w. rename v into w.
+ change (split2 (S sz1) sz2 (WS b w))
+ with (split2 sz1 sz2 w).
+ rewrite IHsz1.
+ destruct b.
+ - unfold pow2; fold pow2.
+ replace (@wordToNat (S sz1 + sz2) w~1)
+ with (1 + 2 * wordToNat w) by (simpl; omega).
+ rewrite <-Nat.div_div;
+ [|discriminate|pose proof (zero_lt_pow2 sz1); omega].
+ rewrite Nat.mul_comm, Nat.div_add by discriminate.
+ rewrite Nat.div_small with (b := 2) by omega.
+ reflexivity.
+ - unfold pow2; fold pow2.
+ replace (@wordToNat (S sz1 + sz2) w~0)
+ with (2 * wordToNat w) by (simpl; omega).
+ rewrite Nat.div_mul_cancel_l;
+ [|pose proof (zero_lt_pow2 sz1); omega|discriminate].
+ reflexivity.
+Qed.
+
+Lemma wordToNat_wrshifta:
+ forall sz (w: word sz) n,
+ wordToNat (wrshifta w n) =
+ Nat.div (wordToNat (sext w n)) (pow2 n).
+Proof.
+ unfold wrshifta; intros.
+ rewrite wordToNat_split2.
+ unfold eq_rec_r, eq_rec.
+ rewrite wordToNat_eq_rect.
+ reflexivity.
+Qed.
+
+Lemma wordToNat_combine:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2),
+ wordToNat (combine w1 w2) =
+ wordToNat w1 + pow2 sz1 * wordToNat w2.
+Proof.
+ dependent induction w1; intros; [simpl; omega|].
+ unfold pow2; fold pow2.
+ rewrite Nat.mul_comm with (n:= 2). (* to avoid [simpl] *)
+ simpl; destruct b.
+ - rewrite IHw1; simpl.
+ rewrite Nat.mul_comm with (n:= pow2 n * 2).
+ rewrite Nat.mul_assoc.
+ rewrite <-Nat.mul_add_distr_r.
+ rewrite Nat.mul_comm with (n:= pow2 n).
+ reflexivity.
+ - rewrite IHw1.
+ rewrite Nat.mul_comm with (n:= pow2 n * 2).
+ rewrite Nat.mul_assoc.
+ rewrite <-Nat.mul_add_distr_r.
+ rewrite Nat.mul_comm with (n:= pow2 n).
+ reflexivity.
+Qed.
+
+Lemma wordToNat_wlshift:
+ forall sz (w: word sz) n,
+ wordToNat (wlshift w n) =
+ Nat.mul (Nat.modulo (wordToNat w) (pow2 (sz - n))) (pow2 n).
+Proof.
+ intros; destruct (le_dec n sz).
+
+ - unfold wlshift; intros.
+ rewrite wordToNat_split1.
+ unfold eq_rec_r, eq_rec.
+ rewrite wordToNat_eq_rect.
+ rewrite wordToNat_combine.
+ rewrite wordToNat_wzero; simpl.
+ replace (pow2 sz) with (pow2 (sz - n + n)) by (f_equal; omega).
+ rewrite pow2_add_mul.
+ rewrite Nat.mul_comm with (n:= pow2 (sz - n)).
+ rewrite Nat.mul_mod_distr_l;
+ [|pose proof (zero_lt_pow2 (sz - n)); omega
+ |pose proof (zero_lt_pow2 n); omega].
+ apply Nat.mul_comm.
+
+ - assert (n > sz)%nat by omega.
+ rewrite wlshift_gt by assumption.
+ replace (sz - n) with 0 by omega.
+ rewrite wordToNat_wzero; simpl; reflexivity.
+Qed.
+
+Lemma wordToNat_extz:
+ forall sz (w: word sz) n,
+ wordToNat (extz w n) = pow2 n * wordToNat w.
+Proof.
+ unfold extz; intros.
+ rewrite wordToNat_combine.
+ rewrite wordToNat_wzero.
+ reflexivity.
+Qed.
+
+Lemma extz_is_mult_pow2: forall sz n d,
+ extz (natToWord sz n) d = natToWord (d + sz) (pow2 d * n).
+Proof.
+ intros. induction d.
+ - unfold extz.
+ rewrite combine_0_n.
+ simpl.
+ f_equal.
+ omega.
+ - unfold extz in *.
+ change (pow2 (S d) * n) with (2 * pow2 d * n).
+ rewrite <- Nat.mul_assoc.
+ change ((S d) + sz) with (S (d + sz)) in *.
+ rewrite <- natToWord_times2.
+ simpl.
+ fold natToWord.
+ f_equal.
+ exact IHd.
+Qed.
+
+Lemma extz_is_mult_pow2_neg: forall sz n d,
+ extz (wneg (natToWord sz n)) d = wneg (natToWord (d + sz) (pow2 d * n)).
+Proof.
+ intros. induction d.
+ - unfold extz.
+ rewrite combine_0_n.
+ simpl.
+ f_equal. f_equal.
+ omega.
+ - unfold extz in *.
+ change (pow2 (S d) * n) with (2 * pow2 d * n).
+ rewrite <- Nat.mul_assoc.
+ change ((S d) + sz) with (S (d + sz)) in *.
+ rewrite <- natToWord_times2.
+ simpl.
+ fold natToWord.
+ f_equal.
+ rewrite wneg_WS_0.
+ f_equal.
+ exact IHd.
+Qed.
+
+Lemma wordToNat_sext_bypass:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2) (Hsz: sz1 = sz2) n,
+ wordToNat w1 = wordToNat w2 ->
+ wordToNat (sext w1 n) = wordToNat (sext w2 n).
+Proof.
+ intros; subst.
+ apply wordToNat_inj in H; subst.
+ reflexivity.
+Qed.
+
+Lemma combine_sext:
+ forall sz1 (w1: word sz1) sz2 (w2: word (S sz2)) n,
+ existT word _ (combine w1 (sext w2 n)) =
+ existT word _ (sext (combine w1 w2) n).
+Proof.
+ unfold sext; intros.
+ rewrite wmsb_combine with (b2:= false) by discriminate.
+ destruct (wmsb w2 false); apply combine_assoc_existT.
+Qed.
+
+Lemma extz_extz:
+ forall sz (w: word sz) n1 n2,
+ existT word _ (extz (extz w n1) n2) =
+ existT word _ (extz w (n2 + n1)).
+Proof.
+ unfold extz; cbn; intros.
+ rewrite combine_assoc_existT.
+ rewrite combine_wzero.
+ reflexivity.
+Qed.
+
+Lemma wrshifta_extz_sext: (* Note: not axiom free *)
+ forall sz (w: word sz) n1 n2,
+ existT word _ (wrshifta (extz w (n1 + n2)) n1) =
+ existT word _ (sext (extz w n2) n1).
+Proof.
+ intros.
+ rewrite <-extz_sext.
+ apply wordToNat_existT; [omega|].
+ rewrite wordToNat_wrshifta.
+
+ replace (wordToNat (sext (extz w (n1 + n2)) n1))
+ with (wordToNat (sext (extz (extz w n2) n1) n1)).
+ - replace (wordToNat (sext (extz (extz w n2) n1) n1))
+ with (wordToNat (extz (sext (extz w n2) n1) n1))
+ by apply existT_wordToNat, extz_sext.
+ do 2 rewrite wordToNat_extz.
+ rewrite Nat.mul_comm, Nat.div_mul
+ by (pose proof (zero_lt_pow2 n1); omega).
+ replace (wordToNat (sext (extz w n2) n1))
+ with (wordToNat (extz (sext w n1) n2))
+ by apply existT_wordToNat, extz_sext.
+ rewrite wordToNat_extz.
+ reflexivity.
+ - apply wordToNat_sext_bypass; [omega|].
+ apply existT_wordToNat.
+ apply extz_extz.
+Qed.
+
+Lemma wordToNat_sext_modulo:
+ forall sz (w: word sz) n,
+ Nat.modulo (wordToNat (sext w n)) (pow2 sz) = wordToNat w.
+Proof.
+ unfold sext; intros.
+ pose proof (zero_lt_pow2 sz).
+ destruct (wmsb w false).
+ - rewrite wordToNat_combine.
+ rewrite Nat.mul_comm, Nat.mod_add by omega.
+ apply Nat.mod_small.
+ apply wordToNat_bound.
+ - rewrite wordToNat_combine.
+ rewrite Nat.mul_comm, Nat.mod_add by omega.
+ apply Nat.mod_small.
+ apply wordToNat_bound.
+Qed.
+
+Lemma wlshift_sext_extz:
+ forall sz (w: word sz) n,
+ existT word _ (wlshift (sext w n) n) =
+ existT word _ (extz w n).
+Proof.
+ intros; apply wordToNat_existT; [omega|].
+ rewrite wordToNat_wlshift.
+ rewrite wordToNat_extz.
+ replace (sz + n - n) with sz by omega.
+ rewrite wordToNat_sext_modulo.
+ apply Nat.mul_comm.
+Qed.
+
+Lemma wlshift_combine_extz:
+ forall sn sl (wl: word sl) ssu (wu: word (ssu + sn)),
+ existT word (sl + (ssu + sn)) (wlshift (combine wl wu) sn) =
+ existT word (sn + (sl + ssu)) (extz (combine wl (split1 ssu _ wu)) sn).
+Proof.
+ intros; apply wordToNat_existT; [omega|].
+ rewrite wordToNat_wlshift.
+ rewrite wordToNat_combine.
+ rewrite wordToNat_extz.
+ rewrite wordToNat_combine.
+ rewrite wordToNat_split1.
+
+ replace (sl + (ssu + sn) - sn) with (sl + ssu) by omega.
+ rewrite Nat.mul_comm; f_equal.
+ rewrite pow2_add_mul.
+ pose proof (zero_lt_pow2 sl).
+ pose proof (zero_lt_pow2 ssu).
+ rewrite Nat.mod_mul_r; try omega.
+ rewrite Nat.mul_comm with (n:= pow2 sl) at 1.
+ rewrite Nat.mod_add; [|omega].
+ rewrite Nat.mod_small by apply wordToNat_bound.
+ do 3 f_equal.
+ rewrite Nat.mul_comm, Nat.div_add; [|omega].
+ rewrite Nat.div_small by apply wordToNat_bound.
+ reflexivity.
+Qed.
+
+Lemma extz_sext_eq_rect:
+ forall sz (w: word sz) n1 n2 nsz Hnsz1,
+ exists Hnsz2,
+ eq_rect (n2 + (sz + n1)) word (extz (sext w n1) n2) nsz Hnsz1 =
+ eq_rect (n2 + sz + n1) word (sext (extz w n2) n1) nsz Hnsz2.
+Proof.
+ intros; subst; simpl.
+ assert (Hsz: n2 + sz + n1 = n2 + (sz + n1)) by omega.
+ exists Hsz.
+ pose proof (extz_sext w n1 n2).
+ pose proof (eq_sigT_snd H).
+ rewrite <-H0.
+ eq_rect_simpl.
+ reflexivity.
+Qed.
+
+Lemma sext_zero:
+ forall n m, sext (natToWord n 0) m = natToWord _ 0.
+Proof.
+ unfold sext; intros.
+ rewrite wmsb_wzero.
+ rewrite combine_wzero.
+ reflexivity.
+Qed.
+
+Lemma sext_split1:
+ forall sz (w: word sz) n,
+ split1 sz _ (sext w n) = w.
+Proof.
+ unfold sext; intros.
+ destruct (wmsb w false); apply split1_combine.
+Qed.
+
+Lemma sext_sext:
+ forall sz (w: word sz) n1 n2,
+ existT word _ (sext w (n1 + n2)) = existT word _ (sext (sext w n1) n2).
+Proof.
+ unfold sext; intros.
+ remember (wmsb w false) as wmsb; destruct wmsb.
+ - destruct n1 as [|n1].
+ + cbn; rewrite wmsb_combine_WO, <-Heqwmsb.
+ rewrite <-combine_assoc_existT.
+ reflexivity.
+ + rewrite wmsb_combine with (b2:= false) by discriminate.
+ rewrite wmsb_wones.
+ rewrite <-combine_assoc_existT.
+ rewrite combine_wones.
+ reflexivity.
+ - destruct n1 as [|n1].
+ + cbn; rewrite wmsb_combine_WO, <-Heqwmsb.
+ rewrite <-combine_assoc_existT.
+ reflexivity.
+ + rewrite wmsb_combine with (b2:= false) by discriminate.
+ rewrite wmsb_wzero.
+ rewrite <-combine_assoc_existT.
+ rewrite combine_wzero.
+ reflexivity.
+Qed.
+
+Lemma wneg_wordToN:
+ forall sz (w: word sz),
+ wordToN w <> 0%N ->
+ wordToN (wneg w) = (Npow2 sz - wordToN w)%N.
+Proof.
+ unfold wneg; intros.
+ rewrite wordToN_NToWord_2.
+ - reflexivity.
+ - pose proof (wordToN_bound w).
+ nomega.
+Qed.
+
+Lemma Nmul_two:
+ forall n, (n + n = 2 * n)%N.
+Proof.
+ intros.
+ destruct n; simpl; auto.
+ rewrite Pos.add_diag.
+ reflexivity.
+Qed.
+
+Lemma wmsb_false_bound:
+ forall sz (w: word (S sz)),
+ wmsb w false = false -> (wordToN w < Npow2 sz)%N.
+Proof.
+ apply (induct_word_S (fun sz w => wmsb w false = false -> (wordToN w < Npow2 sz)%N));
+ [simpl; intros; subst; nomega|].
+ intros; rewrite Npow2_S, Nmul_two.
+ specialize (H H0).
+ destruct b.
+ - rewrite wordToN_WS_1.
+ rewrite N.add_comm.
+ apply N.mul_2_mono_l; auto.
+ - rewrite wordToN_WS_0.
+ apply N.mul_lt_mono_pos_l; [nomega|].
+ assumption.
+Qed.
+
+Lemma wmsb_true_bound:
+ forall sz (w: word (S sz)),
+ wmsb w false = true -> (Npow2 sz <= wordToN w)%N.
+Proof.
+ apply (induct_word_S (fun sz w => wmsb w false = true -> (Npow2 sz <= wordToN w)%N));
+ [simpl; intros; subst; reflexivity|].
+ intros; rewrite Npow2_S, Nmul_two.
+ specialize (H H0).
+ destruct b.
+ - rewrite wordToN_WS_1.
+ apply N.mul_le_mono_nonneg_l with (p:= 2%N) in H; [|compute; discriminate].
+ rewrite N.add_1_r.
+ apply N.le_le_succ_r.
+ assumption.
+ - rewrite wordToN_WS_0.
+ apply N.mul_le_mono_nonneg_l; [compute; discriminate|].
+ assumption.
+Qed.
+
+Lemma ZToWord_wordToZ:
+ forall sz (w: word sz), ZToWord sz (wordToZ w) = w.
+Proof.
+ unfold ZToWord, wordToZ; intros.
+ remember (wmsb w false) as msb; destruct msb.
+ - remember (wordToN (wneg w)) as ww.
+ destruct ww.
+ + assert (wneg w = wzero _).
+ { apply wordToN_inj; rewrite <-Heqww.
+ rewrite wordToN_nat.
+ rewrite roundTrip_0.
+ reflexivity.
+ }
+ rewrite wzero'_def.
+ rewrite <-wneg_idempotent, H.
+ apply eq_sym, wzero_wneg.
+ + assert (wneg w = NToWord _ (N.pos p)).
+ { apply wordToN_inj; rewrite Heqww.
+ rewrite NToWord_wordToN.
+ reflexivity.
+ }
+ rewrite <-wneg_idempotent, H.
+ reflexivity.
+ - remember (wordToN w) as ww.
+ destruct ww.
+ + assert (w = wzero _); subst.
+ { apply wordToN_inj; rewrite <-Heqww.
+ rewrite wordToN_nat.
+ rewrite roundTrip_0.
+ reflexivity.
+ }
+ apply wzero'_def.
+ + assert (w = NToWord _ (N.pos p)); subst.
+ { apply wordToN_inj; rewrite Heqww.
+ rewrite NToWord_wordToN.
+ reflexivity.
+ }
+ reflexivity.
+Qed.
+
+Lemma wordToZ_ZToWord:
+ forall z sz,
+ (- Z.of_nat (pow2 sz) <= z < Z.of_nat (pow2 sz))%Z ->
+ wordToZ (ZToWord (S sz) z) = z.
+Proof.
+ unfold wordToZ, ZToWord; intros.
+ destruct z.
+ - rewrite wmsb_wzero'.
+ rewrite wordToN_wzero'.
+ reflexivity.
+
+ - rewrite posToWord_nat.
+ remember (wmsb (natToWord (S sz) (Pos.to_nat p)) false) as msb.
+ destruct msb.
+ + exfalso.
+ simpl in H; destruct H.
+ apply eq_sym, wmsb_true_bound in Heqmsb.
+ rewrite <-positive_N_nat, <-NToWord_nat in Heqmsb.
+ rewrite <-positive_nat_Z in H0.
+ apply Nat2Z.inj_lt in H0.
+ rewrite <-positive_N_nat, <-Npow2_nat in H0.
+ apply Nlt_in in H0.
+ pose proof (wordToN_NToWord (S sz) (N.pos p)).
+ destruct H1 as [k [? ?]].
+ rewrite H1 in Heqmsb.
+ assert (N.pos p - k * Npow2 (S sz) <= N.pos p)%N by apply N.le_sub_l.
+ assert (Npow2 sz <= N.pos p)%N by (etransitivity; eassumption).
+ apply N.le_ngt in H4; auto.
+ + rewrite wordToN_nat, wordToNat_natToWord_2.
+ * rewrite positive_nat_N; reflexivity.
+ * rewrite <-Npow2_nat, <-positive_N_nat.
+ apply Nlt_out.
+ destruct H.
+ rewrite <-N2Z.inj_pos, <-N_nat_Z in H0.
+ apply Nat2Z.inj_lt in H0.
+ rewrite <-Npow2_nat in H0.
+ apply Nlt_in.
+ rewrite Npow2_S, N2Nat.inj_add.
+ omega.
+
+ - rewrite wneg_idempotent.
+ rewrite posToWord_nat.
+ remember (wmsb (wneg (natToWord (S sz) (Pos.to_nat p))) false) as msb.
+ destruct msb.
+ + rewrite wordToN_nat, wordToNat_natToWord_2.
+ * rewrite positive_nat_N; reflexivity.
+ * rewrite <-Npow2_nat, <-positive_N_nat.
+ apply Nlt_out.
+ destruct H.
+ apply Z.opp_le_mono in H.
+ rewrite Pos2Z.opp_neg, Z.opp_involutive in H.
+ rewrite <-N2Z.inj_pos, <-N_nat_Z in H.
+ apply Nat2Z.inj_le in H.
+ rewrite <-Npow2_nat in H.
+ apply Nlt_in.
+ rewrite Npow2_S, N2Nat.inj_add.
+ assert (N.to_nat (Npow2 sz) > 0)%nat by (rewrite Npow2_nat; apply pow2_zero).
+ omega.
+ + exfalso.
+ simpl in H.
+ apply eq_sym, wmsb_false_bound in Heqmsb.
+ rewrite wneg_wordToN in Heqmsb.
+ * rewrite Npow2_S in Heqmsb.
+ rewrite <-N.add_0_r in Heqmsb.
+ rewrite <-N.add_sub_assoc in Heqmsb.
+ { apply N.add_lt_mono_l in Heqmsb.
+ exfalso; eapply N.nlt_0_r; eauto.
+ }
+ { destruct H.
+ apply Z.opp_le_mono in H.
+ rewrite Pos2Z.opp_neg, Z.opp_involutive in H.
+ rewrite <-N2Z.inj_pos, <-N_nat_Z in H.
+ apply Nat2Z.inj_le in H.
+ rewrite positive_N_nat in H.
+ rewrite <-positive_N_nat, <-NToWord_nat.
+ pose proof (wordToN_NToWord (S sz) (N.pos p)).
+ destruct H1 as [k [? ?]]; rewrite H1.
+ etransitivity; [apply N.le_sub_l|].
+ rewrite <-Npow2_nat in H.
+ rewrite <-positive_N_nat in H.
+ unfold N.le; rewrite N2Nat.inj_compare.
+ apply nat_compare_le; auto.
+ }
+ * intro Hx.
+ replace 0%N with (wordToN (wzero (S sz))) in Hx by apply wordToN_wzero.
+ apply wordToN_inj in Hx.
+ assert (wordToNat (natToWord (S sz) (Pos.to_nat p)) = 0)
+ by (rewrite Hx; apply wordToNat_wzero).
+ rewrite wordToNat_natToWord_2 in H0.
+ { clear -H0.
+ induction p; simpl in H0; try discriminate.
+ elim IHp; rewrite Pos2Nat.inj_xO in H0; omega.
+ }
+ { destruct H.
+ apply Z.opp_le_mono in H.
+ rewrite Pos2Z.opp_neg, Z.opp_involutive in H.
+ rewrite <-N2Z.inj_pos, <-N_nat_Z in H.
+ apply Nat2Z.inj_le in H.
+ rewrite positive_N_nat in H.
+ simpl.
+ pose proof (pow2_zero sz).
+ omega.
+ }
+Qed.
+
+Lemma wordToZ_wordToN:
+ forall sz (w: word sz),
+ wordToZ w = (Z.of_N (wordToN w) - Z.of_N (if wmsb w false then Npow2 sz else 0))%Z.
+Proof.
+ unfold wordToZ; intros.
+ remember (wmsb w false) as msb; destruct msb;
+ [|simpl; rewrite Z.sub_0_r; reflexivity].
+ destruct (weq w (wzero _)); subst;
+ [rewrite wmsb_wzero in Heqmsb; discriminate|].
+ rewrite wneg_wordToN.
+ - pose proof (wordToN_bound w).
+ replace (Z.of_N (wordToN w) - Z.of_N (Npow2 sz))%Z
+ with (- (Z.of_N (Npow2 sz) - Z.of_N (wordToN w)))%Z by omega.
+ rewrite <-N2Z.inj_sub by (apply N.lt_le_incl; assumption).
+ clear; destruct (Npow2 sz - wordToN w)%N; reflexivity.
+ - intro Hx; elim n.
+ rewrite <-wordToN_wzero with (sz:= sz) in Hx.
+ apply wordToN_inj in Hx; auto.
+Qed.
+
+Lemma ZToWord_Z_of_N:
+ forall sz n,
+ ZToWord sz (Z.of_N n) = NToWord sz n.
+Proof.
+ unfold ZToWord, NToWord; intros.
+ destruct n; reflexivity.
+Qed.
+
+Lemma ZToWord_Z_of_nat: forall sz x, ZToWord sz (Z.of_nat x) = natToWord sz x.
+Proof.
+ intros.
+ rewrite <- nat_N_Z.
+ rewrite ZToWord_Z_of_N.
+ rewrite NToWord_nat.
+ rewrite Nnat.Nat2N.id.
+ reflexivity.
+Qed.
+
+Lemma natToWord_Z_to_nat: forall sz n,
+ (0 <= n)%Z ->
+ natToWord sz (Z.to_nat n) = ZToWord sz n.
+Proof.
+ intros. rewrite <- ZToWord_Z_of_nat.
+ rewrite Z2Nat.id by assumption.
+ reflexivity.
+Qed.
+
+Lemma ZToWord_sz0: forall z, ZToWord 0 z = $0.
+Proof.
+ intros. unfold ZToWord. destruct z; try rewrite posToWord_sz0; reflexivity.
+Qed.
+
+Lemma natToWord_pow2_add:
+ forall sz n,
+ natToWord sz (n + pow2 sz) = natToWord sz n.
+Proof.
+ induction sz; intros; [reflexivity|].
+ unfold natToWord, pow2; fold natToWord pow2.
+ rewrite drop_mod2_add, div2_plus_2, IHsz.
+ reflexivity.
+Qed.
+
+Lemma nat_add_pow2_wzero:
+ forall sz n1 n2,
+ n1 + n2 = pow2 sz ->
+ natToWord sz n1 ^+ natToWord sz n2 = wzero sz.
+Proof.
+ intros.
+ rewrite <-natToWord_plus, H.
+ rewrite natToWord_pow2.
+ reflexivity.
+Qed.
+
+Lemma Npos_Npow2_wzero:
+ forall sz p1 p2,
+ N.pos (p1 + p2) = Npow2 sz ->
+ posToWord sz p1 ^+ posToWord sz p2 = wzero sz.
+Proof.
+ intros.
+ do 2 rewrite posToWord_nat.
+ assert (Pos.to_nat p1 + Pos.to_nat p2 = pow2 sz).
+ { rewrite <-Pos2Nat.inj_add, <-Npow2_nat.
+ rewrite <-positive_N_nat.
+ rewrite H; reflexivity.
+ }
+ apply nat_add_pow2_wzero; auto.
+Qed.
+
+Lemma ZToWord_Npow2_sub:
+ forall sz z,
+ ZToWord sz (z - Z.of_N (Npow2 sz)) = ZToWord sz z.
+Proof.
+ unfold ZToWord; intros.
+ remember (z - Z.of_N (Npow2 sz))%Z as zz.
+ destruct z.
+ - destruct zz.
+ + assert (Z.of_N (Npow2 sz) = 0)%Z by omega.
+ change 0%Z with (Z.of_N 0%N) in H.
+ apply N2Z.inj in H.
+ exfalso; eapply Npow2_not_zero; eauto.
+ + pose proof (N2Z.is_nonneg (Npow2 sz)).
+ destruct (Z.of_N (Npow2 sz)); simpl in Heqzz, H;
+ try discriminate.
+ pose proof (Pos2Z.neg_is_neg p0); omega.
+ + assert (Z.of_N (Npow2 sz) = Z.pos p).
+ { rewrite Z.sub_0_l, <-Pos2Z.opp_pos in Heqzz.
+ apply Z.opp_inj in Heqzz; auto.
+ }
+ rewrite <-N2Z.inj_pos in H.
+ apply N2Z.inj in H.
+ rewrite posToWord_nat, <-positive_N_nat, <-H.
+ rewrite Npow2_nat, natToWord_pow2.
+ rewrite wzero_wneg.
+ apply eq_sym, wzero'_def.
+
+ - destruct zz.
+ + assert (Z.of_N (Npow2 sz) = Z.pos p) by omega.
+ rewrite <-N2Z.inj_pos in H.
+ apply N2Z.inj in H.
+ rewrite posToWord_nat, <-positive_N_nat, <-H.
+ rewrite Npow2_nat, natToWord_pow2.
+ apply wzero'_def.
+ + assert (Z.pos p = Z.pos p0 + Z.of_N (Npow2 sz))%Z by omega.
+ do 2 rewrite <-N2Z.inj_pos in H.
+ rewrite <-N2Z.inj_add in H.
+ apply N2Z.inj in H.
+ apply eq_sym.
+ do 2 rewrite posToWord_nat, <-positive_N_nat.
+ rewrite H, N2Nat.inj_add, Npow2_nat.
+ apply natToWord_pow2_add.
+ + assert (Z.pos p - Z.neg p0 = Z.of_N (Npow2 sz))%Z by omega.
+ simpl in H.
+ remember (Npow2 sz) as n; destruct n;
+ [exfalso; eapply Npow2_not_zero; eauto|].
+ rewrite N2Z.inj_pos in H; inversion H; subst; clear H.
+ apply eq_sym, sub_0_eq.
+ rewrite wminus_def, wneg_idempotent.
+ apply Npos_Npow2_wzero; auto.
+
+ - destruct zz.
+ + assert (Z.neg p = Z.of_N (Npow2 sz))%Z by omega.
+ pose proof (N2Z.is_nonneg (Npow2 sz)).
+ rewrite <-H in H0.
+ pose proof (Pos2Z.neg_is_neg p); omega.
+ + assert (Z.neg p = Z.pos p0 + Z.of_N (Npow2 sz))%Z by omega.
+ pose proof (N2Z.is_nonneg (Npow2 sz)).
+ destruct (Z.of_N (Npow2 sz)); simpl in H;
+ try discriminate.
+ pose proof (Pos2Z.neg_is_neg p1); omega.
+ + assert (Pos.to_nat p0 = Pos.to_nat p + pow2 sz).
+ { rewrite <-Npow2_nat.
+ do 2 rewrite <-positive_N_nat.
+ rewrite <-N2Nat.inj_add.
+ f_equal.
+ pose proof (N2Z.is_nonneg (Npow2 sz)).
+ remember (Z.of_N (Npow2 sz)) as z; destruct z.
+ { change 0%Z with (Z.of_N 0) in Heqz.
+ apply N2Z.inj in Heqz.
+ exfalso; eapply Npow2_not_zero; eauto.
+ }
+ { simpl in Heqzz; inversion Heqzz; subst.
+ rewrite <-N2Z.inj_pos in Heqz.
+ apply N2Z.inj in Heqz.
+ rewrite <-Heqz.
+ reflexivity.
+ }
+ { pose proof (Zlt_neg_0 p1); omega. }
+ }
+ f_equal.
+ do 2 rewrite posToWord_nat.
+ rewrite H.
+ apply natToWord_pow2_add.
+Qed.
+
+Lemma wplus_wplusZ:
+ forall sz (w1 w2: word sz),
+ w1 ^+ w2 = wplusZ w1 w2.
+Proof.
+ unfold wplus, wplusZ, wordBin, wordBinZ; intros.
+ do 2 rewrite wordToZ_wordToN.
+ match goal with
+ | [ |- context[(?z1 - ?z2 + (?z3 - ?z4))%Z] ] =>
+ replace (z1 - z2 + (z3 - z4))%Z with (z1 + z3 - z2 - z4)%Z by omega
+ end.
+ rewrite <-N2Z.inj_add.
+ destruct (wmsb w1 false); destruct (wmsb w2 false).
+ - simpl; do 2 rewrite ZToWord_Npow2_sub.
+ apply eq_sym, ZToWord_Z_of_N.
+ - simpl; rewrite Z.sub_0_r, ZToWord_Npow2_sub.
+ apply eq_sym, ZToWord_Z_of_N.
+ - simpl; rewrite Z.sub_0_r, ZToWord_Npow2_sub.
+ apply eq_sym, ZToWord_Z_of_N.
+ - simpl; do 2 rewrite Z.sub_0_r.
+ apply eq_sym, ZToWord_Z_of_N.
+Qed.
+
+Lemma ZToWord_Npow2_sub_k : forall (sz : nat) (z : Z) (k: nat),
+ ZToWord sz (z - Z.of_nat k * Z.of_N (Npow2 sz)) = ZToWord sz z.
+Proof.
+ intros. induction k.
+ - simpl. f_equal. omega.
+ - rewrite <- IHk.
+ replace (z - Z.of_nat (S k) * Z.of_N (Npow2 sz))%Z
+ with ((z - Z.of_nat k * Z.of_N (Npow2 sz)) - Z.of_N (Npow2 sz))%Z by nia.
+ apply ZToWord_Npow2_sub.
+Qed.
+
+Lemma ZToWord_Npow2_add_k : forall (sz : nat) (z : Z) (k: nat),
+ ZToWord sz (z + Z.of_nat k * Z.of_N (Npow2 sz)) = ZToWord sz z.
+Proof.
+ intros.
+ replace z with (z + Z.of_nat k * Z.of_N (Npow2 sz) - Z.of_nat k * Z.of_N (Npow2 sz))%Z at 2
+ by omega.
+ symmetry.
+ apply ZToWord_Npow2_sub_k.
+Qed.
+
+Lemma ZToWord_Npow2_sub_z : forall (sz : nat) (z : Z) (k: Z),
+ ZToWord sz (z - k * Z.of_N (Npow2 sz)) = ZToWord sz z.
+Proof.
+ intros. destruct k.
+ - simpl. f_equal. omega.
+ - rewrite <- positive_nat_Z. apply ZToWord_Npow2_sub_k.
+ - rewrite <- Pos2Z.opp_pos.
+ replace (z - - Z.pos p * Z.of_N (Npow2 sz))%Z
+ with (z + Z.pos p * Z.of_N (Npow2 sz))%Z by nia.
+ rewrite <- positive_nat_Z. apply ZToWord_Npow2_add_k.
+Qed.
+
+Lemma wordToZ_ZToWord': forall sz w,
+ exists k, wordToZ (ZToWord sz w) = (w - k * Z.of_N (Npow2 sz))%Z.
+Proof.
+ intros.
+ destruct sz.
+ - simpl. exists w%Z. rewrite ZToWord_sz0. rewrite wordToZ_wzero. omega.
+ - exists ((w + Z.of_nat (pow2 sz)) / Z.of_N (Npow2 (S sz)))%Z.
+ erewrite <- ZToWord_Npow2_sub_z.
+ rewrite wordToZ_ZToWord.
+ + reflexivity.
+ + replace w with ((- Z.of_nat (pow2 sz)) + (w + Z.of_nat (pow2 sz)))%Z at 1 3 by omega.
+ rewrite <- Z.add_sub_assoc.
+ replace (Z.of_N (Npow2 (S sz))) with (2 * Z.of_nat (pow2 sz))%Z.
+ * remember (Z.of_nat (pow2 sz)) as M.
+ assert (M > 0)%Z. {
+ subst. destruct (pow2 sz) eqn: E.
+ - exfalso. eapply pow2_ne_zero. exact E.
+ - simpl. constructor.
+ }
+ rewrite <- Zdiv.Zmod_eq_full by omega.
+ pose proof (Zdiv.Z_mod_lt (w + M) (2 * M)). omega.
+ * rewrite <- Npow2_nat. rewrite N_nat_Z.
+ rewrite Npow2_S. rewrite N2Z.inj_add. omega.
+Qed.
+
+Lemma ZToWord_plus: forall sz a b, ZToWord sz (a + b) = ZToWord sz a ^+ ZToWord sz b.
+Proof.
+ destruct sz as [|sz]; intros n m; intuition.
+ rewrite wplus_wplusZ.
+ unfold wplusZ, wordBinZ.
+ destruct (wordToZ_ZToWord' (S sz) n) as [k1 D1].
+ destruct (wordToZ_ZToWord' (S sz) m) as [k2 D2].
+ rewrite D1.
+ rewrite D2.
+ replace (n - k1 * Z.of_N (Npow2 (S sz)) + (m - k2 * Z.of_N (Npow2 (S sz))))%Z
+ with (n + m - (k1 + k2) * Z.of_N (Npow2 (S sz)))%Z by nia.
+ symmetry.
+ apply ZToWord_Npow2_sub_z.
+Qed.
+
+Lemma else_0_to_ex_N: forall (b: bool) (a: N),
+ exists k, (if b then a else 0%N) = (k * a)%N.
+Proof.
+ intros. destruct b.
+ - exists 1%N. nia.
+ - exists 0%N. reflexivity.
+Qed.
+
+Local Lemma wmultZ_helper: forall a b k1 k2 p,
+ ((a - k1 * p) * (b - k2 * p) = a * b - (k1 * b + k2 * a - k1 * k2 * p) * p)%Z.
+Proof. intros. nia. Qed.
+
+Lemma wmult_wmultZ: forall (sz : nat) (w1 w2 : word sz), w1 ^* w2 = wmultZ w1 w2.
+Proof.
+ unfold wmultZ, wmult, wordBinZ, wordBin. intros.
+ do 2 rewrite wordToZ_wordToN.
+ destruct (else_0_to_ex_N (wmsb w1 false) (Npow2 sz)) as [k1 E1]. rewrite E1. clear E1.
+ destruct (else_0_to_ex_N (wmsb w2 false) (Npow2 sz)) as [k2 E2]. rewrite E2. clear E2.
+ do 2 rewrite N2Z.inj_mul.
+ rewrite wmultZ_helper.
+ rewrite <- N2Z.inj_mul.
+ rewrite ZToWord_Npow2_sub_z.
+ rewrite ZToWord_Z_of_N.
+ reflexivity.
+Qed.
+
+Lemma ZToWord_mult: forall sz a b, ZToWord sz (a * b) = ZToWord sz a ^* ZToWord sz b.
+Proof.
+ intros. rewrite wmult_wmultZ. unfold wmultZ, wordBinZ.
+ destruct (wordToZ_ZToWord' sz a) as [k1 D1]. rewrite D1. clear D1.
+ destruct (wordToZ_ZToWord' sz b) as [k2 D2]. rewrite D2. clear D2.
+ rewrite wmultZ_helper.
+ symmetry.
+ apply ZToWord_Npow2_sub_z.
+Qed.
+
+Lemma ZToWord_0: forall sz, ZToWord sz 0 = wzero sz.
+Proof.
+ intros. unfold ZToWord. apply wzero'_def.
+Qed.
+
+Lemma wordToZ_wplus_bound:
+ forall sz (w1 w2: word (S sz)),
+ (- Z.of_nat (pow2 sz) <= wordToZ w1 + wordToZ w2 < Z.of_nat (pow2 sz))%Z ->
+ (wordToZ w1 + wordToZ w2 = wordToZ (w1 ^+ w2))%Z.
+Proof.
+ intros.
+ rewrite wplus_wplusZ.
+ unfold wplusZ, wordBinZ.
+ remember (wordToZ w1 + wordToZ w2)%Z as z; clear Heqz.
+ apply eq_sym, wordToZ_ZToWord; assumption.
+Qed.
+
+Lemma wordToZ_wplus_bound':
+ forall sz (w1 w2: word sz),
+ sz <> 0 ->
+ (- Z.of_nat (pow2 (pred sz)) <= wordToZ w1 + wordToZ w2 < Z.of_nat (pow2 (pred sz)))%Z ->
+ (wordToZ w1 + wordToZ w2 = wordToZ (w1 ^+ w2))%Z.
+Proof.
+ intros.
+ destruct sz; [exfalso; auto|clear H].
+ apply wordToZ_wplus_bound; auto.
+Qed.
+
+Lemma wordToZ_size':
+ forall sz (w: word (S sz)),
+ (- Z.of_nat (pow2 sz) <= wordToZ w < Z.of_nat (pow2 sz))%Z.
+Proof.
+ unfold wordToZ; intros.
+ remember (wmsb w false) as msb; destruct msb.
+ - destruct (weq w (wpow2 _)).
+ + subst; rewrite wpow2_wneg.
+ rewrite wpow2_Npow2.
+ remember (Npow2 sz) as np.
+ destruct np; [exfalso; eapply Npow2_not_zero; eauto|].
+ split.
+ * rewrite <-Pos2Z.opp_pos, <-N2Z.inj_pos.
+ rewrite Heqnp.
+ rewrite <-Npow2_nat.
+ rewrite N_nat_Z.
+ reflexivity.
+ * etransitivity.
+ { apply Pos2Z.neg_is_neg. }
+ { change 0%Z with (Z.of_nat 0).
+ apply Nat2Z.inj_lt.
+ apply zero_lt_pow2.
+ }
+ + assert (wordToN (wneg w) < Npow2 sz)%N.
+ { apply wmsb_false_bound.
+ eapply wmsb_wneg_true; eauto.
+ }
+ remember (wordToN (wneg w)) as ww; clear Heqww.
+ destruct ww; simpl.
+ * split; try omega.
+ change 0%Z with (Z.of_nat 0).
+ apply Nat2Z.inj_lt.
+ apply zero_lt_pow2.
+ * split.
+ { rewrite <-Pos2Z.opp_pos, <-N2Z.inj_pos.
+ rewrite <-Npow2_nat.
+ rewrite N_nat_Z.
+ rewrite <-Z.opp_le_mono.
+ apply N2Z.inj_le.
+ apply N.lt_le_incl.
+ assumption.
+ }
+ { etransitivity.
+ { apply Pos2Z.neg_is_neg. }
+ { change 0%Z with (Z.of_nat 0).
+ apply Nat2Z.inj_lt.
+ apply zero_lt_pow2.
+ }
+ }
+ - apply eq_sym, wmsb_false_bound in Heqmsb.
+ destruct (wordToN w); simpl.
+ * split; try omega.
+ change 0%Z with (Z.of_nat 0).
+ apply Nat2Z.inj_lt.
+ apply zero_lt_pow2.
+ * split.
+ { etransitivity.
+ { apply Z.opp_nonpos_nonneg.
+ change 0%Z with (Z.of_nat 0).
+ apply Nat2Z.inj_le.
+ pose proof (zero_lt_pow2 sz); omega.
+ }
+ { pose proof (Pos2Z.is_pos p); omega. }
+ }
+ { rewrite <-N2Z.inj_pos.
+ rewrite <-Npow2_nat.
+ rewrite N_nat_Z.
+ apply N2Z.inj_lt.
+ assumption.
+ }
+Qed.
+
+Lemma wordToZ_size:
+ forall sz (w: word (S sz)),
+ (Z.abs (wordToZ w) <= Z.of_nat (pow2 sz))%Z.
+Proof.
+ intros.
+ pose proof (wordToZ_size' w).
+ destruct H.
+ apply Z.abs_le.
+ split; omega.
+Qed.
+
+Lemma wneg_wzero:
+ forall sz (w: word sz), wneg w = wzero sz -> w = wzero sz.
+Proof.
+ intros.
+ pose proof (wminus_inv w).
+ rewrite H in H0.
+ rewrite wplus_comm, wplus_unit in H0; subst.
+ reflexivity.
+Qed.
+
+Lemma wmsb_false_pos:
+ forall sz (w: word sz),
+ wmsb w false = false <-> (wordToZ w >= 0)%Z.
+Proof.
+ unfold wordToZ; split; intros.
+ - rewrite H.
+ destruct (wordToN w).
+ + omega.
+ + pose proof (Zgt_pos_0 p); omega.
+ - remember (wmsb w false) as b; destruct b; auto.
+ remember (wordToN (wneg w)) as n; destruct n.
+ + replace 0%N with (wordToN (wzero sz)) in Heqn.
+ * apply wordToN_inj in Heqn.
+ apply eq_sym, wneg_wzero in Heqn; subst.
+ rewrite wmsb_wzero in Heqb; discriminate.
+ * rewrite <-wzero'_def.
+ apply wordToN_wzero'.
+ + exfalso; pose proof (Zlt_neg_0 p); omega.
+Qed.
+
+Lemma wmsb_true_neg:
+ forall sz (w: word sz),
+ wmsb w false = true <-> (wordToZ w < 0)%Z.
+Proof.
+ unfold wordToZ; split; intros.
+ - rewrite H.
+ remember (wordToN (wneg w)) as n; destruct n.
+ + replace 0%N with (wordToN (wzero sz)) in Heqn.
+ * apply wordToN_inj in Heqn.
+ apply eq_sym, wneg_wzero in Heqn; subst.
+ rewrite wmsb_wzero in H; discriminate.
+ * rewrite <-wzero'_def.
+ apply wordToN_wzero'.
+ + pose proof (Zlt_neg_0 p); omega.
+ - remember (wmsb w false) as b; destruct b; auto.
+ remember (wordToN w) as n; destruct n.
+ + omega.
+ + pose proof (Zgt_pos_0 p); omega.
+Qed.
+
+Lemma wordToZ_distr_diff_wmsb:
+ forall sz (w1 w2: word sz),
+ wmsb w1 false = negb (wmsb w2 false) ->
+ wordToZ (w1 ^+ w2) = (wordToZ w1 + wordToZ w2)%Z.
+Proof.
+ intros.
+ destruct sz;
+ [rewrite (shatter_word w1), (shatter_word w2); reflexivity|].
+ eapply eq_sym, wordToZ_wplus_bound.
+ pose proof (wordToZ_size' w1).
+ pose proof (wordToZ_size' w2).
+ remember (wmsb w1 false) as msb1; destruct msb1.
+ - apply eq_sym, wmsb_true_neg in Heqmsb1.
+ apply eq_sym, negb_true_iff, wmsb_false_pos in H.
+ destruct H0, H1.
+ split; omega.
+ - apply eq_sym, wmsb_false_pos in Heqmsb1.
+ apply eq_sym, negb_false_iff, wmsb_true_neg in H.
+ destruct H0, H1.
+ split; omega.
+Qed.
+
+Lemma sext_wplus_wordToZ_distr:
+ forall sz (w1 w2: word sz) n,
+ n <> 0 -> wordToZ (sext w1 n ^+ sext w2 n) =
+ (wordToZ (sext w1 n) + wordToZ (sext w2 n))%Z.
+Proof.
+ intros.
+ destruct n; [exfalso; auto|clear H].
+ apply eq_sym, wordToZ_wplus_bound'; [omega|].
+
+ do 2 rewrite sext_wordToZ.
+ destruct sz.
+ - rewrite (shatter_word w1), (shatter_word w2).
+ cbn; split; try (pose proof (pow2_zero n); omega).
+ - replace (pred (S sz + S n)) with (S (sz + n)) by omega.
+ pose proof (wordToZ_size' w1); destruct H.
+ pose proof (wordToZ_size' w2); destruct H1.
+ split.
+ + rewrite pow2_S_z.
+ etransitivity; [|apply Z.add_le_mono; eassumption].
+ rewrite <-Z.add_diag, Z.opp_add_distr.
+ apply Z.add_le_mono;
+ rewrite <-Z.opp_le_mono; apply Nat2Z.inj_le, pow2_le; omega.
+ + rewrite pow2_S_z.
+ eapply Z.lt_le_trans; [apply Z.add_lt_mono; eassumption|].
+ rewrite <-Z.add_diag.
+ apply Z.add_le_mono; apply Nat2Z.inj_le, pow2_le; omega.
+Qed.
+
+Lemma sext_wplus_wordToZ_distr_existT: (* Note: not axiom free *)
+ forall sz (w1 w2: word sz) ssz (sw1 sw2: word ssz) n,
+ existT word _ w1 = existT word _ (sext sw1 n) ->
+ existT word _ w2 = existT word _ (sext sw2 n) ->
+ n <> 0 -> wordToZ (w1 ^+ w2) = (wordToZ w1 + wordToZ w2)%Z.
+Proof.
+ intros.
+ assert (sz = ssz + n) by (apply eq_sigT_fst in H; auto); subst.
+ destruct_existT.
+ apply sext_wplus_wordToZ_distr; auto.
+Qed.
+
+Lemma split1_existT: (* Note: not axiom free *)
+ forall n sz1 (w1: word (n + sz1)) sz2 (w2: word (n + sz2)),
+ existT word _ w1 = existT word _ w2 ->
+ split1 n _ w1 = split1 n _ w2.
+Proof.
+ intros.
+ assert (sz1 = sz2) by (apply eq_sigT_fst in H; omega); subst.
+ destruct_existT.
+ reflexivity.
+Qed.
+
+Lemma word_combinable:
+ forall sz1 sz2 (w: word (sz1 + sz2)),
+ exists w1 w2, w = combine w1 w2.
+Proof.
+ intros.
+ exists (split1 _ _ w), (split2 _ _ w).
+ apply eq_sym, combine_split.
+Qed.
+
+Lemma split1_combine_existT: (* Note: not axiom free *)
+ forall sz n (w: word (n + sz)) sl (wl: word (n + sl)) su (wu: word su),
+ existT word _ w = existT word _ (combine wl wu) ->
+ split1 n _ w = split1 n _ wl.
+Proof.
+ intros.
+ pose proof (word_combinable _ _ w).
+ destruct H0 as [? [? ?]]; subst.
+ pose proof (word_combinable _ _ wl).
+ destruct H0 as [? [? ?]]; subst.
+ assert (sz = sl + su) by (apply eq_sigT_fst in H; omega); subst.
+ pose proof (word_combinable _ _ x0).
+ destruct H0 as [? [? ?]]; subst.
+ do 2 rewrite split1_combine.
+ rewrite combine_assoc_existT in H.
+ destruct_existT.
+ assert (split1 _ _ (split1 _ _ (combine (combine x x3) x4)) =
+ split1 _ _ (split1 _ _ (combine (combine x1 x2) wu)))
+ by (rewrite H; reflexivity).
+ repeat rewrite split1_combine in H0.
+ assumption.
+Qed.
+
+Lemma extz_pow2_wordToZ:
+ forall sz (w: word sz) n,
+ wordToZ (extz w n) = (wordToZ w * Z.of_nat (pow2 n))%Z.
+Proof.
+ induction n; [cbn; omega|].
+ rewrite pow2_S_z.
+ change (wordToZ (extz w (S n))) with (wordToZ (combine (natToWord n 0) w)~0).
+ rewrite wordToZ_WS_0.
+ unfold extz, wzero in IHn.
+ rewrite IHn.
+ rewrite Z.mul_assoc.
+ rewrite Z.mul_comm with (n:= 2%Z).
+ apply eq_sym, Z.mul_assoc.
+Qed.
+
+Lemma extz_wneg:
+ forall sz (w: word sz) n,
+ extz (wneg w) n = wneg (extz w n).
+Proof.
+ induction n; intros; [reflexivity|].
+ cbn; rewrite wneg_WS_0.
+ unfold extz, wzero in IHn.
+ rewrite IHn.
+ reflexivity.
+Qed.
+
+Lemma wneg_wordToZ:
+ forall sz (w: word (S sz)),
+ w <> wpow2 sz ->
+ wordToZ (wneg w) = (- wordToZ w)%Z.
+Proof.
+ intros.
+ assert (wordToZ (wneg w) + wordToZ w = 0)%Z.
+ { destruct (weq w (wzero _)).
+ { subst; rewrite wzero_wneg, wordToZ_wzero.
+ reflexivity.
+ }
+ { rewrite <-wordToZ_distr_diff_wmsb.
+ { rewrite wplus_comm, wminus_inv.
+ apply wordToZ_wzero.
+ }
+ { remember (wmsb w false) as msb; destruct msb.
+ { eapply wmsb_wneg_true; eauto. }
+ { eapply wmsb_wneg_false; eauto.
+ intro Hx; elim n.
+ apply wordToNat_inj.
+ rewrite wordToNat_wzero, Hx; reflexivity.
+ }
+ }
+ }
+ }
+ omega.
+Qed.
+
+Lemma wneg_wordToZ':
+ forall sz (w: word (S sz)) z,
+ w <> wpow2 sz ->
+ (z + wordToZ (wneg w))%Z = (z - wordToZ w)%Z.
+Proof.
+ intros.
+ rewrite wneg_wordToZ by assumption.
+ omega.
+Qed.
+
+Lemma wneg_wplus_distr:
+ forall sz (w1 w2: word sz),
+ wneg (w1 ^+ w2) = wneg w1 ^+ wneg w2.
+Proof.
+ intros.
+ apply wplus_cancel with (c:= w1 ^+ w2).
+ rewrite wplus_comm, wminus_inv.
+ rewrite wplus_comm, wplus_assoc.
+ rewrite <-wplus_assoc with (x:= w1).
+ rewrite wplus_comm with (x:= w2).
+ rewrite wplus_assoc.
+ rewrite wminus_inv.
+ rewrite wplus_wzero_2.
+ rewrite wminus_inv.
+ reflexivity.
+Qed.
+
+Lemma wminus_wneg:
+ forall sz (w1 w2: word sz),
+ wneg (w1 ^- w2) = w2 ^- w1.
+Proof.
+ unfold wminus; intros.
+ rewrite wneg_wplus_distr.
+ rewrite wneg_idempotent.
+ apply wplus_comm.
+Qed.
+
+Lemma wminus_wordToZ:
+ forall sz (w1 w2: word (S sz)),
+ w2 ^- w1 <> wpow2 sz ->
+ wordToZ (w1 ^- w2) = (- wordToZ (w2 ^- w1))%Z.
+Proof.
+ intros.
+ rewrite <-wneg_idempotent with (w:= w1 ^- w2).
+ rewrite wminus_wneg.
+ rewrite wneg_wordToZ by assumption.
+ reflexivity.
+Qed.
+
+Lemma wminus_wordToZ':
+ forall sz (w1 w2: word (sz + 1)),
+ existT word _ (w2 ^- w1) <> existT word _ (wpow2 sz) ->
+ wordToZ (w1 ^- w2) = (- wordToZ (w2 ^- w1))%Z.
+Proof.
+ intro sz.
+ replace (sz + 1) with (S sz) by omega.
+ intros.
+ apply wminus_wordToZ.
+ intro Hx; elim H.
+ rewrite Hx; reflexivity.
+Qed.
+
+Lemma wminus_wminusZ: forall (sz : nat) (w1 w2 : word sz), w1 ^- w2 = wminusZ w1 w2.
+Proof.
+ unfold wminusZ, wminus, wordBinZ. intros. rewrite <- Z.add_opp_r.
+ rewrite wplus_wplusZ. unfold wplusZ, wordBinZ.
+ destruct sz.
+ - do 2 rewrite ZToWord_sz0. reflexivity.
+ - destruct (weq w2 (wpow2 sz)).
+ + subst. rewrite wpow2_wneg.
+ replace (wordToZ w1 + - wordToZ (wpow2 sz))%Z
+ with (wordToZ w1 + wordToZ (wpow2 sz) - 2 * wordToZ (wpow2 sz))%Z by omega.
+ replace (2 * wordToZ (wpow2 sz))%Z with (- 1 * Z.of_N (Npow2 (S sz)))%Z.
+ * symmetry. apply ZToWord_Npow2_sub_z.
+ * rewrite wordToZ_wordToN.
+ rewrite wpow2_wmsb.
+ rewrite wpow2_Npow2.
+ rewrite Npow2_S.
+ rewrite N2Z.inj_add.
+ omega.
+ + rewrite wneg_wordToZ by assumption. reflexivity.
+Qed.
+
+Local Lemma wminusZ_helper: forall a b k1 k2 p,
+ ((a - k1 * p) - (b - k2 * p) = a - b - (k1 - k2) * p)%Z.
+Proof. intros. nia. Qed.
+
+Lemma ZToWord_minus: forall sz a b, ZToWord sz (a - b) = ZToWord sz a ^- ZToWord sz b.
+Proof.
+ intros. rewrite wminus_wminusZ. unfold wminusZ, wordBinZ.
+ destruct (wordToZ_ZToWord' sz a) as [k1 D1]. rewrite D1. clear D1.
+ destruct (wordToZ_ZToWord' sz b) as [k2 D2]. rewrite D2. clear D2.
+ rewrite wminusZ_helper.
+ symmetry.
+ apply ZToWord_Npow2_sub_z.
+Qed.
+
+Lemma extz_zero:
+ forall sz n, extz (natToWord sz 0) n = wzero _.
+Proof.
+ unfold wzero; intros.
+ rewrite extz_combine.
+ apply combine_zero.
+Qed.
+
+Lemma sext_eq_rect:
+ forall sz (w: word sz) n nsz Hsz1,
+ exists Hsz2,
+ eq_rect (sz + n) word (sext w n) (nsz + n) Hsz1 =
+ sext (eq_rect sz word w nsz Hsz2) n.
+Proof.
+ intros.
+ assert (Hsz: sz = nsz) by omega.
+ exists Hsz.
+ subst; simpl.
+ eq_rect_simpl.
+ reflexivity.
+Qed.
+
+Lemma wmsb_sext:
+ forall sz (w: word sz) n,
+ wmsb (sext w n) false = wmsb w false.
+Proof.
+ unfold sext; intros.
+ remember (wmsb w false) as ww; destruct ww.
+ - destruct n; cbn.
+ + rewrite wmsb_combine_WO; auto.
+ + rewrite wmsb_combine with (b2:= false) by discriminate; cbn.
+ clear; induction n; cbn; auto.
+ - destruct n; cbn.
+ + rewrite wmsb_combine_WO; auto.
+ + rewrite wmsb_combine with (b2:= false) by discriminate; cbn.
+ clear; induction n; cbn; auto.
+Qed.
+
+Lemma wmsb_wlshift_sext: (* Note: not axiom free *)
+ forall sz (w: word sz) n,
+ wmsb (sext w n) false = wmsb (wlshift (sext w n) n) false.
+Proof.
+ intros.
+ pose proof (wlshift_sext_extz w n).
+ apply wmsb_existT with (b:= false) in H.
+ rewrite H.
+ rewrite wmsb_sext.
+ rewrite wmsb_extz.
+ reflexivity.
+Qed.
+
+Lemma wordToZ_wordToNat_pos:
+ forall sz (w: word sz),
+ wmsb w false = false ->
+ Z.of_nat (wordToNat w) = wordToZ w.
+Proof.
+ unfold wordToZ; intros.
+ rewrite H.
+ rewrite <-wordToN_to_nat.
+ destruct (wordToN w).
+ - reflexivity.
+ - simpl; apply positive_nat_Z.
+Qed.
+
+Corollary wmsb_Zabs_pos:
+ forall sz (w: word sz),
+ wmsb w false = false -> Z.abs (wordToZ w) = wordToZ w.
+Proof.
+ intros.
+ apply wmsb_false_pos in H.
+ unfold Z.abs.
+ destruct (wordToZ w); auto.
+ pose proof (Zlt_neg_0 p); omega.
+Qed.
+
+Corollary wmsb_Zabs_neg:
+ forall sz (w: word sz),
+ wmsb w false = true -> (Z.abs (wordToZ w) = - wordToZ w)%Z.
+Proof.
+ intros.
+ apply wmsb_true_neg in H.
+ unfold Z.abs.
+ destruct (wordToZ w); auto.
+ pose proof (Zgt_pos_0 p); omega.
+Qed.
+
+Lemma wordToN_combine:
+ forall sz1 (w1: word sz1) sz2 (w2: word sz2),
+ wordToN (combine w1 w2) = (wordToN w1 + Npow2 sz1 * wordToN w2)%N.
+Proof.
+ intros.
+ repeat rewrite wordToN_nat.
+ rewrite pow2_N.
+ rewrite <-Nat2N.inj_mul, <-Nat2N.inj_add.
+ rewrite wordToNat_combine; reflexivity.
+Qed.
+
+Lemma word_exists_bound:
+ forall sz z,
+ (- Z.of_nat (pow2 sz) <= z < Z.of_nat (pow2 sz))%Z ->
+ exists w: word (S sz), wordToZ w = z.
+Proof.
+ intros.
+ exists (ZToWord (S sz) z).
+ apply wordToZ_ZToWord; assumption.
+Qed.
+
+Lemma sext_size:
+ forall sz n (w: word (sz + n)),
+ sz <> 0 ->
+ (- Z.of_nat (pow2 (sz - 1)) <= wordToZ w < Z.of_nat (pow2 (sz - 1)))%Z ->
+ exists sw, w = sext sw n.
+Proof.
+ intros.
+ destruct sz; [exfalso; auto|clear H].
+ simpl in *.
+ replace (sz - 0) with sz in H0 by omega.
+ apply word_exists_bound in H0.
+ destruct H0 as [sw ?].
+ exists sw.
+ apply wordToZ_inj.
+ change (S (sz + n)) with (S sz + n).
+ rewrite sext_wordToZ.
+ auto.
+Qed.
+
+Lemma wordToZ_combine_WO:
+ forall sz (w: word sz),
+ wordToZ (combine w WO) = wordToZ w.
+Proof.
+ dependent induction w; [reflexivity|].
+ simpl; destruct b.
+ - destruct n; [rewrite (shatter_word w); reflexivity|].
+ change (S n + 0) with (S (n + 0)) in *.
+ do 2 rewrite wordToZ_WS_1.
+ rewrite IHw; reflexivity.
+ - do 2 rewrite wordToZ_WS_0.
+ rewrite IHw; reflexivity.
+Qed.
+
+Lemma combine_WO:
+ forall sz (w: word sz),
+ combine w WO = eq_rect _ word w _ (Nat.add_comm 0 sz).
+Proof.
+ intros.
+ apply wordToZ_inj.
+ rewrite wordToZ_eq_rect.
+ apply wordToZ_combine_WO.
+Qed.
+
+Lemma zext_zero:
+ forall sz (w: word sz),
+ zext w 0 = eq_rect _ word w _ (Nat.add_comm 0 sz).
+Proof.
+ unfold zext; intros.
+ apply combine_WO.
+Qed.
+
+Lemma wmsb_false_wordToNat_eq:
+ forall sz (w: word (S sz)),
+ wmsb w false = false ->
+ wordToNat w = wordToNat (split1 sz _ (eq_rect _ word w _ (Nat.add_comm 1 sz))).
+Proof.
+ intros.
+ remember (eq_rect _ word w _ (Nat.add_comm 1 sz)) as ww.
+ assert (wmsb ww false = false) by (subst; rewrite <-wmsb_eq_rect; assumption).
+ replace (wordToNat w) with (wordToNat ww) by (subst; rewrite wordToNat_eq_rect; reflexivity).
+ clear Heqww H w.
+ apply wmsb_false_split2_wzero in H0.
+ rewrite <-combine_split with (w:= ww) at 1.
+ rewrite wordToNat_combine.
+ rewrite <-H0.
+ cbn; omega.
+Qed.
+
+Lemma wordToZ_bound_weakened:
+ forall z n, (Z.abs z < n)%Z -> (- n <= z < n)%Z.
+Proof.
+ intros.
+ apply Z.abs_lt in H.
+ omega.
+Qed.
+
+Lemma zext_size:
+ forall sz n (w: word (sz + n)),
+ (- Z.of_nat (pow2 sz) <= wordToZ w < Z.of_nat (pow2 sz))%Z ->
+ wmsb w false = false ->
+ exists sw, w = zext sw n.
+Proof.
+ intros.
+ destruct n.
+ - exists (eq_rect _ word w _ (Nat.add_comm _ _)).
+ rewrite zext_zero.
+ apply eq_sym, eq_rect_2.
+ - apply word_exists_bound in H.
+ destruct H as [ssw ?].
+ assert (wmsb ssw false = false).
+ { apply wmsb_false_pos; apply wmsb_false_pos in H0.
+ rewrite H; assumption.
+ }
+ eexists.
+ apply wordToZ_inj.
+ rewrite zext_wordToNat_equal_Z by discriminate.
+ rewrite <-H.
+ rewrite <-wordToZ_wordToNat_pos by assumption.
+ rewrite wmsb_false_wordToNat_eq by assumption.
+ reflexivity.
+Qed.
+
+Lemma zext_size_1: (* Note: not axiom free *)
+ forall sz (w: word (sz + 1)),
+ wmsb w false = false ->
+ exists sw, w = zext sw 1.
+Proof.
+ intros.
+ apply zext_size; auto.
+ generalize dependent w.
+ replace (sz + 1) with (S sz) by omega.
+ intros.
+ unfold wordToZ.
+ rewrite H.
+ apply wmsb_false_bound in H.
+ remember (wordToN w) as n; destruct n; simpl.
+ - split.
+ + omega.
+ + pose proof (pow2_zero sz); omega.
+ - rewrite <-N2Z.inj_pos.
+ rewrite <-N_nat_Z.
+ split; [omega|].
+ apply inj_lt.
+ rewrite <-Npow2_nat.
+ apply Nlt_out; auto.
+Qed.
+
+Lemma sext_wplus_exist:
+ forall sz (w1 w2: word sz) n,
+ exists w: word (S sz),
+ existT word _ (sext w1 (S n) ^+ sext w2 (S n)) =
+ existT word _ (sext w n).
+Proof.
+ intros; eexists.
+ apply wordToZ_existT; [omega|].
+ rewrite sext_wplus_wordToZ_distr by discriminate.
+ do 3 rewrite sext_wordToZ.
+ assert (- Z.of_nat (pow2 sz) <= wordToZ w1 + wordToZ w2 < Z.of_nat (pow2 sz))%Z.
+ { clear n.
+ dependent destruction w1.
+ { rewrite (shatter_word w2); cbn; omega. }
+ { remember (WS b w1) as ww1; clear Heqww1 w1 b.
+ pose proof (wordToZ_size' ww1).
+ pose proof (wordToZ_size' w2).
+ destruct H, H0.
+ split.
+ { simpl; do 2 rewrite Nat2Z.inj_add; omega. }
+ { simpl; do 2 rewrite Nat2Z.inj_add; omega. }
+ }
+ }
+ apply wordToZ_ZToWord in H.
+ rewrite <-H.
+ reflexivity.
+Qed.
+
+(* Don't allow simpl to expand out these functions *)
+Arguments natToWord : simpl never.
+Arguments weq : simpl never.
+
+(* Making wlt_dec opaque is necessary to prevent the [exact H] in the
+ * example below from blowing up..
+ *)
+Global Opaque wlt_dec.
+Definition test_wlt_f (a : nat) (b : nat) : nat :=
+ if wlt_dec (natToWord 64 a) $0 then 0 else 0.
+Theorem test_wlt_f_example: forall x y z, test_wlt_f x y = 0 -> test_wlt_f x z = 0.
+Proof.
+ intros.
+ exact H.
+Qed.
+
+Lemma wordToNat_eq1: forall sz (a b: word sz), a = b -> wordToNat a = wordToNat b.
+Proof.
+ intros; subst; reflexivity.
+Qed.
+
+Lemma wordToNat_eq2: forall sz (a b: word sz), wordToNat a = wordToNat b -> a = b.
+Proof.
+ intros.
+ rewrite <- natToWord_wordToNat with (w := a).
+ rewrite <- natToWord_wordToNat with (w := b).
+ rewrite H.
+ reflexivity.
+Qed.
+
+Lemma wordToNat_lt1: forall sz (a b: word sz), a < b -> (wordToNat a < wordToNat b)%nat.
+Proof.
+ intros.
+ pre_nomega.
+ repeat rewrite wordToN_to_nat in H.
+ assumption.
+Qed.
+
+Lemma wordToNat_lt2: forall sz (a b: word sz), (wordToNat a < wordToNat b)%nat -> a < b.
+Proof.
+ intros.
+ pre_nomega.
+ repeat rewrite wordToN_to_nat.
+ assumption.
+Qed.
+
+Lemma wordToNat_gt1: forall sz (a b: word sz), a > b -> (wordToNat a > wordToNat b)%nat.
+Proof.
+ intros.
+ pre_nomega.
+ repeat rewrite wordToN_to_nat in H.
+ assumption.
+Qed.
+
+Lemma wordToNat_gt2: forall sz (a b: word sz), (wordToNat a > wordToNat b)%nat -> a > b.
+Proof.
+ intros.
+ pre_nomega.
+ repeat rewrite wordToN_to_nat.
+ assumption.
+Qed.
+
+Lemma wordToNat_le1: forall sz (a b: word sz), a <= b -> (wordToNat a <= wordToNat b)%nat.
+Proof.
+ intros.
+ pre_nomega.
+ repeat rewrite wordToN_to_nat in H.
+ assumption.
+Qed.
+
+Lemma wordToNat_le2: forall sz (a b: word sz), (wordToNat a <= wordToNat b)%nat -> a <= b.
+Proof.
+ intros.
+ pre_nomega.
+ repeat rewrite wordToN_to_nat.
+ assumption.
+Qed.
+
+Lemma wordToNat_ge1: forall sz (a b: word sz), a >= b -> (wordToNat a >= wordToNat b)%nat.
+Proof.
+ intros.
+ pre_nomega.
+ repeat rewrite wordToN_to_nat in H.
+ assumption.
+Qed.
+
+Lemma wordToNat_ge2: forall sz (a b: word sz), (wordToNat a >= wordToNat b)%nat -> a >= b.
+Proof.
+ intros.
+ pre_nomega.
+ repeat rewrite wordToN_to_nat.
+ assumption.
+Qed.
+
+Lemma wordToNat_neq1: forall sz (a b: word sz), a <> b -> wordToNat a <> wordToNat b.
+Proof.
+ unfold not.
+ intros.
+ apply wordToNat_eq2 in H0.
+ tauto.
+Qed.
+
+Lemma wordToNat_neq2: forall sz (a b: word sz), wordToNat a <> wordToNat b -> a <> b.
+Proof.
+ unfold not.
+ intros.
+ subst.
+ tauto.
+Qed.
+
+Lemma wordToNat_wplus': forall sz (a b: word sz),
+ (#a + #b < pow2 sz)%nat ->
+ #(a ^+ b) = #a + #b.
+Proof.
+ intros.
+ rewrite <-? wordToN_to_nat in *.
+ rewrite <-? Nnat.N2Nat.inj_add in *.
+ rewrite <- Npow2_nat in *.
+ apply Nlt_in in H.
+ rewrite wordToN_plus by assumption.
+ reflexivity.
+Qed.
+
+Lemma wordToNat_wmult': forall sz (a b: word sz),
+ (#a * #b < pow2 sz)%nat ->
+ #(a ^* b) = #a * #b.
+Proof.
+ intros.
+ rewrite <-? wordToN_to_nat in *.
+ rewrite <-? Nnat.N2Nat.inj_mul in *.
+ rewrite <- Npow2_nat in *.
+ apply Nlt_in in H.
+ rewrite wordToN_mult by assumption.
+ reflexivity.
+Qed.
+
+Lemma wordNotNot: forall sz (a b: word sz), (a <> b -> False) -> a = b.
+Proof.
+ intros.
+ destruct (weq a b); subst; tauto.
+Qed.
+
+Ltac pre_word_omega :=
+ unfold wzero, wone in *;
+ repeat match goal with
+ | H: @eq ?T ?a ?b |- _ =>
+ match T with
+ | word ?sz =>
+ apply (@wordToNat_eq1 sz a b) in H;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one in H;
+ simpl in H
+ end
+ | |- @eq ?T ?a ?b =>
+ match T with
+ | word ?sz =>
+ apply (@wordToNat_eq2 sz a b);
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one;
+ simpl
+ end
+ | H: ?a < ?b |- _ =>
+ apply wordToNat_lt1 in H;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one in H;
+ simpl in H
+ | |- ?a < ?b =>
+ apply wordToNat_lt2;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one;
+ simpl
+ | H: ?a > ?b |- _ =>
+ apply wordToNat_gt1 in H;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one in H;
+ simpl in H
+ | |- ?a > ?b =>
+ apply wordToNat_gt2;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one;
+ simpl
+ | H: ?a <= ?b |- _ =>
+ apply wordToNat_le1 in H;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one in H;
+ simpl in H
+ | |- ?a <= ?b =>
+ apply wordToNat_le2;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one;
+ simpl
+ | H: ?a > ?b -> False |- _ =>
+ apply wordToNat_le1 in H;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one in H;
+ simpl in H
+ | |- ?a > ?b -> False =>
+ apply wordToNat_le2;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one;
+ simpl
+ | H: ?a < ?b -> False |- _ =>
+ apply wordToNat_ge1 in H;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one in H;
+ simpl in H
+ | |- ?a < ?b -> False =>
+ apply wordToNat_ge2;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one;
+ simpl
+ | H: not (@eq ?T ?a ?b) |- _ =>
+ match T with
+ | word ?sz =>
+ apply (@wordToNat_neq1 sz a b) in H;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one in H;
+ simpl in H
+ end
+ | |- not (@eq ?T ?a ?b) =>
+ match T with
+ | word ?sz =>
+ apply (@wordToNat_neq2 sz a b);
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one;
+ simpl
+ end
+ | H: @eq ?T ?a ?b -> False |- _ =>
+ match T with
+ | word ?sz =>
+ apply (@wordToNat_neq1 sz a b) in H;
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one in H;
+ simpl in H
+ end
+ | |- @eq ?T ?a ?b -> False =>
+ match T with
+ | word ?sz =>
+ apply (@wordToNat_neq2 sz a b);
+ rewrite ?roundTrip_0, ?roundTrip_1, ?wones_pow2_minus_one;
+ simpl
+ end
+ | H: (@eq ?T ?a ?b -> False) -> False |- _ =>
+ match T with
+ | word ?sz =>
+ apply (@wordNotNot sz a b) in H
+ end
+ | H: (not (@eq ?T ?a ?b)) -> False |- _ =>
+ match T with
+ | word ?sz =>
+ apply (@wordNotNot sz a b) in H
+ end
+ | H: not (@eq ?T ?a ?b -> False) |- _ =>
+ match T with
+ | word ?sz =>
+ apply (@wordNotNot sz a b) in H
+ end
+ | H: not (not (@eq ?T ?a ?b)) |- _ =>
+ match T with
+ | word ?sz =>
+ apply (@wordNotNot sz a b) in H
+ end
+ end.
+
+
+Ltac word_omega := pre_word_omega; omega.
+
+
+
+Lemma word_le_ge_eq sz (w1 w2: word sz): w1 <= w2 -> w1 >= w2 -> w1 = w2.
+Proof.
+ intros; word_omega.
+Qed.
+
+Lemma word_le_zero sz (w: word sz): w <= wzero sz -> w = wzero sz.
+Proof.
+ intros; word_omega.
+Qed.
+
+Close Scope word_scope.
+
+Open Scope word_scope.
+Local Open Scope nat.
+
+Lemma wzero_wones: forall sz, sz >= 1 ->
+ natToWord sz 0 <> wones sz.
+Proof.
+ intros.
+ unfold not.
+ intros.
+ pose proof (f_equal (@wordToNat sz) H0) as sth.
+ unfold wzero in *.
+ rewrite roundTrip_0 in *.
+ rewrite wones_pow2_minus_one in sth.
+ destruct sz; [omega | ].
+ pose proof (NatLib.one_lt_pow2 sz).
+ omega.
+Qed.
+
+Lemma wzero_wplus: forall sz w, wzero sz ^+ w = w.
+Proof.
+ intros.
+ unfold wzero.
+ apply wplus_unit.
+Qed.
+
+Lemma wordToNat_nonZero sz (w: word sz):
+ w <> wzero sz -> wordToNat w > 0.
+Proof.
+ induction w; simpl; unfold wzero; simpl; intros.
+ - tauto.
+ - destruct b.
+ + omega.
+ + assert (sth: w <> (natToWord n 0)).
+ { intro.
+ subst.
+ tauto.
+ }
+ assert (sth2: wordToNat w <> 0).
+ { intro sth3.
+ specialize (IHw sth).
+ omega.
+ }
+ omega.
+Qed.
+
+Lemma split2_pow2: forall sz n,
+ 2 ^ sz <= n < 2 ^ S sz ->
+ wordToNat (split2 sz 1 (natToWord (sz + 1) n)) = 1.
+Proof.
+ intros.
+ rewrite wordToNat_split2.
+ simpl in *.
+ rewrite Nat.add_0_r in *.
+ (* pose proof (wordToNat_natToWord sz n). *)
+ rewrite wordToNat_natToWord_bound with (bound := wones _).
+ - destruct H.
+ assert (sth: pow2 sz <> 0) by omega.
+ pose proof (Nat.div_le_mono _ _ (pow2 sz) sth H) as sth2.
+ rewrite Nat.div_same in sth2 by auto.
+ apply Nat.lt_le_pred in H0.
+ pose proof (Nat.div_le_mono _ _ (pow2 sz) sth H0) as sth3.
+ rewrite <- Nat.sub_1_r in sth3.
+ assert (sth4: pow2 sz = 1 * pow2 sz) by omega.
+ rewrite sth4 in sth3 at 2.
+ assert (sth5: 1 * pow2 sz + pow2 sz - 1 = 1 * pow2 sz + (pow2 sz - 1)) by omega.
+ rewrite sth5 in sth3.
+ rewrite Nat.div_add_l in sth3 by omega.
+ rewrite Nat.div_small with (a := pow2 sz - 1) in sth3 by omega.
+ omega.
+ - rewrite wones_pow2_minus_one.
+ assert (sth: sz + 1 = S sz) by omega.
+ rewrite sth.
+ simpl.
+ omega.
+Qed.
+
+Lemma combine_wones_WO sz:
+ forall w, w <> wzero sz -> split2 sz 1 (combine (wones sz) ($ 0) ^+ combine w ($ 0)) = WO~1.
+Proof.
+ intros.
+ match goal with
+ | |- split2 _ _ (?a ^+ ?b) = _ =>
+ rewrite <- (@natToWord_wordToNat _ a);
+ rewrite <- (@natToWord_wordToNat _ b)
+ end.
+ rewrite <- natToWord_plus.
+ rewrite ?wordToNat_combine.
+ simpl.
+ rewrite wones_pow2_minus_one.
+ pose proof (wordToNat_bound w) as sth.
+ pose proof (wordToNat_nonZero H).
+ assert (sth2: 2^sz <= 2 ^ sz - 1 + wordToNat w < 2 ^ (S sz)). {
+ pose proof (pow2_zero sz) as sth3.
+ split; simpl; omega.
+ }
+ apply split2_pow2 in sth2.
+ rewrite Nat.mul_0_r.
+ rewrite ?Nat.add_0_r.
+ apply (f_equal (natToWord 1)) in sth2.
+ rewrite natToWord_wordToNat in sth2.
+ assumption.
+Qed.
+
+Lemma wordToNat_plus sz (w1 w2: word sz):
+ natToWord sz (wordToNat w1 + wordToNat w2) = w1 ^+ w2.
+Proof.
+ rewrite natToWord_plus.
+ rewrite ?natToWord_wordToNat.
+ auto.
+Qed.
+
+Lemma wordToNat_natToWord_eqn sz:
+ forall n,
+ wordToNat (natToWord sz n) = n mod (pow2 sz).
+Proof.
+ intros.
+ pose proof (wordToNat_natToWord sz n).
+ destruct H as [? [? ?]].
+ rewrite H.
+ assert (sth: pow2 sz * x = x * pow2 sz) by (apply Nat.mul_comm).
+ rewrite <- sth in *.
+ clear sth.
+ pose proof (wordToNat_bound (natToWord sz n)).
+ apply (Nat.mod_unique n (pow2 sz) x (n - pow2 sz * x)); try omega.
+Qed.
+
+Lemma mod_factor a b c:
+ b <> 0 ->
+ c <> 0 ->
+ (a mod (b * c)) mod b = a mod b.
+Proof.
+ intros.
+ pose proof (Nat.mod_mul_r a _ _ H H0).
+ rewrite H1.
+ rewrite Nat.add_mod_idemp_l by auto.
+ rewrite Nat.add_mod by auto.
+ assert (sth: b * ((a/b) mod c) = (a/b) mod c * b) by (apply Nat.mul_comm).
+ rewrite sth.
+ rewrite Nat.mod_mul by auto.
+ rewrite Nat.add_0_r.
+ rewrite Nat.mod_mod by auto.
+ auto.
+Qed.
+
+Lemma split1_combine_wplus sz1 sz2 (w11 w21: word sz1) (w12 w22: word sz2):
+ split1 _ _ (combine w11 w12 ^+ combine w21 w22) = w11 ^+ w21.
+Proof.
+ rewrite <- natToWord_wordToNat at 1.
+ rewrite wordToNat_split1.
+ rewrite <- wordToNat_plus.
+ rewrite ?wordToNat_combine.
+ assert (sth: #w11 + pow2 sz1 * #w12 + (#w21 + pow2 sz1 * #w22) = #w11 + #w21 + pow2 sz1 * (#w12 + #w22)) by ring.
+ rewrite wordToNat_natToWord_eqn.
+ rewrite sth.
+ rewrite Nat.pow_add_r.
+ assert (pow2 sz1 <> 0) by (pose proof (pow2_zero sz1); intro; omega).
+ assert (pow2 sz2 <> 0) by (pose proof (pow2_zero sz2); intro; omega).
+ rewrite mod_factor by auto.
+ rewrite Nat.add_mod by auto.
+ assert (sth2: pow2 sz1 * (# w12 + #w22) = (#w12 + #w22) * pow2 sz1) by ring.
+ rewrite sth2.
+ rewrite Nat.mod_mul by auto.
+ rewrite Nat.add_0_r.
+ rewrite Nat.mod_mod by auto.
+ rewrite <- wordToNat_natToWord_eqn.
+ rewrite natToWord_wordToNat.
+ rewrite natToWord_plus.
+ rewrite ?natToWord_wordToNat.
+ auto.
+Qed.
+
+Lemma div_2 a b:
+ b <> 0 ->
+ a < b * 2 ->
+ a >= b ->
+ a / b = 1.
+Proof.
+ intros.
+ assert (sth: b * 1 <= a) by omega.
+ pose proof (Nat.div_le_lower_bound a b 1 H sth).
+ pose proof (Nat.div_lt_upper_bound a b 2 H H0).
+ omega.
+Qed.
+
+Lemma mod_sub a b:
+ b <> 0 ->
+ a < b * 2 ->
+ a >= b ->
+ a mod b = a - b.
+Proof.
+ intros.
+ rewrite Nat.mod_eq; auto.
+ repeat f_equal.
+ rewrite div_2 by auto.
+ rewrite Nat.mul_1_r; auto.
+Qed.
+
+Lemma wordToNat_wneg_non_0 sz: forall (a: word sz),
+ a <> natToWord _ 0 ->
+ # (wneg a) = pow2 sz - #a.
+Proof.
+ intros.
+ unfold wneg.
+ rewrite pow2_N.
+ rewrite NToWord_nat.
+ rewrite Nnat.N2Nat.inj_sub.
+ rewrite wordToN_to_nat.
+ rewrite Nnat.Nat2N.id.
+ simpl.
+ rewrite wordToNat_natToWord_idempotent'; auto.
+ assert (#a <> 0) by word_omega.
+ pose proof (pow2_zero sz).
+ omega.
+Qed.
+
+Lemma wordToNat_wnot sz: forall (a: word sz),
+ # (wnot a) = pow2 sz - #a - 1.
+Proof.
+ intros.
+ rewrite wnot_def.
+ rewrite pow2_N.
+ rewrite NToWord_nat.
+ rewrite Nnat.N2Nat.inj_sub.
+ rewrite Nnat.N2Nat.inj_sub.
+ rewrite wordToN_to_nat.
+ rewrite Nnat.Nat2N.id.
+ simpl.
+ rewrite wordToNat_natToWord_idempotent'; auto.
+ pose proof (pow2_zero sz).
+ unfold Pos.to_nat; simpl.
+ omega.
+Qed.
+
+Lemma wzero_wor: forall sz w, w ^| wzero sz = w.
+Proof.
+ intros.
+ rewrite wor_comm.
+ rewrite wor_wzero.
+ auto.
+Qed.
+
+Lemma bool_prop1: forall a b, a && negb (a && b) = a && negb b.
+Proof.
+ destruct a, b; simpl; auto.
+Qed.
+
+Lemma wordToNat_wplus sz (w1 w2: word sz):
+ #(w1 ^+ w2) = (#w1 + #w2) mod (pow2 sz).
+Proof.
+ rewrite <- (natToWord_wordToNat w1) at 1.
+ rewrite <- (natToWord_wordToNat w2) at 1.
+ rewrite <- natToWord_plus.
+ rewrite wordToNat_natToWord_eqn.
+ auto.
+Qed.
+
+Lemma wordToNat_wmult : forall (sz : nat) (w1 w2 : word sz),
+ #(w1 ^* w2) = (#w1 * #w2) mod pow2 sz.
+Proof using .
+ clear. intros.
+ rewrite <- (natToWord_wordToNat w1) at 1.
+ rewrite <- (natToWord_wordToNat w2) at 1.
+ rewrite <- natToWord_mult.
+ rewrite wordToNat_natToWord_eqn.
+ reflexivity.
+Qed.
+
+Lemma wor_r_wzero_1 sz: (* Note: not axiom free *)
+ forall w1 w2,
+ w1 ^| w2 = natToWord sz 0 ->
+ w2 = natToWord sz 0.
+Proof.
+ induction w1; simpl; auto; intros.
+ pose proof (shatter_word w2) as sth.
+ simpl in sth.
+ rewrite sth in *.
+ unfold wor in H.
+ simpl in H.
+ unfold natToWord in H.
+ unfold natToWord.
+ fold (natToWord n (Nat.div2 0)) in *.
+ unfold Nat.div2, mod2 in *.
+ inversion H.
+ destruct_existT.
+ rewrite (IHw1 _ H2).
+ f_equal.
+ destruct b, (whd w2); auto.
+Qed.
+
+Lemma wor_r_wzero_2 sz: (* Note: not axiom free *)
+ forall w1 w2,
+ w1 ^| w2 = natToWord sz 0 ->
+ w1 = natToWord sz 0.
+Proof.
+ induction w1; simpl; auto; intros.
+ pose proof (shatter_word w2) as sth.
+ simpl in sth.
+ rewrite sth in *.
+ unfold wor in H.
+ simpl in H.
+ unfold natToWord in H.
+ unfold natToWord.
+ fold (natToWord n (Nat.div2 0)) in *.
+ unfold Nat.div2, mod2 in *.
+ inversion H.
+ destruct_existT.
+ rewrite (IHw1 _ H2).
+ f_equal.
+ destruct b, (whd w2); auto.
+Qed.
+
+Fixpoint countLeadingZerosWord ni no: word ni -> word no :=
+ match ni return word ni -> word no with
+ | 0 => fun _ => $ 0
+ | S m => fun e =>
+ if (weq (split2 m 1 (nat_cast (fun n => word n) (eq_sym (Nat.add_1_r m)) e)) WO~0)
+ then $ 1 ^+ @countLeadingZerosWord m no (split1 m 1 (nat_cast (fun n => word n) (eq_sym (Nat.add_1_r m)) e))
+ else $ 0
+ end.
+
+
+Lemma countLeadingZerosWord_le_len no ni:
+ ni < pow2 no ->
+ forall w: word ni, (countLeadingZerosWord no w <= natToWord _ ni)%word.
+Proof.
+ induction ni; simpl; auto; intros.
+ - word_omega.
+ - match goal with
+ | |- ((if ?P then _ else _) <= _)%word => destruct P; simpl; auto
+ end; [| word_omega].
+ assert (sth: ni < pow2 no) by omega.
+ specialize (IHni sth).
+ assert (sth1: natToWord no (S ni) = natToWord no (1 + ni)) by auto.
+ rewrite sth1.
+ rewrite natToWord_plus.
+ match goal with
+ | |- ((_ ^+ countLeadingZerosWord no ?P) <= _)%word => specialize (IHni P)
+ end.
+ match goal with
+ | |- (?a ^+ ?b <= ?c ^+ ?d)%word =>
+ rewrite (wplus_comm a b); rewrite (wplus_comm c d)
+ end.
+ pre_word_omega.
+ assert (sth2: no > 0). {
+ destruct no; [|omega].
+ destruct ni; simpl in *; try omega.
+ }
+ rewrite <- ?(@natplus1_wordplus1_eq _ _ (wones no)); auto.
+ + pre_word_omega.
+ rewrite wordToNat_natToWord_eqn.
+ rewrite Nat.mod_small; auto.
+ + pre_word_omega.
+ rewrite wordToNat_natToWord_eqn in IHni.
+ rewrite Nat.mod_small in IHni; auto.
+Qed.
+
+Lemma countLeadingZerosWord_le_len_nat no ni:
+ ni < pow2 no ->
+ forall w: word ni, #(countLeadingZerosWord no w) <= ni.
+Proof.
+ intros H w.
+ pose proof (countLeadingZerosWord_le_len H w) as sth.
+ pre_word_omega.
+ rewrite wordToNat_natToWord_idempotent' in * by assumption.
+ assumption.
+Qed.
+
+
+Lemma wordToNat_zero sz: forall (w: word sz), #w = 0 -> w = natToWord _ 0.
+Proof.
+ intros.
+ apply (f_equal (natToWord sz)) in H.
+ rewrite natToWord_wordToNat in H.
+ auto.
+Qed.
+
+Lemma wordToNat_notZero sz: forall (w: word sz), #w <> 0 -> w <> natToWord _ 0.
+Proof.
+ intros.
+ intro.
+ subst.
+ pose proof (wordToNat_wzero sz); unfold wzero in *.
+ tauto.
+Qed.
+
+
+Lemma natToWord_nzero sz x:
+ 0 < x ->
+ x < pow2 sz ->
+ natToWord sz x <> natToWord sz 0.
+Proof.
+ intros.
+ pre_word_omega.
+ rewrite wordToNat_natToWord_idempotent'; omega.
+Qed.
+
+Lemma pow2_lt_pow2_S:
+ forall n, pow2 n < pow2 (n+1).
+Proof.
+ induction n; simpl; omega.
+Qed.
+
+Lemma combine_shiftl_plus_n n x:
+ x < pow2 n ->
+ (combine (natToWord n x) WO~1) = (natToWord (n + 1) (pow2 n)) ^+ natToWord (n + 1) x.
+Proof.
+ intros.
+ apply wordToNat_eq2.
+ rewrite ?wordToNat_combine.
+ rewrite ?wordToNat_natToWord_idempotent'; simpl; auto.
+ rewrite <- wordToNat_plus.
+ pose proof (pow2_lt_pow2_S n) as sth.
+ rewrite ?wordToNat_natToWord_idempotent'; simpl; try omega.
+ rewrite ?wordToNat_natToWord_idempotent'; simpl; try omega.
+ apply Nat.lt_add_lt_sub_l.
+ rewrite Nat.add_1_r.
+ simpl.
+ omega.
+Qed.
+
+Lemma combine_natToWord_wzero n:
+ forall x,
+ x < pow2 n ->
+ combine (natToWord n x) (natToWord 1 0) = natToWord (n+1) x.
+Proof.
+ intros.
+ apply wordToNat_eq2.
+ rewrite ?wordToNat_combine.
+ simpl.
+ rewrite Nat.mul_0_r.
+ rewrite Nat.add_0_r.
+ pose proof (pow2_lt_pow2_S n) as sth2.
+ rewrite ?wordToNat_natToWord_idempotent' by omega.
+ reflexivity.
+Qed.
+
+Lemma word_cancel_l sz (a b c: word sz):
+ a = b -> c ^+ a = c ^+ b.
+Proof.
+ intro H; rewrite H; reflexivity.
+Qed.
+
+
+Lemma word_cancel_r sz (a b c: word sz):
+ a = b -> a ^+ c = b ^+ c.
+Proof.
+ intro H; rewrite H; reflexivity.
+Qed.
+
+Lemma word_cancel_m sz (a b c a' b': word sz):
+ a ^+ a' = b ^+ b'-> a ^+ c ^+ a' = b ^+ c ^+ b'.
+Proof.
+ intros.
+ assert (sth: a ^+ c ^+ a' = a ^+ a'^+ c ).
+ rewrite <- wplus_assoc.
+ rewrite wplus_comm with (y := a').
+ rewrite wplus_assoc.
+ reflexivity.
+ rewrite sth.
+ rewrite H.
+ rewrite <- wplus_assoc.
+ rewrite wplus_comm with (x := b').
+ rewrite wplus_assoc.
+ reflexivity.
+Qed.
+
+Lemma move_wplus_wminus sz (a b c: word sz):
+ a ^+ b = c <-> a = c ^- b.
+Proof.
+ split; intro.
+ + rewrite <- H.
+ rewrite wminus_def.
+ rewrite <- wplus_assoc.
+ rewrite wminus_inv.
+ rewrite wplus_wzero_1.
+ reflexivity.
+ + rewrite H.
+ rewrite wminus_def.
+ rewrite <- wplus_assoc.
+ rewrite wplus_comm with (x:= ^~b).
+ rewrite wminus_inv.
+ rewrite wplus_wzero_1.
+ reflexivity.
+Qed.
+
+Lemma move_wplus_pow2 sz (w1 w2: word (S sz)):
+ w1 = w2 ^+ $(pow2 sz) <->
+ w1 ^+ $(pow2 sz) = w2.
+Proof.
+ split.
+ + intro.
+ apply move_wplus_wminus.
+ rewrite wminus_def.
+ rewrite pow2_wneg.
+ assumption.
+ + intro.
+ apply move_wplus_wminus in H.
+ rewrite <- pow2_wneg.
+ assumption.
+Qed.
+
+Lemma move_wminus_pow2 sz (w1 w2: word (S sz)):
+ w1 = w2 ^- $(pow2 sz) <->
+ w1 ^- $(pow2 sz) = w2.
+Proof.
+ split.
+ + intro.
+ apply <- move_wplus_wminus.
+ rewrite pow2_wneg.
+ assumption.
+ + intro.
+ apply move_wplus_wminus.
+ rewrite <- pow2_wneg.
+ rewrite <- wminus_def.
+ assumption.
+Qed.
+
+Lemma pow2_wzero sz :
+ $(pow2 sz) = wzero sz.
+Proof.
+ apply wordToNat_eq2.
+ rewrite wordToNat_natToWord_eqn.
+ rewrite Nat.mod_same.
+ rewrite wordToNat_wzero; auto.
+ pose proof (zero_lt_pow2 sz) as sth.
+ omega.
+Qed.
+
+Lemma pow2_wplus_wzero sz:
+ $(pow2 sz) ^+ $(pow2 sz) = wzero (sz + 1).
+Proof.
+ apply wordToNat_eq2.
+ rewrite <- natToWord_plus.
+ rewrite <- mul2_add.
+ assert (pow2_1_mul: pow2 1 = 2) by auto.
+ rewrite <- pow2_1_mul at 2.
+ rewrite <- pow2_add_mul.
+ rewrite pow2_wzero; auto.
+Qed.
+
+Lemma wplus_wplus_pow2 sz (x1 x2 y1 y2: word (sz + 1)):
+ x1 = y1 ^+ $(pow2 sz) ->
+ x2 = y2 ^+ $(pow2 sz) ->
+ x1 ^+ x2 = y1 ^+ y2.
+Proof.
+ intros.
+ rewrite H.
+ rewrite <- wplus_assoc.
+ rewrite wplus_comm.
+ rewrite wplus_comm in H0.
+ rewrite H0.
+ rewrite wplus_assoc.
+ rewrite pow2_wplus_wzero.
+ rewrite wzero_wplus.
+ rewrite wplus_comm.
+ reflexivity.
+Qed.
+
+
+
+Lemma wlt_meaning sz (w1 w2: word sz):
+ (w1 < w2)%word <-> #w1 < #w2.
+Proof.
+ pose proof (@wordToNat_gt1 sz w2 w1).
+ pose proof (@wordToNat_gt2 sz w2 w1).
+ tauto.
+Qed.
+
+Lemma combine_wplus sz (w1 w2: word sz):
+ #w1 + #w2 < pow2 sz ->
+ forall sz' (w': word sz'),
+ combine (w1 ^+ w2) w' = combine w1 w' ^+ combine w2 ($ 0).
+Proof.
+ intros.
+ pre_word_omega.
+ rewrite wordToNat_wplus in *.
+ rewrite ?wordToNat_combine.
+ rewrite wordToNat_natToWord_idempotent' by (apply pow2_zero).
+ rewrite Nat.mul_0_r, Nat.add_0_r.
+ rewrite wordToNat_wplus.
+ rewrite Nat.mod_small by assumption.
+ assert (sth: #w1 + #w2 + pow2 sz * #w' = #w1 + pow2 sz * #w' + #w2) by ring.
+ rewrite <- sth; clear sth.
+ rewrite Nat.mod_small; auto.
+ rewrite Nat.pow_add_r.
+ assert (sth: pow2 sz' = 1 + (pow2 sz' - 1)) by (pose proof (pow2_zero sz'); omega).
+ rewrite sth; clear sth.
+ rewrite Nat.mul_add_distr_l.
+ rewrite Nat.mul_1_r.
+ pose proof (wordToNat_bound w').
+ pose proof (pow2_zero sz).
+ apply Nat.lt_le_pred in H0.
+ rewrite pred_of_minus in H0.
+ pose proof (mult_le_compat_l _ _ (pow2 sz) H0).
+ omega.
+Qed.
+
+Lemma word1_neq (w: word 1):
+ w <> WO~0 ->
+ w <> WO~1 ->
+ False.
+Proof.
+ shatter_word w; intros.
+ destruct x; tauto.
+Qed.
+
+Lemma combine_1 sz:
+ sz > 1 ->
+ natToWord (sz + 1) 1 = combine ($ 1) WO~0.
+Proof.
+ intros.
+ rewrite <- natToWord_wordToNat.
+ f_equal.
+ rewrite wordToNat_combine; simpl.
+ rewrite Nat.mul_0_r, Nat.add_0_r.
+ rewrite wordToNat_natToWord_idempotent'; auto.
+ destruct sz; simpl; try omega.
+ pose proof (pow2_zero sz).
+ omega.
+Qed.
+
+Lemma wordToNat_cast ni no (pf: ni = no):
+ forall w,
+ #w = #(match pf in _ = Y return _ Y with
+ | eq_refl => w
+ end).
+Proof.
+ destruct pf; intros; auto.
+Qed.
+
+
+Lemma countLeadingZerosWord_lt_len no ni:
+ ni < pow2 no ->
+ forall w: word ni,
+ w <> wzero ni ->
+ (countLeadingZerosWord no w < natToWord _ ni)%word.
+Proof.
+ induction ni; auto; intros.
+ - shatter_word w.
+ tauto.
+ - unfold countLeadingZerosWord; fold countLeadingZerosWord.
+ rewrite nat_cast_cast.
+ match goal with
+ | |- ((if ?P then _ else _) < _)%word => destruct P; simpl; auto
+ end.
+ + assert (sth: ni < pow2 no) by omega.
+ specialize (IHni sth).
+ assert (sth1: natToWord no (S ni) = natToWord no (1 + ni)) by auto.
+ rewrite sth1.
+ rewrite natToWord_plus.
+ match goal with
+ | |- ((_ ^+ countLeadingZerosWord no ?P) < _)%word => specialize (IHni P)
+ end.
+ match goal with
+ | |- (?a ^+ ?b < ?c ^+ ?d)%word =>
+ rewrite (wplus_comm a b); rewrite (wplus_comm c d)
+ end.
+ pre_word_omega.
+ assert (sth2: no > 0). {
+ destruct no; [|omega].
+ destruct ni; simpl in *; try omega.
+ }
+ apply wordToNat_zero in e.
+ match type of IHni with
+ | split1 ni 1 ?P <> _ -> _ =>
+ assert (sth3: #P <> 0) by (rewrite <- wordToNat_cast; auto);
+ apply wordToNat_notZero in sth3;
+ rewrite <- (combine_split ni 1 P) in sth3
+ end.
+ rewrite e in *.
+ match type of sth3 with
+ | combine ?P _ <> _ => destruct (weq P (natToWord _ 0));
+ [rewrite e0 in *; rewrite combine_zero in sth3; tauto|]
+ end.
+ specialize (IHni n).
+ rewrite <- ?(@natplus1_wordplus1_eq _ _ (wones no)); auto.
+ * pre_word_omega.
+ omega.
+ * pre_word_omega.
+ rewrite wordToNat_natToWord_eqn.
+ rewrite Nat.mod_small; auto.
+ * pre_word_omega.
+ rewrite wordToNat_natToWord_eqn in IHni.
+ rewrite Nat.mod_small in IHni; auto.
+ + pre_word_omega.
+ rewrite wordToNat_natToWord_idempotent'; auto; try omega.
+Qed.
+
+
+Fixpoint countLeadingZerosWord_nat ni: word ni -> nat :=
+ match ni return word ni -> nat with
+ | 0 => fun _ => 0
+ | S m => fun e =>
+ if (weq (split2 m 1 (nat_cast (fun n => word n) (eq_sym (Nat.add_1_r m)) e)) WO~0)
+ then 1 + @countLeadingZerosWord_nat m (split1 m 1 (nat_cast (fun n => word n) (eq_sym (Nat.add_1_r m)) e))
+ else 0
+ end.
+
+Lemma countLeadingZerosWord_nat_correct ni:
+ forall no (w: word ni),
+ ni < pow2 no ->
+ #(countLeadingZerosWord no w) = countLeadingZerosWord_nat w.
+Proof.
+ induction ni; intros; simpl; auto.
+ - rewrite ?wordToNat_natToWord_idempotent'; auto.
+ - match goal with
+ | |- # (if ?P then _ else _) = if ?P then _ else _ => destruct P
+ end.
+ + rewrite <- wordToNat_plus.
+ rewrite ?wordToNat_natToWord_idempotent'; try omega.
+ * simpl;f_equal.
+ rewrite IHni; auto.
+ * rewrite ?wordToNat_natToWord_idempotent'; try omega.
+ match goal with
+ | |- 1 + #(countLeadingZerosWord no ?x) < _ => pose proof (@countLeadingZerosWord_le_len_nat no ni ltac:(omega) x) as sth
+ end.
+ omega.
+ + rewrite roundTrip_0; auto.
+Qed.
+
+Lemma countLeadingZerosWord_nat_le_len ni (w: word ni):
+ countLeadingZerosWord_nat w <= ni.
+Proof.
+ induction ni; simpl; auto; intros.
+ match goal with
+ | |- ((if ?P then _ else _) <= _) => destruct P; simpl; auto
+ end.
+ apply Le.le_n_S.
+ eapply IHni.
+Qed.
+
+Lemma countLeadingZerosWord_enough_size ni no no' (pf: ni < pow2 no) (pf': ni < pow2 no'): forall (w: word ni),
+ #(countLeadingZerosWord no w) =
+ #(countLeadingZerosWord no' w).
+Proof.
+ intros.
+ rewrite ?countLeadingZerosWord_nat_correct; auto.
+Qed.
+
+(* Usually this kind of lemmas would need a guarantee that "(wordToN a mod wordToN b)%N"
+ does not overflow, but fortunately this can never overflow.
+ And also, we don't need to prevent b from being 0. *)
+Lemma wordToN_mod: forall sz (a b: word sz),
+ wordToN (a ^% b) = (wordToN a mod wordToN b)%N.
+Proof.
+ intros. unfold wmod, wordBin.
+ rewrite wordToN_NToWord_2; [ reflexivity | ].
+ destruct (wordToN b) eqn: E.
+ - unfold N.modulo, N.div_eucl. destruct (wordToN a) eqn: F; simpl.
+ + apply Npow2_pos.
+ + rewrite <- F. apply wordToN_bound.
+ - eapply N.lt_trans.
+ + apply N.mod_upper_bound. congruence.
+ + rewrite <- E. apply wordToN_bound.
+Qed.
+
+Lemma N_to_Z_to_nat: forall (a: N), Z.to_nat (Z.of_N a) = N.to_nat a.
+Proof.
+ intros. rewrite <- (N2Z.id a) at 2.
+ rewrite Z_N_nat. reflexivity.
+Qed.
+
+Section ThisShouldBeInCoqLibrary.
+
+ Lemma N2Nat_inj_mod: forall (a b: N),
+ (b <> 0)%N ->
+ N.to_nat (a mod b)%N = (N.to_nat a) mod (N.to_nat b).
+ Proof.
+ intros.
+ rewrite <-? N_to_Z_to_nat.
+ rewrite N2Z.inj_mod by assumption.
+ apply Nat2Z.inj.
+ rewrite Zdiv.mod_Zmod.
+ - rewrite? Z2Nat.id; try apply N2Z.is_nonneg.
+ + reflexivity.
+ + pose proof (Z.mod_pos_bound (Z.of_N a) (Z.of_N b)) as Q.
+ destruct Q as [Q _].
+ * destruct b; try contradiction. simpl. constructor.
+ * exact Q.
+ - destruct b; try contradiction. simpl.
+ pose proof (Pos2Nat.is_pos p) as Q. omega.
+ Qed.
+
+ Lemma Nat2Z_inj_pow: forall n m : nat,
+ Z.of_nat (n ^ m) = (Z.of_nat n ^ Z.of_nat m)%Z.
+ Proof.
+ intros. induction m.
+ - reflexivity.
+ - rewrite Nat2Z.inj_succ.
+ rewrite Z.pow_succ_r by (apply Nat2Z.is_nonneg).
+ rewrite <- IHm.
+ rewrite <- Nat2Z.inj_mul.
+ reflexivity.
+ Qed.
+
+ Lemma Z2Nat_inj_pow: forall n m : Z,
+ (0 <= n)%Z ->
+ (0 <= m)%Z ->
+ Z.to_nat (n ^ m) = Z.to_nat n ^ Z.to_nat m.
+ Proof.
+ intros.
+ pose proof (Nat2Z_inj_pow (Z.to_nat n) (Z.to_nat m)) as P.
+ rewrite? Z2Nat.id in P by assumption.
+ rewrite <- P.
+ apply Nat2Z.id.
+ Qed.
+
+End ThisShouldBeInCoqLibrary.
+
+Lemma wordToNat_mod: forall sz (a b: word sz),
+ b <> $0 ->
+ #(a ^% b) = #a mod #b.
+Proof.
+ intros.
+ rewrite <-? wordToN_to_nat in *.
+ rewrite <-? N2Nat_inj_mod in *.
+ - rewrite wordToN_mod by assumption.
+ reflexivity.
+ - intro. apply H. replace 0%N with (wordToN (natToWord sz 0)) in H0.
+ + apply wordToN_inj. exact H0.
+ + erewrite <- wordToN_wzero. reflexivity.
+Qed.
+
+Lemma wlshift_mul_pow2: forall sz n (a: word sz),
+ wlshift a n = a ^* $ (pow2 n).
+Proof.
+ intros.
+ apply wordToNat_inj.
+ unfold wlshift.
+ rewrite? wordToNat_split1.
+ unfold eq_rec_r, eq_rec.
+ rewrite? wordToNat_eq_rect.
+ rewrite? wordToNat_combine.
+ rewrite? wordToNat_wzero.
+ rewrite wordToNat_wmult.
+ rewrite wordToNat_natToWord_eqn.
+ rewrite Nat.add_0_l.
+ rewrite Nat.mul_mod_idemp_r by (apply pow2_ne_zero).
+ rewrite Nat.mul_comm.
+ reflexivity.
+Qed.
+
+Lemma wlshift_mul_Zpow2: forall sz n (a: word sz),
+ (0 <= n)%Z ->
+ wlshift a (Z.to_nat n) = a ^* ZToWord sz (2 ^ n).
+Proof.
+ intros. rewrite wlshift_mul_pow2. f_equal.
+ change 2 with (Z.to_nat 2).
+ rewrite <- Z2Nat_inj_pow by omega.
+ apply natToWord_Z_to_nat.
+ apply Z.pow_nonneg.
+ omega.
+Qed.
+
+Lemma wlshift_distr_plus: forall sz n (a b: word sz),
+ wlshift (a ^+ b) n = wlshift a n ^+ wlshift b n.
+Proof.
+ intros.
+ rewrite? wlshift_mul_pow2.
+ apply wmult_plus_distr.
+Qed.
+
+Lemma wlshift'_distr_plus: forall sz n (a b: word sz),
+ wlshift' (a ^+ b) n = wlshift' a n ^+ wlshift' b n.
+Proof.
+ intros. rewrite? wlshift_alt. apply wlshift_distr_plus.
+Qed.
+
+Lemma wlshift_iter: forall sz n1 n2 (a: word sz),
+ wlshift (wlshift a n1) n2 = wlshift a (n1 + n2).
+Proof.
+ intros. rewrite? wlshift_mul_pow2.
+ rewrite <- wmult_assoc.
+ rewrite <- natToWord_mult.
+ do 2 f_equal.
+ symmetry.
+ apply Nat.pow_add_r.
+Qed.
+
+Lemma wlshift'_iter: forall sz n1 n2 (a: word sz),
+ wlshift' (wlshift' a n1) n2 = wlshift' a (n1 + n2).
+Proof.
+ intros. rewrite? wlshift_alt. apply wlshift_iter.
+Qed.
+
+Lemma wlshift_zero: forall sz n, wlshift $0 n = natToWord sz 0.
+Proof.
+ intros.
+ apply wordToNat_inj.
+ unfold wlshift.
+ rewrite? wordToNat_split1.
+ unfold eq_rec_r, eq_rec.
+ rewrite? wordToNat_eq_rect.
+ rewrite? wordToNat_combine.
+ rewrite? wordToNat_wzero.
+ rewrite Nat.mul_0_r.
+ change (0 + 0) with 0.
+ rewrite Nat.mod_0_l by (apply pow2_ne_zero).
+ reflexivity.
+Qed.
+
+Lemma wlshift'_zero: forall sz n, wlshift' $0 n = natToWord sz 0.
+Proof.
+ intros. rewrite? wlshift_alt. apply wlshift_zero.
+Qed.
+
+Lemma sext_natToWord_nat_cast: forall sz2 sz1 sz n (e: sz1 + sz2 = sz),
+ 2 * n < pow2 sz1 ->
+ nat_cast word e (sext (natToWord sz1 n) sz2) = natToWord sz n.
+Proof.
+ intros. rewrite nat_cast_eq_rect. apply sext_natToWord. assumption.
+Qed.
+
+Lemma sext_neg_natToWord_nat_cast: forall sz2 sz1 sz n (e: sz1 + sz2 = sz),
+ 2 * n < pow2 sz1 ->
+ nat_cast word e (sext (wneg (natToWord sz1 n)) sz2) = wneg (natToWord sz n).
+Proof.
+ intros. rewrite nat_cast_eq_rect. apply sext_wneg_natToWord. assumption.
+Qed.
+
+Lemma sext0: forall sz0 sz (v: word sz) (e: sz0 = 0),
+ sext v sz0 = nat_cast word (eq_ind_r (fun sz0 : nat => sz = sz + sz0) (plus_n_O sz) e) v.
+Proof.
+ intros. subst.
+ unfold sext.
+ destruct (wmsb v false) eqn: E;
+ simpl; rewrite combine_n_0; rewrite <- nat_cast_eq_rect; apply nat_cast_proof_irrel.
+Qed.
+
+Lemma wordToN_wordToZ: forall (sz : nat) (w : word sz),
+ wordToN w = Z.to_N (wordToZ w + Z.of_N (if wmsb w false then Npow2 sz else 0%N)).
+Proof.
+ intros.
+ rewrite (wordToZ_wordToN w).
+ remember (if wmsb w false then Npow2 sz else 0%N) as c; clear Heqc.
+ rewrite Z.sub_add.
+ symmetry.
+ apply N2Z.id.
+Qed.
+
+Lemma uwordToZ_ZToWord_0: forall (z : Z) (sz : nat),
+ (0 <= z < Z.of_N (Npow2 sz))%Z ->
+ uwordToZ (ZToWord sz z) = z.
+Proof.
+ intros.
+ unfold uwordToZ.
+ pose proof (Z2N.id _ (proj1 H)).
+ remember (Z.to_N z) as n; clear Heqn. subst z.
+ apply proj2 in H.
+ f_equal.
+ rewrite ZToWord_Z_of_N.
+ apply wordToN_NToWord_2.
+ apply N2Z.inj_lt.
+ assumption.
+Qed.
+
+Lemma uwordToZ_ZToWord: forall (z : Z) (sz : nat),
+ (0 <= z < 2 ^ (Z.of_nat sz))%Z ->
+ uwordToZ (ZToWord sz z) = z.
+Proof.
+ intros. apply uwordToZ_ZToWord_0.
+ intuition idtac.
+ change 2%Z with (Z.of_nat 2) in H1.
+ rewrite <- Nat2Z_inj_pow in H1.
+ rewrite <- N_nat_Z.
+ rewrite Npow2_nat.
+ assumption.
+Qed.
+
+Lemma wordToN_neq_0: forall sz (b : word sz),
+ b <> $0 ->
+ wordToN b <> 0%N.
+Proof.
+ intros.
+ intro C.
+ apply H.
+ apply wordToN_inj.
+ erewrite <- wordToN_wzero in C.
+ unfold wzero in C.
+ exact C.
+Qed.
+
+(* These counterexamples will hopefully be found by users who use commands
+ such as "Search ((_ ^+ _) ^% _)" *)
+Lemma wmod_plus_distr_does_not_hold: ~ forall sz (a b m: word sz),
+ m <> $0 ->
+ (a ^+ b) ^% m = ((a ^% m) ^+ (b ^% m)) ^% m.
+Proof.
+ intro C.
+ specialize (C 4 $9 $11 $7). cbv in C.
+ match type of C with (?A -> _) => assert A by (intro; discriminate) end.
+ specialize (C H). discriminate.
+Qed.
+
+Lemma wmul_mod_distr_does_not_hold: ~ forall sz (a b n: word sz),
+ n <> $0 ->
+ (a ^* b) ^% n = ((a ^% n) ^* (b ^% n)) ^% n.
+Proof.
+ intro C.
+ specialize (C 4 $9 $11 $7). cbv in C.
+ match type of C with (?A -> _) => assert A by (intro; discriminate) end.
+ specialize (C H). discriminate.
+Qed.
+
+Lemma Nmod_0_r: forall a : N, (a mod 0)%N = a.
+Proof.
+ intros. destruct a; reflexivity.
+Qed.
+
+Lemma wordToN_0: forall sz,
+ wordToN (natToWord sz 0) = 0%N.
+Proof.
+ intros. change (natToWord sz 0) with (wzero sz).
+ apply wordToN_wzero.
+Qed.
+
+Lemma NToWord_0: forall sz,
+ NToWord sz 0 = $ (0).
+Proof.
+ intros. change 0%nat with (N.to_nat 0).
+ apply NToWord_nat.
+Qed.
+
+Lemma wmod_0_r: forall sz (a: word sz), a ^% $0 = a.
+Proof.
+ intros. unfold wmod, wordBin.
+ rewrite wordToN_0.
+ rewrite Nmod_0_r.
+ apply NToWord_wordToN.
+Qed.
+
+Lemma wordToN_NToWord_eqn: forall sz (n : N),
+ wordToN (NToWord sz n) = (n mod Npow2 sz)%N.
+Proof.
+ intros.
+ pose proof (Npow2_not_zero sz).
+ apply Nnat.N2Nat.inj.
+ rewrite wordToN_to_nat.
+ rewrite N2Nat_inj_mod by assumption.
+ rewrite Npow2_nat.
+ rewrite <- wordToNat_natToWord_eqn.
+ rewrite <- NToWord_nat.
+ reflexivity.
+Qed.
+
+Lemma Nminus_mod_idemp_r: forall a b n : N,
+ (n <> 0)%N ->
+ (b <= a)%N ->
+ ((a - b mod n) mod n)%N = ((a - b) mod n)%N.
+Proof.
+ intros.
+ apply N2Z.inj.
+ rewrite? N2Z.inj_mod by assumption.
+ pose proof (N.mod_le b n H).
+ rewrite N2Z.inj_sub by (eapply N.le_trans; eassumption).
+ rewrite N2Z.inj_sub by assumption.
+ rewrite? N2Z.inj_mod by assumption.
+ apply Zdiv.Zminus_mod_idemp_r.
+Qed.
+
+Lemma drop_sub_N: forall sz (n k : N),
+ (k * Npow2 sz <= n)%N ->
+ NToWord sz (n - k * Npow2 sz) = NToWord sz n.
+Proof.
+ intros.
+ apply wordToN_inj.
+ pose proof (Npow2_not_zero sz).
+ do 2 rewrite wordToN_NToWord_eqn.
+ rewrite <- Nminus_mod_idemp_r by assumption.
+ rewrite N.mod_mul by assumption.
+ rewrite N.sub_0_r.
+ reflexivity.
+Qed.
+
+Lemma wmod_divides: forall sz (a b: word sz),
+ a ^% b = $0 ->
+ exists k, a = b ^* k.
+Proof.
+ intros. destruct (weq b $0).
+ - subst b. rewrite wmod_0_r in *. subst a. exists (natToWord sz 0).
+ symmetry. apply wmult_neut_r.
+ - unfold wmod, wmult, wordBin in *.
+ pose proof (N.mod_divides (wordToN a) (wordToN b)) as P.
+ apply wordToN_neq_0 in n.
+ specialize (P n).
+ destruct P as [ [k P] _].
+ + apply (f_equal (@wordToN sz)) in H.
+ rewrite wordToN_NToWord_2 in H.
+ * rewrite H. apply wordToN_0.
+ * pose proof (wordToN_bound a). remember (wordToN a) as c. clear Heqc a.
+ pose proof (wordToN_bound b). remember (wordToN b) as d. clear Heqd b.
+ pose proof (N.mod_upper_bound c d n).
+ nomega.
+ + exists (NToWord sz (k - k / (Npow2 sz) * Npow2 sz)).
+ rewrite wordToN_NToWord_2.
+ { rewrite N.mul_sub_distr_l.
+ rewrite N.mul_assoc.
+ rewrite drop_sub_N.
+ - rewrite <- P. symmetry. apply NToWord_wordToN.
+ - rewrite <- N.mul_assoc.
+ rewrite <- (N.mul_comm (Npow2 sz)).
+ apply N.mul_le_mono_l.
+ apply (N.mul_div_le k (Npow2 sz)).
+ apply Npow2_not_zero.
+ }
+ { rewrite <- N.mul_comm. rewrite <- N.mod_eq by (apply Npow2_not_zero).
+ apply N.mod_upper_bound. apply Npow2_not_zero. }
+Qed.
+
+Lemma wmod_divides_other_direction_does_not_hold: ~ forall sz (a b: word sz),
+ b <> $0 ->
+ (exists k, a = b ^* k) ->
+ a ^% b = $0.
+Proof.
+ intro C. specialize (C 4 $14 $5).
+ match type of C with (?A -> _) => assert A by (intro; discriminate) end.
+ specialize (C H).
+ match type of C with (?A -> _) => assert A as B end.
+ - exists (natToWord 4 6). reflexivity.
+ - specialize (C B). cbv in C. discriminate.
+Qed.
+
+Lemma wmod_mul_does_not_hold: ~ forall sz (a b: word sz),
+ b <> $0 ->
+ (a ^* b) ^% b = $0.
+Proof.
+ intro C.
+ specialize (C 4 $6 $5).
+ match type of C with (?A -> _) => assert A by (intro; discriminate) end.
+ specialize (C H).
+ cbv in C.
+ discriminate.
+Qed.
+
+Lemma wmult_plus_distr_l: forall (sz : nat) (x y z : word sz),
+ z ^* (x ^+ y) = z ^* x ^+ z ^* y.
+Proof.
+ intros. rewrite! (wmult_comm z).
+ apply wmult_plus_distr.
+Qed.
+
+Lemma wmod_same: forall sz (a: word sz), a ^% a = $0.
+Proof.
+ intros. destruct (weq a $0).
+ - subst a. rewrite wmod_0_r in *. reflexivity.
+ - unfold wmod, wordBin. apply wordToN_neq_0 in n. rewrite N.mod_same by assumption.
+ apply NToWord_0.
+Qed.
+
+Lemma wmod_0_l: forall sz (m: word sz),
+ $0 ^% m = $0.
+Proof.
+ intros. unfold wmod, wordBin.
+ rewrite wordToN_0.
+ destruct (N.eq_dec (wordToN m) 0%N).
+ - rewrite e. change (0 mod 0)%N with 0%N. apply NToWord_0.
+ - rewrite N.mod_0_l by assumption. apply NToWord_0.
+Qed.
+
+Lemma wmod_plus_distr: forall sz (a b m: word sz),
+ (exists k, (wordToN m * k)%N = Npow2 sz) ->
+ (a ^+ b) ^% m = ((a ^% m) ^+ (b ^% m)) ^% m.
+Proof.
+ intros. destruct H as [k E].
+ assert (wordToN m <> 0%N) as H. {
+ intro C. rewrite C in E. simpl in E. symmetry in E.
+ apply Npow2_not_zero in E.
+ assumption.
+ }
+ unfold wplus, wmod, wordBin.
+ pose proof (wordToN_bound a). remember (wordToN a) as c. clear Heqc a.
+ pose proof (wordToN_bound b). remember (wordToN b) as d. clear Heqd b.
+ pose proof (wordToN_bound m). remember (wordToN m) as n. clear Heqn m.
+ pose proof (N.mod_upper_bound c n H).
+ pose proof (N.mod_upper_bound d n H).
+ rewrite (@wordToN_NToWord_2 sz (c mod n)) by nomega.
+ rewrite (@wordToN_NToWord_2 sz (d mod n)) by nomega.
+ repeat match goal with
+ | |- context [wordToN (NToWord ?sz ?n)] =>
+ let k := fresh "k" in
+ let E := fresh "E" in
+ let B := fresh "B" in
+ destruct (wordToN_NToWord sz n) as [ k [E B] ];
+ rewrite E in *; clear E
+ end.
+ rewrite <- E in *.
+ rewrite <- Nminus_mod_idemp_r by assumption.
+ rewrite <- (@Nminus_mod_idemp_r (c mod n + d mod n)) by assumption.
+ rewrite (N.mul_comm n k).
+ do 2 rewrite N.mul_assoc.
+ do 2 rewrite N.mod_mul by assumption.
+ do 2 rewrite N.sub_0_r.
+ f_equal.
+ apply N.add_mod.
+ assumption.
+Qed.
+
+Lemma wmod_mul: forall sz (a b: word sz),
+ (exists k, (wordToN b * k)%N = Npow2 sz) ->
+ (a ^* b) ^% b = $0.
+Proof.
+ intros. destruct H as [k E].
+ assert (wordToN b <> 0%N) as H. {
+ intro C. rewrite C in E. simpl in E. symmetry in E.
+ apply Npow2_not_zero in E.
+ assumption.
+ }
+ unfold wmult, wmod, wordBin.
+ pose proof (wordToN_bound a). remember (wordToN a) as c. clear Heqc a.
+ pose proof (wordToN_bound b). remember (wordToN b) as d. clear Heqd b.
+ pose proof (N.mod_upper_bound c d H).
+ repeat match goal with
+ | |- context [wordToN (NToWord ?sz ?n)] =>
+ let k := fresh "k" in
+ let E := fresh "E" in
+ let B := fresh "B" in
+ destruct (wordToN_NToWord sz n) as [ k [E B] ];
+ rewrite E in *; clear E
+ end.
+ rewrite <- E in *.
+ rewrite <- Nminus_mod_idemp_r by assumption.
+ rewrite (N.mul_comm d k).
+ rewrite N.mul_assoc.
+ rewrite N.mod_mul by assumption.
+ rewrite N.sub_0_r.
+ rewrite N.mul_mod by assumption.
+ rewrite N.mod_same by assumption.
+ rewrite N.mul_0_r.
+ rewrite N.mod_0_l by assumption.
+ apply NToWord_0.
+Qed.
+
+Local Close Scope nat.
+Close Scope word_scope.
diff --git a/snapshots/coq-riscv/bbv/theories/WordScope.v b/snapshots/coq-riscv/bbv/theories/WordScope.v
new file mode 100644
index 00000000..5d30fdab
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/WordScope.v
@@ -0,0 +1,10 @@
+(* Word.v defines notations for words by first opening word_scope, and then closing it again,
+ to prevent notation clashes.
+ It does, however, bind word_scope to the type word, so whenever an expression of type word
+ is expected, it is parsed with notations enabled, but when the expected type is unknown,
+ word notations don't work by default.
+ If you want to enable them even for unknown expected types, you can import this file
+ instead of Word.v. *)
+
+Require Export bbv.Word.
+Open Scope word_scope.
diff --git a/snapshots/coq-riscv/bbv/theories/ZLib.v b/snapshots/coq-riscv/bbv/theories/ZLib.v
new file mode 100644
index 00000000..4530df5c
--- /dev/null
+++ b/snapshots/coq-riscv/bbv/theories/ZLib.v
@@ -0,0 +1,25 @@
+Require Import Coq.ZArith.BinInt.
+Require Import Coq.omega.Omega.
+
+Local Open Scope Z_scope.
+
+
+Lemma mod2_cases: forall (n: Z), n mod 2 = 0 \/ n mod 2 = 1.
+Proof.
+ intros. pose proof (Z.mod_pos_bound n 2). omega.
+Qed.
+
+Lemma div_mul_undo: forall a b,
+ b <> 0 ->
+ a mod b = 0 ->
+ a / b * b = a.
+Proof.
+ intros.
+ pose proof Z.div_mul_cancel_l as A. specialize (A a 1 b).
+ replace (b * 1) with b in A by omega.
+ rewrite Z.div_1_r in A.
+ rewrite Z.mul_comm.
+ rewrite <- Z.divide_div_mul_exact; try assumption.
+ - apply A; congruence.
+ - apply Z.mod_divide; assumption.
+Qed.
diff --git a/snapshots/coq-riscv/build b/snapshots/coq-riscv/build
new file mode 100755
index 00000000..4d89f5d5
--- /dev/null
+++ b/snapshots/coq-riscv/build
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+if [ ! -d bbv ]; then
+ echo Run clean from the coq-riscv directory
+ exit 1
+fi
+
+set -ex
+cd bbv
+make
+cd ../sail/lib/coq
+make
+cd ../../riscv
+coqc -R ../../bbv/theories bbv -R ../lib/coq Sail riscv_extras.v
+coqc -R ../../bbv/theories bbv -R ../lib/coq Sail riscv_types.v
+coqc -R ../../bbv/theories bbv -R ../lib/coq Sail riscv.v
diff --git a/snapshots/coq-riscv/clean b/snapshots/coq-riscv/clean
new file mode 100755
index 00000000..9b161fd2
--- /dev/null
+++ b/snapshots/coq-riscv/clean
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+if [ ! -d bbv ]; then
+ echo Run clean from the coq-riscv directory
+ exit 1
+fi
+
+set -ex
+rm -f sail/riscv/*.vo
+cd sail/lib/coq
+make clean
+cd ../../../bbv
+make clean
diff --git a/snapshots/coq-riscv/sail/lib/coq/.gitignore b/snapshots/coq-riscv/sail/lib/coq/.gitignore
new file mode 100644
index 00000000..1aa62803
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/.gitignore
@@ -0,0 +1 @@
+deps \ No newline at end of file
diff --git a/snapshots/coq-riscv/sail/lib/coq/Makefile b/snapshots/coq-riscv/sail/lib/coq/Makefile
new file mode 100644
index 00000000..99321aae
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Makefile
@@ -0,0 +1,24 @@
+BBV_DIR=../../../bbv/theories
+
+SRC=Sail2_prompt_monad.v Sail2_prompt.v Sail2_impl_base.v Sail2_instr_kinds.v Sail2_operators_bitlists.v Sail2_operators_mwords.v Sail2_operators.v Sail2_values.v Sail2_state_monad.v Sail2_state.v Sail2_string.v
+
+COQ_LIBS = -R . Sail -R "$(BBV_DIR)" bbv
+
+TARGETS=$(SRC:.v=.vo)
+
+.PHONY: all clean *.ide
+
+all: $(TARGETS)
+clean:
+ rm -f -- $(TARGETS) $(TARGETS:.vo=.glob) $(TARGETS:%.vo=.%.aux) deps
+
+%.vo: %.v
+ coqc $(COQ_LIBS) $<
+
+%.ide: %.v
+ coqide $(COQ_LIBS) $<
+
+deps: $(SRC)
+ coqdep $(COQ_LIBS) $(SRC) > deps
+
+-include deps
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_impl_base.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_impl_base.v
new file mode 100644
index 00000000..464c2902
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_impl_base.v
@@ -0,0 +1,1103 @@
+(*========================================================================*)
+(* Sail *)
+(* *)
+(* Copyright (c) 2013-2017 *)
+(* Kathyrn Gray *)
+(* Shaked Flur *)
+(* Stephen Kell *)
+(* Gabriel Kerneis *)
+(* Robert Norton-Wright *)
+(* Christopher Pulte *)
+(* Peter Sewell *)
+(* Alasdair Armstrong *)
+(* Brian Campbell *)
+(* Thomas Bauereiss *)
+(* Anthony Fox *)
+(* Jon French *)
+(* Dominic Mulligan *)
+(* Stephen Kell *)
+(* Mark Wassell *)
+(* *)
+(* All rights reserved. *)
+(* *)
+(* This software was developed by the University of Cambridge Computer *)
+(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *)
+(* (REMS) project, funded by EPSRC grant EP/K008528/1. *)
+(* *)
+(* Redistribution and use in source and binary forms, with or without *)
+(* modification, are permitted provided that the following conditions *)
+(* are met: *)
+(* 1. Redistributions of source code must retain the above copyright *)
+(* notice, this list of conditions and the following disclaimer. *)
+(* 2. Redistributions in binary form must reproduce the above copyright *)
+(* notice, this list of conditions and the following disclaimer in *)
+(* the documentation and/or other materials provided with the *)
+(* distribution. *)
+(* *)
+(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *)
+(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *)
+(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *)
+(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *)
+(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)
+(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *)
+(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *)
+(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *)
+(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *)
+(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *)
+(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *)
+(* SUCH DAMAGE. *)
+(*========================================================================*)
+
+Require Import Sail2_instr_kinds.
+
+(*
+class ( EnumerationType 'a )
+ val toNat : 'a -> nat
+end
+
+
+val enumeration_typeCompare : forall 'a. EnumerationType 'a => 'a -> 'a -> ordering
+let ~{ocaml} enumeration_typeCompare e1 e2 =
+ compare (toNat e1) (toNat e2)
+let inline {ocaml} enumeration_typeCompare = defaultCompare
+
+
+default_instance forall 'a. EnumerationType 'a => (Ord 'a)
+ let compare = enumeration_typeCompare
+ let (<) r1 r2 = (enumeration_typeCompare r1 r2) = LT
+ let (<=) r1 r2 = (enumeration_typeCompare r1 r2) <> GT
+ let (>) r1 r2 = (enumeration_typeCompare r1 r2) = GT
+ let (>=) r1 r2 = (enumeration_typeCompare r1 r2) <> LT
+end
+
+
+
+(* maybe isn't a member of type Ord - this should be in the Lem standard library*)
+instance forall 'a. Ord 'a => (Ord (maybe 'a))
+ let compare = maybeCompare compare
+ let (<) r1 r2 = (maybeCompare compare r1 r2) = LT
+ let (<=) r1 r2 = (maybeCompare compare r1 r2) <> GT
+ let (>) r1 r2 = (maybeCompare compare r1 r2) = GT
+ let (>=) r1 r2 = (maybeCompare compare r1 r2) <> LT
+end
+
+type word8 = nat (* bounded at a byte, for when lem supports it*)
+
+type end_flag =
+ | E_big_endian
+ | E_little_endian
+
+type bit =
+ | Bitc_zero
+ | Bitc_one
+
+type bit_lifted =
+ | Bitl_zero
+ | Bitl_one
+ | Bitl_undef (* used for modelling h/w arch unspecified bits *)
+ | Bitl_unknown (* used for interpreter analysis exhaustive execution *)
+
+type direction =
+ | D_increasing
+ | D_decreasing
+
+let dir_of_bool is_inc = if is_inc then D_increasing else D_decreasing
+let bool_of_dir = function
+ | D_increasing -> true
+ | D_decreasing -> false
+ end
+
+(* at some point this should probably not mention bit_lifted anymore *)
+type register_value = <|
+ rv_bits: list bit_lifted (* MSB first, smallest index number *);
+ rv_dir: direction;
+ rv_start: nat ;
+ rv_start_internal: nat;
+ (*when dir is increasing, rv_start = rv_start_internal.
+ Otherwise, tells interpreter how to reconstruct a proper decreasing value*)
+ |>
+
+type byte_lifted = Byte_lifted of list bit_lifted (* of length 8 *) (*MSB first everywhere*)
+
+type instruction_field_value = list bit
+
+type byte = Byte of list bit (* of length 8 *) (*MSB first everywhere*)
+
+type address_lifted = Address_lifted of list byte_lifted (* of length 8 for 64bit machines*) * maybe integer
+(* for both values of end_flag, MSBy first *)
+
+type memory_byte = byte_lifted (* of length 8 *) (*MSB first everywhere*)
+
+type memory_value = list memory_byte
+(* the list is of length >=1 *)
+(* the head of the list is the byte stored at the lowest address;
+when calling a Sail function with a wmv effect, the least significant 8
+bits of the bit vector passed to the function will be interpreted as
+the lowest address byte; similarly, when calling a Sail function with
+rmem effect, the lowest address byte will be placed in the least
+significant 8 bits of the bit vector returned by the function; this
+behaviour is consistent with little-endian. *)
+
+
+(* not sure which of these is more handy yet *)
+type address = Address of list byte (* of length 8 *) * integer
+(* type address = Address of integer *)
+
+type opcode = Opcode of list byte (* of length 4 *)
+
+(** typeclass instantiations *)
+
+instance (EnumerationType bit)
+ let toNat = function
+ | Bitc_zero -> 0
+ | Bitc_one -> 1
+ end
+end
+
+instance (EnumerationType bit_lifted)
+ let toNat = function
+ | Bitl_zero -> 0
+ | Bitl_one -> 1
+ | Bitl_undef -> 2
+ | Bitl_unknown -> 3
+ end
+end
+
+let ~{ocaml} byte_liftedCompare (Byte_lifted b1) (Byte_lifted b2) = compare b1 b2
+let inline {ocaml} byte_liftedCompare = defaultCompare
+
+let ~{ocaml} byte_liftedLess b1 b2 = byte_liftedCompare b1 b2 = LT
+let ~{ocaml} byte_liftedLessEq b1 b2 = byte_liftedCompare b1 b2 <> GT
+let ~{ocaml} byte_liftedGreater b1 b2 = byte_liftedCompare b1 b2 = GT
+let ~{ocaml} byte_liftedGreaterEq b1 b2 = byte_liftedCompare b1 b2 <> LT
+
+let inline {ocaml} byte_liftedLess = defaultLess
+let inline {ocaml} byte_liftedLessEq = defaultLessEq
+let inline {ocaml} byte_liftedGreater = defaultGreater
+let inline {ocaml} byte_liftedGreaterEq = defaultGreaterEq
+
+instance (Ord byte_lifted)
+ let compare = byte_liftedCompare
+ let (<) = byte_liftedLess
+ let (<=) = byte_liftedLessEq
+ let (>) = byte_liftedGreater
+ let (>=) = byte_liftedGreaterEq
+end
+
+let ~{ocaml} byteCompare (Byte b1) (Byte b2) = compare b1 b2
+let inline {ocaml} byteCompare = defaultCompare
+
+let ~{ocaml} byteLess b1 b2 = byteCompare b1 b2 = LT
+let ~{ocaml} byteLessEq b1 b2 = byteCompare b1 b2 <> GT
+let ~{ocaml} byteGreater b1 b2 = byteCompare b1 b2 = GT
+let ~{ocaml} byteGreaterEq b1 b2 = byteCompare b1 b2 <> LT
+
+let inline {ocaml} byteLess = defaultLess
+let inline {ocaml} byteLessEq = defaultLessEq
+let inline {ocaml} byteGreater = defaultGreater
+let inline {ocaml} byteGreaterEq = defaultGreaterEq
+
+instance (Ord byte)
+ let compare = byteCompare
+ let (<) = byteLess
+ let (<=) = byteLessEq
+ let (>) = byteGreater
+ let (>=) = byteGreaterEq
+end
+
+
+
+
+
+let ~{ocaml} opcodeCompare (Opcode o1) (Opcode o2) =
+ compare o1 o2
+let {ocaml} opcodeCompare = defaultCompare
+
+let ~{ocaml} opcodeLess b1 b2 = opcodeCompare b1 b2 = LT
+let ~{ocaml} opcodeLessEq b1 b2 = opcodeCompare b1 b2 <> GT
+let ~{ocaml} opcodeGreater b1 b2 = opcodeCompare b1 b2 = GT
+let ~{ocaml} opcodeGreaterEq b1 b2 = opcodeCompare b1 b2 <> LT
+
+let inline {ocaml} opcodeLess = defaultLess
+let inline {ocaml} opcodeLessEq = defaultLessEq
+let inline {ocaml} opcodeGreater = defaultGreater
+let inline {ocaml} opcodeGreaterEq = defaultGreaterEq
+
+instance (Ord opcode)
+ let compare = opcodeCompare
+ let (<) = opcodeLess
+ let (<=) = opcodeLessEq
+ let (>) = opcodeGreater
+ let (>=) = opcodeGreaterEq
+end
+
+let addressCompare (Address b1 i1) (Address b2 i2) = compare i1 i2
+(* this cannot be defaultCompare for OCaml because addresses contain big ints *)
+
+let addressLess b1 b2 = addressCompare b1 b2 = LT
+let addressLessEq b1 b2 = addressCompare b1 b2 <> GT
+let addressGreater b1 b2 = addressCompare b1 b2 = GT
+let addressGreaterEq b1 b2 = addressCompare b1 b2 <> LT
+
+instance (SetType address)
+ let setElemCompare = addressCompare
+end
+
+instance (Ord address)
+ let compare = addressCompare
+ let (<) = addressLess
+ let (<=) = addressLessEq
+ let (>) = addressGreater
+ let (>=) = addressGreaterEq
+end
+
+let {coq; ocaml} addressEqual a1 a2 = (addressCompare a1 a2) = EQ
+let inline {hol; isabelle} addressEqual = unsafe_structural_equality
+
+let {coq; ocaml} addressInequal a1 a2 = not (addressEqual a1 a2)
+let inline {hol; isabelle} addressInequal = unsafe_structural_inequality
+
+instance (Eq address)
+ let (=) = addressEqual
+ let (<>) = addressInequal
+end
+
+let ~{ocaml} directionCompare d1 d2 =
+ match (d1, d2) with
+ | (D_decreasing, D_increasing) -> GT
+ | (D_increasing, D_decreasing) -> LT
+ | _ -> EQ
+ end
+let inline {ocaml} directionCompare = defaultCompare
+
+let ~{ocaml} directionLess b1 b2 = directionCompare b1 b2 = LT
+let ~{ocaml} directionLessEq b1 b2 = directionCompare b1 b2 <> GT
+let ~{ocaml} directionGreater b1 b2 = directionCompare b1 b2 = GT
+let ~{ocaml} directionGreaterEq b1 b2 = directionCompare b1 b2 <> LT
+
+let inline {ocaml} directionLess = defaultLess
+let inline {ocaml} directionLessEq = defaultLessEq
+let inline {ocaml} directionGreater = defaultGreater
+let inline {ocaml} directionGreaterEq = defaultGreaterEq
+
+instance (Ord direction)
+ let compare = directionCompare
+ let (<) = directionLess
+ let (<=) = directionLessEq
+ let (>) = directionGreater
+ let (>=) = directionGreaterEq
+end
+
+instance (Show direction)
+ let show = function D_increasing -> "D_increasing" | D_decreasing -> "D_decreasing" end
+end
+
+let ~{ocaml} register_valueCompare rv1 rv2 =
+ compare (rv1.rv_bits, rv1.rv_dir, rv1.rv_start, rv1.rv_start_internal)
+ (rv2.rv_bits, rv2.rv_dir, rv2.rv_start, rv2.rv_start_internal)
+let inline {ocaml} register_valueCompare = defaultCompare
+
+let ~{ocaml} register_valueLess b1 b2 = register_valueCompare b1 b2 = LT
+let ~{ocaml} register_valueLessEq b1 b2 = register_valueCompare b1 b2 <> GT
+let ~{ocaml} register_valueGreater b1 b2 = register_valueCompare b1 b2 = GT
+let ~{ocaml} register_valueGreaterEq b1 b2 = register_valueCompare b1 b2 <> LT
+
+let inline {ocaml} register_valueLess = defaultLess
+let inline {ocaml} register_valueLessEq = defaultLessEq
+let inline {ocaml} register_valueGreater = defaultGreater
+let inline {ocaml} register_valueGreaterEq = defaultGreaterEq
+
+instance (Ord register_value)
+ let compare = register_valueCompare
+ let (<) = register_valueLess
+ let (<=) = register_valueLessEq
+ let (>) = register_valueGreater
+ let (>=) = register_valueGreaterEq
+end
+
+let address_liftedCompare (Address_lifted b1 i1) (Address_lifted b2 i2) =
+ compare (i1,b1) (i2,b2)
+(* this cannot be defaultCompare for OCaml because address_lifteds contain big
+ ints *)
+
+let address_liftedLess b1 b2 = address_liftedCompare b1 b2 = LT
+let address_liftedLessEq b1 b2 = address_liftedCompare b1 b2 <> GT
+let address_liftedGreater b1 b2 = address_liftedCompare b1 b2 = GT
+let address_liftedGreaterEq b1 b2 = address_liftedCompare b1 b2 <> LT
+
+instance (Ord address_lifted)
+ let compare = address_liftedCompare
+ let (<) = address_liftedLess
+ let (<=) = address_liftedLessEq
+ let (>) = address_liftedGreater
+ let (>=) = address_liftedGreaterEq
+end
+
+(* Registers *)
+type slice = (nat * nat)
+
+type reg_name =
+ (* do we really need this here if ppcmem already has this information by itself? *)
+| Reg of string * nat * nat * direction
+(*Name of the register, accessing the entire register, the start and size of this register, and its direction *)
+
+| Reg_slice of string * nat * direction * slice
+(* Name of the register, accessing from the bit indexed by the first
+to the bit indexed by the second integer of the slice, inclusive. For
+machineDef* the first is a smaller number or equal to the second, adjusted
+to reflect the correct span direction in the interpreter side. *)
+
+| Reg_field of string * nat * direction * string * slice
+(*Name of the register, start and direction, and name of the field of the register
+accessed. The slice specifies where this field is in the register*)
+
+| Reg_f_slice of string * nat * direction * string * slice * slice
+(* The first four components are as in Reg_field; the final slice
+specifies a part of the field, indexed w.r.t. the register as a whole *)
+
+let register_base_name : reg_name -> string = function
+ | Reg s _ _ _ -> s
+ | Reg_slice s _ _ _ -> s
+ | Reg_field s _ _ _ _ -> s
+ | Reg_f_slice s _ _ _ _ _ -> s
+ end
+
+let slice_of_reg_name : reg_name -> slice = function
+ | Reg _ start width D_increasing -> (start, start + width -1)
+ | Reg _ start width D_decreasing -> (start - width - 1, start)
+ | Reg_slice _ _ _ sl -> sl
+ | Reg_field _ _ _ _ sl -> sl
+ | Reg_f_slice _ _ _ _ _ sl -> sl
+ end
+
+let width_of_reg_name (r: reg_name) : nat =
+ let width_of_slice (i, j) = (* j - i + 1 in *)
+
+ (integerFromNat j) - (integerFromNat i) + 1
+ $> abs $> natFromInteger
+ in
+ match r with
+ | Reg _ _ width _ -> width
+ | Reg_slice _ _ _ sl -> width_of_slice sl
+ | Reg_field _ _ _ _ sl -> width_of_slice sl
+ | Reg_f_slice _ _ _ _ _ sl -> width_of_slice sl
+ end
+
+let reg_name_non_empty_intersection (r: reg_name) (r': reg_name) : bool =
+ register_base_name r = register_base_name r' &&
+ let (i1, i2) = slice_of_reg_name r in
+ let (i1', i2') = slice_of_reg_name r' in
+ i1' <= i2 && i2' >= i1
+
+let reg_nameCompare r1 r2 =
+ compare (register_base_name r1,slice_of_reg_name r1)
+ (register_base_name r2,slice_of_reg_name r2)
+
+let reg_nameLess b1 b2 = reg_nameCompare b1 b2 = LT
+let reg_nameLessEq b1 b2 = reg_nameCompare b1 b2 <> GT
+let reg_nameGreater b1 b2 = reg_nameCompare b1 b2 = GT
+let reg_nameGreaterEq b1 b2 = reg_nameCompare b1 b2 <> LT
+
+instance (Ord reg_name)
+ let compare = reg_nameCompare
+ let (<) = reg_nameLess
+ let (<=) = reg_nameLessEq
+ let (>) = reg_nameGreater
+ let (>=) = reg_nameGreaterEq
+end
+
+let {coq;ocaml} reg_nameEqual a1 a2 = (reg_nameCompare a1 a2) = EQ
+let {hol;isabelle} reg_nameEqual = unsafe_structural_equality
+let {coq;ocaml} reg_nameInequal a1 a2 = not (reg_nameEqual a1 a2)
+let {hol;isabelle} reg_nameInequal = unsafe_structural_inequality
+
+instance (Eq reg_name)
+ let (=) = reg_nameEqual
+ let (<>) = reg_nameInequal
+end
+
+instance (SetType reg_name)
+ let setElemCompare = reg_nameCompare
+end
+
+let direction_of_reg_name r = match r with
+ | Reg _ _ _ d -> d
+ | Reg_slice _ _ d _ -> d
+ | Reg_field _ _ d _ _ -> d
+ | Reg_f_slice _ _ d _ _ _ -> d
+ end
+
+let start_of_reg_name r = match r with
+ | Reg _ start _ _ -> start
+ | Reg_slice _ start _ _ -> start
+ | Reg_field _ start _ _ _ -> start
+ | Reg_f_slice _ start _ _ _ _ -> start
+end
+
+(* Data structures for building up instructions *)
+
+(* read_kind, write_kind, barrier_kind, trans_kind and instruction_kind have
+ been moved to sail_instr_kinds.lem. This removes the dependency of the
+ shallow embedding on the rest of sail_impl_base.lem, and helps avoid name
+ clashes between the different monad types. *)
+
+type event =
+ | E_read_mem of read_kind * address_lifted * nat * maybe (list reg_name)
+ | E_read_memt of read_kind * address_lifted * nat * maybe (list reg_name)
+ | E_write_mem of write_kind * address_lifted * nat * maybe (list reg_name) * memory_value * maybe (list reg_name)
+ | E_write_ea of write_kind * address_lifted * nat * maybe (list reg_name)
+ | E_excl_res
+ | E_write_memv of maybe address_lifted * memory_value * maybe (list reg_name)
+ | E_write_memvt of maybe address_lifted * (bit_lifted * memory_value) * maybe (list reg_name)
+ | E_barrier of barrier_kind
+ | E_footprint
+ | E_read_reg of reg_name
+ | E_write_reg of reg_name * register_value
+ | E_escape
+ | E_error of string
+
+
+let eventCompare e1 e2 =
+ match (e1,e2) with
+ | (E_read_mem rk1 v1 i1 tr1, E_read_mem rk2 v2 i2 tr2) ->
+ compare (rk1, (v1,i1,tr1)) (rk2,(v2, i2, tr2))
+ | (E_read_memt rk1 v1 i1 tr1, E_read_memt rk2 v2 i2 tr2) ->
+ compare (rk1, (v1,i1,tr1)) (rk2,(v2, i2, tr2))
+ | (E_write_mem wk1 v1 i1 tr1 v1' tr1', E_write_mem wk2 v2 i2 tr2 v2' tr2') ->
+ compare ((wk1,v1,i1),(tr1,v1',tr1')) ((wk2,v2,i2),(tr2,v2',tr2'))
+ | (E_write_ea wk1 a1 i1 tr1, E_write_ea wk2 a2 i2 tr2) ->
+ compare (wk1, (a1, i1, tr1)) (wk2, (a2, i2, tr2))
+ | (E_excl_res, E_excl_res) -> EQ
+ | (E_write_memv _ mv1 tr1, E_write_memv _ mv2 tr2) -> compare (mv1,tr1) (mv2,tr2)
+ | (E_write_memvt _ mv1 tr1, E_write_memvt _ mv2 tr2) -> compare (mv1,tr1) (mv2,tr2)
+ | (E_barrier bk1, E_barrier bk2) -> compare bk1 bk2
+ | (E_read_reg r1, E_read_reg r2) -> compare r1 r2
+ | (E_write_reg r1 v1, E_write_reg r2 v2) -> compare (r1,v1) (r2,v2)
+ | (E_error s1, E_error s2) -> compare s1 s2
+ | (E_escape,E_escape) -> EQ
+ | (E_read_mem _ _ _ _, _) -> LT
+ | (E_write_mem _ _ _ _ _ _, _) -> LT
+ | (E_write_ea _ _ _ _, _) -> LT
+ | (E_excl_res, _) -> LT
+ | (E_write_memv _ _ _, _) -> LT
+ | (E_barrier _, _) -> LT
+ | (E_read_reg _, _) -> LT
+ | (E_write_reg _ _, _) -> LT
+ | _ -> GT
+ end
+
+let eventLess b1 b2 = eventCompare b1 b2 = LT
+let eventLessEq b1 b2 = eventCompare b1 b2 <> GT
+let eventGreater b1 b2 = eventCompare b1 b2 = GT
+let eventGreaterEq b1 b2 = eventCompare b1 b2 <> LT
+
+instance (Ord event)
+ let compare = eventCompare
+ let (<) = eventLess
+ let (<=) = eventLessEq
+ let (>) = eventGreater
+ let (>=) = eventGreaterEq
+end
+
+instance (SetType event)
+ let setElemCompare = compare
+end
+
+
+(* the address_lifted types should go away here and be replaced by address *)
+type with_aux 'o = 'o * maybe ((unit -> (string * string)) * ((list (reg_name * register_value)) -> list event))
+type outcome 'a 'e =
+ (* Request to read memory, value is location to read, integer is size to read,
+ followed by registers that were used in computing that size *)
+ | Read_mem of (read_kind * address_lifted * nat) * (memory_value -> with_aux (outcome 'a 'e))
+ (* Tell the system a write is imminent, at address lifted, of size nat *)
+ | Write_ea of (write_kind * address_lifted * nat) * (with_aux (outcome 'a 'e))
+ (* Request the result of store-exclusive *)
+ | Excl_res of (bool -> with_aux (outcome 'a 'e))
+ (* Request to write memory at last signalled address. Memory value should be 8
+ times the size given in ea signal *)
+ | Write_memv of memory_value * (bool -> with_aux (outcome 'a 'e))
+ (* Request a memory barrier *)
+ | Barrier of barrier_kind * with_aux (outcome 'a 'e)
+ (* Tell the system to dynamically recalculate dependency footprint *)
+ | Footprint of with_aux (outcome 'a 'e)
+ (* Request to read register, will track dependency when mode.track_values *)
+ | Read_reg of reg_name * (register_value -> with_aux (outcome 'a 'e))
+ (* Request to write register *)
+ | Write_reg of (reg_name * register_value) * with_aux (outcome 'a 'e)
+ | Escape of maybe string
+ (*Result of a failed assert with possible error message to report*)
+ | Fail of maybe string
+ (* Exception of type 'e *)
+ | Exception of 'e
+ | Internal of (maybe string * maybe (unit -> string)) * with_aux (outcome 'a 'e)
+ | Done of 'a
+ | Error of string
+
+type outcome_s 'a 'e = with_aux (outcome 'a 'e)
+(* first string : output of instruction_stack_to_string
+ second string: output of local_variables_to_string *)
+
+(** operations and coercions on basic values *)
+
+val word8_to_bitls : word8 -> list bit_lifted
+val bitls_to_word8 : list bit_lifted -> word8
+
+val integer_of_word8_list : list word8 -> integer
+val word8_list_of_integer : integer -> integer -> list word8
+
+val concretizable_bitl : bit_lifted -> bool
+val concretizable_bytl : byte_lifted -> bool
+val concretizable_bytls : list byte_lifted -> bool
+
+let concretizable_bitl = function
+ | Bitl_zero -> true
+ | Bitl_one -> true
+ | Bitl_undef -> false
+ | Bitl_unknown -> false
+end
+
+let concretizable_bytl (Byte_lifted bs) = List.all concretizable_bitl bs
+let concretizable_bytls = List.all concretizable_bytl
+
+(* constructing values *)
+
+val build_register_value : list bit_lifted -> direction -> nat -> nat -> register_value
+let build_register_value bs dir width start_index =
+ <| rv_bits = bs;
+ rv_dir = dir; (* D_increasing for Power, D_decreasing for ARM *)
+ rv_start_internal = start_index;
+ rv_start = if dir = D_increasing
+ then start_index
+ else (start_index+1) - width; (* Smaller index, as in Power, for external interaction *)
+ |>
+
+val register_value : bit_lifted -> direction -> nat -> nat -> register_value
+let register_value b dir width start_index =
+ build_register_value (List.replicate width b) dir width start_index
+
+val register_value_zeros : direction -> nat -> nat -> register_value
+let register_value_zeros dir width start_index =
+ register_value Bitl_zero dir width start_index
+
+val register_value_ones : direction -> nat -> nat -> register_value
+let register_value_ones dir width start_index =
+ register_value Bitl_one dir width start_index
+
+val register_value_for_reg : reg_name -> list bit_lifted -> register_value
+let register_value_for_reg r bs : register_value =
+ let () = ensure (width_of_reg_name r = List.length bs)
+ ("register_value_for_reg (\"" ^ show (register_base_name r) ^ "\") length mismatch: "
+ ^ show (width_of_reg_name r) ^ " vs " ^ show (List.length bs))
+ in
+ let (j1, j2) = slice_of_reg_name r in
+ let d = direction_of_reg_name r in
+ <| rv_bits = bs;
+ rv_dir = d;
+ rv_start_internal = if d = D_increasing then j1 else (start_of_reg_name r) - j1;
+ rv_start = j1;
+ |>
+
+val byte_lifted_undef : byte_lifted
+let byte_lifted_undef = Byte_lifted (List.replicate 8 Bitl_undef)
+
+val byte_lifted_unknown : byte_lifted
+let byte_lifted_unknown = Byte_lifted (List.replicate 8 Bitl_unknown)
+
+val memory_value_unknown : nat (*the number of bytes*) -> memory_value
+let memory_value_unknown (width:nat) : memory_value =
+ List.replicate width byte_lifted_unknown
+
+val memory_value_undef : nat (*the number of bytes*) -> memory_value
+let memory_value_undef (width:nat) : memory_value =
+ List.replicate width byte_lifted_undef
+
+val match_endianness : forall 'a. end_flag -> list 'a -> list 'a
+let match_endianness endian l =
+ match endian with
+ | E_little_endian -> List.reverse l
+ | E_big_endian -> l
+ end
+
+(* lengths *)
+
+val memory_value_length : memory_value -> nat
+let memory_value_length (mv:memory_value) = List.length mv
+
+
+(* aux fns *)
+
+val maybe_all : forall 'a. list (maybe 'a) -> maybe (list 'a)
+let rec maybe_all' xs acc =
+ match xs with
+ | [] -> Just (List.reverse acc)
+ | Nothing :: _ -> Nothing
+ | (Just y)::xs' -> maybe_all' xs' (y::acc)
+ end
+let maybe_all xs = maybe_all' xs []
+
+(** coercions *)
+
+(* bits and bytes *)
+
+let bit_to_bool = function (* TODO: rename bool_of_bit *)
+ | Bitc_zero -> false
+ | Bitc_one -> true
+end
+
+
+val bit_lifted_of_bit : bit -> bit_lifted
+let bit_lifted_of_bit b =
+ match b with
+ | Bitc_zero -> Bitl_zero
+ | Bitc_one -> Bitl_one
+ end
+
+val bit_of_bit_lifted : bit_lifted -> maybe bit
+let bit_of_bit_lifted bl =
+ match bl with
+ | Bitl_zero -> Just Bitc_zero
+ | Bitl_one -> Just Bitc_one
+ | Bitl_undef -> Nothing
+ | Bitl_unknown -> Nothing
+ end
+
+
+val byte_lifted_of_byte : byte -> byte_lifted
+let byte_lifted_of_byte (Byte bs) : byte_lifted = Byte_lifted (List.map bit_lifted_of_bit bs)
+
+val byte_of_byte_lifted : byte_lifted -> maybe byte
+let byte_of_byte_lifted bl =
+ match bl with
+ | Byte_lifted bls ->
+ match maybe_all (List.map bit_of_bit_lifted bls) with
+ | Nothing -> Nothing
+ | Just bs -> Just (Byte bs)
+ end
+ end
+
+
+val bytes_of_bits : list bit -> list byte (*assumes (length bits) mod 8 = 0*)
+let rec bytes_of_bits bits = match bits with
+ | [] -> []
+ | b0::b1::b2::b3::b4::b5::b6::b7::bits ->
+ (Byte [b0;b1;b2;b3;b4;b5;b6;b7])::(bytes_of_bits bits)
+ | _ -> failwith "bytes_of_bits not given bits divisible by 8"
+end
+
+val byte_lifteds_of_bit_lifteds : list bit_lifted -> list byte_lifted (*assumes (length bits) mod 8 = 0*)
+let rec byte_lifteds_of_bit_lifteds bits = match bits with
+ | [] -> []
+ | b0::b1::b2::b3::b4::b5::b6::b7::bits ->
+ (Byte_lifted [b0;b1;b2;b3;b4;b5;b6;b7])::(byte_lifteds_of_bit_lifteds bits)
+ | _ -> failwith "byte_lifteds of bit_lifteds not given bits divisible by 8"
+end
+
+
+val byte_of_memory_byte : memory_byte -> maybe byte
+let byte_of_memory_byte = byte_of_byte_lifted
+
+val memory_byte_of_byte : byte -> memory_byte
+let memory_byte_of_byte = byte_lifted_of_byte
+
+
+(* to and from nat *)
+
+(* this natFromBoolList could move to the Lem word.lem library *)
+val natFromBoolList : list bool -> nat
+let rec natFromBoolListAux (acc : nat) (bl : list bool) =
+ match bl with
+ | [] -> acc
+ | (true :: bl') -> natFromBoolListAux ((acc * 2) + 1) bl'
+ | (false :: bl') -> natFromBoolListAux (acc * 2) bl'
+ end
+let natFromBoolList bl =
+ natFromBoolListAux 0 (List.reverse bl)
+
+
+val nat_of_bit_list : list bit -> nat
+let nat_of_bit_list b =
+ natFromBoolList (List.reverse (List.map bit_to_bool b))
+ (* natFromBoolList takes a list with LSB first, for consistency with rest of Lem word library, so we reverse it. twice. *)
+
+
+(* to and from integer *)
+
+val integer_of_bit_list : list bit -> integer
+let integer_of_bit_list b =
+ integerFromBoolList (false,(List.reverse (List.map bit_to_bool b)))
+ (* integerFromBoolList takes a list with LSB first, so we reverse it *)
+
+val bit_list_of_integer : nat -> integer -> list bit
+let bit_list_of_integer len b =
+ List.map (fun b -> if b then Bitc_one else Bitc_zero)
+ (reverse (boolListFrombitSeq len (bitSeqFromInteger Nothing b)))
+
+val integer_of_byte_list : list byte -> integer
+let integer_of_byte_list bytes = integer_of_bit_list (List.concatMap (fun (Byte bs) -> bs) bytes)
+
+val byte_list_of_integer : nat -> integer -> list byte
+let byte_list_of_integer (len:nat) (a:integer):list byte =
+ let bits = bit_list_of_integer (len * 8) a in bytes_of_bits bits
+
+
+val integer_of_address : address -> integer
+let integer_of_address (a:address):integer =
+ match a with
+ | Address bs i -> i
+ end
+
+val address_of_integer : integer -> address
+let address_of_integer (i:integer):address =
+ Address (byte_list_of_integer 8 i) i
+
+(* to and from signed-integer *)
+
+val signed_integer_of_bit_list : list bit -> integer
+let signed_integer_of_bit_list b =
+ match b with
+ | [] -> failwith "empty bit list"
+ | Bitc_zero :: b' ->
+ integerFromBoolList (false,(List.reverse (List.map bit_to_bool b)))
+ | Bitc_one :: b' ->
+ let b'_val = integerFromBoolList (false,(List.reverse (List.map bit_to_bool b'))) in
+ (* integerFromBoolList takes a list with LSB first, so we reverse it *)
+ let msb_val = integerPow 2 ((List.length b) - 1) in
+ b'_val - msb_val
+ end
+
+
+(* regarding a list of int as a list of bytes in memory, MSB lowest-address first, convert to an integer *)
+val integer_address_of_int_list : list int -> integer
+let rec integerFromIntListAux (acc: integer) (is: list int) =
+ match is with
+ | [] -> acc
+ | (i :: is') -> integerFromIntListAux ((acc * 256) + integerFromInt i) is'
+ end
+let integer_address_of_int_list (is: list int) =
+ integerFromIntListAux 0 is
+
+val address_of_byte_list : list byte -> address
+let address_of_byte_list bs =
+ if List.length bs <> 8 then failwith "address_of_byte_list given list not of length 8" else
+ Address bs (integer_of_byte_list bs)
+
+let address_of_byte_lifted_list bls =
+ match maybe_all (List.map byte_of_byte_lifted bls) with
+ | Nothing -> Nothing
+ | Just bs -> Just (address_of_byte_list bs)
+ end
+
+(* operations on addresses *)
+
+val add_address_nat : address -> nat -> address
+let add_address_nat (a:address) (i:nat) : address =
+ address_of_integer ((integer_of_address a) + (integerFromNat i))
+
+val clear_low_order_bits_of_address : address -> address
+let clear_low_order_bits_of_address a =
+ match a with
+ | Address [b0;b1;b2;b3;b4;b5;b6;b7] i ->
+ match b7 with
+ | Byte [bt0;bt1;bt2;bt3;bt4;bt5;bt6;bt7] ->
+ let b7' = Byte [bt0;bt1;bt2;bt3;bt4;bt5;Bitc_zero;Bitc_zero] in
+ let bytes = [b0;b1;b2;b3;b4;b5;b6;b7'] in
+ Address bytes (integer_of_byte_list bytes)
+ | _ -> failwith "Byte does not contain 8 bits"
+ end
+ | _ -> failwith "Address does not contain 8 bytes"
+ end
+
+
+
+val byte_list_of_memory_value : end_flag -> memory_value -> maybe (list byte)
+let byte_list_of_memory_value endian mv =
+ match_endianness endian mv
+ $> List.map byte_of_memory_byte
+ $> maybe_all
+
+
+val integer_of_memory_value : end_flag -> memory_value -> maybe integer
+let integer_of_memory_value endian (mv:memory_value):maybe integer =
+ match byte_list_of_memory_value endian mv with
+ | Just bs -> Just (integer_of_byte_list bs)
+ | Nothing -> Nothing
+ end
+
+val memory_value_of_integer : end_flag -> nat -> integer -> memory_value
+let memory_value_of_integer endian (len:nat) (i:integer):memory_value =
+ List.map byte_lifted_of_byte (byte_list_of_integer len i)
+ $> match_endianness endian
+
+
+val integer_of_register_value : register_value -> maybe integer
+let integer_of_register_value (rv:register_value):maybe integer =
+ match maybe_all (List.map bit_of_bit_lifted rv.rv_bits) with
+ | Nothing -> Nothing
+ | Just bs -> Just (integer_of_bit_list bs)
+ end
+
+(* NOTE: register_value_for_reg_of_integer might be easier to use *)
+val register_value_of_integer : nat -> nat -> direction -> integer -> register_value
+let register_value_of_integer (len:nat) (start:nat) (dir:direction) (i:integer):register_value =
+ let bs = bit_list_of_integer len i in
+ build_register_value (List.map bit_lifted_of_bit bs) dir len start
+
+val register_value_for_reg_of_integer : reg_name -> integer -> register_value
+let register_value_for_reg_of_integer (r: reg_name) (i:integer) : register_value =
+ register_value_of_integer (width_of_reg_name r) (start_of_reg_name r) (direction_of_reg_name r) i
+
+(* *)
+
+val opcode_of_bytes : byte -> byte -> byte -> byte -> opcode
+let opcode_of_bytes b0 b1 b2 b3 : opcode = Opcode [b0;b1;b2;b3]
+
+val register_value_of_address : address -> direction -> register_value
+let register_value_of_address (Address bytes _) dir : register_value =
+ let bits = List.concatMap (fun (Byte bs) -> List.map bit_lifted_of_bit bs) bytes in
+ <| rv_bits = bits;
+ rv_dir = dir;
+ rv_start = 0;
+ rv_start_internal = if dir = D_increasing then 0 else (List.length bits) - 1
+ |>
+
+val register_value_of_memory_value : memory_value -> direction -> register_value
+let register_value_of_memory_value bytes dir : register_value =
+ let bitls = List.concatMap (fun (Byte_lifted bs) -> bs) bytes in
+ <| rv_bits = bitls;
+ rv_dir = dir;
+ rv_start = 0;
+ rv_start_internal = if dir = D_increasing then 0 else (List.length bitls) - 1
+ |>
+
+val memory_value_of_register_value: register_value -> memory_value
+let memory_value_of_register_value r =
+ (byte_lifteds_of_bit_lifteds r.rv_bits)
+
+val address_lifted_of_register_value : register_value -> maybe address_lifted
+(* returning Nothing iff the register value is not 64 bits wide, but
+allowing Bitl_undef and Bitl_unknown *)
+let address_lifted_of_register_value (rv:register_value) : maybe address_lifted =
+ if List.length rv.rv_bits <> 64 then Nothing
+ else
+ Just (Address_lifted (byte_lifteds_of_bit_lifteds rv.rv_bits)
+ (if List.all concretizable_bitl rv.rv_bits
+ then match (maybe_all (List.map bit_of_bit_lifted rv.rv_bits)) with
+ | (Just(bits)) -> Just (integer_of_bit_list bits)
+ | Nothing -> Nothing end
+ else Nothing))
+
+val address_of_address_lifted : address_lifted -> maybe address
+(* returning Nothing iff the address contains any Bitl_undef or Bitl_unknown *)
+let address_of_address_lifted (al:address_lifted): maybe address =
+ match al with
+ | Address_lifted bls (Just i)->
+ match maybe_all ((List.map byte_of_byte_lifted) bls) with
+ | Nothing -> Nothing
+ | Just bs -> Just (Address bs i)
+ end
+ | _ -> Nothing
+end
+
+val address_of_register_value : register_value -> maybe address
+(* returning Nothing iff the register value is not 64 bits wide, or contains Bitl_undef or Bitl_unknown *)
+let address_of_register_value (rv:register_value) : maybe address =
+ match address_lifted_of_register_value rv with
+ | Nothing -> Nothing
+ | Just al ->
+ match address_of_address_lifted al with
+ | Nothing -> Nothing
+ | Just a -> Just a
+ end
+ end
+
+let address_of_memory_value (endian: end_flag) (mv:memory_value) : maybe address =
+ match byte_list_of_memory_value endian mv with
+ | Nothing -> Nothing
+ | Just bs ->
+ if List.length bs <> 8 then Nothing else
+ Just (address_of_byte_list bs)
+ end
+
+val byte_of_int : int -> byte
+let byte_of_int (i:int) : byte =
+ Byte (bit_list_of_integer 8 (integerFromInt i))
+
+val memory_byte_of_int : int -> memory_byte
+let memory_byte_of_int (i:int) : memory_byte =
+ memory_byte_of_byte (byte_of_int i)
+
+(*
+val int_of_memory_byte : int -> maybe memory_byte
+let int_of_memory_byte (mb:memory_byte) : int =
+ failwith "TODO"
+*)
+
+
+
+val memory_value_of_address_lifted : end_flag -> address_lifted -> memory_value
+let memory_value_of_address_lifted endian (Address_lifted bs _ :address_lifted) =
+ match_endianness endian bs
+
+val byte_list_of_address : address -> list byte
+let byte_list_of_address (Address bs _) : list byte = bs
+
+val memory_value_of_address : end_flag -> address -> memory_value
+let memory_value_of_address endian (Address bs _) =
+ match_endianness endian bs
+ $> List.map byte_lifted_of_byte
+
+val byte_list_of_opcode : opcode -> list byte
+let byte_list_of_opcode (Opcode bs) : list byte = bs
+
+(** ****************************************** *)
+(** show type class instantiations *)
+(** ****************************************** *)
+
+(* matching printing_functions.ml *)
+val stringFromReg_name : reg_name -> string
+let stringFromReg_name r =
+ let norm_sl start dir (first,second) = (first,second)
+ (* match dir with
+ | D_increasing -> (first,second)
+ | D_decreasing -> (start - first, start - second)
+ end *)
+ in
+ match r with
+ | Reg s start size dir -> s
+ | Reg_slice s start dir sl ->
+ let (first,second) = norm_sl start dir sl in
+ s ^ "[" ^ show first ^ (if (first = second) then "" else ".." ^ (show second)) ^ "]"
+ | Reg_field s start dir f sl ->
+ let (first,second) = norm_sl start dir sl in
+ s ^ "." ^ f ^ " (" ^ (show start) ^ ", " ^ (show dir) ^ ", " ^ (show first) ^ ", " ^ (show second) ^ ")"
+ | Reg_f_slice s start dir f (first1,second1) (first,second) ->
+ let (first,second) =
+ match dir with
+ | D_increasing -> (first,second)
+ | D_decreasing -> (start - first, start - second)
+ end in
+ s ^ "." ^ f ^ "]" ^ show first ^ (if (first = second) then "" else ".." ^ (show second)) ^ "]"
+ end
+
+instance (Show reg_name)
+ let show = stringFromReg_name
+end
+
+
+(* hex pp of integers, adapting the Lem string_extra.lem code *)
+val stringFromNaturalHexHelper : natural -> list char -> list char
+let rec stringFromNaturalHexHelper n acc =
+ if n = 0 then
+ acc
+ else
+ stringFromNaturalHexHelper (n / 16) (String_extra.chr (natFromNatural (let nd = n mod 16 in if nd <=9 then nd + 48 else nd - 10 + 97)) :: acc)
+
+val stringFromNaturalHex : natural -> string
+let (*~{ocaml;hol}*) stringFromNaturalHex n =
+ if n = 0 then "0" else toString (stringFromNaturalHexHelper n [])
+
+val stringFromIntegerHex : integer -> string
+let (*~{ocaml}*) stringFromIntegerHex i =
+ if i < 0 then
+ "-" ^ stringFromNaturalHex (naturalFromInteger i)
+ else
+ stringFromNaturalHex (naturalFromInteger i)
+
+
+let stringFromAddress (Address bs i) =
+ let i' = integer_of_byte_list bs in
+ if i=i' then
+(*TODO: ideally this should be made to match the src/pp.ml pp_address; the following very roughly matches what's used in the ppcmem UI, enough to make exceptions readable *)
+ if i < 65535 then
+ show i
+ else
+ stringFromIntegerHex i
+ else
+ "stringFromAddress bytes and integer mismatch"
+
+instance (Show address)
+ let show = stringFromAddress
+end
+
+let stringFromByte_lifted bl =
+ match byte_of_byte_lifted bl with
+ | Nothing -> "u?"
+ | Just (Byte bits) ->
+ let i = integer_of_bit_list bits in
+ show i
+ end
+
+instance (Show byte_lifted)
+ let show = stringFromByte_lifted
+end
+
+(* possible next instruction address options *)
+type nia =
+ | NIA_successor
+ | NIA_concrete_address of address
+ | NIA_indirect_address
+
+let niaCompare n1 n2 = match (n1,n2) with
+ | (NIA_successor, NIA_successor) -> EQ
+ | (NIA_successor, _) -> LT
+ | (_, NIA_successor) -> GT
+ | (NIA_concrete_address a1, NIA_concrete_address a2) -> compare a1 a2
+ | (NIA_concrete_address _, _) -> LT
+ | (_, NIA_concrete_address _) -> GT
+ | (NIA_indirect_address, NIA_indirect_address) -> EQ
+ (* | (NIA_indirect_address, _) -> LT
+ | (_, NIA_indirect_address) -> GT *)
+ end
+
+instance (Ord nia)
+ let compare = niaCompare
+ let (<) n1 n2 = (niaCompare n1 n2) = LT
+ let (<=) n1 n2 = (niaCompare n1 n2) <> GT
+ let (>) n1 n2 = (niaCompare n1 n2) = GT
+ let (>=) n1 n2 = (niaCompare n1 n2) <> LT
+end
+
+let stringFromNia = function
+ | NIA_successor -> "NIA_successor"
+ | NIA_concrete_address a -> "NIA_concrete_address " ^ show a
+ | NIA_indirect_address -> "NIA_indirect_address"
+end
+
+instance (Show nia)
+ let show = stringFromNia
+end
+
+type dia =
+ | DIA_none
+ | DIA_concrete_address of address
+ | DIA_register of reg_name
+
+let diaCompare d1 d2 = match (d1, d2) with
+ | (DIA_none, DIA_none) -> EQ
+ | (DIA_none, _) -> LT
+ | (DIA_concrete_address a1, DIA_none) -> GT
+ | (DIA_concrete_address a1, DIA_concrete_address a2) -> compare a1 a2
+ | (DIA_concrete_address a1, _) -> LT
+ | (DIA_register r1, DIA_register r2) -> compare r1 r2
+ | (DIA_register _, _) -> GT
+end
+
+instance (Ord dia)
+ let compare = diaCompare
+ let (<) n1 n2 = (diaCompare n1 n2) = LT
+ let (<=) n1 n2 = (diaCompare n1 n2) <> GT
+ let (>) n1 n2 = (diaCompare n1 n2) = GT
+ let (>=) n1 n2 = (diaCompare n1 n2) <> LT
+end
+
+let stringFromDia = function
+ | DIA_none -> "DIA_none"
+ | DIA_concrete_address a -> "DIA_concrete_address " ^ show a
+ | DIA_register r -> "DIA_delayed_register " ^ show r
+end
+
+instance (Show dia)
+ let show = stringFromDia
+end
+*)
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_instr_kinds.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_instr_kinds.v
new file mode 100644
index 00000000..c93e9e93
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_instr_kinds.v
@@ -0,0 +1,302 @@
+(*========================================================================*)
+(* Sail *)
+(* *)
+(* Copyright (c) 2013-2017 *)
+(* Kathyrn Gray *)
+(* Shaked Flur *)
+(* Stephen Kell *)
+(* Gabriel Kerneis *)
+(* Robert Norton-Wright *)
+(* Christopher Pulte *)
+(* Peter Sewell *)
+(* Alasdair Armstrong *)
+(* Brian Campbell *)
+(* Thomas Bauereiss *)
+(* Anthony Fox *)
+(* Jon French *)
+(* Dominic Mulligan *)
+(* Stephen Kell *)
+(* Mark Wassell *)
+(* *)
+(* All rights reserved. *)
+(* *)
+(* This software was developed by the University of Cambridge Computer *)
+(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *)
+(* (REMS) project, funded by EPSRC grant EP/K008528/1. *)
+(* *)
+(* Redistribution and use in source and binary forms, with or without *)
+(* modification, are permitted provided that the following conditions *)
+(* are met: *)
+(* 1. Redistributions of source code must retain the above copyright *)
+(* notice, this list of conditions and the following disclaimer. *)
+(* 2. Redistributions in binary form must reproduce the above copyright *)
+(* notice, this list of conditions and the following disclaimer in *)
+(* the documentation and/or other materials provided with the *)
+(* distribution. *)
+(* *)
+(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *)
+(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *)
+(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *)
+(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *)
+(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)
+(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *)
+(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *)
+(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *)
+(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *)
+(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *)
+(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *)
+(* SUCH DAMAGE. *)
+(*========================================================================*)
+
+
+(*
+
+class ( EnumerationType 'a )
+ val toNat : 'a -> nat
+end
+
+
+val enumeration_typeCompare : forall 'a. EnumerationType 'a => 'a -> 'a -> ordering
+let ~{ocaml} enumeration_typeCompare e1 e2 :=
+ compare (toNat e1) (toNat e2)
+let inline {ocaml} enumeration_typeCompare := defaultCompare
+
+
+default_instance forall 'a. EnumerationType 'a => (Ord 'a)
+ let compare := enumeration_typeCompare
+ let (<) r1 r2 := (enumeration_typeCompare r1 r2) = LT
+ let (<=) r1 r2 := (enumeration_typeCompare r1 r2) <> GT
+ let (>) r1 r2 := (enumeration_typeCompare r1 r2) = GT
+ let (>=) r1 r2 := (enumeration_typeCompare r1 r2) <> LT
+end
+*)
+
+(* Data structures for building up instructions *)
+
+(* careful: changes in the read/write/barrier kinds have to be
+ reflected in deep_shallow_convert *)
+Inductive read_kind :=
+ (* common reads *)
+ | Read_plain
+ (* Power reads *)
+ | Read_reserve
+ (* AArch64 reads *)
+ | Read_acquire | Read_exclusive | Read_exclusive_acquire | Read_stream
+ (* RISC-V reads *)
+ | Read_RISCV_acquire | Read_RISCV_strong_acquire
+ | Read_RISCV_reserved | Read_RISCV_reserved_acquire
+ | Read_RISCV_reserved_strong_acquire
+ (* x86 reads *)
+ | Read_X86_locked (* the read part of a lock'd instruction (rmw) *)
+.
+(*
+instance (Show read_kind)
+ let show := function
+ | Read_plain -> "Read_plain"
+ | Read_reserve -> "Read_reserve"
+ | Read_acquire -> "Read_acquire"
+ | Read_exclusive -> "Read_exclusive"
+ | Read_exclusive_acquire -> "Read_exclusive_acquire"
+ | Read_stream -> "Read_stream"
+ | Read_RISCV_acquire -> "Read_RISCV_acquire"
+ | Read_RISCV_strong_acquire -> "Read_RISCV_strong_acquire"
+ | Read_RISCV_reserved -> "Read_RISCV_reserved"
+ | Read_RISCV_reserved_acquire -> "Read_RISCV_reserved_acquire"
+ | Read_RISCV_reserved_strong_acquire -> "Read_RISCV_reserved_strong_acquire"
+ | Read_X86_locked -> "Read_X86_locked"
+ end
+end
+*)
+Inductive write_kind :=
+ (* common writes *)
+ | Write_plain
+ (* Power writes *)
+ | Write_conditional
+ (* AArch64 writes *)
+ | Write_release | Write_exclusive | Write_exclusive_release
+ (* RISC-V *)
+ | Write_RISCV_release | Write_RISCV_strong_release
+ | Write_RISCV_conditional | Write_RISCV_conditional_release
+ | Write_RISCV_conditional_strong_release
+ (* x86 writes *)
+ | Write_X86_locked (* the write part of a lock'd instruction (rmw) *)
+.
+(*
+instance (Show write_kind)
+ let show := function
+ | Write_plain -> "Write_plain"
+ | Write_conditional -> "Write_conditional"
+ | Write_release -> "Write_release"
+ | Write_exclusive -> "Write_exclusive"
+ | Write_exclusive_release -> "Write_exclusive_release"
+ | Write_RISCV_release -> "Write_RISCV_release"
+ | Write_RISCV_strong_release -> "Write_RISCV_strong_release"
+ | Write_RISCV_conditional -> "Write_RISCV_conditional"
+ | Write_RISCV_conditional_release -> "Write_RISCV_conditional_release"
+ | Write_RISCV_conditional_strong_release -> "Write_RISCV_conditional_strong_release"
+ | Write_X86_locked -> "Write_X86_locked"
+ end
+end
+*)
+Inductive barrier_kind :=
+ (* Power barriers *)
+ Barrier_Sync | Barrier_LwSync | Barrier_Eieio | Barrier_Isync
+ (* AArch64 barriers *)
+ | Barrier_DMB | Barrier_DMB_ST | Barrier_DMB_LD | Barrier_DSB
+ | Barrier_DSB_ST | Barrier_DSB_LD | Barrier_ISB
+ | Barrier_TM_COMMIT
+ (* MIPS barriers *)
+ | Barrier_MIPS_SYNC
+ (* RISC-V barriers *)
+ | Barrier_RISCV_rw_rw
+ | Barrier_RISCV_r_rw
+ | Barrier_RISCV_r_r
+ | Barrier_RISCV_rw_w
+ | Barrier_RISCV_w_w
+ | Barrier_RISCV_w_rw
+ | Barrier_RISCV_rw_r
+ | Barrier_RISCV_r_w
+ | Barrier_RISCV_w_r
+ | Barrier_RISCV_i
+ (* X86 *)
+ | Barrier_x86_MFENCE.
+
+(*
+instance (Show barrier_kind)
+ let show := function
+ | Barrier_Sync -> "Barrier_Sync"
+ | Barrier_LwSync -> "Barrier_LwSync"
+ | Barrier_Eieio -> "Barrier_Eieio"
+ | Barrier_Isync -> "Barrier_Isync"
+ | Barrier_DMB -> "Barrier_DMB"
+ | Barrier_DMB_ST -> "Barrier_DMB_ST"
+ | Barrier_DMB_LD -> "Barrier_DMB_LD"
+ | Barrier_DSB -> "Barrier_DSB"
+ | Barrier_DSB_ST -> "Barrier_DSB_ST"
+ | Barrier_DSB_LD -> "Barrier_DSB_LD"
+ | Barrier_ISB -> "Barrier_ISB"
+ | Barrier_TM_COMMIT -> "Barrier_TM_COMMIT"
+ | Barrier_MIPS_SYNC -> "Barrier_MIPS_SYNC"
+ | Barrier_RISCV_rw_rw -> "Barrier_RISCV_rw_rw"
+ | Barrier_RISCV_r_rw -> "Barrier_RISCV_r_rw"
+ | Barrier_RISCV_r_r -> "Barrier_RISCV_r_r"
+ | Barrier_RISCV_rw_w -> "Barrier_RISCV_rw_w"
+ | Barrier_RISCV_w_w -> "Barrier_RISCV_w_w"
+ | Barrier_RISCV_i -> "Barrier_RISCV_i"
+ | Barrier_x86_MFENCE -> "Barrier_x86_MFENCE"
+ end
+end*)
+
+Inductive trans_kind :=
+ (* AArch64 *)
+ | Transaction_start | Transaction_commit | Transaction_abort.
+(*
+instance (Show trans_kind)
+ let show := function
+ | Transaction_start -> "Transaction_start"
+ | Transaction_commit -> "Transaction_commit"
+ | Transaction_abort -> "Transaction_abort"
+ end
+end*)
+
+Inductive instruction_kind :=
+ | IK_barrier : barrier_kind -> instruction_kind
+ | IK_mem_read : read_kind -> instruction_kind
+ | IK_mem_write : write_kind -> instruction_kind
+ | IK_mem_rmw : (read_kind * write_kind) -> instruction_kind
+ | IK_branch (* this includes conditional-branch (multiple nias, none of which is NIA_indirect_address),
+ indirect/computed-branch (single nia of kind NIA_indirect_address)
+ and branch/jump (single nia of kind NIA_concrete_address) *)
+ | IK_trans : trans_kind -> instruction_kind
+ | IK_simple : instruction_kind.
+
+(*
+instance (Show instruction_kind)
+ let show := function
+ | IK_barrier barrier_kind -> "IK_barrier " ^ (show barrier_kind)
+ | IK_mem_read read_kind -> "IK_mem_read " ^ (show read_kind)
+ | IK_mem_write write_kind -> "IK_mem_write " ^ (show write_kind)
+ | IK_mem_rmw (r, w) -> "IK_mem_rmw " ^ (show r) ^ " " ^ (show w)
+ | IK_branch -> "IK_branch"
+ | IK_trans trans_kind -> "IK_trans " ^ (show trans_kind)
+ | IK_simple -> "IK_simple"
+ end
+end
+*)
+
+Definition read_is_exclusive r :=
+match r with
+ | Read_plain => false
+ | Read_reserve => true
+ | Read_acquire => false
+ | Read_exclusive => true
+ | Read_exclusive_acquire => true
+ | Read_stream => false
+ | Read_RISCV_acquire => false
+ | Read_RISCV_strong_acquire => false
+ | Read_RISCV_reserved => true
+ | Read_RISCV_reserved_acquire => true
+ | Read_RISCV_reserved_strong_acquire => true
+ | Read_X86_locked => true
+end.
+
+
+(*
+instance (EnumerationType read_kind)
+ let toNat := function
+ | Read_plain -> 0
+ | Read_reserve -> 1
+ | Read_acquire -> 2
+ | Read_exclusive -> 3
+ | Read_exclusive_acquire -> 4
+ | Read_stream -> 5
+ | Read_RISCV_acquire -> 6
+ | Read_RISCV_strong_acquire -> 7
+ | Read_RISCV_reserved -> 8
+ | Read_RISCV_reserved_acquire -> 9
+ | Read_RISCV_reserved_strong_acquire -> 10
+ | Read_X86_locked -> 11
+ end
+end
+
+instance (EnumerationType write_kind)
+ let toNat := function
+ | Write_plain -> 0
+ | Write_conditional -> 1
+ | Write_release -> 2
+ | Write_exclusive -> 3
+ | Write_exclusive_release -> 4
+ | Write_RISCV_release -> 5
+ | Write_RISCV_strong_release -> 6
+ | Write_RISCV_conditional -> 7
+ | Write_RISCV_conditional_release -> 8
+ | Write_RISCV_conditional_strong_release -> 9
+ | Write_X86_locked -> 10
+ end
+end
+
+instance (EnumerationType barrier_kind)
+ let toNat := function
+ | Barrier_Sync -> 0
+ | Barrier_LwSync -> 1
+ | Barrier_Eieio ->2
+ | Barrier_Isync -> 3
+ | Barrier_DMB -> 4
+ | Barrier_DMB_ST -> 5
+ | Barrier_DMB_LD -> 6
+ | Barrier_DSB -> 7
+ | Barrier_DSB_ST -> 8
+ | Barrier_DSB_LD -> 9
+ | Barrier_ISB -> 10
+ | Barrier_TM_COMMIT -> 11
+ | Barrier_MIPS_SYNC -> 12
+ | Barrier_RISCV_rw_rw -> 13
+ | Barrier_RISCV_r_rw -> 14
+ | Barrier_RISCV_r_r -> 15
+ | Barrier_RISCV_rw_w -> 16
+ | Barrier_RISCV_w_w -> 17
+ | Barrier_RISCV_i -> 18
+ | Barrier_x86_MFENCE -> 19
+ end
+end
+*)
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_operators.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_operators.v
new file mode 100644
index 00000000..ab02c4a8
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_operators.v
@@ -0,0 +1,232 @@
+Require Import Sail2_values.
+Require List.
+Import List.ListNotations.
+
+(*** Bit vector operations *)
+
+Section Bitvectors.
+Context {a b c} `{Bitvector a} `{Bitvector b} `{Bitvector c}.
+
+(*val concat_bv : forall 'a 'b 'c. Bitvector 'a, Bitvector 'b, Bitvector 'c => 'a -> 'b -> 'c*)
+Definition concat_bv (l : a) (r : b) : list bitU := bits_of l ++ bits_of r.
+
+(*val cons_bv : forall 'a 'b 'c. Bitvector 'a, Bitvector 'b => bitU -> 'a -> 'b*)
+Definition cons_bv b' (v : a) : list bitU := b' :: bits_of v.
+
+Definition cast_unit_bv b : list bitU := [b].
+Definition bv_of_bit len b : list bitU := extz_bits len [b].
+
+(*Definition most_significant v := match bits_of v with
+ | cons b _ => b
+ | _ => failwith "most_significant applied to empty vector"
+ end.
+
+Definition get_max_representable_in sign (n : integer) : integer :=
+ if (n = 64) then match sign with | true -> max_64 | false -> max_64u end
+ else if (n=32) then match sign with | true -> max_32 | false -> max_32u end
+ else if (n=8) then max_8
+ else if (n=5) then max_5
+ else match sign with | true -> integerPow 2 ((natFromInteger n) -1)
+ | false -> integerPow 2 (natFromInteger n)
+ end
+
+Definition get_min_representable_in _ (n : integer) : integer :=
+ if n = 64 then min_64
+ else if n = 32 then min_32
+ else if n = 8 then min_8
+ else if n = 5 then min_5
+ else 0 - (integerPow 2 (natFromInteger n))
+
+val arith_op_bv_int : forall 'a 'b. Bitvector 'a =>
+ (integer -> integer -> integer) -> bool -> 'a -> integer -> 'a*)
+Definition arith_op_bv_int {a} `{Bitvector a} (op : Z -> Z -> Z) (sign : bool) (l : a) (r : Z) : a :=
+ let r' := of_int (length l) r in
+ arith_op_bv op sign l r'.
+
+(*val arith_op_int_bv : forall 'a 'b. Bitvector 'a =>
+ (integer -> integer -> integer) -> bool -> integer -> 'a -> 'a*)
+Definition arith_op_int_bv {a} `{Bitvector a} (op : Z -> Z -> Z) (sign : bool) (l : Z) (r : a) : a :=
+ let l' := of_int (length r) l in
+ arith_op_bv op sign l' r.
+(*
+Definition add_bv_int := arith_op_bv_int Zplus false 1.
+Definition sadd_bv_int := arith_op_bv_int Zplus true 1.
+Definition sub_bv_int := arith_op_bv_int Zminus false 1.
+Definition mult_bv_int := arith_op_bv_int Zmult false 2.
+Definition smult_bv_int := arith_op_bv_int Zmult true 2.
+
+(*val arith_op_int_bv : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
+ (integer -> integer -> integer) -> bool -> integer -> integer -> 'a -> 'b
+Definition arith_op_int_bv op sign size l r :=
+ let r' = int_of_bv sign r in
+ let n = op l r' in
+ of_int (size * length r) n
+
+Definition add_int_bv = arith_op_int_bv integerAdd false 1
+Definition sadd_int_bv = arith_op_int_bv integerAdd true 1
+Definition sub_int_bv = arith_op_int_bv integerMinus false 1
+Definition mult_int_bv = arith_op_int_bv integerMult false 2
+Definition smult_int_bv = arith_op_int_bv integerMult true 2
+
+Definition arith_op_bv_bit op sign (size : integer) l r :=
+ let l' = int_of_bv sign l in
+ let n = op l' (match r with | B1 -> (1 : integer) | _ -> 0 end) in
+ of_int (size * length l) n
+
+Definition add_bv_bit := arith_op_bv_bit integerAdd false 1
+Definition sadd_bv_bit := arith_op_bv_bit integerAdd true 1
+Definition sub_bv_bit := arith_op_bv_bit integerMinus true 1
+
+val arith_op_overflow_bv : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
+ (integer -> integer -> integer) -> bool -> integer -> 'a -> 'a -> ('b * bitU * bitU)
+Definition arith_op_overflow_bv op sign size l r :=
+ let len := length l in
+ let act_size := len * size in
+ let (l_sign,r_sign) := (int_of_bv sign l,int_of_bv sign r) in
+ let (l_unsign,r_unsign) := (int_of_bv false l,int_of_bv false r) in
+ let n := op l_sign r_sign in
+ let n_unsign := op l_unsign r_unsign in
+ let correct_size := of_int act_size n in
+ let one_more_size_u := bits_of_int (act_size + 1) n_unsign in
+ let overflow :=
+ if n <= get_max_representable_in sign len &&
+ n >= get_min_representable_in sign len
+ then B0 else B1 in
+ let c_out := most_significant one_more_size_u in
+ (correct_size,overflow,c_out)
+
+Definition add_overflow_bv := arith_op_overflow_bv integerAdd false 1
+Definition add_overflow_bv_signed := arith_op_overflow_bv integerAdd true 1
+Definition sub_overflow_bv := arith_op_overflow_bv integerMinus false 1
+Definition sub_overflow_bv_signed := arith_op_overflow_bv integerMinus true 1
+Definition mult_overflow_bv := arith_op_overflow_bv integerMult false 2
+Definition mult_overflow_bv_signed := arith_op_overflow_bv integerMult true 2
+
+val arith_op_overflow_bv_bit : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
+ (integer -> integer -> integer) -> bool -> integer -> 'a -> bitU -> ('b * bitU * bitU)
+Definition arith_op_overflow_bv_bit op sign size l r_bit :=
+ let act_size := length l * size in
+ let l' := int_of_bv sign l in
+ let l_u := int_of_bv false l in
+ let (n,nu,changed) := match r_bit with
+ | B1 -> (op l' 1, op l_u 1, true)
+ | B0 -> (l',l_u,false)
+ | BU -> failwith "arith_op_overflow_bv_bit applied to undefined bit"
+ end in
+ let correct_size := of_int act_size n in
+ let one_larger := bits_of_int (act_size + 1) nu in
+ let overflow :=
+ if changed
+ then
+ if n <= get_max_representable_in sign act_size && n >= get_min_representable_in sign act_size
+ then B0 else B1
+ else B0 in
+ (correct_size,overflow,most_significant one_larger)
+
+Definition add_overflow_bv_bit := arith_op_overflow_bv_bit integerAdd false 1
+Definition add_overflow_bv_bit_signed := arith_op_overflow_bv_bit integerAdd true 1
+Definition sub_overflow_bv_bit := arith_op_overflow_bv_bit integerMinus false 1
+Definition sub_overflow_bv_bit_signed := arith_op_overflow_bv_bit integerMinus true 1
+
+type shift := LL_shift | RR_shift | RR_shift_arith | LL_rot | RR_rot
+
+val shift_op_bv : forall 'a. Bitvector 'a => shift -> 'a -> integer -> 'a
+Definition shift_op_bv op v n :=
+ match op with
+ | LL_shift ->
+ of_bits (get_bits true v n (length v - 1) ++ repeat [B0] n)
+ | RR_shift ->
+ of_bits (repeat [B0] n ++ get_bits true v 0 (length v - n - 1))
+ | RR_shift_arith ->
+ of_bits (repeat [most_significant v] n ++ get_bits true v 0 (length v - n - 1))
+ | LL_rot ->
+ of_bits (get_bits true v n (length v - 1) ++ get_bits true v 0 (n - 1))
+ | RR_rot ->
+ of_bits (get_bits false v 0 (n - 1) ++ get_bits false v n (length v - 1))
+ end
+
+Definition shiftl_bv := shift_op_bv LL_shift (*"<<"*)
+Definition shiftr_bv := shift_op_bv RR_shift (*">>"*)
+Definition arith_shiftr_bv := shift_op_bv RR_shift_arith
+Definition rotl_bv := shift_op_bv LL_rot (*"<<<"*)
+Definition rotr_bv := shift_op_bv LL_rot (*">>>"*)
+
+Definition shiftl_mword w n := Machine_word.shiftLeft w (natFromInteger n)
+Definition shiftr_mword w n := Machine_word.shiftRight w (natFromInteger n)
+Definition rotl_mword w n := Machine_word.rotateLeft (natFromInteger n) w
+Definition rotr_mword w n := Machine_word.rotateRight (natFromInteger n) w
+
+Definition rec arith_op_no0 (op : integer -> integer -> integer) l r :=
+ if r = 0
+ then Nothing
+ else Just (op l r)
+
+val arith_op_bv_no0 : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
+ (integer -> integer -> integer) -> bool -> integer -> 'a -> 'a -> 'b
+Definition arith_op_bv_no0 op sign size l r :=
+ let act_size := length l * size in
+ let (l',r') := (int_of_bv sign l,int_of_bv sign r) in
+ let n := arith_op_no0 op l' r' in
+ let (representable,n') :=
+ match n with
+ | Just n' ->
+ (n' <= get_max_representable_in sign act_size &&
+ n' >= get_min_representable_in sign act_size, n')
+ | _ -> (false,0)
+ end in
+ if representable then (of_int act_size n') else (of_bits (repeat [BU] act_size))
+
+Definition mod_bv := arith_op_bv_no0 hardware_mod false 1
+Definition quot_bv := arith_op_bv_no0 hardware_quot false 1
+Definition quot_bv_signed := arith_op_bv_no0 hardware_quot true 1
+
+Definition mod_mword := Machine_word.modulo
+Definition quot_mword := Machine_word.unsignedDivide
+Definition quot_mword_signed := Machine_word.signedDivide
+
+Definition arith_op_bv_int_no0 op sign size l r :=
+ arith_op_bv_no0 op sign size l (of_int (length l) r)
+
+Definition quot_bv_int := arith_op_bv_int_no0 hardware_quot false 1
+Definition mod_bv_int := arith_op_bv_int_no0 hardware_mod false 1
+*)
+Definition replicate_bits_bv {a b} `{Bitvector a} `{Bitvector b} (v : a) count : b := of_bits (repeat (bits_of v) count).
+Import List.
+Import ListNotations.
+Definition duplicate_bit_bv {a} `{Bitvector a} bit len : a := replicate_bits_bv [bit] len.
+
+(*val eq_bv : forall 'a. Bitvector 'a => 'a -> 'a -> bool*)
+Definition eq_bv {A} `{Bitvector A} (l : A) r := (unsigned l =? unsigned r).
+
+(*val neq_bv : forall 'a. Bitvector 'a => 'a -> 'a -> bool*)
+Definition neq_bv (l : a) (r :a) : bool := (negb (unsigned l =? unsigned r)).
+(*
+val ucmp_bv : forall 'a. Bitvector 'a => (integer -> integer -> bool) -> 'a -> 'a -> bool
+Definition ucmp_bv cmp l r := cmp (unsigned l) (unsigned r)
+
+val scmp_bv : forall 'a. Bitvector 'a => (integer -> integer -> bool) -> 'a -> 'a -> bool
+Definition scmp_bv cmp l r := cmp (signed l) (signed r)
+
+Definition ult_bv := ucmp_bv (<)
+Definition slt_bv := scmp_bv (<)
+Definition ugt_bv := ucmp_bv (>)
+Definition sgt_bv := scmp_bv (>)
+Definition ulteq_bv := ucmp_bv (<=)
+Definition slteq_bv := scmp_bv (<=)
+Definition ugteq_bv := ucmp_bv (>=)
+Definition sgteq_bv := scmp_bv (>=)
+*)
+
+(*val get_slice_int_bv : forall 'a. Bitvector 'a => integer -> integer -> integer -> 'a*)*)
+Definition get_slice_int_bv {a} `{Bitvector a} len n lo : a :=
+ let hi := lo + len - 1 in
+ let bs := bools_of_int (hi + 1) n in
+ of_bools (subrange_list false bs hi lo).
+
+(*val set_slice_int_bv : forall 'a. Bitvector 'a => integer -> integer -> integer -> 'a -> integer
+Definition set_slice_int_bv {a} `{Bitvector a} len n lo (v : a) :=
+ let hi := lo + len - 1 in
+ let bs := bits_of_int (hi + 1) n in
+ maybe_failwith (signed_of_bits (update_subrange_list false bs hi lo (bits_of v))).*)
+
+End Bitvectors.
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_operators_bitlists.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_operators_bitlists.v
new file mode 100644
index 00000000..dbd8215c
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_operators_bitlists.v
@@ -0,0 +1,182 @@
+Require Import Sail2_values.
+Require Import Sail2_operators.
+
+(*
+
+(* Specialisation of operators to bit lists *)
+
+val access_vec_inc : list bitU -> integer -> bitU
+let access_vec_inc = access_bv_inc
+
+val access_vec_dec : list bitU -> integer -> bitU
+let access_vec_dec = access_bv_dec
+
+val update_vec_inc : list bitU -> integer -> bitU -> list bitU
+let update_vec_inc = update_bv_inc
+
+val update_vec_dec : list bitU -> integer -> bitU -> list bitU
+let update_vec_dec = update_bv_dec
+
+val subrange_vec_inc : list bitU -> integer -> integer -> list bitU
+let subrange_vec_inc = subrange_bv_inc
+
+val subrange_vec_dec : list bitU -> integer -> integer -> list bitU
+let subrange_vec_dec = subrange_bv_dec
+
+val update_subrange_vec_inc : list bitU -> integer -> integer -> list bitU -> list bitU
+let update_subrange_vec_inc = update_subrange_bv_inc
+
+val update_subrange_vec_dec : list bitU -> integer -> integer -> list bitU -> list bitU
+let update_subrange_vec_dec = update_subrange_bv_dec
+
+val extz_vec : integer -> list bitU -> list bitU
+let extz_vec = extz_bv
+
+val exts_vec : integer -> list bitU -> list bitU
+let exts_vec = exts_bv
+
+val concat_vec : list bitU -> list bitU -> list bitU
+let concat_vec = concat_bv
+
+val cons_vec : bitU -> list bitU -> list bitU
+let cons_vec = cons_bv
+
+val bool_of_vec : mword ty1 -> bitU
+let bool_of_vec = bool_of_bv
+
+val cast_unit_vec : bitU -> mword ty1
+let cast_unit_vec = cast_unit_bv
+
+val vec_of_bit : integer -> bitU -> list bitU
+let vec_of_bit = bv_of_bit
+
+val msb : list bitU -> bitU
+let msb = most_significant
+
+val int_of_vec : bool -> list bitU -> integer
+let int_of_vec = int_of_bv
+
+val string_of_vec : list bitU -> string
+let string_of_vec = string_of_bv
+
+val and_vec : list bitU -> list bitU -> list bitU
+val or_vec : list bitU -> list bitU -> list bitU
+val xor_vec : list bitU -> list bitU -> list bitU
+val not_vec : list bitU -> list bitU
+let and_vec = and_bv
+let or_vec = or_bv
+let xor_vec = xor_bv
+let not_vec = not_bv
+
+val add_vec : list bitU -> list bitU -> list bitU
+val sadd_vec : list bitU -> list bitU -> list bitU
+val sub_vec : list bitU -> list bitU -> list bitU
+val mult_vec : list bitU -> list bitU -> list bitU
+val smult_vec : list bitU -> list bitU -> list bitU
+let add_vec = add_bv
+let sadd_vec = sadd_bv
+let sub_vec = sub_bv
+let mult_vec = mult_bv
+let smult_vec = smult_bv
+
+val add_vec_int : list bitU -> integer -> list bitU
+val sadd_vec_int : list bitU -> integer -> list bitU
+val sub_vec_int : list bitU -> integer -> list bitU
+val mult_vec_int : list bitU -> integer -> list bitU
+val smult_vec_int : list bitU -> integer -> list bitU
+let add_vec_int = add_bv_int
+let sadd_vec_int = sadd_bv_int
+let sub_vec_int = sub_bv_int
+let mult_vec_int = mult_bv_int
+let smult_vec_int = smult_bv_int
+
+val add_int_vec : integer -> list bitU -> list bitU
+val sadd_int_vec : integer -> list bitU -> list bitU
+val sub_int_vec : integer -> list bitU -> list bitU
+val mult_int_vec : integer -> list bitU -> list bitU
+val smult_int_vec : integer -> list bitU -> list bitU
+let add_int_vec = add_int_bv
+let sadd_int_vec = sadd_int_bv
+let sub_int_vec = sub_int_bv
+let mult_int_vec = mult_int_bv
+let smult_int_vec = smult_int_bv
+
+val add_vec_bit : list bitU -> bitU -> list bitU
+val sadd_vec_bit : list bitU -> bitU -> list bitU
+val sub_vec_bit : list bitU -> bitU -> list bitU
+let add_vec_bit = add_bv_bit
+let sadd_vec_bit = sadd_bv_bit
+let sub_vec_bit = sub_bv_bit
+
+val add_overflow_vec : list bitU -> list bitU -> (list bitU * bitU * bitU)
+val add_overflow_vec_signed : list bitU -> list bitU -> (list bitU * bitU * bitU)
+val sub_overflow_vec : list bitU -> list bitU -> (list bitU * bitU * bitU)
+val sub_overflow_vec_signed : list bitU -> list bitU -> (list bitU * bitU * bitU)
+val mult_overflow_vec : list bitU -> list bitU -> (list bitU * bitU * bitU)
+val mult_overflow_vec_signed : list bitU -> list bitU -> (list bitU * bitU * bitU)
+let add_overflow_vec = add_overflow_bv
+let add_overflow_vec_signed = add_overflow_bv_signed
+let sub_overflow_vec = sub_overflow_bv
+let sub_overflow_vec_signed = sub_overflow_bv_signed
+let mult_overflow_vec = mult_overflow_bv
+let mult_overflow_vec_signed = mult_overflow_bv_signed
+
+val add_overflow_vec_bit : list bitU -> bitU -> (list bitU * bitU * bitU)
+val add_overflow_vec_bit_signed : list bitU -> bitU -> (list bitU * bitU * bitU)
+val sub_overflow_vec_bit : list bitU -> bitU -> (list bitU * bitU * bitU)
+val sub_overflow_vec_bit_signed : list bitU -> bitU -> (list bitU * bitU * bitU)
+let add_overflow_vec_bit = add_overflow_bv_bit
+let add_overflow_vec_bit_signed = add_overflow_bv_bit_signed
+let sub_overflow_vec_bit = sub_overflow_bv_bit
+let sub_overflow_vec_bit_signed = sub_overflow_bv_bit_signed
+
+val shiftl : list bitU -> integer -> list bitU
+val shiftr : list bitU -> integer -> list bitU
+val arith_shiftr : list bitU -> integer -> list bitU
+val rotl : list bitU -> integer -> list bitU
+val rotr : list bitU -> integer -> list bitU
+let shiftl = shiftl_bv
+let shiftr = shiftr_bv
+let arith_shiftr = arith_shiftr_bv
+let rotl = rotl_bv
+let rotr = rotr_bv
+
+val mod_vec : list bitU -> list bitU -> list bitU
+val quot_vec : list bitU -> list bitU -> list bitU
+val quot_vec_signed : list bitU -> list bitU -> list bitU
+let mod_vec = mod_bv
+let quot_vec = quot_bv
+let quot_vec_signed = quot_bv_signed
+
+val mod_vec_int : list bitU -> integer -> list bitU
+val quot_vec_int : list bitU -> integer -> list bitU
+let mod_vec_int = mod_bv_int
+let quot_vec_int = quot_bv_int
+
+val replicate_bits : list bitU -> integer -> list bitU
+let replicate_bits = replicate_bits_bv
+
+val duplicate : bitU -> integer -> list bitU
+let duplicate = duplicate_bit_bv
+
+val eq_vec : list bitU -> list bitU -> bool
+val neq_vec : list bitU -> list bitU -> bool
+val ult_vec : list bitU -> list bitU -> bool
+val slt_vec : list bitU -> list bitU -> bool
+val ugt_vec : list bitU -> list bitU -> bool
+val sgt_vec : list bitU -> list bitU -> bool
+val ulteq_vec : list bitU -> list bitU -> bool
+val slteq_vec : list bitU -> list bitU -> bool
+val ugteq_vec : list bitU -> list bitU -> bool
+val sgteq_vec : list bitU -> list bitU -> bool
+let eq_vec = eq_bv
+let neq_vec = neq_bv
+let ult_vec = ult_bv
+let slt_vec = slt_bv
+let ugt_vec = ugt_bv
+let sgt_vec = sgt_bv
+let ulteq_vec = ulteq_bv
+let slteq_vec = slteq_bv
+let ugteq_vec = ugteq_bv
+let sgteq_vec = sgteq_bv
+*)
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_operators_mwords.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_operators_mwords.v
new file mode 100644
index 00000000..1d4eb906
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_operators_mwords.v
@@ -0,0 +1,433 @@
+Require Import Sail2_values.
+Require Import Sail2_operators.
+Require Import Sail2_prompt_monad.
+Require Import Sail2_prompt.
+Require Import bbv.Word.
+Require bbv.BinNotation.
+Require Import Arith.
+Require Import ZArith.
+Require Import Omega.
+Require Import Eqdep_dec.
+
+Module Z_eq_dec.
+Definition U := Z.
+Definition eq_dec := Z.eq_dec.
+End Z_eq_dec.
+Module ZEqdep := DecidableEqDep (Z_eq_dec).
+
+Definition cast_T {T : Z -> Type} {m n} (x : T m) (eq : m = n) : T n.
+rewrite <- eq.
+exact x.
+Defined.
+
+Lemma cast_T_refl {T : Z -> Type} {m} {H:m = m} (x : T m) : cast_T x H = x.
+rewrite (ZEqdep.UIP _ _ H eq_refl).
+reflexivity.
+Qed.
+
+Definition autocast {T : Z -> Type} {m n} (x : T m) `{H:ArithFact (m = n)} : T n :=
+ cast_T x (use_ArithFact H).
+
+Definition autocast_m {rv e m n} (x : monad rv (mword m) e) `{H:ArithFact (m = n)} : monad rv (mword n) e :=
+ x >>= fun x => returnm (cast_T x (use_ArithFact H)).
+
+Definition cast_word {m n} (x : Word.word m) (eq : m = n) : Word.word n.
+rewrite <- eq.
+exact x.
+Defined.
+
+Lemma cast_word_refl {m} {H:m = m} (x : word m) : cast_word x H = x.
+rewrite (UIP_refl_nat _ H).
+reflexivity.
+Qed.
+
+Definition mword_of_nat {m} (x : Word.word m) : mword (Z.of_nat m).
+destruct m.
+- exact x.
+- simpl. rewrite SuccNat2Pos.id_succ. exact x.
+Defined.
+
+Definition cast_to_mword {m n} (x : Word.word m) (eq : Z.of_nat m = n) : mword n.
+destruct n.
+- constructor.
+- rewrite <- eq. exact (mword_of_nat x).
+- exfalso. destruct m; simpl in *; congruence.
+Defined.
+
+(*
+(* Specialisation of operators to machine words *)
+
+val access_vec_inc : forall 'a. Size 'a => mword 'a -> integer -> bitU*)
+Definition access_vec_inc {a} : mword a -> Z -> bitU := access_mword_inc.
+
+(*val access_vec_dec : forall 'a. Size 'a => mword 'a -> integer -> bitU*)
+Definition access_vec_dec {a} : mword a -> Z -> bitU := access_mword_dec.
+
+(*val update_vec_inc : forall 'a. Size 'a => mword 'a -> integer -> bitU -> mword 'a*)
+(* TODO: probably ought to use a monadic version instead, but using bad default for
+ type compatibility just now *)
+Definition update_vec_inc {a} (w : mword a) i b : mword a :=
+ opt_def w (update_mword_inc w i b).
+
+(*val update_vec_dec : forall 'a. Size 'a => mword 'a -> integer -> bitU -> mword 'a*)
+Definition update_vec_dec {a} (w : mword a) i b : mword a := opt_def w (update_mword_dec w i b).
+
+Lemma subrange_lemma0 {n m o} `{ArithFact (0 <= o)} `{ArithFact (o <= m < n)} : (Z.to_nat o <= Z.to_nat m < Z.to_nat n)%nat.
+intros.
+unwrap_ArithFacts.
+split.
++ apply Z2Nat.inj_le; omega.
++ apply Z2Nat.inj_lt; omega.
+Qed.
+Lemma subrange_lemma1 {n m o} : (o <= m < n -> n = m + 1 + (n - (m + 1)))%nat.
+intros. omega.
+Qed.
+Lemma subrange_lemma2 {n m o} : (o <= m < n -> m+1 = o+(m-o+1))%nat.
+omega.
+Qed.
+Lemma subrange_lemma3 {n m o} `{ArithFact (0 <= o)} `{ArithFact (o <= m < n)} :
+ Z.of_nat (Z.to_nat m - Z.to_nat o + 1)%nat = m - o + 1.
+unwrap_ArithFacts.
+rewrite Nat2Z.inj_add.
+rewrite Nat2Z.inj_sub.
+repeat rewrite Z2Nat.id; try omega.
+reflexivity.
+apply Z2Nat.inj_le; omega.
+Qed.
+
+Definition subrange_vec_dec {n} (v : mword n) m o `{ArithFact (0 <= o)} `{ArithFact (o <= m < n)} : mword (m - o + 1) :=
+ let n := Z.to_nat n in
+ let m := Z.to_nat m in
+ let o := Z.to_nat o in
+ let prf : (o <= m < n)%nat := subrange_lemma0 in
+ let w := get_word v in
+ cast_to_mword (split2 o (m-o+1)
+ (cast_word (split1 (m+1) (n-(m+1)) (cast_word w (subrange_lemma1 prf)))
+ (subrange_lemma2 prf))) subrange_lemma3.
+
+Definition subrange_vec_inc {n} (v : mword n) m o `{ArithFact (0 <= m)} `{ArithFact (m <= o < n)} : mword (o - m + 1) := autocast (subrange_vec_dec v (n-1-m) (n-1-o)).
+
+(* TODO: get rid of bogus default *)
+Parameter dummy_vector : forall {n} `{ArithFact (n >= 0)}, mword n.
+
+(*val update_subrange_vec_inc : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> integer -> mword 'b -> mword 'a*)
+Definition update_subrange_vec_inc {a b} (v : mword a) i j (w : mword b) : mword a :=
+ opt_def dummy_vector (of_bits (update_subrange_bv_inc v i j w)).
+
+(*val update_subrange_vec_dec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> integer -> mword 'b -> mword 'a*)
+Definition update_subrange_vec_dec {a b} (v : mword a) i j (w : mword b) : mword a :=
+ opt_def dummy_vector (of_bits (update_subrange_bv_dec v i j w)).
+
+Lemma mword_nonneg {a} : mword a -> a >= 0.
+destruct a;
+auto using Z.le_ge, Zle_0_pos with zarith.
+destruct 1.
+Qed.
+
+(*val extz_vec : forall 'a 'b. Size 'a, Size 'b => integer -> mword 'a -> mword 'b*)
+Definition extz_vec {a b} `{ArithFact (b >= a)} (n : Z) (v : mword a) : mword b.
+refine (cast_to_mword (Word.zext (get_word v) (Z.to_nat (b - a))) _).
+unwrap_ArithFacts.
+assert (a >= 0). { apply mword_nonneg. assumption. }
+rewrite <- Z2Nat.inj_add; try omega.
+rewrite Zplus_minus.
+apply Z2Nat.id.
+auto with zarith.
+Defined.
+
+(*val exts_vec : forall 'a 'b. Size 'a, Size 'b => integer -> mword 'a -> mword 'b*)
+Definition exts_vec {a b} `{ArithFact (b >= a)} (n : Z) (v : mword a) : mword b.
+refine (cast_to_mword (Word.sext (get_word v) (Z.to_nat (b - a))) _).
+unwrap_ArithFacts.
+assert (a >= 0). { apply mword_nonneg. assumption. }
+rewrite <- Z2Nat.inj_add; try omega.
+rewrite Zplus_minus.
+apply Z2Nat.id.
+auto with zarith.
+Defined.
+
+Definition zero_extend {a} (v : mword a) (n : Z) `{ArithFact (n >= a)} : mword n := extz_vec n v.
+
+Definition sign_extend {a} (v : mword a) (n : Z) `{ArithFact (n >= a)} : mword n := exts_vec n v.
+
+Lemma truncate_eq {m n} : m >= 0 -> m <= n -> (Z.to_nat n = Z.to_nat m + (Z.to_nat n - Z.to_nat m))%nat.
+intros.
+assert ((Z.to_nat m <= Z.to_nat n)%nat).
+{ apply Z2Nat.inj_le; omega. }
+omega.
+Qed.
+
+Definition vector_truncate {n} (v : mword n) (m : Z) `{ArithFact (m >= 0)} `{ArithFact (m <= n)} : mword m :=
+ cast_to_mword (Word.split1 _ _ (cast_word (get_word v) (ltac:(unwrap_ArithFacts; apply truncate_eq; auto) : Z.to_nat n = Z.to_nat m + (Z.to_nat n - Z.to_nat m))%nat)) (ltac:(unwrap_ArithFacts; apply Z2Nat.id; omega) : Z.of_nat (Z.to_nat m) = m).
+
+Lemma concat_eq {a b} : a >= 0 -> b >= 0 -> Z.of_nat (Z.to_nat b + Z.to_nat a)%nat = a + b.
+intros.
+rewrite Nat2Z.inj_add.
+rewrite Z2Nat.id; auto with zarith.
+rewrite Z2Nat.id; auto with zarith.
+Qed.
+
+
+(*val concat_vec : forall 'a 'b 'c. Size 'a, Size 'b, Size 'c => mword 'a -> mword 'b -> mword 'c*)
+Definition concat_vec {a b} (v : mword a) (w : mword b) : mword (a + b) :=
+ cast_to_mword (Word.combine (get_word w) (get_word v)) (ltac:(solve [auto using concat_eq, mword_nonneg with zarith]) : Z.of_nat (Z.to_nat b + Z.to_nat a)%nat = a + b).
+
+(*val cons_vec : forall 'a 'b 'c. Size 'a, Size 'b => bitU -> mword 'a -> mword 'b*)
+(*Definition cons_vec {a b} : bitU -> mword a -> mword b := cons_bv.*)
+
+(*val bool_of_vec : mword ty1 -> bitU
+Definition bool_of_vec := bool_of_bv
+
+val cast_unit_vec : bitU -> mword ty1
+Definition cast_unit_vec := cast_unit_bv
+
+val vec_of_bit : forall 'a. Size 'a => integer -> bitU -> mword 'a
+Definition vec_of_bit := bv_of_bit*)
+
+Require Import bbv.NatLib.
+
+Lemma Npow2_pow {n} : (2 ^ (N.of_nat n) = Npow2 n)%N.
+induction n.
+* reflexivity.
+* rewrite Nnat.Nat2N.inj_succ.
+ rewrite N.pow_succ_r'.
+ rewrite IHn.
+ rewrite Npow2_S.
+ rewrite Word.Nmul_two.
+ reflexivity.
+Qed.
+
+Program Definition uint {a} (x : mword a) : {z : Z & ArithFact (0 <= z /\ z <= 2 ^ a - 1)} :=
+ existT _ (Z.of_N (Word.wordToN (get_word x))) _.
+Next Obligation.
+constructor.
+constructor.
+* apply N2Z.is_nonneg.
+* assert (2 ^ a - 1 = Z.of_N (2 ^ (Z.to_N a) - 1)). {
+ rewrite N2Z.inj_sub.
+ * rewrite N2Z.inj_pow.
+ rewrite Z2N.id; auto.
+ destruct a; auto with zarith. destruct x.
+ * apply N.le_trans with (m := (2^0)%N); auto using N.le_refl.
+ apply N.pow_le_mono_r.
+ inversion 1.
+ apply N.le_0_l.
+ }
+ rewrite H.
+ apply N2Z.inj_le.
+ rewrite N.sub_1_r.
+ apply N.lt_le_pred.
+ rewrite <- Z_nat_N.
+ rewrite Npow2_pow.
+ apply Word.wordToN_bound.
+Defined.
+
+Lemma Zpow_pow2 {n} : 2 ^ Z.of_nat n = Z.of_nat (pow2 n).
+induction n.
+* reflexivity.
+* rewrite pow2_S_z.
+ rewrite Nat2Z.inj_succ.
+ rewrite Z.pow_succ_r; auto with zarith.
+Qed.
+
+Program Definition sint {a} `{ArithFact (a > 0)} (x : mword a) : {z : Z & ArithFact (-(2^(a-1)) <= z /\ z <= 2 ^ (a-1) - 1)} :=
+ existT _ (Word.wordToZ (get_word x)) _.
+Next Obligation.
+destruct H.
+destruct a; try inversion fact.
+constructor.
+generalize (get_word x).
+rewrite <- positive_nat_Z.
+destruct (Pos2Nat.is_succ p) as [n eq].
+rewrite eq.
+rewrite Nat2Z.id.
+intro w.
+destruct (Word.wordToZ_size' w) as [LO HI].
+replace 1 with (Z.of_nat 1); auto.
+rewrite <- Nat2Z.inj_sub; auto with arith.
+simpl.
+rewrite <- minus_n_O.
+rewrite Zpow_pow2.
+rewrite Z.sub_1_r.
+rewrite <- Z.lt_le_pred.
+auto.
+Defined.
+
+Lemma length_list_pos : forall {A} {l:list A}, length_list l >= 0.
+unfold length_list.
+auto with zarith.
+Qed.
+Hint Resolve length_list_pos : sail.
+
+Definition vec_of_bits (l:list bitU) : mword (length_list l) := opt_def dummy_vector (of_bits l).
+(*
+
+val msb : forall 'a. Size 'a => mword 'a -> bitU
+Definition msb := most_significant
+
+val int_of_vec : forall 'a. Size 'a => bool -> mword 'a -> integer
+Definition int_of_vec := int_of_bv
+
+val string_of_vec : forall 'a. Size 'a => mword 'a -> string*)
+Definition string_of_bits {n} (w : mword n) : string := string_of_bv w.
+Definition with_word' {n} (P : Type -> Type) : (forall n, Word.word n -> P (Word.word n)) -> mword n -> P (mword n) := fun f w => @with_word n _ (f (Z.to_nat n)) w.
+Definition word_binop {n} (f : forall n, Word.word n -> Word.word n -> Word.word n) : mword n -> mword n -> mword n := with_word' (fun x => x -> x) f.
+Definition word_unop {n} (f : forall n, Word.word n -> Word.word n) : mword n -> mword n := with_word' (fun x => x) f.
+
+
+(*
+val and_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val or_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val xor_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val not_vec : forall 'a. Size 'a => mword 'a -> mword 'a*)
+Definition and_vec {n} : mword n -> mword n -> mword n := word_binop Word.wand.
+Definition or_vec {n} : mword n -> mword n -> mword n := word_binop Word.wor.
+Definition xor_vec {n} : mword n -> mword n -> mword n := word_binop Word.wxor.
+Definition not_vec {n} : mword n -> mword n := word_unop Word.wnot.
+
+(*val add_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val sadd_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val sub_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val mult_vec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> mword 'a -> mword 'b
+val smult_vec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> mword 'a -> mword 'b*)
+Definition add_vec {n} : mword n -> mword n -> mword n := word_binop Word.wplus.
+(*Definition sadd_vec {n} : mword n -> mword n -> mword n := sadd_bv w.*)
+Definition sub_vec {n} : mword n -> mword n -> mword n := word_binop Word.wminus.
+Definition mult_vec {n m} `{ArithFact (m >= n)} (l : mword n) (r : mword n) : mword m :=
+ word_binop Word.wmult (zero_extend l _) (zero_extend r _).
+Definition mults_vec {n m} `{ArithFact (m >= n)} (l : mword n) (r : mword n) : mword m :=
+ word_binop Word.wmult (sign_extend l _) (sign_extend r _).
+
+(*val add_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+val sadd_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+val sub_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+val mult_vec_int : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> mword 'b
+val smult_vec_int : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> mword 'b*)
+Definition add_vec_int {a} (l : mword a) (r : Z) : mword a := arith_op_bv_int Z.add false l r.
+Definition sadd_vec_int {a} (l : mword a) (r : Z) : mword a := arith_op_bv_int Z.add true l r.
+Definition sub_vec_int {a} (l : mword a) (r : Z) : mword a := arith_op_bv_int Z.sub false l r.
+(*Definition mult_vec_int {a b} : mword a -> Z -> mword b := mult_bv_int.
+Definition smult_vec_int {a b} : mword a -> Z -> mword b := smult_bv_int.*)
+
+(*val add_int_vec : forall 'a. Size 'a => integer -> mword 'a -> mword 'a
+val sadd_int_vec : forall 'a. Size 'a => integer -> mword 'a -> mword 'a
+val sub_int_vec : forall 'a. Size 'a => integer -> mword 'a -> mword 'a
+val mult_int_vec : forall 'a 'b. Size 'a, Size 'b => integer -> mword 'a -> mword 'b
+val smult_int_vec : forall 'a 'b. Size 'a, Size 'b => integer -> mword 'a -> mword 'b
+Definition add_int_vec := add_int_bv
+Definition sadd_int_vec := sadd_int_bv
+Definition sub_int_vec := sub_int_bv
+Definition mult_int_vec := mult_int_bv
+Definition smult_int_vec := smult_int_bv
+
+val add_vec_bit : forall 'a. Size 'a => mword 'a -> bitU -> mword 'a
+val sadd_vec_bit : forall 'a. Size 'a => mword 'a -> bitU -> mword 'a
+val sub_vec_bit : forall 'a. Size 'a => mword 'a -> bitU -> mword 'a
+Definition add_vec_bit := add_bv_bit
+Definition sadd_vec_bit := sadd_bv_bit
+Definition sub_vec_bit := sub_bv_bit
+
+val add_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
+val add_overflow_vec_signed : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
+val sub_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
+val sub_overflow_vec_signed : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
+val mult_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
+val mult_overflow_vec_signed : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
+Definition add_overflow_vec := add_overflow_bv
+Definition add_overflow_vec_signed := add_overflow_bv_signed
+Definition sub_overflow_vec := sub_overflow_bv
+Definition sub_overflow_vec_signed := sub_overflow_bv_signed
+Definition mult_overflow_vec := mult_overflow_bv
+Definition mult_overflow_vec_signed := mult_overflow_bv_signed
+
+val add_overflow_vec_bit : forall 'a. Size 'a => mword 'a -> bitU -> (mword 'a * bitU * bitU)
+val add_overflow_vec_bit_signed : forall 'a. Size 'a => mword 'a -> bitU -> (mword 'a * bitU * bitU)
+val sub_overflow_vec_bit : forall 'a. Size 'a => mword 'a -> bitU -> (mword 'a * bitU * bitU)
+val sub_overflow_vec_bit_signed : forall 'a. Size 'a => mword 'a -> bitU -> (mword 'a * bitU * bitU)
+Definition add_overflow_vec_bit := add_overflow_bv_bit
+Definition add_overflow_vec_bit_signed := add_overflow_bv_bit_signed
+Definition sub_overflow_vec_bit := sub_overflow_bv_bit
+Definition sub_overflow_vec_bit_signed := sub_overflow_bv_bit_signed
+
+val shiftl : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+val shiftr : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+val arith_shiftr : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+val rotl : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+val rotr : forall 'a. Size 'a => mword 'a -> integer -> mword 'a*)
+(* TODO: check/redefine behaviour on out-of-range n *)
+Definition shiftl {a} (v : mword a) n : mword a := with_word (P := id) (fun w => Word.wlshift w (Z.to_nat n)) v.
+Definition shiftr {a} (v : mword a) n : mword a := with_word (P := id) (fun w => Word.wrshift w (Z.to_nat n)) v.
+Definition arith_shiftr {a} (v : mword a) n : mword a := with_word (P := id) (fun w => Word.wrshifta w (Z.to_nat n)) v.
+(*
+Definition rotl := rotl_bv
+Definition rotr := rotr_bv
+
+val mod_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val quot_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val quot_vec_signed : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+Definition mod_vec := mod_bv
+Definition quot_vec := quot_bv
+Definition quot_vec_signed := quot_bv_signed
+
+val mod_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+val quot_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+Definition mod_vec_int := mod_bv_int
+Definition quot_vec_int := quot_bv_int
+
+val replicate_bits : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> mword 'b*)
+Fixpoint replicate_bits_aux {a} (w : Word.word a) (n : nat) : Word.word (n * a) :=
+match n with
+| O => Word.WO
+| S m => Word.combine w (replicate_bits_aux w m)
+end.
+Lemma replicate_ok {n a} `{ArithFact (n >= 0)} `{ArithFact (a >= 0)} :
+ Z.of_nat (Z.to_nat n * Z.to_nat a) = a * n.
+destruct H. destruct H0.
+rewrite <- Z2Nat.id; auto with zarith.
+rewrite Z2Nat.inj_mul; auto with zarith.
+rewrite Nat.mul_comm. reflexivity.
+Qed.
+Definition replicate_bits {a} (w : mword a) (n : Z) `{ArithFact (n >= 0)} : mword (a * n) :=
+ cast_to_mword (replicate_bits_aux (get_word w) (Z.to_nat n)) replicate_ok.
+
+(*val duplicate : forall 'a. Size 'a => bitU -> integer -> mword 'a
+Definition duplicate := duplicate_bit_bv
+
+val eq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
+val neq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
+val ult_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
+val slt_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
+val ugt_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
+val sgt_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
+val ulteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
+val slteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
+val ugteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
+val sgteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool*)
+Definition eq_vec {n} (x : mword n) (y : mword n) : bool := Word.weqb (get_word x) (get_word y).
+Definition neq_vec {n} (x : mword n) (y : mword n) : bool := negb (eq_vec x y).
+(*Definition ult_vec := ult_bv.
+Definition slt_vec := slt_bv.
+Definition ugt_vec := ugt_bv.
+Definition sgt_vec := sgt_bv.
+Definition ulteq_vec := ulteq_bv.
+Definition slteq_vec := slteq_bv.
+Definition ugteq_vec := ugteq_bv.
+Definition sgteq_vec := sgteq_bv.
+
+*)
+
+Program Fixpoint reverse_endianness_word {n} (bits : word n) : word n :=
+ match n with
+ | S (S (S (S (S (S (S (S m))))))) =>
+ combine
+ (reverse_endianness_word (split2 8 m bits))
+ (split1 8 m bits)
+ | _ => bits
+ end.
+Next Obligation.
+omega.
+Qed.
+
+Definition reverse_endianness {n} (bits : mword n) := with_word (P := id) reverse_endianness_word bits.
+
+Definition get_slice_int {a} `{ArithFact (a >= 0)} : Z -> Z -> Z -> mword a := get_slice_int_bv.
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_prompt.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_prompt.v
new file mode 100644
index 00000000..0b3a2cd8
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_prompt.v
@@ -0,0 +1,127 @@
+(*Require Import Sail_impl_base*)
+Require Import Sail2_values.
+Require Import Sail2_prompt_monad.
+
+Require Import List.
+Import ListNotations.
+(*
+
+val iter_aux : forall 'rv 'a 'e. integer -> (integer -> 'a -> monad 'rv unit 'e) -> list 'a -> monad 'rv unit 'e
+let rec iter_aux i f xs = match xs with
+ | x :: xs -> f i x >> iter_aux (i + 1) f xs
+ | [] -> return ()
+ end
+
+declare {isabelle} termination_argument iter_aux = automatic
+
+val iteri : forall 'rv 'a 'e. (integer -> 'a -> monad 'rv unit 'e) -> list 'a -> monad 'rv unit 'e
+let iteri f xs = iter_aux 0 f xs
+
+val iter : forall 'rv 'a 'e. ('a -> monad 'rv unit 'e) -> list 'a -> monad 'rv unit 'e
+let iter f xs = iteri (fun _ x -> f x) xs
+
+val foreachM : forall 'a 'rv 'vars 'e.
+ list 'a -> 'vars -> ('a -> 'vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e*)
+Fixpoint foreachM {a rv Vars e} (l : list a) (vars : Vars) (body : a -> Vars -> monad rv Vars e) : monad rv Vars e :=
+match l with
+| [] => returnm vars
+| (x :: xs) =>
+ body x vars >>= fun vars =>
+ foreachM xs vars body
+end.
+
+Fixpoint foreach_ZM_up' {rv e Vars} from to step off n `{ArithFact (0 < step)} `{ArithFact (0 <= off)} (vars : Vars) (body : forall (z : Z) `(ArithFact (from <= z <= to)), Vars -> monad rv Vars e) {struct n} : monad rv Vars e :=
+ if sumbool_of_bool (from + off <=? to) then
+ match n with
+ | O => returnm vars
+ | S n => body (from + off) _ vars >>= fun vars => foreach_ZM_up' from to step (off + step) n vars body
+ end
+ else returnm vars.
+
+Fixpoint foreach_ZM_down' {rv e Vars} from to step off n `{ArithFact (0 < step)} `{ArithFact (off <= 0)} (vars : Vars) (body : forall (z : Z) `(ArithFact (to <= z <= from)), Vars -> monad rv Vars e) {struct n} : monad rv Vars e :=
+ if sumbool_of_bool (to <=? from + off) then
+ match n with
+ | O => returnm vars
+ | S n => body (from + off) _ vars >>= fun vars => foreach_ZM_down' from to step (off - step) n vars body
+ end
+ else returnm vars.
+
+Definition foreach_ZM_up {rv e Vars} from to step vars body `{ArithFact (0 < step)} :=
+ foreach_ZM_up' (rv := rv) (e := e) (Vars := Vars) from to step 0 (S (Z.abs_nat (from - to))) vars body.
+Definition foreach_ZM_down {rv e Vars} from to step vars body `{ArithFact (0 < step)} :=
+ foreach_ZM_down' (rv := rv) (e := e) (Vars := Vars) from to step 0 (S (Z.abs_nat (from - to))) vars body.
+
+(*declare {isabelle} termination_argument foreachM = automatic*)
+
+(*val and_boolM : forall 'rv 'e. monad 'rv bool 'e -> monad 'rv bool 'e -> monad 'rv bool 'e*)
+Definition and_boolM {rv E} (l : monad rv bool E) (r : monad rv bool E) : monad rv bool E :=
+ l >>= (fun l => if l then r else returnm false).
+
+(*val or_boolM : forall 'rv 'e. monad 'rv bool 'e -> monad 'rv bool 'e -> monad 'rv bool 'e*)
+Definition or_boolM {rv E} (l : monad rv bool E) (r : monad rv bool E) : monad rv bool E :=
+ l >>= (fun l => if l then returnm true else r).
+
+(*val bool_of_bitU_fail : forall 'rv 'e. bitU -> monad 'rv bool 'e*)
+Definition bool_of_bitU_fail {rv E} (b : bitU) : monad rv bool E :=
+match b with
+ | B0 => returnm false
+ | B1 => returnm true
+ | BU => Fail "bool_of_bitU"
+end.
+
+(*val bool_of_bitU_oracle : forall 'rv 'e. bitU -> monad 'rv bool 'e*)
+Definition bool_of_bitU_oracle {rv E} (b : bitU) : monad rv bool E :=
+match b with
+ | B0 => returnm false
+ | B1 => returnm true
+ | BU => undefined_bool tt
+end.
+
+
+(*val whileM : forall 'rv 'vars 'e. 'vars -> ('vars -> monad 'rv bool 'e) ->
+ ('vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e
+let rec whileM vars cond body =
+ cond vars >>= fun cond_val ->
+ if cond_val then
+ body vars >>= fun vars -> whileM vars cond body
+ else return vars
+
+val untilM : forall 'rv 'vars 'e. 'vars -> ('vars -> monad 'rv bool 'e) ->
+ ('vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e
+let rec untilM vars cond body =
+ body vars >>= fun vars ->
+ cond vars >>= fun cond_val ->
+ if cond_val then return vars else untilM vars cond body
+
+(*let write_two_regs r1 r2 vec =
+ let is_inc =
+ let is_inc_r1 = is_inc_of_reg r1 in
+ let is_inc_r2 = is_inc_of_reg r2 in
+ let () = ensure (is_inc_r1 = is_inc_r2)
+ "write_two_regs called with vectors of different direction" in
+ is_inc_r1 in
+
+ let (size_r1 : integer) = size_of_reg r1 in
+ let (start_vec : integer) = get_start vec in
+ let size_vec = length vec in
+ let r1_v =
+ if is_inc
+ then slice vec start_vec (size_r1 - start_vec - 1)
+ else slice vec start_vec (start_vec - size_r1 - 1) in
+ let r2_v =
+ if is_inc
+ then slice vec (size_r1 - start_vec) (size_vec - start_vec)
+ else slice vec (start_vec - size_r1) (start_vec - size_vec) in
+ write_reg r1 r1_v >> write_reg r2 r2_v*)
+
+*)
+
+(* If we need to build an existential after a monadic operation, assume that
+ we can do it entirely from the type. *)
+
+Definition build_ex_m {rv e} {T:Type} (x:monad rv T e) {P:T -> Prop} `{H:forall x, ArithFact (P x)} : monad rv {x : T & ArithFact (P x)} e :=
+ x >>= fun y => returnm (existT _ y (H y)).
+
+Definition projT1_m {rv e} {P:Z -> Prop} (x: monad rv {x : Z & P x} e) : monad rv Z e :=
+ x >>= fun y => returnm (projT1 y).
+
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_prompt_monad.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_prompt_monad.v
new file mode 100644
index 00000000..2715b5e7
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_prompt_monad.v
@@ -0,0 +1,247 @@
+Require Import String.
+(*Require Import Sail_impl_base*)
+Require Import Sail2_instr_kinds.
+Require Import Sail2_values.
+
+
+
+Definition register_name := string.
+Definition address := list bitU.
+
+Inductive monad regval a e :=
+ | Done : a -> monad regval a e
+ (* Read a number : bytes from memory, returned in little endian order *)
+ | Read_mem : read_kind -> address -> nat -> (list memory_byte -> monad regval a e) -> monad regval a e
+ (* Read the tag : a memory address *)
+ | Read_tag : address -> (bitU -> monad regval a e) -> monad regval a e
+ (* Tell the system a write is imminent, at address lifted, : size nat *)
+ | Write_ea : write_kind -> address -> nat -> monad regval a e -> monad regval a e
+ (* Request the result : store-exclusive *)
+ | Excl_res : (bool -> monad regval a e) -> monad regval a e
+ (* Request to write memory at last signalled address. Memory value should be 8
+ times the size given in ea signal, given in little endian order *)
+ | Write_memv : list memory_byte -> (bool -> monad regval a e) -> monad regval a e
+ (* Request to write the tag at last signalled address. *)
+ | Write_tag : address -> bitU -> (bool -> monad regval a e) -> monad regval a e
+ (* Tell the system to dynamically recalculate dependency footprint *)
+ | Footprint : monad regval a e -> monad regval a e
+ (* Request a memory barrier *)
+ | Barrier : barrier_kind -> monad regval a e -> monad regval a e
+ (* Request to read register, will track dependency when mode.track_values *)
+ | Read_reg : register_name -> (regval -> monad regval a e) -> monad regval a e
+ (* Request to write register *)
+ | Write_reg : register_name -> regval -> monad regval a e -> monad regval a e
+ | Undefined : (bool -> monad regval a e) -> monad regval a e
+ (*Result : a failed assert with possible error message to report*)
+ | Fail : string -> monad regval a e
+ | Error : string -> monad regval a e
+ (* Exception : type e *)
+ | Exception : e -> monad regval a e.
+ (* TODO: Reading/writing tags *)
+
+Arguments Done [_ _ _].
+Arguments Read_mem [_ _ _].
+Arguments Read_tag [_ _ _].
+Arguments Write_ea [_ _ _].
+Arguments Excl_res [_ _ _].
+Arguments Write_memv [_ _ _].
+Arguments Write_tag [_ _ _].
+Arguments Footprint [_ _ _].
+Arguments Barrier [_ _ _].
+Arguments Read_reg [_ _ _].
+Arguments Write_reg [_ _ _].
+Arguments Undefined [_ _ _].
+Arguments Fail [_ _ _].
+Arguments Error [_ _ _].
+Arguments Exception [_ _ _].
+
+(*val return : forall rv a e. a -> monad rv a e*)
+Definition returnm {rv A E} (a : A) : monad rv A E := Done a.
+
+(*val bind : forall rv a b e. monad rv a e -> (a -> monad rv b e) -> monad rv b e*)
+Fixpoint bind {rv A B E} (m : monad rv A E) (f : A -> monad rv B E) := match m with
+ | Done a => f a
+ | Read_mem rk a sz k => Read_mem rk a sz (fun v => bind (k v) f)
+ | Read_tag a k => Read_tag a (fun v => bind (k v) f)
+ | Write_memv descr k => Write_memv descr (fun v => bind (k v) f)
+ | Write_tag a t k => Write_tag a t (fun v => bind (k v) f)
+ | Read_reg descr k => Read_reg descr (fun v => bind (k v) f)
+ | Excl_res k => Excl_res (fun v => bind (k v) f)
+ | Undefined k => Undefined (fun v => bind (k v) f)
+ | Write_ea wk a sz k => Write_ea wk a sz (bind k f)
+ | Footprint k => Footprint (bind k f)
+ | Barrier bk k => Barrier bk (bind k f)
+ | Write_reg r v k => Write_reg r v (bind k f)
+ | Fail descr => Fail descr
+ | Error descr => Error descr
+ | Exception e => Exception e
+end.
+
+Notation "m >>= f" := (bind m f) (at level 50, left associativity).
+(*val (>>) : forall rv b e. monad rv unit e -> monad rv b e -> monad rv b e*)
+Definition bind0 {rv A E} (m : monad rv unit E) (n : monad rv A E) :=
+ m >>= fun (_ : unit) => n.
+Notation "m >> n" := (bind0 m n) (at level 50, left associativity).
+
+(*val exit : forall rv a e. unit -> monad rv a e*)
+Definition exit {rv A E} (_ : unit) : monad rv A E := Fail "exit".
+
+(*val undefined_bool : forall 'rv 'e. unit -> monad 'rv bool 'e*)
+Definition undefined_bool {rv e} (_:unit) : monad rv bool e := Undefined returnm.
+
+(*val assert_exp : forall rv e. bool -> string -> monad rv unit e*)
+Definition assert_exp {rv E} (exp :bool) msg : monad rv unit E :=
+ if exp then Done tt else Fail msg.
+
+Definition assert_exp' {rv E} (exp :bool) msg : monad rv (exp = true) E :=
+ if exp return monad rv (exp = true) E then Done eq_refl else Fail msg.
+Definition bindH {rv A P E} (m : monad rv P E) (n : monad rv A E) :=
+ m >>= fun (H : P) => n.
+Notation "m >>> n" := (bindH m n) (at level 50, left associativity).
+
+(*val throw : forall rv a e. e -> monad rv a e*)
+Definition throw {rv A E} e : monad rv A E := Exception e.
+
+(*val try_catch : forall rv a e1 e2. monad rv a e1 -> (e1 -> monad rv a e2) -> monad rv a e2*)
+Fixpoint try_catch {rv A E1 E2} (m : monad rv A E1) (h : E1 -> monad rv A E2) := match m with
+ | Done a => Done a
+ | Read_mem rk a sz k => Read_mem rk a sz (fun v => try_catch (k v) h)
+ | Read_tag a k => Read_tag a (fun v => try_catch (k v) h)
+ | Write_memv descr k => Write_memv descr (fun v => try_catch (k v) h)
+ | Write_tag a t k => Write_tag a t (fun v => try_catch (k v) h)
+ | Read_reg descr k => Read_reg descr (fun v => try_catch (k v) h)
+ | Excl_res k => Excl_res (fun v => try_catch (k v) h)
+ | Undefined k => Undefined (fun v => try_catch (k v) h)
+ | Write_ea wk a sz k => Write_ea wk a sz (try_catch k h)
+ | Footprint k => Footprint (try_catch k h)
+ | Barrier bk k => Barrier bk (try_catch k h)
+ | Write_reg r v k => Write_reg r v (try_catch k h)
+ | Fail descr => Fail descr
+ | Error descr => Error descr
+ | Exception e => h e
+end.
+
+(* For early return, we abuse exceptions by throwing and catching
+ the return value. The exception type is "either r e", where "inr e"
+ represents a proper exception and "inl r" an early return : value "r". *)
+Definition monadR rv a r e := monad rv a (sum r e).
+
+(*val early_return : forall rv a r e. r -> monadR rv a r e*)
+Definition early_return {rv A R E} (r : R) : monadR rv A R E := throw (inl r).
+
+(*val catch_early_return : forall rv a e. monadR rv a a e -> monad rv a e*)
+Definition catch_early_return {rv A E} (m : monadR rv A A E) :=
+ try_catch m
+ (fun r => match r with
+ | inl a => returnm a
+ | inr e => throw e
+ end).
+
+(* Lift to monad with early return by wrapping exceptions *)
+(*val liftR : forall rv a r e. monad rv a e -> monadR rv a r e*)
+Definition liftR {rv A R E} (m : monad rv A E) : monadR rv A R E :=
+ try_catch m (fun e => throw (inr e)).
+
+(* Catch exceptions in the presence : early returns *)
+(*val try_catchR : forall rv a r e1 e2. monadR rv a r e1 -> (e1 -> monadR rv a r e2) -> monadR rv a r e2*)
+Definition try_catchR {rv A R E1 E2} (m : monadR rv A R E1) (h : E1 -> monadR rv A R E2) :=
+ try_catch m
+ (fun r => match r with
+ | inl r => throw (inl r)
+ | inr e => h e
+ end).
+
+(*val maybe_fail : forall 'rv 'a 'e. string -> maybe 'a -> monad 'rv 'a 'e*)
+Definition maybe_fail {rv A E} msg (x : option A) : monad rv A E :=
+match x with
+ | Some a => returnm a
+ | None => Fail msg
+end.
+
+(*val read_mem_bytes : forall 'rv 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monad 'rv (list memory_byte) 'e*)
+Definition read_mem_bytes {rv A E} rk (addr : mword A) sz : monad rv (list memory_byte) E :=
+ Read_mem rk (bits_of addr) (Z.to_nat sz) returnm.
+
+(*val read_mem : forall 'rv 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monad 'rv 'b 'e*)
+Definition read_mem {rv A B E} `{ArithFact (B >= 0)} rk (addr : mword A) sz : monad rv (mword B) E :=
+ bind
+ (read_mem_bytes rk addr sz)
+ (fun bytes =>
+ maybe_fail "bits_of_mem_bytes" (of_bits (bits_of_mem_bytes bytes))).
+
+(*val read_tag : forall rv a e. Bitvector a => a -> monad rv bitU e*)
+Definition read_tag {rv a e} `{Bitvector a} (addr : a) : monad rv bitU e :=
+ Read_tag (bits_of addr) returnm.
+
+(*val excl_result : forall rv e. unit -> monad rv bool e*)
+Definition excl_result {rv e} (_:unit) : monad rv bool e :=
+ let k successful := (returnm successful) in
+ Excl_res k.
+
+Definition write_mem_ea {rv a E} `{Bitvector a} wk (addr: a) sz : monad rv unit E :=
+ Write_ea wk (bits_of addr) (Z.to_nat sz) (Done tt).
+
+Definition write_mem_val {rv a e} `{Bitvector a} (v : a) : monad rv bool e := match mem_bytes_of_bits v with
+ | Some v => Write_memv v returnm
+ | None => Fail "write_mem_val"
+end.
+
+(*val write_tag : forall rv a e. Bitvector 'a => 'a -> bitU -> monad rv bool e*)
+Definition write_tag {rv a e} (addr : mword a) (b : bitU) : monad rv bool e := Write_tag (bits_of addr) b returnm.
+
+Definition read_reg {s rv a e} (reg : register_ref s rv a) : monad rv a e :=
+ let k v :=
+ match reg.(of_regval) v with
+ | Some v => Done v
+ | None => Error "read_reg: unrecognised value"
+ end
+ in
+ Read_reg reg.(name) k.
+
+(* TODO
+val read_reg_range : forall s r rv a e. Bitvector a => register_ref s rv r -> integer -> integer -> monad rv a e
+Definition read_reg_range reg i j :=
+ read_reg_aux of_bits (external_reg_slice reg (natFromInteger i,natFromInteger j))
+
+Definition read_reg_bit reg i :=
+ read_reg_aux (fun v -> v) (external_reg_slice reg (natFromInteger i,natFromInteger i)) >>= fun v ->
+ returnm (extract_only_element v)
+
+Definition read_reg_field reg regfield :=
+ read_reg_aux (external_reg_field_whole reg regfield)
+
+Definition read_reg_bitfield reg regfield :=
+ read_reg_aux (external_reg_field_whole reg regfield) >>= fun v ->
+ returnm (extract_only_element v)*)
+
+Definition reg_deref {s rv a e} := @read_reg s rv a e.
+
+(*Parameter write_reg : forall {s rv a e}, register_ref s rv a -> a -> monad rv unit e.*)
+Definition write_reg {s rv a e} (reg : register_ref s rv a) (v : a) : monad rv unit e :=
+ Write_reg reg.(name) (reg.(regval_of) v) (Done tt).
+
+(* TODO
+Definition write_reg reg v :=
+ write_reg_aux (external_reg_whole reg) v
+Definition write_reg_range reg i j v :=
+ write_reg_aux (external_reg_slice reg (natFromInteger i,natFromInteger j)) v
+Definition write_reg_pos reg i v :=
+ let iN := natFromInteger i in
+ write_reg_aux (external_reg_slice reg (iN,iN)) [v]
+Definition write_reg_bit := write_reg_pos
+Definition write_reg_field reg regfield v :=
+ write_reg_aux (external_reg_field_whole reg regfield.field_name) v
+Definition write_reg_field_bit reg regfield bit :=
+ write_reg_aux (external_reg_field_whole reg regfield.field_name)
+ (Vector [bit] 0 (is_inc_of_reg reg))
+Definition write_reg_field_range reg regfield i j v :=
+ write_reg_aux (external_reg_field_slice reg regfield.field_name (natFromInteger i,natFromInteger j)) v
+Definition write_reg_field_pos reg regfield i v :=
+ write_reg_field_range reg regfield i i [v]
+Definition write_reg_field_bit := write_reg_field_pos*)
+
+(*val barrier : forall rv e. barrier_kind -> monad rv unit e*)
+Definition barrier {rv e} bk : monad rv unit e := Barrier bk (Done tt).
+
+(*val footprint : forall rv e. unit -> monad rv unit e*)
+Definition footprint {rv e} (_ : unit) : monad rv unit e := Footprint (Done tt).
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_state.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_state.v
new file mode 100644
index 00000000..1d5cb342
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_state.v
@@ -0,0 +1,69 @@
+(*Require Import Sail_impl_base*)
+Require Import Sail2_values.
+Require Import Sail2_prompt_monad.
+Require Import Sail2_prompt.
+Require Import Sail2_state_monad.
+(*
+(* State monad wrapper around prompt monad *)
+
+val liftState : forall 'regval 'regs 'a 'e. register_accessors 'regs 'regval -> monad 'regval 'a 'e -> monadS 'regs 'a 'e
+let rec liftState ra s = match s with
+ | (Done a) -> returnS a
+ | (Read_mem rk a sz k) -> bindS (read_mem_bytesS rk a sz) (fun v -> liftState ra (k v))
+ | (Read_tag t k) -> bindS (read_tagS t) (fun v -> liftState ra (k v))
+ | (Write_memv a k) -> bindS (write_mem_bytesS a) (fun v -> liftState ra (k v))
+ | (Write_tagv t k) -> bindS (write_tagS t) (fun v -> liftState ra (k v))
+ | (Read_reg r k) -> bindS (read_regvalS ra r) (fun v -> liftState ra (k v))
+ | (Excl_res k) -> bindS (excl_resultS ()) (fun v -> liftState ra (k v))
+ | (Undefined k) -> bindS (undefined_boolS ()) (fun v -> liftState ra (k v))
+ | (Write_ea wk a sz k) -> seqS (write_mem_eaS wk a sz) (liftState ra k)
+ | (Write_reg r v k) -> seqS (write_regvalS ra r v) (liftState ra k)
+ | (Footprint k) -> liftState ra k
+ | (Barrier _ k) -> liftState ra k
+ | (Fail descr) -> failS descr
+ | (Error descr) -> failS descr
+ | (Exception e) -> throwS e
+end
+
+
+val iterS_aux : forall 'rv 'a 'e. integer -> (integer -> 'a -> monadS 'rv unit 'e) -> list 'a -> monadS 'rv unit 'e
+let rec iterS_aux i f xs = match xs with
+ | x :: xs -> f i x >>$ iterS_aux (i + 1) f xs
+ | [] -> returnS ()
+ end
+
+declare {isabelle} termination_argument iterS_aux = automatic
+
+val iteriS : forall 'rv 'a 'e. (integer -> 'a -> monadS 'rv unit 'e) -> list 'a -> monadS 'rv unit 'e
+let iteriS f xs = iterS_aux 0 f xs
+
+val iterS : forall 'rv 'a 'e. ('a -> monadS 'rv unit 'e) -> list 'a -> monadS 'rv unit 'e
+let iterS f xs = iteriS (fun _ x -> f x) xs
+
+val foreachS : forall 'a 'rv 'vars 'e.
+ list 'a -> 'vars -> ('a -> 'vars -> monadS 'rv 'vars 'e) -> monadS 'rv 'vars 'e
+let rec foreachS xs vars body = match xs with
+ | [] -> returnS vars
+ | x :: xs ->
+ body x vars >>$= fun vars ->
+ foreachS xs vars body
+end
+
+declare {isabelle} termination_argument foreachS = automatic
+
+
+val whileS : forall 'rv 'vars 'e. 'vars -> ('vars -> monadS 'rv bool 'e) ->
+ ('vars -> monadS 'rv 'vars 'e) -> monadS 'rv 'vars 'e
+let rec whileS vars cond body s =
+ (cond vars >>$= (fun cond_val s' ->
+ if cond_val then
+ (body vars >>$= (fun vars s'' -> whileS vars cond body s'')) s'
+ else returnS vars s')) s
+
+val untilS : forall 'rv 'vars 'e. 'vars -> ('vars -> monadS 'rv bool 'e) ->
+ ('vars -> monadS 'rv 'vars 'e) -> monadS 'rv 'vars 'e
+let rec untilS vars cond body s =
+ (body vars >>$= (fun vars s' ->
+ (cond vars >>$= (fun cond_val s'' ->
+ if cond_val then returnS vars s'' else untilS vars cond body s'')) s')) s
+*)
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_state_monad.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_state_monad.v
new file mode 100644
index 00000000..c48db31b
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_state_monad.v
@@ -0,0 +1,253 @@
+Require Import Sail2_instr_kinds.
+Require Import Sail2_values.
+(*
+(* 'a is result type *)
+
+type memstate = map integer memory_byte
+type tagstate = map integer bitU
+(* type regstate = map string (vector bitU) *)
+
+type sequential_state 'regs =
+ <| regstate : 'regs;
+ memstate : memstate;
+ tagstate : tagstate;
+ write_ea : maybe (write_kind * integer * integer);
+ last_exclusive_operation_was_load : bool|>
+
+val init_state : forall 'regs. 'regs -> sequential_state 'regs
+let init_state regs =
+ <| regstate = regs;
+ memstate = Map.empty;
+ tagstate = Map.empty;
+ write_ea = Nothing;
+ last_exclusive_operation_was_load = false |>
+
+type ex 'e =
+ | Failure of string
+ | Throw of 'e
+
+type result 'a 'e =
+ | Value of 'a
+ | Ex of (ex 'e)
+
+(* State, nondeterminism and exception monad with result value type 'a
+ and exception type 'e. *)
+type monadS 'regs 'a 'e = sequential_state 'regs -> list (result 'a 'e * sequential_state 'regs)
+
+val returnS : forall 'regs 'a 'e. 'a -> monadS 'regs 'a 'e
+let returnS a s = [(Value a,s)]
+
+val bindS : forall 'regs 'a 'b 'e. monadS 'regs 'a 'e -> ('a -> monadS 'regs 'b 'e) -> monadS 'regs 'b 'e
+let bindS m f (s : sequential_state 'regs) =
+ List.concatMap (function
+ | (Value a, s') -> f a s'
+ | (Ex e, s') -> [(Ex e, s')]
+ end) (m s)
+
+val seqS: forall 'regs 'b 'e. monadS 'regs unit 'e -> monadS 'regs 'b 'e -> monadS 'regs 'b 'e
+let seqS m n = bindS m (fun (_ : unit) -> n)
+
+let inline (>>$=) = bindS
+let inline (>>$) = seqS
+
+val chooseS : forall 'regs 'a 'e. list 'a -> monadS 'regs 'a 'e
+let chooseS xs s = List.map (fun x -> (Value x, s)) xs
+
+val readS : forall 'regs 'a 'e. (sequential_state 'regs -> 'a) -> monadS 'regs 'a 'e
+let readS f = (fun s -> returnS (f s) s)
+
+val updateS : forall 'regs 'e. (sequential_state 'regs -> sequential_state 'regs) -> monadS 'regs unit 'e
+let updateS f = (fun s -> returnS () (f s))
+
+val failS : forall 'regs 'a 'e. string -> monadS 'regs 'a 'e
+let failS msg s = [(Ex (Failure msg), s)]
+
+val exitS : forall 'regs 'e 'a. unit -> monadS 'regs 'a 'e
+let exitS () = failS "exit"
+
+val throwS : forall 'regs 'a 'e. 'e -> monadS 'regs 'a 'e
+let throwS e s = [(Ex (Throw e), s)]
+
+val try_catchS : forall 'regs 'a 'e1 'e2. monadS 'regs 'a 'e1 -> ('e1 -> monadS 'regs 'a 'e2) -> monadS 'regs 'a 'e2
+let try_catchS m h s =
+ List.concatMap (function
+ | (Value a, s') -> returnS a s'
+ | (Ex (Throw e), s') -> h e s'
+ | (Ex (Failure msg), s') -> [(Ex (Failure msg), s')]
+ end) (m s)
+
+val assert_expS : forall 'regs 'e. bool -> string -> monadS 'regs unit 'e
+let assert_expS exp msg = if exp then returnS () else failS msg
+
+(* For early return, we abuse exceptions by throwing and catching
+ the return value. The exception type is "either 'r 'e", where "Right e"
+ represents a proper exception and "Left r" an early return of value "r". *)
+type monadSR 'regs 'a 'r 'e = monadS 'regs 'a (either 'r 'e)
+
+val early_returnS : forall 'regs 'a 'r 'e. 'r -> monadSR 'regs 'a 'r 'e
+let early_returnS r = throwS (Left r)
+
+val catch_early_returnS : forall 'regs 'a 'e. monadSR 'regs 'a 'a 'e -> monadS 'regs 'a 'e
+let catch_early_returnS m =
+ try_catchS m
+ (function
+ | Left a -> returnS a
+ | Right e -> throwS e
+ end)
+
+(* Lift to monad with early return by wrapping exceptions *)
+val liftSR : forall 'a 'r 'regs 'e. monadS 'regs 'a 'e -> monadSR 'regs 'a 'r 'e
+let liftSR m = try_catchS m (fun e -> throwS (Right e))
+
+(* Catch exceptions in the presence of early returns *)
+val try_catchSR : forall 'regs 'a 'r 'e1 'e2. monadSR 'regs 'a 'r 'e1 -> ('e1 -> monadSR 'regs 'a 'r 'e2) -> monadSR 'regs 'a 'r 'e2
+let try_catchSR m h =
+ try_catchS m
+ (function
+ | Left r -> throwS (Left r)
+ | Right e -> h e
+ end)
+
+val read_tagS : forall 'regs 'a 'e. Bitvector 'a => 'a -> monadS 'regs bitU 'e
+let read_tagS addr =
+ readS (fun s -> fromMaybe B0 (Map.lookup (unsigned addr) s.tagstate))
+
+(* Read bytes from memory and return in little endian order *)
+val read_mem_bytesS : forall 'regs 'e 'a. Bitvector 'a => read_kind -> 'a -> nat -> monadS 'regs (list memory_byte) 'e
+let read_mem_bytesS read_kind addr sz =
+ let addr = unsigned addr in
+ let sz = integerFromNat sz in
+ let addrs = index_list addr (addr+sz-1) 1 in
+ let read_byte s addr = Map.lookup addr s.memstate in
+ readS (fun s -> just_list (List.map (read_byte s) addrs)) >>$= (function
+ | Just mem_val ->
+ updateS (fun s ->
+ if read_is_exclusive read_kind
+ then <| s with last_exclusive_operation_was_load = true |>
+ else s) >>$
+ returnS mem_val
+ | Nothing -> failS "read_memS"
+ end)
+
+val read_memS : forall 'regs 'e 'a 'b. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monadS 'regs 'b 'e
+let read_memS rk a sz =
+ read_mem_bytesS rk a (natFromInteger sz) >>$= (fun bytes ->
+ returnS (bits_of_mem_bytes bytes))
+
+val excl_resultS : forall 'regs 'e. unit -> monadS 'regs bool 'e
+let excl_resultS () =
+ readS (fun s -> s.last_exclusive_operation_was_load) >>$= (fun excl_load ->
+ updateS (fun s -> <| s with last_exclusive_operation_was_load = false |>) >>$
+ chooseS (if excl_load then [false; true] else [false]))
+
+val write_mem_eaS : forall 'regs 'e 'a. Bitvector 'a => write_kind -> 'a -> nat -> monadS 'regs unit 'e
+let write_mem_eaS write_kind addr sz =
+ let addr = unsigned addr in
+ let sz = integerFromNat sz in
+ updateS (fun s -> <| s with write_ea = Just (write_kind, addr, sz) |>)
+
+(* Write little-endian list of bytes to previously announced address *)
+val write_mem_bytesS : forall 'regs 'e. list memory_byte -> monadS 'regs bool 'e
+let write_mem_bytesS v =
+ readS (fun s -> s.write_ea) >>$= (function
+ | Nothing -> failS "write ea has not been announced yet"
+ | Just (_, addr, sz) ->
+ let addrs = index_list addr (addr+sz-1) 1 in
+ (*let v = external_mem_value (bits_of v) in*)
+ let a_v = List.zip addrs v in
+ let write_byte mem (addr, v) = Map.insert addr v mem in
+ updateS (fun s ->
+ <| s with memstate = List.foldl write_byte s.memstate a_v |>) >>$
+ returnS true
+ end)
+
+val write_mem_valS : forall 'regs 'e 'a. Bitvector 'a => 'a -> monadS 'regs bool 'e
+let write_mem_valS v = match mem_bytes_of_bits v with
+ | Just v -> write_mem_bytesS v
+ | Nothing -> failS "write_mem_val"
+end
+
+val write_tagS : forall 'regs 'e. bitU -> monadS 'regs bool 'e
+let write_tagS t =
+ readS (fun s -> s.write_ea) >>$= (function
+ | Nothing -> failS "write ea has not been announced yet"
+ | Just (_, addr, _) ->
+ (*let taddr = addr / cap_alignment in*)
+ updateS (fun s -> <| s with tagstate = Map.insert addr t s.tagstate |>) >>$
+ returnS true
+ end)
+
+val read_regS : forall 'regs 'rv 'a 'e. register_ref 'regs 'rv 'a -> monadS 'regs 'a 'e
+let read_regS reg = readS (fun s -> reg.read_from s.regstate)
+
+(* TODO
+let read_reg_range reg i j state =
+ let v = slice (get_reg state (name_of_reg reg)) i j in
+ [(Value (vec_to_bvec v),state)]
+let read_reg_bit reg i state =
+ let v = access (get_reg state (name_of_reg reg)) i in
+ [(Value v,state)]
+let read_reg_field reg regfield =
+ let (i,j) = register_field_indices reg regfield in
+ read_reg_range reg i j
+let read_reg_bitfield reg regfield =
+ let (i,_) = register_field_indices reg regfield in
+ read_reg_bit reg i *)
+
+val read_regvalS : forall 'regs 'rv 'e.
+ register_accessors 'regs 'rv -> string -> monadS 'regs 'rv 'e
+let read_regvalS (read, _) reg =
+ readS (fun s -> read reg s.regstate) >>$= (function
+ | Just v -> returnS v
+ | Nothing -> failS ("read_regvalS " ^ reg)
+ end)
+
+val write_regvalS : forall 'regs 'rv 'e.
+ register_accessors 'regs 'rv -> string -> 'rv -> monadS 'regs unit 'e
+let write_regvalS (_, write) reg v =
+ readS (fun s -> write reg v s.regstate) >>$= (function
+ | Just rs' -> updateS (fun s -> <| s with regstate = rs' |>)
+ | Nothing -> failS ("write_regvalS " ^ reg)
+ end)
+
+val write_regS : forall 'regs 'rv 'a 'e. register_ref 'regs 'rv 'a -> 'a -> monadS 'regs unit 'e
+let write_regS reg v =
+ updateS (fun s -> <| s with regstate = reg.write_to v s.regstate |>)
+
+(* TODO
+val update_reg : forall 'regs 'rv 'a 'b 'e. register_ref 'regs 'rv 'a -> ('a -> 'b -> 'a) -> 'b -> monadS 'regs unit 'e
+let update_reg reg f v state =
+ let current_value = get_reg state reg in
+ let new_value = f current_value v in
+ [(Value (), set_reg state reg new_value)]
+
+let write_reg_field reg regfield = update_reg reg regfield.set_field
+
+val update_reg_range : forall 'regs 'rv 'a 'b. Bitvector 'a, Bitvector 'b => register_ref 'regs 'rv 'a -> integer -> integer -> 'a -> 'b -> 'a
+let update_reg_range reg i j reg_val new_val = set_bits (reg.is_inc) reg_val i j (bits_of new_val)
+let write_reg_range reg i j = update_reg reg (update_reg_range reg i j)
+
+let update_reg_pos reg i reg_val x = update_list reg.is_inc reg_val i x
+let write_reg_pos reg i = update_reg reg (update_reg_pos reg i)
+
+let update_reg_bit reg i reg_val bit = set_bit (reg.is_inc) reg_val i (to_bitU bit)
+let write_reg_bit reg i = update_reg reg (update_reg_bit reg i)
+
+let update_reg_field_range regfield i j reg_val new_val =
+ let current_field_value = regfield.get_field reg_val in
+ let new_field_value = set_bits (regfield.field_is_inc) current_field_value i j (bits_of new_val) in
+ regfield.set_field reg_val new_field_value
+let write_reg_field_range reg regfield i j = update_reg reg (update_reg_field_range regfield i j)
+
+let update_reg_field_pos regfield i reg_val x =
+ let current_field_value = regfield.get_field reg_val in
+ let new_field_value = update_list regfield.field_is_inc current_field_value i x in
+ regfield.set_field reg_val new_field_value
+let write_reg_field_pos reg regfield i = update_reg reg (update_reg_field_pos regfield i)
+
+let update_reg_field_bit regfield i reg_val bit =
+ let current_field_value = regfield.get_field reg_val in
+ let new_field_value = set_bit (regfield.field_is_inc) current_field_value i (to_bitU bit) in
+ regfield.set_field reg_val new_field_value
+let write_reg_field_bit reg regfield i = update_reg reg (update_reg_field_bit regfield i)*)
+*)
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_string.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_string.v
new file mode 100644
index 00000000..9ca9cb67
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_string.v
@@ -0,0 +1,35 @@
+Require Import Sail2_values.
+
+Definition string_sub (s : string) (start : Z) (len : Z) : string :=
+ String.substring (Z.to_nat start) (Z.to_nat len) s.
+
+Definition string_startswith s expected :=
+ let prefix := String.substring 0 (String.length expected) s in
+ generic_eq prefix expected.
+
+Definition string_drop s (n : {n : Z & ArithFact (n >= 0)}) :=
+ let n := Z.to_nat (projT1 n) in
+ String.substring n (String.length s - n) s.
+
+Definition string_length s : {n : Z & ArithFact (n >= 0)} :=
+ build_ex (Z.of_nat (String.length s)).
+
+Definition string_append := String.append.
+
+(* TODO: maybe_int_of_prefix, maybe_int_of_string *)
+
+Fixpoint n_leading_spaces (s:string) : nat :=
+ match s with
+ | EmptyString => 0
+ | String " " t => S (n_leading_spaces t)
+ | _ => 0
+ end.
+
+Definition opt_spc_matches_prefix s : option (unit * {n : Z & ArithFact (n >= 0)}) :=
+ Some (tt, build_ex (Z.of_nat (n_leading_spaces s))).
+
+Definition spc_matches_prefix s : option (unit * {n : Z & ArithFact (n >= 0)}) :=
+ match n_leading_spaces s with
+ | O => None
+ | S n => Some (tt, build_ex (Z.of_nat (S n)))
+ end. \ No newline at end of file
diff --git a/snapshots/coq-riscv/sail/lib/coq/Sail2_values.v b/snapshots/coq-riscv/sail/lib/coq/Sail2_values.v
new file mode 100644
index 00000000..30df0672
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/Sail2_values.v
@@ -0,0 +1,1643 @@
+(* Version of sail_values.lem that uses Lems machine words library *)
+
+(*Require Import Sail_impl_base*)
+Require Export ZArith.
+Require Import Ascii.
+Require Export String.
+Require Import bbv.Word.
+Require Export List.
+Require Export Sumbool.
+Require Export DecidableClass.
+Import ListNotations.
+
+Open Scope Z.
+
+(* Constraint solving basics. A HintDb which unfolding hints and lemmata
+ can be added to, and a typeclass to wrap constraint arguments in to
+ trigger automatic solving. *)
+Create HintDb sail.
+Class ArithFact (P : Prop) := { fact : P }.
+Lemma use_ArithFact {P} `(ArithFact P) : P.
+apply fact.
+Defined.
+
+Definition build_ex {T:Type} (n:T) {P:T -> Prop} `{H:ArithFact (P n)} : {x : T & ArithFact (P x)} :=
+ existT _ n H.
+
+Definition generic_eq {T:Type} (x y:T) `{Decidable (x = y)} := Decidable_witness.
+Definition generic_neq {T:Type} (x y:T) `{Decidable (x = y)} := negb Decidable_witness.
+Lemma generic_eq_true {T} {x y:T} `{Decidable (x = y)} : generic_eq x y = true -> x = y.
+apply Decidable_spec.
+Qed.
+Lemma generic_eq_false {T} {x y:T} `{Decidable (x = y)} : generic_eq x y = false -> x <> y.
+unfold generic_eq.
+intros H1 H2.
+rewrite <- Decidable_spec in H2.
+congruence.
+Qed.
+Lemma generic_neq_true {T} {x y:T} `{Decidable (x = y)} : generic_neq x y = true -> x <> y.
+unfold generic_neq.
+intros H1 H2.
+rewrite <- Decidable_spec in H2.
+destruct Decidable_witness; simpl in *;
+congruence.
+Qed.
+Lemma generic_neq_false {T} {x y:T} `{Decidable (x = y)} : generic_neq x y = false -> x = y.
+unfold generic_neq.
+intro H1.
+rewrite <- Decidable_spec.
+destruct Decidable_witness; simpl in *;
+congruence.
+Qed.
+Instance Decidable_eq_from_dec {T:Type} (eqdec: forall x y : T, {x = y} + {x <> y}) :
+ forall (x y : T), Decidable (eq x y) := {
+ Decidable_witness := proj1_sig (bool_of_sumbool (eqdec x y))
+}.
+destruct (eqdec x y); simpl; split; congruence.
+Defined.
+
+Instance Decidable_eq_string : forall (x y : string), Decidable (x = y) :=
+ Decidable_eq_from_dec String.string_dec.
+
+
+(* Project away range constraints in comparisons *)
+Definition ltb_range_l {P} (l : sigT P) r := Z.ltb (projT1 l) r.
+Definition leb_range_l {P} (l : sigT P) r := Z.leb (projT1 l) r.
+Definition gtb_range_l {P} (l : sigT P) r := Z.gtb (projT1 l) r.
+Definition geb_range_l {P} (l : sigT P) r := Z.geb (projT1 l) r.
+Definition ltb_range_r {P} l (r : sigT P) := Z.ltb l (projT1 r).
+Definition leb_range_r {P} l (r : sigT P) := Z.leb l (projT1 r).
+Definition gtb_range_r {P} l (r : sigT P) := Z.gtb l (projT1 r).
+Definition geb_range_r {P} l (r : sigT P) := Z.geb l (projT1 r).
+
+Definition ii := Z.
+Definition nn := nat.
+
+(*val pow : Z -> Z -> Z*)
+Definition pow m n := m ^ n.
+
+Program Definition pow2 n : {z : Z & ArithFact (2 ^ n <= z <= 2 ^ n)} := existT _ (pow 2 n) _.
+Next Obligation.
+constructor.
+unfold pow.
+auto using Z.le_refl.
+Qed.
+
+(*
+Definition inline lt := (<)
+Definition inline gt := (>)
+Definition inline lteq := (<=)
+Definition inline gteq := (>=)
+
+val eq : forall a. Eq a => a -> a -> bool
+Definition inline eq l r := (l = r)
+
+val neq : forall a. Eq a => a -> a -> bool*)
+Definition neq l r := (negb (l =? r)). (* Z only *)
+
+(*let add_int l r := integerAdd l r
+Definition add_signed l r := integerAdd l r
+Definition sub_int l r := integerMinus l r
+Definition mult_int l r := integerMult l r
+Definition div_int l r := integerDiv l r
+Definition div_nat l r := natDiv l r
+Definition power_int_nat l r := integerPow l r
+Definition power_int_int l r := integerPow l (Z.to_nat r)
+Definition negate_int i := integerNegate i
+Definition min_int l r := integerMin l r
+Definition max_int l r := integerMax l r
+
+Definition add_real l r := realAdd l r
+Definition sub_real l r := realMinus l r
+Definition mult_real l r := realMult l r
+Definition div_real l r := realDiv l r
+Definition negate_real r := realNegate r
+Definition abs_real r := realAbs r
+Definition power_real b e := realPowInteger b e*)
+
+Definition print_endline (_ : string) : unit := tt.
+Definition prerr_endline (_ : string) : unit := tt.
+Definition prerr (_ : string) : unit := tt.
+Definition print_int (_ : string) (_ : Z) : unit := tt.
+Definition prerr_int (_ : string) (_ : Z) : unit := tt.
+Definition putchar (_ : Z) : unit := tt.
+
+Definition shl_int := Z.shiftl.
+Definition shr_int := Z.shiftr.
+
+(*
+Definition or_bool l r := (l || r)
+Definition and_bool l r := (l && r)
+Definition xor_bool l r := xor l r
+*)
+Definition append_list {A:Type} (l : list A) r := l ++ r.
+Definition length_list {A:Type} (xs : list A) := Z.of_nat (List.length xs).
+Definition take_list {A:Type} n (xs : list A) := firstn (Z.to_nat n) xs.
+Definition drop_list {A:Type} n (xs : list A) := skipn (Z.to_nat n) xs.
+(*
+val repeat : forall a. list a -> Z -> list a*)
+Fixpoint repeat' {a} (xs : list a) n :=
+ match n with
+ | O => []
+ | S n => xs ++ repeat' xs n
+ end.
+Lemma repeat'_length {a} {xs : list a} {n : nat} : List.length (repeat' xs n) = (n * List.length xs)%nat.
+induction n.
+* reflexivity.
+* simpl.
+ rewrite app_length.
+ auto with arith.
+Qed.
+Definition repeat {a} (xs : list a) (n : Z) :=
+ if n <=? 0 then []
+ else repeat' xs (Z.to_nat n).
+Lemma repeat_length {a} {xs : list a} {n : Z} (H : n >= 0) : length_list (repeat xs n) = n * length_list xs.
+unfold length_list, repeat.
+destruct n.
++ reflexivity.
++ simpl (List.length _).
+ rewrite repeat'_length.
+ rewrite Nat2Z.inj_mul.
+ rewrite positive_nat_Z.
+ reflexivity.
++ exfalso.
+ auto with zarith.
+Qed.
+
+(*declare {isabelle} termination_argument repeat = automatic
+
+Definition duplicate_to_list bit length := repeat [bit] length
+
+Fixpoint replace bs (n : Z) b' := match bs with
+ | [] => []
+ | b :: bs =>
+ if n = 0 then b' :: bs
+ else b :: replace bs (n - 1) b'
+ end
+declare {isabelle} termination_argument replace = automatic
+
+Definition upper n := n
+
+(* Modulus operation corresponding to quot below -- result
+ has sign of dividend. *)
+Definition hardware_mod (a: Z) (b:Z) : Z :=
+ let m := (abs a) mod (abs b) in
+ if a < 0 then ~m else m
+
+(* There are different possible answers for integer divide regarding
+rounding behaviour on negative operands. Positive operands always
+round down so derive the one we want (trucation towards zero) from
+that *)
+Definition hardware_quot (a:Z) (b:Z) : Z :=
+ let q := (abs a) / (abs b) in
+ if ((a<0) = (b<0)) then
+ q (* same sign -- result positive *)
+ else
+ ~q (* different sign -- result negative *)
+
+Definition max_64u := (integerPow 2 64) - 1
+Definition max_64 := (integerPow 2 63) - 1
+Definition min_64 := 0 - (integerPow 2 63)
+Definition max_32u := (4294967295 : Z)
+Definition max_32 := (2147483647 : Z)
+Definition min_32 := (0 - 2147483648 : Z)
+Definition max_8 := (127 : Z)
+Definition min_8 := (0 - 128 : Z)
+Definition max_5 := (31 : Z)
+Definition min_5 := (0 - 32 : Z)
+*)
+
+(* just_list takes a list of maybes and returns Some xs if all elements have
+ a value, and None if one of the elements is None. *)
+(*val just_list : forall a. list (option a) -> option (list a)*)
+Fixpoint just_list {A} (l : list (option A)) := match l with
+ | [] => Some []
+ | (x :: xs) =>
+ match (x, just_list xs) with
+ | (Some x, Some xs) => Some (x :: xs)
+ | (_, _) => None
+ end
+ end.
+(*declare {isabelle} termination_argument just_list = automatic
+
+lemma just_list_spec:
+ ((forall xs. (just_list xs = None) <-> List.elem None xs) &&
+ (forall xs es. (just_list xs = Some es) <-> (xs = List.map Some es)))*)
+
+Lemma just_list_length {A} : forall (l : list (option A)) (l' : list A),
+ Some l' = just_list l -> List.length l = List.length l'.
+induction l.
+* intros.
+ simpl in H.
+ inversion H.
+ reflexivity.
+* intros.
+ destruct a; simplify_eq H.
+ simpl in *.
+ destruct (just_list l); simplify_eq H.
+ intros.
+ subst.
+ simpl.
+ f_equal.
+ apply IHl.
+ reflexivity.
+Qed.
+
+Lemma just_list_length_Z {A} : forall (l : list (option A)) l', Some l' = just_list l -> length_list l = length_list l'.
+unfold length_list.
+intros.
+f_equal.
+auto using just_list_length.
+Qed.
+
+Fixpoint member_Z_list (x : Z) (l : list Z) : bool :=
+match l with
+| [] => false
+| h::t => if x =? h then true else member_Z_list x t
+end.
+
+Lemma member_Z_list_In {x l} : member_Z_list x l = true <-> In x l.
+induction l.
+* simpl. split. congruence. tauto.
+* simpl. destruct (x =? a) eqn:H.
+ + rewrite Z.eqb_eq in H. subst. tauto.
+ + rewrite Z.eqb_neq in H. split.
+ - intro Heq. right. apply IHl. assumption.
+ - intros [bad | good]. congruence. apply IHl. assumption.
+Qed.
+
+(*** Bits *)
+Inductive bitU := B0 | B1 | BU.
+
+Definition showBitU b :=
+match b with
+ | B0 => "O"
+ | B1 => "I"
+ | BU => "U"
+end%string.
+
+Definition bitU_char b :=
+match b with
+| B0 => "0"
+| B1 => "1"
+| BU => "?"
+end%char.
+
+(*instance (Show bitU)
+ let show := showBitU
+end*)
+
+Class BitU (a : Type) : Type := {
+ to_bitU : a -> bitU;
+ of_bitU : bitU -> a
+}.
+
+Instance bitU_BitU : (BitU bitU) := {
+ to_bitU b := b;
+ of_bitU b := b
+}.
+
+Definition bool_of_bitU bu := match bu with
+ | B0 => Some false
+ | B1 => Some true
+ | BU => None
+ end.
+
+Definition bitU_of_bool (b : bool) := if b then B1 else B0.
+
+(*Instance bool_BitU : (BitU bool) := {
+ to_bitU := bitU_of_bool;
+ of_bitU := bool_of_bitU
+}.*)
+
+Definition cast_bit_bool := bool_of_bitU.
+(*
+Definition bit_lifted_of_bitU bu := match bu with
+ | B0 => Bitl_zero
+ | B1 => Bitl_one
+ | BU => Bitl_undef
+ end.
+
+Definition bitU_of_bit := function
+ | Bitc_zero => B0
+ | Bitc_one => B1
+ end.
+
+Definition bit_of_bitU := function
+ | B0 => Bitc_zero
+ | B1 => Bitc_one
+ | BU => failwith "bit_of_bitU: BU"
+ end.
+
+Definition bitU_of_bit_lifted := function
+ | Bitl_zero => B0
+ | Bitl_one => B1
+ | Bitl_undef => BU
+ | Bitl_unknown => failwith "bitU_of_bit_lifted Bitl_unknown"
+ end.
+*)
+Definition not_bit b :=
+match b with
+ | B1 => B0
+ | B0 => B1
+ | BU => BU
+ end.
+
+(*val is_one : Z -> bitU*)
+Definition is_one (i : Z) :=
+ if i =? 1 then B1 else B0.
+
+Definition binop_bit op x y :=
+ match (x, y) with
+ | (BU,_) => BU (*Do we want to do this or to respect | of I and & of B0 rules?*)
+ | (_,BU) => BU (*Do we want to do this or to respect | of I and & of B0 rules?*)
+ | (x,y) => bitU_of_bool (op (bool_of_bitU x) (bool_of_bitU y))
+ end.
+
+(*val and_bit : bitU -> bitU -> bitU
+Definition and_bit := binop_bit (&&)
+
+val or_bit : bitU -> bitU -> bitU
+Definition or_bit := binop_bit (||)
+
+val xor_bit : bitU -> bitU -> bitU
+Definition xor_bit := binop_bit xor
+
+val (&.) : bitU -> bitU -> bitU
+Definition inline (&.) x y := and_bit x y
+
+val (|.) : bitU -> bitU -> bitU
+Definition inline (|.) x y := or_bit x y
+
+val (+.) : bitU -> bitU -> bitU
+Definition inline (+.) x y := xor_bit x y
+*)
+
+(*** Bool lists ***)
+
+(*val bools_of_nat_aux : integer -> natural -> list bool -> list bool*)
+Fixpoint bools_of_nat_aux len (x : nat) (acc : list bool) : list bool :=
+ match len with
+ | O => acc
+ | S len' => bools_of_nat_aux len' (x / 2) ((if x mod 2 =? 1 then true else false) :: acc)
+ end %nat.
+ (*else (if x mod 2 = 1 then true else false) :: bools_of_nat_aux (x / 2)*)
+(*declare {isabelle} termination_argument bools_of_nat_aux = automatic*)
+Definition bools_of_nat len n := bools_of_nat_aux (Z.to_nat len) n [] (*List.reverse (bools_of_nat_aux n)*).
+
+(*val nat_of_bools_aux : natural -> list bool -> natural*)
+Fixpoint nat_of_bools_aux (acc : nat) (bs : list bool) : nat :=
+ match bs with
+ | [] => acc
+ | true :: bs => nat_of_bools_aux ((2 * acc) + 1) bs
+ | false :: bs => nat_of_bools_aux (2 * acc) bs
+end.
+(*declare {isabelle; hol} termination_argument nat_of_bools_aux = automatic*)
+Definition nat_of_bools bs := nat_of_bools_aux 0 bs.
+
+(*val unsigned_of_bools : list bool -> integer*)
+Definition unsigned_of_bools bs := Z.of_nat (nat_of_bools bs).
+
+(*val signed_of_bools : list bool -> integer*)
+Definition signed_of_bools bs :=
+ match bs with
+ | true :: _ => 0 - (1 + (unsigned_of_bools (List.map negb bs)))
+ | false :: _ => unsigned_of_bools bs
+ | [] => 0 (* Treat empty list as all zeros *)
+ end.
+
+(*val int_of_bools : bool -> list bool -> integer*)
+Definition int_of_bools (sign : bool) bs := if sign then signed_of_bools bs else unsigned_of_bools bs.
+
+(*val pad_list : forall 'a. 'a -> list 'a -> integer -> list 'a*)
+Fixpoint pad_list_nat {a} (x : a) (xs : list a) n :=
+ match n with
+ | O => xs
+ | S n' => pad_list_nat x (x :: xs) n'
+ end.
+(*declare {isabelle} termination_argument pad_list = automatic*)
+Definition pad_list {a} x xs n := @pad_list_nat a x xs (Z.to_nat n).
+
+Definition ext_list {a} pad len (xs : list a) :=
+ let longer := len - (Z.of_nat (List.length xs)) in
+ if longer <? 0 then skipn (Z.abs_nat (longer)) xs
+ else pad_list pad xs longer.
+
+(*let extz_bools len bs = ext_list false len bs*)
+Definition exts_bools len bs :=
+ match bs with
+ | true :: _ => ext_list true len bs
+ | _ => ext_list false len bs
+ end.
+
+Fixpoint add_one_bool_ignore_overflow_aux bits := match bits with
+ | [] => []
+ | false :: bits => true :: bits
+ | true :: bits => false :: add_one_bool_ignore_overflow_aux bits
+end.
+(*declare {isabelle; hol} termination_argument add_one_bool_ignore_overflow_aux = automatic*)
+
+Definition add_one_bool_ignore_overflow bits :=
+ List.rev (add_one_bool_ignore_overflow_aux (List.rev bits)).
+
+(*let bool_list_of_int n =
+ let bs_abs = false :: bools_of_nat (naturalFromInteger (abs n)) in
+ if n >= (0 : integer) then bs_abs
+ else add_one_bool_ignore_overflow (List.map not bs_abs)
+let bools_of_int len n = exts_bools len (bool_list_of_int n)*)
+Definition bools_of_int len n :=
+ let bs_abs := bools_of_nat len (Z.abs_nat n) in
+ if n >=? 0 then bs_abs
+ else add_one_bool_ignore_overflow (List.map negb bs_abs).
+
+(*** Bit lists ***)
+
+(*val bits_of_nat_aux : natural -> list bitU*)
+Fixpoint bits_of_nat_aux n x :=
+ match n,x with
+ | O,_ => []
+ | _,O => []
+ | S n, S _ => (if x mod 2 =? 1 then B1 else B0) :: bits_of_nat_aux n (x / 2)
+ end%nat.
+(**declare {isabelle} termination_argument bits_of_nat_aux = automatic*)
+Definition bits_of_nat n := List.rev (bits_of_nat_aux n n).
+
+(*val nat_of_bits_aux : natural -> list bitU -> natural*)
+Fixpoint nat_of_bits_aux acc bs := match bs with
+ | [] => Some acc
+ | B1 :: bs => nat_of_bits_aux ((2 * acc) + 1) bs
+ | B0 :: bs => nat_of_bits_aux (2 * acc) bs
+ | BU :: bs => None
+end%nat.
+(*declare {isabelle} termination_argument nat_of_bits_aux = automatic*)
+Definition nat_of_bits bits := nat_of_bits_aux 0 bits.
+
+Definition not_bits := List.map not_bit.
+
+Definition binop_bits op bsl bsr :=
+ List.fold_right (fun '(bl, br) acc => binop_bit op bl br :: acc) [] (List.combine bsl bsr).
+(*
+Definition and_bits := binop_bits (&&)
+Definition or_bits := binop_bits (||)
+Definition xor_bits := binop_bits xor
+
+val unsigned_of_bits : list bitU -> Z*)
+Definition unsigned_of_bits bits :=
+match just_list (List.map bool_of_bitU bits) with
+| Some bs => Some (unsigned_of_bools bs)
+| None => None
+end.
+
+(*val signed_of_bits : list bitU -> Z*)
+Definition signed_of_bits bits :=
+ match just_list (List.map bool_of_bitU bits) with
+ | Some bs => Some (signed_of_bools bs)
+ | None => None
+ end.
+
+(*val int_of_bits : bool -> list bitU -> maybe integer*)
+Definition int_of_bits (sign : bool) bs :=
+ if sign then signed_of_bits bs else unsigned_of_bits bs.
+
+(*val pad_bitlist : bitU -> list bitU -> Z -> list bitU*)
+Fixpoint pad_bitlist_nat (b : bitU) bits n :=
+match n with
+| O => bits
+| S n' => pad_bitlist_nat b (b :: bits) n'
+end.
+Definition pad_bitlist b bits n := pad_bitlist_nat b bits (Z.to_nat n). (* Negative n will come out as 0 *)
+(* if n <= 0 then bits else pad_bitlist b (b :: bits) (n - 1).
+declare {isabelle} termination_argument pad_bitlist = automatic*)
+
+Definition ext_bits pad len bits :=
+ let longer := len - (Z.of_nat (List.length bits)) in
+ if longer <? 0 then skipn (Z.abs_nat longer) bits
+ else pad_bitlist pad bits longer.
+
+Definition extz_bits len bits := ext_bits B0 len bits.
+Parameter undefined_list_bitU : list bitU.
+Definition exts_bits len bits :=
+ match bits with
+ | BU :: _ => undefined_list_bitU (*failwith "exts_bits: undefined bit"*)
+ | B1 :: _ => ext_bits B1 len bits
+ | _ => ext_bits B0 len bits
+ end.
+
+Fixpoint add_one_bit_ignore_overflow_aux bits := match bits with
+ | [] => []
+ | B0 :: bits => B1 :: bits
+ | B1 :: bits => B0 :: add_one_bit_ignore_overflow_aux bits
+ | BU :: _ => undefined_list_bitU (*failwith "add_one_bit_ignore_overflow: undefined bit"*)
+end.
+(*declare {isabelle} termination_argument add_one_bit_ignore_overflow_aux = automatic*)
+
+Definition add_one_bit_ignore_overflow bits :=
+ rev (add_one_bit_ignore_overflow_aux (rev bits)).
+
+Definition bitlist_of_int n :=
+ let bits_abs := B0 :: bits_of_nat (Z.abs_nat n) in
+ if n >=? 0 then bits_abs
+ else add_one_bit_ignore_overflow (not_bits bits_abs).
+
+Definition bits_of_int len n := exts_bits len (bitlist_of_int n).
+
+(*val arith_op_bits :
+ (integer -> integer -> integer) -> bool -> list bitU -> list bitU -> list bitU*)
+Definition arith_op_bits (op : Z -> Z -> Z) (sign : bool) l r :=
+ match (int_of_bits sign l, int_of_bits sign r) with
+ | (Some li, Some ri) => bits_of_int (length_list l) (op li ri)
+ | (_, _) => repeat [BU] (length_list l)
+ end.
+
+
+Definition char_of_nibble x :=
+ match x with
+ | (B0, B0, B0, B0) => Some "0"%char
+ | (B0, B0, B0, B1) => Some "1"%char
+ | (B0, B0, B1, B0) => Some "2"%char
+ | (B0, B0, B1, B1) => Some "3"%char
+ | (B0, B1, B0, B0) => Some "4"%char
+ | (B0, B1, B0, B1) => Some "5"%char
+ | (B0, B1, B1, B0) => Some "6"%char
+ | (B0, B1, B1, B1) => Some "7"%char
+ | (B1, B0, B0, B0) => Some "8"%char
+ | (B1, B0, B0, B1) => Some "9"%char
+ | (B1, B0, B1, B0) => Some "A"%char
+ | (B1, B0, B1, B1) => Some "B"%char
+ | (B1, B1, B0, B0) => Some "C"%char
+ | (B1, B1, B0, B1) => Some "D"%char
+ | (B1, B1, B1, B0) => Some "E"%char
+ | (B1, B1, B1, B1) => Some "F"%char
+ | _ => None
+ end.
+
+Fixpoint hexstring_of_bits bs := match bs with
+ | b1 :: b2 :: b3 :: b4 :: bs =>
+ let n := char_of_nibble (b1, b2, b3, b4) in
+ let s := hexstring_of_bits bs in
+ match (n, s) with
+ | (Some n, Some s) => Some (String n s)
+ | _ => None
+ end
+ | [] => Some EmptyString
+ | _ => None
+ end%string.
+
+Fixpoint binstring_of_bits bs := match bs with
+ | b :: bs => String (bitU_char b) (binstring_of_bits bs)
+ | [] => EmptyString
+ end.
+
+Definition show_bitlist bs :=
+ match hexstring_of_bits bs with
+ | Some s => String "0" (String "x" s)
+ | None => String "0" (String "b" (binstring_of_bits bs))
+ end.
+
+(*** List operations *)
+(*
+Definition inline (^^) := append_list
+
+val subrange_list_inc : forall a. list a -> Z -> Z -> list a*)
+Definition subrange_list_inc {A} (xs : list A) i j :=
+ let toJ := firstn (Z.to_nat j + 1) xs in
+ let fromItoJ := skipn (Z.to_nat i) toJ in
+ fromItoJ.
+
+(*val subrange_list_dec : forall a. list a -> Z -> Z -> list a*)
+Definition subrange_list_dec {A} (xs : list A) i j :=
+ let top := (length_list xs) - 1 in
+ subrange_list_inc xs (top - i) (top - j).
+
+(*val subrange_list : forall a. bool -> list a -> Z -> Z -> list a*)
+Definition subrange_list {A} (is_inc : bool) (xs : list A) i j :=
+ if is_inc then subrange_list_inc xs i j else subrange_list_dec xs i j.
+
+Definition splitAt {A} n (l : list A) := (firstn n l, skipn n l).
+
+(*val update_subrange_list_inc : forall a. list a -> Z -> Z -> list a -> list a*)
+Definition update_subrange_list_inc {A} (xs : list A) i j xs' :=
+ let (toJ,suffix) := splitAt (Z.to_nat j + 1) xs in
+ let (prefix,_fromItoJ) := splitAt (Z.to_nat i) toJ in
+ prefix ++ xs' ++ suffix.
+
+(*val update_subrange_list_dec : forall a. list a -> Z -> Z -> list a -> list a*)
+Definition update_subrange_list_dec {A} (xs : list A) i j xs' :=
+ let top := (length_list xs) - 1 in
+ update_subrange_list_inc xs (top - i) (top - j) xs'.
+
+(*val update_subrange_list : forall a. bool -> list a -> Z -> Z -> list a -> list a*)
+Definition update_subrange_list {A} (is_inc : bool) (xs : list A) i j xs' :=
+ if is_inc then update_subrange_list_inc xs i j xs' else update_subrange_list_dec xs i j xs'.
+
+Open Scope nat.
+Fixpoint nth_in_range {A} (n:nat) (l:list A) : n < length l -> A.
+refine
+ (match n, l with
+ | O, h::_ => fun _ => h
+ | S m, _::t => fun H => nth_in_range A m t _
+ | _,_ => fun H => _
+ end).
+exfalso. inversion H.
+exfalso. inversion H.
+simpl in H. omega.
+Defined.
+
+Lemma nth_in_range_is_nth : forall A n (l : list A) d (H : n < length l),
+ nth_in_range n l H = nth n l d.
+intros until d. revert n.
+induction l; intros n H.
+* inversion H.
+* destruct n.
+ + reflexivity.
+ + apply IHl.
+Qed.
+
+Lemma nth_Z_nat {A} {n} {xs : list A} :
+ (0 <= n)%Z -> (n < length_list xs)%Z -> Z.to_nat n < length xs.
+unfold length_list.
+intros nonneg bounded.
+rewrite Z2Nat.inj_lt in bounded; auto using Zle_0_nat.
+rewrite Nat2Z.id in bounded.
+assumption.
+Qed.
+
+(*
+Lemma nth_top_aux {A} {n} {xs : list A} : Z.to_nat n < length xs -> let top := ((length_list xs) - 1)%Z in Z.to_nat (top - n)%Z < length xs.
+unfold length_list.
+generalize (length xs).
+intro n0.
+rewrite <- (Nat2Z.id n0).
+intro H.
+apply Z2Nat.inj_lt.
+* omega.
+*)
+
+Close Scope nat.
+
+(*val access_list_inc : forall a. list a -> Z -> a*)
+Definition access_list_inc {A} (xs : list A) n `{ArithFact (0 <= n)} `{ArithFact (n < length_list xs)} := nth_in_range (Z.to_nat n) xs (nth_Z_nat (use_ArithFact _) (use_ArithFact _)).
+
+(*val access_list_dec : forall a. list a -> Z -> a*)
+Definition access_list_dec {A} (xs : list A) n `{ArithFact (0 <= n)} `{ArithFact (n < length_list xs)} : A.
+refine (
+ let top := (length_list xs) - 1 in
+ @access_list_inc A xs (top - n) _ _).
+constructor. apply use_ArithFact in H. apply use_ArithFact in H0. omega.
+constructor. apply use_ArithFact in H. apply use_ArithFact in H0. omega.
+Defined.
+
+(*val access_list : forall a. bool -> list a -> Z -> a*)
+Definition access_list {A} (is_inc : bool) (xs : list A) n `{ArithFact (0 <= n)} `{ArithFact (n < length_list xs)} :=
+ if is_inc then access_list_inc xs n else access_list_dec xs n.
+
+Definition access_list_opt_inc {A} (xs : list A) n := nth_error xs (Z.to_nat n).
+
+(*val access_list_dec : forall a. list a -> Z -> a*)
+Definition access_list_opt_dec {A} (xs : list A) n :=
+ let top := (length_list xs) - 1 in
+ access_list_opt_inc xs (top - n).
+
+(*val access_list : forall a. bool -> list a -> Z -> a*)
+Definition access_list_opt {A} (is_inc : bool) (xs : list A) n :=
+ if is_inc then access_list_opt_inc xs n else access_list_opt_dec xs n.
+
+Definition list_update {A} (xs : list A) n x := firstn n xs ++ x :: skipn (S n) xs.
+
+(*val update_list_inc : forall a. list a -> Z -> a -> list a*)
+Definition update_list_inc {A} (xs : list A) n x := list_update xs (Z.to_nat n) x.
+
+(*val update_list_dec : forall a. list a -> Z -> a -> list a*)
+Definition update_list_dec {A} (xs : list A) n x :=
+ let top := (length_list xs) - 1 in
+ update_list_inc xs (top - n) x.
+
+(*val update_list : forall a. bool -> list a -> Z -> a -> list a*)
+Definition update_list {A} (is_inc : bool) (xs : list A) n x :=
+ if is_inc then update_list_inc xs n x else update_list_dec xs n x.
+
+(*Definition extract_only_element := function
+ | [] => failwith "extract_only_element called for empty list"
+ | [e] => e
+ | _ => failwith "extract_only_element called for list with more elements"
+end*)
+
+(*** Machine words *)
+
+Definition mword (n : Z) :=
+ match n with
+ | Zneg _ => False
+ | Z0 => word 0
+ | Zpos p => word (Pos.to_nat p)
+ end.
+
+Definition get_word {n} : mword n -> word (Z.to_nat n) :=
+ match n with
+ | Zneg _ => fun x => match x with end
+ | Z0 => fun x => x
+ | Zpos p => fun x => x
+ end.
+
+Definition with_word {n} {P : Type -> Type} : (word (Z.to_nat n) -> P (word (Z.to_nat n))) -> mword n -> P (mword n) :=
+match n with
+| Zneg _ => fun f w => match w with end
+| Z0 => fun f w => f w
+| Zpos _ => fun f w => f w
+end.
+
+Program Definition to_word {n} : n >= 0 -> word (Z.to_nat n) -> mword n :=
+ match n with
+ | Zneg _ => fun H _ => _
+ | Z0 => fun _ w => w
+ | Zpos _ => fun _ w => w
+ end.
+
+(*val length_mword : forall a. mword a -> Z*)
+Definition length_mword {n} (w : mword n) := n.
+
+(*val slice_mword_dec : forall a b. mword a -> Z -> Z -> mword b*)
+(*Definition slice_mword_dec w i j := word_extract (Z.to_nat i) (Z.to_nat j) w.
+
+val slice_mword_inc : forall a b. mword a -> Z -> Z -> mword b
+Definition slice_mword_inc w i j :=
+ let top := (length_mword w) - 1 in
+ slice_mword_dec w (top - i) (top - j)
+
+val slice_mword : forall a b. bool -> mword a -> Z -> Z -> mword b
+Definition slice_mword is_inc w i j := if is_inc then slice_mword_inc w i j else slice_mword_dec w i j
+
+val update_slice_mword_dec : forall a b. mword a -> Z -> Z -> mword b -> mword a
+Definition update_slice_mword_dec w i j w' := word_update w (Z.to_nat i) (Z.to_nat j) w'
+
+val update_slice_mword_inc : forall a b. mword a -> Z -> Z -> mword b -> mword a
+Definition update_slice_mword_inc w i j w' :=
+ let top := (length_mword w) - 1 in
+ update_slice_mword_dec w (top - i) (top - j) w'
+
+val update_slice_mword : forall a b. bool -> mword a -> Z -> Z -> mword b -> mword a
+Definition update_slice_mword is_inc w i j w' :=
+ if is_inc then update_slice_mword_inc w i j w' else update_slice_mword_dec w i j w'
+
+val access_mword_dec : forall a. mword a -> Z -> bitU*)
+Parameter undefined_bit : bool.
+Definition getBit {n} :=
+match n with
+| O => fun (w : word O) i => undefined_bit
+| S n => fun (w : word (S n)) i => wlsb (wrshift w i)
+end.
+
+Definition access_mword_dec {m} (w : mword m) n := bitU_of_bool (getBit (get_word w) (Z.to_nat n)).
+
+(*val access_mword_inc : forall a. mword a -> Z -> bitU*)
+Definition access_mword_inc {m} (w : mword m) n :=
+ let top := (length_mword w) - 1 in
+ access_mword_dec w (top - n).
+
+(*Parameter access_mword : forall {a}, bool -> mword a -> Z -> bitU.*)
+Definition access_mword {a} (is_inc : bool) (w : mword a) n :=
+ if is_inc then access_mword_inc w n else access_mword_dec w n.
+
+Definition setBit {n} :=
+match n with
+| O => fun (w : word O) i b => w
+| S n => fun (w : word (S n)) i (b : bool) =>
+ let bit : word (S n) := wlshift (natToWord _ 1) i in
+ let mask : word (S n) := wnot bit in
+ let masked := wand mask w in
+ if b then masked else wor masked bit
+end.
+
+(*val update_mword_bool_dec : forall 'a. mword 'a -> integer -> bool -> mword 'a*)
+Definition update_mword_bool_dec {a} (w : mword a) n b : mword a :=
+ with_word (P := id) (fun w => setBit w (Z.to_nat n) b) w.
+Definition update_mword_dec {a} (w : mword a) n b :=
+ match bool_of_bitU b with
+ | Some bl => Some (update_mword_bool_dec w n bl)
+ | None => None
+ end.
+
+(*val update_mword_inc : forall a. mword a -> Z -> bitU -> mword a*)
+Definition update_mword_inc {a} (w : mword a) n b :=
+ let top := (length_mword w) - 1 in
+ update_mword_dec w (top - n) b.
+
+(*Parameter update_mword : forall {a}, bool -> mword a -> Z -> bitU -> mword a.*)
+Definition update_mword {a} (is_inc : bool) (w : mword a) n b :=
+ if is_inc then update_mword_inc w n b else update_mword_dec w n b.
+
+(*val int_of_mword : forall 'a. bool -> mword 'a -> integer*)
+Definition int_of_mword {a} `{ArithFact (a >= 0)} (sign : bool) (w : mword a) :=
+ if sign then wordToZ (get_word w) else Z.of_N (wordToN (get_word w)).
+
+
+(*val mword_of_int : forall a. Size a => Z -> Z -> mword a
+Definition mword_of_int len n :=
+ let w := wordFromInteger n in
+ if (length_mword w = len) then w else failwith "unexpected word length"
+*)
+Program Definition mword_of_int {len} `{H:ArithFact (len >= 0)} n : mword len :=
+match len with
+| Zneg _ => _
+| Z0 => ZToWord 0 n
+| Zpos p => ZToWord (Pos.to_nat p) n
+end.
+Next Obligation.
+destruct H.
+auto.
+Defined.
+(*
+(* Translating between a type level number (itself n) and an integer *)
+
+Definition size_itself_int x := Z.of_nat (size_itself x)
+
+(* NB: the corresponding sail type is forall n. atom(n) -> itself(n),
+ the actual integer is ignored. *)
+
+val make_the_value : forall n. Z -> itself n
+Definition inline make_the_value x := the_value
+*)
+
+Fixpoint bitlistFromWord {n} w :=
+match w with
+| WO => []
+| WS b w => b :: bitlistFromWord w
+end.
+
+Fixpoint wordFromBitlist l : word (length l) :=
+match l with
+| [] => WO
+| b::t => WS b (wordFromBitlist t)
+end.
+
+Local Open Scope nat.
+Program Definition fit_bbv_word {n m} (w : word n) : word m :=
+match Nat.compare m n with
+| Gt => extz w (m - n)
+| Eq => w
+| Lt => split2 (n - m) m w
+end.
+Next Obligation.
+symmetry in Heq_anonymous.
+apply nat_compare_gt in Heq_anonymous.
+omega.
+Defined.
+Next Obligation.
+
+symmetry in Heq_anonymous.
+apply nat_compare_eq in Heq_anonymous.
+omega.
+Defined.
+Next Obligation.
+
+symmetry in Heq_anonymous.
+apply nat_compare_lt in Heq_anonymous.
+omega.
+Defined.
+Local Close Scope nat.
+
+(*** Bitvectors *)
+
+Class Bitvector (a:Type) : Type := {
+ bits_of : a -> list bitU;
+ of_bits : list bitU -> option a;
+ of_bools : list bool -> a;
+ (* The first parameter specifies the desired length of the bitvector *)
+ of_int : Z -> Z -> a;
+ length : a -> Z;
+ unsigned : a -> option Z;
+ signed : a -> option Z;
+ arith_op_bv : (Z -> Z -> Z) -> bool -> a -> a -> a
+}.
+
+Instance bitlist_Bitvector {a : Type} `{BitU a} : (Bitvector (list a)) := {
+ bits_of v := List.map to_bitU v;
+ of_bits v := Some (List.map of_bitU v);
+ of_bools v := List.map of_bitU (List.map bitU_of_bool v);
+ of_int len n := List.map of_bitU (bits_of_int len n);
+ length := length_list;
+ unsigned v := unsigned_of_bits (List.map to_bitU v);
+ signed v := signed_of_bits (List.map to_bitU v);
+ arith_op_bv op sign l r := List.map of_bitU (arith_op_bits op sign (List.map to_bitU l) (List.map to_bitU r))
+}.
+
+Class ReasonableSize (a : Z) : Prop := {
+ isPositive : a >= 0
+}.
+
+(* Omega doesn't know about In, but can handle disjunctions. *)
+Ltac unfold_In :=
+repeat match goal with
+| H:context [member_Z_list _ _ = true] |- _ => rewrite member_Z_list_In in H
+| H:context [In ?x (?y :: ?t)] |- _ => change (In x (y :: t)) with (y = x \/ In x t) in H
+| H:context [In ?x []] |- _ => change (In x []) with False in H
+end.
+
+(* Definitions in the context that involve proof for other constraints can
+ break some of the constraint solving tactics, so prune definition bodies
+ down to integer types. *)
+Ltac not_Z ty := match ty with Z => fail 1 | _ => idtac end.
+Ltac clear_non_Z_defns :=
+ repeat match goal with H := _ : ?X |- _ => not_Z X; clearbody H end.
+Ltac clear_irrelevant_defns :=
+repeat match goal with X := _ |- _ =>
+ match goal with |- context[X] => idtac end ||
+ match goal with _ : context[X] |- _ => idtac end || clear X
+end.
+
+Lemma ArithFact_mword (a : Z) (w : mword a) : ArithFact (a >= 0).
+constructor.
+destruct a.
+auto with zarith.
+auto using Z.le_ge, Zle_0_pos.
+destruct w.
+Qed.
+Ltac unwrap_ArithFacts :=
+ repeat match goal with H:(ArithFact _) |- _ => let H' := fresh H in case H as [H'] end.
+Ltac unbool_comparisons :=
+ repeat match goal with
+ | H:context [Z.geb _ _] |- _ => rewrite Z.geb_leb in H
+ | H:context [Z.gtb _ _] |- _ => rewrite Z.gtb_ltb in H
+ | H:context [Z.leb _ _ = true] |- _ => rewrite Z.leb_le in H
+ | H:context [Z.ltb _ _ = true] |- _ => rewrite Z.ltb_lt in H
+ | H:context [Z.eqb _ _ = true] |- _ => rewrite Z.eqb_eq in H
+ | H:context [Z.leb _ _ = false] |- _ => rewrite Z.leb_gt in H
+ | H:context [Z.ltb _ _ = false] |- _ => rewrite Z.ltb_ge in H
+ | H:context [Z.eqb _ _ = false] |- _ => rewrite Z.eqb_neq in H
+ | H:context [orb _ _ = true] |- _ => rewrite Bool.orb_true_iff in H
+ | H:context [orb _ _ = false] |- _ => rewrite Bool.orb_false_iff in H
+ | H:context [andb _ _ = true] |- _ => rewrite Bool.andb_true_iff in H
+ | H:context [andb _ _ = false] |- _ => rewrite Bool.andb_false_iff in H
+ | H:context [negb _ = true] |- _ => rewrite Bool.negb_true_iff in H
+ | H:context [negb _ = false] |- _ => rewrite Bool.negb_false_iff in H
+ | H:context [generic_eq _ _ = true] |- _ => apply generic_eq_true in H
+ | H:context [generic_eq _ _ = false] |- _ => apply generic_eq_false in H
+ | H:context [generic_neq _ _ = true] |- _ => apply generic_neq_true in H
+ | H:context [generic_neq _ _ = false] |- _ => apply generic_neq_false in H
+ end.
+
+(* Split up dependent pairs to get at proofs of properties *)
+Ltac extract_properties :=
+ repeat match goal with H := (projT1 ?X) |- _ =>
+ let x := fresh "x" in
+ let Hx := fresh "Hx" in
+ destruct X as [x Hx] in *;
+ change (projT1 (existT _ x Hx)) with x in *; unfold H in * end;
+ repeat match goal with |- context [projT1 ?X] =>
+ let x := fresh "x" in
+ let Hx := fresh "Hx" in
+ destruct X as [x Hx] in *;
+ change (projT1 (existT _ x Hx)) with x in * end.
+(* TODO: hyps, too? *)
+Ltac reduce_list_lengths :=
+ repeat match goal with |- context [length_list ?X] =>
+ let r := (eval cbn in (length_list X)) in
+ change (length_list X) with r
+ end.
+(* TODO: can we restrict this to concrete terms? *)
+Ltac reduce_pow :=
+ repeat match goal with H:context [Z.pow ?X ?Y] |- _ =>
+ let r := (eval cbn in (Z.pow X Y)) in
+ change (Z.pow X Y) with r in H
+ end;
+ repeat match goal with |- context [Z.pow ?X ?Y] =>
+ let r := (eval cbn in (Z.pow X Y)) in
+ change (Z.pow X Y) with r
+ end.
+Ltac dump_context :=
+ repeat match goal with
+ | H:=?X |- _ => idtac H ":=" X; fail
+ | H:?X |- _ => idtac H ":" X; fail end;
+ match goal with |- ?X => idtac "Goal:" X end.
+Ltac prepare_for_solver :=
+(*dump_context;*)
+ clear_irrelevant_defns;
+ clear_non_Z_defns;
+ extract_properties;
+ repeat match goal with w:mword ?n |- _ => apply ArithFact_mword in w end;
+ unwrap_ArithFacts;
+ unfold_In;
+ autounfold with sail in * |- *; (* You can add Hint Unfold ... : sail to let omega see through fns *)
+ unbool_comparisons;
+ reduce_list_lengths;
+ reduce_pow.
+Ltac solve_arithfact :=
+(* Attempt a simple proof first to avoid lengthy preparation steps (especially
+ as the large proof terms can upset subsequent proofs). *)
+try (constructor; omega);
+prepare_for_solver;
+(*dump_context;*)
+ solve
+ [ match goal with |- ArithFact (?x _) => is_evar x; idtac "Warning: unknown constraint"; constructor; exact (I : (fun _ => True) _) end
+ | match goal with |- ArithFact (?x = ?y) =>
+ (is_evar x || is_evar y);
+ (* compute to allow projections to remove proofs that might not be allowed in the evar *)
+ let x := eval cbn in x in
+ let y := eval cbn in y in
+ idtac "Warning: unknown equality constraint"; constructor; exact (eq_refl _ : x = y) end
+ | apply ArithFact_mword; assumption
+ | constructor; omega with Z
+ (* The datatypes hints give us some list handling, esp In *)
+ | constructor; eauto 3 with datatypes zarith sail
+ | constructor; idtac "Unable to solve constraint"; dump_context; fail
+ ].
+(* Add an indirection so that you can redefine run_solver to fail to get
+ slow running constraints into proof mode. *)
+Ltac run_solver := solve_arithfact.
+Hint Extern 0 (ArithFact _) => run_solver : typeclass_instances.
+
+Hint Unfold length_mword : sail.
+
+Definition neq_atom (x : Z) (y : Z) : bool := negb (Z.eqb x y).
+Hint Unfold neq_atom : sail.
+
+Lemma ReasonableSize_witness (a : Z) (w : mword a) : ReasonableSize a.
+constructor.
+destruct a.
+auto with zarith.
+auto using Z.le_ge, Zle_0_pos.
+destruct w.
+Qed.
+
+Hint Extern 0 (ReasonableSize ?A) => (unwrap_ArithFacts; solve [apply ReasonableSize_witness; assumption | constructor; omega]) : typeclass_instances.
+
+Definition to_range (x : Z) : {y : Z & ArithFact (x <= y <= x)} := build_ex x.
+
+
+
+Instance mword_Bitvector {a : Z} `{ArithFact (a >= 0)} : (Bitvector (mword a)) := {
+ bits_of v := List.map bitU_of_bool (bitlistFromWord (get_word v));
+ of_bits v := option_map (fun bl => to_word isPositive (fit_bbv_word (wordFromBitlist bl))) (just_list (List.map bool_of_bitU v));
+ of_bools v := to_word isPositive (fit_bbv_word (wordFromBitlist v));
+ of_int len z := mword_of_int z; (* cheat a little *)
+ length v := a;
+ unsigned v := Some (Z.of_N (wordToN (get_word v)));
+ signed v := Some (wordToZ (get_word v));
+ arith_op_bv op sign l r := mword_of_int (op (int_of_mword sign l) (int_of_mword sign r))
+}.
+
+Section Bitvector_defs.
+Context {a b} `{Bitvector a} `{Bitvector b}.
+
+Definition opt_def {a} (def:a) (v:option a) :=
+match v with
+| Some x => x
+| None => def
+end.
+
+(* The Lem version is partial, but lets go with BU here to avoid constraints for now *)
+Definition access_bv_inc (v : a) n := opt_def BU (access_list_opt_inc (bits_of v) n).
+Definition access_bv_dec (v : a) n := opt_def BU (access_list_opt_dec (bits_of v) n).
+
+Definition update_bv_inc (v : a) n b := update_list true (bits_of v) n b.
+Definition update_bv_dec (v : a) n b := update_list false (bits_of v) n b.
+
+Definition subrange_bv_inc (v : a) i j := subrange_list true (bits_of v) i j.
+Definition subrange_bv_dec (v : a) i j := subrange_list true (bits_of v) i j.
+
+Definition update_subrange_bv_inc (v : a) i j (v' : b) := update_subrange_list true (bits_of v) i j (bits_of v').
+Definition update_subrange_bv_dec (v : a) i j (v' : b) := update_subrange_list false (bits_of v) i j (bits_of v').
+
+(*val extz_bv : forall a b. Bitvector a, Bitvector b => Z -> a -> b*)
+Definition extz_bv n (v : a) : option b := of_bits (extz_bits n (bits_of v)).
+
+(*val exts_bv : forall a b. Bitvector a, Bitvector b => Z -> a -> b*)
+Definition exts_bv n (v : a) : option b := of_bits (exts_bits n (bits_of v)).
+
+(*val string_of_bv : forall a. Bitvector a => a -> string *)
+Definition string_of_bv v := show_bitlist (bits_of v).
+
+End Bitvector_defs.
+
+(*** Bytes and addresses *)
+
+Definition memory_byte := list bitU.
+
+(*val byte_chunks : forall a. list a -> option (list (list a))*)
+Fixpoint byte_chunks {a} (bs : list a) := match bs with
+ | [] => Some []
+ | a::b::c::d::e::f::g::h::rest =>
+ match byte_chunks rest with
+ | None => None
+ | Some rest => Some ([a;b;c;d;e;f;g;h] :: rest)
+ end
+ | _ => None
+end.
+(*declare {isabelle} termination_argument byte_chunks = automatic*)
+
+Section BytesBits.
+Context {a} `{Bitvector a}.
+
+(*val bytes_of_bits : forall a. Bitvector a => a -> option (list memory_byte)*)
+Definition bytes_of_bits (bs : a) := byte_chunks (bits_of bs).
+
+(*val bits_of_bytes : forall a. Bitvector a => list memory_byte -> a*)
+Definition bits_of_bytes (bs : list memory_byte) : list bitU := List.concat (List.map bits_of bs).
+
+Definition mem_bytes_of_bits (bs : a) := option_map (@rev (list bitU)) (bytes_of_bits bs).
+Definition bits_of_mem_bytes (bs : list memory_byte) := bits_of_bytes (List.rev bs).
+
+End BytesBits.
+
+(*val bitv_of_byte_lifteds : list Sail_impl_base.byte_lifted -> list bitU
+Definition bitv_of_byte_lifteds v :=
+ foldl (fun x (Byte_lifted y) => x ++ (List.map bitU_of_bit_lifted y)) [] v
+
+val bitv_of_bytes : list Sail_impl_base.byte -> list bitU
+Definition bitv_of_bytes v :=
+ foldl (fun x (Byte y) => x ++ (List.map bitU_of_bit y)) [] v
+
+val byte_lifteds_of_bitv : list bitU -> list byte_lifted
+Definition byte_lifteds_of_bitv bits :=
+ let bits := List.map bit_lifted_of_bitU bits in
+ byte_lifteds_of_bit_lifteds bits
+
+val bytes_of_bitv : list bitU -> list byte
+Definition bytes_of_bitv bits :=
+ let bits := List.map bit_of_bitU bits in
+ bytes_of_bits bits
+
+val bit_lifteds_of_bitUs : list bitU -> list bit_lifted
+Definition bit_lifteds_of_bitUs bits := List.map bit_lifted_of_bitU bits
+
+val bit_lifteds_of_bitv : list bitU -> list bit_lifted
+Definition bit_lifteds_of_bitv v := bit_lifteds_of_bitUs v
+
+
+val address_lifted_of_bitv : list bitU -> address_lifted
+Definition address_lifted_of_bitv v :=
+ let byte_lifteds := byte_lifteds_of_bitv v in
+ let maybe_address_integer :=
+ match (maybe_all (List.map byte_of_byte_lifted byte_lifteds)) with
+ | Some bs => Some (integer_of_byte_list bs)
+ | _ => None
+ end in
+ Address_lifted byte_lifteds maybe_address_integer
+
+val bitv_of_address_lifted : address_lifted -> list bitU
+Definition bitv_of_address_lifted (Address_lifted bs _) := bitv_of_byte_lifteds bs
+
+val address_of_bitv : list bitU -> address
+Definition address_of_bitv v :=
+ let bytes := bytes_of_bitv v in
+ address_of_byte_list bytes*)
+
+Fixpoint reverse_endianness_list (bits : list bitU) :=
+ match bits with
+ | _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: t =>
+ reverse_endianness_list t ++ firstn 8 bits
+ | _ => bits
+ end.
+
+(*** Registers *)
+
+Definition register_field := string.
+Definition register_field_index : Type := string * (Z * Z). (* name, start and end *)
+
+Inductive register :=
+ | Register : string * (* name *)
+ Z * (* length *)
+ Z * (* start index *)
+ bool * (* is increasing *)
+ list register_field_index
+ -> register
+ | UndefinedRegister : Z -> register (* length *)
+ | RegisterPair : register * register -> register.
+
+Record register_ref regstate regval a :=
+ { name : string;
+ (*is_inc : bool;*)
+ read_from : regstate -> a;
+ write_to : a -> regstate -> regstate;
+ of_regval : regval -> option a;
+ regval_of : a -> regval }.
+Notation "{[ r 'with' 'name' := e ]}" := ({| name := e; read_from := read_from r; write_to := write_to r; of_regval := of_regval r; regval_of := regval_of r |}).
+Notation "{[ r 'with' 'read_from' := e ]}" := ({| read_from := e; name := name r; write_to := write_to r; of_regval := of_regval r; regval_of := regval_of r |}).
+Notation "{[ r 'with' 'write_to' := e ]}" := ({| write_to := e; name := name r; read_from := read_from r; of_regval := of_regval r; regval_of := regval_of r |}).
+Notation "{[ r 'with' 'of_regval' := e ]}" := ({| of_regval := e; name := name r; read_from := read_from r; write_to := write_to r; regval_of := regval_of r |}).
+Notation "{[ r 'with' 'regval_of' := e ]}" := ({| regval_of := e; name := name r; read_from := read_from r; write_to := write_to r; of_regval := of_regval r |}).
+Arguments name [_ _ _].
+Arguments read_from [_ _ _].
+Arguments write_to [_ _ _].
+Arguments of_regval [_ _ _].
+Arguments regval_of [_ _ _].
+
+(* Register accessors: pair of functions for reading and writing register values *)
+Definition register_accessors regstate regval : Type :=
+ ((string -> regstate -> option regval) *
+ (string -> regval -> regstate -> option regstate)).
+
+Record field_ref regtype a :=
+ { field_name : string;
+ field_start : Z;
+ field_is_inc : bool;
+ get_field : regtype -> a;
+ set_field : regtype -> a -> regtype }.
+Arguments field_name [_ _].
+Arguments field_start [_ _].
+Arguments field_is_inc [_ _].
+Arguments get_field [_ _].
+Arguments set_field [_ _].
+
+(*
+(*let name_of_reg := function
+ | Register name _ _ _ _ => name
+ | UndefinedRegister _ => failwith "name_of_reg UndefinedRegister"
+ | RegisterPair _ _ => failwith "name_of_reg RegisterPair"
+end
+
+Definition size_of_reg := function
+ | Register _ size _ _ _ => size
+ | UndefinedRegister size => size
+ | RegisterPair _ _ => failwith "size_of_reg RegisterPair"
+end
+
+Definition start_of_reg := function
+ | Register _ _ start _ _ => start
+ | UndefinedRegister _ => failwith "start_of_reg UndefinedRegister"
+ | RegisterPair _ _ => failwith "start_of_reg RegisterPair"
+end
+
+Definition is_inc_of_reg := function
+ | Register _ _ _ is_inc _ => is_inc
+ | UndefinedRegister _ => failwith "is_inc_of_reg UndefinedRegister"
+ | RegisterPair _ _ => failwith "in_inc_of_reg RegisterPair"
+end
+
+Definition dir_of_reg := function
+ | Register _ _ _ is_inc _ => dir_of_bool is_inc
+ | UndefinedRegister _ => failwith "dir_of_reg UndefinedRegister"
+ | RegisterPair _ _ => failwith "dir_of_reg RegisterPair"
+end
+
+Definition size_of_reg_nat reg := Z.to_nat (size_of_reg reg)
+Definition start_of_reg_nat reg := Z.to_nat (start_of_reg reg)
+
+val register_field_indices_aux : register -> register_field -> option (Z * Z)
+Fixpoint register_field_indices_aux register rfield :=
+ match register with
+ | Register _ _ _ _ rfields => List.lookup rfield rfields
+ | RegisterPair r1 r2 =>
+ let m_indices := register_field_indices_aux r1 rfield in
+ if isSome m_indices then m_indices else register_field_indices_aux r2 rfield
+ | UndefinedRegister _ => None
+ end
+
+val register_field_indices : register -> register_field -> Z * Z
+Definition register_field_indices register rfield :=
+ match register_field_indices_aux register rfield with
+ | Some indices => indices
+ | None => failwith "Invalid register/register-field combination"
+ end
+
+Definition register_field_indices_nat reg regfield=
+ let (i,j) := register_field_indices reg regfield in
+ (Z.to_nat i,Z.to_nat j)*)
+
+(*let rec external_reg_value reg_name v :=
+ let (internal_start, external_start, direction) :=
+ match reg_name with
+ | Reg _ start size dir =>
+ (start, (if dir = D_increasing then start else (start - (size +1))), dir)
+ | Reg_slice _ reg_start dir (slice_start, _) =>
+ ((if dir = D_increasing then slice_start else (reg_start - slice_start)),
+ slice_start, dir)
+ | Reg_field _ reg_start dir _ (slice_start, _) =>
+ ((if dir = D_increasing then slice_start else (reg_start - slice_start)),
+ slice_start, dir)
+ | Reg_f_slice _ reg_start dir _ _ (slice_start, _) =>
+ ((if dir = D_increasing then slice_start else (reg_start - slice_start)),
+ slice_start, dir)
+ end in
+ let bits := bit_lifteds_of_bitv v in
+ <| rv_bits := bits;
+ rv_dir := direction;
+ rv_start := external_start;
+ rv_start_internal := internal_start |>
+
+val internal_reg_value : register_value -> list bitU
+Definition internal_reg_value v :=
+ List.map bitU_of_bit_lifted v.rv_bits
+ (*(Z.of_nat v.rv_start_internal)
+ (v.rv_dir = D_increasing)*)
+
+
+Definition external_slice (d:direction) (start:nat) ((i,j):(nat*nat)) :=
+ match d with
+ (*This is the case the thread/concurrecny model expects, so no change needed*)
+ | D_increasing => (i,j)
+ | D_decreasing => let slice_i = start - i in
+ let slice_j = (i - j) + slice_i in
+ (slice_i,slice_j)
+ end *)
+
+(* TODO
+Definition external_reg_whole r :=
+ Reg (r.name) (Z.to_nat r.start) (Z.to_nat r.size) (dir_of_bool r.is_inc)
+
+Definition external_reg_slice r (i,j) :=
+ let start := Z.to_nat r.start in
+ let dir := dir_of_bool r.is_inc in
+ Reg_slice (r.name) start dir (external_slice dir start (i,j))
+
+Definition external_reg_field_whole reg rfield :=
+ let (m,n) := register_field_indices_nat reg rfield in
+ let start := start_of_reg_nat reg in
+ let dir := dir_of_reg reg in
+ Reg_field (name_of_reg reg) start dir rfield (external_slice dir start (m,n))
+
+Definition external_reg_field_slice reg rfield (i,j) :=
+ let (m,n) := register_field_indices_nat reg rfield in
+ let start := start_of_reg_nat reg in
+ let dir := dir_of_reg reg in
+ Reg_f_slice (name_of_reg reg) start dir rfield
+ (external_slice dir start (m,n))
+ (external_slice dir start (i,j))*)
+
+(*val external_mem_value : list bitU -> memory_value
+Definition external_mem_value v :=
+ byte_lifteds_of_bitv v $> List.reverse
+
+val internal_mem_value : memory_value -> list bitU
+Definition internal_mem_value bytes :=
+ List.reverse bytes $> bitv_of_byte_lifteds*)
+
+
+val foreach : forall a vars.
+ (list a) -> vars -> (a -> vars -> vars) -> vars*)
+Fixpoint foreach {a Vars} (l : list a) (vars : Vars) (body : a -> Vars -> Vars) : Vars :=
+match l with
+| [] => vars
+| (x :: xs) => foreach xs (body x vars) body
+end.
+
+(*declare {isabelle} termination_argument foreach = automatic
+
+val index_list : Z -> Z -> Z -> list Z*)
+Fixpoint index_list' from to step n :=
+ if orb (andb (step >? 0) (from <=? to)) (andb (step <? 0) (to <=? from)) then
+ match n with
+ | O => []
+ | S n => from :: index_list' (from + step) to step n
+ end
+ else [].
+
+Definition index_list from to step :=
+ if orb (andb (step >? 0) (from <=? to)) (andb (step <? 0) (to <=? from)) then
+ index_list' from to step (S (Z.abs_nat (from - to)))
+ else [].
+
+Fixpoint foreach_Z' {Vars} from to step n (vars : Vars) (body : Z -> Vars -> Vars) : Vars :=
+ if orb (andb (step >? 0) (from <=? to)) (andb (step <? 0) (to <=? from)) then
+ match n with
+ | O => vars
+ | S n => let vars := body from vars in foreach_Z' (from + step) to step n vars body
+ end
+ else vars.
+
+Definition foreach_Z {Vars} from to step vars body :=
+ foreach_Z' (Vars := Vars) from to step (S (Z.abs_nat (from - to))) vars body.
+
+Fixpoint foreach_Z_up' {Vars} from to step off n `{ArithFact (0 < step)} `{ArithFact (0 <= off)} (vars : Vars) (body : forall (z : Z) `(ArithFact (from <= z <= to)), Vars -> Vars) {struct n} : Vars :=
+ if sumbool_of_bool (from + off <=? to) then
+ match n with
+ | O => vars
+ | S n => let vars := body (from + off) _ vars in foreach_Z_up' from to step (off + step) n vars body
+ end
+ else vars.
+
+Fixpoint foreach_Z_down' {Vars} from to step off n `{ArithFact (0 < step)} `{ArithFact (off <= 0)} (vars : Vars) (body : forall (z : Z) `(ArithFact (to <= z <= from)), Vars -> Vars) {struct n} : Vars :=
+ if sumbool_of_bool (to <=? from + off) then
+ match n with
+ | O => vars
+ | S n => let vars := body (from + off) _ vars in foreach_Z_down' from to step (off - step) n vars body
+ end
+ else vars.
+
+Definition foreach_Z_up {Vars} from to step vars body `{ArithFact (0 < step)} :=
+ foreach_Z_up' (Vars := Vars) from to step 0 (S (Z.abs_nat (from - to))) vars body.
+Definition foreach_Z_down {Vars} from to step vars body `{ArithFact (0 < step)} :=
+ foreach_Z_down' (Vars := Vars) from to step 0 (S (Z.abs_nat (from - to))) vars body.
+
+(*val while : forall vars. vars -> (vars -> bool) -> (vars -> vars) -> vars
+Fixpoint while vars cond body :=
+ if cond vars then while (body vars) cond body else vars
+
+val until : forall vars. vars -> (vars -> bool) -> (vars -> vars) -> vars
+Fixpoint until vars cond body :=
+ let vars := body vars in
+ if cond vars then vars else until (body vars) cond body
+
+
+Definition assert' b msg_opt :=
+ let msg := match msg_opt with
+ | Some msg => msg
+ | None => "unspecified error"
+ end in
+ if b then () else failwith msg
+
+(* convert numbers unsafely to naturals *)
+
+class (ToNatural a) val toNatural : a -> natural end
+(* eta-expanded for Isabelle output, otherwise it breaks *)
+instance (ToNatural Z) let toNatural := (fun n => naturalFromInteger n) end
+instance (ToNatural int) let toNatural := (fun n => naturalFromInt n) end
+instance (ToNatural nat) let toNatural := (fun n => naturalFromNat n) end
+instance (ToNatural natural) let toNatural := (fun n => n) end
+
+Definition toNaturalFiveTup (n1,n2,n3,n4,n5) :=
+ (toNatural n1,
+ toNatural n2,
+ toNatural n3,
+ toNatural n4,
+ toNatural n5)
+
+(* Let the following types be generated by Sail per spec, using either bitlists
+ or machine words as bitvector representation *)
+(*type regfp :=
+ | RFull of (string)
+ | RSlice of (string * Z * Z)
+ | RSliceBit of (string * Z)
+ | RField of (string * string)
+
+type niafp :=
+ | NIAFP_successor
+ | NIAFP_concrete_address of vector bitU
+ | NIAFP_indirect_address
+
+(* only for MIPS *)
+type diafp :=
+ | DIAFP_none
+ | DIAFP_concrete of vector bitU
+ | DIAFP_reg of regfp
+
+Definition regfp_to_reg (reg_info : string -> option string -> (nat * nat * direction * (nat * nat))) := function
+ | RFull name =>
+ let (start,length,direction,_) := reg_info name None in
+ Reg name start length direction
+ | RSlice (name,i,j) =>
+ let i = Z.to_nat i in
+ let j = Z.to_nat j in
+ let (start,length,direction,_) = reg_info name None in
+ let slice = external_slice direction start (i,j) in
+ Reg_slice name start direction slice
+ | RSliceBit (name,i) =>
+ let i = Z.to_nat i in
+ let (start,length,direction,_) = reg_info name None in
+ let slice = external_slice direction start (i,i) in
+ Reg_slice name start direction slice
+ | RField (name,field_name) =>
+ let (start,length,direction,span) = reg_info name (Some field_name) in
+ let slice = external_slice direction start span in
+ Reg_field name start direction field_name slice
+end
+
+Definition niafp_to_nia reginfo = function
+ | NIAFP_successor => NIA_successor
+ | NIAFP_concrete_address v => NIA_concrete_address (address_of_bitv v)
+ | NIAFP_indirect_address => NIA_indirect_address
+end
+
+Definition diafp_to_dia reginfo = function
+ | DIAFP_none => DIA_none
+ | DIAFP_concrete v => DIA_concrete_address (address_of_bitv v)
+ | DIAFP_reg r => DIA_register (regfp_to_reg reginfo r)
+end
+*)
+*)
+
+(* Arithmetic functions which return proofs that match the expected Sail
+ types in smt.sail. *)
+
+Definition div_with_eq n m : {o : Z & ArithFact (o = Z.quot n m)} := build_ex (Z.quot n m).
+Definition mod_with_eq n m : {o : Z & ArithFact (o = Z.rem n m)} := build_ex (Z.rem n m).
+Definition abs_with_eq n : {o : Z & ArithFact (o = Z.abs n)} := build_ex (Z.abs n).
+
+(* Similarly, for ranges (currently in MIPS) *)
+
+Definition eq_range {n m o p} (l : {l & ArithFact (n <= l <= m)}) (r : {r & ArithFact (o <= r <= p)}) : bool :=
+ (projT1 l) =? (projT1 r).
+Definition add_range {n m o p} (l : {l & ArithFact (n <= l <= m)}) (r : {r & ArithFact (o <= r <= p)})
+ : {x & ArithFact (n+o <= x <= m+p)} :=
+ build_ex ((projT1 l) + (projT1 r)).
+Definition sub_range {n m o p} (l : {l & ArithFact (n <= l <= m)}) (r : {r & ArithFact (o <= r <= p)})
+ : {x & ArithFact (n-p <= x <= m-o)} :=
+ build_ex ((projT1 l) - (projT1 r)).
+Definition negate_range {n m} (l : {l : Z & ArithFact (n <= l <= m)})
+ : {x : Z & ArithFact ((- m) <= x <= (- n))} :=
+ build_ex (- (projT1 l)).
+
+Definition min_atom (a : Z) (b : Z) : {c : Z & ArithFact (c = a \/ c = b /\ c <= a /\ c <= b)} :=
+ build_ex (Z.min a b).
+Definition max_atom (a : Z) (b : Z) : {c : Z & ArithFact (c = a \/ c = b /\ c >= a /\ c >= b)} :=
+ build_ex (Z.max a b).
+
+
+(*** Generic vectors *)
+
+Definition vec (T:Type) (n:Z) := { l : list T & length_list l = n }.
+Definition vec_length {T n} (v : vec T n) := n.
+Definition vec_access_dec {T n} (v : vec T n) m `{ArithFact (0 <= m < n)} : T :=
+ access_list_dec (projT1 v) m.
+Definition vec_access_inc {T n} (v : vec T n) m `{ArithFact (0 <= m < n)} : T :=
+ access_list_inc (projT1 v) m.
+
+Program Definition vec_init {T} (t : T) (n : Z) `{ArithFact (n >= 0)} : vec T n :=
+ existT _ (repeat [t] n) _.
+Next Obligation.
+rewrite repeat_length; auto using fact.
+unfold length_list.
+simpl.
+auto with zarith.
+Qed.
+
+Lemma skipn_length {A n} {l: list A} : (n <= List.length l -> List.length (skipn n l) = List.length l - n)%nat.
+revert l.
+induction n.
+* simpl. auto with arith.
+* intros l H.
+ destruct l.
+ + inversion H.
+ + simpl in H.
+ simpl.
+ rewrite IHn; auto with arith.
+Qed.
+Lemma update_list_inc_length {T} {l:list T} {m x} : 0 <= m < length_list l -> length_list (update_list_inc l m x) = length_list l.
+unfold update_list_inc, list_update, length_list.
+intro H.
+f_equal.
+assert ((0 <= Z.to_nat m < Datatypes.length l)%nat).
+{ destruct H as [H1 H2].
+ split.
+ + change 0%nat with (Z.to_nat 0).
+ apply Z2Nat.inj_le; auto with zarith.
+ + rewrite <- Nat2Z.id.
+ apply Z2Nat.inj_lt; auto with zarith.
+}
+rewrite app_length.
+rewrite firstn_length_le; only 2:omega.
+cbn -[skipn].
+rewrite skipn_length;
+omega.
+Qed.
+
+Program Definition vec_update_dec {T n} (v : vec T n) m t `{ArithFact (0 <= m < n)} : vec T n := existT _ (update_list_dec (projT1 v) m t) _.
+Next Obligation.
+unfold update_list_dec.
+rewrite update_list_inc_length.
++ destruct v. apply e.
++ destruct H.
+ destruct v. simpl (projT1 _). rewrite e.
+ omega.
+Qed.
+
+Program Definition vec_update_inc {T n} (v : vec T n) m t `{ArithFact (0 <= m < n)} : vec T n := existT _ (update_list_inc (projT1 v) m t) _.
+Next Obligation.
+rewrite update_list_inc_length.
++ destruct v. apply e.
++ destruct H.
+ destruct v. simpl (projT1 _). rewrite e.
+ omega.
+Qed.
+
+Program Definition vec_map {S T} (f : S -> T) {n} (v : vec S n) : vec T n := existT _ (List.map f (projT1 v)) _.
+Next Obligation.
+destruct v as [l H].
+cbn.
+unfold length_list.
+rewrite map_length.
+apply H.
+Qed.
+
+Program Definition just_vec {A n} (v : vec (option A) n) : option (vec A n) :=
+ match just_list (projT1 v) with
+ | None => None
+ | Some v' => Some (existT _ v' _)
+ end.
+Next Obligation.
+rewrite <- (just_list_length_Z _ _ Heq_anonymous).
+destruct v.
+assumption.
+Qed.
+
+Definition list_of_vec {A n} (v : vec A n) : list A := projT1 v.
+
+Program Definition vec_of_list {A} n (l : list A) : option (vec A n) :=
+ if sumbool_of_bool (n =? length_list l) then Some (existT _ l _) else None.
+Next Obligation.
+symmetry.
+apply Z.eqb_eq.
+assumption.
+Qed.
+
+Definition vec_of_list_len {A} (l : list A) : vec A (length_list l) := existT _ l (eq_refl _).
+
+Definition map_bind {A B} (f : A -> option B) (a : option A) : option B :=
+match a with
+| Some a' => f a'
+| None => None
+end.
+
+Definition sub_nat (x : {x : Z & ArithFact (x >= 0)}) (y : {y : Z & ArithFact (y >= 0)}) :
+ {z : Z & ArithFact (z >= 0)} :=
+ let z := projT1 x - projT1 y in
+ if sumbool_of_bool (z >=? 0) then build_ex z else build_ex 0.
diff --git a/snapshots/coq-riscv/sail/lib/coq/_CoqProject b/snapshots/coq-riscv/sail/lib/coq/_CoqProject
new file mode 100644
index 00000000..9f5d26b8
--- /dev/null
+++ b/snapshots/coq-riscv/sail/lib/coq/_CoqProject
@@ -0,0 +1,2 @@
+-R . Sail
+-R ../../../bbv/theories bbv
diff --git a/snapshots/coq-riscv/sail/riscv/coq.patch b/snapshots/coq-riscv/sail/riscv/coq.patch
new file mode 100644
index 00000000..cd7ad6b3
--- /dev/null
+++ b/snapshots/coq-riscv/sail/riscv/coq.patch
@@ -0,0 +1,431 @@
+--- riscv.v.orig 2018-08-15 11:35:48.766557392 +0100
++++ riscv.v 2018-08-15 11:36:59.395492502 +0100
+@@ -7712,14 +7712,13 @@
+ returnm ((EXTZ 56 (shiftl (_get_Satp64_PPN satp64) PAGESIZE_BITS))
+ : mword 56).
+
+-Fixpoint walk39 (vaddr : mword 39) (ac : AccessType) (priv : Privilege) (mxr : bool) (do_sum : bool) (ptb : mword 56) '((existT _ level _) : {n : Z & ArithFact (n >=
+- 0)}) (global : bool)
++Fixpoint walk39 (vaddr : mword 39) (ac : AccessType) (priv : Privilege) (mxr : bool) (do_sum : bool) (ptb : mword 56) (level : nat) (global : bool)
+ : M (PTW_Result) :=
+ let va := Mk_SV39_Vaddr vaddr in
+ let pt_ofs : paddr39 :=
+ shiftl
+ (EXTZ 56
+- (subrange_vec_dec (shiftr (_get_SV39_Vaddr_VPNi va) (Z.mul level SV39_LEVEL_BITS))
++ (subrange_vec_dec (shiftr (_get_SV39_Vaddr_VPNi va) (Z.mul (Z.of_nat level) SV39_LEVEL_BITS))
+ (projT1 (sub_range (build_ex SV39_LEVEL_BITS) (build_ex 1))) 0)) PTE39_LOG_SIZE in
+ let pte_addr := add_vec ptb pt_ofs in
+ phys_mem_read Data (EXTZ 64 pte_addr) 8 false false false >>= fun w__0 : MemoryOpResult (mword 64) =>
+@@ -7732,26 +7731,26 @@
+ let is_global := orb global (eq_vec (_get_PTE_Bits_G pattr) ((bool_to_bits true) : mword 1)) in
+ (if ((isInvalidPTE pbits)) then returnm ((PTW_Failure PTW_Invalid_PTE) : PTW_Result)
+ else if ((isPTEPtr pbits)) then
+- (if sumbool_of_bool ((Z.eqb level 0)) then
++ (match level with | O =>
+ returnm ((PTW_Failure PTW_Invalid_PTE)
+ : PTW_Result)
+- else
++ | S level' =>
+ (walk39 vaddr ac priv mxr do_sum
+ (EXTZ 56 (shiftl (_get_SV39_PTE_PPNi pte) PAGESIZE_BITS))
+- (build_ex (projT1 (sub_range (build_ex level) (build_ex 1)))) is_global)
+- : M (PTW_Result))
++ level' is_global)
++ : M (PTW_Result) end)
+ : M (PTW_Result)
+ else
+ checkPTEPermission ac priv mxr do_sum pattr >>= fun w__3 : bool =>
+ returnm ((if ((negb w__3)) then PTW_Failure PTW_No_Permission
+- else if sumbool_of_bool ((Z.gtb level 0)) then
++ else if sumbool_of_bool (Nat.ltb O level) then
+ let mask :=
+ sub_vec_int
+ (shiftl
+ (xor_vec (_get_SV39_PTE_PPNi pte)
+ (xor_vec (_get_SV39_PTE_PPNi pte)
+ (EXTZ 44 (vec_of_bits [B1] : mword 1))))
+- (Z.mul level SV39_LEVEL_BITS)) 1 in
++ (Z.mul (Z.of_nat level) SV39_LEVEL_BITS)) 1 in
+ if ((neq_vec (and_vec (_get_SV39_PTE_PPNi pte) mask)
+ (EXTZ 44 (vec_of_bits [B0] : mword 1)))) then
+ PTW_Failure PTW_Misaligned
+@@ -7760,15 +7759,18 @@
+ or_vec (_get_SV39_PTE_PPNi pte)
+ (and_vec (EXTZ 44 (_get_SV39_Vaddr_VPNi va)) mask) in
+ PTW_Success (concat_vec ppn (_get_SV39_Vaddr_PgOfs va),pte,pte_addr,build_ex
+- level,is_global)
++ (Z.of_nat level),is_global)
+ else
+ PTW_Success (concat_vec (_get_SV39_PTE_PPNi pte) (_get_SV39_Vaddr_PgOfs va),pte,pte_addr,build_ex
+- level,is_global))
++ (Z.of_nat level),is_global))
+ : PTW_Result))
+ : M (PTW_Result)
+ end)
+ : M (PTW_Result).
+
++Hint Unfold PAGESIZE_BITS : sail.
++Hint Unfold SV39_LEVEL_BITS : sail.
++
+ Definition make_TLB39_Entry (asid : mword 16) (global : bool) (vAddr : mword 39) (pAddr : mword 56) (pte : SV39_PTE) '((existT _ level _) : {n : Z & ArithFact (n >=
+ 0)}) (pteAddr : mword 56)
+ : M (TLB39_Entry) :=
+@@ -7884,7 +7886,7 @@
+ : M (TR39_Result)
+ | None =>
+ curPTB39 tt >>= fun w__6 : mword 56 =>
+- walk39 vAddr ac priv mxr do_sum w__6 (build_ex level) false >>= fun w__7 : PTW_Result =>
++ walk39 vAddr ac priv mxr do_sum w__6 (Z.to_nat level) false >>= fun w__7 : PTW_Result =>
+ (match w__7 with
+ | PTW_Failure (f) => returnm ((TR39_Failure f) : TR39_Result)
+ | PTW_Success (pAddr,pte,pteAddr,(existT _ level _),global) =>
+@@ -7961,7 +7963,7 @@
+ | Sbare => returnm ((TR_Address vAddr) : TR_Result)
+ | SV39 =>
+ translate39 (subrange_vec_dec vAddr 38 0) ac effPriv mxr do_sum
+- (build_ex (projT1 (sub_range (build_ex SV39_LEVELS) (build_ex 1)))) >>= fun w__7 : TR39_Result =>
++ (build_ex ( (Z.sub ( SV39_LEVELS) ( 1)))) >>= fun w__7 : TR39_Result =>
+ returnm ((match w__7 with
+ | TR39_Address (pa) => TR_Address (EXTZ 64 pa)
+ | TR39_Failure (f) => TR_Failure (translationException ac f)
+@@ -10867,11 +10869,11 @@
+ (match width with
+ | WORD =>
+ mem_read addr 4 aq rl true >>= fun w__2 : MemoryOpResult (mword 32) =>
+- (process_loadres rd vaddr w__2 false)
++ (process_loadres (n := 4) rd vaddr w__2 false)
+ : M (bool)
+ | DOUBLE =>
+ mem_read addr 8 aq rl true >>= fun w__4 : MemoryOpResult (mword 64) =>
+- (process_loadres rd vaddr w__4 false)
++ (process_loadres (n := 8) rd vaddr w__4 false)
+ : M (bool)
+ | _ => (internal_error "LOADRES expected WORD or DOUBLE") : M (bool)
+ end)
+@@ -10894,19 +10896,19 @@
+ (match width with
+ | BYTE =>
+ mem_read addr 1 aq rl false >>= fun w__3 : MemoryOpResult (mword 8) =>
+- (process_load rd vaddr w__3 is_unsigned)
++ (process_load (n := 1) rd vaddr w__3 is_unsigned)
+ : M (bool)
+ | HALF =>
+ mem_read addr 2 aq rl false >>= fun w__5 : MemoryOpResult (mword 16) =>
+- (process_load rd vaddr w__5 is_unsigned)
++ (process_load (n := 2) rd vaddr w__5 is_unsigned)
+ : M (bool)
+ | WORD =>
+ mem_read addr 4 aq rl false >>= fun w__7 : MemoryOpResult (mword 32) =>
+- (process_load rd vaddr w__7 is_unsigned)
++ (process_load (n := 4) rd vaddr w__7 is_unsigned)
+ : M (bool)
+ | DOUBLE =>
+ mem_read addr 8 aq rl false >>= fun w__9 : MemoryOpResult (mword 64) =>
+- (process_load rd vaddr w__9 is_unsigned)
++ (process_load (n := 8) rd vaddr w__9 is_unsigned)
+ : M (bool)
+ end)
+ : M (bool)
+@@ -11023,7 +11025,7 @@
+ if sumbool_of_bool ((andb s
+ (Z.gtb q (projT1 (sub_range (build_ex (projT1 (pow2 31))) (build_ex 1))))))
+ then
+- projT1 (sub_range (build_ex 0) ((ex_int (pow 2 31)) : {n : Z & ArithFact (True)}))
++ (Z.sub ( 0) ((pow 2 31)))
+ else q in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTS 64 (to_bits 32 q')) >>
+@@ -11127,11 +11129,11 @@
+ match width with
+ | WORD =>
+ mem_read addr 4 aq (andb aq rl) true >>= fun w__4 : MemoryOpResult (mword 32) =>
+- returnm ((extend_value false w__4)
++ returnm ((extend_value (n := 4) false w__4)
+ : MemoryOpResult xlenbits)
+ | DOUBLE =>
+ mem_read addr 8 aq (andb aq rl) true >>= fun w__5 : MemoryOpResult (mword 64) =>
+- returnm ((extend_value false w__5)
++ returnm ((extend_value (n := 8) false w__5)
+ : MemoryOpResult xlenbits)
+ | _ => (internal_error "AMO expected WORD or DOUBLE") : M (MemoryOpResult xlenbits)
+ end >>= fun rval : MemoryOpResult xlenbits =>
+@@ -11193,134 +11195,140 @@
+ returnm (true
+ : bool).
+
+-Fixpoint execute (merge_var : ast)
+-: M (bool) :=
+- match merge_var with
++Definition expand_ast (i : ast) : ast :=
++match i with
+ | C_ADDI4SPN (rdc,nzimm) =>
+ let imm : bits 12 :=
+ concat_vec (vec_of_bits [B0;B0] : mword 2)
+ (concat_vec nzimm (vec_of_bits [B0;B0] : mword 2)) in
+ let rd := creg2reg_bits rdc in
+- (execute (ITYPE (imm,sp,rd,RISCV_ADDI)))
+- : M (bool)
++ ( (ITYPE (imm,sp,rd,RISCV_ADDI)))
++
+ | C_LW (uimm,rsc,rdc) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0] : mword 2)) in
+ let rd := creg2reg_bits rdc in
+ let rs := creg2reg_bits rsc in
+- (execute (LOAD (imm,rs,rd,false,WORD,false,false)))
+- : M (bool)
++ ( (LOAD (imm,rs,rd,false,WORD,false,false)))
++
+ | C_LD (uimm,rsc,rdc) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0;B0] : mword 3)) in
+ let rd := creg2reg_bits rdc in
+ let rs := creg2reg_bits rsc in
+- (execute (LOAD (imm,rs,rd,false,DOUBLE,false,false)))
+- : M (bool)
++ ( (LOAD (imm,rs,rd,false,DOUBLE,false,false)))
++
+ | C_SW (uimm,rsc1,rsc2) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0] : mword 2)) in
+ let rs1 := creg2reg_bits rsc1 in
+ let rs2 := creg2reg_bits rsc2 in
+- (execute (STORE (imm,rs2,rs1,WORD,false,false)))
+- : M (bool)
++ ( (STORE (imm,rs2,rs1,WORD,false,false)))
++
+ | C_SD (uimm,rsc1,rsc2) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0;B0] : mword 3)) in
+ let rs1 := creg2reg_bits rsc1 in
+ let rs2 := creg2reg_bits rsc2 in
+- (execute (STORE (imm,rs2,rs1,DOUBLE,false,false)))
+- : M (bool)
++ ( (STORE (imm,rs2,rs1,DOUBLE,false,false)))
++
+ | C_ADDI (nzi,rsd) =>
+ let imm : bits 12 := EXTS 12 nzi in
+- (execute (ITYPE (imm,rsd,rsd,RISCV_ADDI)))
+- : M (bool)
++ ( (ITYPE (imm,rsd,rsd,RISCV_ADDI)))
++
+ | C_JAL (imm) =>
+- (execute (RISCV_JAL (EXTS 21 (concat_vec imm (vec_of_bits [B0] : mword 1)),ra))) : M (bool)
++ ( (RISCV_JAL (EXTS 21 (concat_vec imm (vec_of_bits [B0] : mword 1)),ra)))
+ | C_LI (imm,rd) =>
+ let imm : bits 12 := EXTS 12 imm in
+- (execute (ITYPE (imm,zreg,rd,RISCV_ADDI)))
+- : M (bool)
++ ( (ITYPE (imm,zreg,rd,RISCV_ADDI)))
++
+ | C_ADDI16SP (imm) =>
+ let imm : bits 12 := EXTS 12 (concat_vec imm (vec_of_bits [B0;B0;B0;B0] : mword 4)) in
+- (execute (ITYPE (imm,sp,sp,RISCV_ADDI)))
+- : M (bool)
++ ( (ITYPE (imm,sp,sp,RISCV_ADDI)))
++
+ | C_LUI (imm,rd) =>
+ let res : bits 20 := EXTS 20 imm in
+- (execute (UTYPE (res,rd,RISCV_LUI)))
+- : M (bool)
++ ( (UTYPE (res,rd,RISCV_LUI)))
++
+ | C_SRLI (shamt,rsd) =>
+ let rsd := creg2reg_bits rsd in
+- (execute (SHIFTIOP (shamt,rsd,rsd,RISCV_SRLI)))
+- : M (bool)
++ ( (SHIFTIOP (shamt,rsd,rsd,RISCV_SRLI)))
++
+ | C_SRAI (shamt,rsd) =>
+ let rsd := creg2reg_bits rsd in
+- (execute (SHIFTIOP (shamt,rsd,rsd,RISCV_SRAI)))
+- : M (bool)
++ ( (SHIFTIOP (shamt,rsd,rsd,RISCV_SRAI)))
++
+ | C_ANDI (imm,rsd) =>
+ let rsd := creg2reg_bits rsd in
+- (execute (ITYPE (EXTS 12 imm,rsd,rsd,RISCV_ANDI)))
+- : M (bool)
++ ( (ITYPE (EXTS 12 imm,rsd,rsd,RISCV_ANDI)))
++
+ | C_SUB (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+- (execute (RTYPE (rs2,rsd,rsd,RISCV_SUB)))
+- : M (bool)
++ ( (RTYPE (rs2,rsd,rsd,RISCV_SUB)))
++
+ | C_XOR (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+- (execute (RTYPE (rs2,rsd,rsd,RISCV_XOR)))
+- : M (bool)
++ ( (RTYPE (rs2,rsd,rsd,RISCV_XOR)))
++
+ | C_OR (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+- (execute (RTYPE (rs2,rsd,rsd,RISCV_OR)))
+- : M (bool)
++ ( (RTYPE (rs2,rsd,rsd,RISCV_OR)))
++
+ | C_AND (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+- (execute (RTYPE (rs2,rsd,rsd,RISCV_AND)))
+- : M (bool)
++ ( (RTYPE (rs2,rsd,rsd,RISCV_AND)))
++
+ | C_SUBW (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+- (execute (RTYPEW (rs2,rsd,rsd,RISCV_SUBW)))
+- : M (bool)
++ ( (RTYPEW (rs2,rsd,rsd,RISCV_SUBW)))
++
+ | C_ADDW (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+- (execute (RTYPEW (rs2,rsd,rsd,RISCV_ADDW)))
+- : M (bool)
++ ( (RTYPEW (rs2,rsd,rsd,RISCV_ADDW)))
++
+ | C_J (imm) =>
+- (execute (RISCV_JAL (EXTS 21 (concat_vec imm (vec_of_bits [B0] : mword 1)),zreg)))
+- : M (bool)
++ ( (RISCV_JAL (EXTS 21 (concat_vec imm (vec_of_bits [B0] : mword 1)),zreg)))
++
+ | C_BEQZ (imm,rs) =>
+- (execute
++ (
+ (BTYPE (EXTS 13 (concat_vec imm (vec_of_bits [B0] : mword 1)),zreg,creg2reg_bits rs,RISCV_BEQ)))
+- : M (bool)
++
+ | C_BNEZ (imm,rs) =>
+- (execute
++ (
+ (BTYPE (EXTS 13 (concat_vec imm (vec_of_bits [B0] : mword 1)),zreg,creg2reg_bits rs,RISCV_BNE)))
+- : M (bool)
+- | C_SLLI (shamt,rsd) => (execute (SHIFTIOP (shamt,rsd,rsd,RISCV_SLLI))) : M (bool)
++
++ | C_SLLI (shamt,rsd) => ( (SHIFTIOP (shamt,rsd,rsd,RISCV_SLLI)))
+ | C_LWSP (uimm,rd) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0] : mword 2)) in
+- (execute (LOAD (imm,sp,rd,false,WORD,false,false)))
+- : M (bool)
++ ( (LOAD (imm,sp,rd,false,WORD,false,false)))
++
+ | C_LDSP (uimm,rd) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0;B0] : mword 3)) in
+- (execute (LOAD (imm,sp,rd,false,DOUBLE,false,false)))
+- : M (bool)
++ ( (LOAD (imm,sp,rd,false,DOUBLE,false,false)))
++
+ | C_SWSP (uimm,rs2) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0] : mword 2)) in
+- (execute (STORE (imm,rs2,sp,WORD,false,false)))
+- : M (bool)
++ ( (STORE (imm,rs2,sp,WORD,false,false)))
++
+ | C_SDSP (uimm,rs2) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0;B0] : mword 3)) in
+- (execute (STORE (imm,rs2,sp,DOUBLE,false,false)))
+- : M (bool)
++ ( (STORE (imm,rs2,sp,DOUBLE,false,false)))
++
+ | C_JR (rs1) =>
+- (execute (RISCV_JALR (EXTZ 12 (vec_of_bits [B0] : mword 1),rs1,zreg))) : M (bool)
++ ( (RISCV_JALR (EXTZ 12 (vec_of_bits [B0] : mword 1),rs1,zreg)))
+ | C_JALR (rs1) =>
+- (execute (RISCV_JALR (EXTZ 12 (vec_of_bits [B0] : mword 1),rs1,ra))) : M (bool)
+- | C_MV (rd,rs2) => (execute (RTYPE (rs2,zreg,rd,RISCV_ADD))) : M (bool)
+- | C_ADD (rsd,rs2) => (execute (RTYPE (rs2,rsd,rsd,RISCV_ADD))) : M (bool)
++ ( (RISCV_JALR (EXTZ 12 (vec_of_bits [B0] : mword 1),rs1,ra)))
++ | C_MV (rd,rs2) => ( (RTYPE (rs2,zreg,rd,RISCV_ADD)))
++ | C_ADD (rsd,rs2) => ( (RTYPE (rs2,rsd,rsd,RISCV_ADD)))
++| _ => i
++end.
++
++Fixpoint execute (merge_var : ast)
++: M (bool) :=
++let merge_var := expand_ast merge_var in
++ match merge_var with
+ | UTYPE (imm,rd,op) => (execute_UTYPE imm rd op) : M (bool)
+ | RISCV_JAL (imm,rd) => (execute_RISCV_JAL imm rd) : M (bool)
+ | RISCV_JALR (imm,rs1,rd) => (execute_RISCV_JALR imm rs1 rd) : M (bool)
+@@ -11360,6 +11368,7 @@
+ | THREAD_START (g__29) => returnm ((execute_THREAD_START g__29) : bool)
+ | ILLEGAL (s) => (execute_ILLEGAL s) : M (bool)
+ | C_ILLEGAL (g__30) => (execute_C_ILLEGAL g__30) : M (bool)
++| _ => Fail "Unexpanded instruction"
+ end.
+
+ Definition assembly_forwards (arg_ : ast)
+@@ -11622,7 +11631,7 @@
+ | _ => exit tt : M (string)
+ end)
+ : M (string).
+-
++(*
+ Definition assembly_backwards (arg_ : string)
+ : M (ast) :=
+ let _stringappend_1112_ := arg_ in
+@@ -29689,7 +29698,7 @@
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))).
+-
++*)
+ Definition encdec_forwards (arg_ : ast)
+ : M (mword 32) :=
+ (match arg_ with
+@@ -31899,7 +31908,7 @@
+ : M ((bool * bool))
+ end)
+ : M ((bool * bool)).
+-
++(*
+ Definition loop '(tt : unit)
+ : M (unit) :=
+ let insns_per_tick := plat_insns_per_tick tt in
+@@ -31938,7 +31947,7 @@
+ returnm (i, step_no))) >>= fun '(i, step_no) =>
+ returnm (tt
+ : unit).
+-
++*)
+ Definition read_kind_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 11)}
+ : read_kind :=
+ let p0_ := arg_ in
+@@ -32029,7 +32038,7 @@
+ else if sumbool_of_bool ((Z.eqb p0_ 20)) then Barrier_RISCV_w_r
+ else if sumbool_of_bool ((Z.eqb p0_ 21)) then Barrier_RISCV_i
+ else Barrier_x86_MFENCE.
+-
++(*
+ Definition num_of_barrier_kind (arg_ : barrier_kind)
+ : {e : Z & ArithFact (0 <= e /\ e <= 22)} :=
+ match arg_ with
+@@ -32057,7 +32066,7 @@
+ | Barrier_RISCV_i => build_ex 21
+ | Barrier_x86_MFENCE => build_ex 22
+ end.
+-
++*)
+ Definition trans_kind_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 2)}
+ : trans_kind :=
+ let p0_ := arg_ in
+@@ -32078,6 +32087,7 @@
+ "x10";"x9";"x8";"x7";"x6";"x5";"x4";"x3";"x2";"x1";"x0"].
+ Let CIA_fp := RFull "CIA".
+ Let NIA_fp := RFull "NIA".
++(*
+ Definition initial_analysis (instr : ast)
+ : M ((list regfp * list regfp * list regfp * list niafp * diafp * instruction_kind)) :=
+ let iR := [] : regfps in
+@@ -32602,7 +32612,7 @@
+ end >>= fun '(Nias, aR, iR, ik, oR) =>
+ returnm ((iR, oR, aR, Nias, Dia, ik)
+ : (list regfp * list regfp * list regfp * list niafp * diafp * instruction_kind)).
+-
++*)
+ Let initial_regstate : regstate :=
+ {| tlb39 := None;
+ htif_exit_code :=
diff --git a/snapshots/coq-riscv/sail/riscv/riscv.v b/snapshots/coq-riscv/sail/riscv/riscv.v
new file mode 100644
index 00000000..86296adb
--- /dev/null
+++ b/snapshots/coq-riscv/sail/riscv/riscv.v
@@ -0,0 +1,33165 @@
+(*Generated by Sail from riscv.*)
+Require Import Sail2_instr_kinds.
+Require Import Sail2_values.
+Require Import Sail2_string.
+Require Import Sail2_operators_mwords.
+Require Import Sail2_prompt_monad.
+Require Import Sail2_prompt.
+Require Import Sail2_state.
+Require Import riscv_types.
+Require Import riscv_extras.
+Import ListNotations.
+Open Scope string.
+Open Scope bool.
+Section Content.
+
+Definition spc_forwards '(tt : unit) : string := " ".
+
+Definition spc_backwards (s : string) : unit := tt.
+
+Definition opt_spc_forwards '(tt : unit) : string := "".
+
+Definition opt_spc_backwards (s : string) : unit := tt.
+
+Definition def_spc_forwards '(tt : unit) : string := " ".
+
+Definition def_spc_backwards (s : string) : unit := tt.
+
+Axiom eq_real : forall (_ : real) (_ : real) , bool.
+
+Axiom vcons : forall {n : Z} {a : Type} (_ : a) (_ : vec a n) , vec a (n + 1).
+
+Axiom vector_concat : forall {n : Z} {m : Z} {a : Type} (_ : vec a n) (_ : vec a m) , vec a (n + m).
+
+Definition neq_atom (x : Z) (y : Z) : bool := negb (Z.eqb x y).
+
+Definition neq_int (x : Z) (y : Z) : bool := negb (Z.eqb x y).
+
+Definition neq_vec {n : Z} (x : mword n) (y : mword n) : bool := negb (eq_vec x y).
+
+
+
+Axiom builtin_and_vec : forall {n : Z} (_ : bits n) (_ : bits n) , bits n.
+
+
+
+Axiom builtin_or_vec : forall {n : Z} (_ : bits n) (_ : bits n) , bits n.
+
+
+
+Axiom __raw_SetSlice_int : forall (w : Z) (_ : Z) (_ : Z) (_ : bits w) , Z.
+
+Definition __GetSlice_int (n : Z) (m : Z) (o : Z) `{ArithFact (n >= 0)}
+: mword n :=
+ get_slice_int n m o.
+
+Axiom __raw_SetSlice_bits : forall (n : Z) (w : Z) (_ : bits n) (_ : Z) (_ : bits w) , bits n.
+
+Axiom __raw_GetSlice_bits : forall
+
+(n : Z) (w : Z) (_ : bits n) (_ : Z)
+`{ArithFact (w >= 0)},
+bits w.
+
+Axiom __SignExtendSlice : forall {m : Z} (_ : bits m) (_ : Z) (_ : Z) , bits m.
+
+Axiom __ZeroExtendSlice : forall {m : Z} (_ : bits m) (_ : Z) (_ : Z) , bits m.
+
+Definition cast_unit_vec (b : bitU)
+: M (mword 1) :=
+ (match b with
+ | B0 => returnm ((vec_of_bits [B0] : mword 1) : mword 1)
+ | B1 => returnm ((vec_of_bits [B1] : mword 1) : mword 1)
+ | _ => exit tt : M (mword 1)
+ end)
+ : M (mword 1).
+
+Axiom string_of_int : forall (_ : Z) , string.
+
+Axiom DecStr : forall (_ : Z) , string.
+
+Axiom HexStr : forall (_ : Z) , string.
+
+Axiom real_power : forall (_ : real) (_ : Z) , real.
+
+Axiom add_real : forall (_ : real) (_ : real) , real.
+
+Axiom sub_real : forall (_ : real) (_ : real) , real.
+
+Axiom negate_real : forall (_ : real) , real.
+
+Axiom mult_real : forall (_ : real) (_ : real) , real.
+
+Axiom Sqrt : forall (_ : real) , real.
+
+Axiom gteq_real : forall (_ : real) (_ : real) , bool.
+
+Axiom lteq_real : forall (_ : real) (_ : real) , bool.
+
+Axiom gt_real : forall (_ : real) (_ : real) , bool.
+
+Axiom lt_real : forall (_ : real) (_ : real) , bool.
+
+Axiom RoundDown : forall (_ : real) , Z.
+
+Axiom RoundUp : forall (_ : real) , Z.
+
+Axiom abs_real : forall (_ : real) , real.
+
+Axiom quotient_nat : forall
+
+(_ : {n : Z & ArithFact (n >= 0)}) (_ : {n : Z & ArithFact (n >= 0)})
+,
+{n : Z & ArithFact (n >= 0)}.
+
+Axiom quotient_real : forall (_ : real) (_ : real) , real.
+
+Axiom quotient : forall (_ : Z) (_ : Z) , Z.
+
+Axiom quot_round_zero : forall (_ : Z) (_ : Z) , Z.
+
+Axiom rem_round_zero : forall (_ : Z) (_ : Z) , Z.
+
+Axiom modulus : forall (_ : Z) (_ : Z) , Z.
+
+Axiom Real : forall (_ : Z) , real.
+
+Axiom min_nat : forall
+
+(_ : {n : Z & ArithFact (n >= 0)}) (_ : {n : Z & ArithFact (n >= 0)})
+,
+{n : Z & ArithFact (n >= 0)}.
+
+Axiom max_nat : forall
+
+(_ : {n : Z & ArithFact (n >= 0)}) (_ : {n : Z & ArithFact (n >= 0)})
+,
+{n : Z & ArithFact (n >= 0)}.
+
+Definition __RISCV_write (addr : mword 64) (width : Z) (data : mword (8 * width))
+: M (bool) :=
+ (write_ram 64 width
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) addr data)
+ : M (bool).
+
+Axiom __TraceMemoryWrite : forall {m : Z} (n : Z) (_ : bits m) (_ : bits (8 * n)) , unit.
+
+Definition __RISCV_read (addr : mword 64) (width : Z) (aq : bool) (rl : bool) (res : bool) `{ArithFact (width >=
+ 0)}
+: M (option (mword (8 * width))) :=
+ (match (aq, rl, res) with
+ | (false, false, false) =>
+ read_ram 64 width
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) addr >>= fun w__0 : mword (8 * width) =>
+ returnm ((Some w__0)
+ : option (mword (8 * width)))
+ | (true, false, false) =>
+ read_ram 64 width
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) addr >>= fun w__1 : mword (8 * width) =>
+ returnm ((Some w__1)
+ : option (mword (8 * width)))
+ | (true, true, false) =>
+ read_ram 64 width
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) addr >>= fun w__2 : mword (8 * width) =>
+ returnm ((Some w__2)
+ : option (mword (8 * width)))
+ | (false, false, true) =>
+ read_ram 64 width
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) addr >>= fun w__3 : mword (8 * width) =>
+ returnm ((Some w__3)
+ : option (mword (8 * width)))
+ | (true, false, true) =>
+ read_ram 64 width
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) addr >>= fun w__4 : mword (8 * width) =>
+ returnm ((Some w__4)
+ : option (mword (8 * width)))
+ | (true, true, true) =>
+ read_ram 64 width
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) addr >>= fun w__5 : mword (8 * width) =>
+ returnm ((Some w__5)
+ : option (mword (8 * width)))
+ | (false, true, false) => returnm (None : option (mword (8 * width)))
+ | (false, true, true) => returnm (None : option (mword (8 * width)))
+ end)
+ : M (option (mword (8 * width))).
+
+Axiom __TraceMemoryRead : forall {m : Z} (n : Z) (_ : bits m) (_ : bits (8 * n)) , unit.
+
+Definition ex_nat '((existT _ n _) : {n : Z & ArithFact (n >= 0)})
+: {syn_n : Z & ArithFact (syn_n >= 0)} :=
+ build_ex
+ n.
+
+Definition ex_int (n : Z) : {syn_n : Z & ArithFact (True)} := build_ex n.
+
+Definition coerce_int_nat (x : Z)
+: M ({n : Z & ArithFact (n >= 0)}) :=
+ assert_exp' (x >=? 0) "" >>= fun _ => returnm ((build_ex x) : {n : Z & ArithFact (n >= 0)}).
+
+Definition EXTS {n : Z} (m__tv : Z) (v : mword n) `{ArithFact (m__tv >= n)}
+: mword m__tv :=
+ sign_extend v m__tv.
+
+Definition EXTZ {n : Z} (m__tv : Z) (v : mword n) `{ArithFact (m__tv >= n)}
+: mword m__tv :=
+ zero_extend v m__tv.
+
+Definition zopz0zI_s {n : Z} (x : mword n) (y : mword n) `{ArithFact (n >= 1)}
+: bool :=
+ Z.ltb (projT1 (sint x)) (projT1 (sint y)).
+
+Definition zopz0zKzJ_s {n : Z} (x : mword n) (y : mword n) `{ArithFact (n >= 1)}
+: bool :=
+ Z.geb (projT1 (sint x)) (projT1 (sint y)).
+
+Definition zopz0zI_u {n : Z} (x : mword n) (y : mword n)
+: bool :=
+ Z.ltb (projT1 (uint x)) (projT1 (uint y)).
+
+Definition zopz0zKzJ_u {n : Z} (x : mword n) (y : mword n)
+: bool :=
+ Z.geb (projT1 (uint x)) (projT1 (uint y)).
+
+Definition zopz0zIzJ_u {n : Z} (x : mword n) (y : mword n)
+: bool :=
+ Z.leb (projT1 (uint x)) (projT1 (uint y)).
+
+Definition bool_to_bits (x : bool)
+: mword 1 :=
+ if (x) then (vec_of_bits [B1] : mword 1)
+ else (vec_of_bits [B0] : mword 1).
+
+Definition bit_to_bool (b : bitU)
+: M (bool) :=
+ (match b with
+ | B1 => returnm (true : bool)
+ | B0 => returnm (false : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool).
+
+Definition vector64 (n : Z) : mword 64 := get_slice_int 64 n 0.
+
+Definition to_bits (l : Z) (n : Z) `{ArithFact (l >= 0)} : mword l := get_slice_int l n 0.
+
+Axiom vector_update_subrange_inc : forall
+{n : Z}
+(_ : mword n) (m : Z) (o : Z) (_ : mword (o - (m - 1)))
+,
+mword n.
+
+Definition shift_right_arith64 (v : mword 64) (shift : mword 6)
+: mword 64 :=
+ let v128 : bits 128 := EXTS 128 v in
+ subrange_vec_dec (shift_bits_right v128 shift) 63 0.
+
+Definition shift_right_arith32 (v : mword 32) (shift : mword 5)
+: mword 32 :=
+ let v64 : bits 64 := EXTS 64 v in
+ subrange_vec_dec (shift_bits_right v64 shift) 31 0.
+
+Let xlen := 64.
+Definition xlen_max_unsigned_spec := sub_range (build_ex (projT1 (pow2 xlen))) (build_ex 1).
+Let xlen_max_unsigned := projT1 xlen_max_unsigned_spec .
+
+Definition xlen_max_signed_spec :=
+sub_range (build_ex (projT1 (pow2 (projT1 (sub_range (build_ex xlen) (build_ex 1)))))) (build_ex 1).
+Let xlen_max_signed := projT1 xlen_max_signed_spec .
+
+Definition xlen_min_signed_spec :=
+sub_range (build_ex 0) (build_ex (projT1 (pow2 (projT1 (sub_range (build_ex xlen) (build_ex 1)))))).
+Let xlen_min_signed := projT1 xlen_min_signed_spec .
+
+Definition regbits_to_regno (b : mword 5)
+: {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)} :=
+ let '(existT _ r _) := uint b in
+ build_ex
+ r.
+
+Definition creg2reg_bits (creg : mword 3)
+: mword 5 :=
+ concat_vec (vec_of_bits [B0;B1] : mword 2) creg.
+
+Let zreg : regbits := (vec_of_bits [B0;B0;B0;B0;B0] : mword 5).
+Let ra : regbits := (vec_of_bits [B0;B0;B0;B0;B1] : mword 5).
+Let sp : regbits := (vec_of_bits [B0;B0;B0;B1;B0] : mword 5).
+Definition rX (r : Z) `{ArithFact (0 <= r /\ (r + 1) <= 32)}
+: M (mword 64) :=
+ let p0_ := r in
+ (if sumbool_of_bool ((Z.eqb p0_ 0)) then
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64)
+ : mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then (read_reg x1_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then (read_reg x2_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then (read_reg x3_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then (read_reg x4_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 5)) then (read_reg x5_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 6)) then (read_reg x6_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 7)) then (read_reg x7_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 8)) then (read_reg x8_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 9)) then (read_reg x9_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 10)) then (read_reg x10_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 11)) then (read_reg x11_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 12)) then (read_reg x12_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 13)) then (read_reg x13_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 14)) then (read_reg x14_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 15)) then (read_reg x15_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 16)) then (read_reg x16_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 17)) then (read_reg x17_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 18)) then (read_reg x18_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 19)) then (read_reg x19_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 20)) then (read_reg x20_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 21)) then (read_reg x21_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 22)) then (read_reg x22_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 23)) then (read_reg x23_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 24)) then (read_reg x24_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 25)) then (read_reg x25_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 26)) then (read_reg x26_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 27)) then (read_reg x27_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 28)) then (read_reg x28_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 29)) then (read_reg x29_ref : M (mword 64)) : M (mword 64)
+ else if sumbool_of_bool ((Z.eqb p0_ 30)) then (read_reg x30_ref : M (mword 64)) : M (mword 64)
+ else (read_reg x31_ref : M (mword 64)) : M (mword 64))
+ : M (mword 64).
+
+Definition wX (r : Z) (v : mword 64) `{ArithFact (0 <= r /\ (r + 1) <= 32)}
+: M (unit) :=
+ let p0_ := r in
+ (if sumbool_of_bool ((Z.eqb p0_ 0)) then returnm (tt : unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then write_reg x1_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then write_reg x2_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then write_reg x3_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then write_reg x4_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 5)) then write_reg x5_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 6)) then write_reg x6_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 7)) then write_reg x7_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 8)) then write_reg x8_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 9)) then write_reg x9_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 10)) then write_reg x10_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 11)) then write_reg x11_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 12)) then write_reg x12_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 13)) then write_reg x13_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 14)) then write_reg x14_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 15)) then write_reg x15_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 16)) then write_reg x16_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 17)) then write_reg x17_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 18)) then write_reg x18_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 19)) then write_reg x19_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 20)) then write_reg x20_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 21)) then write_reg x21_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 22)) then write_reg x22_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 23)) then write_reg x23_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 24)) then write_reg x24_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 25)) then write_reg x25_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 26)) then write_reg x26_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 27)) then write_reg x27_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 28)) then write_reg x28_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 29)) then write_reg x29_ref v : M (unit)
+ else if sumbool_of_bool ((Z.eqb p0_ 30)) then write_reg x30_ref v : M (unit)
+ else write_reg x31_ref v : M (unit)) >>
+ returnm ((if sumbool_of_bool ((neq_atom r 0)) then
+ print_endline
+ (String.append "x"
+ (String.append (string_of_int r) (String.append " <- " (string_of_bits v))))
+ else tt)
+ : unit).
+
+Definition reg_name_abi (r : mword 5)
+: string :=
+ let b__0 := r in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "zero"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "ra"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "sp"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "gp"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "tp"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t0"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t1"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t2"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "fp"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s1"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a0"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a1"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a2"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a3"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a4"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a5"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a6"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a7"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s2"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s3"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s4"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s5"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s6"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s7"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s8"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s9"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s10"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s11"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t3"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t4"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno b__0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t5"
+ else "t6".
+
+Definition Architecture_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 2)}
+: Architecture :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then RV32
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then RV64
+ else RV128.
+
+Definition num_of_Architecture (arg_ : Architecture)
+: {e : Z & ArithFact (0 <= e /\ e <= 2)} :=
+ match arg_ with | RV32 => build_ex 0 | RV64 => build_ex 1 | RV128 => build_ex 2 end.
+
+Definition architecture (a : mword 2)
+: option Architecture :=
+ let b__0 := a in
+ if ((eq_vec b__0 (vec_of_bits [B0;B1] : mword 2))) then Some RV32
+ else if ((eq_vec b__0 (vec_of_bits [B1;B0] : mword 2))) then Some RV64
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1] : mword 2))) then Some RV128
+ else None.
+
+Definition arch_to_bits (a : Architecture)
+: mword 2 :=
+ match a with
+ | RV32 => (vec_of_bits [B0;B1] : mword 2)
+ | RV64 => (vec_of_bits [B1;B0] : mword 2)
+ | RV128 => (vec_of_bits [B1;B1] : mword 2)
+ end.
+
+Definition Privilege_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 2)}
+: Privilege :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then User
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then Supervisor
+ else Machine.
+
+Definition num_of_Privilege (arg_ : Privilege)
+: {e : Z & ArithFact (0 <= e /\ e <= 2)} :=
+ match arg_ with | User => build_ex 0 | Supervisor => build_ex 1 | Machine => build_ex 2 end.
+
+Definition privLevel_to_bits (p : Privilege)
+: mword 2 :=
+ match p with
+ | User => (vec_of_bits [B0;B0] : mword 2)
+ | Supervisor => (vec_of_bits [B0;B1] : mword 2)
+ | Machine => (vec_of_bits [B1;B1] : mword 2)
+ end.
+
+Definition privLevel_of_bits (p : mword 2)
+: Privilege :=
+ let b__0 := p in
+ if ((eq_vec b__0 (vec_of_bits [B0;B0] : mword 2))) then User
+ else if ((eq_vec b__0 (vec_of_bits [B0;B1] : mword 2))) then Supervisor
+ else Machine.
+
+Definition privLevel_to_str (p : Privilege)
+: string :=
+ match p with | User => "U" | Supervisor => "S" | Machine => "M" end.
+
+Definition AccessType_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 3)}
+: AccessType :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then Read
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then Write
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then ReadWrite
+ else Execute.
+
+Definition num_of_AccessType (arg_ : AccessType)
+: {e : Z & ArithFact (0 <= e /\ e <= 3)} :=
+ match arg_ with
+ | Read => build_ex 0
+ | Write => build_ex 1
+ | ReadWrite => build_ex 2
+ | Execute => build_ex 3
+ end.
+
+Definition accessType_to_str (a : AccessType)
+: string :=
+ match a with | Read => "R" | Write => "W" | ReadWrite => "RW" | Execute => "X" end.
+
+Definition ReadType_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 1)}
+: ReadType :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then Instruction
+ else Data.
+
+Definition num_of_ReadType (arg_ : ReadType)
+: {e : Z & ArithFact (0 <= e /\ e <= 1)} :=
+ match arg_ with | Instruction => build_ex 0 | Data => build_ex 1 end.
+
+Definition readType_to_str (r : ReadType)
+: string :=
+ match r with | Instruction => "I" | Data => "D" end.
+
+Definition word_width_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 3)}
+: word_width :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then BYTE
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then HALF
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then WORD
+ else DOUBLE.
+
+Definition num_of_word_width (arg_ : word_width)
+: {e : Z & ArithFact (0 <= e /\ e <= 3)} :=
+ match arg_ with
+ | BYTE => build_ex 0
+ | HALF => build_ex 1
+ | WORD => build_ex 2
+ | DOUBLE => build_ex 3
+ end.
+
+Definition InterruptType_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 8)}
+: InterruptType :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then I_U_Software
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then I_S_Software
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then I_M_Software
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then I_U_Timer
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then I_S_Timer
+ else if sumbool_of_bool ((Z.eqb p0_ 5)) then I_M_Timer
+ else if sumbool_of_bool ((Z.eqb p0_ 6)) then I_U_External
+ else if sumbool_of_bool ((Z.eqb p0_ 7)) then I_S_External
+ else I_M_External.
+
+Definition num_of_InterruptType (arg_ : InterruptType)
+: {e : Z & ArithFact (0 <= e /\ e <= 8)} :=
+ match arg_ with
+ | I_U_Software => build_ex 0
+ | I_S_Software => build_ex 1
+ | I_M_Software => build_ex 2
+ | I_U_Timer => build_ex 3
+ | I_S_Timer => build_ex 4
+ | I_M_Timer => build_ex 5
+ | I_U_External => build_ex 6
+ | I_S_External => build_ex 7
+ | I_M_External => build_ex 8
+ end.
+
+Definition interruptType_to_bits (i : InterruptType)
+: mword 4 :=
+ match i with
+ | I_U_Software => (vec_of_bits [B0;B0;B0;B0] : mword 4)
+ | I_S_Software => (vec_of_bits [B0;B0;B0;B1] : mword 4)
+ | I_M_Software => (vec_of_bits [B0;B0;B1;B1] : mword 4)
+ | I_U_Timer => (vec_of_bits [B0;B1;B0;B0] : mword 4)
+ | I_S_Timer => (vec_of_bits [B0;B1;B0;B1] : mword 4)
+ | I_M_Timer => (vec_of_bits [B0;B1;B1;B1] : mword 4)
+ | I_U_External => (vec_of_bits [B1;B0;B0;B0] : mword 4)
+ | I_S_External => (vec_of_bits [B1;B0;B0;B1] : mword 4)
+ | I_M_External => (vec_of_bits [B1;B0;B1;B1] : mword 4)
+ end.
+
+Definition ExceptionType_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 15)}
+: ExceptionType :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then E_Fetch_Addr_Align
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then E_Fetch_Access_Fault
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then E_Illegal_Instr
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then E_Breakpoint
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then E_Load_Addr_Align
+ else if sumbool_of_bool ((Z.eqb p0_ 5)) then E_Load_Access_Fault
+ else if sumbool_of_bool ((Z.eqb p0_ 6)) then E_SAMO_Addr_Align
+ else if sumbool_of_bool ((Z.eqb p0_ 7)) then E_SAMO_Access_Fault
+ else if sumbool_of_bool ((Z.eqb p0_ 8)) then E_U_EnvCall
+ else if sumbool_of_bool ((Z.eqb p0_ 9)) then E_S_EnvCall
+ else if sumbool_of_bool ((Z.eqb p0_ 10)) then E_Reserved_10
+ else if sumbool_of_bool ((Z.eqb p0_ 11)) then E_M_EnvCall
+ else if sumbool_of_bool ((Z.eqb p0_ 12)) then E_Fetch_Page_Fault
+ else if sumbool_of_bool ((Z.eqb p0_ 13)) then E_Load_Page_Fault
+ else if sumbool_of_bool ((Z.eqb p0_ 14)) then E_Reserved_14
+ else E_SAMO_Page_Fault.
+
+Definition num_of_ExceptionType (arg_ : ExceptionType)
+: {e : Z & ArithFact (0 <= e /\ e <= 15)} :=
+ match arg_ with
+ | E_Fetch_Addr_Align => build_ex 0
+ | E_Fetch_Access_Fault => build_ex 1
+ | E_Illegal_Instr => build_ex 2
+ | E_Breakpoint => build_ex 3
+ | E_Load_Addr_Align => build_ex 4
+ | E_Load_Access_Fault => build_ex 5
+ | E_SAMO_Addr_Align => build_ex 6
+ | E_SAMO_Access_Fault => build_ex 7
+ | E_U_EnvCall => build_ex 8
+ | E_S_EnvCall => build_ex 9
+ | E_Reserved_10 => build_ex 10
+ | E_M_EnvCall => build_ex 11
+ | E_Fetch_Page_Fault => build_ex 12
+ | E_Load_Page_Fault => build_ex 13
+ | E_Reserved_14 => build_ex 14
+ | E_SAMO_Page_Fault => build_ex 15
+ end.
+
+Definition exceptionType_to_bits (e : ExceptionType)
+: mword 4 :=
+ match e with
+ | E_Fetch_Addr_Align => (vec_of_bits [B0;B0;B0;B0] : mword 4)
+ | E_Fetch_Access_Fault => (vec_of_bits [B0;B0;B0;B1] : mword 4)
+ | E_Illegal_Instr => (vec_of_bits [B0;B0;B1;B0] : mword 4)
+ | E_Breakpoint => (vec_of_bits [B0;B0;B1;B1] : mword 4)
+ | E_Load_Addr_Align => (vec_of_bits [B0;B1;B0;B0] : mword 4)
+ | E_Load_Access_Fault => (vec_of_bits [B0;B1;B0;B1] : mword 4)
+ | E_SAMO_Addr_Align => (vec_of_bits [B0;B1;B1;B0] : mword 4)
+ | E_SAMO_Access_Fault => (vec_of_bits [B0;B1;B1;B1] : mword 4)
+ | E_U_EnvCall => (vec_of_bits [B1;B0;B0;B0] : mword 4)
+ | E_S_EnvCall => (vec_of_bits [B1;B0;B0;B1] : mword 4)
+ | E_Reserved_10 => (vec_of_bits [B1;B0;B1;B0] : mword 4)
+ | E_M_EnvCall => (vec_of_bits [B1;B0;B1;B1] : mword 4)
+ | E_Fetch_Page_Fault => (vec_of_bits [B1;B1;B0;B0] : mword 4)
+ | E_Load_Page_Fault => (vec_of_bits [B1;B1;B0;B1] : mword 4)
+ | E_Reserved_14 => (vec_of_bits [B1;B1;B1;B0] : mword 4)
+ | E_SAMO_Page_Fault => (vec_of_bits [B1;B1;B1;B1] : mword 4)
+ end.
+
+Definition exceptionType_to_str (e : ExceptionType)
+: string :=
+ match e with
+ | E_Fetch_Addr_Align => "misaligned-fetch"
+ | E_Fetch_Access_Fault => "fetch-access-fault"
+ | E_Illegal_Instr => "illegal-instruction"
+ | E_Breakpoint => "breakpoint"
+ | E_Load_Addr_Align => "misaligned-load"
+ | E_Load_Access_Fault => "load-access-fault"
+ | E_SAMO_Addr_Align => "misaliged-store/amo"
+ | E_SAMO_Access_Fault => "store/amo-access-fault"
+ | E_U_EnvCall => "u-call"
+ | E_S_EnvCall => "s-call"
+ | E_Reserved_10 => "reserved-0"
+ | E_M_EnvCall => "m-call"
+ | E_Fetch_Page_Fault => "fetch-page-fault"
+ | E_Load_Page_Fault => "load-page-fault"
+ | E_Reserved_14 => "reserved-1"
+ | E_SAMO_Page_Fault => "store/amo-page-fault"
+ end.
+
+Definition not_implemented {a : Type} (message : string)
+: M (a) :=
+ (throw (Error_not_implemented message))
+ : M (a).
+
+Definition internal_error {a : Type} (s : string)
+: M (a) :=
+ assert_exp' false s >>= fun _ => (throw (Error_internal_error tt)) : M (a).
+
+Definition TrapVectorMode_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 2)}
+: TrapVectorMode :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then TV_Direct
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then TV_Vector
+ else TV_Reserved.
+
+Definition num_of_TrapVectorMode (arg_ : TrapVectorMode)
+: {e : Z & ArithFact (0 <= e /\ e <= 2)} :=
+ match arg_ with
+ | TV_Direct => build_ex 0
+ | TV_Vector => build_ex 1
+ | TV_Reserved => build_ex 2
+ end.
+
+Definition trapVectorMode_of_bits (m : mword 2)
+: TrapVectorMode :=
+ let b__0 := m in
+ if ((eq_vec b__0 (vec_of_bits [B0;B0] : mword 2))) then TV_Direct
+ else if ((eq_vec b__0 (vec_of_bits [B0;B1] : mword 2))) then TV_Vector
+ else TV_Reserved.
+
+Definition ExtStatus_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 3)}
+: ExtStatus :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then Off
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then Initial
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then Clean
+ else Dirty.
+
+Definition num_of_ExtStatus (arg_ : ExtStatus)
+: {e : Z & ArithFact (0 <= e /\ e <= 3)} :=
+ match arg_ with
+ | Off => build_ex 0
+ | Initial => build_ex 1
+ | Clean => build_ex 2
+ | Dirty => build_ex 3
+ end.
+
+Definition extStatus_to_bits (e : ExtStatus)
+: mword 2 :=
+ match e with
+ | Off => (vec_of_bits [B0;B0] : mword 2)
+ | Initial => (vec_of_bits [B0;B1] : mword 2)
+ | Clean => (vec_of_bits [B1;B0] : mword 2)
+ | Dirty => (vec_of_bits [B1;B1] : mword 2)
+ end.
+
+Definition extStatus_of_bits (e : mword 2)
+: ExtStatus :=
+ let b__0 := e in
+ if ((eq_vec b__0 (vec_of_bits [B0;B0] : mword 2))) then Off
+ else if ((eq_vec b__0 (vec_of_bits [B0;B1] : mword 2))) then Initial
+ else if ((eq_vec b__0 (vec_of_bits [B1;B0] : mword 2))) then Clean
+ else Dirty.
+
+Definition SATPMode_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 2)}
+: SATPMode :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then Sbare
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then Sv32
+ else Sv39.
+
+Definition num_of_SATPMode (arg_ : SATPMode)
+: {e : Z & ArithFact (0 <= e /\ e <= 2)} :=
+ match arg_ with | Sbare => build_ex 0 | Sv32 => build_ex 1 | Sv39 => build_ex 2 end.
+
+Definition satpMode_of_bits (a : Architecture) (m : mword 4)
+: option SATPMode :=
+ match (a, m) with
+ | (g__33, b__0) =>
+ if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B0] : mword 4))) then Some Sbare
+ else
+ match (g__33, b__0) with
+ | (RV32, b__0) =>
+ if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1] : mword 4))) then Some Sv32
+ else match (RV32, b__0) with | (g__34, g__35) => None end
+ | (RV64, b__0) =>
+ if ((eq_vec b__0 (vec_of_bits [B1;B0;B0;B0] : mword 4))) then Some Sv39
+ else match (RV64, b__0) with | (g__34, g__35) => None end
+ | (g__34, g__35) => None
+ end
+ end.
+
+Definition uop_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 1)}
+: uop :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then RISCV_LUI
+ else RISCV_AUIPC.
+
+Definition num_of_uop (arg_ : uop)
+: {e : Z & ArithFact (0 <= e /\ e <= 1)} :=
+ match arg_ with | RISCV_LUI => build_ex 0 | RISCV_AUIPC => build_ex 1 end.
+
+Definition bop_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 5)}
+: bop :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then RISCV_BEQ
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then RISCV_BNE
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then RISCV_BLT
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then RISCV_BGE
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then RISCV_BLTU
+ else RISCV_BGEU.
+
+Definition num_of_bop (arg_ : bop)
+: {e : Z & ArithFact (0 <= e /\ e <= 5)} :=
+ match arg_ with
+ | RISCV_BEQ => build_ex 0
+ | RISCV_BNE => build_ex 1
+ | RISCV_BLT => build_ex 2
+ | RISCV_BGE => build_ex 3
+ | RISCV_BLTU => build_ex 4
+ | RISCV_BGEU => build_ex 5
+ end.
+
+Definition iop_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 5)}
+: iop :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then RISCV_ADDI
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then RISCV_SLTI
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then RISCV_SLTIU
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then RISCV_XORI
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then RISCV_ORI
+ else RISCV_ANDI.
+
+Definition num_of_iop (arg_ : iop)
+: {e : Z & ArithFact (0 <= e /\ e <= 5)} :=
+ match arg_ with
+ | RISCV_ADDI => build_ex 0
+ | RISCV_SLTI => build_ex 1
+ | RISCV_SLTIU => build_ex 2
+ | RISCV_XORI => build_ex 3
+ | RISCV_ORI => build_ex 4
+ | RISCV_ANDI => build_ex 5
+ end.
+
+Definition sop_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 2)}
+: sop :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then RISCV_SLLI
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then RISCV_SRLI
+ else RISCV_SRAI.
+
+Definition num_of_sop (arg_ : sop)
+: {e : Z & ArithFact (0 <= e /\ e <= 2)} :=
+ match arg_ with
+ | RISCV_SLLI => build_ex 0
+ | RISCV_SRLI => build_ex 1
+ | RISCV_SRAI => build_ex 2
+ end.
+
+Definition rop_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 9)}
+: rop :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then RISCV_ADD
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then RISCV_SUB
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then RISCV_SLL
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then RISCV_SLT
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then RISCV_SLTU
+ else if sumbool_of_bool ((Z.eqb p0_ 5)) then RISCV_XOR
+ else if sumbool_of_bool ((Z.eqb p0_ 6)) then RISCV_SRL
+ else if sumbool_of_bool ((Z.eqb p0_ 7)) then RISCV_SRA
+ else if sumbool_of_bool ((Z.eqb p0_ 8)) then RISCV_OR
+ else RISCV_AND.
+
+Definition num_of_rop (arg_ : rop)
+: {e : Z & ArithFact (0 <= e /\ e <= 9)} :=
+ match arg_ with
+ | RISCV_ADD => build_ex 0
+ | RISCV_SUB => build_ex 1
+ | RISCV_SLL => build_ex 2
+ | RISCV_SLT => build_ex 3
+ | RISCV_SLTU => build_ex 4
+ | RISCV_XOR => build_ex 5
+ | RISCV_SRL => build_ex 6
+ | RISCV_SRA => build_ex 7
+ | RISCV_OR => build_ex 8
+ | RISCV_AND => build_ex 9
+ end.
+
+Definition ropw_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 4)}
+: ropw :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then RISCV_ADDW
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then RISCV_SUBW
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then RISCV_SLLW
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then RISCV_SRLW
+ else RISCV_SRAW.
+
+Definition num_of_ropw (arg_ : ropw)
+: {e : Z & ArithFact (0 <= e /\ e <= 4)} :=
+ match arg_ with
+ | RISCV_ADDW => build_ex 0
+ | RISCV_SUBW => build_ex 1
+ | RISCV_SLLW => build_ex 2
+ | RISCV_SRLW => build_ex 3
+ | RISCV_SRAW => build_ex 4
+ end.
+
+Definition sopw_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 2)}
+: sopw :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then RISCV_SLLIW
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then RISCV_SRLIW
+ else RISCV_SRAIW.
+
+Definition num_of_sopw (arg_ : sopw)
+: {e : Z & ArithFact (0 <= e /\ e <= 2)} :=
+ match arg_ with
+ | RISCV_SLLIW => build_ex 0
+ | RISCV_SRLIW => build_ex 1
+ | RISCV_SRAIW => build_ex 2
+ end.
+
+Definition amoop_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 8)}
+: amoop :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then AMOSWAP
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then AMOADD
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then AMOXOR
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then AMOAND
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then AMOOR
+ else if sumbool_of_bool ((Z.eqb p0_ 5)) then AMOMIN
+ else if sumbool_of_bool ((Z.eqb p0_ 6)) then AMOMAX
+ else if sumbool_of_bool ((Z.eqb p0_ 7)) then AMOMINU
+ else AMOMAXU.
+
+Definition num_of_amoop (arg_ : amoop)
+: {e : Z & ArithFact (0 <= e /\ e <= 8)} :=
+ match arg_ with
+ | AMOSWAP => build_ex 0
+ | AMOADD => build_ex 1
+ | AMOXOR => build_ex 2
+ | AMOAND => build_ex 3
+ | AMOOR => build_ex 4
+ | AMOMIN => build_ex 5
+ | AMOMAX => build_ex 6
+ | AMOMINU => build_ex 7
+ | AMOMAXU => build_ex 8
+ end.
+
+Definition csrop_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 2)}
+: csrop :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then CSRRW
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then CSRRS
+ else CSRRC.
+
+Definition num_of_csrop (arg_ : csrop)
+: {e : Z & ArithFact (0 <= e /\ e <= 2)} :=
+ match arg_ with | CSRRW => build_ex 0 | CSRRS => build_ex 1 | CSRRC => build_ex 2 end.
+
+Definition reg_name_forwards (arg_ : mword 5)
+: string :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "zero"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "ra"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "sp"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "gp"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "tp"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t0"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t1"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t2"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "fp"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s1"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a0"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a1"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a2"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a3"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a4"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a5"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a6"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "a7"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s2"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s3"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s4"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s5"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s6"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s7"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s8"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s9"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s10"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "s11"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t3"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t4"
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ "t5"
+ else "t6".
+
+Definition reg_name_backwards (arg_ : string)
+: M (mword 5) :=
+ (match arg_ with
+ | "zero" => returnm ((vec_of_bits [B0;B0;B0;B0;B0] : mword 5) : mword 5)
+ | "ra" => returnm ((vec_of_bits [B0;B0;B0;B0;B1] : mword 5) : mword 5)
+ | "sp" => returnm ((vec_of_bits [B0;B0;B0;B1;B0] : mword 5) : mword 5)
+ | "gp" => returnm ((vec_of_bits [B0;B0;B0;B1;B1] : mword 5) : mword 5)
+ | "tp" => returnm ((vec_of_bits [B0;B0;B1;B0;B0] : mword 5) : mword 5)
+ | "t0" => returnm ((vec_of_bits [B0;B0;B1;B0;B1] : mword 5) : mword 5)
+ | "t1" => returnm ((vec_of_bits [B0;B0;B1;B1;B0] : mword 5) : mword 5)
+ | "t2" => returnm ((vec_of_bits [B0;B0;B1;B1;B1] : mword 5) : mword 5)
+ | "fp" => returnm ((vec_of_bits [B0;B1;B0;B0;B0] : mword 5) : mword 5)
+ | "s1" => returnm ((vec_of_bits [B0;B1;B0;B0;B1] : mword 5) : mword 5)
+ | "a0" => returnm ((vec_of_bits [B0;B1;B0;B1;B0] : mword 5) : mword 5)
+ | "a1" => returnm ((vec_of_bits [B0;B1;B0;B1;B1] : mword 5) : mword 5)
+ | "a2" => returnm ((vec_of_bits [B0;B1;B1;B0;B0] : mword 5) : mword 5)
+ | "a3" => returnm ((vec_of_bits [B0;B1;B1;B0;B1] : mword 5) : mword 5)
+ | "a4" => returnm ((vec_of_bits [B0;B1;B1;B1;B0] : mword 5) : mword 5)
+ | "a5" => returnm ((vec_of_bits [B0;B1;B1;B1;B1] : mword 5) : mword 5)
+ | "a6" => returnm ((vec_of_bits [B1;B0;B0;B0;B0] : mword 5) : mword 5)
+ | "a7" => returnm ((vec_of_bits [B1;B0;B0;B0;B1] : mword 5) : mword 5)
+ | "s2" => returnm ((vec_of_bits [B1;B0;B0;B1;B0] : mword 5) : mword 5)
+ | "s3" => returnm ((vec_of_bits [B1;B0;B0;B1;B1] : mword 5) : mword 5)
+ | "s4" => returnm ((vec_of_bits [B1;B0;B1;B0;B0] : mword 5) : mword 5)
+ | "s5" => returnm ((vec_of_bits [B1;B0;B1;B0;B1] : mword 5) : mword 5)
+ | "s6" => returnm ((vec_of_bits [B1;B0;B1;B1;B0] : mword 5) : mword 5)
+ | "s7" => returnm ((vec_of_bits [B1;B0;B1;B1;B1] : mword 5) : mword 5)
+ | "s8" => returnm ((vec_of_bits [B1;B1;B0;B0;B0] : mword 5) : mword 5)
+ | "s9" => returnm ((vec_of_bits [B1;B1;B0;B0;B1] : mword 5) : mword 5)
+ | "s10" => returnm ((vec_of_bits [B1;B1;B0;B1;B0] : mword 5) : mword 5)
+ | "s11" => returnm ((vec_of_bits [B1;B1;B0;B1;B1] : mword 5) : mword 5)
+ | "t3" => returnm ((vec_of_bits [B1;B1;B1;B0;B0] : mword 5) : mword 5)
+ | "t4" => returnm ((vec_of_bits [B1;B1;B1;B0;B1] : mword 5) : mword 5)
+ | "t5" => returnm ((vec_of_bits [B1;B1;B1;B1;B0] : mword 5) : mword 5)
+ | "t6" => returnm ((vec_of_bits [B1;B1;B1;B1;B1] : mword 5) : mword 5)
+ | _ => exit tt : M (mword 5)
+ end)
+ : M (mword 5).
+
+Definition reg_name_forwards_matches (arg_ : mword 5)
+: bool :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else false.
+
+Definition reg_name_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with
+ | "zero" => true
+ | "ra" => true
+ | "sp" => true
+ | "gp" => true
+ | "tp" => true
+ | "t0" => true
+ | "t1" => true
+ | "t2" => true
+ | "fp" => true
+ | "s1" => true
+ | "a0" => true
+ | "a1" => true
+ | "a2" => true
+ | "a3" => true
+ | "a4" => true
+ | "a5" => true
+ | "a6" => true
+ | "a7" => true
+ | "s2" => true
+ | "s3" => true
+ | "s4" => true
+ | "s5" => true
+ | "s6" => true
+ | "s7" => true
+ | "s8" => true
+ | "s9" => true
+ | "s10" => true
+ | "s11" => true
+ | "t3" => true
+ | "t4" => true
+ | "t5" => true
+ | "t6" => true
+ | _ => false
+ end.
+
+Definition reg_name_matches_prefix (arg_ : string)
+: option ((mword 5 * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1871_ := arg_ in
+ if ((andb (string_startswith _stringappend_1871_ "zero")
+ (match (string_drop _stringappend_1871_ (string_length "zero")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "zero")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "ra")
+ (match (string_drop _stringappend_1871_ (string_length "ra")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "ra")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "sp")
+ (match (string_drop _stringappend_1871_ (string_length "sp")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "sp")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "gp")
+ (match (string_drop _stringappend_1871_ (string_length "gp")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "gp")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "tp")
+ (match (string_drop _stringappend_1871_ (string_length "tp")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "tp")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B0;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "t0")
+ (match (string_drop _stringappend_1871_ (string_length "t0")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "t0")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B0;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "t1")
+ (match (string_drop _stringappend_1871_ (string_length "t1")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "t1")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "t2")
+ (match (string_drop _stringappend_1871_ (string_length "t2")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "t2")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "fp")
+ (match (string_drop _stringappend_1871_ (string_length "fp")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "fp")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B0;B0;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s1")
+ (match (string_drop _stringappend_1871_ (string_length "s1")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s1")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B0;B0;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "a0")
+ (match (string_drop _stringappend_1871_ (string_length "a0")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "a0")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B0;B1;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "a1")
+ (match (string_drop _stringappend_1871_ (string_length "a1")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "a1")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B0;B1;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "a2")
+ (match (string_drop _stringappend_1871_ (string_length "a2")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "a2")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B1;B0;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "a3")
+ (match (string_drop _stringappend_1871_ (string_length "a3")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "a3")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B1;B0;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "a4")
+ (match (string_drop _stringappend_1871_ (string_length "a4")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "a4")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B1;B1;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "a5")
+ (match (string_drop _stringappend_1871_ (string_length "a5")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "a5")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B1;B1;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "a6")
+ (match (string_drop _stringappend_1871_ (string_length "a6")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "a6")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B0;B0;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "a7")
+ (match (string_drop _stringappend_1871_ (string_length "a7")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "a7")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B0;B0;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s2")
+ (match (string_drop _stringappend_1871_ (string_length "s2")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s2")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B0;B1;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s3")
+ (match (string_drop _stringappend_1871_ (string_length "s3")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s3")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B0;B1;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s4")
+ (match (string_drop _stringappend_1871_ (string_length "s4")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s4")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B1;B0;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s5")
+ (match (string_drop _stringappend_1871_ (string_length "s5")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s5")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B1;B0;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s6")
+ (match (string_drop _stringappend_1871_ (string_length "s6")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s6")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B1;B1;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s7")
+ (match (string_drop _stringappend_1871_ (string_length "s7")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s7")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B1;B1;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s8")
+ (match (string_drop _stringappend_1871_ (string_length "s8")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s8")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B0;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s9")
+ (match (string_drop _stringappend_1871_ (string_length "s9")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s9")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B0;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s10")
+ (match (string_drop _stringappend_1871_ (string_length "s10")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s10")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B1;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "s11")
+ (match (string_drop _stringappend_1871_ (string_length "s11")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "s11")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B1;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "t3")
+ (match (string_drop _stringappend_1871_ (string_length "t3")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "t3")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B1;B0;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "t4")
+ (match (string_drop _stringappend_1871_ (string_length "t4")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "t4")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B1;B0;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "t5")
+ (match (string_drop _stringappend_1871_ (string_length "t5")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "t5")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B1;B1;B0] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1871_ "t6")
+ (match (string_drop _stringappend_1871_ (string_length "t6")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1871_ (string_length "t6")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B1;B1;B1] : mword 5),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition sep_forwards (arg_ : unit)
+: string :=
+ match arg_ with
+ | tt =>
+ string_append (opt_spc_forwards tt)
+ (string_append "," (string_append (def_spc_forwards tt) ""))
+ end.
+
+Definition sep_backwards (arg_ : string)
+: M (unit) :=
+ let _stringappend_1864_ := arg_ in
+ match (opt_spc_matches_prefix _stringappend_1864_) with
+ | Some (_stringappend_1865_,(existT _ _stringappend_1866_ _)) =>
+ returnm ((_stringappend_1865_, build_ex _stringappend_1866_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__1 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1866_ _) := w__1 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1867_ := string_drop _stringappend_1864_ (build_ex _stringappend_1866_) in
+ let _stringappend_1868_ := string_drop _stringappend_1867_ (string_length ",") in
+ match (opt_spc_matches_prefix _stringappend_1868_) with
+ | Some (_stringappend_1869_,(existT _ _stringappend_1870_ _)) =>
+ returnm ((_stringappend_1869_, build_ex _stringappend_1870_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__3 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1870_ _) := w__3 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1868_ (build_ex _stringappend_1870_)) with
+ | "" => returnm (tt : unit)
+ | _ => exit tt : M (unit)
+ end)
+ : M (unit).
+
+Definition sep_forwards_matches (arg_ : unit) : bool := match arg_ with | tt => true end.
+
+Definition sep_backwards_matches (arg_ : string)
+: M (bool) :=
+ let _stringappend_1857_ := arg_ in
+ (if ((match (opt_spc_matches_prefix _stringappend_1857_) with
+ | Some (_stringappend_1858_,(existT _ _stringappend_1859_ _)) =>
+ let _stringappend_1860_ :=
+ string_drop _stringappend_1857_ (build_ex _stringappend_1859_) in
+ if ((andb (string_startswith _stringappend_1860_ ",")
+ (let _stringappend_1861_ := string_drop _stringappend_1860_ (string_length ",") in
+ if ((match (opt_spc_matches_prefix _stringappend_1861_) with
+ | Some (_stringappend_1862_,(existT _ _stringappend_1863_ _)) =>
+ match (string_drop _stringappend_1861_ (build_ex _stringappend_1863_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false))) then
+ true
+ else false
+ | None => false
+ end)) then
+ match (opt_spc_matches_prefix _stringappend_1857_) with
+ | Some (_stringappend_1858_,(existT _ _stringappend_1859_ _)) =>
+ returnm ((_stringappend_1858_, build_ex _stringappend_1859_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__1 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1859_ _) := w__1 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1860_ := string_drop _stringappend_1857_ (build_ex _stringappend_1859_) in
+ let _stringappend_1861_ := string_drop _stringappend_1860_ (string_length ",") in
+ match (opt_spc_matches_prefix _stringappend_1861_) with
+ | Some (_stringappend_1862_,(existT _ _stringappend_1863_ _)) =>
+ returnm ((_stringappend_1862_, build_ex _stringappend_1863_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__3 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1863_ _) := w__3 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1861_ (build_ex _stringappend_1863_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else returnm (false : bool))
+ : M (bool).
+
+Definition sep_matches_prefix (arg_ : string)
+: M (option ((unit * {n : Z & ArithFact (n >= 0)}))) :=
+ let _stringappend_1850_ := arg_ in
+ (if ((match (opt_spc_matches_prefix _stringappend_1850_) with
+ | Some (_stringappend_1851_,(existT _ _stringappend_1852_ _)) =>
+ let _stringappend_1853_ :=
+ string_drop _stringappend_1850_ (build_ex _stringappend_1852_) in
+ if ((andb (string_startswith _stringappend_1853_ ",")
+ (let _stringappend_1854_ := string_drop _stringappend_1853_ (string_length ",") in
+ if ((match (opt_spc_matches_prefix _stringappend_1854_) with
+ | Some (_stringappend_1855_,(existT _ _stringappend_1856_ _)) =>
+ match (string_drop _stringappend_1854_ (build_ex _stringappend_1856_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false))) then
+ true
+ else false
+ | None => false
+ end)) then
+ match (opt_spc_matches_prefix _stringappend_1850_) with
+ | Some (_stringappend_1851_,(existT _ _stringappend_1852_ _)) =>
+ returnm ((_stringappend_1851_, build_ex _stringappend_1852_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__1 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1852_ _) := w__1 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1853_ := string_drop _stringappend_1850_ (build_ex _stringappend_1852_) in
+ let _stringappend_1854_ := string_drop _stringappend_1853_ (string_length ",") in
+ match (opt_spc_matches_prefix _stringappend_1854_) with
+ | Some (_stringappend_1855_,(existT _ _stringappend_1856_ _)) =>
+ returnm ((_stringappend_1855_, build_ex _stringappend_1856_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__3 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1856_ _) := w__3 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_1854_ (build_ex _stringappend_1856_)) with
+ | s_ => Some (tt, sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((unit * {n : Z & ArithFact (n >= 0)})))
+ else returnm (None : option ((unit * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((unit * {n : Z & ArithFact (n >= 0)}))).
+
+Definition bool_bits_forwards (arg_ : bool)
+: mword 1 :=
+ match arg_ with
+ | true => (vec_of_bits [B1] : mword 1)
+ | false => (vec_of_bits [B0] : mword 1)
+ end.
+
+Definition bool_bits_backwards (arg_ : mword 1)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then true
+ else false.
+
+Definition bool_bits_forwards_matches (arg_ : bool)
+: bool :=
+ match arg_ with | true => true | false => true end.
+
+Definition bool_bits_backwards_matches (arg_ : mword 1)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0] : mword 1))) then true
+ else false.
+
+Definition bool_not_bits_forwards (arg_ : bool)
+: mword 1 :=
+ match arg_ with
+ | true => (vec_of_bits [B0] : mword 1)
+ | false => (vec_of_bits [B1] : mword 1)
+ end.
+
+Definition bool_not_bits_backwards (arg_ : mword 1)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0] : mword 1))) then true
+ else false.
+
+Definition bool_not_bits_forwards_matches (arg_ : bool)
+: bool :=
+ match arg_ with | true => true | false => true end.
+
+Definition bool_not_bits_backwards_matches (arg_ : mword 1)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0] : mword 1))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then true
+ else false.
+
+Definition size_bits_forwards (arg_ : word_width)
+: mword 2 :=
+ match arg_ with
+ | BYTE => (vec_of_bits [B0;B0] : mword 2)
+ | HALF => (vec_of_bits [B0;B1] : mword 2)
+ | WORD => (vec_of_bits [B1;B0] : mword 2)
+ | DOUBLE => (vec_of_bits [B1;B1] : mword 2)
+ end.
+
+Definition size_bits_backwards (arg_ : mword 2)
+: word_width :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0] : mword 2))) then BYTE
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1] : mword 2))) then HALF
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0] : mword 2))) then WORD
+ else DOUBLE.
+
+Definition size_bits_forwards_matches (arg_ : word_width)
+: bool :=
+ match arg_ with | BYTE => true | HALF => true | WORD => true | DOUBLE => true end.
+
+Definition size_bits_backwards_matches (arg_ : mword 2)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0] : mword 2))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1] : mword 2))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0] : mword 2))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1] : mword 2))) then true
+ else false.
+
+Definition size_mnemonic_forwards (arg_ : word_width)
+: string :=
+ match arg_ with | BYTE => "b" | HALF => "h" | WORD => "w" | DOUBLE => "d" end.
+
+Definition size_mnemonic_backwards (arg_ : string)
+: M (word_width) :=
+ (match arg_ with
+ | "b" => returnm (BYTE : word_width)
+ | "h" => returnm (HALF : word_width)
+ | "w" => returnm (WORD : word_width)
+ | "d" => returnm (DOUBLE : word_width)
+ | _ => exit tt : M (word_width)
+ end)
+ : M (word_width).
+
+Definition size_mnemonic_forwards_matches (arg_ : word_width)
+: bool :=
+ match arg_ with | BYTE => true | HALF => true | WORD => true | DOUBLE => true end.
+
+Definition size_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "b" => true | "h" => true | "w" => true | "d" => true | _ => false end.
+
+Definition size_mnemonic_matches_prefix (arg_ : string)
+: option ((word_width * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1846_ := arg_ in
+ if ((andb (string_startswith _stringappend_1846_ "b")
+ (match (string_drop _stringappend_1846_ (string_length "b")) with | s_ => true end))) then
+ match (string_drop _stringappend_1846_ (string_length "b")) with
+ | s_ => Some (BYTE, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1846_ "h")
+ (match (string_drop _stringappend_1846_ (string_length "h")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1846_ (string_length "h")) with
+ | s_ => Some (HALF, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1846_ "w")
+ (match (string_drop _stringappend_1846_ (string_length "w")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1846_ (string_length "w")) with
+ | s_ => Some (WORD, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1846_ "d")
+ (match (string_drop _stringappend_1846_ (string_length "d")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1846_ (string_length "d")) with
+ | s_ => Some (DOUBLE, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition Mk_Misa (v : mword 64) : Misa := {| Misa_Misa_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Misa_bits (v : Misa) : mword 64 := subrange_vec_dec v.(Misa_Misa_chunk_0) 63 0.
+
+Definition _set_Misa_bits (r_ref : register_ref regstate register_value Misa) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_bits (v : Misa) (x : mword 64)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Misa_MXL (v : Misa) : mword 2 := subrange_vec_dec v.(Misa_Misa_chunk_0) 63 62.
+
+Definition _set_Misa_MXL (r_ref : register_ref regstate register_value Misa) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 63 62 (subrange_vec_dec v 1 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_MXL (v : Misa) (x : mword 2)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 63 62 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_Misa_Z (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 25 25.
+
+Definition _set_Misa_Z (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 25 25 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_Z (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 25 25 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_Y (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 24 24.
+
+Definition _set_Misa_Y (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 24 24 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_Y (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 24 24 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_X (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 23 23.
+
+Definition _set_Misa_X (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 23 23 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_X (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 23 23 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_W (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 22 22.
+
+Definition _set_Misa_W (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 22 22 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_W (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 22 22 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_V (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 21 21.
+
+Definition _set_Misa_V (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 21 21 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_V (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 21 21 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_U (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 20 20.
+
+Definition _set_Misa_U (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 20 20 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_U (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 20 20 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_T (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 19 19.
+
+Definition _set_Misa_T (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 19 19 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_T (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 19 19 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_S (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 18 18.
+
+Definition _set_Misa_S (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 18 18 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_S (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 18 18 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_R (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 17 17.
+
+Definition _set_Misa_R (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 17 17 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_R (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 17 17 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_Q (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 16 16.
+
+Definition _set_Misa_Q (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 16 16 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_Q (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 16 16 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_P (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 15 15.
+
+Definition _set_Misa_P (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 15 15 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_P (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 15 15 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_O (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 14 14.
+
+Definition _set_Misa_O (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 14 14 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_O (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 14 14 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_N (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 13 13.
+
+Definition _set_Misa_N (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 13 13 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_N (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 13 13 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_M (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 12 12.
+
+Definition _set_Misa_M (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 12 12 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_M (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 12 12 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_L (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 11 11.
+
+Definition _set_Misa_L (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 11 11 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_L (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 11 11 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_K (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 10 10.
+
+Definition _set_Misa_K (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 10 10 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_K (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 10 10 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_J (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 9 9.
+
+Definition _set_Misa_J (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 9 9 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_J (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 9 9 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_I (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 8 8.
+
+Definition _set_Misa_I (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 8 8 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_I (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 8 8 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_H (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 7 7.
+
+Definition _set_Misa_H (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 7 7 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_H (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 7 7 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_G (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 6 6.
+
+Definition _set_Misa_G (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 6 6 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_G (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 6 6 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_F (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 5 5.
+
+Definition _set_Misa_F (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 5 5 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_F (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 5 5 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_E (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 4 4.
+
+Definition _set_Misa_E (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 4 4 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_E (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 4 4 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_D (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 3 3.
+
+Definition _set_Misa_D (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 3 3 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_D (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 3 3 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_C (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 2 2.
+
+Definition _set_Misa_C (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 2 2 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_C (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 2 2 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_B (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 1 1.
+
+Definition _set_Misa_B (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_B (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Misa_A (v : Misa) : mword 1 := subrange_vec_dec v.(Misa_Misa_chunk_0) 0 0.
+
+Definition _set_Misa_A (r_ref : register_ref regstate register_value Misa) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec r.(Misa_Misa_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
+ : Misa in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Misa_A (v : Misa) (x : mword 1)
+: Misa :=
+ {[ v with
+ Misa_Misa_chunk_0 :=
+ (update_subrange_vec_dec v.(Misa_Misa_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.
+
+Definition legalize_misa (m : Misa) (v : mword 64)
+: M (Misa) :=
+ let v := Mk_Misa v in
+ and_boolM (returnm ((eq_vec (_get_Misa_C v) ((bool_to_bits false) : mword 1)) : bool))
+ ((read_reg nextPC_ref : M (mword 64)) >>= fun w__0 : xlenbits =>
+ cast_unit_vec (access_vec_dec w__0 1) >>= fun w__1 : mword 1 =>
+ returnm ((eq_vec (w__1 : mword 1) ((bool_to_bits true) : mword 1))
+ : bool)) >>= fun w__2 : bool =>
+ returnm ((if (w__2) then m
+ else _update_Misa_C m (_get_Misa_C v))
+ : Misa).
+
+Definition Mk_Mstatus (v : mword 64)
+: Mstatus :=
+ {| Mstatus_Mstatus_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Mstatus_bits (v : Mstatus)
+: mword 64 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 63 0.
+
+Definition _set_Mstatus_bits (r_ref : register_ref regstate register_value Mstatus) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_bits (v : Mstatus) (x : mword 64)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Mstatus_SD (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 63 63.
+
+Definition _set_Mstatus_SD (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 63 63 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_SD (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 63 63 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_SXL (v : Mstatus)
+: mword 2 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 35 34.
+
+Definition _set_Mstatus_SXL (r_ref : register_ref regstate register_value Mstatus) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 35 34 (subrange_vec_dec v 1 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_SXL (v : Mstatus) (x : mword 2)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 35 34 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_Mstatus_UXL (v : Mstatus)
+: mword 2 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 33 32.
+
+Definition _set_Mstatus_UXL (r_ref : register_ref regstate register_value Mstatus) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 33 32 (subrange_vec_dec v 1 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_UXL (v : Mstatus) (x : mword 2)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 33 32 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_Mstatus_TSR (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 22 22.
+
+Definition _set_Mstatus_TSR (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 22 22 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_TSR (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 22 22 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_TW (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 21 21.
+
+Definition _set_Mstatus_TW (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 21 21 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_TW (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 21 21 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_TVM (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 20 20.
+
+Definition _set_Mstatus_TVM (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 20 20 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_TVM (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 20 20 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_MXR (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 19 19.
+
+Definition _set_Mstatus_MXR (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 19 19 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_MXR (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 19 19 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_SUM (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 18 18.
+
+Definition _set_Mstatus_SUM (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 18 18 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_SUM (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 18 18 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_MPRV (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 17 17.
+
+Definition _set_Mstatus_MPRV (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 17 17 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_MPRV (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 17 17 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_XS (v : Mstatus)
+: mword 2 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 16 15.
+
+Definition _set_Mstatus_XS (r_ref : register_ref regstate register_value Mstatus) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 16 15 (subrange_vec_dec v 1 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_XS (v : Mstatus) (x : mword 2)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 16 15 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_Mstatus_FS (v : Mstatus)
+: mword 2 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 14 13.
+
+Definition _set_Mstatus_FS (r_ref : register_ref regstate register_value Mstatus) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 14 13 (subrange_vec_dec v 1 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_FS (v : Mstatus) (x : mword 2)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 14 13 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_Mstatus_MPP (v : Mstatus)
+: mword 2 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 12 11.
+
+Definition _set_Mstatus_MPP (r_ref : register_ref regstate register_value Mstatus) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 12 11 (subrange_vec_dec v 1 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_MPP (v : Mstatus) (x : mword 2)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 12 11 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_Mstatus_SPP (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 8 8.
+
+Definition _set_Mstatus_SPP (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 8 8 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_SPP (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 8 8 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_MPIE (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 7 7.
+
+Definition _set_Mstatus_MPIE (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 7 7 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_MPIE (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 7 7 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_SPIE (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 5 5.
+
+Definition _set_Mstatus_SPIE (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 5 5 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_SPIE (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 5 5 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_UPIE (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 4 4.
+
+Definition _set_Mstatus_UPIE (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 4 4 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_UPIE (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 4 4 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_MIE (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 3 3.
+
+Definition _set_Mstatus_MIE (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 3 3 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_MIE (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 3 3 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_SIE (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 1 1.
+
+Definition _set_Mstatus_SIE (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_SIE (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mstatus_UIE (v : Mstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 0 0.
+
+Definition _set_Mstatus_UIE (r_ref : register_ref regstate register_value Mstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Mstatus_Mstatus_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
+ : Mstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mstatus_UIE (v : Mstatus) (x : mword 1)
+: Mstatus :=
+ {[ v with
+ Mstatus_Mstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Mstatus_Mstatus_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.
+
+Definition legalize_mstatus (o : Mstatus) (v : mword 64)
+: Mstatus :=
+ let m : Mstatus := Mk_Mstatus v in
+ let m := _update_Mstatus_XS m (extStatus_to_bits Off) in
+ let m :=
+ _update_Mstatus_SD m
+ ((bool_to_bits
+ (orb
+ (eq_vec ((extStatus_to_bits (extStatus_of_bits (_get_Mstatus_FS m))) : mword 2)
+ ((extStatus_to_bits Dirty)
+ : mword 2))
+ (eq_vec ((extStatus_to_bits (extStatus_of_bits (_get_Mstatus_XS m))) : mword 2)
+ ((extStatus_to_bits Dirty)
+ : mword 2))))
+ : mword 1) in
+ let m := _update_Mstatus_SXL m (_get_Mstatus_SXL o) in
+ let m := _update_Mstatus_UXL m (_get_Mstatus_UXL o) in
+ let m := _update_Mstatus_UPIE m ((bool_to_bits false) : mword 1) in
+ _update_Mstatus_UIE m ((bool_to_bits false) : mword 1).
+
+Definition cur_Architecture '(tt : unit)
+: M (Architecture) :=
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ match w__0 with
+ | Machine => read_reg misa_ref >>= fun w__1 : Misa => returnm ((_get_Misa_MXL w__1) : arch_xlen)
+ | Supervisor =>
+ read_reg mstatus_ref >>= fun w__2 : Mstatus => returnm ((_get_Mstatus_SXL w__2) : arch_xlen)
+ | User =>
+ read_reg mstatus_ref >>= fun w__3 : Mstatus => returnm ((_get_Mstatus_UXL w__3) : arch_xlen)
+ end >>= fun a : arch_xlen =>
+ (match (architecture a) with
+ | Some (a) => returnm (a : Architecture)
+ | None => (internal_error "Invalid current architecture") : M (Architecture)
+ end)
+ : M (Architecture).
+
+Definition in32BitMode '(tt : unit)
+: M (bool) :=
+ cur_Architecture tt >>= fun w__0 : Architecture => returnm ((generic_eq w__0 RV32) : bool).
+
+Definition haveAtomics '(tt : unit)
+: M (bool) :=
+ read_reg misa_ref >>= fun w__0 : Misa =>
+ returnm ((eq_vec (_get_Misa_A w__0) ((bool_to_bits true) : mword 1))
+ : bool).
+
+Definition haveRVC '(tt : unit)
+: M (bool) :=
+ read_reg misa_ref >>= fun w__0 : Misa =>
+ returnm ((eq_vec (_get_Misa_C w__0) ((bool_to_bits true) : mword 1))
+ : bool).
+
+Definition haveMulDiv '(tt : unit)
+: M (bool) :=
+ read_reg misa_ref >>= fun w__0 : Misa =>
+ returnm ((eq_vec (_get_Misa_M w__0) ((bool_to_bits true) : mword 1))
+ : bool).
+
+Definition haveFP '(tt : unit)
+: M (bool) :=
+ (or_boolM
+ (read_reg misa_ref >>= fun w__0 : Misa =>
+ returnm ((eq_vec (_get_Misa_F w__0) ((bool_to_bits true) : mword 1))
+ : bool))
+ (read_reg misa_ref >>= fun w__1 : Misa =>
+ returnm ((eq_vec (_get_Misa_D w__1) ((bool_to_bits true) : mword 1))
+ : bool)))
+ : M (bool).
+
+Definition Mk_Minterrupts (v : mword 64)
+: Minterrupts :=
+ {| Minterrupts_Minterrupts_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Minterrupts_bits (v : Minterrupts)
+: mword 64 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 63 0.
+
+Definition _set_Minterrupts_bits (r_ref : register_ref regstate register_value Minterrupts) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_bits (v : Minterrupts) (x : mword 64)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Minterrupts_MEI (v : Minterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 11 11.
+
+Definition _set_Minterrupts_MEI (r_ref : register_ref regstate register_value Minterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 11 11 (subrange_vec_dec v 0 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_MEI (v : Minterrupts) (x : mword 1)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 11 11 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Minterrupts_SEI (v : Minterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 9 9.
+
+Definition _set_Minterrupts_SEI (r_ref : register_ref regstate register_value Minterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 9 9 (subrange_vec_dec v 0 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_SEI (v : Minterrupts) (x : mword 1)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 9 9 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Minterrupts_UEI (v : Minterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 8 8.
+
+Definition _set_Minterrupts_UEI (r_ref : register_ref regstate register_value Minterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 8 8 (subrange_vec_dec v 0 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_UEI (v : Minterrupts) (x : mword 1)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 8 8 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Minterrupts_MTI (v : Minterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 7 7.
+
+Definition _set_Minterrupts_MTI (r_ref : register_ref regstate register_value Minterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 7 7 (subrange_vec_dec v 0 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_MTI (v : Minterrupts) (x : mword 1)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 7 7 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Minterrupts_STI (v : Minterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 5 5.
+
+Definition _set_Minterrupts_STI (r_ref : register_ref regstate register_value Minterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 5 5 (subrange_vec_dec v 0 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_STI (v : Minterrupts) (x : mword 1)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 5 5 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Minterrupts_UTI (v : Minterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 4 4.
+
+Definition _set_Minterrupts_UTI (r_ref : register_ref regstate register_value Minterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 4 4 (subrange_vec_dec v 0 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_UTI (v : Minterrupts) (x : mword 1)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 4 4 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Minterrupts_MSI (v : Minterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 3 3.
+
+Definition _set_Minterrupts_MSI (r_ref : register_ref regstate register_value Minterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 3 3 (subrange_vec_dec v 0 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_MSI (v : Minterrupts) (x : mword 1)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 3 3 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Minterrupts_SSI (v : Minterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 1 1.
+
+Definition _set_Minterrupts_SSI (r_ref : register_ref regstate register_value Minterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_SSI (v : Minterrupts) (x : mword 1)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Minterrupts_USI (v : Minterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 0 0.
+
+Definition _set_Minterrupts_USI (r_ref : register_ref regstate register_value Minterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Minterrupts_Minterrupts_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
+ : Minterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Minterrupts_USI (v : Minterrupts) (x : mword 1)
+: Minterrupts :=
+ {[ v with
+ Minterrupts_Minterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Minterrupts_Minterrupts_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.
+
+Definition legalize_mip (o : Minterrupts) (v : mword 64)
+: Minterrupts :=
+ let v := Mk_Minterrupts v in
+ let m := _update_Minterrupts_SEI o (_get_Minterrupts_SEI v) in
+ let m := _update_Minterrupts_STI m (_get_Minterrupts_STI v) in
+ _update_Minterrupts_SSI m (_get_Minterrupts_SSI v).
+
+Definition legalize_mie (o : Minterrupts) (v : mword 64)
+: Minterrupts :=
+ let v := Mk_Minterrupts v in
+ let m := _update_Minterrupts_MEI o (_get_Minterrupts_MEI v) in
+ let m := _update_Minterrupts_MTI m (_get_Minterrupts_MTI v) in
+ let m := _update_Minterrupts_MSI m (_get_Minterrupts_MSI v) in
+ let m := _update_Minterrupts_SEI m (_get_Minterrupts_SEI v) in
+ let m := _update_Minterrupts_STI m (_get_Minterrupts_STI v) in
+ _update_Minterrupts_SSI m (_get_Minterrupts_SSI v).
+
+Definition legalize_mideleg (o : Minterrupts) (v : mword 64)
+: Minterrupts :=
+ let m := Mk_Minterrupts v in
+ let m := _update_Minterrupts_MEI m ((bool_to_bits false) : mword 1) in
+ let m := _update_Minterrupts_MTI m ((bool_to_bits false) : mword 1) in
+ _update_Minterrupts_MSI m ((bool_to_bits false) : mword 1).
+
+Definition Mk_Medeleg (v : mword 64)
+: Medeleg :=
+ {| Medeleg_Medeleg_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Medeleg_bits (v : Medeleg)
+: mword 64 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 63 0.
+
+Definition _set_Medeleg_bits (r_ref : register_ref regstate register_value Medeleg) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_bits (v : Medeleg) (x : mword 64)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Medeleg_SAMO_Page_Fault (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 15 15.
+
+Definition _set_Medeleg_SAMO_Page_Fault (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 15 15 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_SAMO_Page_Fault (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 15 15 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_Load_Page_Fault (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 13 13.
+
+Definition _set_Medeleg_Load_Page_Fault (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 13 13 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_Load_Page_Fault (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 13 13 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_Fetch_Page_Fault (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 12 12.
+
+Definition _set_Medeleg_Fetch_Page_Fault (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 12 12 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_Fetch_Page_Fault (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 12 12 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_MEnvCall (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 10 10.
+
+Definition _set_Medeleg_MEnvCall (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 10 10 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_MEnvCall (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 10 10 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_SEnvCall (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 9 9.
+
+Definition _set_Medeleg_SEnvCall (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 9 9 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_SEnvCall (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 9 9 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_UEnvCall (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 8 8.
+
+Definition _set_Medeleg_UEnvCall (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 8 8 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_UEnvCall (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 8 8 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_SAMO_Access_Fault (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 7 7.
+
+Definition _set_Medeleg_SAMO_Access_Fault (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 7 7 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_SAMO_Access_Fault (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 7 7 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_SAMO_Addr_Align (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 6 6.
+
+Definition _set_Medeleg_SAMO_Addr_Align (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 6 6 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_SAMO_Addr_Align (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 6 6 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_Load_Access_Fault (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 5 5.
+
+Definition _set_Medeleg_Load_Access_Fault (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 5 5 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_Load_Access_Fault (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 5 5 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_Load_Addr_Align (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 4 4.
+
+Definition _set_Medeleg_Load_Addr_Align (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 4 4 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_Load_Addr_Align (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 4 4 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_Breakpoint (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 3 3.
+
+Definition _set_Medeleg_Breakpoint (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 3 3 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_Breakpoint (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 3 3 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_Illegal_Instr (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 2 2.
+
+Definition _set_Medeleg_Illegal_Instr (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 2 2 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_Illegal_Instr (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 2 2 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_Fetch_Access_Fault (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 1 1.
+
+Definition _set_Medeleg_Fetch_Access_Fault (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_Fetch_Access_Fault (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Medeleg_Fetch_Addr_Align (v : Medeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 0 0.
+
+Definition _set_Medeleg_Fetch_Addr_Align (r_ref : register_ref regstate register_value Medeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Medeleg_Medeleg_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
+ : Medeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Medeleg_Fetch_Addr_Align (v : Medeleg) (x : mword 1)
+: Medeleg :=
+ {[ v with
+ Medeleg_Medeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Medeleg_Medeleg_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.
+
+Definition legalize_medeleg (o : Medeleg) (v : mword 64)
+: Medeleg :=
+ let m := Mk_Medeleg v in
+ _update_Medeleg_MEnvCall m ((bool_to_bits false) : mword 1).
+
+Definition Mk_Mtvec (v : mword 64)
+: Mtvec :=
+ {| Mtvec_Mtvec_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Mtvec_bits (v : Mtvec) : mword 64 := subrange_vec_dec v.(Mtvec_Mtvec_chunk_0) 63 0.
+
+Definition _set_Mtvec_bits (r_ref : register_ref regstate register_value Mtvec) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mtvec_Mtvec_chunk_0 :=
+ (update_subrange_vec_dec r.(Mtvec_Mtvec_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Mtvec in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mtvec_bits (v : Mtvec) (x : mword 64)
+: Mtvec :=
+ {[ v with
+ Mtvec_Mtvec_chunk_0 :=
+ (update_subrange_vec_dec v.(Mtvec_Mtvec_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Mtvec_Base (v : Mtvec) : mword 62 := subrange_vec_dec v.(Mtvec_Mtvec_chunk_0) 63 2.
+
+Definition _set_Mtvec_Base (r_ref : register_ref regstate register_value Mtvec) (v : mword 62)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mtvec_Mtvec_chunk_0 :=
+ (update_subrange_vec_dec r.(Mtvec_Mtvec_chunk_0) 63 2 (subrange_vec_dec v 61 0)) ]}
+ : Mtvec in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mtvec_Base (v : Mtvec) (x : mword 62)
+: Mtvec :=
+ {[ v with
+ Mtvec_Mtvec_chunk_0 :=
+ (update_subrange_vec_dec v.(Mtvec_Mtvec_chunk_0) 63 2 (subrange_vec_dec x 61 0)) ]}.
+
+Definition _get_Mtvec_Mode (v : Mtvec) : mword 2 := subrange_vec_dec v.(Mtvec_Mtvec_chunk_0) 1 0.
+
+Definition _set_Mtvec_Mode (r_ref : register_ref regstate register_value Mtvec) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mtvec_Mtvec_chunk_0 :=
+ (update_subrange_vec_dec r.(Mtvec_Mtvec_chunk_0) 1 0 (subrange_vec_dec v 1 0)) ]}
+ : Mtvec in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mtvec_Mode (v : Mtvec) (x : mword 2)
+: Mtvec :=
+ {[ v with
+ Mtvec_Mtvec_chunk_0 :=
+ (update_subrange_vec_dec v.(Mtvec_Mtvec_chunk_0) 1 0 (subrange_vec_dec x 1 0)) ]}.
+
+Definition legalize_tvec (o : Mtvec) (v : mword 64)
+: Mtvec :=
+ let v := Mk_Mtvec v in
+ match (trapVectorMode_of_bits (_get_Mtvec_Mode v)) with
+ | TV_Direct => v
+ | TV_Vector => v
+ | _ => _update_Mtvec_Mode v (_get_Mtvec_Mode o)
+ end.
+
+Definition Mk_Mcause (v : mword 64)
+: Mcause :=
+ {| Mcause_Mcause_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Mcause_bits (v : Mcause)
+: mword 64 :=
+ subrange_vec_dec v.(Mcause_Mcause_chunk_0) 63 0.
+
+Definition _set_Mcause_bits (r_ref : register_ref regstate register_value Mcause) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mcause_Mcause_chunk_0 :=
+ (update_subrange_vec_dec r.(Mcause_Mcause_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Mcause in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mcause_bits (v : Mcause) (x : mword 64)
+: Mcause :=
+ {[ v with
+ Mcause_Mcause_chunk_0 :=
+ (update_subrange_vec_dec v.(Mcause_Mcause_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Mcause_IsInterrupt (v : Mcause)
+: mword 1 :=
+ subrange_vec_dec v.(Mcause_Mcause_chunk_0) 63 63.
+
+Definition _set_Mcause_IsInterrupt (r_ref : register_ref regstate register_value Mcause) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mcause_Mcause_chunk_0 :=
+ (update_subrange_vec_dec r.(Mcause_Mcause_chunk_0) 63 63 (subrange_vec_dec v 0 0)) ]}
+ : Mcause in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mcause_IsInterrupt (v : Mcause) (x : mword 1)
+: Mcause :=
+ {[ v with
+ Mcause_Mcause_chunk_0 :=
+ (update_subrange_vec_dec v.(Mcause_Mcause_chunk_0) 63 63 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Mcause_Cause (v : Mcause)
+: mword 63 :=
+ subrange_vec_dec v.(Mcause_Mcause_chunk_0) 62 0.
+
+Definition _set_Mcause_Cause (r_ref : register_ref regstate register_value Mcause) (v : mword 63)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Mcause_Mcause_chunk_0 :=
+ (update_subrange_vec_dec r.(Mcause_Mcause_chunk_0) 62 0 (subrange_vec_dec v 62 0)) ]}
+ : Mcause in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Mcause_Cause (v : Mcause) (x : mword 63)
+: Mcause :=
+ {[ v with
+ Mcause_Mcause_chunk_0 :=
+ (update_subrange_vec_dec v.(Mcause_Mcause_chunk_0) 62 0 (subrange_vec_dec x 62 0)) ]}.
+
+Definition tvec_addr (m : Mtvec) (c : Mcause)
+: option (mword 64) :=
+ let base : xlenbits := concat_vec (_get_Mtvec_Base m) (vec_of_bits [B0;B0] : mword 2) in
+ match (trapVectorMode_of_bits (_get_Mtvec_Mode m)) with
+ | TV_Direct => Some base
+ | TV_Vector =>
+ if ((eq_vec (_get_Mcause_IsInterrupt c) ((bool_to_bits true) : mword 1))) then
+ Some (add_vec base
+ (shift_bits_left (EXTZ 64 (_get_Mcause_Cause c)) (vec_of_bits [B1;B0] : mword 2)))
+ else Some base
+ | TV_Reserved => None
+ end.
+
+Definition legalize_xepc (v : mword 64)
+: M (mword 64) :=
+ haveRVC tt >>= fun w__0 : bool =>
+ returnm ((and_vec v
+ (EXTS 64
+ (if (w__0) then (vec_of_bits [B1;B1;B0] : mword 3)
+ else (vec_of_bits [B1;B0;B0] : mword 3))))
+ : mword 64).
+
+Definition pc_alignment_mask '(tt : unit)
+: M (mword 64) :=
+ read_reg misa_ref >>= fun w__0 : Misa =>
+ returnm ((not_vec
+ (EXTZ 64
+ (if ((eq_vec (_get_Misa_C w__0) ((bool_to_bits true) : mword 1))) then
+ (vec_of_bits [B0;B0] : mword 2)
+ else (vec_of_bits [B1;B0] : mword 2))))
+ : mword 64).
+
+Definition Mk_Counteren (v : mword 32)
+: Counteren :=
+ {| Counteren_Counteren_chunk_0 := (subrange_vec_dec v 31 0) |}.
+
+Definition _get_Counteren_bits (v : Counteren)
+: mword 32 :=
+ subrange_vec_dec v.(Counteren_Counteren_chunk_0) 31 0.
+
+Definition _set_Counteren_bits (r_ref : register_ref regstate register_value Counteren) (v : mword 32)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec r.(Counteren_Counteren_chunk_0) 31 0 (subrange_vec_dec v 31 0)) ]}
+ : Counteren in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Counteren_bits (v : Counteren) (x : mword 32)
+: Counteren :=
+ {[ v with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec v.(Counteren_Counteren_chunk_0) 31 0 (subrange_vec_dec x 31 0)) ]}.
+
+Definition _get_Counteren_HPM (v : Counteren)
+: mword 29 :=
+ subrange_vec_dec v.(Counteren_Counteren_chunk_0) 31 3.
+
+Definition _set_Counteren_HPM (r_ref : register_ref regstate register_value Counteren) (v : mword 29)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec r.(Counteren_Counteren_chunk_0) 31 3 (subrange_vec_dec v 28 0)) ]}
+ : Counteren in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Counteren_HPM (v : Counteren) (x : mword 29)
+: Counteren :=
+ {[ v with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec v.(Counteren_Counteren_chunk_0) 31 3 (subrange_vec_dec x 28 0)) ]}.
+
+Definition _get_Counteren_IR (v : Counteren)
+: mword 1 :=
+ subrange_vec_dec v.(Counteren_Counteren_chunk_0) 2 2.
+
+Definition _set_Counteren_IR (r_ref : register_ref regstate register_value Counteren) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec r.(Counteren_Counteren_chunk_0) 2 2 (subrange_vec_dec v 0 0)) ]}
+ : Counteren in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Counteren_IR (v : Counteren) (x : mword 1)
+: Counteren :=
+ {[ v with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec v.(Counteren_Counteren_chunk_0) 2 2 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Counteren_TM (v : Counteren)
+: mword 1 :=
+ subrange_vec_dec v.(Counteren_Counteren_chunk_0) 1 1.
+
+Definition _set_Counteren_TM (r_ref : register_ref regstate register_value Counteren) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec r.(Counteren_Counteren_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
+ : Counteren in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Counteren_TM (v : Counteren) (x : mword 1)
+: Counteren :=
+ {[ v with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec v.(Counteren_Counteren_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Counteren_CY (v : Counteren)
+: mword 1 :=
+ subrange_vec_dec v.(Counteren_Counteren_chunk_0) 0 0.
+
+Definition _set_Counteren_CY (r_ref : register_ref regstate register_value Counteren) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec r.(Counteren_Counteren_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
+ : Counteren in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Counteren_CY (v : Counteren) (x : mword 1)
+: Counteren :=
+ {[ v with
+ Counteren_Counteren_chunk_0 :=
+ (update_subrange_vec_dec v.(Counteren_Counteren_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.
+
+Definition legalize_mcounteren (c : Counteren) (v : mword 64)
+: M (Counteren) :=
+ cast_unit_vec (access_vec_dec v 2) >>= fun w__0 : mword 1 =>
+ let c := _update_Counteren_IR c (w__0 : mword 1) in
+ cast_unit_vec (access_vec_dec v 1) >>= fun w__1 : mword 1 =>
+ let c := _update_Counteren_TM c (w__1 : mword 1) in
+ cast_unit_vec (access_vec_dec v 0) >>= fun w__2 : mword 1 =>
+ let c := _update_Counteren_CY c (w__2 : mword 1) in
+ returnm (c
+ : Counteren).
+
+Definition legalize_scounteren (c : Counteren) (v : mword 64)
+: M (Counteren) :=
+ cast_unit_vec (access_vec_dec v 2) >>= fun w__0 : mword 1 =>
+ let c := _update_Counteren_IR c (w__0 : mword 1) in
+ cast_unit_vec (access_vec_dec v 1) >>= fun w__1 : mword 1 =>
+ let c := _update_Counteren_TM c (w__1 : mword 1) in
+ cast_unit_vec (access_vec_dec v 0) >>= fun w__2 : mword 1 =>
+ let c := _update_Counteren_CY c (w__2 : mword 1) in
+ returnm (c
+ : Counteren).
+
+Definition retire_instruction '(tt : unit)
+: M (unit) :=
+ read_reg minstret_written_ref >>= fun w__0 : bool =>
+ (if ((eq_vec ((bool_to_bits w__0) : mword 1) ((bool_to_bits true) : mword 1))) then
+ write_reg minstret_written_ref false
+ : M (unit)
+ else
+ (read_reg minstret_ref : M (mword 64)) >>= fun w__1 : mword 64 =>
+ write_reg minstret_ref (add_vec_int w__1 1)
+ : M (unit))
+ : M (unit).
+
+Definition Mk_Sstatus (v : mword 64)
+: Sstatus :=
+ {| Sstatus_Sstatus_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Sstatus_bits (v : Sstatus)
+: mword 64 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 63 0.
+
+Definition _set_Sstatus_bits (r_ref : register_ref regstate register_value Sstatus) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_bits (v : Sstatus) (x : mword 64)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Sstatus_SD (v : Sstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 63 63.
+
+Definition _set_Sstatus_SD (r_ref : register_ref regstate register_value Sstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 63 63 (subrange_vec_dec v 0 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_SD (v : Sstatus) (x : mword 1)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 63 63 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sstatus_UXL (v : Sstatus)
+: mword 2 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 33 32.
+
+Definition _set_Sstatus_UXL (r_ref : register_ref regstate register_value Sstatus) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 33 32 (subrange_vec_dec v 1 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_UXL (v : Sstatus) (x : mword 2)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 33 32 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_Sstatus_MXR (v : Sstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 19 19.
+
+Definition _set_Sstatus_MXR (r_ref : register_ref regstate register_value Sstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 19 19 (subrange_vec_dec v 0 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_MXR (v : Sstatus) (x : mword 1)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 19 19 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sstatus_SUM (v : Sstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 18 18.
+
+Definition _set_Sstatus_SUM (r_ref : register_ref regstate register_value Sstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 18 18 (subrange_vec_dec v 0 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_SUM (v : Sstatus) (x : mword 1)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 18 18 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sstatus_XS (v : Sstatus)
+: mword 2 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 16 15.
+
+Definition _set_Sstatus_XS (r_ref : register_ref regstate register_value Sstatus) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 16 15 (subrange_vec_dec v 1 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_XS (v : Sstatus) (x : mword 2)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 16 15 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_Sstatus_FS (v : Sstatus)
+: mword 2 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 14 13.
+
+Definition _set_Sstatus_FS (r_ref : register_ref regstate register_value Sstatus) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 14 13 (subrange_vec_dec v 1 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_FS (v : Sstatus) (x : mword 2)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 14 13 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_Sstatus_SPP (v : Sstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 8 8.
+
+Definition _set_Sstatus_SPP (r_ref : register_ref regstate register_value Sstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 8 8 (subrange_vec_dec v 0 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_SPP (v : Sstatus) (x : mword 1)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 8 8 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sstatus_SPIE (v : Sstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 5 5.
+
+Definition _set_Sstatus_SPIE (r_ref : register_ref regstate register_value Sstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 5 5 (subrange_vec_dec v 0 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_SPIE (v : Sstatus) (x : mword 1)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 5 5 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sstatus_UPIE (v : Sstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 4 4.
+
+Definition _set_Sstatus_UPIE (r_ref : register_ref regstate register_value Sstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 4 4 (subrange_vec_dec v 0 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_UPIE (v : Sstatus) (x : mword 1)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 4 4 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sstatus_SIE (v : Sstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 1 1.
+
+Definition _set_Sstatus_SIE (r_ref : register_ref regstate register_value Sstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_SIE (v : Sstatus) (x : mword 1)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sstatus_UIE (v : Sstatus)
+: mword 1 :=
+ subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 0 0.
+
+Definition _set_Sstatus_UIE (r_ref : register_ref regstate register_value Sstatus) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec r.(Sstatus_Sstatus_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
+ : Sstatus in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sstatus_UIE (v : Sstatus) (x : mword 1)
+: Sstatus :=
+ {[ v with
+ Sstatus_Sstatus_chunk_0 :=
+ (update_subrange_vec_dec v.(Sstatus_Sstatus_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.
+
+Definition lower_mstatus (m : Mstatus)
+: Sstatus :=
+ let s := Mk_Sstatus (EXTZ 64 (vec_of_bits [B0] : mword 1)) in
+ let s := _update_Sstatus_SD s (_get_Mstatus_SD m) in
+ let s := _update_Sstatus_UXL s (_get_Mstatus_UXL m) in
+ let s := _update_Sstatus_MXR s (_get_Mstatus_MXR m) in
+ let s := _update_Sstatus_SUM s (_get_Mstatus_SUM m) in
+ let s := _update_Sstatus_XS s (_get_Mstatus_XS m) in
+ let s := _update_Sstatus_FS s (_get_Mstatus_FS m) in
+ let s := _update_Sstatus_SPP s (_get_Mstatus_SPP m) in
+ let s := _update_Sstatus_SPIE s (_get_Mstatus_SPIE m) in
+ let s := _update_Sstatus_UPIE s (_get_Mstatus_UPIE m) in
+ let s := _update_Sstatus_SIE s (_get_Mstatus_SIE m) in
+ _update_Sstatus_UIE s (_get_Mstatus_UIE m).
+
+Definition lift_sstatus (m : Mstatus) (s : Sstatus)
+: Mstatus :=
+ let m := _update_Mstatus_SD m (_get_Sstatus_SD s) in
+ let m := _update_Mstatus_MXR m (_get_Sstatus_MXR s) in
+ let m := _update_Mstatus_SUM m (_get_Sstatus_SUM s) in
+ let m := _update_Mstatus_XS m (_get_Sstatus_XS s) in
+ let m := _update_Mstatus_FS m (_get_Sstatus_FS s) in
+ let m := _update_Mstatus_SPP m (_get_Sstatus_SPP s) in
+ let m := _update_Mstatus_SPIE m (_get_Sstatus_SPIE s) in
+ let m := _update_Mstatus_UPIE m (_get_Sstatus_UPIE s) in
+ let m := _update_Mstatus_SIE m (_get_Sstatus_SIE s) in
+ _update_Mstatus_UIE m (_get_Sstatus_UIE s).
+
+Definition legalize_sstatus (m : Mstatus) (v : mword 64)
+: Mstatus :=
+ lift_sstatus m (Mk_Sstatus v).
+
+Definition Mk_Sedeleg (v : mword 64)
+: Sedeleg :=
+ {| Sedeleg_Sedeleg_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Sedeleg_bits (v : Sedeleg)
+: mword 64 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 63 0.
+
+Definition _set_Sedeleg_bits (r_ref : register_ref regstate register_value Sedeleg) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_bits (v : Sedeleg) (x : mword 64)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Sedeleg_UEnvCall (v : Sedeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 8 8.
+
+Definition _set_Sedeleg_UEnvCall (r_ref : register_ref regstate register_value Sedeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 8 8 (subrange_vec_dec v 0 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_UEnvCall (v : Sedeleg) (x : mword 1)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 8 8 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sedeleg_SAMO_Access_Fault (v : Sedeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 7 7.
+
+Definition _set_Sedeleg_SAMO_Access_Fault (r_ref : register_ref regstate register_value Sedeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 7 7 (subrange_vec_dec v 0 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_SAMO_Access_Fault (v : Sedeleg) (x : mword 1)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 7 7 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sedeleg_SAMO_Addr_Align (v : Sedeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 6 6.
+
+Definition _set_Sedeleg_SAMO_Addr_Align (r_ref : register_ref regstate register_value Sedeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 6 6 (subrange_vec_dec v 0 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_SAMO_Addr_Align (v : Sedeleg) (x : mword 1)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 6 6 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sedeleg_Load_Access_Fault (v : Sedeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 5 5.
+
+Definition _set_Sedeleg_Load_Access_Fault (r_ref : register_ref regstate register_value Sedeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 5 5 (subrange_vec_dec v 0 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_Load_Access_Fault (v : Sedeleg) (x : mword 1)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 5 5 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sedeleg_Load_Addr_Align (v : Sedeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 4 4.
+
+Definition _set_Sedeleg_Load_Addr_Align (r_ref : register_ref regstate register_value Sedeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 4 4 (subrange_vec_dec v 0 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_Load_Addr_Align (v : Sedeleg) (x : mword 1)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 4 4 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sedeleg_Breakpoint (v : Sedeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 3 3.
+
+Definition _set_Sedeleg_Breakpoint (r_ref : register_ref regstate register_value Sedeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 3 3 (subrange_vec_dec v 0 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_Breakpoint (v : Sedeleg) (x : mword 1)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 3 3 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sedeleg_Illegal_Instr (v : Sedeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 2 2.
+
+Definition _set_Sedeleg_Illegal_Instr (r_ref : register_ref regstate register_value Sedeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 2 2 (subrange_vec_dec v 0 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_Illegal_Instr (v : Sedeleg) (x : mword 1)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 2 2 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sedeleg_Fetch_Access_Fault (v : Sedeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 1 1.
+
+Definition _set_Sedeleg_Fetch_Access_Fault (r_ref : register_ref regstate register_value Sedeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_Fetch_Access_Fault (v : Sedeleg) (x : mword 1)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sedeleg_Fetch_Addr_Align (v : Sedeleg)
+: mword 1 :=
+ subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 0 0.
+
+Definition _set_Sedeleg_Fetch_Addr_Align (r_ref : register_ref regstate register_value Sedeleg) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec r.(Sedeleg_Sedeleg_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
+ : Sedeleg in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sedeleg_Fetch_Addr_Align (v : Sedeleg) (x : mword 1)
+: Sedeleg :=
+ {[ v with
+ Sedeleg_Sedeleg_chunk_0 :=
+ (update_subrange_vec_dec v.(Sedeleg_Sedeleg_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.
+
+Definition legalize_sedeleg (s : Sedeleg) (v : mword 64)
+: Sedeleg :=
+ Mk_Sedeleg (EXTZ 64 (subrange_vec_dec v 8 0)).
+
+Definition Mk_Sinterrupts (v : mword 64)
+: Sinterrupts :=
+ {| Sinterrupts_Sinterrupts_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Sinterrupts_bits (v : Sinterrupts)
+: mword 64 :=
+ subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 63 0.
+
+Definition _set_Sinterrupts_bits (r_ref : register_ref regstate register_value Sinterrupts) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Sinterrupts_Sinterrupts_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Sinterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sinterrupts_bits (v : Sinterrupts) (x : mword 64)
+: Sinterrupts :=
+ {[ v with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Sinterrupts_SEI (v : Sinterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 9 9.
+
+Definition _set_Sinterrupts_SEI (r_ref : register_ref regstate register_value Sinterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Sinterrupts_Sinterrupts_chunk_0) 9 9 (subrange_vec_dec v 0 0)) ]}
+ : Sinterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sinterrupts_SEI (v : Sinterrupts) (x : mword 1)
+: Sinterrupts :=
+ {[ v with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 9 9 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sinterrupts_UEI (v : Sinterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 8 8.
+
+Definition _set_Sinterrupts_UEI (r_ref : register_ref regstate register_value Sinterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Sinterrupts_Sinterrupts_chunk_0) 8 8 (subrange_vec_dec v 0 0)) ]}
+ : Sinterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sinterrupts_UEI (v : Sinterrupts) (x : mword 1)
+: Sinterrupts :=
+ {[ v with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 8 8 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sinterrupts_STI (v : Sinterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 5 5.
+
+Definition _set_Sinterrupts_STI (r_ref : register_ref regstate register_value Sinterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Sinterrupts_Sinterrupts_chunk_0) 5 5 (subrange_vec_dec v 0 0)) ]}
+ : Sinterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sinterrupts_STI (v : Sinterrupts) (x : mword 1)
+: Sinterrupts :=
+ {[ v with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 5 5 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sinterrupts_UTI (v : Sinterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 4 4.
+
+Definition _set_Sinterrupts_UTI (r_ref : register_ref regstate register_value Sinterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Sinterrupts_Sinterrupts_chunk_0) 4 4 (subrange_vec_dec v 0 0)) ]}
+ : Sinterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sinterrupts_UTI (v : Sinterrupts) (x : mword 1)
+: Sinterrupts :=
+ {[ v with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 4 4 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sinterrupts_SSI (v : Sinterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 1 1.
+
+Definition _set_Sinterrupts_SSI (r_ref : register_ref regstate register_value Sinterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Sinterrupts_Sinterrupts_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
+ : Sinterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sinterrupts_SSI (v : Sinterrupts) (x : mword 1)
+: Sinterrupts :=
+ {[ v with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_Sinterrupts_USI (v : Sinterrupts)
+: mword 1 :=
+ subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 0 0.
+
+Definition _set_Sinterrupts_USI (r_ref : register_ref regstate register_value Sinterrupts) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec r.(Sinterrupts_Sinterrupts_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
+ : Sinterrupts in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Sinterrupts_USI (v : Sinterrupts) (x : mword 1)
+: Sinterrupts :=
+ {[ v with
+ Sinterrupts_Sinterrupts_chunk_0 :=
+ (update_subrange_vec_dec v.(Sinterrupts_Sinterrupts_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.
+
+Definition lower_mip (m : Minterrupts) (d : Minterrupts)
+: Sinterrupts :=
+ let s : Sinterrupts := Mk_Sinterrupts (EXTZ 64 (vec_of_bits [B0] : mword 1)) in
+ let s := _update_Sinterrupts_SEI s (and_vec (_get_Minterrupts_SEI m) (_get_Minterrupts_SEI d)) in
+ let s := _update_Sinterrupts_STI s (and_vec (_get_Minterrupts_STI m) (_get_Minterrupts_STI d)) in
+ let s := _update_Sinterrupts_SSI s (and_vec (_get_Minterrupts_SSI m) (_get_Minterrupts_SSI d)) in
+ let s := _update_Sinterrupts_UEI s (and_vec (_get_Minterrupts_UEI m) (_get_Minterrupts_UEI d)) in
+ let s := _update_Sinterrupts_UTI s (and_vec (_get_Minterrupts_UTI m) (_get_Minterrupts_UTI d)) in
+ _update_Sinterrupts_USI s (and_vec (_get_Minterrupts_USI m) (_get_Minterrupts_USI d)).
+
+Definition lower_mie (m : Minterrupts) (d : Minterrupts)
+: Sinterrupts :=
+ let s : Sinterrupts := Mk_Sinterrupts (EXTZ 64 (vec_of_bits [B0] : mword 1)) in
+ let s := _update_Sinterrupts_SEI s (and_vec (_get_Minterrupts_SEI m) (_get_Minterrupts_SEI d)) in
+ let s := _update_Sinterrupts_STI s (and_vec (_get_Minterrupts_STI m) (_get_Minterrupts_STI d)) in
+ let s := _update_Sinterrupts_SSI s (and_vec (_get_Minterrupts_SSI m) (_get_Minterrupts_SSI d)) in
+ let s := _update_Sinterrupts_UEI s (and_vec (_get_Minterrupts_UEI m) (_get_Minterrupts_UEI d)) in
+ let s := _update_Sinterrupts_UTI s (and_vec (_get_Minterrupts_UTI m) (_get_Minterrupts_UTI d)) in
+ _update_Sinterrupts_USI s (and_vec (_get_Minterrupts_USI m) (_get_Minterrupts_USI d)).
+
+Definition lift_sip (o : Minterrupts) (d : Minterrupts) (s : Sinterrupts)
+: Minterrupts :=
+ let m : Minterrupts := o in
+ let m := _update_Minterrupts_SSI m (and_vec (_get_Sinterrupts_SSI s) (_get_Minterrupts_SSI d)) in
+ let m := _update_Minterrupts_UEI m (and_vec (_get_Minterrupts_UEI m) (_get_Minterrupts_UEI d)) in
+ _update_Minterrupts_USI m (and_vec (_get_Minterrupts_USI m) (_get_Minterrupts_USI d)).
+
+Definition legalize_sip (m : Minterrupts) (d : Minterrupts) (v : mword 64)
+: Minterrupts :=
+ lift_sip m d (Mk_Sinterrupts v).
+
+Definition lift_sie (o : Minterrupts) (d : Minterrupts) (s : Sinterrupts)
+: Minterrupts :=
+ let m : Minterrupts := o in
+ let m :=
+ if ((eq_vec (_get_Minterrupts_SEI d) ((bool_to_bits true) : mword 1))) then
+ _update_Minterrupts_SEI m (_get_Sinterrupts_SEI s)
+ else m in
+ let m :=
+ if ((eq_vec (_get_Minterrupts_STI d) ((bool_to_bits true) : mword 1))) then
+ _update_Minterrupts_STI m (_get_Sinterrupts_STI s)
+ else m in
+ let m :=
+ if ((eq_vec (_get_Minterrupts_SSI d) ((bool_to_bits true) : mword 1))) then
+ _update_Minterrupts_SSI m (_get_Sinterrupts_SSI s)
+ else m in
+ let m :=
+ if ((eq_vec (_get_Minterrupts_UEI d) ((bool_to_bits true) : mword 1))) then
+ _update_Minterrupts_UEI m (_get_Sinterrupts_UEI s)
+ else m in
+ let m :=
+ if ((eq_vec (_get_Minterrupts_UTI d) ((bool_to_bits true) : mword 1))) then
+ _update_Minterrupts_UTI m (_get_Sinterrupts_UTI s)
+ else m in
+ if ((eq_vec (_get_Minterrupts_USI d) ((bool_to_bits true) : mword 1))) then
+ _update_Minterrupts_USI m (_get_Sinterrupts_USI s)
+ else m.
+
+Definition legalize_sie (m : Minterrupts) (d : Minterrupts) (v : mword 64)
+: Minterrupts :=
+ lift_sie m d (Mk_Sinterrupts v).
+
+Definition Mk_Satp64 (v : mword 64)
+: Satp64 :=
+ {| Satp64_Satp64_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_Satp64_bits (v : Satp64)
+: mword 64 :=
+ subrange_vec_dec v.(Satp64_Satp64_chunk_0) 63 0.
+
+Definition _set_Satp64_bits (r_ref : register_ref regstate register_value Satp64) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Satp64_Satp64_chunk_0 :=
+ (update_subrange_vec_dec r.(Satp64_Satp64_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : Satp64 in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Satp64_bits (v : Satp64) (x : mword 64)
+: Satp64 :=
+ {[ v with
+ Satp64_Satp64_chunk_0 :=
+ (update_subrange_vec_dec v.(Satp64_Satp64_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_Satp64_Mode (v : Satp64)
+: mword 4 :=
+ subrange_vec_dec v.(Satp64_Satp64_chunk_0) 63 60.
+
+Definition _set_Satp64_Mode (r_ref : register_ref regstate register_value Satp64) (v : mword 4)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Satp64_Satp64_chunk_0 :=
+ (update_subrange_vec_dec r.(Satp64_Satp64_chunk_0) 63 60 (subrange_vec_dec v 3 0)) ]}
+ : Satp64 in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Satp64_Mode (v : Satp64) (x : mword 4)
+: Satp64 :=
+ {[ v with
+ Satp64_Satp64_chunk_0 :=
+ (update_subrange_vec_dec v.(Satp64_Satp64_chunk_0) 63 60 (subrange_vec_dec x 3 0)) ]}.
+
+Definition _get_Satp64_Asid (v : Satp64)
+: mword 16 :=
+ subrange_vec_dec v.(Satp64_Satp64_chunk_0) 59 44.
+
+Definition _set_Satp64_Asid (r_ref : register_ref regstate register_value Satp64) (v : mword 16)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Satp64_Satp64_chunk_0 :=
+ (update_subrange_vec_dec r.(Satp64_Satp64_chunk_0) 59 44 (subrange_vec_dec v 15 0)) ]}
+ : Satp64 in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Satp64_Asid (v : Satp64) (x : mword 16)
+: Satp64 :=
+ {[ v with
+ Satp64_Satp64_chunk_0 :=
+ (update_subrange_vec_dec v.(Satp64_Satp64_chunk_0) 59 44 (subrange_vec_dec x 15 0)) ]}.
+
+Definition _get_Satp64_PPN (v : Satp64)
+: mword 44 :=
+ subrange_vec_dec v.(Satp64_Satp64_chunk_0) 43 0.
+
+Definition _set_Satp64_PPN (r_ref : register_ref regstate register_value Satp64) (v : mword 44)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ Satp64_Satp64_chunk_0 :=
+ (update_subrange_vec_dec r.(Satp64_Satp64_chunk_0) 43 0 (subrange_vec_dec v 43 0)) ]}
+ : Satp64 in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_Satp64_PPN (v : Satp64) (x : mword 44)
+: Satp64 :=
+ {[ v with
+ Satp64_Satp64_chunk_0 :=
+ (update_subrange_vec_dec v.(Satp64_Satp64_chunk_0) 43 0 (subrange_vec_dec x 43 0)) ]}.
+
+Definition legalize_satp (a : Architecture) (o : mword 64) (v : mword 64)
+: mword 64 :=
+ let s := Mk_Satp64 v in
+ match (satpMode_of_bits a (_get_Satp64_Mode s)) with
+ | None => o
+ | Some (Sv32) => o
+ | Some (_) => _get_Satp64_bits s
+ end.
+
+Definition csr_name (csr : mword 12)
+: string :=
+ let b__0 := csr in
+ if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then "ustatus"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ "uie"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ "utvec"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "fflags"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "frm"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "fcsr"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "cycle"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "time"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "instret"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "cycleh"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "timeh"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "instreth"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "sstatus"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "sedeleg"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "sideleg"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ "sie"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ "stvec"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ "scounteren"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "sscratch"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "sepc"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "scause"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "stval"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ "sip"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "satp"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B0;B1] : mword 12))) then
+ "mvendorid"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B0] : mword 12))) then
+ "marchid"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B1] : mword 12))) then
+ "mimpid"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B1;B0;B0] : mword 12))) then
+ "mhartid"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "mstatus"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "misa"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "medeleg"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "mideleg"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ "mie"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ "mtvec"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ "mcounteren"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "mscratch"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "mepc"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "mcause"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "mtval"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ "mip"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ "pmpcfg0"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B0] : mword 12))) then
+ "pmpaddr0"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "mcycle"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "minstret"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "mcycleh"
+ else if ((eq_vec b__0 (vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "minstreth"
+ else if ((eq_vec b__0 (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ "tselect"
+ else "UNKNOWN".
+
+Definition csr_name_map_forwards (arg_ : mword 12)
+: string :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then "ustatus"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then "uie"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ "utvec"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "uscratch"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "uepc"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "ucause"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "utval"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then "uip"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "fflags"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then "frm"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "fcsr"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "cycle"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "time"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "instret"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "cycleh"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "timeh"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "instreth"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "sstatus"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "sedeleg"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "sideleg"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then "sie"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ "stvec"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ "scounteren"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "sscratch"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "sepc"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "scause"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "stval"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then "sip"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "satp"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B0;B1] : mword 12))) then
+ "mvendorid"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B0] : mword 12))) then
+ "marchid"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B1] : mword 12))) then
+ "mimpid"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B1;B0;B0] : mword 12))) then
+ "mhartid"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "mstatus"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "misa"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "medeleg"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "mideleg"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then "mie"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ "mtvec"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ "mcounteren"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "mscratch"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ "mepc"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "mcause"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ "mtval"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then "mip"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ "pmpcfg0"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B1] : mword 12))) then
+ "pmpcfg1"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B1;B0] : mword 12))) then
+ "pmpcfg2"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B1;B1] : mword 12))) then
+ "pmpcfg3"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B0] : mword 12))) then
+ "pmpaddr0"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B1] : mword 12))) then
+ "pmpaddr1"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B1;B0] : mword 12))) then
+ "pmpaddr2"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B1;B1] : mword 12))) then
+ "pmpaddr3"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B0;B0] : mword 12))) then
+ "pmpaddr4"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B0;B1] : mword 12))) then
+ "pmpaddr5"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B1;B0] : mword 12))) then
+ "pmpaddr6"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B1;B1] : mword 12))) then
+ "pmpaddr7"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;B0] : mword 12))) then
+ "pmpaddr8"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;B1] : mword 12))) then
+ "pmpaddr9"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B1;B0] : mword 12))) then
+ "pmpaddr10"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B1;B1] : mword 12))) then
+ "pmpaddr11"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B0;B0] : mword 12))) then
+ "pmpaddr12"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B0;B1] : mword 12))) then
+ "pmpaddr13"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B1;B0] : mword 12))) then
+ "pmpaddr14"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B1;B1] : mword 12))) then
+ "pmpaddr15"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "mcycle"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "minstret"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ "mcycleh"
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ "minstreth"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ "tselect"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B1] : mword 12))) then
+ "tdata1"
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B1;B0] : mword 12))) then
+ "tdata2"
+ else "tdata3".
+
+Definition csr_name_map_backwards (arg_ : string)
+: M (mword 12) :=
+ (match arg_ with
+ | "ustatus" =>
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "uie" => returnm ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12) : mword 12)
+ | "utvec" =>
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12) : mword 12)
+ | "uscratch" =>
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "uepc" =>
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "ucause" =>
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "utval" =>
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12) : mword 12)
+ | "uip" => returnm ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12) : mword 12)
+ | "fflags" =>
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "frm" => returnm ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "fcsr" =>
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12) : mword 12)
+ | "cycle" =>
+ returnm ((vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "time" =>
+ returnm ((vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "instret" =>
+ returnm ((vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "cycleh" =>
+ returnm ((vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "timeh" =>
+ returnm ((vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "instreth" =>
+ returnm ((vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "sstatus" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "sedeleg" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "sideleg" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12) : mword 12)
+ | "sie" => returnm ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12) : mword 12)
+ | "stvec" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12) : mword 12)
+ | "scounteren" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12) : mword 12)
+ | "sscratch" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "sepc" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "scause" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "stval" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12) : mword 12)
+ | "sip" => returnm ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12) : mword 12)
+ | "satp" =>
+ returnm ((vec_of_bits [B0;B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "mvendorid" =>
+ returnm ((vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "marchid" =>
+ returnm ((vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "mimpid" =>
+ returnm ((vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B1] : mword 12) : mword 12)
+ | "mhartid" =>
+ returnm ((vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B1;B0;B0] : mword 12) : mword 12)
+ | "mstatus" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "misa" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "medeleg" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "mideleg" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12) : mword 12)
+ | "mie" => returnm ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12) : mword 12)
+ | "mtvec" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12) : mword 12)
+ | "mcounteren" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12) : mword 12)
+ | "mscratch" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "mepc" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "mcause" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "mtval" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12) : mword 12)
+ | "mip" => returnm ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12) : mword 12)
+ | "pmpcfg0" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "pmpcfg1" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "pmpcfg2" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "pmpcfg3" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B1;B1] : mword 12) : mword 12)
+ | "pmpaddr0" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "pmpaddr1" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "pmpaddr2" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "pmpaddr3" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B1;B1] : mword 12) : mword 12)
+ | "pmpaddr4" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B0;B0] : mword 12) : mword 12)
+ | "pmpaddr5" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B0;B1] : mword 12) : mword 12)
+ | "pmpaddr6" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B1;B0] : mword 12) : mword 12)
+ | "pmpaddr7" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B1;B1] : mword 12) : mword 12)
+ | "pmpaddr8" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;B0] : mword 12) : mword 12)
+ | "pmpaddr9" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;B1] : mword 12) : mword 12)
+ | "pmpaddr10" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B1;B0] : mword 12) : mword 12)
+ | "pmpaddr11" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B1;B1] : mword 12) : mword 12)
+ | "pmpaddr12" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B0;B0] : mword 12) : mword 12)
+ | "pmpaddr13" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B0;B1] : mword 12) : mword 12)
+ | "pmpaddr14" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B1;B0] : mword 12) : mword 12)
+ | "pmpaddr15" =>
+ returnm ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B1;B1] : mword 12) : mword 12)
+ | "mcycle" =>
+ returnm ((vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "minstret" =>
+ returnm ((vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "mcycleh" =>
+ returnm ((vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "minstreth" =>
+ returnm ((vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "tselect" =>
+ returnm ((vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12) : mword 12)
+ | "tdata1" =>
+ returnm ((vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B1] : mword 12) : mword 12)
+ | "tdata2" =>
+ returnm ((vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B1;B0] : mword 12) : mword 12)
+ | "tdata3" =>
+ returnm ((vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B1;B1] : mword 12) : mword 12)
+ | _ => exit tt : M (mword 12)
+ end)
+ : M (mword 12).
+
+Definition csr_name_map_forwards_matches (arg_ : mword 12)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B1;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B1;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B1] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B1;B0] : mword 12))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B1;B1] : mword 12))) then true
+ else false.
+
+Definition csr_name_map_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with
+ | "ustatus" => true
+ | "uie" => true
+ | "utvec" => true
+ | "uscratch" => true
+ | "uepc" => true
+ | "ucause" => true
+ | "utval" => true
+ | "uip" => true
+ | "fflags" => true
+ | "frm" => true
+ | "fcsr" => true
+ | "cycle" => true
+ | "time" => true
+ | "instret" => true
+ | "cycleh" => true
+ | "timeh" => true
+ | "instreth" => true
+ | "sstatus" => true
+ | "sedeleg" => true
+ | "sideleg" => true
+ | "sie" => true
+ | "stvec" => true
+ | "scounteren" => true
+ | "sscratch" => true
+ | "sepc" => true
+ | "scause" => true
+ | "stval" => true
+ | "sip" => true
+ | "satp" => true
+ | "mvendorid" => true
+ | "marchid" => true
+ | "mimpid" => true
+ | "mhartid" => true
+ | "mstatus" => true
+ | "misa" => true
+ | "medeleg" => true
+ | "mideleg" => true
+ | "mie" => true
+ | "mtvec" => true
+ | "mcounteren" => true
+ | "mscratch" => true
+ | "mepc" => true
+ | "mcause" => true
+ | "mtval" => true
+ | "mip" => true
+ | "pmpcfg0" => true
+ | "pmpcfg1" => true
+ | "pmpcfg2" => true
+ | "pmpcfg3" => true
+ | "pmpaddr0" => true
+ | "pmpaddr1" => true
+ | "pmpaddr2" => true
+ | "pmpaddr3" => true
+ | "pmpaddr4" => true
+ | "pmpaddr5" => true
+ | "pmpaddr6" => true
+ | "pmpaddr7" => true
+ | "pmpaddr8" => true
+ | "pmpaddr9" => true
+ | "pmpaddr10" => true
+ | "pmpaddr11" => true
+ | "pmpaddr12" => true
+ | "pmpaddr13" => true
+ | "pmpaddr14" => true
+ | "pmpaddr15" => true
+ | "mcycle" => true
+ | "minstret" => true
+ | "mcycleh" => true
+ | "minstreth" => true
+ | "tselect" => true
+ | "tdata1" => true
+ | "tdata2" => true
+ | "tdata3" => true
+ | _ => false
+ end.
+
+Definition csr_name_map_matches_prefix (arg_ : string)
+: option ((mword 12 * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1773_ := arg_ in
+ if ((andb (string_startswith _stringappend_1773_ "ustatus")
+ (match (string_drop _stringappend_1773_ (string_length "ustatus")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "ustatus")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "uie")
+ (match (string_drop _stringappend_1773_ (string_length "uie")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "uie")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "utvec")
+ (match (string_drop _stringappend_1773_ (string_length "utvec")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "utvec")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "uscratch")
+ (match (string_drop _stringappend_1773_ (string_length "uscratch")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "uscratch")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "uepc")
+ (match (string_drop _stringappend_1773_ (string_length "uepc")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "uepc")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "ucause")
+ (match (string_drop _stringappend_1773_ (string_length "ucause")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "ucause")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "utval")
+ (match (string_drop _stringappend_1773_ (string_length "utval")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "utval")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "uip")
+ (match (string_drop _stringappend_1773_ (string_length "uip")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "uip")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "fflags")
+ (match (string_drop _stringappend_1773_ (string_length "fflags")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "fflags")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "frm")
+ (match (string_drop _stringappend_1773_ (string_length "frm")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "frm")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "fcsr")
+ (match (string_drop _stringappend_1773_ (string_length "fcsr")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "fcsr")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "cycle")
+ (match (string_drop _stringappend_1773_ (string_length "cycle")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "cycle")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "time")
+ (match (string_drop _stringappend_1773_ (string_length "time")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "time")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "instret")
+ (match (string_drop _stringappend_1773_ (string_length "instret")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "instret")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "cycleh")
+ (match (string_drop _stringappend_1773_ (string_length "cycleh")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "cycleh")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "timeh")
+ (match (string_drop _stringappend_1773_ (string_length "timeh")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "timeh")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "instreth")
+ (match (string_drop _stringappend_1773_ (string_length "instreth")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "instreth")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "sstatus")
+ (match (string_drop _stringappend_1773_ (string_length "sstatus")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "sstatus")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "sedeleg")
+ (match (string_drop _stringappend_1773_ (string_length "sedeleg")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "sedeleg")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "sideleg")
+ (match (string_drop _stringappend_1773_ (string_length "sideleg")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "sideleg")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "sie")
+ (match (string_drop _stringappend_1773_ (string_length "sie")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "sie")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "stvec")
+ (match (string_drop _stringappend_1773_ (string_length "stvec")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "stvec")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "scounteren")
+ (match (string_drop _stringappend_1773_ (string_length "scounteren")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "scounteren")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "sscratch")
+ (match (string_drop _stringappend_1773_ (string_length "sscratch")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "sscratch")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "sepc")
+ (match (string_drop _stringappend_1773_ (string_length "sepc")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "sepc")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "scause")
+ (match (string_drop _stringappend_1773_ (string_length "scause")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "scause")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "stval")
+ (match (string_drop _stringappend_1773_ (string_length "stval")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "stval")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "sip")
+ (match (string_drop _stringappend_1773_ (string_length "sip")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "sip")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "satp")
+ (match (string_drop _stringappend_1773_ (string_length "satp")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "satp")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mvendorid")
+ (match (string_drop _stringappend_1773_ (string_length "mvendorid")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mvendorid")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "marchid")
+ (match (string_drop _stringappend_1773_ (string_length "marchid")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "marchid")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mimpid")
+ (match (string_drop _stringappend_1773_ (string_length "mimpid")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mimpid")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mhartid")
+ (match (string_drop _stringappend_1773_ (string_length "mhartid")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mhartid")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B1;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mstatus")
+ (match (string_drop _stringappend_1773_ (string_length "mstatus")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mstatus")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "misa")
+ (match (string_drop _stringappend_1773_ (string_length "misa")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "misa")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "medeleg")
+ (match (string_drop _stringappend_1773_ (string_length "medeleg")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "medeleg")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mideleg")
+ (match (string_drop _stringappend_1773_ (string_length "mideleg")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mideleg")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mie")
+ (match (string_drop _stringappend_1773_ (string_length "mie")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "mie")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mtvec")
+ (match (string_drop _stringappend_1773_ (string_length "mtvec")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mtvec")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mcounteren")
+ (match (string_drop _stringappend_1773_ (string_length "mcounteren")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mcounteren")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mscratch")
+ (match (string_drop _stringappend_1773_ (string_length "mscratch")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mscratch")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mepc")
+ (match (string_drop _stringappend_1773_ (string_length "mepc")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "mepc")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mcause")
+ (match (string_drop _stringappend_1773_ (string_length "mcause")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mcause")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mtval")
+ (match (string_drop _stringappend_1773_ (string_length "mtval")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mtval")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mip")
+ (match (string_drop _stringappend_1773_ (string_length "mip")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1773_ (string_length "mip")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpcfg0")
+ (match (string_drop _stringappend_1773_ (string_length "pmpcfg0")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpcfg0")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpcfg1")
+ (match (string_drop _stringappend_1773_ (string_length "pmpcfg1")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpcfg1")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpcfg2")
+ (match (string_drop _stringappend_1773_ (string_length "pmpcfg2")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpcfg2")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpcfg3")
+ (match (string_drop _stringappend_1773_ (string_length "pmpcfg3")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpcfg3")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr0")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr0")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr0")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr1")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr1")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr1")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr2")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr2")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr2")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr3")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr3")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr3")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr4")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr4")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr4")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr5")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr5")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr5")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr6")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr6")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr6")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr7")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr7")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr7")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B1;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr8")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr8")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr8")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr9")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr9")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr9")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr10")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr10")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr10")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr11")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr11")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr11")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr12")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr12")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr12")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr13")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr13")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr13")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr14")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr14")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr14")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "pmpaddr15")
+ (match (string_drop _stringappend_1773_ (string_length "pmpaddr15")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "pmpaddr15")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B1;B1;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mcycle")
+ (match (string_drop _stringappend_1773_ (string_length "mcycle")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mcycle")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "minstret")
+ (match (string_drop _stringappend_1773_ (string_length "minstret")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "minstret")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "mcycleh")
+ (match (string_drop _stringappend_1773_ (string_length "mcycleh")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "mcycleh")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "minstreth")
+ (match (string_drop _stringappend_1773_ (string_length "minstreth")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "minstreth")) with
+ | s_ =>
+ Some ((vec_of_bits [B1;B0;B1;B1;B1;B0;B0;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "tselect")
+ (match (string_drop _stringappend_1773_ (string_length "tselect")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "tselect")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "tdata1")
+ (match (string_drop _stringappend_1773_ (string_length "tdata1")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "tdata1")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "tdata2")
+ (match (string_drop _stringappend_1773_ (string_length "tdata2")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "tdata2")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B1;B0] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1773_ "tdata3")
+ (match (string_drop _stringappend_1773_ (string_length "tdata3")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1773_ (string_length "tdata3")) with
+ | s_ =>
+ Some ((vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B1;B1] : mword 12),
+ sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition csrAccess (csr : mword 12) : mword 2 := subrange_vec_dec csr 11 10.
+
+Definition csrPriv (csr : mword 12) : mword 2 := subrange_vec_dec csr 9 8.
+
+Definition is_CSR_defined (csr : mword 12) (p : Privilege)
+: bool :=
+ let b__0 := csr in
+ if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B0;B1] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B1] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B1;B0;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B0] : mword 12))) then
+ false
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ orb (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2))
+ (eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Supervisor) : mword 2))
+ else if ((eq_vec b__0 (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ eq_vec ((privLevel_to_bits p) : mword 2) ((privLevel_to_bits Machine) : mword 2)
+ else false.
+
+Definition check_CSR_access (csrrw : mword 2) (csrpr : mword 2) (p : Privilege) (isWrite : bool)
+: bool :=
+ andb
+ (negb
+ (andb (eq_vec ((bool_to_bits isWrite) : mword 1) ((bool_to_bits true) : mword 1))
+ (eq_vec csrrw (vec_of_bits [B1;B1] : mword 2))))
+ (zopz0zKzJ_u (privLevel_to_bits p) csrpr).
+
+Definition check_TVM_SATP (csr : mword 12) (p : Privilege)
+: M (bool) :=
+ and_boolM
+ (returnm ((eq_vec csr (vec_of_bits [B0;B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))
+ : bool))
+ ((and_boolM
+ (returnm ((eq_vec ((privLevel_to_bits p) : mword 2)
+ ((privLevel_to_bits Supervisor)
+ : mword 2))
+ : bool))
+ (read_reg mstatus_ref >>= fun w__0 : Mstatus =>
+ returnm ((eq_vec (_get_Mstatus_TVM w__0) ((bool_to_bits true) : mword 1))
+ : bool)))
+ : M (bool)) >>= fun w__2 : bool =>
+ returnm ((negb w__2)
+ : bool).
+
+Definition check_Counteren (csr : mword 12) (p : Privilege)
+: M (bool) :=
+ (match (csr, p) with
+ | (b__0, Supervisor) =>
+ (if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ read_reg mcounteren_ref >>= fun w__0 : Counteren =>
+ returnm ((eq_vec (_get_Counteren_CY w__0) ((bool_to_bits true) : mword 1))
+ : bool)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ read_reg mcounteren_ref >>= fun w__1 : Counteren =>
+ returnm ((eq_vec (_get_Counteren_TM w__1) ((bool_to_bits true) : mword 1))
+ : bool)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ read_reg mcounteren_ref >>= fun w__2 : Counteren =>
+ returnm ((eq_vec (_get_Counteren_IR w__2) ((bool_to_bits true) : mword 1))
+ : bool)
+ else
+ returnm ((match (b__0, Supervisor) with
+ | (g__31, g__32) =>
+ if ((andb
+ (zopz0zIzJ_u
+ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12) csr)
+ (zopz0zIzJ_u csr
+ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B1;B1;B1;B1;B1] : mword 12))))
+ then
+ false
+ else true
+ end)
+ : bool))
+ : M (bool)
+ | (b__3, User) =>
+ (if ((eq_vec b__3 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ read_reg scounteren_ref >>= fun w__6 : Counteren =>
+ returnm ((eq_vec (_get_Counteren_CY w__6) ((bool_to_bits true) : mword 1))
+ : bool)
+ else if ((eq_vec b__3 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ read_reg scounteren_ref >>= fun w__7 : Counteren =>
+ returnm ((eq_vec (_get_Counteren_TM w__7) ((bool_to_bits true) : mword 1))
+ : bool)
+ else if ((eq_vec b__3 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ read_reg scounteren_ref >>= fun w__8 : Counteren =>
+ returnm ((eq_vec (_get_Counteren_IR w__8) ((bool_to_bits true) : mword 1))
+ : bool)
+ else
+ returnm ((match (b__3, User) with
+ | (g__31, g__32) =>
+ if ((andb
+ (zopz0zIzJ_u
+ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12) csr)
+ (zopz0zIzJ_u csr
+ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B1;B1;B1;B1;B1] : mword 12))))
+ then
+ false
+ else true
+ end)
+ : bool))
+ : M (bool)
+ | (g__31, g__32) =>
+ returnm ((if ((andb
+ (zopz0zIzJ_u (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12)
+ csr)
+ (zopz0zIzJ_u csr
+ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B1;B1;B1;B1;B1] : mword 12)))) then
+ false
+ else true)
+ : bool)
+ end)
+ : M (bool).
+
+Definition check_CSR (csr : mword 12) (p : Privilege) (isWrite : bool)
+: M (bool) :=
+ (and_boolM (returnm ((is_CSR_defined csr p) : bool))
+ ((and_boolM (returnm ((check_CSR_access (csrAccess csr) (csrPriv csr) p isWrite) : bool))
+ ((and_boolM ((check_TVM_SATP csr p) : M (bool)) ((check_Counteren csr p) : M (bool)))
+ : M (bool)))
+ : M (bool)))
+ : M (bool).
+
+Axiom load_reservation : forall (_ : xlenbits) , unit.
+
+Axiom match_reservation : forall (_ : xlenbits) , M (bool).
+
+Axiom cancel_reservation : forall (_ : unit) , unit.
+
+Definition exception_delegatee (e : ExceptionType) (p : Privilege)
+: M (Privilege) :=
+ let '(existT _ idx _) := num_of_ExceptionType e in
+ read_reg medeleg_ref >>= fun w__0 : Medeleg =>
+ let super := access_vec_dec (_get_Medeleg_bits w__0) idx in
+ read_reg sedeleg_ref >>= fun w__1 : Sedeleg =>
+ let user := access_vec_dec (_get_Sedeleg_bits w__1) idx in
+ and_boolM
+ (read_reg misa_ref >>= fun w__2 : Misa =>
+ returnm ((eq_vec (_get_Misa_S w__2) ((bool_to_bits true) : mword 1))
+ : bool)) ((bit_to_bool super) : M (bool)) >>= fun w__4 : bool =>
+ let deleg := if (w__4) then Supervisor else Machine in
+ returnm ((if ((zopz0zI_u (privLevel_to_bits deleg) (privLevel_to_bits p))) then p
+ else deleg)
+ : Privilege).
+
+Definition findPendingInterrupt (ip : mword 64)
+: option InterruptType :=
+ let ip := Mk_Minterrupts ip in
+ if ((eq_vec (_get_Minterrupts_MEI ip) ((bool_to_bits true) : mword 1))) then Some I_M_External
+ else if ((eq_vec (_get_Minterrupts_MSI ip) ((bool_to_bits true) : mword 1))) then
+ Some I_M_Software
+ else if ((eq_vec (_get_Minterrupts_MTI ip) ((bool_to_bits true) : mword 1))) then Some I_M_Timer
+ else if ((eq_vec (_get_Minterrupts_SEI ip) ((bool_to_bits true) : mword 1))) then
+ Some I_S_External
+ else if ((eq_vec (_get_Minterrupts_SSI ip) ((bool_to_bits true) : mword 1))) then
+ Some I_S_Software
+ else if ((eq_vec (_get_Minterrupts_STI ip) ((bool_to_bits true) : mword 1))) then Some I_S_Timer
+ else if ((eq_vec (_get_Minterrupts_UEI ip) ((bool_to_bits true) : mword 1))) then
+ Some I_U_External
+ else if ((eq_vec (_get_Minterrupts_USI ip) ((bool_to_bits true) : mword 1))) then
+ Some I_U_Software
+ else if ((eq_vec (_get_Minterrupts_UTI ip) ((bool_to_bits true) : mword 1))) then Some I_U_Timer
+ else None.
+
+Definition curInterrupt (priv : Privilege) (pend : Minterrupts) (enbl : Minterrupts) (delg : Minterrupts)
+: M (option ((InterruptType * Privilege))) :=
+ let en_mip : xlenbits := and_vec (_get_Minterrupts_bits pend) (_get_Minterrupts_bits enbl) in
+ (if ((eq_vec en_mip (EXTZ 64 (vec_of_bits [B0] : mword 1)))) then
+ returnm (None
+ : option ((InterruptType * Privilege)))
+ else
+ or_boolM
+ (returnm ((neq_vec ((privLevel_to_bits priv) : mword 2)
+ ((privLevel_to_bits Machine)
+ : mword 2))
+ : bool))
+ ((and_boolM
+ (returnm ((eq_vec ((privLevel_to_bits priv) : mword 2)
+ ((privLevel_to_bits Machine)
+ : mword 2))
+ : bool))
+ (read_reg mstatus_ref >>= fun w__0 : Mstatus =>
+ returnm ((eq_vec (_get_Mstatus_MIE w__0) ((bool_to_bits true) : mword 1))
+ : bool)))
+ : M (bool)) >>= fun eff_mie =>
+ or_boolM
+ (returnm ((eq_vec ((privLevel_to_bits priv) : mword 2)
+ ((privLevel_to_bits User)
+ : mword 2))
+ : bool))
+ ((and_boolM
+ (returnm ((eq_vec ((privLevel_to_bits priv) : mword 2)
+ ((privLevel_to_bits Supervisor)
+ : mword 2))
+ : bool))
+ (read_reg mstatus_ref >>= fun w__2 : Mstatus =>
+ returnm ((eq_vec (_get_Mstatus_SIE w__2) ((bool_to_bits true) : mword 1))
+ : bool)))
+ : M (bool)) >>= fun eff_sie =>
+ let eff_mip := and_vec en_mip (not_vec (_get_Minterrupts_bits delg)) in
+ let eff_sip := and_vec en_mip (_get_Minterrupts_bits delg) in
+ (if ((andb eff_mie (neq_vec eff_mip (EXTZ 64 (vec_of_bits [B0] : mword 1))))) then
+ (match (findPendingInterrupt eff_mip) with
+ | Some (i) =>
+ let r := (i, Machine) in
+ returnm ((Some r)
+ : option ((InterruptType * Privilege)))
+ | None =>
+ (internal_error
+ (String.append "non-zero eff_mip="
+ (String.append (string_of_bits eff_mip) ", but nothing pending")))
+ : M (option ((InterruptType * Privilege)))
+ end)
+ : M (option ((InterruptType * Privilege)))
+ else if ((andb eff_sie (neq_vec eff_sip (EXTZ 64 (vec_of_bits [B0] : mword 1))))) then
+ (match (findPendingInterrupt eff_sip) with
+ | Some (i) =>
+ let r := (i, Supervisor) in
+ returnm ((Some r)
+ : option ((InterruptType * Privilege)))
+ | None =>
+ (internal_error
+ (String.append "non-zero eff_sip="
+ (String.append (string_of_bits eff_sip) ", but nothing pending")))
+ : M (option ((InterruptType * Privilege)))
+ end)
+ : M (option ((InterruptType * Privilege)))
+ else
+ let p :=
+ if ((eq_vec (_get_Minterrupts_MTI pend) ((bool_to_bits true) : mword 1))) then "1"
+ else "0" in
+ let e :=
+ if ((eq_vec (_get_Minterrupts_MTI enbl) ((bool_to_bits true) : mword 1))) then "1"
+ else "0" in
+ let d :=
+ if ((eq_vec (_get_Minterrupts_MTI delg) ((bool_to_bits true) : mword 1))) then "1"
+ else "0" in
+ let '_ :=
+ (print_endline
+ (String.append " MTI: pend="
+ (String.append p
+ (String.append " enbl=" (String.append e (String.append " delg=" d))))))
+ : unit in
+ let eff_mip := and_vec en_mip (not_vec (_get_Minterrupts_bits delg)) in
+ let eff_sip := and_vec en_mip (_get_Minterrupts_bits delg) in
+ read_reg mstatus_ref >>= fun w__8 : Mstatus =>
+ read_reg mstatus_ref >>= fun w__9 : Mstatus =>
+ read_reg mstatus_ref >>= fun w__10 : Mstatus =>
+ let '_ :=
+ (print_endline
+ (String.append "mstatus="
+ (String.append (string_of_bits (_get_Mstatus_bits w__8))
+ (String.append " mie,sie="
+ (String.append (string_of_bits (_get_Mstatus_MIE w__9))
+ (String.append ","
+ (String.append (string_of_bits (_get_Mstatus_SIE w__10))
+ (String.append " en_mip="
+ (String.append (string_of_bits en_mip)
+ (String.append " eff_mip="
+ (String.append (string_of_bits eff_mip)
+ (String.append " eff_sip=" (string_of_bits eff_sip)))))))))))))
+ : unit in
+ returnm (None
+ : option ((InterruptType * Privilege))))
+ : M (option ((InterruptType * Privilege))))
+ : M (option ((InterruptType * Privilege))).
+
+Definition tval (excinfo : option (mword 64))
+: mword 64 :=
+ match excinfo with | Some (e) => e | None => EXTZ 64 (vec_of_bits [B0] : mword 1) end.
+
+Definition handle_trap (del_priv : Privilege) (intr : bool) (c : mword 4) (pc : mword 64) (info : option (mword 64))
+: M (mword 64) :=
+ let '_ :=
+ (print_endline
+ (String.append "handling "
+ (String.append (if (intr) then "int#" else "exc#")
+ (String.append (string_of_bits c)
+ (String.append " at priv "
+ (String.append ((privLevel_to_str del_priv) : string)
+ (String.append " with tval " (string_of_bits (tval info)))))))))
+ : unit in
+ (match del_priv with
+ | Machine =>
+ _set_Mcause_IsInterrupt mcause_ref ((bool_to_bits intr) : mword 1) >>
+ _set_Mcause_Cause mcause_ref (EXTZ 63 c) >>
+ read_reg mstatus_ref >>= fun w__0 : Mstatus =>
+ _set_Mstatus_MPIE mstatus_ref (_get_Mstatus_MIE w__0) >>
+ _set_Mstatus_MIE mstatus_ref ((bool_to_bits false) : mword 1) >>
+ read_reg cur_privilege_ref >>= fun w__1 : Privilege =>
+ _set_Mstatus_MPP mstatus_ref (privLevel_to_bits w__1) >>
+ write_reg mtval_ref (tval info) >>
+ write_reg mepc_ref pc >>
+ write_reg cur_privilege_ref del_priv >>
+ read_reg mstatus_ref >>= fun w__2 : Mstatus =>
+ read_reg mstatus_ref >>= fun w__3 : Mstatus =>
+ let '_ :=
+ (print_endline
+ (String.append "CSR mstatus <- "
+ (String.append (string_of_bits (_get_Mstatus_bits w__2))
+ (String.append " (input: "
+ (String.append (string_of_bits (_get_Mstatus_bits w__3)) ")")))))
+ : unit in
+ let '_ := (cancel_reservation tt) : unit in
+ read_reg mtvec_ref >>= fun w__4 : Mtvec =>
+ read_reg mcause_ref >>= fun w__5 : Mcause =>
+ (match (tvec_addr w__4 w__5) with
+ | Some (epc) => returnm (epc : mword 64)
+ | None => (internal_error "Invalid mtvec mode") : M (mword 64)
+ end)
+ : M (mword 64)
+ | Supervisor =>
+ _set_Mcause_IsInterrupt scause_ref ((bool_to_bits intr) : mword 1) >>
+ _set_Mcause_Cause scause_ref (EXTZ 63 c) >>
+ read_reg mstatus_ref >>= fun w__8 : Mstatus =>
+ _set_Mstatus_SPIE mstatus_ref (_get_Mstatus_SIE w__8) >>
+ _set_Mstatus_SIE mstatus_ref ((bool_to_bits false) : mword 1) >>
+ read_reg cur_privilege_ref >>= fun w__9 : Privilege =>
+ match w__9 with
+ | User => returnm ((bool_to_bits false) : mword 1)
+ | Supervisor => returnm ((bool_to_bits true) : mword 1)
+ | Machine => (internal_error "invalid privilege for s-mode trap") : M (mword 1)
+ end >>= fun w__11 : mword 1 =>
+ _set_Mstatus_SPP mstatus_ref w__11 >>
+ write_reg stval_ref (tval info) >>
+ write_reg sepc_ref pc >>
+ write_reg cur_privilege_ref del_priv >>
+ read_reg mstatus_ref >>= fun w__12 : Mstatus =>
+ read_reg mstatus_ref >>= fun w__13 : Mstatus =>
+ let '_ :=
+ (print_endline
+ (String.append "CSR mstatus <- "
+ (String.append (string_of_bits (_get_Mstatus_bits w__12))
+ (String.append " (input: "
+ (String.append (string_of_bits (_get_Mstatus_bits w__13)) ")")))))
+ : unit in
+ let '_ := (cancel_reservation tt) : unit in
+ read_reg stvec_ref >>= fun w__14 : Mtvec =>
+ read_reg scause_ref >>= fun w__15 : Mcause =>
+ (match (tvec_addr w__14 w__15) with
+ | Some (epc) => returnm (epc : mword 64)
+ | None => (internal_error "Invalid stvec mode") : M (mword 64)
+ end)
+ : M (mword 64)
+ | User => (internal_error "the N extension is currently unsupported") : M (mword 64)
+ end)
+ : M (mword 64).
+
+Definition handle_exception (cur_priv : Privilege) (ctl : ctl_result) (pc : mword 64)
+: M (mword 64) :=
+ (match (cur_priv, ctl) with
+ | (_, CTL_TRAP (e)) =>
+ exception_delegatee e.(sync_exception_trap) cur_priv >>= fun del_priv =>
+ let '_ :=
+ (print_endline
+ (String.append "trapping from "
+ (String.append ((privLevel_to_str cur_priv) : string)
+ (String.append " to "
+ (String.append ((privLevel_to_str del_priv) : string)
+ (String.append " to handle "
+ ((exceptionType_to_str e.(sync_exception_trap))
+ : string)))))))
+ : unit in
+ (handle_trap del_priv false ((exceptionType_to_bits e.(sync_exception_trap)) : mword 4) pc
+ e.(sync_exception_excinfo))
+ : M (mword 64)
+ | (_, CTL_MRET (_)) =>
+ read_reg cur_privilege_ref >>= fun prev_priv =>
+ read_reg mstatus_ref >>= fun w__1 : Mstatus =>
+ _set_Mstatus_MIE mstatus_ref (_get_Mstatus_MPIE w__1) >>
+ _set_Mstatus_MPIE mstatus_ref ((bool_to_bits true) : mword 1) >>
+ read_reg mstatus_ref >>= fun w__2 : Mstatus =>
+ write_reg cur_privilege_ref (privLevel_of_bits (_get_Mstatus_MPP w__2)) >>
+ _set_Mstatus_MPP mstatus_ref (privLevel_to_bits User) >>
+ read_reg mstatus_ref >>= fun w__3 : Mstatus =>
+ read_reg mstatus_ref >>= fun w__4 : Mstatus =>
+ let '_ :=
+ (print_endline
+ (String.append "CSR mstatus <- "
+ (String.append (string_of_bits (_get_Mstatus_bits w__3))
+ (String.append " (input: "
+ (String.append (string_of_bits (_get_Mstatus_bits w__4)) ")")))))
+ : unit in
+ read_reg cur_privilege_ref >>= fun w__5 : Privilege =>
+ let '_ :=
+ (print_endline
+ (String.append "ret-ing from "
+ (String.append ((privLevel_to_str prev_priv) : string)
+ (String.append " to " ((privLevel_to_str w__5) : string)))))
+ : unit in
+ let '_ := (cancel_reservation tt) : unit in
+ (read_reg mepc_ref : M (mword 64)) >>= fun w__6 : mword 64 =>
+ pc_alignment_mask tt >>= fun w__7 : mword 64 => returnm ((and_vec w__6 w__7) : mword 64)
+ | (_, CTL_SRET (_)) =>
+ read_reg cur_privilege_ref >>= fun prev_priv =>
+ read_reg mstatus_ref >>= fun w__8 : Mstatus =>
+ _set_Mstatus_SIE mstatus_ref (_get_Mstatus_SPIE w__8) >>
+ _set_Mstatus_SPIE mstatus_ref ((bool_to_bits true) : mword 1) >>
+ read_reg mstatus_ref >>= fun w__9 : Mstatus =>
+ write_reg
+ cur_privilege_ref
+ (if ((eq_vec (_get_Mstatus_SPP w__9) ((bool_to_bits true) : mword 1))) then Supervisor
+ else User) >>
+ _set_Mstatus_SPP mstatus_ref ((bool_to_bits false) : mword 1) >>
+ read_reg mstatus_ref >>= fun w__10 : Mstatus =>
+ read_reg mstatus_ref >>= fun w__11 : Mstatus =>
+ let '_ :=
+ (print_endline
+ (String.append "CSR mstatus <- "
+ (String.append (string_of_bits (_get_Mstatus_bits w__10))
+ (String.append " (input: "
+ (String.append (string_of_bits (_get_Mstatus_bits w__11)) ")")))))
+ : unit in
+ read_reg cur_privilege_ref >>= fun w__12 : Privilege =>
+ let '_ :=
+ (print_endline
+ (String.append "ret-ing from "
+ (String.append ((privLevel_to_str prev_priv) : string)
+ (String.append " to " ((privLevel_to_str w__12) : string)))))
+ : unit in
+ let '_ := (cancel_reservation tt) : unit in
+ (read_reg sepc_ref : M (mword 64)) >>= fun w__13 : mword 64 =>
+ pc_alignment_mask tt >>= fun w__14 : mword 64 => returnm ((and_vec w__13 w__14) : mword 64)
+ end)
+ : M (mword 64).
+
+Definition handle_mem_exception (addr : mword 64) (e : ExceptionType)
+: M (unit) :=
+ let t : sync_exception := {| sync_exception_trap := e; sync_exception_excinfo := (Some addr) |} in
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__1 : mword 64 =>
+ handle_exception w__0 (CTL_TRAP t) w__1 >>= fun w__2 : xlenbits =>
+ write_reg nextPC_ref w__2
+ : M (unit).
+
+Definition handle_decode_exception (instbits : mword 64)
+: M (unit) :=
+ let t : sync_exception :=
+ {| sync_exception_trap := E_Illegal_Instr;
+ sync_exception_excinfo := (Some instbits) |} in
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__1 : mword 64 =>
+ handle_exception w__0 (CTL_TRAP t) w__1 >>= fun w__2 : xlenbits =>
+ write_reg nextPC_ref w__2
+ : M (unit).
+
+Definition handle_interrupt (i : InterruptType) (del_priv : Privilege)
+: M (unit) :=
+ (read_reg PC_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ handle_trap del_priv true ((interruptType_to_bits i) : mword 4) w__0 None >>= fun w__1 : xlenbits =>
+ write_reg nextPC_ref w__1
+ : M (unit).
+
+Definition handle_illegal '(tt : unit)
+: M (unit) :=
+ let t : sync_exception :=
+ {| sync_exception_trap := E_Illegal_Instr;
+ sync_exception_excinfo := None |} in
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__1 : mword 64 =>
+ handle_exception w__0 (CTL_TRAP t) w__1 >>= fun w__2 : xlenbits =>
+ write_reg nextPC_ref w__2
+ : M (unit).
+
+Definition init_sys '(tt : unit)
+: M (unit) :=
+ write_reg cur_privilege_ref Machine >>
+ write_reg mhartid_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ _set_Misa_MXL misa_ref (arch_to_bits RV64) >>
+ _set_Misa_A misa_ref ((bool_to_bits true) : mword 1) >>
+ _set_Misa_C misa_ref ((bool_to_bits true) : mword 1) >>
+ _set_Misa_I misa_ref ((bool_to_bits true) : mword 1) >>
+ _set_Misa_M misa_ref ((bool_to_bits true) : mword 1) >>
+ _set_Misa_U misa_ref ((bool_to_bits true) : mword 1) >>
+ _set_Misa_S misa_ref ((bool_to_bits true) : mword 1) >>
+ read_reg misa_ref >>= fun w__0 : Misa =>
+ _set_Mstatus_SXL mstatus_ref (_get_Misa_MXL w__0) >>
+ read_reg misa_ref >>= fun w__1 : Misa =>
+ _set_Mstatus_UXL mstatus_ref (_get_Misa_MXL w__1) >>
+ _set_Mstatus_SD mstatus_ref ((bool_to_bits false) : mword 1) >>
+ _set_Minterrupts_bits mip_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ _set_Minterrupts_bits mie_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ _set_Minterrupts_bits mideleg_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ _set_Medeleg_bits medeleg_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ _set_Mtvec_bits mtvec_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ _set_Mcause_bits mcause_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ write_reg mepc_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ write_reg mtval_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ write_reg mscratch_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ write_reg mcycle_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ write_reg mtime_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ _set_Counteren_bits mcounteren_ref (EXTZ 32 (vec_of_bits [B0] : mword 1)) >>
+ write_reg minstret_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ write_reg minstret_written_ref false >>
+ read_reg mstatus_ref >>= fun w__2 : Mstatus =>
+ returnm ((print_endline
+ (String.append "CSR mstatus <- "
+ (String.append (string_of_bits (_get_Mstatus_bits w__2))
+ (String.append " (input: "
+ (String.append
+ (string_of_bits ((EXTZ 64 (vec_of_bits [B0] : mword 1)) : xlenbits))
+ ")")))))
+ : unit).
+
+Axiom plat_ram_base : forall (_ : unit) , xlenbits.
+
+Axiom plat_ram_size : forall (_ : unit) , xlenbits.
+
+Axiom plat_enable_dirty_update : forall (_ : unit) , bool.
+
+Axiom plat_enable_misaligned_access : forall (_ : unit) , bool.
+
+Axiom plat_rom_base : forall (_ : unit) , xlenbits.
+
+Axiom plat_rom_size : forall (_ : unit) , xlenbits.
+
+Axiom plat_clint_base : forall (_ : unit) , xlenbits.
+
+Axiom plat_clint_size : forall (_ : unit) , xlenbits.
+
+Axiom plat_htif_tohost : forall (_ : unit) , xlenbits.
+
+Definition phys_mem_segments '(tt : unit)
+: list ((mword 64 * mword 64)) :=
+ (plat_rom_base tt, plat_rom_size tt) :: (plat_ram_base tt, plat_ram_size tt) :: [].
+
+Definition within_phys_mem (addr : mword 64) (width : Z)
+: bool :=
+ if ((andb (zopz0zIzJ_u (plat_ram_base tt) addr)
+ (zopz0zIzJ_u (add_vec_int addr width) (add_vec (plat_ram_base tt) (plat_ram_size tt)))))
+ then
+ true
+ else if ((andb (zopz0zIzJ_u (plat_rom_base tt) addr)
+ (zopz0zIzJ_u (add_vec_int addr width) (add_vec (plat_rom_base tt) (plat_rom_size tt)))))
+ then
+ true
+ else false.
+
+Definition within_clint (addr : mword 64) (width : Z)
+: bool :=
+ andb (zopz0zIzJ_u (plat_clint_base tt) addr)
+ (zopz0zIzJ_u (add_vec_int addr width) (add_vec (plat_clint_base tt) (plat_clint_size tt))).
+
+Definition within_htif_writable (addr : mword 64) (width : Z)
+: bool :=
+ eq_vec (plat_htif_tohost tt) addr.
+
+Definition within_htif_readable (addr : mword 64) (width : Z)
+: bool :=
+ eq_vec (plat_htif_tohost tt) addr.
+
+Axiom plat_insns_per_tick : forall (_ : unit) , Z.
+
+Let MSIP_BASE : xlenbits :=
+(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64).
+Let MTIMECMP_BASE : xlenbits :=
+(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64).
+Let MTIME_BASE : xlenbits :=
+(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B1;B0;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B0;B0;
+ B0]
+ : mword 64).
+Definition clint_load (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ let addr := sub_vec addr (plat_clint_base tt) in
+ (if sumbool_of_bool ((andb (eq_vec addr MSIP_BASE) (orb (Z.eqb width 8) (Z.eqb width 4)))) then
+ read_reg mip_ref >>= fun w__0 : Minterrupts =>
+ let '_ :=
+ (print_endline
+ (String.append "clint["
+ (String.append (string_of_bits addr)
+ (String.append "] -> " (string_of_bits (_get_Minterrupts_MSI w__0))))))
+ : unit in
+ read_reg mip_ref >>= fun w__1 : Minterrupts =>
+ returnm ((MemValue (autocast (zero_extend (_get_Minterrupts_MSI w__1) (Z.mul 8 width))))
+ : MemoryOpResult (mword (8 * width)))
+ else if sumbool_of_bool ((andb (eq_vec addr MTIMECMP_BASE) (Z.eqb width 8))) then
+ (read_reg mtimecmp_ref : M (mword 64)) >>= fun w__2 : xlenbits =>
+ let '_ :=
+ (print_endline
+ (String.append "clint["
+ (String.append (string_of_bits addr) (String.append "] -> " (string_of_bits w__2)))))
+ : unit in
+ (read_reg mtimecmp_ref : M (mword 64)) >>= fun w__3 : xlenbits =>
+ returnm ((MemValue (autocast (zero_extend w__3 64)))
+ : MemoryOpResult (mword (8 * width)))
+ else if sumbool_of_bool ((andb (eq_vec addr MTIME_BASE) (Z.eqb width 8))) then
+ (read_reg mtime_ref : M (mword 64)) >>= fun w__4 : xlenbits =>
+ let '_ :=
+ (print_endline
+ (String.append "clint["
+ (String.append (string_of_bits addr) (String.append "] -> " (string_of_bits w__4)))))
+ : unit in
+ (read_reg mtime_ref : M (mword 64)) >>= fun w__5 : xlenbits =>
+ returnm ((MemValue (autocast (zero_extend w__5 64)))
+ : MemoryOpResult (mword (8 * width)))
+ else
+ let '_ :=
+ (print_endline
+ (String.append "clint[" (String.append (string_of_bits addr) "] -> <not-mapped>")))
+ : unit in
+ returnm ((MemException E_Load_Access_Fault)
+ : MemoryOpResult (mword (8 * width))))
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition clint_dispatch '(tt : unit)
+: M (unit) :=
+ (read_reg mtime_ref : M (mword 64)) >>= fun w__0 : xlenbits =>
+ let '_ := (print_endline (String.append "clint::tick mtime <- " (string_of_bits w__0))) : unit in
+ _set_Minterrupts_MTI mip_ref ((bool_to_bits false) : mword 1) >>
+ (read_reg mtimecmp_ref : M (mword 64)) >>= fun w__1 : xlenbits =>
+ (read_reg mtime_ref : M (mword 64)) >>= fun w__2 : mword 64 =>
+ (if ((zopz0zIzJ_u w__1 w__2)) then
+ (read_reg mtime_ref : M (mword 64)) >>= fun w__3 : xlenbits =>
+ let '_ :=
+ (print_endline (String.append " clint timer pending at mtime " (string_of_bits w__3)))
+ : unit in
+ (_set_Minterrupts_MTI mip_ref ((bool_to_bits true) : mword 1))
+ : M (unit)
+ else returnm (tt : unit))
+ : M (unit).
+
+Definition clint_store (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult bool) :=
+ let addr := sub_vec addr (plat_clint_base tt) in
+ (if sumbool_of_bool ((andb (eq_vec addr MSIP_BASE) (orb (Z.eqb width 8) (Z.eqb width 4)))) then
+ cast_unit_vec (access_vec_dec data 0) >>= fun w__0 : mword 1 =>
+ let '_ :=
+ (print_endline
+ (String.append "clint["
+ (String.append (string_of_bits addr)
+ (String.append "] <- "
+ (String.append (string_of_bits data)
+ (String.append " (mip.MSI <- "
+ (String.append (string_of_bits (w__0 : mword 1)) ")")))))))
+ : unit in
+ cast_unit_vec (access_vec_dec data 0) >>= fun w__1 : mword 1 =>
+ _set_Minterrupts_MSI mip_ref
+ ((bool_to_bits (eq_vec (w__1 : mword 1) (vec_of_bits [B1] : mword 1)))
+ : mword 1) >>
+ clint_dispatch tt >> returnm ((MemValue true) : MemoryOpResult bool)
+ else if sumbool_of_bool ((andb (eq_vec addr MTIMECMP_BASE) (Z.eqb width 8))) then
+ let '_ :=
+ (print_endline
+ (String.append "clint["
+ (String.append (string_of_bits addr)
+ (String.append "] <- " (String.append (string_of_bits data) " (mtimecmp)")))))
+ : unit in
+ write_reg mtimecmp_ref (zero_extend data 64) >>
+ clint_dispatch tt >> returnm ((MemValue true) : MemoryOpResult bool)
+ else
+ let '_ :=
+ (print_endline
+ (String.append "clint["
+ (String.append (string_of_bits addr)
+ (String.append "] <- " (String.append (string_of_bits data) " (<unmapped>)")))))
+ : unit in
+ returnm ((MemException E_SAMO_Access_Fault)
+ : MemoryOpResult bool))
+ : M (MemoryOpResult bool).
+
+Definition tick_clock '(tt : unit)
+: M (unit) :=
+ (read_reg mcycle_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ write_reg mcycle_ref (add_vec_int w__0 1) >>
+ (read_reg mtime_ref : M (mword 64)) >>= fun w__1 : mword 64 =>
+ write_reg mtime_ref (add_vec_int w__1 1) >> (clint_dispatch tt) : M (unit).
+
+Axiom plat_term_write : forall (_ : bits 8) , unit.
+
+Axiom plat_term_read : forall (_ : unit) , bits 8.
+
+Definition Mk_htif_cmd (v : mword 64)
+: htif_cmd :=
+ {| htif_cmd_htif_cmd_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_htif_cmd_bits (v : htif_cmd)
+: mword 64 :=
+ subrange_vec_dec v.(htif_cmd_htif_cmd_chunk_0) 63 0.
+
+Definition _set_htif_cmd_bits (r_ref : register_ref regstate register_value htif_cmd) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ htif_cmd_htif_cmd_chunk_0 :=
+ (update_subrange_vec_dec r.(htif_cmd_htif_cmd_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : htif_cmd in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_htif_cmd_bits (v : htif_cmd) (x : mword 64)
+: htif_cmd :=
+ {[ v with
+ htif_cmd_htif_cmd_chunk_0 :=
+ (update_subrange_vec_dec v.(htif_cmd_htif_cmd_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_htif_cmd_device (v : htif_cmd)
+: mword 8 :=
+ subrange_vec_dec v.(htif_cmd_htif_cmd_chunk_0) 63 56.
+
+Definition _set_htif_cmd_device (r_ref : register_ref regstate register_value htif_cmd) (v : mword 8)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ htif_cmd_htif_cmd_chunk_0 :=
+ (update_subrange_vec_dec r.(htif_cmd_htif_cmd_chunk_0) 63 56 (subrange_vec_dec v 7 0)) ]}
+ : htif_cmd in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_htif_cmd_device (v : htif_cmd) (x : mword 8)
+: htif_cmd :=
+ {[ v with
+ htif_cmd_htif_cmd_chunk_0 :=
+ (update_subrange_vec_dec v.(htif_cmd_htif_cmd_chunk_0) 63 56 (subrange_vec_dec x 7 0)) ]}.
+
+Definition _get_htif_cmd_cmd (v : htif_cmd)
+: mword 8 :=
+ subrange_vec_dec v.(htif_cmd_htif_cmd_chunk_0) 55 48.
+
+Definition _set_htif_cmd_cmd (r_ref : register_ref regstate register_value htif_cmd) (v : mword 8)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ htif_cmd_htif_cmd_chunk_0 :=
+ (update_subrange_vec_dec r.(htif_cmd_htif_cmd_chunk_0) 55 48 (subrange_vec_dec v 7 0)) ]}
+ : htif_cmd in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_htif_cmd_cmd (v : htif_cmd) (x : mword 8)
+: htif_cmd :=
+ {[ v with
+ htif_cmd_htif_cmd_chunk_0 :=
+ (update_subrange_vec_dec v.(htif_cmd_htif_cmd_chunk_0) 55 48 (subrange_vec_dec x 7 0)) ]}.
+
+Definition _get_htif_cmd_payload (v : htif_cmd)
+: mword 48 :=
+ subrange_vec_dec v.(htif_cmd_htif_cmd_chunk_0) 47 0.
+
+Definition _set_htif_cmd_payload (r_ref : register_ref regstate register_value htif_cmd) (v : mword 48)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ htif_cmd_htif_cmd_chunk_0 :=
+ (update_subrange_vec_dec r.(htif_cmd_htif_cmd_chunk_0) 47 0 (subrange_vec_dec v 47 0)) ]}
+ : htif_cmd in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_htif_cmd_payload (v : htif_cmd) (x : mword 48)
+: htif_cmd :=
+ {[ v with
+ htif_cmd_htif_cmd_chunk_0 :=
+ (update_subrange_vec_dec v.(htif_cmd_htif_cmd_chunk_0) 47 0 (subrange_vec_dec x 47 0)) ]}.
+
+Definition htif_load (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (read_reg htif_tohost_ref : M (mword 64)) >>= fun w__0 : xlenbits =>
+ let '_ :=
+ (print_endline
+ (String.append "htif["
+ (String.append (string_of_bits addr) (String.append "] -> " (string_of_bits w__0)))))
+ : unit in
+ (if sumbool_of_bool ((Z.eqb width 8)) then
+ (read_reg htif_tohost_ref : M (mword 64)) >>= fun w__1 : xlenbits =>
+ returnm ((MemValue (autocast (zero_extend w__1 64)))
+ : MemoryOpResult (mword (8 * width)))
+ else returnm ((MemException E_Load_Access_Fault) : MemoryOpResult (mword (8 * width))))
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition htif_store (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (1 <=
+ width /\
+ width <= 8)}
+: M (MemoryOpResult bool) :=
+ let '_ :=
+ (print_endline
+ (String.append "htif["
+ (String.append (string_of_bits addr) (String.append "] <- " (string_of_bits data)))))
+ : unit in
+ let cbits : xlenbits := EXTZ 64 data in
+ write_reg htif_tohost_ref cbits >>
+ let cmd := Mk_htif_cmd cbits in
+ let b__0 := _get_htif_cmd_device cmd in
+ (if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0] : mword 8))) then
+ let '_ :=
+ (print_endline
+ (String.append "htif-syscall-proxy cmd: " (string_of_bits (_get_htif_cmd_payload cmd))))
+ : unit in
+ cast_unit_vec (access_vec_dec (_get_htif_cmd_payload cmd) 0) >>= fun w__0 : mword 1 =>
+ (if ((eq_vec (w__0 : mword 1) (vec_of_bits [B1] : mword 1))) then
+ write_reg htif_done_ref true >>
+ write_reg
+ htif_exit_code_ref
+ ((shift_bits_right (zero_extend (_get_htif_cmd_payload cmd) xlen)
+ (vec_of_bits [B0;B1] : mword 2))
+ : xlenbits)
+ : M (unit)
+ else returnm (tt : unit))
+ : M (unit)
+ else
+ returnm ((if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B1] : mword 8))) then
+ let '_ :=
+ (print_endline
+ (String.append "htif-term cmd: " (string_of_bits (_get_htif_cmd_payload cmd))))
+ : unit in
+ let b__2 := _get_htif_cmd_cmd cmd in
+ if ((eq_vec b__2 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0] : mword 8))) then tt
+ else if ((eq_vec b__2 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B1] : mword 8))) then
+ plat_term_write (subrange_vec_dec (_get_htif_cmd_payload cmd) 7 0)
+ else print_endline (String.append "Unknown term cmd: " (string_of_bits b__2))
+ else print_endline (String.append "htif-???? cmd: " (string_of_bits data)))
+ : unit)) >>
+ returnm ((MemValue true)
+ : MemoryOpResult bool).
+
+Definition htif_tick '(tt : unit)
+: M (unit) :=
+ (read_reg htif_tohost_ref : M (mword 64)) >>= fun w__0 : xlenbits =>
+ let '_ := (print_endline (String.append "htif::tick " (string_of_bits w__0))) : unit in
+ write_reg htif_tohost_ref (EXTZ 64 (vec_of_bits [B0] : mword 1))
+ : M (unit).
+
+Definition within_mmio_readable (addr : mword 64) (width : Z)
+: bool :=
+ orb (within_clint addr width) (andb (within_htif_readable addr width) (Z.leb 1 width)).
+
+Definition within_mmio_writable (addr : mword 64) (width : Z)
+: bool :=
+ orb (within_clint addr width) (andb (within_htif_writable addr width) (Z.leb width 8)).
+
+Definition mmio_read (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (if ((within_clint addr width)) then
+ (clint_load addr width)
+ : M (MemoryOpResult (mword (8 * width)))
+ else if sumbool_of_bool ((andb (within_htif_readable addr width) (Z.leb 1 width))) then
+ (htif_load addr width)
+ : M (MemoryOpResult (mword (8 * width)))
+ else returnm ((MemException E_Load_Access_Fault) : MemoryOpResult (mword (8 * width))))
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition mmio_write (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult bool) :=
+ (if ((within_clint addr width)) then (clint_store addr width data) : M (MemoryOpResult bool)
+ else if sumbool_of_bool ((andb (within_htif_writable addr width) (Z.leb width 8))) then
+ (htif_store addr width data)
+ : M (MemoryOpResult bool)
+ else returnm ((MemException E_SAMO_Access_Fault) : MemoryOpResult bool))
+ : M (MemoryOpResult bool).
+
+Definition init_platform '(tt : unit)
+: M (unit) :=
+ write_reg htif_tohost_ref (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ write_reg htif_done_ref false >>
+ write_reg htif_exit_code_ref (EXTZ 64 (vec_of_bits [B0] : mword 1))
+ : M (unit).
+
+Definition tick_platform '(tt : unit)
+: M (unit) :=
+ let '_ := (cancel_reservation tt) : unit in
+ (htif_tick tt)
+ : M (unit).
+
+Definition is_aligned_addr (addr : mword 64) (width : Z)
+: bool :=
+ Z.eqb (projT1 ((ex_int (modulus (projT1 (uint addr)) width)) : {syn_n : Z & ArithFact (True)}))
+ 0.
+
+Definition phys_mem_read (t : ReadType) (addr : mword 64) (width : Z) (aq : bool) (rl : bool) (res : bool) `{ArithFact (width >=
+ 0)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ __RISCV_read addr width aq rl res >>= fun w__0 : option (mword (8 * width)) =>
+ returnm ((match (t, w__0) with
+ | (Instruction, None) => MemException E_Fetch_Access_Fault
+ | (Data, None) => MemException E_Load_Access_Fault
+ | (_, Some (v)) =>
+ let '_ :=
+ (print_endline
+ (String.append "mem["
+ (String.append ((readType_to_str t) : string)
+ (String.append ","
+ (String.append (string_of_bits addr)
+ (String.append "] -> " (string_of_bits v)))))))
+ : unit in
+ MemValue v
+ end)
+ : MemoryOpResult (mword (8 * width))).
+
+Definition checked_mem_read (t : ReadType) (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (if ((andb (generic_eq ((readType_to_str t) : string) ((readType_to_str Data) : string))
+ (within_mmio_readable addr width))) then
+ (mmio_read addr width)
+ : M (MemoryOpResult (mword (8 * width)))
+ else if ((within_phys_mem addr width)) then
+ (phys_mem_read t addr width false false false)
+ : M (MemoryOpResult (mword (8 * width)))
+ else returnm ((MemException E_Load_Access_Fault) : MemoryOpResult (mword (8 * width))))
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition MEMr (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (checked_mem_read Data addr width)
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition MEMr_acquire (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (checked_mem_read Data addr width)
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition MEMr_strong_acquire (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (checked_mem_read Data addr width)
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition MEMr_reserved (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (checked_mem_read Data addr width)
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition MEMr_reserved_acquire (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (checked_mem_read Data addr width)
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition MEMr_reserved_strong_acquire (addr : mword 64) (width : Z) `{ArithFact (width >= 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (checked_mem_read Data addr width)
+ : M (MemoryOpResult (mword (8 * width))).
+
+Definition mem_read (addr : mword 64) (width : Z) (aq : bool) (rl : bool) (res : bool) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult (mword (8 * width))) :=
+ (if ((andb (orb aq res) (negb (is_aligned_addr addr width)))) then
+ returnm ((MemException E_Load_Addr_Align)
+ : MemoryOpResult (mword (8 * width)))
+ else
+ (match (aq, rl, res) with
+ | (false, false, false) =>
+ (checked_mem_read Data addr width) : M (MemoryOpResult (mword (8 * width)))
+ | (true, false, false) => (MEMr_acquire addr width) : M (MemoryOpResult (mword (8 * width)))
+ | (false, false, true) =>
+ (MEMr_reserved addr width) : M (MemoryOpResult (mword (8 * width)))
+ | (true, false, true) =>
+ (MEMr_reserved_acquire addr width) : M (MemoryOpResult (mword (8 * width)))
+ | (false, true, false) =>
+ (throw (Error_not_implemented "load.rl")) : M (MemoryOpResult (mword (8 * width)))
+ | (true, true, false) =>
+ (MEMr_strong_acquire addr width) : M (MemoryOpResult (mword (8 * width)))
+ | (false, true, true) =>
+ (throw (Error_not_implemented "lr.rl")) : M (MemoryOpResult (mword (8 * width)))
+ | (true, true, true) =>
+ (MEMr_reserved_strong_acquire addr width) : M (MemoryOpResult (mword (8 * width)))
+ end)
+ : M (MemoryOpResult (mword (8 * width))))
+ : M (MemoryOpResult (mword (8 * width))).
+
+Axiom MEMea : forall (_ : xlenbits) (n : Z) , M (unit).
+
+Axiom MEMea_release : forall (_ : xlenbits) (n : Z) , M (unit).
+
+Axiom MEMea_strong_release : forall (_ : xlenbits) (n : Z) , M (unit).
+
+Axiom MEMea_conditional : forall (_ : xlenbits) (n : Z) , M (unit).
+
+Axiom MEMea_conditional_release : forall (_ : xlenbits) (n : Z) , M (unit).
+
+Axiom MEMea_conditional_strong_release : forall (_ : xlenbits) (n : Z) , M (unit).
+
+Definition mem_write_ea (addr : mword 64) (width : Z) (aq : bool) (rl : bool) (con : bool)
+: M (MemoryOpResult unit) :=
+ (if ((andb (orb rl con) (negb (is_aligned_addr addr width)))) then
+ returnm ((MemException E_SAMO_Addr_Align)
+ : MemoryOpResult unit)
+ else
+ (match (aq, rl, con) with
+ | (false, false, false) => MEMea addr width >> returnm ((MemValue tt) : MemoryOpResult unit)
+ | (false, true, false) =>
+ MEMea_release addr width >> returnm ((MemValue tt) : MemoryOpResult unit)
+ | (false, false, true) =>
+ MEMea_conditional addr width >> returnm ((MemValue tt) : MemoryOpResult unit)
+ | (false, true, true) =>
+ MEMea_conditional_release addr width >> returnm ((MemValue tt) : MemoryOpResult unit)
+ | (true, false, false) =>
+ (throw (Error_not_implemented "store.aq")) : M (MemoryOpResult unit)
+ | (true, true, false) =>
+ MEMea_strong_release addr width >> returnm ((MemValue tt) : MemoryOpResult unit)
+ | (true, false, true) => (throw (Error_not_implemented "sc.aq")) : M (MemoryOpResult unit)
+ | (true, true, true) =>
+ MEMea_conditional_strong_release addr width >>
+ returnm ((MemValue tt)
+ : MemoryOpResult unit)
+ end)
+ : M (MemoryOpResult unit))
+ : M (MemoryOpResult unit).
+
+Definition phys_mem_write (addr : mword 64) (width : Z) (data : mword (8 * width))
+: M (MemoryOpResult bool) :=
+ let '_ :=
+ (print_endline
+ (String.append "mem["
+ (String.append (string_of_bits addr) (String.append "] <- " (string_of_bits data)))))
+ : unit in
+ __RISCV_write addr width data >>= fun w__0 : bool =>
+ returnm ((MemValue w__0)
+ : MemoryOpResult bool).
+
+Definition checked_mem_write (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult bool) :=
+ (if ((within_mmio_writable addr width)) then
+ (mmio_write addr width data)
+ : M (MemoryOpResult bool)
+ else if ((within_phys_mem addr width)) then
+ (phys_mem_write addr width data)
+ : M (MemoryOpResult bool)
+ else returnm ((MemException E_SAMO_Access_Fault) : MemoryOpResult bool))
+ : M (MemoryOpResult bool).
+
+Definition MEMval (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (width >= 1)}
+: M (MemoryOpResult bool) :=
+ (checked_mem_write addr width data)
+ : M (MemoryOpResult bool).
+
+Definition MEMval_release (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult bool) :=
+ (checked_mem_write addr width data)
+ : M (MemoryOpResult bool).
+
+Definition MEMval_strong_release (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult bool) :=
+ (checked_mem_write addr width data)
+ : M (MemoryOpResult bool).
+
+Definition MEMval_conditional (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult bool) :=
+ (checked_mem_write addr width data)
+ : M (MemoryOpResult bool).
+
+Definition MEMval_conditional_release (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult bool) :=
+ (checked_mem_write addr width data)
+ : M (MemoryOpResult bool).
+
+Definition MEMval_conditional_strong_release (addr : mword 64) (width : Z) (data : mword (8 * width)) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult bool) :=
+ (checked_mem_write addr width data)
+ : M (MemoryOpResult bool).
+
+Definition mem_write_value (addr : mword 64) (width : Z) (value : mword (8 * width)) (aq : bool) (rl : bool) (con : bool) `{ArithFact (width >=
+ 1)}
+: M (MemoryOpResult bool) :=
+ (if ((andb (orb rl con) (negb (is_aligned_addr addr width)))) then
+ returnm ((MemException E_SAMO_Addr_Align)
+ : MemoryOpResult bool)
+ else
+ (match (aq, rl, con) with
+ | (false, false, false) => (checked_mem_write addr width value) : M (MemoryOpResult bool)
+ | (false, true, false) => (MEMval_release addr width value) : M (MemoryOpResult bool)
+ | (false, false, true) => (MEMval_conditional addr width value) : M (MemoryOpResult bool)
+ | (false, true, true) =>
+ (MEMval_conditional_release addr width value) : M (MemoryOpResult bool)
+ | (true, false, false) =>
+ (throw (Error_not_implemented "store.aq")) : M (MemoryOpResult bool)
+ | (true, true, false) => (MEMval_strong_release addr width value) : M (MemoryOpResult bool)
+ | (true, false, true) => (throw (Error_not_implemented "sc.aq")) : M (MemoryOpResult bool)
+ | (true, true, true) =>
+ (MEMval_conditional_strong_release addr width value) : M (MemoryOpResult bool)
+ end)
+ : M (MemoryOpResult bool))
+ : M (MemoryOpResult bool).
+
+Axiom MEM_fence_rw_rw : forall (_ : unit) , M (unit).
+
+Axiom MEM_fence_r_rw : forall (_ : unit) , M (unit).
+
+Axiom MEM_fence_r_r : forall (_ : unit) , M (unit).
+
+Axiom MEM_fence_rw_w : forall (_ : unit) , M (unit).
+
+Axiom MEM_fence_w_w : forall (_ : unit) , M (unit).
+
+Axiom MEM_fence_w_rw : forall (_ : unit) , M (unit).
+
+Axiom MEM_fence_rw_r : forall (_ : unit) , M (unit).
+
+Axiom MEM_fence_r_w : forall (_ : unit) , M (unit).
+
+Axiom MEM_fence_w_r : forall (_ : unit) , M (unit).
+
+Axiom MEM_fence_i : forall (_ : unit) , M (unit).
+
+Let PAGESIZE_BITS := 12.
+Definition Mk_PTE_Bits (v : mword 8)
+: PTE_Bits :=
+ {| PTE_Bits_PTE_Bits_chunk_0 := (subrange_vec_dec v 7 0) |}.
+
+Definition _get_PTE_Bits_bits (v : PTE_Bits)
+: mword 8 :=
+ subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 7 0.
+
+Definition _set_PTE_Bits_bits (r_ref : register_ref regstate register_value PTE_Bits) (v : mword 8)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec r.(PTE_Bits_PTE_Bits_chunk_0) 7 0 (subrange_vec_dec v 7 0)) ]}
+ : PTE_Bits in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_PTE_Bits_bits (v : PTE_Bits) (x : mword 8)
+: PTE_Bits :=
+ {[ v with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 7 0 (subrange_vec_dec x 7 0)) ]}.
+
+Definition _get_PTE_Bits_D (v : PTE_Bits)
+: mword 1 :=
+ subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 7 7.
+
+Definition _set_PTE_Bits_D (r_ref : register_ref regstate register_value PTE_Bits) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec r.(PTE_Bits_PTE_Bits_chunk_0) 7 7 (subrange_vec_dec v 0 0)) ]}
+ : PTE_Bits in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_PTE_Bits_D (v : PTE_Bits) (x : mword 1)
+: PTE_Bits :=
+ {[ v with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 7 7 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_PTE_Bits_A (v : PTE_Bits)
+: mword 1 :=
+ subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 6 6.
+
+Definition _set_PTE_Bits_A (r_ref : register_ref regstate register_value PTE_Bits) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec r.(PTE_Bits_PTE_Bits_chunk_0) 6 6 (subrange_vec_dec v 0 0)) ]}
+ : PTE_Bits in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_PTE_Bits_A (v : PTE_Bits) (x : mword 1)
+: PTE_Bits :=
+ {[ v with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 6 6 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_PTE_Bits_G (v : PTE_Bits)
+: mword 1 :=
+ subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 5 5.
+
+Definition _set_PTE_Bits_G (r_ref : register_ref regstate register_value PTE_Bits) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec r.(PTE_Bits_PTE_Bits_chunk_0) 5 5 (subrange_vec_dec v 0 0)) ]}
+ : PTE_Bits in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_PTE_Bits_G (v : PTE_Bits) (x : mword 1)
+: PTE_Bits :=
+ {[ v with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 5 5 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_PTE_Bits_U (v : PTE_Bits)
+: mword 1 :=
+ subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 4 4.
+
+Definition _set_PTE_Bits_U (r_ref : register_ref regstate register_value PTE_Bits) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec r.(PTE_Bits_PTE_Bits_chunk_0) 4 4 (subrange_vec_dec v 0 0)) ]}
+ : PTE_Bits in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_PTE_Bits_U (v : PTE_Bits) (x : mword 1)
+: PTE_Bits :=
+ {[ v with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 4 4 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_PTE_Bits_X (v : PTE_Bits)
+: mword 1 :=
+ subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 3 3.
+
+Definition _set_PTE_Bits_X (r_ref : register_ref regstate register_value PTE_Bits) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec r.(PTE_Bits_PTE_Bits_chunk_0) 3 3 (subrange_vec_dec v 0 0)) ]}
+ : PTE_Bits in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_PTE_Bits_X (v : PTE_Bits) (x : mword 1)
+: PTE_Bits :=
+ {[ v with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 3 3 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_PTE_Bits_W (v : PTE_Bits)
+: mword 1 :=
+ subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 2 2.
+
+Definition _set_PTE_Bits_W (r_ref : register_ref regstate register_value PTE_Bits) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec r.(PTE_Bits_PTE_Bits_chunk_0) 2 2 (subrange_vec_dec v 0 0)) ]}
+ : PTE_Bits in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_PTE_Bits_W (v : PTE_Bits) (x : mword 1)
+: PTE_Bits :=
+ {[ v with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 2 2 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_PTE_Bits_R (v : PTE_Bits)
+: mword 1 :=
+ subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 1 1.
+
+Definition _set_PTE_Bits_R (r_ref : register_ref regstate register_value PTE_Bits) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec r.(PTE_Bits_PTE_Bits_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
+ : PTE_Bits in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_PTE_Bits_R (v : PTE_Bits) (x : mword 1)
+: PTE_Bits :=
+ {[ v with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.
+
+Definition _get_PTE_Bits_V (v : PTE_Bits)
+: mword 1 :=
+ subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 0 0.
+
+Definition _set_PTE_Bits_V (r_ref : register_ref regstate register_value PTE_Bits) (v : mword 1)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec r.(PTE_Bits_PTE_Bits_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
+ : PTE_Bits in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_PTE_Bits_V (v : PTE_Bits) (x : mword 1)
+: PTE_Bits :=
+ {[ v with
+ PTE_Bits_PTE_Bits_chunk_0 :=
+ (update_subrange_vec_dec v.(PTE_Bits_PTE_Bits_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.
+
+Definition isPTEPtr (p : mword 8)
+: bool :=
+ let a := Mk_PTE_Bits p in
+ andb (eq_vec (_get_PTE_Bits_R a) ((bool_to_bits false) : mword 1))
+ (andb (eq_vec (_get_PTE_Bits_W a) ((bool_to_bits false) : mword 1))
+ (eq_vec (_get_PTE_Bits_X a) ((bool_to_bits false) : mword 1))).
+
+Definition isInvalidPTE (p : mword 8)
+: bool :=
+ let a := Mk_PTE_Bits p in
+ orb (eq_vec (_get_PTE_Bits_V a) ((bool_to_bits false) : mword 1))
+ (andb (eq_vec (_get_PTE_Bits_W a) ((bool_to_bits true) : mword 1))
+ (eq_vec (_get_PTE_Bits_R a) ((bool_to_bits false) : mword 1))).
+
+Definition checkPTEPermission (ac : AccessType) (priv : Privilege) (mxr : bool) (do_sum : bool) (p : PTE_Bits)
+: M (bool) :=
+ (match (ac, priv) with
+ | (Read, User) =>
+ returnm ((andb (eq_vec (_get_PTE_Bits_U p) ((bool_to_bits true) : mword 1))
+ (orb (eq_vec (_get_PTE_Bits_R p) ((bool_to_bits true) : mword 1))
+ (andb (eq_vec (_get_PTE_Bits_X p) ((bool_to_bits true) : mword 1)) mxr)))
+ : bool)
+ | (Write, User) =>
+ returnm ((andb (eq_vec (_get_PTE_Bits_U p) ((bool_to_bits true) : mword 1))
+ (eq_vec (_get_PTE_Bits_W p) ((bool_to_bits true) : mword 1)))
+ : bool)
+ | (ReadWrite, User) =>
+ returnm ((andb (eq_vec (_get_PTE_Bits_U p) ((bool_to_bits true) : mword 1))
+ (andb (eq_vec (_get_PTE_Bits_W p) ((bool_to_bits true) : mword 1))
+ (orb (eq_vec (_get_PTE_Bits_R p) ((bool_to_bits true) : mword 1))
+ (andb (eq_vec (_get_PTE_Bits_X p) ((bool_to_bits true) : mword 1)) mxr))))
+ : bool)
+ | (Execute, User) =>
+ returnm ((andb (eq_vec (_get_PTE_Bits_U p) ((bool_to_bits true) : mword 1))
+ (eq_vec (_get_PTE_Bits_X p) ((bool_to_bits true) : mword 1)))
+ : bool)
+ | (Read, Supervisor) =>
+ returnm ((andb (orb (eq_vec (_get_PTE_Bits_U p) ((bool_to_bits false) : mword 1)) do_sum)
+ (orb (eq_vec (_get_PTE_Bits_R p) ((bool_to_bits true) : mword 1))
+ (andb (eq_vec (_get_PTE_Bits_X p) ((bool_to_bits true) : mword 1)) mxr)))
+ : bool)
+ | (Write, Supervisor) =>
+ returnm ((andb (orb (eq_vec (_get_PTE_Bits_U p) ((bool_to_bits false) : mword 1)) do_sum)
+ (eq_vec (_get_PTE_Bits_W p) ((bool_to_bits true) : mword 1)))
+ : bool)
+ | (ReadWrite, Supervisor) =>
+ returnm ((andb (orb (eq_vec (_get_PTE_Bits_U p) ((bool_to_bits false) : mword 1)) do_sum)
+ (andb (eq_vec (_get_PTE_Bits_W p) ((bool_to_bits true) : mword 1))
+ (orb (eq_vec (_get_PTE_Bits_R p) ((bool_to_bits true) : mword 1))
+ (andb (eq_vec (_get_PTE_Bits_X p) ((bool_to_bits true) : mword 1)) mxr))))
+ : bool)
+ | (Execute, Supervisor) =>
+ returnm ((andb (eq_vec (_get_PTE_Bits_U p) ((bool_to_bits false) : mword 1))
+ (eq_vec (_get_PTE_Bits_X p) ((bool_to_bits true) : mword 1)))
+ : bool)
+ | (_, Machine) => (internal_error "m-mode mem perm check") : M (bool)
+ end)
+ : M (bool).
+
+Definition update_PTE_Bits (p : PTE_Bits) (a : AccessType)
+: option PTE_Bits :=
+ let update_d :=
+ andb
+ (orb (generic_eq ((accessType_to_str a) : string) ((accessType_to_str Write) : string))
+ (generic_eq ((accessType_to_str a) : string) ((accessType_to_str ReadWrite) : string)))
+ (eq_vec (_get_PTE_Bits_D p) ((bool_to_bits false) : mword 1)) in
+ let update_a := eq_vec (_get_PTE_Bits_A p) ((bool_to_bits false) : mword 1) in
+ if ((orb update_d update_a)) then
+ let np := _update_PTE_Bits_A p ((bool_to_bits true) : mword 1) in
+ let np := if (update_d) then _update_PTE_Bits_D p ((bool_to_bits true) : mword 1) else np in
+ Some np
+ else None.
+
+Definition PTW_Error_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 4)}
+: PTW_Error :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then PTW_Access
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then PTW_Invalid_PTE
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then PTW_No_Permission
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then PTW_Misaligned
+ else PTW_PTE_Update.
+
+Definition num_of_PTW_Error (arg_ : PTW_Error)
+: {e : Z & ArithFact (0 <= e /\ e <= 4)} :=
+ match arg_ with
+ | PTW_Access => build_ex 0
+ | PTW_Invalid_PTE => build_ex 1
+ | PTW_No_Permission => build_ex 2
+ | PTW_Misaligned => build_ex 3
+ | PTW_PTE_Update => build_ex 4
+ end.
+
+Definition ptw_error_to_str (e : PTW_Error)
+: string :=
+ match e with
+ | PTW_Access => "mem-access-error"
+ | PTW_Invalid_PTE => "invalid-pte"
+ | PTW_No_Permission => "no-permission"
+ | PTW_Misaligned => "misaligned-superpage"
+ | PTW_PTE_Update => "pte-update-needed"
+ end.
+
+Definition translationException (a : AccessType) (f : PTW_Error)
+: ExceptionType :=
+ match (a, f) with
+ | (ReadWrite, PTW_Access) => E_SAMO_Access_Fault
+ | (ReadWrite, _) => E_SAMO_Page_Fault
+ | (Read, PTW_Access) => E_Load_Access_Fault
+ | (Read, _) => E_Load_Page_Fault
+ | (Write, PTW_Access) => E_SAMO_Access_Fault
+ | (Write, _) => E_SAMO_Page_Fault
+ | (Fetch, PTW_Access) => E_Fetch_Access_Fault
+ | (Fetch, _) => E_Fetch_Page_Fault
+ end.
+
+Let SV39_LEVEL_BITS := 9.
+Let SV39_LEVELS := 3.
+Let PTE39_LOG_SIZE := 3.
+Let PTE39_SIZE := 8.
+Definition Mk_SV39_Vaddr (v : mword 39)
+: SV39_Vaddr :=
+ {| SV39_Vaddr_SV39_Vaddr_chunk_0 := (subrange_vec_dec v 38 0) |}.
+
+Definition _get_SV39_Vaddr_bits (v : SV39_Vaddr)
+: mword 39 :=
+ subrange_vec_dec v.(SV39_Vaddr_SV39_Vaddr_chunk_0) 38 0.
+
+Definition _set_SV39_Vaddr_bits (r_ref : register_ref regstate register_value SV39_Vaddr) (v : mword 39)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_Vaddr_SV39_Vaddr_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_Vaddr_SV39_Vaddr_chunk_0) 38 0 (subrange_vec_dec v 38 0)) ]}
+ : SV39_Vaddr in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_Vaddr_bits (v : SV39_Vaddr) (x : mword 39)
+: SV39_Vaddr :=
+ {[ v with
+ SV39_Vaddr_SV39_Vaddr_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_Vaddr_SV39_Vaddr_chunk_0) 38 0 (subrange_vec_dec x 38 0)) ]}.
+
+Definition _get_SV39_Vaddr_VPNi (v : SV39_Vaddr)
+: mword 27 :=
+ subrange_vec_dec v.(SV39_Vaddr_SV39_Vaddr_chunk_0) 38 12.
+
+Definition _set_SV39_Vaddr_VPNi (r_ref : register_ref regstate register_value SV39_Vaddr) (v : mword 27)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_Vaddr_SV39_Vaddr_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_Vaddr_SV39_Vaddr_chunk_0) 38 12 (subrange_vec_dec v 26 0)) ]}
+ : SV39_Vaddr in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_Vaddr_VPNi (v : SV39_Vaddr) (x : mword 27)
+: SV39_Vaddr :=
+ {[ v with
+ SV39_Vaddr_SV39_Vaddr_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_Vaddr_SV39_Vaddr_chunk_0) 38 12 (subrange_vec_dec x 26 0)) ]}.
+
+Definition _get_SV39_Vaddr_PgOfs (v : SV39_Vaddr)
+: mword 12 :=
+ subrange_vec_dec v.(SV39_Vaddr_SV39_Vaddr_chunk_0) 11 0.
+
+Definition _set_SV39_Vaddr_PgOfs (r_ref : register_ref regstate register_value SV39_Vaddr) (v : mword 12)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_Vaddr_SV39_Vaddr_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_Vaddr_SV39_Vaddr_chunk_0) 11 0 (subrange_vec_dec v 11 0)) ]}
+ : SV39_Vaddr in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_Vaddr_PgOfs (v : SV39_Vaddr) (x : mword 12)
+: SV39_Vaddr :=
+ {[ v with
+ SV39_Vaddr_SV39_Vaddr_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_Vaddr_SV39_Vaddr_chunk_0) 11 0 (subrange_vec_dec x 11 0)) ]}.
+
+Definition Mk_SV39_Paddr (v : mword 56)
+: SV39_Paddr :=
+ {| SV39_Paddr_SV39_Paddr_chunk_0 := (subrange_vec_dec v 55 0) |}.
+
+Definition _get_SV39_Paddr_bits (v : SV39_Paddr)
+: mword 56 :=
+ subrange_vec_dec v.(SV39_Paddr_SV39_Paddr_chunk_0) 55 0.
+
+Definition _set_SV39_Paddr_bits (r_ref : register_ref regstate register_value SV39_Paddr) (v : mword 56)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_Paddr_SV39_Paddr_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_Paddr_SV39_Paddr_chunk_0) 55 0 (subrange_vec_dec v 55 0)) ]}
+ : SV39_Paddr in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_Paddr_bits (v : SV39_Paddr) (x : mword 56)
+: SV39_Paddr :=
+ {[ v with
+ SV39_Paddr_SV39_Paddr_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_Paddr_SV39_Paddr_chunk_0) 55 0 (subrange_vec_dec x 55 0)) ]}.
+
+Definition _get_SV39_Paddr_PPNi (v : SV39_Paddr)
+: mword 44 :=
+ subrange_vec_dec v.(SV39_Paddr_SV39_Paddr_chunk_0) 55 12.
+
+Definition _set_SV39_Paddr_PPNi (r_ref : register_ref regstate register_value SV39_Paddr) (v : mword 44)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_Paddr_SV39_Paddr_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_Paddr_SV39_Paddr_chunk_0) 55 12 (subrange_vec_dec v 43 0)) ]}
+ : SV39_Paddr in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_Paddr_PPNi (v : SV39_Paddr) (x : mword 44)
+: SV39_Paddr :=
+ {[ v with
+ SV39_Paddr_SV39_Paddr_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_Paddr_SV39_Paddr_chunk_0) 55 12 (subrange_vec_dec x 43 0)) ]}.
+
+Definition _get_SV39_Paddr_PgOfs (v : SV39_Paddr)
+: mword 12 :=
+ subrange_vec_dec v.(SV39_Paddr_SV39_Paddr_chunk_0) 11 0.
+
+Definition _set_SV39_Paddr_PgOfs (r_ref : register_ref regstate register_value SV39_Paddr) (v : mword 12)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_Paddr_SV39_Paddr_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_Paddr_SV39_Paddr_chunk_0) 11 0 (subrange_vec_dec v 11 0)) ]}
+ : SV39_Paddr in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_Paddr_PgOfs (v : SV39_Paddr) (x : mword 12)
+: SV39_Paddr :=
+ {[ v with
+ SV39_Paddr_SV39_Paddr_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_Paddr_SV39_Paddr_chunk_0) 11 0 (subrange_vec_dec x 11 0)) ]}.
+
+Definition Mk_SV39_PTE (v : mword 64)
+: SV39_PTE :=
+ {| SV39_PTE_SV39_PTE_chunk_0 := (subrange_vec_dec v 63 0) |}.
+
+Definition _get_SV39_PTE_bits (v : SV39_PTE)
+: mword 64 :=
+ subrange_vec_dec v.(SV39_PTE_SV39_PTE_chunk_0) 63 0.
+
+Definition _set_SV39_PTE_bits (r_ref : register_ref regstate register_value SV39_PTE) (v : mword 64)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_PTE_SV39_PTE_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_PTE_SV39_PTE_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
+ : SV39_PTE in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_PTE_bits (v : SV39_PTE) (x : mword 64)
+: SV39_PTE :=
+ {[ v with
+ SV39_PTE_SV39_PTE_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_PTE_SV39_PTE_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.
+
+Definition _get_SV39_PTE_PPNi (v : SV39_PTE)
+: mword 44 :=
+ subrange_vec_dec v.(SV39_PTE_SV39_PTE_chunk_0) 53 10.
+
+Definition _set_SV39_PTE_PPNi (r_ref : register_ref regstate register_value SV39_PTE) (v : mword 44)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_PTE_SV39_PTE_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_PTE_SV39_PTE_chunk_0) 53 10 (subrange_vec_dec v 43 0)) ]}
+ : SV39_PTE in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_PTE_PPNi (v : SV39_PTE) (x : mword 44)
+: SV39_PTE :=
+ {[ v with
+ SV39_PTE_SV39_PTE_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_PTE_SV39_PTE_chunk_0) 53 10 (subrange_vec_dec x 43 0)) ]}.
+
+Definition _get_SV39_PTE_RSW (v : SV39_PTE)
+: mword 2 :=
+ subrange_vec_dec v.(SV39_PTE_SV39_PTE_chunk_0) 9 8.
+
+Definition _set_SV39_PTE_RSW (r_ref : register_ref regstate register_value SV39_PTE) (v : mword 2)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_PTE_SV39_PTE_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_PTE_SV39_PTE_chunk_0) 9 8 (subrange_vec_dec v 1 0)) ]}
+ : SV39_PTE in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_PTE_RSW (v : SV39_PTE) (x : mword 2)
+: SV39_PTE :=
+ {[ v with
+ SV39_PTE_SV39_PTE_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_PTE_SV39_PTE_chunk_0) 9 8 (subrange_vec_dec x 1 0)) ]}.
+
+Definition _get_SV39_PTE_BITS (v : SV39_PTE)
+: mword 8 :=
+ subrange_vec_dec v.(SV39_PTE_SV39_PTE_chunk_0) 7 0.
+
+Definition _set_SV39_PTE_BITS (r_ref : register_ref regstate register_value SV39_PTE) (v : mword 8)
+: M (unit) :=
+ reg_deref r_ref >>= fun r =>
+ let r :=
+ {[ r with
+ SV39_PTE_SV39_PTE_chunk_0 :=
+ (update_subrange_vec_dec r.(SV39_PTE_SV39_PTE_chunk_0) 7 0 (subrange_vec_dec v 7 0)) ]}
+ : SV39_PTE in
+ write_reg r_ref r
+ : M (unit).
+
+Definition _update_SV39_PTE_BITS (v : SV39_PTE) (x : mword 8)
+: SV39_PTE :=
+ {[ v with
+ SV39_PTE_SV39_PTE_chunk_0 :=
+ (update_subrange_vec_dec v.(SV39_PTE_SV39_PTE_chunk_0) 7 0 (subrange_vec_dec x 7 0)) ]}.
+
+Definition curAsid64 '(tt : unit)
+: M (mword 16) :=
+ (read_reg satp_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ let satp64 := Mk_Satp64 w__0 in
+ returnm ((_get_Satp64_Asid satp64)
+ : mword 16).
+
+Definition curPTB39 '(tt : unit)
+: M (mword 56) :=
+ (read_reg satp_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ let satp64 := Mk_Satp64 w__0 in
+ returnm ((EXTZ 56 (shiftl (_get_Satp64_PPN satp64) PAGESIZE_BITS))
+ : mword 56).
+
+Fixpoint walk39 (vaddr : mword 39) (ac : AccessType) (priv : Privilege) (mxr : bool) (do_sum : bool) (ptb : mword 56) (level : nat) (global : bool)
+: M (PTW_Result) :=
+ let va := Mk_SV39_Vaddr vaddr in
+ let pt_ofs : paddr39 :=
+ shiftl
+ (EXTZ 56
+ (subrange_vec_dec (shiftr (_get_SV39_Vaddr_VPNi va) (Z.mul (Z.of_nat level) SV39_LEVEL_BITS))
+ (projT1 (sub_range (build_ex SV39_LEVEL_BITS) (build_ex 1))) 0)) PTE39_LOG_SIZE in
+ let pte_addr := add_vec ptb pt_ofs in
+ phys_mem_read Data (EXTZ 64 pte_addr) 8 false false false >>= fun w__0 : MemoryOpResult (mword 64) =>
+ (match w__0 with
+ | MemException (_) => returnm ((PTW_Failure PTW_Access) : PTW_Result)
+ | MemValue (v) =>
+ let pte := Mk_SV39_PTE v in
+ let pbits := _get_SV39_PTE_BITS pte in
+ let pattr := Mk_PTE_Bits pbits in
+ let is_global := orb global (eq_vec (_get_PTE_Bits_G pattr) ((bool_to_bits true) : mword 1)) in
+ (if ((isInvalidPTE pbits)) then returnm ((PTW_Failure PTW_Invalid_PTE) : PTW_Result)
+ else if ((isPTEPtr pbits)) then
+ (match level with | O =>
+ returnm ((PTW_Failure PTW_Invalid_PTE)
+ : PTW_Result)
+ | S level' =>
+ (walk39 vaddr ac priv mxr do_sum
+ (EXTZ 56 (shiftl (_get_SV39_PTE_PPNi pte) PAGESIZE_BITS))
+ level' is_global)
+ : M (PTW_Result) end)
+ : M (PTW_Result)
+ else
+ checkPTEPermission ac priv mxr do_sum pattr >>= fun w__3 : bool =>
+ returnm ((if ((negb w__3)) then PTW_Failure PTW_No_Permission
+ else if sumbool_of_bool (Nat.ltb O level) then
+ let mask :=
+ sub_vec_int
+ (shiftl
+ (xor_vec (_get_SV39_PTE_PPNi pte)
+ (xor_vec (_get_SV39_PTE_PPNi pte)
+ (EXTZ 44 (vec_of_bits [B1] : mword 1))))
+ (Z.mul (Z.of_nat level) SV39_LEVEL_BITS)) 1 in
+ if ((neq_vec (and_vec (_get_SV39_PTE_PPNi pte) mask)
+ (EXTZ 44 (vec_of_bits [B0] : mword 1)))) then
+ PTW_Failure PTW_Misaligned
+ else
+ let ppn :=
+ or_vec (_get_SV39_PTE_PPNi pte)
+ (and_vec (EXTZ 44 (_get_SV39_Vaddr_VPNi va)) mask) in
+ PTW_Success (concat_vec ppn (_get_SV39_Vaddr_PgOfs va),pte,pte_addr,build_ex
+ (Z.of_nat level),is_global)
+ else
+ PTW_Success (concat_vec (_get_SV39_PTE_PPNi pte) (_get_SV39_Vaddr_PgOfs va),pte,pte_addr,build_ex
+ (Z.of_nat level),is_global))
+ : PTW_Result))
+ : M (PTW_Result)
+ end)
+ : M (PTW_Result).
+
+Hint Unfold PAGESIZE_BITS : sail.
+Hint Unfold SV39_LEVEL_BITS : sail.
+
+Definition make_TLB39_Entry (asid : mword 16) (global : bool) (vAddr : mword 39) (pAddr : mword 56) (pte : SV39_PTE) '((existT _ level _) : {n : Z & ArithFact (n >=
+ 0)}) (pteAddr : mword 56)
+: M (TLB39_Entry) :=
+ let '(existT _ shift _) :=
+ (build_ex (projT1 (add_range (build_ex PAGESIZE_BITS) (build_ex (Z.mul level SV39_LEVEL_BITS)))))
+ : {n : Z & ArithFact (n >= 0)} in
+ let vAddrMask : vaddr39 :=
+ sub_vec_int
+ (shiftl (xor_vec vAddr (xor_vec vAddr (EXTZ 39 (vec_of_bits [B1] : mword 1)))) shift) 1 in
+ let vMatchMask : vaddr39 := not_vec vAddrMask in
+ (read_reg mcycle_ref : M (mword 64)) >>= fun w__0 : xlenbits =>
+ returnm (({| TLB39_Entry_asid := asid;
+ TLB39_Entry_global := global;
+ TLB39_Entry_pte := pte;
+ TLB39_Entry_pteAddr := pteAddr;
+ TLB39_Entry_vAddrMask := vAddrMask;
+ TLB39_Entry_vMatchMask := vMatchMask;
+ TLB39_Entry_vAddr := (and_vec vAddr vMatchMask);
+ TLB39_Entry_pAddr := (shiftl (shiftr pAddr shift) shift);
+ TLB39_Entry_age := w__0 |})
+ : TLB39_Entry).
+
+Definition lookupTLB39 (asid : mword 16) (vaddr : mword 39)
+: M (option ((Z * TLB39_Entry))) :=
+ read_reg tlb39_ref >>= fun w__0 : option TLB39_Entry =>
+ returnm ((match w__0 with
+ | None => None
+ | Some (e) =>
+ if ((andb (orb e.(TLB39_Entry_global) (eq_vec e.(TLB39_Entry_asid) asid))
+ (eq_vec e.(TLB39_Entry_vAddr) (and_vec e.(TLB39_Entry_vMatchMask) vaddr))))
+ then
+ Some (0, e)
+ else None
+ end)
+ : option ((Z * TLB39_Entry))).
+
+Definition addToTLB39 (asid : mword 16) (vAddr : mword 39) (pAddr : mword 56) (pte : SV39_PTE) (pteAddr : mword 56) '((existT _ level _) : {n : Z & ArithFact (n >=
+ 0)}) (global : bool)
+: M (unit) :=
+ make_TLB39_Entry asid global vAddr pAddr pte (build_ex level) pteAddr >>= fun ent =>
+ write_reg tlb39_ref (Some ent)
+ : M (unit).
+
+Definition writeTLB39 (idx : Z) (ent : TLB39_Entry)
+: M (unit) :=
+ write_reg tlb39_ref (Some ent)
+ : M (unit).
+
+Definition flushTLB (asid : option (mword 16)) (addr : option (mword 39))
+: M (unit) :=
+ read_reg tlb39_ref >>= fun w__0 : option TLB39_Entry =>
+ let ent : option TLB39_Entry :=
+ match (w__0, asid, addr) with
+ | (None, _, _) => None
+ | (Some (e), None, None) => None
+ | (Some (e), None, Some (a)) =>
+ if ((eq_vec e.(TLB39_Entry_vAddr) (and_vec e.(TLB39_Entry_vMatchMask) a))) then None
+ else Some e
+ | (Some (e), Some (i), None) =>
+ if ((andb (eq_vec e.(TLB39_Entry_asid) i) (negb e.(TLB39_Entry_global)))) then None
+ else Some e
+ | (Some (e), Some (i), Some (a)) =>
+ if ((andb (eq_vec e.(TLB39_Entry_asid) i)
+ (andb (eq_vec e.(TLB39_Entry_vAddr) (and_vec a e.(TLB39_Entry_vMatchMask)))
+ (negb e.(TLB39_Entry_global))))) then
+ None
+ else Some e
+ end in
+ write_reg tlb39_ref ent
+ : M (unit).
+
+Definition translate39 (vAddr : mword 39) (ac : AccessType) (priv : Privilege) (mxr : bool) (do_sum : bool) '((existT _ level _) : {n : Z & ArithFact (n >=
+ 0)})
+: M (TR39_Result) :=
+ curAsid64 tt >>= fun asid =>
+ lookupTLB39 asid vAddr >>= fun w__0 : option ((Z * TLB39_Entry)) =>
+ (match w__0 with
+ | Some (idx,ent) =>
+ let pteBits := Mk_PTE_Bits (_get_SV39_PTE_BITS ent.(TLB39_Entry_pte)) in
+ checkPTEPermission ac priv mxr do_sum pteBits >>= fun w__1 : bool =>
+ (if ((negb w__1)) then returnm ((TR39_Failure PTW_No_Permission) : TR39_Result)
+ else
+ (match (update_PTE_Bits pteBits ac) with
+ | None =>
+ returnm ((TR39_Address (or_vec ent.(TLB39_Entry_pAddr)
+ (EXTZ 56 (and_vec vAddr ent.(TLB39_Entry_vAddrMask)))))
+ : TR39_Result)
+ | Some (pbits) =>
+ (if ((negb (plat_enable_dirty_update tt))) then
+ returnm ((TR39_Failure PTW_PTE_Update)
+ : TR39_Result)
+ else
+ let n_ent : TLB39_Entry := ent in
+ let n_ent :=
+ {[ n_ent with
+ TLB39_Entry_pte :=
+ (_update_SV39_PTE_BITS ent.(TLB39_Entry_pte) (_get_PTE_Bits_bits pbits)) ]}
+ : TLB39_Entry in
+ writeTLB39 idx n_ent >>
+ checked_mem_write (EXTZ 64 ent.(TLB39_Entry_pteAddr)) 8
+ (_get_SV39_PTE_bits ent.(TLB39_Entry_pte)) >>= fun w__2 : MemoryOpResult bool =>
+ match w__2 with
+ | MemValue (_) => returnm (tt : unit)
+ | MemException (e) =>
+ (internal_error "invalid physical address in TLB") : M (unit)
+ end >>
+ returnm ((TR39_Address (or_vec ent.(TLB39_Entry_pAddr)
+ (EXTZ 56 (and_vec vAddr ent.(TLB39_Entry_vAddrMask)))))
+ : TR39_Result))
+ : M (TR39_Result)
+ end)
+ : M (TR39_Result))
+ : M (TR39_Result)
+ | None =>
+ curPTB39 tt >>= fun w__6 : mword 56 =>
+ walk39 vAddr ac priv mxr do_sum w__6 (Z.to_nat level) false >>= fun w__7 : PTW_Result =>
+ (match w__7 with
+ | PTW_Failure (f) => returnm ((TR39_Failure f) : TR39_Result)
+ | PTW_Success (pAddr,pte,pteAddr,(existT _ level _),global) =>
+ (match (update_PTE_Bits (Mk_PTE_Bits (_get_SV39_PTE_BITS pte)) ac) with
+ | None =>
+ addToTLB39 asid vAddr pAddr pte pteAddr (build_ex level) global >>
+ returnm ((TR39_Address pAddr)
+ : TR39_Result)
+ | Some (pbits) =>
+ (if ((negb (plat_enable_dirty_update tt))) then
+ returnm ((TR39_Failure PTW_PTE_Update)
+ : TR39_Result)
+ else
+ let w_pte : SV39_PTE := _update_SV39_PTE_BITS pte (_get_PTE_Bits_bits pbits) in
+ checked_mem_write (EXTZ 64 pteAddr) 8 (_get_SV39_PTE_bits w_pte) >>= fun w__8 : MemoryOpResult bool =>
+ (match w__8 with
+ | MemValue (_) =>
+ addToTLB39 asid vAddr pAddr w_pte pteAddr (build_ex level) global >>
+ returnm ((TR39_Address pAddr)
+ : TR39_Result)
+ | MemException (e) => returnm ((TR39_Failure PTW_Access) : TR39_Result)
+ end)
+ : M (TR39_Result))
+ : M (TR39_Result)
+ end)
+ : M (TR39_Result)
+ end)
+ : M (TR39_Result)
+ end)
+ : M (TR39_Result).
+
+Definition translationMode (priv : Privilege)
+: M (SATPMode) :=
+ (if ((eq_vec ((privLevel_to_bits priv) : mword 2) ((privLevel_to_bits Machine) : mword 2)))
+ then
+ returnm (Sbare
+ : SATPMode)
+ else
+ read_reg mstatus_ref >>= fun w__0 : Mstatus =>
+ let arch := architecture (_get_Mstatus_SXL w__0) in
+ (match arch with
+ | Some (RV64) =>
+ (read_reg satp_ref : M (mword 64)) >>= fun w__1 : mword 64 =>
+ let mbits : satp_mode := _get_Satp64_Mode (Mk_Satp64 w__1) in
+ (match (satpMode_of_bits RV64 mbits) with
+ | Some (m) => returnm (m : SATPMode)
+ | None => (internal_error "invalid RV64 translation mode in satp") : M (SATPMode)
+ end)
+ : M (SATPMode)
+ | _ => (internal_error "unsupported address translation arch") : M (SATPMode)
+ end)
+ : M (SATPMode))
+ : M (SATPMode).
+
+Definition translateAddr (vAddr : mword 64) (ac : AccessType) (rt : ReadType)
+: M (TR_Result) :=
+ match rt with
+ | Instruction => read_reg cur_privilege_ref : M (Privilege)
+ | Data =>
+ read_reg mstatus_ref >>= fun w__1 : Mstatus =>
+ (if ((eq_vec (_get_Mstatus_MPRV w__1) ((bool_to_bits true) : mword 1))) then
+ read_reg mstatus_ref >>= fun w__2 : Mstatus =>
+ returnm ((privLevel_of_bits (_get_Mstatus_MPP w__2))
+ : Privilege)
+ else read_reg cur_privilege_ref : M (Privilege))
+ : M (Privilege)
+ end >>= fun effPriv : Privilege =>
+ read_reg mstatus_ref >>= fun w__5 : Mstatus =>
+ let mxr : bool := eq_vec (_get_Mstatus_MXR w__5) ((bool_to_bits true) : mword 1) in
+ read_reg mstatus_ref >>= fun w__6 : Mstatus =>
+ let do_sum : bool := eq_vec (_get_Mstatus_SUM w__6) ((bool_to_bits true) : mword 1) in
+ translationMode effPriv >>= fun mode : SATPMode =>
+ (match mode with
+ | Sbare => returnm ((TR_Address vAddr) : TR_Result)
+ | SV39 =>
+ translate39 (subrange_vec_dec vAddr 38 0) ac effPriv mxr do_sum
+ (build_ex ( (Z.sub ( SV39_LEVELS) ( 1)))) >>= fun w__7 : TR39_Result =>
+ returnm ((match w__7 with
+ | TR39_Address (pa) => TR_Address (EXTZ 64 pa)
+ | TR39_Failure (f) => TR_Failure (translationException ac f)
+ end)
+ : TR_Result)
+ end)
+ : M (TR_Result).
+
+Definition encdec_uop_forwards (arg_ : uop)
+: mword 7 :=
+ match arg_ with
+ | RISCV_LUI => (vec_of_bits [B0;B1;B1;B0;B1;B1;B1] : mword 7)
+ | RISCV_AUIPC => (vec_of_bits [B0;B0;B1;B0;B1;B1;B1] : mword 7)
+ end.
+
+Definition encdec_uop_backwards (arg_ : mword 7)
+: uop :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B1;B1;B0;B1;B1;B1] : mword 7))) then RISCV_LUI
+ else RISCV_AUIPC.
+
+Definition encdec_uop_forwards_matches (arg_ : uop)
+: bool :=
+ match arg_ with | RISCV_LUI => true | RISCV_AUIPC => true end.
+
+Definition encdec_uop_backwards_matches (arg_ : mword 7)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B1;B1;B0;B1;B1;B1] : mword 7))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1;B0;B1;B1;B1] : mword 7))) then true
+ else false.
+
+Definition utype_mnemonic_forwards (arg_ : uop)
+: string :=
+ match arg_ with | RISCV_LUI => "lui" | RISCV_AUIPC => "auipc" end.
+
+Definition utype_mnemonic_backwards (arg_ : string)
+: M (uop) :=
+ (match arg_ with
+ | "lui" => returnm (RISCV_LUI : uop)
+ | "auipc" => returnm (RISCV_AUIPC : uop)
+ | _ => exit tt : M (uop)
+ end)
+ : M (uop).
+
+Definition utype_mnemonic_forwards_matches (arg_ : uop)
+: bool :=
+ match arg_ with | RISCV_LUI => true | RISCV_AUIPC => true end.
+
+Definition utype_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "lui" => true | "auipc" => true | _ => false end.
+
+Definition utype_mnemonic_matches_prefix (arg_ : string)
+: option ((uop * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1771_ := arg_ in
+ if ((andb (string_startswith _stringappend_1771_ "lui")
+ (match (string_drop _stringappend_1771_ (string_length "lui")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1771_ (string_length "lui")) with
+ | s_ => Some (RISCV_LUI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1771_ "auipc")
+ (match (string_drop _stringappend_1771_ (string_length "auipc")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1771_ (string_length "auipc")) with
+ | s_ => Some (RISCV_AUIPC, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition encdec_bop_forwards (arg_ : bop)
+: mword 3 :=
+ match arg_ with
+ | RISCV_BEQ => (vec_of_bits [B0;B0;B0] : mword 3)
+ | RISCV_BNE => (vec_of_bits [B0;B0;B1] : mword 3)
+ | RISCV_BLT => (vec_of_bits [B1;B0;B0] : mword 3)
+ | RISCV_BGE => (vec_of_bits [B1;B0;B1] : mword 3)
+ | RISCV_BLTU => (vec_of_bits [B1;B1;B0] : mword 3)
+ | RISCV_BGEU => (vec_of_bits [B1;B1;B1] : mword 3)
+ end.
+
+Definition encdec_bop_backwards (arg_ : mword 3)
+: bop :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3))) then RISCV_BEQ
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1] : mword 3))) then RISCV_BNE
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B0] : mword 3))) then RISCV_BLT
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1] : mword 3))) then RISCV_BGE
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0] : mword 3))) then RISCV_BLTU
+ else RISCV_BGEU.
+
+Definition encdec_bop_forwards_matches (arg_ : bop)
+: bool :=
+ match arg_ with
+ | RISCV_BEQ => true
+ | RISCV_BNE => true
+ | RISCV_BLT => true
+ | RISCV_BGE => true
+ | RISCV_BLTU => true
+ | RISCV_BGEU => true
+ end.
+
+Definition encdec_bop_backwards_matches (arg_ : mword 3)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B0] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1] : mword 3))) then true
+ else false.
+
+Definition btype_mnemonic_forwards (arg_ : bop)
+: string :=
+ match arg_ with
+ | RISCV_BEQ => "beq"
+ | RISCV_BNE => "bne"
+ | RISCV_BLT => "blt"
+ | RISCV_BGE => "bge"
+ | RISCV_BLTU => "bltu"
+ | RISCV_BGEU => "bgeu"
+ end.
+
+Definition btype_mnemonic_backwards (arg_ : string)
+: M (bop) :=
+ (match arg_ with
+ | "beq" => returnm (RISCV_BEQ : bop)
+ | "bne" => returnm (RISCV_BNE : bop)
+ | "blt" => returnm (RISCV_BLT : bop)
+ | "bge" => returnm (RISCV_BGE : bop)
+ | "bltu" => returnm (RISCV_BLTU : bop)
+ | "bgeu" => returnm (RISCV_BGEU : bop)
+ | _ => exit tt : M (bop)
+ end)
+ : M (bop).
+
+Definition btype_mnemonic_forwards_matches (arg_ : bop)
+: bool :=
+ match arg_ with
+ | RISCV_BEQ => true
+ | RISCV_BNE => true
+ | RISCV_BLT => true
+ | RISCV_BGE => true
+ | RISCV_BLTU => true
+ | RISCV_BGEU => true
+ end.
+
+Definition btype_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with
+ | "beq" => true
+ | "bne" => true
+ | "blt" => true
+ | "bge" => true
+ | "bltu" => true
+ | "bgeu" => true
+ | _ => false
+ end.
+
+Definition btype_mnemonic_matches_prefix (arg_ : string)
+: option ((bop * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1765_ := arg_ in
+ if ((andb (string_startswith _stringappend_1765_ "beq")
+ (match (string_drop _stringappend_1765_ (string_length "beq")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1765_ (string_length "beq")) with
+ | s_ => Some (RISCV_BEQ, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1765_ "bne")
+ (match (string_drop _stringappend_1765_ (string_length "bne")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1765_ (string_length "bne")) with
+ | s_ => Some (RISCV_BNE, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1765_ "blt")
+ (match (string_drop _stringappend_1765_ (string_length "blt")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1765_ (string_length "blt")) with
+ | s_ => Some (RISCV_BLT, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1765_ "bge")
+ (match (string_drop _stringappend_1765_ (string_length "bge")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1765_ (string_length "bge")) with
+ | s_ => Some (RISCV_BGE, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1765_ "bltu")
+ (match (string_drop _stringappend_1765_ (string_length "bltu")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1765_ (string_length "bltu")) with
+ | s_ => Some (RISCV_BLTU, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1765_ "bgeu")
+ (match (string_drop _stringappend_1765_ (string_length "bgeu")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1765_ (string_length "bgeu")) with
+ | s_ => Some (RISCV_BGEU, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition encdec_iop_forwards (arg_ : iop)
+: mword 3 :=
+ match arg_ with
+ | RISCV_ADDI => (vec_of_bits [B0;B0;B0] : mword 3)
+ | RISCV_SLTI => (vec_of_bits [B0;B1;B0] : mword 3)
+ | RISCV_SLTIU => (vec_of_bits [B0;B1;B1] : mword 3)
+ | RISCV_XORI => (vec_of_bits [B1;B0;B0] : mword 3)
+ | RISCV_ORI => (vec_of_bits [B1;B1;B0] : mword 3)
+ | RISCV_ANDI => (vec_of_bits [B1;B1;B1] : mword 3)
+ end.
+
+Definition encdec_iop_backwards (arg_ : mword 3)
+: iop :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3))) then RISCV_ADDI
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B0] : mword 3))) then RISCV_SLTI
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1] : mword 3))) then RISCV_SLTIU
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B0] : mword 3))) then RISCV_XORI
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0] : mword 3))) then RISCV_ORI
+ else RISCV_ANDI.
+
+Definition encdec_iop_forwards_matches (arg_ : iop)
+: bool :=
+ match arg_ with
+ | RISCV_ADDI => true
+ | RISCV_SLTI => true
+ | RISCV_SLTIU => true
+ | RISCV_XORI => true
+ | RISCV_ORI => true
+ | RISCV_ANDI => true
+ end.
+
+Definition encdec_iop_backwards_matches (arg_ : mword 3)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B0] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B0] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B0] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1;B1] : mword 3))) then true
+ else false.
+
+Definition itype_mnemonic_forwards (arg_ : iop)
+: string :=
+ match arg_ with
+ | RISCV_ADDI => "addi"
+ | RISCV_SLTI => "slti"
+ | RISCV_SLTIU => "sltiu"
+ | RISCV_XORI => "xori"
+ | RISCV_ORI => "ori"
+ | RISCV_ANDI => "andi"
+ end.
+
+Definition itype_mnemonic_backwards (arg_ : string)
+: M (iop) :=
+ (match arg_ with
+ | "addi" => returnm (RISCV_ADDI : iop)
+ | "slti" => returnm (RISCV_SLTI : iop)
+ | "sltiu" => returnm (RISCV_SLTIU : iop)
+ | "xori" => returnm (RISCV_XORI : iop)
+ | "ori" => returnm (RISCV_ORI : iop)
+ | "andi" => returnm (RISCV_ANDI : iop)
+ | _ => exit tt : M (iop)
+ end)
+ : M (iop).
+
+Definition itype_mnemonic_forwards_matches (arg_ : iop)
+: bool :=
+ match arg_ with
+ | RISCV_ADDI => true
+ | RISCV_SLTI => true
+ | RISCV_SLTIU => true
+ | RISCV_XORI => true
+ | RISCV_ORI => true
+ | RISCV_ANDI => true
+ end.
+
+Definition itype_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with
+ | "addi" => true
+ | "slti" => true
+ | "sltiu" => true
+ | "xori" => true
+ | "ori" => true
+ | "andi" => true
+ | _ => false
+ end.
+
+Definition itype_mnemonic_matches_prefix (arg_ : string)
+: option ((iop * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1759_ := arg_ in
+ if ((andb (string_startswith _stringappend_1759_ "addi")
+ (match (string_drop _stringappend_1759_ (string_length "addi")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1759_ (string_length "addi")) with
+ | s_ => Some (RISCV_ADDI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1759_ "slti")
+ (match (string_drop _stringappend_1759_ (string_length "slti")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1759_ (string_length "slti")) with
+ | s_ => Some (RISCV_SLTI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1759_ "sltiu")
+ (match (string_drop _stringappend_1759_ (string_length "sltiu")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1759_ (string_length "sltiu")) with
+ | s_ => Some (RISCV_SLTIU, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1759_ "xori")
+ (match (string_drop _stringappend_1759_ (string_length "xori")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1759_ (string_length "xori")) with
+ | s_ => Some (RISCV_XORI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1759_ "ori")
+ (match (string_drop _stringappend_1759_ (string_length "ori")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1759_ (string_length "ori")) with
+ | s_ => Some (RISCV_ORI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1759_ "andi")
+ (match (string_drop _stringappend_1759_ (string_length "andi")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1759_ (string_length "andi")) with
+ | s_ => Some (RISCV_ANDI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition encdec_sop_forwards (arg_ : sop)
+: mword 3 :=
+ match arg_ with
+ | RISCV_SLLI => (vec_of_bits [B0;B0;B1] : mword 3)
+ | RISCV_SRLI => (vec_of_bits [B1;B0;B1] : mword 3)
+ | RISCV_SRAI => (vec_of_bits [B1;B0;B1] : mword 3)
+ end.
+
+Definition encdec_sop_backwards (arg_ : mword 3)
+: sop :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B1] : mword 3))) then RISCV_SLLI
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1] : mword 3))) then RISCV_SRLI
+ else RISCV_SRAI.
+
+Definition encdec_sop_forwards_matches (arg_ : sop)
+: bool :=
+ match arg_ with | RISCV_SLLI => true | RISCV_SRLI => true | RISCV_SRAI => true end.
+
+Definition encdec_sop_backwards_matches (arg_ : mword 3)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B1] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0;B1] : mword 3))) then true
+ else false.
+
+Definition shiftiop_mnemonic_forwards (arg_ : sop)
+: string :=
+ match arg_ with | RISCV_SLLI => "slli" | RISCV_SRLI => "srli" | RISCV_SRAI => "srai" end.
+
+Definition shiftiop_mnemonic_backwards (arg_ : string)
+: M (sop) :=
+ (match arg_ with
+ | "slli" => returnm (RISCV_SLLI : sop)
+ | "srli" => returnm (RISCV_SRLI : sop)
+ | "srai" => returnm (RISCV_SRAI : sop)
+ | _ => exit tt : M (sop)
+ end)
+ : M (sop).
+
+Definition shiftiop_mnemonic_forwards_matches (arg_ : sop)
+: bool :=
+ match arg_ with | RISCV_SLLI => true | RISCV_SRLI => true | RISCV_SRAI => true end.
+
+Definition shiftiop_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "slli" => true | "srli" => true | "srai" => true | _ => false end.
+
+Definition shiftiop_mnemonic_matches_prefix (arg_ : string)
+: option ((sop * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1756_ := arg_ in
+ if ((andb (string_startswith _stringappend_1756_ "slli")
+ (match (string_drop _stringappend_1756_ (string_length "slli")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1756_ (string_length "slli")) with
+ | s_ => Some (RISCV_SLLI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1756_ "srli")
+ (match (string_drop _stringappend_1756_ (string_length "srli")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1756_ (string_length "srli")) with
+ | s_ => Some (RISCV_SRLI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1756_ "srai")
+ (match (string_drop _stringappend_1756_ (string_length "srai")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1756_ (string_length "srai")) with
+ | s_ => Some (RISCV_SRAI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition rtype_mnemonic_forwards (arg_ : rop)
+: string :=
+ match arg_ with
+ | RISCV_ADD => "add"
+ | RISCV_SUB => "sub"
+ | RISCV_SLL => "sll"
+ | RISCV_SLT => "slt"
+ | RISCV_SLTU => "sltu"
+ | RISCV_XOR => "xor"
+ | RISCV_SRL => "srl"
+ | RISCV_SRA => "sra"
+ | RISCV_OR => "or"
+ | RISCV_AND => "and"
+ end.
+
+Definition rtype_mnemonic_backwards (arg_ : string)
+: M (rop) :=
+ (match arg_ with
+ | "add" => returnm (RISCV_ADD : rop)
+ | "sub" => returnm (RISCV_SUB : rop)
+ | "sll" => returnm (RISCV_SLL : rop)
+ | "slt" => returnm (RISCV_SLT : rop)
+ | "sltu" => returnm (RISCV_SLTU : rop)
+ | "xor" => returnm (RISCV_XOR : rop)
+ | "srl" => returnm (RISCV_SRL : rop)
+ | "sra" => returnm (RISCV_SRA : rop)
+ | "or" => returnm (RISCV_OR : rop)
+ | "and" => returnm (RISCV_AND : rop)
+ | _ => exit tt : M (rop)
+ end)
+ : M (rop).
+
+Definition rtype_mnemonic_forwards_matches (arg_ : rop)
+: bool :=
+ match arg_ with
+ | RISCV_ADD => true
+ | RISCV_SUB => true
+ | RISCV_SLL => true
+ | RISCV_SLT => true
+ | RISCV_SLTU => true
+ | RISCV_XOR => true
+ | RISCV_SRL => true
+ | RISCV_SRA => true
+ | RISCV_OR => true
+ | RISCV_AND => true
+ end.
+
+Definition rtype_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with
+ | "add" => true
+ | "sub" => true
+ | "sll" => true
+ | "slt" => true
+ | "sltu" => true
+ | "xor" => true
+ | "srl" => true
+ | "sra" => true
+ | "or" => true
+ | "and" => true
+ | _ => false
+ end.
+
+Definition rtype_mnemonic_matches_prefix (arg_ : string)
+: option ((rop * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1746_ := arg_ in
+ if ((andb (string_startswith _stringappend_1746_ "add")
+ (match (string_drop _stringappend_1746_ (string_length "add")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "add")) with
+ | s_ => Some (RISCV_ADD, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1746_ "sub")
+ (match (string_drop _stringappend_1746_ (string_length "sub")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "sub")) with
+ | s_ => Some (RISCV_SUB, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1746_ "sll")
+ (match (string_drop _stringappend_1746_ (string_length "sll")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "sll")) with
+ | s_ => Some (RISCV_SLL, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1746_ "slt")
+ (match (string_drop _stringappend_1746_ (string_length "slt")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "slt")) with
+ | s_ => Some (RISCV_SLT, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1746_ "sltu")
+ (match (string_drop _stringappend_1746_ (string_length "sltu")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "sltu")) with
+ | s_ => Some (RISCV_SLTU, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1746_ "xor")
+ (match (string_drop _stringappend_1746_ (string_length "xor")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "xor")) with
+ | s_ => Some (RISCV_XOR, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1746_ "srl")
+ (match (string_drop _stringappend_1746_ (string_length "srl")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "srl")) with
+ | s_ => Some (RISCV_SRL, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1746_ "sra")
+ (match (string_drop _stringappend_1746_ (string_length "sra")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "sra")) with
+ | s_ => Some (RISCV_SRA, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1746_ "or")
+ (match (string_drop _stringappend_1746_ (string_length "or")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "or")) with
+ | s_ => Some (RISCV_OR, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1746_ "and")
+ (match (string_drop _stringappend_1746_ (string_length "and")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1746_ (string_length "and")) with
+ | s_ => Some (RISCV_AND, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition extend_value {n : Z} (is_unsigned : bool) (value : MemoryOpResult (mword (8 * n))) `{ArithFact (1 <=
+ n /\
+ n <= 8)}
+: MemoryOpResult (mword 64) :=
+ match value with
+ | MemValue (v) => MemValue (if (is_unsigned) then EXTZ 64 v else (EXTS 64 v) : xlenbits)
+ | MemException (e) => MemException e
+ end.
+
+Definition process_load {n : Z} (rd : mword 5) (addr : mword 64) (value : MemoryOpResult (mword (8 * n))) (is_unsigned : bool) `{ArithFact (1 <=
+ n /\
+ n <= 8)}
+: M (bool) :=
+ (match (extend_value is_unsigned value) with
+ | MemValue (result) =>
+ wX
+ (projT1 ((regbits_to_regno rd)
+ : {syn_n : Z & ArithFact (0 <= syn_n /\ (syn_n + 1) <= 32)})) result >>
+ returnm (true
+ : bool)
+ | MemException (e) => handle_mem_exception addr e >> returnm (false : bool)
+ end)
+ : M (bool).
+
+Definition check_misaligned (vaddr : mword 64) (width : word_width)
+: M (bool) :=
+ (if ((plat_enable_misaligned_access tt)) then returnm (false : bool)
+ else
+ (match width with
+ | BYTE => returnm (false : bool)
+ | HALF =>
+ cast_unit_vec (access_vec_dec vaddr 0) >>= fun w__0 : mword 1 =>
+ returnm ((eq_vec (w__0 : mword 1) ((bool_to_bits true) : mword 1))
+ : bool)
+ | WORD =>
+ (or_boolM
+ (cast_unit_vec (access_vec_dec vaddr 0) >>= fun w__1 : mword 1 =>
+ returnm ((eq_vec (w__1 : mword 1) ((bool_to_bits true) : mword 1))
+ : bool))
+ (cast_unit_vec (access_vec_dec vaddr 1) >>= fun w__2 : mword 1 =>
+ returnm ((eq_vec (w__2 : mword 1) ((bool_to_bits true) : mword 1))
+ : bool)))
+ : M (bool)
+ | DOUBLE =>
+ (or_boolM
+ (cast_unit_vec (access_vec_dec vaddr 0) >>= fun w__4 : mword 1 =>
+ returnm ((eq_vec (w__4 : mword 1) ((bool_to_bits true) : mword 1))
+ : bool))
+ ((or_boolM
+ (cast_unit_vec (access_vec_dec vaddr 1) >>= fun w__5 : mword 1 =>
+ returnm ((eq_vec (w__5 : mword 1) ((bool_to_bits true) : mword 1))
+ : bool))
+ (cast_unit_vec (access_vec_dec vaddr 2) >>= fun w__6 : mword 1 =>
+ returnm ((eq_vec (w__6 : mword 1) ((bool_to_bits true) : mword 1))
+ : bool)))
+ : M (bool)))
+ : M (bool)
+ end)
+ : M (bool))
+ : M (bool).
+
+Definition maybe_aq_forwards (arg_ : bool)
+: string :=
+ match arg_ with | true => ".aq" | false => "" end.
+
+Definition maybe_aq_backwards (arg_ : string)
+: M (bool) :=
+ (match arg_ with
+ | ".aq" => returnm (true : bool)
+ | "" => returnm (false : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool).
+
+Definition maybe_aq_forwards_matches (arg_ : bool)
+: bool :=
+ match arg_ with | true => true | false => true end.
+
+Definition maybe_aq_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | ".aq" => true | "" => true | _ => false end.
+
+Definition maybe_aq_matches_prefix (arg_ : string)
+: option ((bool * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1744_ := arg_ in
+ if ((andb (string_startswith _stringappend_1744_ ".aq")
+ (match (string_drop _stringappend_1744_ (string_length ".aq")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1744_ (string_length ".aq")) with
+ | s_ => Some (true, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1744_ "")
+ (match (string_drop _stringappend_1744_ (string_length "")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1744_ (string_length "")) with
+ | s_ => Some (false, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition maybe_rl_forwards (arg_ : bool)
+: string :=
+ match arg_ with | true => ".rl" | false => "" end.
+
+Definition maybe_rl_backwards (arg_ : string)
+: M (bool) :=
+ (match arg_ with
+ | ".rl" => returnm (true : bool)
+ | "" => returnm (false : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool).
+
+Definition maybe_rl_forwards_matches (arg_ : bool)
+: bool :=
+ match arg_ with | true => true | false => true end.
+
+Definition maybe_rl_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | ".rl" => true | "" => true | _ => false end.
+
+Definition maybe_rl_matches_prefix (arg_ : string)
+: option ((bool * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1742_ := arg_ in
+ if ((andb (string_startswith _stringappend_1742_ ".rl")
+ (match (string_drop _stringappend_1742_ (string_length ".rl")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1742_ (string_length ".rl")) with
+ | s_ => Some (true, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1742_ "")
+ (match (string_drop _stringappend_1742_ (string_length "")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1742_ (string_length "")) with
+ | s_ => Some (false, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition maybe_u_forwards (arg_ : bool)
+: string :=
+ match arg_ with | true => "u" | false => "" end.
+
+Definition maybe_u_backwards (arg_ : string)
+: M (bool) :=
+ (match arg_ with
+ | "u" => returnm (true : bool)
+ | "" => returnm (false : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool).
+
+Definition maybe_u_forwards_matches (arg_ : bool)
+: bool :=
+ match arg_ with | true => true | false => true end.
+
+Definition maybe_u_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "u" => true | "" => true | _ => false end.
+
+Definition maybe_u_matches_prefix (arg_ : string)
+: option ((bool * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1740_ := arg_ in
+ if ((andb (string_startswith _stringappend_1740_ "u")
+ (match (string_drop _stringappend_1740_ (string_length "u")) with | s_ => true end))) then
+ match (string_drop _stringappend_1740_ (string_length "u")) with
+ | s_ => Some (true, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1740_ "")
+ (match (string_drop _stringappend_1740_ (string_length "")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1740_ (string_length "")) with
+ | s_ => Some (false, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition shiftw_mnemonic_forwards (arg_ : sop)
+: string :=
+ match arg_ with | RISCV_SLLI => "slli" | RISCV_SRLI => "srli" | RISCV_SRAI => "srai" end.
+
+Definition shiftw_mnemonic_backwards (arg_ : string)
+: M (sop) :=
+ (match arg_ with
+ | "slli" => returnm (RISCV_SLLI : sop)
+ | "srli" => returnm (RISCV_SRLI : sop)
+ | "srai" => returnm (RISCV_SRAI : sop)
+ | _ => exit tt : M (sop)
+ end)
+ : M (sop).
+
+Definition shiftw_mnemonic_forwards_matches (arg_ : sop)
+: bool :=
+ match arg_ with | RISCV_SLLI => true | RISCV_SRLI => true | RISCV_SRAI => true end.
+
+Definition shiftw_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "slli" => true | "srli" => true | "srai" => true | _ => false end.
+
+Definition shiftw_mnemonic_matches_prefix (arg_ : string)
+: option ((sop * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1737_ := arg_ in
+ if ((andb (string_startswith _stringappend_1737_ "slli")
+ (match (string_drop _stringappend_1737_ (string_length "slli")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1737_ (string_length "slli")) with
+ | s_ => Some (RISCV_SLLI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1737_ "srli")
+ (match (string_drop _stringappend_1737_ (string_length "srli")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1737_ (string_length "srli")) with
+ | s_ => Some (RISCV_SRLI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1737_ "srai")
+ (match (string_drop _stringappend_1737_ (string_length "srai")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1737_ (string_length "srai")) with
+ | s_ => Some (RISCV_SRAI, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition rtypew_mnemonic_forwards (arg_ : ropw)
+: string :=
+ match arg_ with
+ | RISCV_ADDW => "addw"
+ | RISCV_SUBW => "subw"
+ | RISCV_SLLW => "sllw"
+ | RISCV_SRLW => "srlw"
+ | RISCV_SRAW => "sraw"
+ end.
+
+Definition rtypew_mnemonic_backwards (arg_ : string)
+: M (ropw) :=
+ (match arg_ with
+ | "addw" => returnm (RISCV_ADDW : ropw)
+ | "subw" => returnm (RISCV_SUBW : ropw)
+ | "sllw" => returnm (RISCV_SLLW : ropw)
+ | "srlw" => returnm (RISCV_SRLW : ropw)
+ | "sraw" => returnm (RISCV_SRAW : ropw)
+ | _ => exit tt : M (ropw)
+ end)
+ : M (ropw).
+
+Definition rtypew_mnemonic_forwards_matches (arg_ : ropw)
+: bool :=
+ match arg_ with
+ | RISCV_ADDW => true
+ | RISCV_SUBW => true
+ | RISCV_SLLW => true
+ | RISCV_SRLW => true
+ | RISCV_SRAW => true
+ end.
+
+Definition rtypew_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with
+ | "addw" => true
+ | "subw" => true
+ | "sllw" => true
+ | "srlw" => true
+ | "sraw" => true
+ | _ => false
+ end.
+
+Definition rtypew_mnemonic_matches_prefix (arg_ : string)
+: option ((ropw * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1732_ := arg_ in
+ if ((andb (string_startswith _stringappend_1732_ "addw")
+ (match (string_drop _stringappend_1732_ (string_length "addw")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1732_ (string_length "addw")) with
+ | s_ => Some (RISCV_ADDW, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1732_ "subw")
+ (match (string_drop _stringappend_1732_ (string_length "subw")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1732_ (string_length "subw")) with
+ | s_ => Some (RISCV_SUBW, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1732_ "sllw")
+ (match (string_drop _stringappend_1732_ (string_length "sllw")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1732_ (string_length "sllw")) with
+ | s_ => Some (RISCV_SLLW, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1732_ "srlw")
+ (match (string_drop _stringappend_1732_ (string_length "srlw")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1732_ (string_length "srlw")) with
+ | s_ => Some (RISCV_SRLW, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1732_ "sraw")
+ (match (string_drop _stringappend_1732_ (string_length "sraw")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1732_ (string_length "sraw")) with
+ | s_ => Some (RISCV_SRAW, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition shiftiwop_mnemonic_forwards (arg_ : sopw)
+: string :=
+ match arg_ with | RISCV_SLLIW => "slliw" | RISCV_SRLIW => "srliw" | RISCV_SRAIW => "sraiw" end.
+
+Definition shiftiwop_mnemonic_backwards (arg_ : string)
+: M (sopw) :=
+ (match arg_ with
+ | "slliw" => returnm (RISCV_SLLIW : sopw)
+ | "srliw" => returnm (RISCV_SRLIW : sopw)
+ | "sraiw" => returnm (RISCV_SRAIW : sopw)
+ | _ => exit tt : M (sopw)
+ end)
+ : M (sopw).
+
+Definition shiftiwop_mnemonic_forwards_matches (arg_ : sopw)
+: bool :=
+ match arg_ with | RISCV_SLLIW => true | RISCV_SRLIW => true | RISCV_SRAIW => true end.
+
+Definition shiftiwop_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "slliw" => true | "srliw" => true | "sraiw" => true | _ => false end.
+
+Definition shiftiwop_mnemonic_matches_prefix (arg_ : string)
+: option ((sopw * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1729_ := arg_ in
+ if ((andb (string_startswith _stringappend_1729_ "slliw")
+ (match (string_drop _stringappend_1729_ (string_length "slliw")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1729_ (string_length "slliw")) with
+ | s_ => Some (RISCV_SLLIW, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1729_ "srliw")
+ (match (string_drop _stringappend_1729_ (string_length "srliw")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1729_ (string_length "srliw")) with
+ | s_ => Some (RISCV_SRLIW, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1729_ "sraiw")
+ (match (string_drop _stringappend_1729_ (string_length "sraiw")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1729_ (string_length "sraiw")) with
+ | s_ => Some (RISCV_SRAIW, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition encdec_mul_op_forwards (arg0 : bool) (arg1 : bool) (arg2 : bool)
+: M (mword 3) :=
+ let arg_ := (arg0, arg1, arg2) in
+ (match arg_ with
+ | (false, true, true) => returnm ((vec_of_bits [B0;B0;B0] : mword 3) : mword 3)
+ | (true, true, true) => returnm ((vec_of_bits [B0;B0;B1] : mword 3) : mword 3)
+ | (true, true, false) => returnm ((vec_of_bits [B0;B1;B0] : mword 3) : mword 3)
+ | (true, false, false) => returnm ((vec_of_bits [B0;B1;B1] : mword 3) : mword 3)
+ | _ => exit tt : M (mword 3)
+ end)
+ : M (mword 3).
+
+Definition encdec_mul_op_backwards (arg_ : mword 3)
+: (bool * bool * bool) :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3))) then (false, true, true)
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1] : mword 3))) then (true, true, true)
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B0] : mword 3))) then (true, true, false)
+ else (true, false, false).
+
+Definition encdec_mul_op_forwards_matches (arg0 : bool) (arg1 : bool) (arg2 : bool)
+: bool :=
+ let arg_ := (arg0, arg1, arg2) in
+ match arg_ with
+ | (false, true, true) => true
+ | (true, true, true) => true
+ | (true, true, false) => true
+ | (true, false, false) => true
+ | _ => false
+ end.
+
+Definition encdec_mul_op_backwards_matches (arg_ : mword 3)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B0;B1] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B0] : mword 3))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0;B1;B1] : mword 3))) then true
+ else false.
+
+Definition mul_mnemonic_forwards (arg0 : bool) (arg1 : bool) (arg2 : bool)
+: M (string) :=
+ let arg_ := (arg0, arg1, arg2) in
+ (match arg_ with
+ | (false, true, true) => returnm ("mul" : string)
+ | (true, true, true) => returnm ("mulh" : string)
+ | (true, true, false) => returnm ("mulhsu" : string)
+ | (true, false, false) => returnm ("mulhu" : string)
+ | _ => exit tt : M (string)
+ end)
+ : M (string).
+
+Definition mul_mnemonic_backwards (arg_ : string)
+: M ((bool * bool * bool)) :=
+ (match arg_ with
+ | "mul" => returnm ((false, true, true) : (bool * bool * bool))
+ | "mulh" => returnm ((true, true, true) : (bool * bool * bool))
+ | "mulhsu" => returnm ((true, true, false) : (bool * bool * bool))
+ | "mulhu" => returnm ((true, false, false) : (bool * bool * bool))
+ | _ => exit tt : M ((bool * bool * bool))
+ end)
+ : M ((bool * bool * bool)).
+
+Definition mul_mnemonic_forwards_matches (arg0 : bool) (arg1 : bool) (arg2 : bool)
+: bool :=
+ let arg_ := (arg0, arg1, arg2) in
+ match arg_ with
+ | (false, true, true) => true
+ | (true, true, true) => true
+ | (true, true, false) => true
+ | (true, false, false) => true
+ | _ => false
+ end.
+
+Definition mul_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with
+ | "mul" => true
+ | "mulh" => true
+ | "mulhsu" => true
+ | "mulhu" => true
+ | _ => false
+ end.
+
+Definition mul_mnemonic_matches_prefix (arg_ : string)
+: option (((bool * bool * bool) * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1725_ := arg_ in
+ if ((andb (string_startswith _stringappend_1725_ "mul")
+ (match (string_drop _stringappend_1725_ (string_length "mul")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1725_ (string_length "mul")) with
+ | s_ => Some ((false, true, true), sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1725_ "mulh")
+ (match (string_drop _stringappend_1725_ (string_length "mulh")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1725_ (string_length "mulh")) with
+ | s_ => Some ((true, true, true), sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1725_ "mulhsu")
+ (match (string_drop _stringappend_1725_ (string_length "mulhsu")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1725_ (string_length "mulhsu")) with
+ | s_ => Some ((true, true, false), sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1725_ "mulhu")
+ (match (string_drop _stringappend_1725_ (string_length "mulhu")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1725_ (string_length "mulhu")) with
+ | s_ => Some ((true, false, false), sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition maybe_not_u_forwards (arg_ : bool)
+: string :=
+ match arg_ with | false => "u" | true => "" end.
+
+Definition maybe_not_u_backwards (arg_ : string)
+: M (bool) :=
+ (match arg_ with
+ | "u" => returnm (false : bool)
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool).
+
+Definition maybe_not_u_forwards_matches (arg_ : bool)
+: bool :=
+ match arg_ with | false => true | true => true end.
+
+Definition maybe_not_u_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "u" => true | "" => true | _ => false end.
+
+Definition maybe_not_u_matches_prefix (arg_ : string)
+: option ((bool * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1723_ := arg_ in
+ if ((andb (string_startswith _stringappend_1723_ "u")
+ (match (string_drop _stringappend_1723_ (string_length "u")) with | s_ => true end))) then
+ match (string_drop _stringappend_1723_ (string_length "u")) with
+ | s_ => Some (false, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1723_ "")
+ (match (string_drop _stringappend_1723_ (string_length "")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1723_ (string_length "")) with
+ | s_ => Some (true, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition bit_maybe_r_forwards (arg_ : mword 1)
+: string :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then "r"
+ else "".
+
+Definition bit_maybe_r_backwards (arg_ : string)
+: M (mword 1) :=
+ (match arg_ with
+ | "r" => returnm ((vec_of_bits [B1] : mword 1) : mword 1)
+ | "" => returnm ((vec_of_bits [B0] : mword 1) : mword 1)
+ | _ => exit tt : M (mword 1)
+ end)
+ : M (mword 1).
+
+Definition bit_maybe_r_forwards_matches (arg_ : mword 1)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0] : mword 1))) then true
+ else false.
+
+Definition bit_maybe_r_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "r" => true | "" => true | _ => false end.
+
+Definition bit_maybe_r_matches_prefix (arg_ : string)
+: option ((mword 1 * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1721_ := arg_ in
+ if ((andb (string_startswith _stringappend_1721_ "r")
+ (match (string_drop _stringappend_1721_ (string_length "r")) with | s_ => true end))) then
+ match (string_drop _stringappend_1721_ (string_length "r")) with
+ | s_ => Some ((vec_of_bits [B1] : mword 1), sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1721_ "")
+ (match (string_drop _stringappend_1721_ (string_length "")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1721_ (string_length "")) with
+ | s_ => Some ((vec_of_bits [B0] : mword 1), sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition bit_maybe_w_forwards (arg_ : mword 1)
+: string :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then "w"
+ else "".
+
+Definition bit_maybe_w_backwards (arg_ : string)
+: M (mword 1) :=
+ (match arg_ with
+ | "w" => returnm ((vec_of_bits [B1] : mword 1) : mword 1)
+ | "" => returnm ((vec_of_bits [B0] : mword 1) : mword 1)
+ | _ => exit tt : M (mword 1)
+ end)
+ : M (mword 1).
+
+Definition bit_maybe_w_forwards_matches (arg_ : mword 1)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0] : mword 1))) then true
+ else false.
+
+Definition bit_maybe_w_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "w" => true | "" => true | _ => false end.
+
+Definition bit_maybe_w_matches_prefix (arg_ : string)
+: option ((mword 1 * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1719_ := arg_ in
+ if ((andb (string_startswith _stringappend_1719_ "w")
+ (match (string_drop _stringappend_1719_ (string_length "w")) with | s_ => true end))) then
+ match (string_drop _stringappend_1719_ (string_length "w")) with
+ | s_ => Some ((vec_of_bits [B1] : mword 1), sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1719_ "")
+ (match (string_drop _stringappend_1719_ (string_length "")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1719_ (string_length "")) with
+ | s_ => Some ((vec_of_bits [B0] : mword 1), sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition bit_maybe_i_forwards (arg_ : mword 1)
+: string :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then "i"
+ else "".
+
+Definition bit_maybe_i_backwards (arg_ : string)
+: M (mword 1) :=
+ (match arg_ with
+ | "i" => returnm ((vec_of_bits [B1] : mword 1) : mword 1)
+ | "" => returnm ((vec_of_bits [B0] : mword 1) : mword 1)
+ | _ => exit tt : M (mword 1)
+ end)
+ : M (mword 1).
+
+Definition bit_maybe_i_forwards_matches (arg_ : mword 1)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0] : mword 1))) then true
+ else false.
+
+Definition bit_maybe_i_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "i" => true | "" => true | _ => false end.
+
+Definition bit_maybe_i_matches_prefix (arg_ : string)
+: option ((mword 1 * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1717_ := arg_ in
+ if ((andb (string_startswith _stringappend_1717_ "i")
+ (match (string_drop _stringappend_1717_ (string_length "i")) with | s_ => true end))) then
+ match (string_drop _stringappend_1717_ (string_length "i")) with
+ | s_ => Some ((vec_of_bits [B1] : mword 1), sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1717_ "")
+ (match (string_drop _stringappend_1717_ (string_length "")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1717_ (string_length "")) with
+ | s_ => Some ((vec_of_bits [B0] : mword 1), sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition bit_maybe_o_forwards (arg_ : mword 1)
+: string :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then "o"
+ else "".
+
+Definition bit_maybe_o_backwards (arg_ : string)
+: M (mword 1) :=
+ (match arg_ with
+ | "o" => returnm ((vec_of_bits [B1] : mword 1) : mword 1)
+ | "" => returnm ((vec_of_bits [B0] : mword 1) : mword 1)
+ | _ => exit tt : M (mword 1)
+ end)
+ : M (mword 1).
+
+Definition bit_maybe_o_forwards_matches (arg_ : mword 1)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B1] : mword 1))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B0] : mword 1))) then true
+ else false.
+
+Definition bit_maybe_o_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "o" => true | "" => true | _ => false end.
+
+Definition bit_maybe_o_matches_prefix (arg_ : string)
+: option ((mword 1 * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1715_ := arg_ in
+ if ((andb (string_startswith _stringappend_1715_ "o")
+ (match (string_drop _stringappend_1715_ (string_length "o")) with | s_ => true end))) then
+ match (string_drop _stringappend_1715_ (string_length "o")) with
+ | s_ => Some ((vec_of_bits [B1] : mword 1), sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1715_ "")
+ (match (string_drop _stringappend_1715_ (string_length "")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1715_ (string_length "")) with
+ | s_ => Some ((vec_of_bits [B0] : mword 1), sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition fence_bits_forwards (arg_ : mword 4)
+: string :=
+ match arg_ with
+ | v__0 =>
+ let r : bits 1 := subrange_vec_dec v__0 3 3 in
+ let w : bits 1 := subrange_vec_dec v__0 2 2 in
+ let i : bits 1 := subrange_vec_dec v__0 1 1 in
+ let o : bits 1 := subrange_vec_dec v__0 0 0 in
+ string_append (bit_maybe_r_forwards r)
+ (string_append (bit_maybe_w_forwards w)
+ (string_append (bit_maybe_i_forwards i) (string_append (bit_maybe_o_forwards o) "")))
+ end.
+
+Definition fence_bits_backwards (arg_ : string)
+: M (mword 4) :=
+ let _stringappend_1703_ := arg_ in
+ match (bit_maybe_r_matches_prefix _stringappend_1703_) with
+ | Some (_stringappend_1704_,(existT _ _stringappend_1705_ _)) =>
+ returnm ((_stringappend_1704_, build_ex _stringappend_1705_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__1 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(r, existT _ _stringappend_1705_ _) := w__1 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1706_ := string_drop _stringappend_1703_ (build_ex _stringappend_1705_) in
+ match (bit_maybe_w_matches_prefix _stringappend_1706_) with
+ | Some (_stringappend_1707_,(existT _ _stringappend_1708_ _)) =>
+ returnm ((_stringappend_1707_, build_ex _stringappend_1708_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__3 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(w, existT _ _stringappend_1708_ _) := w__3 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1709_ := string_drop _stringappend_1706_ (build_ex _stringappend_1708_) in
+ match (bit_maybe_i_matches_prefix _stringappend_1709_) with
+ | Some (_stringappend_1710_,(existT _ _stringappend_1711_ _)) =>
+ returnm ((_stringappend_1710_, build_ex _stringappend_1711_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__5 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(i, existT _ _stringappend_1711_ _) := w__5 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1712_ := string_drop _stringappend_1709_ (build_ex _stringappend_1711_) in
+ match (bit_maybe_o_matches_prefix _stringappend_1712_) with
+ | Some (_stringappend_1713_,(existT _ _stringappend_1714_ _)) =>
+ returnm ((_stringappend_1713_, build_ex _stringappend_1714_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__7 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(o, existT _ _stringappend_1714_ _) := w__7 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1712_ (build_ex _stringappend_1714_)) with
+ | "" =>
+ returnm ((concat_vec (r : bits 1)
+ (concat_vec (w : bits 1) (concat_vec (i : bits 1) (o : bits 1))))
+ : mword 4)
+ | _ => exit tt : M (mword 4)
+ end)
+ : M (mword 4).
+
+Definition fence_bits_forwards_matches (arg_ : mword 4)
+: bool :=
+ match arg_ with | v__1 => true end.
+
+Definition fence_bits_backwards_matches (arg_ : string)
+: M (bool) :=
+ let _stringappend_1691_ := arg_ in
+ (if ((match (bit_maybe_r_matches_prefix _stringappend_1691_) with
+ | Some (_stringappend_1692_,(existT _ _stringappend_1693_ _)) =>
+ let _stringappend_1694_ :=
+ string_drop _stringappend_1691_ (build_ex _stringappend_1693_) in
+ if ((match (bit_maybe_w_matches_prefix _stringappend_1694_) with
+ | Some (_stringappend_1695_,(existT _ _stringappend_1696_ _)) =>
+ let _stringappend_1697_ :=
+ string_drop _stringappend_1694_ (build_ex _stringappend_1696_) in
+ if ((match (bit_maybe_i_matches_prefix _stringappend_1697_) with
+ | Some (_stringappend_1698_,(existT _ _stringappend_1699_ _)) =>
+ let _stringappend_1700_ :=
+ string_drop _stringappend_1697_ (build_ex _stringappend_1699_) in
+ if ((match (bit_maybe_o_matches_prefix _stringappend_1700_) with
+ | Some (_stringappend_1701_,(existT _ _stringappend_1702_ _)) =>
+ match (string_drop _stringappend_1700_
+ (build_ex
+ _stringappend_1702_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ match (bit_maybe_r_matches_prefix _stringappend_1691_) with
+ | Some (_stringappend_1692_,(existT _ _stringappend_1693_ _)) =>
+ returnm ((_stringappend_1692_, build_ex _stringappend_1693_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__1 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(r, existT _ _stringappend_1693_ _) := w__1 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1694_ := string_drop _stringappend_1691_ (build_ex _stringappend_1693_) in
+ match (bit_maybe_w_matches_prefix _stringappend_1694_) with
+ | Some (_stringappend_1695_,(existT _ _stringappend_1696_ _)) =>
+ returnm ((_stringappend_1695_, build_ex _stringappend_1696_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__3 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(w, existT _ _stringappend_1696_ _) := w__3 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1697_ := string_drop _stringappend_1694_ (build_ex _stringappend_1696_) in
+ match (bit_maybe_i_matches_prefix _stringappend_1697_) with
+ | Some (_stringappend_1698_,(existT _ _stringappend_1699_ _)) =>
+ returnm ((_stringappend_1698_, build_ex _stringappend_1699_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__5 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(i, existT _ _stringappend_1699_ _) := w__5 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1700_ := string_drop _stringappend_1697_ (build_ex _stringappend_1699_) in
+ match (bit_maybe_o_matches_prefix _stringappend_1700_) with
+ | Some (_stringappend_1701_,(existT _ _stringappend_1702_ _)) =>
+ returnm ((_stringappend_1701_, build_ex _stringappend_1702_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__7 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(o, existT _ _stringappend_1702_ _) := w__7 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1700_ (build_ex _stringappend_1702_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else returnm (false : bool))
+ : M (bool).
+
+Definition fence_bits_matches_prefix (arg_ : string)
+: M (option ((mword 4 * {n : Z & ArithFact (n >= 0)}))) :=
+ let _stringappend_1679_ := arg_ in
+ (if ((match (bit_maybe_r_matches_prefix _stringappend_1679_) with
+ | Some (_stringappend_1680_,(existT _ _stringappend_1681_ _)) =>
+ let _stringappend_1682_ :=
+ string_drop _stringappend_1679_ (build_ex _stringappend_1681_) in
+ if ((match (bit_maybe_w_matches_prefix _stringappend_1682_) with
+ | Some (_stringappend_1683_,(existT _ _stringappend_1684_ _)) =>
+ let _stringappend_1685_ :=
+ string_drop _stringappend_1682_ (build_ex _stringappend_1684_) in
+ if ((match (bit_maybe_i_matches_prefix _stringappend_1685_) with
+ | Some (_stringappend_1686_,(existT _ _stringappend_1687_ _)) =>
+ let _stringappend_1688_ :=
+ string_drop _stringappend_1685_ (build_ex _stringappend_1687_) in
+ if ((match (bit_maybe_o_matches_prefix _stringappend_1688_) with
+ | Some (_stringappend_1689_,(existT _ _stringappend_1690_ _)) =>
+ match (string_drop _stringappend_1688_
+ (build_ex
+ _stringappend_1690_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ match (bit_maybe_r_matches_prefix _stringappend_1679_) with
+ | Some (_stringappend_1680_,(existT _ _stringappend_1681_ _)) =>
+ returnm ((_stringappend_1680_, build_ex _stringappend_1681_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__1 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(r, existT _ _stringappend_1681_ _) := w__1 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1682_ := string_drop _stringappend_1679_ (build_ex _stringappend_1681_) in
+ match (bit_maybe_w_matches_prefix _stringappend_1682_) with
+ | Some (_stringappend_1683_,(existT _ _stringappend_1684_ _)) =>
+ returnm ((_stringappend_1683_, build_ex _stringappend_1684_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__3 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(w, existT _ _stringappend_1684_ _) := w__3 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1685_ := string_drop _stringappend_1682_ (build_ex _stringappend_1684_) in
+ match (bit_maybe_i_matches_prefix _stringappend_1685_) with
+ | Some (_stringappend_1686_,(existT _ _stringappend_1687_ _)) =>
+ returnm ((_stringappend_1686_, build_ex _stringappend_1687_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__5 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(i, existT _ _stringappend_1687_ _) := w__5 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1688_ := string_drop _stringappend_1685_ (build_ex _stringappend_1687_) in
+ match (bit_maybe_o_matches_prefix _stringappend_1688_) with
+ | Some (_stringappend_1689_,(existT _ _stringappend_1690_ _)) =>
+ returnm ((_stringappend_1689_, build_ex _stringappend_1690_)
+ : (mword 1 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 1 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__7 : (mword 1 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(o, existT _ _stringappend_1690_ _) := w__7 : (mword 1 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_1688_ (build_ex _stringappend_1690_)) with
+ | s_ =>
+ Some (concat_vec (r : bits 1)
+ (concat_vec (w : bits 1) (concat_vec (i : bits 1) (o : bits 1))),
+ sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((mword 4 * {n : Z & ArithFact (n >= 0)})))
+ else returnm (None : option ((mword 4 * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((mword 4 * {n : Z & ArithFact (n >= 0)}))).
+
+Definition aqrl_str (aq : bool) (rl : bool)
+: string :=
+ match (aq, rl) with
+ | (false, false) => ""
+ | (false, true) => ".rl"
+ | (true, false) => ".aq"
+ | (true, true) => ".aqrl"
+ end.
+
+Definition lrsc_width_str (width : word_width)
+: string :=
+ match width with | BYTE => ".b" | HALF => ".h" | WORD => ".w" | DOUBLE => ".d" end.
+
+Definition process_loadres {n : Z} (rd : mword 5) (addr : mword 64) (value : MemoryOpResult (mword (8 * n))) (is_unsigned : bool) `{ArithFact (1 <=
+ n /\
+ n <= 8)}
+: M (bool) :=
+ (match (extend_value is_unsigned value) with
+ | MemValue (result) =>
+ let '_ := (load_reservation addr) : unit in
+ wX
+ (projT1 ((regbits_to_regno rd)
+ : {syn_n : Z & ArithFact (0 <= syn_n /\ (syn_n + 1) <= 32)})) result >>
+ returnm (true
+ : bool)
+ | MemException (e) => handle_mem_exception addr e >> returnm (false : bool)
+ end)
+ : M (bool).
+
+Definition encdec_amoop_forwards (arg_ : amoop)
+: mword 5 :=
+ match arg_ with
+ | AMOSWAP => (vec_of_bits [B0;B0;B0;B0;B1] : mword 5)
+ | AMOADD => (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ | AMOXOR => (vec_of_bits [B0;B0;B1;B0;B0] : mword 5)
+ | AMOAND => (vec_of_bits [B0;B1;B1;B0;B0] : mword 5)
+ | AMOOR => (vec_of_bits [B0;B1;B0;B0;B0] : mword 5)
+ | AMOMIN => (vec_of_bits [B1;B0;B0;B0;B0] : mword 5)
+ | AMOMAX => (vec_of_bits [B1;B0;B1;B0;B0] : mword 5)
+ | AMOMINU => (vec_of_bits [B1;B1;B0;B0;B0] : mword 5)
+ | AMOMAXU => (vec_of_bits [B1;B1;B1;B0;B0] : mword 5)
+ end.
+
+Definition encdec_amoop_backwards (arg_ : mword 5)
+: amoop :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ AMOSWAP
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ AMOADD
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ AMOXOR
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ AMOAND
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ AMOOR
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ AMOMIN
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ AMOMAX
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ AMOMINU
+ else AMOMAXU.
+
+Definition encdec_amoop_forwards_matches (arg_ : amoop)
+: bool :=
+ match arg_ with
+ | AMOSWAP => true
+ | AMOADD => true
+ | AMOXOR => true
+ | AMOAND => true
+ | AMOOR => true
+ | AMOMIN => true
+ | AMOMAX => true
+ | AMOMINU => true
+ | AMOMAXU => true
+ end.
+
+Definition encdec_amoop_backwards_matches (arg_ : mword 5)
+: bool :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B0;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno p0_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B1;B1;B1;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ true
+ else false.
+
+Definition amo_mnemonic_forwards (arg_ : amoop)
+: string :=
+ match arg_ with
+ | AMOSWAP => "amoswap"
+ | AMOADD => "amoadd"
+ | AMOXOR => "amoxor"
+ | AMOAND => "amoand"
+ | AMOOR => "amoor"
+ | AMOMIN => "amomin"
+ | AMOMAX => "amomax"
+ | AMOMINU => "amominu"
+ | AMOMAXU => "amomaxu"
+ end.
+
+Definition amo_mnemonic_backwards (arg_ : string)
+: M (amoop) :=
+ (match arg_ with
+ | "amoswap" => returnm (AMOSWAP : amoop)
+ | "amoadd" => returnm (AMOADD : amoop)
+ | "amoxor" => returnm (AMOXOR : amoop)
+ | "amoand" => returnm (AMOAND : amoop)
+ | "amoor" => returnm (AMOOR : amoop)
+ | "amomin" => returnm (AMOMIN : amoop)
+ | "amomax" => returnm (AMOMAX : amoop)
+ | "amominu" => returnm (AMOMINU : amoop)
+ | "amomaxu" => returnm (AMOMAXU : amoop)
+ | _ => exit tt : M (amoop)
+ end)
+ : M (amoop).
+
+Definition amo_mnemonic_forwards_matches (arg_ : amoop)
+: bool :=
+ match arg_ with
+ | AMOSWAP => true
+ | AMOADD => true
+ | AMOXOR => true
+ | AMOAND => true
+ | AMOOR => true
+ | AMOMIN => true
+ | AMOMAX => true
+ | AMOMINU => true
+ | AMOMAXU => true
+ end.
+
+Definition amo_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with
+ | "amoswap" => true
+ | "amoadd" => true
+ | "amoxor" => true
+ | "amoand" => true
+ | "amoor" => true
+ | "amomin" => true
+ | "amomax" => true
+ | "amominu" => true
+ | "amomaxu" => true
+ | _ => false
+ end.
+
+Definition amo_mnemonic_matches_prefix (arg_ : string)
+: option ((amoop * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1670_ := arg_ in
+ if ((andb (string_startswith _stringappend_1670_ "amoswap")
+ (match (string_drop _stringappend_1670_ (string_length "amoswap")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1670_ (string_length "amoswap")) with
+ | s_ => Some (AMOSWAP, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1670_ "amoadd")
+ (match (string_drop _stringappend_1670_ (string_length "amoadd")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1670_ (string_length "amoadd")) with
+ | s_ => Some (AMOADD, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1670_ "amoxor")
+ (match (string_drop _stringappend_1670_ (string_length "amoxor")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1670_ (string_length "amoxor")) with
+ | s_ => Some (AMOXOR, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1670_ "amoand")
+ (match (string_drop _stringappend_1670_ (string_length "amoand")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1670_ (string_length "amoand")) with
+ | s_ => Some (AMOAND, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1670_ "amoor")
+ (match (string_drop _stringappend_1670_ (string_length "amoor")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1670_ (string_length "amoor")) with
+ | s_ => Some (AMOOR, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1670_ "amomin")
+ (match (string_drop _stringappend_1670_ (string_length "amomin")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1670_ (string_length "amomin")) with
+ | s_ => Some (AMOMIN, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1670_ "amomax")
+ (match (string_drop _stringappend_1670_ (string_length "amomax")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1670_ (string_length "amomax")) with
+ | s_ => Some (AMOMAX, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1670_ "amominu")
+ (match (string_drop _stringappend_1670_ (string_length "amominu")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1670_ (string_length "amominu")) with
+ | s_ => Some (AMOMINU, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1670_ "amomaxu")
+ (match (string_drop _stringappend_1670_ (string_length "amomaxu")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1670_ (string_length "amomaxu")) with
+ | s_ => Some (AMOMAXU, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition encdec_csrop_forwards (arg_ : csrop)
+: mword 2 :=
+ match arg_ with
+ | CSRRW => (vec_of_bits [B0;B1] : mword 2)
+ | CSRRS => (vec_of_bits [B1;B0] : mword 2)
+ | CSRRC => (vec_of_bits [B1;B1] : mword 2)
+ end.
+
+Definition encdec_csrop_backwards (arg_ : mword 2)
+: csrop :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B1] : mword 2))) then CSRRW
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0] : mword 2))) then CSRRS
+ else CSRRC.
+
+Definition encdec_csrop_forwards_matches (arg_ : csrop)
+: bool :=
+ match arg_ with | CSRRW => true | CSRRS => true | CSRRC => true end.
+
+Definition encdec_csrop_backwards_matches (arg_ : mword 2)
+: bool :=
+ let p0_ := arg_ in
+ if ((eq_vec p0_ (vec_of_bits [B0;B1] : mword 2))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B0] : mword 2))) then true
+ else if ((eq_vec p0_ (vec_of_bits [B1;B1] : mword 2))) then true
+ else false.
+
+Definition readCSR (csr : mword 12)
+: M (mword 64) :=
+ let b__0 := csr in
+ (if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B0;B1] : mword 12))) then
+ (read_reg mvendorid_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B0] : mword 12))) then
+ (read_reg marchid_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B0;B1;B1] : mword 12))) then
+ (read_reg mimpid_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B1;B1;B0;B0;B0;B1;B0;B1;B0;B0] : mword 12))) then
+ (read_reg mhartid_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ read_reg mstatus_ref >>= fun w__4 : Mstatus => returnm ((_get_Mstatus_bits w__4) : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ read_reg misa_ref >>= fun w__5 : Misa => returnm ((_get_Misa_bits w__5) : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ read_reg medeleg_ref >>= fun w__6 : Medeleg => returnm ((_get_Medeleg_bits w__6) : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ read_reg mideleg_ref >>= fun w__7 : Minterrupts =>
+ returnm ((_get_Minterrupts_bits w__7)
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ read_reg mie_ref >>= fun w__8 : Minterrupts =>
+ returnm ((_get_Minterrupts_bits w__8)
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ read_reg mtvec_ref >>= fun w__9 : Mtvec => returnm ((_get_Mtvec_bits w__9) : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ read_reg mcounteren_ref >>= fun w__10 : Counteren =>
+ returnm ((EXTZ 64 (_get_Counteren_bits w__10))
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ (read_reg mscratch_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ (read_reg mepc_ref : M (mword 64)) >>= fun w__12 : mword 64 =>
+ pc_alignment_mask tt >>= fun w__13 : mword 64 => returnm ((and_vec w__12 w__13) : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ read_reg mcause_ref >>= fun w__14 : Mcause => returnm ((_get_Mcause_bits w__14) : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ (read_reg mtval_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ read_reg mip_ref >>= fun w__16 : Minterrupts =>
+ returnm ((_get_Minterrupts_bits w__16)
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ (read_reg pmpcfg0_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B0] : mword 12))) then
+ (read_reg pmpaddr0_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ read_reg mstatus_ref >>= fun w__19 : Mstatus =>
+ returnm ((_get_Sstatus_bits (lower_mstatus w__19))
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ read_reg sedeleg_ref >>= fun w__20 : Sedeleg =>
+ returnm ((_get_Sedeleg_bits w__20)
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ read_reg sideleg_ref >>= fun w__21 : Sinterrupts =>
+ returnm ((_get_Sinterrupts_bits w__21)
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ read_reg mie_ref >>= fun w__22 : Minterrupts =>
+ read_reg mideleg_ref >>= fun w__23 : Minterrupts =>
+ returnm ((_get_Sinterrupts_bits (lower_mie w__22 w__23))
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ read_reg stvec_ref >>= fun w__24 : Mtvec => returnm ((_get_Mtvec_bits w__24) : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ read_reg scounteren_ref >>= fun w__25 : Counteren =>
+ returnm ((EXTZ 64 (_get_Counteren_bits w__25))
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ (read_reg sscratch_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ (read_reg sepc_ref : M (mword 64)) >>= fun w__27 : mword 64 =>
+ pc_alignment_mask tt >>= fun w__28 : mword 64 => returnm ((and_vec w__27 w__28) : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ read_reg scause_ref >>= fun w__29 : Mcause => returnm ((_get_Mcause_bits w__29) : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ (read_reg stval_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ read_reg mip_ref >>= fun w__31 : Minterrupts =>
+ read_reg mideleg_ref >>= fun w__32 : Minterrupts =>
+ returnm ((_get_Sinterrupts_bits (lower_mip w__31 w__32))
+ : xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ (read_reg satp_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ (read_reg mcycle_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ (read_reg mtime_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ (read_reg minstret_ref : M (mword 64))
+ : M (xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ (read_reg tselect_ref : M (mword 64)) >>= fun w__37 : mword 64 =>
+ returnm ((not_vec w__37)
+ : xlenbits)
+ else
+ let '_ := (print_bits "unhandled read to CSR " csr) : unit in
+ returnm ((vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64)
+ : mword 64)) >>= fun res : xlenbits =>
+ let '_ :=
+ (print_endline
+ (String.append "CSR "
+ (String.append ((csr_name csr) : string) (String.append " -> " (string_of_bits res)))))
+ : unit in
+ returnm (res
+ : mword 64).
+
+Definition writeCSR (csr : mword 12) (value : mword 64)
+: M (unit) :=
+ let b__0 := csr in
+ (if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ read_reg mstatus_ref >>= fun w__0 : Mstatus =>
+ write_reg mstatus_ref (legalize_mstatus w__0 value) >>
+ read_reg mstatus_ref >>= fun w__1 : Mstatus =>
+ returnm ((Some (_get_Mstatus_bits w__1))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ read_reg misa_ref >>= fun w__2 : Misa =>
+ legalize_misa w__2 value >>= fun w__3 : Misa =>
+ write_reg misa_ref w__3 >>
+ read_reg misa_ref >>= fun w__4 : Misa =>
+ returnm ((Some (_get_Misa_bits w__4))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ read_reg medeleg_ref >>= fun w__5 : Medeleg =>
+ write_reg medeleg_ref (legalize_medeleg w__5 value) >>
+ read_reg medeleg_ref >>= fun w__6 : Medeleg =>
+ returnm ((Some (_get_Medeleg_bits w__6))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ read_reg mideleg_ref >>= fun w__7 : Minterrupts =>
+ write_reg mideleg_ref (legalize_mideleg w__7 value) >>
+ read_reg mideleg_ref >>= fun w__8 : Minterrupts =>
+ returnm ((Some (_get_Minterrupts_bits w__8))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ read_reg mie_ref >>= fun w__9 : Minterrupts =>
+ write_reg mie_ref (legalize_mie w__9 value) >>
+ read_reg mie_ref >>= fun w__10 : Minterrupts =>
+ returnm ((Some (_get_Minterrupts_bits w__10))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ read_reg mtvec_ref >>= fun w__11 : Mtvec =>
+ write_reg mtvec_ref (legalize_tvec w__11 value) >>
+ read_reg mtvec_ref >>= fun w__12 : Mtvec =>
+ returnm ((Some (_get_Mtvec_bits w__12))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ read_reg mcounteren_ref >>= fun w__13 : Counteren =>
+ legalize_mcounteren w__13 value >>= fun w__14 : Counteren =>
+ write_reg mcounteren_ref w__14 >>
+ read_reg mcounteren_ref >>= fun w__15 : Counteren =>
+ returnm ((Some (EXTZ 64 (_get_Counteren_bits w__15)))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ write_reg mscratch_ref value >>
+ (read_reg mscratch_ref : M (mword 64)) >>= fun w__16 : mword 64 =>
+ returnm ((Some w__16)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ legalize_xepc value >>= fun w__17 : xlenbits =>
+ write_reg mepc_ref w__17 >>
+ (read_reg mepc_ref : M (mword 64)) >>= fun w__18 : mword 64 =>
+ returnm ((Some w__18)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ _set_Mcause_bits mcause_ref value >>
+ read_reg mcause_ref >>= fun w__19 : Mcause =>
+ returnm ((Some (_get_Mcause_bits w__19))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ write_reg mtval_ref value >>
+ (read_reg mtval_ref : M (mword 64)) >>= fun w__20 : mword 64 =>
+ returnm ((Some w__20)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ read_reg mip_ref >>= fun w__21 : Minterrupts =>
+ write_reg mip_ref (legalize_mip w__21 value) >>
+ read_reg mip_ref >>= fun w__22 : Minterrupts =>
+ returnm ((Some (_get_Minterrupts_bits w__22))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ write_reg pmpcfg0_ref value >>
+ (read_reg pmpcfg0_ref : M (mword 64)) >>= fun w__23 : mword 64 =>
+ returnm ((Some w__23)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B1;B1;B1;B0;B1;B1;B0;B0;B0;B0] : mword 12))) then
+ write_reg pmpaddr0_ref value >>
+ (read_reg pmpaddr0_ref : M (mword 64)) >>= fun w__24 : mword 64 =>
+ returnm ((Some w__24)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ read_reg mstatus_ref >>= fun w__25 : Mstatus =>
+ write_reg mstatus_ref (legalize_sstatus w__25 value) >>
+ read_reg mstatus_ref >>= fun w__26 : Mstatus =>
+ returnm ((Some (_get_Mstatus_bits w__26))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ read_reg sedeleg_ref >>= fun w__27 : Sedeleg =>
+ write_reg sedeleg_ref (legalize_sedeleg w__27 value) >>
+ read_reg sedeleg_ref >>= fun w__28 : Sedeleg =>
+ returnm ((Some (_get_Sedeleg_bits w__28))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ _set_Sinterrupts_bits sideleg_ref value >>
+ read_reg sideleg_ref >>= fun w__29 : Sinterrupts =>
+ returnm ((Some (_get_Sinterrupts_bits w__29))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ read_reg mie_ref >>= fun w__30 : Minterrupts =>
+ read_reg mideleg_ref >>= fun w__31 : Minterrupts =>
+ write_reg mie_ref (legalize_sie w__30 w__31 value) >>
+ read_reg mie_ref >>= fun w__32 : Minterrupts =>
+ returnm ((Some (_get_Minterrupts_bits w__32))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12))) then
+ read_reg stvec_ref >>= fun w__33 : Mtvec =>
+ write_reg stvec_ref (legalize_tvec w__33 value) >>
+ read_reg stvec_ref >>= fun w__34 : Mtvec =>
+ returnm ((Some (_get_Mtvec_bits w__34))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B1;B0] : mword 12))) then
+ read_reg scounteren_ref >>= fun w__35 : Counteren =>
+ legalize_scounteren w__35 value >>= fun w__36 : Counteren =>
+ write_reg scounteren_ref w__36 >>
+ read_reg scounteren_ref >>= fun w__37 : Counteren =>
+ returnm ((Some (EXTZ 64 (_get_Counteren_bits w__37)))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ write_reg sscratch_ref value >>
+ (read_reg sscratch_ref : M (mword 64)) >>= fun w__38 : mword 64 =>
+ returnm ((Some w__38)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B0;B1] : mword 12))) then
+ legalize_xepc value >>= fun w__39 : xlenbits =>
+ write_reg sepc_ref w__39 >>
+ (read_reg sepc_ref : M (mword 64)) >>= fun w__40 : mword 64 =>
+ returnm ((Some w__40)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ _set_Mcause_bits scause_ref value >>
+ read_reg scause_ref >>= fun w__41 : Mcause =>
+ returnm ((Some (_get_Mcause_bits w__41))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B0;B1;B1] : mword 12))) then
+ write_reg stval_ref value >>
+ (read_reg stval_ref : M (mword 64)) >>= fun w__42 : mword 64 =>
+ returnm ((Some w__42)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B0;B1;B0;B0;B0;B1;B0;B0] : mword 12))) then
+ read_reg mip_ref >>= fun w__43 : Minterrupts =>
+ read_reg mideleg_ref >>= fun w__44 : Minterrupts =>
+ write_reg mip_ref (legalize_sip w__43 w__44 value) >>
+ read_reg mip_ref >>= fun w__45 : Minterrupts =>
+ returnm ((Some (_get_Minterrupts_bits w__45))
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B0;B0;B1;B1;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ cur_Architecture tt >>= fun w__46 : Architecture =>
+ (read_reg satp_ref : M (mword 64)) >>= fun w__47 : mword 64 =>
+ write_reg satp_ref (legalize_satp w__46 w__47 value) >>
+ (read_reg satp_ref : M (mword 64)) >>= fun w__48 : mword 64 =>
+ returnm ((Some w__48)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B0;B1;B1;B1;B1;B0;B1;B0;B0;B0;B0;B0] : mword 12))) then
+ write_reg tselect_ref value >>
+ (read_reg tselect_ref : M (mword 64)) >>= fun w__49 : mword 64 =>
+ returnm ((Some w__49)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12))) then
+ write_reg mcycle_ref value >>
+ (read_reg mcycle_ref : M (mword 64)) >>= fun w__50 : mword 64 =>
+ returnm ((Some w__50)
+ : option xlenbits)
+ else if ((eq_vec b__0 (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B0;B0;B1;B0] : mword 12))) then
+ write_reg minstret_ref value >>
+ write_reg minstret_written_ref true >>
+ (read_reg minstret_ref : M (mword 64)) >>= fun w__51 : mword 64 =>
+ returnm ((Some w__51)
+ : option xlenbits)
+ else returnm (None : option xlenbits)) >>= fun res : option xlenbits =>
+ returnm ((match res with
+ | Some (v) =>
+ print_endline
+ (String.append "CSR "
+ (String.append ((csr_name csr) : string)
+ (String.append " <- "
+ (String.append (string_of_bits v)
+ (String.append " (input: " (String.append (string_of_bits value) ")"))))))
+ | None => print_bits "unhandled write to CSR " csr
+ end)
+ : unit).
+
+Definition maybe_i_forwards (arg_ : bool)
+: string :=
+ match arg_ with | true => "i" | false => "" end.
+
+Definition maybe_i_backwards (arg_ : string)
+: M (bool) :=
+ (match arg_ with
+ | "i" => returnm (true : bool)
+ | "" => returnm (false : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool).
+
+Definition maybe_i_forwards_matches (arg_ : bool)
+: bool :=
+ match arg_ with | true => true | false => true end.
+
+Definition maybe_i_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "i" => true | "" => true | _ => false end.
+
+Definition maybe_i_matches_prefix (arg_ : string)
+: option ((bool * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1668_ := arg_ in
+ if ((andb (string_startswith _stringappend_1668_ "i")
+ (match (string_drop _stringappend_1668_ (string_length "i")) with | s_ => true end))) then
+ match (string_drop _stringappend_1668_ (string_length "i")) with
+ | s_ => Some (true, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1668_ "")
+ (match (string_drop _stringappend_1668_ (string_length "")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1668_ (string_length "")) with
+ | s_ => Some (false, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition csr_mnemonic_forwards (arg_ : csrop)
+: string :=
+ match arg_ with | CSRRW => "csrrw" | CSRRS => "csrrs" | CSRRC => "csrrc" end.
+
+Definition csr_mnemonic_backwards (arg_ : string)
+: M (csrop) :=
+ (match arg_ with
+ | "csrrw" => returnm (CSRRW : csrop)
+ | "csrrs" => returnm (CSRRS : csrop)
+ | "csrrc" => returnm (CSRRC : csrop)
+ | _ => exit tt : M (csrop)
+ end)
+ : M (csrop).
+
+Definition csr_mnemonic_forwards_matches (arg_ : csrop)
+: bool :=
+ match arg_ with | CSRRW => true | CSRRS => true | CSRRC => true end.
+
+Definition csr_mnemonic_backwards_matches (arg_ : string)
+: bool :=
+ match arg_ with | "csrrw" => true | "csrrs" => true | "csrrc" => true | _ => false end.
+
+Definition csr_mnemonic_matches_prefix (arg_ : string)
+: option ((csrop * {n : Z & ArithFact (n >= 0)})) :=
+ let _stringappend_1665_ := arg_ in
+ if ((andb (string_startswith _stringappend_1665_ "csrrw")
+ (match (string_drop _stringappend_1665_ (string_length "csrrw")) with | s_ => true end)))
+ then
+ match (string_drop _stringappend_1665_ (string_length "csrrw")) with
+ | s_ => Some (CSRRW, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1665_ "csrrs")
+ (match (string_drop _stringappend_1665_ (string_length "csrrs")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1665_ (string_length "csrrs")) with
+ | s_ => Some (CSRRS, sub_nat (string_length arg_) (string_length s_))
+ end
+ else if ((andb (string_startswith _stringappend_1665_ "csrrc")
+ (match (string_drop _stringappend_1665_ (string_length "csrrc")) with
+ | s_ => true
+ end))) then
+ match (string_drop _stringappend_1665_ (string_length "csrrc")) with
+ | s_ => Some (CSRRC, sub_nat (string_length arg_) (string_length s_))
+ end
+ else None.
+
+Definition decodeCompressed (v__2 : mword 16)
+: option ast :=
+ if sumbool_of_bool ((andb
+ (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B0;B0] : mword 3))
+ (andb
+ (Z.eqb
+ (projT1 ((regbits_to_regno (subrange_vec_dec v__2 11 7))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2)))))
+ then
+ let nzi1 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let nzi0 : bits 5 := subrange_vec_dec v__2 6 2 in
+ if sumbool_of_bool ((andb (eq_vec nzi1 (vec_of_bits [B0] : mword 1))
+ (Z.eqb
+ (projT1 ((regbits_to_regno nzi0)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ Some (NOP tt)
+ else None
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B0;B0] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B0] : mword 2)))) then
+ let nz54 : bits 2 := subrange_vec_dec v__2 12 11 in
+ let nz96 : bits 4 := subrange_vec_dec v__2 10 7 in
+ let nz2 : bits 1 := subrange_vec_dec v__2 6 6 in
+ let nz3 : bits 1 := subrange_vec_dec v__2 5 5 in
+ let rd : cregbits := subrange_vec_dec v__2 4 2 in
+ let nzimm := (concat_vec nz96 (concat_vec nz54 (concat_vec nz3 nz2))) : bits 8 in
+ if ((eq_vec nzimm (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0] : mword 8))) then None
+ else Some (C_ADDI4SPN (rd,nzimm))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B1;B0] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B0] : mword 2)))) then
+ let ui53 : bits 3 := subrange_vec_dec v__2 12 10 in
+ let rs1 : cregbits := subrange_vec_dec v__2 9 7 in
+ let ui2 : bits 1 := subrange_vec_dec v__2 6 6 in
+ let ui6 : bits 1 := subrange_vec_dec v__2 5 5 in
+ let rd : cregbits := subrange_vec_dec v__2 4 2 in
+ let uimm := (concat_vec ui6 (concat_vec ui53 ui2)) : bits 5 in
+ Some (C_LW (uimm,rs1,rd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B1;B1] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B0] : mword 2)))) then
+ let ui53 : bits 3 := subrange_vec_dec v__2 12 10 in
+ let rs1 : cregbits := subrange_vec_dec v__2 9 7 in
+ let ui76 : bits 2 := subrange_vec_dec v__2 6 5 in
+ let rd : cregbits := subrange_vec_dec v__2 4 2 in
+ let uimm := (concat_vec ui76 ui53) : bits 5 in
+ Some (C_LD (uimm,rs1,rd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B1;B0] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B0] : mword 2)))) then
+ let ui53 : bits 3 := subrange_vec_dec v__2 12 10 in
+ let rs1 : cregbits := subrange_vec_dec v__2 9 7 in
+ let ui2 : bits 1 := subrange_vec_dec v__2 6 6 in
+ let ui6 : bits 1 := subrange_vec_dec v__2 5 5 in
+ let rs2 : cregbits := subrange_vec_dec v__2 4 2 in
+ let uimm := (concat_vec ui6 (concat_vec ui53 ui2)) : bits 5 in
+ Some (C_SW (uimm,rs1,rs2))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B1;B1] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B0] : mword 2)))) then
+ let ui53 : bits 3 := subrange_vec_dec v__2 12 10 in
+ let rs1 : bits 3 := subrange_vec_dec v__2 9 7 in
+ let ui76 : bits 2 := subrange_vec_dec v__2 6 5 in
+ let rs2 : bits 3 := subrange_vec_dec v__2 4 2 in
+ let uimm := (concat_vec ui76 ui53) : bits 5 in
+ Some (C_SD (uimm,rs1,rs2))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B0;B0] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ let nzi5 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rsd : regbits := subrange_vec_dec v__2 11 7 in
+ let nzi40 : bits 5 := subrange_vec_dec v__2 6 2 in
+ let nzi := (concat_vec nzi5 nzi40) : bits 6 in
+ if sumbool_of_bool ((orb (eq_vec nzi (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6))
+ (Z.eqb
+ (projT1 ((regbits_to_regno rsd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ None
+ else Some (C_ADDI (nzi,rsd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B0;B1] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ let imm5 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rsd : regbits := subrange_vec_dec v__2 11 7 in
+ let imm40 : bits 5 := subrange_vec_dec v__2 6 2 in
+ Some (C_ADDIW (concat_vec imm5 imm40,rsd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B1;B0] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ let imm5 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rd : regbits := subrange_vec_dec v__2 11 7 in
+ let imm40 : bits 5 := subrange_vec_dec v__2 6 2 in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ None
+ else Some (C_LI (concat_vec imm5 imm40,rd))
+ else if sumbool_of_bool ((andb
+ (eq_vec (subrange_vec_dec v__2 15 13)
+ (vec_of_bits [B0;B1;B1] : mword 3))
+ (andb
+ (Z.eqb
+ (projT1 ((regbits_to_regno (subrange_vec_dec v__2 11 7))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno
+ (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))
+ (eq_vec (subrange_vec_dec v__2 1 0)
+ (vec_of_bits [B0;B1] : mword 2))))) then
+ let nzi9 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let nzi4 : bits 1 := subrange_vec_dec v__2 6 6 in
+ let nzi6 : bits 1 := subrange_vec_dec v__2 5 5 in
+ let nzi87 : bits 2 := subrange_vec_dec v__2 4 3 in
+ let nzi5 : bits 1 := subrange_vec_dec v__2 2 2 in
+ let nzimm := concat_vec nzi9 (concat_vec nzi87 (concat_vec nzi6 (concat_vec nzi5 nzi4))) in
+ if ((eq_vec nzimm (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6))) then None
+ else Some (C_ADDI16SP nzimm)
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B1;B1] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ let imm17 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rd : regbits := subrange_vec_dec v__2 11 7 in
+ let imm1612 : bits 5 := subrange_vec_dec v__2 6 2 in
+ if sumbool_of_bool ((orb
+ (Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))
+ (Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno sp)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ None
+ else Some (C_LUI (concat_vec imm17 imm1612,rd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B0;B0] : mword 3))
+ (andb (eq_vec (subrange_vec_dec v__2 11 10) (vec_of_bits [B0;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2))))) then
+ let nzui5 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rsd : cregbits := subrange_vec_dec v__2 9 7 in
+ let nzui40 : bits 5 := subrange_vec_dec v__2 6 2 in
+ let shamt : bits 6 := concat_vec nzui5 nzui40 in
+ if ((eq_vec shamt (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6))) then None
+ else Some (C_SRLI (shamt,rsd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B0;B0] : mword 3))
+ (andb (eq_vec (subrange_vec_dec v__2 11 10) (vec_of_bits [B0;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2))))) then
+ let nzui5 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rsd : cregbits := subrange_vec_dec v__2 9 7 in
+ let nzui40 : bits 5 := subrange_vec_dec v__2 6 2 in
+ let shamt : bits 6 := concat_vec nzui5 nzui40 in
+ if ((eq_vec shamt (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6))) then None
+ else Some (C_SRAI (shamt,rsd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B0;B0] : mword 3))
+ (andb (eq_vec (subrange_vec_dec v__2 11 10) (vec_of_bits [B1;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2))))) then
+ let i5 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rsd : cregbits := subrange_vec_dec v__2 9 7 in
+ let i40 : bits 5 := subrange_vec_dec v__2 6 2 in
+ Some (C_ANDI (concat_vec i5 i40,rsd))
+ else if ((andb
+ (eq_vec (subrange_vec_dec v__2 15 10) (vec_of_bits [B1;B0;B0;B0;B1;B1] : mword 6))
+ (andb (eq_vec (subrange_vec_dec v__2 6 5) (vec_of_bits [B0;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2))))) then
+ let rsd : cregbits := subrange_vec_dec v__2 9 7 in
+ let rs2 : cregbits := subrange_vec_dec v__2 4 2 in
+ Some (C_SUB (rsd,rs2))
+ else if ((andb
+ (eq_vec (subrange_vec_dec v__2 15 10) (vec_of_bits [B1;B0;B0;B0;B1;B1] : mword 6))
+ (andb (eq_vec (subrange_vec_dec v__2 6 5) (vec_of_bits [B0;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2))))) then
+ let rsd : cregbits := subrange_vec_dec v__2 9 7 in
+ let rs2 : cregbits := subrange_vec_dec v__2 4 2 in
+ Some (C_XOR (rsd,rs2))
+ else if ((andb
+ (eq_vec (subrange_vec_dec v__2 15 10) (vec_of_bits [B1;B0;B0;B0;B1;B1] : mword 6))
+ (andb (eq_vec (subrange_vec_dec v__2 6 5) (vec_of_bits [B1;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2))))) then
+ let rsd : cregbits := subrange_vec_dec v__2 9 7 in
+ let rs2 : cregbits := subrange_vec_dec v__2 4 2 in
+ Some (C_OR (rsd,rs2))
+ else if ((andb
+ (eq_vec (subrange_vec_dec v__2 15 10) (vec_of_bits [B1;B0;B0;B0;B1;B1] : mword 6))
+ (andb (eq_vec (subrange_vec_dec v__2 6 5) (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2))))) then
+ let rsd : cregbits := subrange_vec_dec v__2 9 7 in
+ let rs2 : cregbits := subrange_vec_dec v__2 4 2 in
+ Some (C_AND (rsd,rs2))
+ else if ((andb
+ (eq_vec (subrange_vec_dec v__2 15 10) (vec_of_bits [B1;B0;B0;B1;B1;B1] : mword 6))
+ (andb (eq_vec (subrange_vec_dec v__2 6 5) (vec_of_bits [B0;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2))))) then
+ let rsd : cregbits := subrange_vec_dec v__2 9 7 in
+ let rs2 : cregbits := subrange_vec_dec v__2 4 2 in
+ Some (C_SUBW (rsd,rs2))
+ else if ((andb
+ (eq_vec (subrange_vec_dec v__2 15 10) (vec_of_bits [B1;B0;B0;B1;B1;B1] : mword 6))
+ (andb (eq_vec (subrange_vec_dec v__2 6 5) (vec_of_bits [B0;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2))))) then
+ let rsd : cregbits := subrange_vec_dec v__2 9 7 in
+ let rs2 : cregbits := subrange_vec_dec v__2 4 2 in
+ Some (C_ADDW (rsd,rs2))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B0;B1] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ let i11 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let i4 : bits 1 := subrange_vec_dec v__2 11 11 in
+ let i98 : bits 2 := subrange_vec_dec v__2 10 9 in
+ let i10 : bits 1 := subrange_vec_dec v__2 8 8 in
+ let i6 : bits 1 := subrange_vec_dec v__2 7 7 in
+ let i7 : bits 1 := subrange_vec_dec v__2 6 6 in
+ let i31 : bits 3 := subrange_vec_dec v__2 5 3 in
+ let i5 : bits 1 := subrange_vec_dec v__2 2 2 in
+ Some (C_J (concat_vec i11
+ (concat_vec i10
+ (concat_vec i98
+ (concat_vec i7 (concat_vec i6 (concat_vec i5 (concat_vec i4 i31))))))))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B1;B0] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ let i8 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let i43 : bits 2 := subrange_vec_dec v__2 11 10 in
+ let rs : cregbits := subrange_vec_dec v__2 9 7 in
+ let i76 : bits 2 := subrange_vec_dec v__2 6 5 in
+ let i21 : bits 2 := subrange_vec_dec v__2 4 3 in
+ let i5 : bits 1 := subrange_vec_dec v__2 2 2 in
+ Some (C_BEQZ (concat_vec i8 (concat_vec i76 (concat_vec i5 (concat_vec i43 i21))),rs))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B1;B1] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ let i8 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let i43 : bits 2 := subrange_vec_dec v__2 11 10 in
+ let rs : cregbits := subrange_vec_dec v__2 9 7 in
+ let i76 : bits 2 := subrange_vec_dec v__2 6 5 in
+ let i21 : bits 2 := subrange_vec_dec v__2 4 3 in
+ let i5 : bits 1 := subrange_vec_dec v__2 2 2 in
+ Some (C_BNEZ (concat_vec i8 (concat_vec i76 (concat_vec i5 (concat_vec i43 i21))),rs))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B0;B0] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ let nzui5 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rsd : regbits := subrange_vec_dec v__2 11 7 in
+ let nzui40 : bits 5 := subrange_vec_dec v__2 6 2 in
+ let shamt : bits 6 := concat_vec nzui5 nzui40 in
+ if sumbool_of_bool ((orb (eq_vec shamt (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6))
+ (Z.eqb
+ (projT1 ((regbits_to_regno rsd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ None
+ else Some (C_SLLI (shamt,rsd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B1;B0] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ let ui5 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rd : regbits := subrange_vec_dec v__2 11 7 in
+ let ui42 : bits 3 := subrange_vec_dec v__2 6 4 in
+ let ui76 : bits 2 := subrange_vec_dec v__2 3 2 in
+ let uimm : bits 6 := concat_vec ui76 (concat_vec ui5 ui42) in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ None
+ else Some (C_LWSP (uimm,rd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B0;B1;B1] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ let ui5 : bits 1 := subrange_vec_dec v__2 12 12 in
+ let rd : regbits := subrange_vec_dec v__2 11 7 in
+ let ui43 : bits 2 := subrange_vec_dec v__2 6 5 in
+ let ui86 : bits 3 := subrange_vec_dec v__2 4 2 in
+ let uimm : bits 6 := concat_vec ui86 (concat_vec ui5 ui43) in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ None
+ else Some (C_LDSP (uimm,rd))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B1;B0] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ let ui52 : bits 4 := subrange_vec_dec v__2 12 9 in
+ let ui76 : bits 2 := subrange_vec_dec v__2 8 7 in
+ let rs2 : regbits := subrange_vec_dec v__2 6 2 in
+ let uimm : bits 6 := concat_vec ui76 ui52 in
+ Some (C_SWSP (uimm,rs2))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 13) (vec_of_bits [B1;B1;B1] : mword 3))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ let ui53 : bits 3 := subrange_vec_dec v__2 12 10 in
+ let ui86 : bits 3 := subrange_vec_dec v__2 9 7 in
+ let rs2 : regbits := subrange_vec_dec v__2 6 2 in
+ let uimm : bits 6 := concat_vec ui86 ui53 in
+ Some (C_SDSP (uimm,rs2))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 12) (vec_of_bits [B1;B0;B0;B0] : mword 4))
+ (eq_vec (subrange_vec_dec v__2 6 0) (vec_of_bits [B0;B0;B0;B0;B0;B1;B0] : mword 7))))
+ then
+ let rs1 : regbits := subrange_vec_dec v__2 11 7 in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ None
+ else Some (C_JR rs1)
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 12) (vec_of_bits [B1;B0;B0;B1] : mword 4))
+ (eq_vec (subrange_vec_dec v__2 6 0) (vec_of_bits [B0;B0;B0;B0;B0;B1;B0] : mword 7))))
+ then
+ let rs1 : regbits := subrange_vec_dec v__2 11 7 in
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) then
+ None
+ else Some (C_JALR rs1)
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 12) (vec_of_bits [B1;B0;B0;B0] : mword 4))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ let rd : regbits := subrange_vec_dec v__2 11 7 in
+ let rs2 : regbits := subrange_vec_dec v__2 6 2 in
+ if sumbool_of_bool ((orb
+ (Z.eqb
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))
+ (Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ None
+ else Some (C_MV (rd,rs2))
+ else if ((andb (eq_vec (subrange_vec_dec v__2 15 12) (vec_of_bits [B1;B0;B0;B1] : mword 4))
+ (eq_vec (subrange_vec_dec v__2 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ let rsd : regbits := subrange_vec_dec v__2 11 7 in
+ let rs2 : regbits := subrange_vec_dec v__2 6 2 in
+ if sumbool_of_bool ((orb
+ (Z.eqb
+ (projT1 ((regbits_to_regno rsd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))
+ (Z.eqb
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno zreg)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ None
+ else Some (C_ADD (rsd,rs2))
+ else if ((eq_vec v__2 (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 16)))
+ then
+ Some (C_ILLEGAL tt)
+ else None.
+
+Fixpoint execute_WFI (g__26 : unit)
+: M (bool) :=
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ (match w__0 with
+ | Machine => returnm (true : bool)
+ | Supervisor =>
+ read_reg mstatus_ref >>= fun w__1 : Mstatus =>
+ (if ((eq_vec (_get_Mstatus_TW w__1) ((bool_to_bits true) : mword 1))) then
+ handle_illegal tt >> returnm (false : bool)
+ else returnm (true : bool))
+ : M (bool)
+ | User => handle_illegal tt >> returnm (false : bool)
+ end)
+ : M (bool).
+
+Fixpoint execute_UTYPE (imm : mword 20) (rd : mword 5) (op : uop)
+: M (bool) :=
+ let off : xlenbits :=
+ EXTS 64 (concat_vec imm (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12)) in
+ match op with
+ | RISCV_LUI => returnm (off : xlenbits)
+ | RISCV_AUIPC =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ returnm ((add_vec w__0 off)
+ : xlenbits)
+ end >>= fun ret : xlenbits =>
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) ret >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_THREAD_START (g__29 : unit) : bool := true.
+
+Fixpoint execute_STORECON (aq : bool) (rl : bool) (rs2 : mword 5) (rs1 : mword 5) (width : word_width) (rd : mword 5)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun vaddr : xlenbits =>
+ match width with
+ | BYTE => returnm (true : bool)
+ | HALF =>
+ cast_unit_vec (access_vec_dec vaddr 0) >>= fun w__0 : mword 1 =>
+ returnm ((eq_vec (w__0 : mword 1) (vec_of_bits [B0] : mword 1))
+ : bool)
+ | WORD =>
+ returnm ((eq_vec (subrange_vec_dec vaddr 1 0) (vec_of_bits [B0;B0] : mword 2)) : bool)
+ | DOUBLE =>
+ returnm ((eq_vec (subrange_vec_dec vaddr 2 0) (vec_of_bits [B0;B0;B0] : mword 3)) : bool)
+ end >>= fun aligned : bool =>
+ (if ((negb aligned)) then handle_mem_exception vaddr E_SAMO_Addr_Align >> returnm (false : bool)
+ else
+ match_reservation vaddr >>= fun w__1 : bool =>
+ (if ((eq_vec ((bool_to_bits w__1) : mword 1) ((bool_to_bits false) : mword 1))) then
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTZ 64 (vec_of_bits [B1] : mword 1)) >>
+ returnm (true
+ : bool)
+ else
+ translateAddr vaddr Write Data >>= fun w__2 : TR_Result =>
+ (match w__2 with
+ | TR_Failure (e) => handle_mem_exception vaddr e >> returnm (false : bool)
+ | TR_Address (addr) =>
+ match width with
+ | WORD => (mem_write_ea addr 4 aq rl true) : M (MemoryOpResult unit)
+ | DOUBLE => (mem_write_ea addr 8 aq rl true) : M (MemoryOpResult unit)
+ | _ => (internal_error "STORECON expected word or double") : M (MemoryOpResult unit)
+ end >>= fun eares : MemoryOpResult unit =>
+ (match eares with
+ | MemException (e) => handle_mem_exception addr e >> returnm (false : bool)
+ | MemValue (_) =>
+ rX
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs2_val =>
+ match width with
+ | WORD =>
+ (mem_write_value addr 4 (subrange_vec_dec rs2_val 31 0) aq rl true)
+ : M (MemoryOpResult bool)
+ | DOUBLE => (mem_write_value addr 8 rs2_val aq rl true) : M (MemoryOpResult bool)
+ | _ =>
+ (internal_error "STORECON expected word or double") : M (MemoryOpResult bool)
+ end >>= fun res : MemoryOpResult bool =>
+ (match res with
+ | MemValue (true) =>
+ wX
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTZ 64 (vec_of_bits [B0] : mword 1)) >>
+ let '_ := (cancel_reservation tt) : unit in
+ returnm (true
+ : bool)
+ | MemValue (false) =>
+ wX
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTZ 64 (vec_of_bits [B1] : mword 1)) >>
+ let '_ := (cancel_reservation tt) : unit in
+ returnm (true
+ : bool)
+ | MemException (e) => handle_mem_exception addr e >> returnm (false : bool)
+ end)
+ : M (bool)
+ end)
+ : M (bool)
+ end)
+ : M (bool))
+ : M (bool))
+ : M (bool).
+
+Fixpoint execute_STORE (imm : mword 12) (rs2 : mword 5) (rs1 : mword 5) (width : word_width) (aq : bool) (rl : bool)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__0 : mword 64 =>
+ let vaddr : xlenbits := add_vec w__0 (EXTS 64 imm) in
+ check_misaligned vaddr width >>= fun w__1 : bool =>
+ (if (w__1) then handle_mem_exception vaddr E_SAMO_Addr_Align >> returnm (false : bool)
+ else
+ translateAddr vaddr Write Data >>= fun w__2 : TR_Result =>
+ (match w__2 with
+ | TR_Failure (e) => handle_mem_exception vaddr e >> returnm (false : bool)
+ | TR_Address (addr) =>
+ match width with
+ | BYTE => (mem_write_ea addr 1 aq rl false) : M (MemoryOpResult unit)
+ | HALF => (mem_write_ea addr 2 aq rl false) : M (MemoryOpResult unit)
+ | WORD => (mem_write_ea addr 4 aq rl false) : M (MemoryOpResult unit)
+ | DOUBLE => (mem_write_ea addr 8 aq rl false) : M (MemoryOpResult unit)
+ end >>= fun eares : MemoryOpResult unit =>
+ (match eares with
+ | MemException (e) => handle_mem_exception addr e >> returnm (false : bool)
+ | MemValue (_) =>
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs2_val =>
+ match width with
+ | BYTE =>
+ (mem_write_value addr 1 (subrange_vec_dec rs2_val 7 0) aq rl false)
+ : M (MemoryOpResult bool)
+ | HALF =>
+ (mem_write_value addr 2 (subrange_vec_dec rs2_val 15 0) aq rl false)
+ : M (MemoryOpResult bool)
+ | WORD =>
+ (mem_write_value addr 4 (subrange_vec_dec rs2_val 31 0) aq rl false)
+ : M (MemoryOpResult bool)
+ | DOUBLE => (mem_write_value addr 8 rs2_val aq rl false) : M (MemoryOpResult bool)
+ end >>= fun res : MemoryOpResult bool =>
+ (match res with
+ | MemValue (true) => returnm (true : bool)
+ | MemValue (false) =>
+ (internal_error "store got false from mem_write_value") : M (bool)
+ | MemException (e) => handle_mem_exception addr e >> returnm (false : bool)
+ end)
+ : M (bool)
+ end)
+ : M (bool)
+ end)
+ : M (bool))
+ : M (bool).
+
+Fixpoint execute_STOP_FETCHING (g__28 : unit) : bool := true.
+
+Fixpoint execute_SRET (g__24 : unit)
+: M (bool) :=
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ match w__0 with
+ | User => (handle_illegal tt) : M (unit)
+ | Supervisor =>
+ read_reg mstatus_ref >>= fun w__1 : Mstatus =>
+ (if ((eq_vec (_get_Mstatus_TSR w__1) ((bool_to_bits true) : mword 1))) then
+ (handle_illegal tt)
+ : M (unit)
+ else
+ read_reg cur_privilege_ref >>= fun w__2 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__3 : mword 64 =>
+ handle_exception w__2 (CTL_SRET tt) w__3 >>= fun w__4 : xlenbits =>
+ write_reg nextPC_ref w__4
+ : M (unit))
+ : M (unit)
+ | Machine =>
+ read_reg cur_privilege_ref >>= fun w__5 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__6 : mword 64 =>
+ handle_exception w__5 (CTL_SRET tt) w__6 >>= fun w__7 : xlenbits =>
+ write_reg nextPC_ref w__7
+ : M (unit)
+ end >>
+ returnm (false
+ : bool).
+
+Fixpoint execute_SHIFTW (shamt : mword 5) (rs1 : mword 5) (rd : mword 5) (op : sop)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__0 : mword 64 =>
+ let rs1_val := subrange_vec_dec w__0 31 0 in
+ let result : bits 32 :=
+ match op with
+ | RISCV_SLLI => shift_bits_left rs1_val shamt
+ | RISCV_SRLI => shift_bits_right rs1_val shamt
+ | RISCV_SRAI => shift_right_arith32 rs1_val shamt
+ end in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTS 64 result) >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_SHIFTIWOP (shamt : mword 5) (rs1 : mword 5) (rd : mword 5) (op : sopw)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs1_val =>
+ let result : xlenbits :=
+ match op with
+ | RISCV_SLLIW => EXTS 64 (shift_bits_left (subrange_vec_dec rs1_val 31 0) shamt)
+ | RISCV_SRLIW => EXTS 64 (shift_bits_right (subrange_vec_dec rs1_val 31 0) shamt)
+ | RISCV_SRAIW => EXTS 64 (shift_right_arith32 (subrange_vec_dec rs1_val 31 0) shamt)
+ end in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) result >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_SHIFTIOP (shamt : mword 6) (rs1 : mword 5) (rd : mword 5) (op : sop)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs1_val =>
+ let result : xlenbits :=
+ match op with
+ | RISCV_SLLI => shift_bits_left rs1_val shamt
+ | RISCV_SRLI => shift_bits_right rs1_val shamt
+ | RISCV_SRAI => shift_right_arith64 rs1_val shamt
+ end in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) result >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_SFENCE_VMA (rs1 : mword 5) (rs2 : mword 5)
+: M (bool) :=
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ (if ((eq_vec ((privLevel_to_bits w__0) : mword 2) ((privLevel_to_bits User) : mword 2))) then
+ handle_illegal tt >> returnm (false : bool)
+ else
+ read_reg mstatus_ref >>= fun w__1 : Mstatus =>
+ read_reg mstatus_ref >>= fun w__2 : Mstatus =>
+ let p__20 := (architecture (_get_Mstatus_SXL w__1), _get_Mstatus_TVM w__2) in
+ (match p__20 with
+ | (Some (RV64), v_0) =>
+ (if ((eq_vec v_0 ((bool_to_bits true) : mword 1))) then
+ handle_illegal tt >> returnm (false : bool)
+ else if ((eq_vec v_0 ((bool_to_bits false) : mword 1))) then
+ (if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ returnm (None
+ : option vaddr39)
+ else
+ rX
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__3 : mword 64 =>
+ returnm ((Some (subrange_vec_dec w__3 38 0))
+ : option vaddr39)) >>= fun addr : option vaddr39 =>
+ (if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ returnm (None
+ : option asid64)
+ else
+ rX
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__4 : mword 64 =>
+ returnm ((Some (subrange_vec_dec w__4 15 0))
+ : option asid64)) >>= fun asid : option asid64 =>
+ flushTLB asid addr >> returnm (true : bool)
+ else
+ (match (Some RV64, v_0) with
+ | (g__18, g__19) => (internal_error "unimplemented sfence architecture") : M (bool)
+ end)
+ : M (bool))
+ : M (bool)
+ | (g__18, g__19) => (internal_error "unimplemented sfence architecture") : M (bool)
+ end)
+ : M (bool))
+ : M (bool).
+
+Fixpoint execute_RTYPEW (rs2 : mword 5) (rs1 : mword 5) (rd : mword 5) (op : ropw)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__0 : mword 64 =>
+ let rs1_val := subrange_vec_dec w__0 31 0 in
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__1 : mword 64 =>
+ let rs2_val := subrange_vec_dec w__1 31 0 in
+ let result : bits 32 :=
+ match op with
+ | RISCV_ADDW => add_vec rs1_val rs2_val
+ | RISCV_SUBW => sub_vec rs1_val rs2_val
+ | RISCV_SLLW => shift_bits_left rs1_val (subrange_vec_dec rs2_val 4 0)
+ | RISCV_SRLW => shift_bits_right rs1_val (subrange_vec_dec rs2_val 4 0)
+ | RISCV_SRAW => shift_right_arith32 rs1_val (subrange_vec_dec rs2_val 4 0)
+ end in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTS 64 result) >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_RTYPE (rs2 : mword 5) (rs1 : mword 5) (rd : mword 5) (op : rop)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs1_val =>
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs2_val =>
+ let result : xlenbits :=
+ match op with
+ | RISCV_ADD => add_vec rs1_val rs2_val
+ | RISCV_SUB => sub_vec rs1_val rs2_val
+ | RISCV_SLL => shift_bits_left rs1_val (subrange_vec_dec rs2_val 5 0)
+ | RISCV_SLT => EXTZ 64 ((bool_to_bits (zopz0zI_s rs1_val rs2_val)) : mword 1)
+ | RISCV_SLTU => EXTZ 64 ((bool_to_bits (zopz0zI_u rs1_val rs2_val)) : mword 1)
+ | RISCV_XOR => xor_vec rs1_val rs2_val
+ | RISCV_SRL => shift_bits_right rs1_val (subrange_vec_dec rs2_val 5 0)
+ | RISCV_SRA => shift_right_arith64 rs1_val (subrange_vec_dec rs2_val 5 0)
+ | RISCV_OR => or_vec rs1_val rs2_val
+ | RISCV_AND => and_vec rs1_val rs2_val
+ end in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) result >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_RISCV_JALR (imm : mword 12) (rs1 : mword 5) (rd : mword 5)
+: M (bool) :=
+ (read_reg nextPC_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) w__0 >>
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__1 : mword 64 =>
+ let newPC : xlenbits := add_vec w__1 (EXTS 64 imm) in
+ write_reg nextPC_ref (concat_vec (subrange_vec_dec newPC 63 1) (vec_of_bits [B0] : mword 1)) >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_RISCV_JAL (imm : mword 21) (rd : mword 5)
+: M (bool) :=
+ (read_reg PC_ref : M (mword 64)) >>= fun pc : xlenbits =>
+ (read_reg nextPC_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) w__0 >>
+ let offset : xlenbits := EXTS 64 imm in
+ write_reg nextPC_ref (add_vec pc offset) >> returnm (true : bool).
+
+Fixpoint execute_REMW (rs2 : mword 5) (rs1 : mword 5) (rd : mword 5) (s : bool)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__0 : mword 64 =>
+ let rs1_val := subrange_vec_dec w__0 31 0 in
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__1 : mword 64 =>
+ let rs2_val := subrange_vec_dec w__1 31 0 in
+ let rs1_int : Z := if (s) then projT1 (sint rs1_val) else projT1 (uint rs1_val) in
+ let rs2_int : Z := if (s) then projT1 (sint rs2_val) else projT1 (uint rs2_val) in
+ let r : Z :=
+ if sumbool_of_bool ((Z.eqb rs2_int 0)) then rs1_int
+ else rem_round_zero rs1_int rs2_int in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTS 64 (to_bits 32 r)) >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_REM (rs2 : mword 5) (rs1 : mword 5) (rd : mword 5) (s : bool)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs1_val =>
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs2_val =>
+ let rs1_int : Z := if (s) then projT1 (sint rs1_val) else projT1 (uint rs1_val) in
+ let rs2_int : Z := if (s) then projT1 (sint rs2_val) else projT1 (uint rs2_val) in
+ let r : Z :=
+ if sumbool_of_bool ((Z.eqb rs2_int 0)) then rs1_int
+ else rem_round_zero rs1_int rs2_int in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (to_bits xlen r) >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_NOP (g__27 : unit) : bool := true.
+
+Fixpoint execute_MULW (rs2 : mword 5) (rs1 : mword 5) (rd : mword 5)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__0 : mword 64 =>
+ let rs1_val := subrange_vec_dec w__0 31 0 in
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__1 : mword 64 =>
+ let rs2_val := subrange_vec_dec w__1 31 0 in
+ let rs1_int : Z := projT1 (sint rs1_val) in
+ let rs2_int : Z := projT1 (sint rs2_val) in
+ let result32 := subrange_vec_dec (to_bits 64 (Z.mul rs1_int rs2_int)) 31 0 in
+ let result : xlenbits := EXTS 64 result32 in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) result >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_MUL (rs2 : mword 5) (rs1 : mword 5) (rd : mword 5) (high : bool) (signed1 : bool) (signed2 : bool)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs1_val =>
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs2_val =>
+ let rs1_int : Z := if (signed1) then projT1 (sint rs1_val) else projT1 (uint rs1_val) in
+ let rs2_int : Z := if (signed2) then projT1 (sint rs2_val) else projT1 (uint rs2_val) in
+ let result128 := to_bits 128 (Z.mul rs1_int rs2_int) in
+ let result :=
+ if (high) then subrange_vec_dec result128 127 64
+ else subrange_vec_dec result128 63 0 in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) result >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_MRET (g__23 : unit)
+: M (bool) :=
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ (if ((eq_vec ((privLevel_to_bits w__0) : mword 2) ((privLevel_to_bits Machine) : mword 2)))
+ then
+ read_reg cur_privilege_ref >>= fun w__1 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__2 : mword 64 =>
+ handle_exception w__1 (CTL_MRET tt) w__2 >>= fun w__3 : xlenbits =>
+ write_reg nextPC_ref w__3
+ : M (unit)
+ else (handle_illegal tt) : M (unit)) >>
+ returnm (false
+ : bool).
+
+Fixpoint execute_LOADRES (aq : bool) (rl : bool) (rs1 : mword 5) (width : word_width) (rd : mword 5)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun vaddr : xlenbits =>
+ match width with
+ | BYTE => returnm (true : bool)
+ | HALF =>
+ cast_unit_vec (access_vec_dec vaddr 0) >>= fun w__0 : mword 1 =>
+ returnm ((eq_vec (w__0 : mword 1) (vec_of_bits [B0] : mword 1))
+ : bool)
+ | WORD =>
+ returnm ((eq_vec (subrange_vec_dec vaddr 1 0) (vec_of_bits [B0;B0] : mword 2)) : bool)
+ | DOUBLE =>
+ returnm ((eq_vec (subrange_vec_dec vaddr 2 0) (vec_of_bits [B0;B0;B0] : mword 3)) : bool)
+ end >>= fun aligned : bool =>
+ (if ((negb aligned)) then handle_mem_exception vaddr E_Load_Addr_Align >> returnm (false : bool)
+ else
+ translateAddr vaddr Read Data >>= fun w__1 : TR_Result =>
+ (match w__1 with
+ | TR_Failure (e) => handle_mem_exception vaddr e >> returnm (false : bool)
+ | TR_Address (addr) =>
+ (match width with
+ | WORD =>
+ mem_read addr 4 aq rl true >>= fun w__2 : MemoryOpResult (mword 32) =>
+ (process_loadres (n := 4) rd vaddr w__2 false)
+ : M (bool)
+ | DOUBLE =>
+ mem_read addr 8 aq rl true >>= fun w__4 : MemoryOpResult (mword 64) =>
+ (process_loadres (n := 8) rd vaddr w__4 false)
+ : M (bool)
+ | _ => (internal_error "LOADRES expected WORD or DOUBLE") : M (bool)
+ end)
+ : M (bool)
+ end)
+ : M (bool))
+ : M (bool).
+
+Fixpoint execute_LOAD (imm : mword 12) (rs1 : mword 5) (rd : mword 5) (is_unsigned : bool) (width : word_width) (aq : bool) (rl : bool)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__0 : mword 64 =>
+ let vaddr : xlenbits := add_vec w__0 (EXTS 64 imm) in
+ check_misaligned vaddr width >>= fun w__1 : bool =>
+ (if (w__1) then handle_mem_exception vaddr E_Load_Addr_Align >> returnm (false : bool)
+ else
+ translateAddr vaddr Read Data >>= fun w__2 : TR_Result =>
+ (match w__2 with
+ | TR_Failure (e) => handle_mem_exception vaddr e >> returnm (false : bool)
+ | TR_Address (addr) =>
+ (match width with
+ | BYTE =>
+ mem_read addr 1 aq rl false >>= fun w__3 : MemoryOpResult (mword 8) =>
+ (process_load (n := 1) rd vaddr w__3 is_unsigned)
+ : M (bool)
+ | HALF =>
+ mem_read addr 2 aq rl false >>= fun w__5 : MemoryOpResult (mword 16) =>
+ (process_load (n := 2) rd vaddr w__5 is_unsigned)
+ : M (bool)
+ | WORD =>
+ mem_read addr 4 aq rl false >>= fun w__7 : MemoryOpResult (mword 32) =>
+ (process_load (n := 4) rd vaddr w__7 is_unsigned)
+ : M (bool)
+ | DOUBLE =>
+ mem_read addr 8 aq rl false >>= fun w__9 : MemoryOpResult (mword 64) =>
+ (process_load (n := 8) rd vaddr w__9 is_unsigned)
+ : M (bool)
+ end)
+ : M (bool)
+ end)
+ : M (bool))
+ : M (bool).
+
+Fixpoint execute_ITYPE (imm : mword 12) (rs1 : mword 5) (rd : mword 5) (op : iop)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs1_val =>
+ let immext : xlenbits := EXTS 64 imm in
+ let result : xlenbits :=
+ match op with
+ | RISCV_ADDI => add_vec rs1_val immext
+ | RISCV_SLTI => EXTZ 64 ((bool_to_bits (zopz0zI_s rs1_val immext)) : mword 1)
+ | RISCV_SLTIU => EXTZ 64 ((bool_to_bits (zopz0zI_u rs1_val immext)) : mword 1)
+ | RISCV_XORI => xor_vec rs1_val immext
+ | RISCV_ORI => or_vec rs1_val immext
+ | RISCV_ANDI => and_vec rs1_val immext
+ end in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) result >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_ILLEGAL (s : mword 32) : M (bool) := handle_illegal tt >> returnm (false : bool).
+
+Fixpoint execute_FENCEI (g__21 : unit) : bool := true.
+
+Fixpoint execute_FENCE (pred : mword 4) (succ : mword 4)
+: M (bool) :=
+ match (pred, succ) with
+ | (v__132, v__133) =>
+ (if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B1;B1] : mword 2)))) then
+ (MEM_fence_rw_rw tt)
+ : M (unit)
+ else if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B1;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B1;B1] : mword 2)))) then
+ (MEM_fence_r_rw tt)
+ : M (unit)
+ else if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B1;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ (MEM_fence_r_r tt)
+ : M (unit)
+ else if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ (MEM_fence_rw_w tt)
+ : M (unit)
+ else if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B0;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ (MEM_fence_w_w tt)
+ : M (unit)
+ else if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B0;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B1;B1] : mword 2)))) then
+ (MEM_fence_w_rw tt)
+ : M (unit)
+ else if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ (MEM_fence_rw_r tt)
+ : M (unit)
+ else if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B1;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ (MEM_fence_r_w tt)
+ : M (unit)
+ else if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B0;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ (MEM_fence_w_r tt)
+ : M (unit)
+ else
+ returnm ((if ((andb (eq_vec (subrange_vec_dec v__132 1 0) (vec_of_bits [B0;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__133 1 0) (vec_of_bits [B0;B0] : mword 2))))
+ then
+ tt
+ else
+ let '_ := (print_endline "FIXME: unsupported fence") : unit in
+ tt)
+ : unit))
+ : M (unit)
+ end >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_ECALL (g__22 : unit)
+: M (bool) :=
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ let t : sync_exception :=
+ {| sync_exception_trap :=
+ (match w__0 with
+ | User => E_U_EnvCall
+ | Supervisor => E_S_EnvCall
+ | Machine => E_M_EnvCall
+ end);
+ sync_exception_excinfo := (None : option xlenbits) |} in
+ read_reg cur_privilege_ref >>= fun w__1 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__2 : mword 64 =>
+ handle_exception w__1 (CTL_TRAP t) w__2 >>= fun w__3 : xlenbits =>
+ write_reg nextPC_ref w__3 >> returnm (false : bool).
+
+Fixpoint execute_EBREAK (g__25 : unit)
+: M (bool) :=
+ (read_reg PC_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ handle_mem_exception w__0 E_Breakpoint >> returnm (false : bool).
+
+Fixpoint execute_DIVW (rs2 : mword 5) (rs1 : mword 5) (rd : mword 5) (s : bool)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__0 : mword 64 =>
+ let rs1_val := subrange_vec_dec w__0 31 0 in
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__1 : mword 64 =>
+ let rs2_val := subrange_vec_dec w__1 31 0 in
+ let rs1_int : Z := if (s) then projT1 (sint rs1_val) else projT1 (uint rs1_val) in
+ let rs2_int : Z := if (s) then projT1 (sint rs2_val) else projT1 (uint rs2_val) in
+ let q : Z := if sumbool_of_bool ((Z.eqb rs2_int 0)) then -1 else quot_round_zero rs1_int rs2_int in
+ let q' : Z :=
+ if sumbool_of_bool ((andb s
+ (Z.gtb q (projT1 (sub_range (build_ex (projT1 (pow2 31))) (build_ex 1))))))
+ then
+ (Z.sub ( 0) ((pow 2 31)))
+ else q in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTS 64 (to_bits 32 q')) >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_DIV (rs2 : mword 5) (rs1 : mword 5) (rd : mword 5) (s : bool)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs1_val =>
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs2_val =>
+ let rs1_int : Z := if (s) then projT1 (sint rs1_val) else projT1 (uint rs1_val) in
+ let rs2_int : Z := if (s) then projT1 (sint rs2_val) else projT1 (uint rs2_val) in
+ let q : Z := if sumbool_of_bool ((Z.eqb rs2_int 0)) then -1 else quot_round_zero rs1_int rs2_int in
+ let q' : Z := if sumbool_of_bool ((andb s (Z.gtb q xlen_max_signed))) then xlen_min_signed else q in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (to_bits xlen q') >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_C_ILLEGAL (g__30 : unit)
+: M (bool) :=
+ handle_illegal tt >> returnm (false : bool).
+
+Fixpoint execute_C_ADDIW (imm : mword 6) (rsd : mword 5)
+: M (bool) :=
+ let imm : bits 32 := EXTS 32 imm in
+ rX (projT1 ((regbits_to_regno rsd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs_val =>
+ let res : bits 32 := add_vec (subrange_vec_dec rs_val 31 0) imm in
+ wX (projT1 ((regbits_to_regno rsd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTS 64 res) >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_CSR (csr : mword 12) (rs1 : mword 5) (rd : mword 5) (is_imm : bool) (op : csrop)
+: M (bool) :=
+ (if (is_imm) then returnm ((EXTZ 64 rs1) : xlenbits)
+ else
+ (rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))
+ : M (xlenbits)) >>= fun rs1_val : xlenbits =>
+ let isWrite : bool :=
+ match op with
+ | CSRRW => true
+ | _ => if (is_imm) then neq_int (projT1 (uint rs1_val)) 0 else neq_int (projT1 (uint rs1)) 0
+ end in
+ read_reg cur_privilege_ref >>= fun w__1 : Privilege =>
+ check_CSR csr w__1 isWrite >>= fun w__2 : bool =>
+ (if ((negb w__2)) then handle_illegal tt >> returnm (false : bool)
+ else
+ readCSR csr >>= fun csr_val =>
+ (if (isWrite) then
+ let new_val : xlenbits :=
+ match op with
+ | CSRRW => rs1_val
+ | CSRRS => or_vec csr_val rs1_val
+ | CSRRC => and_vec csr_val (not_vec rs1_val)
+ end in
+ (writeCSR csr new_val)
+ : M (unit)
+ else returnm (tt : unit)) >>
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) csr_val >>
+ returnm (true
+ : bool))
+ : M (bool).
+
+Fixpoint execute_BTYPE (imm : mword 13) (rs2 : mword 5) (rs1 : mword 5) (op : bop)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs1_val =>
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs2_val =>
+ let taken : bool :=
+ match op with
+ | RISCV_BEQ => eq_vec rs1_val rs2_val
+ | RISCV_BNE => neq_vec rs1_val rs2_val
+ | RISCV_BLT => zopz0zI_s rs1_val rs2_val
+ | RISCV_BGE => zopz0zKzJ_s rs1_val rs2_val
+ | RISCV_BLTU => zopz0zI_u rs1_val rs2_val
+ | RISCV_BGEU => zopz0zKzJ_u rs1_val rs2_val
+ end in
+ (if (taken) then
+ (read_reg PC_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ write_reg nextPC_ref (add_vec w__0 (EXTS 64 imm))
+ : M (unit)
+ else returnm (tt : unit)) >>
+ returnm (true
+ : bool).
+
+Fixpoint execute_AMO (op : amoop) (aq : bool) (rl : bool) (rs2 : mword 5) (rs1 : mword 5) (width : word_width) (rd : mword 5)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun vaddr : xlenbits =>
+ translateAddr vaddr ReadWrite Data >>= fun w__0 : TR_Result =>
+ (match w__0 with
+ | TR_Failure (e) => handle_mem_exception vaddr e >> returnm (false : bool)
+ | TR_Address (addr) =>
+ match width with
+ | WORD => (mem_write_ea addr 4 (andb aq rl) rl true) : M (MemoryOpResult unit)
+ | DOUBLE => (mem_write_ea addr 8 (andb aq rl) rl true) : M (MemoryOpResult unit)
+ | _ => (internal_error "AMO expected WORD or DOUBLE") : M (MemoryOpResult unit)
+ end >>= fun eares : MemoryOpResult unit =>
+ (match eares with
+ | MemException (e) => handle_mem_exception addr e >> returnm (false : bool)
+ | MemValue (_) =>
+ match width with
+ | WORD =>
+ mem_read addr 4 aq (andb aq rl) true >>= fun w__4 : MemoryOpResult (mword 32) =>
+ returnm ((extend_value (n := 4) false w__4)
+ : MemoryOpResult xlenbits)
+ | DOUBLE =>
+ mem_read addr 8 aq (andb aq rl) true >>= fun w__5 : MemoryOpResult (mword 64) =>
+ returnm ((extend_value (n := 8) false w__5)
+ : MemoryOpResult xlenbits)
+ | _ => (internal_error "AMO expected WORD or DOUBLE") : M (MemoryOpResult xlenbits)
+ end >>= fun rval : MemoryOpResult xlenbits =>
+ (match rval with
+ | MemException (e) => handle_mem_exception addr e >> returnm (false : bool)
+ | MemValue (loaded) =>
+ rX (projT1 ((regbits_to_regno rs2) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun rs2_val : xlenbits =>
+ let result : xlenbits :=
+ match op with
+ | AMOSWAP => rs2_val
+ | AMOADD => add_vec rs2_val loaded
+ | AMOXOR => xor_vec rs2_val loaded
+ | AMOAND => and_vec rs2_val loaded
+ | AMOOR => or_vec rs2_val loaded
+ | AMOMIN => vector64 (Z.min (projT1 (sint rs2_val)) (projT1 (sint loaded)))
+ | AMOMAX => vector64 (Z.max (projT1 (sint rs2_val)) (projT1 (sint loaded)))
+ | AMOMINU =>
+ vector64
+ (projT1 (min_nat (build_ex (projT1 (uint rs2_val)))
+ (build_ex (projT1 (uint loaded)))))
+ | AMOMAXU =>
+ vector64
+ (projT1 (max_nat (build_ex (projT1 (uint rs2_val)))
+ (build_ex (projT1 (uint loaded)))))
+ end in
+ match width with
+ | WORD =>
+ (mem_write_value addr 4 (subrange_vec_dec result 31 0) (andb aq rl) rl true)
+ : M (MemoryOpResult bool)
+ | DOUBLE =>
+ (mem_write_value addr 8 result (andb aq rl) rl true) : M (MemoryOpResult bool)
+ | _ => (internal_error "AMO expected WORD or DOUBLE") : M (MemoryOpResult bool)
+ end >>= fun wval : MemoryOpResult bool =>
+ (match wval with
+ | MemValue (true) =>
+ wX
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) loaded >>
+ returnm (true
+ : bool)
+ | MemValue (false) =>
+ (internal_error "AMO got false from mem_write_value") : M (bool)
+ | MemException (e) => handle_mem_exception addr e >> returnm (false : bool)
+ end)
+ : M (bool)
+ end)
+ : M (bool)
+ end)
+ : M (bool)
+ end)
+ : M (bool).
+
+Fixpoint execute_ADDIW (imm : mword 12) (rs1 : mword 5) (rd : mword 5)
+: M (bool) :=
+ rX (projT1 ((regbits_to_regno rs1) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) >>= fun w__0 : mword 64 =>
+ let result : xlenbits := add_vec (EXTS 64 imm) w__0 in
+ wX (projT1 ((regbits_to_regno rd) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (EXTS 64 (subrange_vec_dec result 31 0)) >>
+ returnm (true
+ : bool).
+
+Definition expand_ast (i : ast) : ast :=
+match i with
+ | C_ADDI4SPN (rdc,nzimm) =>
+ let imm : bits 12 :=
+ concat_vec (vec_of_bits [B0;B0] : mword 2)
+ (concat_vec nzimm (vec_of_bits [B0;B0] : mword 2)) in
+ let rd := creg2reg_bits rdc in
+ ( (ITYPE (imm,sp,rd,RISCV_ADDI)))
+
+ | C_LW (uimm,rsc,rdc) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0] : mword 2)) in
+ let rd := creg2reg_bits rdc in
+ let rs := creg2reg_bits rsc in
+ ( (LOAD (imm,rs,rd,false,WORD,false,false)))
+
+ | C_LD (uimm,rsc,rdc) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0;B0] : mword 3)) in
+ let rd := creg2reg_bits rdc in
+ let rs := creg2reg_bits rsc in
+ ( (LOAD (imm,rs,rd,false,DOUBLE,false,false)))
+
+ | C_SW (uimm,rsc1,rsc2) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0] : mword 2)) in
+ let rs1 := creg2reg_bits rsc1 in
+ let rs2 := creg2reg_bits rsc2 in
+ ( (STORE (imm,rs2,rs1,WORD,false,false)))
+
+ | C_SD (uimm,rsc1,rsc2) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0;B0] : mword 3)) in
+ let rs1 := creg2reg_bits rsc1 in
+ let rs2 := creg2reg_bits rsc2 in
+ ( (STORE (imm,rs2,rs1,DOUBLE,false,false)))
+
+ | C_ADDI (nzi,rsd) =>
+ let imm : bits 12 := EXTS 12 nzi in
+ ( (ITYPE (imm,rsd,rsd,RISCV_ADDI)))
+
+ | C_JAL (imm) =>
+ ( (RISCV_JAL (EXTS 21 (concat_vec imm (vec_of_bits [B0] : mword 1)),ra)))
+ | C_LI (imm,rd) =>
+ let imm : bits 12 := EXTS 12 imm in
+ ( (ITYPE (imm,zreg,rd,RISCV_ADDI)))
+
+ | C_ADDI16SP (imm) =>
+ let imm : bits 12 := EXTS 12 (concat_vec imm (vec_of_bits [B0;B0;B0;B0] : mword 4)) in
+ ( (ITYPE (imm,sp,sp,RISCV_ADDI)))
+
+ | C_LUI (imm,rd) =>
+ let res : bits 20 := EXTS 20 imm in
+ ( (UTYPE (res,rd,RISCV_LUI)))
+
+ | C_SRLI (shamt,rsd) =>
+ let rsd := creg2reg_bits rsd in
+ ( (SHIFTIOP (shamt,rsd,rsd,RISCV_SRLI)))
+
+ | C_SRAI (shamt,rsd) =>
+ let rsd := creg2reg_bits rsd in
+ ( (SHIFTIOP (shamt,rsd,rsd,RISCV_SRAI)))
+
+ | C_ANDI (imm,rsd) =>
+ let rsd := creg2reg_bits rsd in
+ ( (ITYPE (EXTS 12 imm,rsd,rsd,RISCV_ANDI)))
+
+ | C_SUB (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+ ( (RTYPE (rs2,rsd,rsd,RISCV_SUB)))
+
+ | C_XOR (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+ ( (RTYPE (rs2,rsd,rsd,RISCV_XOR)))
+
+ | C_OR (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+ ( (RTYPE (rs2,rsd,rsd,RISCV_OR)))
+
+ | C_AND (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+ ( (RTYPE (rs2,rsd,rsd,RISCV_AND)))
+
+ | C_SUBW (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+ ( (RTYPEW (rs2,rsd,rsd,RISCV_SUBW)))
+
+ | C_ADDW (rsd,rs2) =>
+ let rsd := creg2reg_bits rsd in
+ let rs2 := creg2reg_bits rs2 in
+ ( (RTYPEW (rs2,rsd,rsd,RISCV_ADDW)))
+
+ | C_J (imm) =>
+ ( (RISCV_JAL (EXTS 21 (concat_vec imm (vec_of_bits [B0] : mword 1)),zreg)))
+
+ | C_BEQZ (imm,rs) =>
+ (
+ (BTYPE (EXTS 13 (concat_vec imm (vec_of_bits [B0] : mword 1)),zreg,creg2reg_bits rs,RISCV_BEQ)))
+
+ | C_BNEZ (imm,rs) =>
+ (
+ (BTYPE (EXTS 13 (concat_vec imm (vec_of_bits [B0] : mword 1)),zreg,creg2reg_bits rs,RISCV_BNE)))
+
+ | C_SLLI (shamt,rsd) => ( (SHIFTIOP (shamt,rsd,rsd,RISCV_SLLI)))
+ | C_LWSP (uimm,rd) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0] : mword 2)) in
+ ( (LOAD (imm,sp,rd,false,WORD,false,false)))
+
+ | C_LDSP (uimm,rd) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0;B0] : mword 3)) in
+ ( (LOAD (imm,sp,rd,false,DOUBLE,false,false)))
+
+ | C_SWSP (uimm,rs2) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0] : mword 2)) in
+ ( (STORE (imm,rs2,sp,WORD,false,false)))
+
+ | C_SDSP (uimm,rs2) =>
+ let imm : bits 12 := EXTZ 12 (concat_vec uimm (vec_of_bits [B0;B0;B0] : mword 3)) in
+ ( (STORE (imm,rs2,sp,DOUBLE,false,false)))
+
+ | C_JR (rs1) =>
+ ( (RISCV_JALR (EXTZ 12 (vec_of_bits [B0] : mword 1),rs1,zreg)))
+ | C_JALR (rs1) =>
+ ( (RISCV_JALR (EXTZ 12 (vec_of_bits [B0] : mword 1),rs1,ra)))
+ | C_MV (rd,rs2) => ( (RTYPE (rs2,zreg,rd,RISCV_ADD)))
+ | C_ADD (rsd,rs2) => ( (RTYPE (rs2,rsd,rsd,RISCV_ADD)))
+| _ => i
+end.
+
+Fixpoint execute (merge_var : ast)
+: M (bool) :=
+let merge_var := expand_ast merge_var in
+ match merge_var with
+ | UTYPE (imm,rd,op) => (execute_UTYPE imm rd op) : M (bool)
+ | RISCV_JAL (imm,rd) => (execute_RISCV_JAL imm rd) : M (bool)
+ | RISCV_JALR (imm,rs1,rd) => (execute_RISCV_JALR imm rs1 rd) : M (bool)
+ | BTYPE (imm,rs2,rs1,op) => (execute_BTYPE imm rs2 rs1 op) : M (bool)
+ | ITYPE (imm,rs1,rd,op) => (execute_ITYPE imm rs1 rd op) : M (bool)
+ | SHIFTIOP (shamt,rs1,rd,op) => (execute_SHIFTIOP shamt rs1 rd op) : M (bool)
+ | RTYPE (rs2,rs1,rd,op) => (execute_RTYPE rs2 rs1 rd op) : M (bool)
+ | LOAD (imm,rs1,rd,is_unsigned,width,aq,rl) =>
+ (execute_LOAD imm rs1 rd is_unsigned width aq rl) : M (bool)
+ | STORE (imm,rs2,rs1,width,aq,rl) => (execute_STORE imm rs2 rs1 width aq rl) : M (bool)
+ | ADDIW (imm,rs1,rd) => (execute_ADDIW imm rs1 rd) : M (bool)
+ | SHIFTW (shamt,rs1,rd,op) => (execute_SHIFTW shamt rs1 rd op) : M (bool)
+ | RTYPEW (rs2,rs1,rd,op) => (execute_RTYPEW rs2 rs1 rd op) : M (bool)
+ | SHIFTIWOP (shamt,rs1,rd,op) => (execute_SHIFTIWOP shamt rs1 rd op) : M (bool)
+ | MUL (rs2,rs1,rd,high,signed1,signed2) =>
+ (execute_MUL rs2 rs1 rd high signed1 signed2) : M (bool)
+ | DIV (rs2,rs1,rd,s) => (execute_DIV rs2 rs1 rd s) : M (bool)
+ | REM (rs2,rs1,rd,s) => (execute_REM rs2 rs1 rd s) : M (bool)
+ | MULW (rs2,rs1,rd) => (execute_MULW rs2 rs1 rd) : M (bool)
+ | DIVW (rs2,rs1,rd,s) => (execute_DIVW rs2 rs1 rd s) : M (bool)
+ | REMW (rs2,rs1,rd,s) => (execute_REMW rs2 rs1 rd s) : M (bool)
+ | FENCE (pred,succ) => (execute_FENCE pred succ) : M (bool)
+ | FENCEI (g__21) => returnm ((execute_FENCEI g__21) : bool)
+ | ECALL (g__22) => (execute_ECALL g__22) : M (bool)
+ | MRET (g__23) => (execute_MRET g__23) : M (bool)
+ | SRET (g__24) => (execute_SRET g__24) : M (bool)
+ | EBREAK (g__25) => (execute_EBREAK g__25) : M (bool)
+ | WFI (g__26) => (execute_WFI g__26) : M (bool)
+ | SFENCE_VMA (rs1,rs2) => (execute_SFENCE_VMA rs1 rs2) : M (bool)
+ | LOADRES (aq,rl,rs1,width,rd) => (execute_LOADRES aq rl rs1 width rd) : M (bool)
+ | STORECON (aq,rl,rs2,rs1,width,rd) => (execute_STORECON aq rl rs2 rs1 width rd) : M (bool)
+ | AMO (op,aq,rl,rs2,rs1,width,rd) => (execute_AMO op aq rl rs2 rs1 width rd) : M (bool)
+ | CSR (csr,rs1,rd,is_imm,op) => (execute_CSR csr rs1 rd is_imm op) : M (bool)
+ | NOP (g__27) => returnm ((execute_NOP g__27) : bool)
+ | C_ADDIW (imm,rsd) => (execute_C_ADDIW imm rsd) : M (bool)
+ | STOP_FETCHING (g__28) => returnm ((execute_STOP_FETCHING g__28) : bool)
+ | THREAD_START (g__29) => returnm ((execute_THREAD_START g__29) : bool)
+ | ILLEGAL (s) => (execute_ILLEGAL s) : M (bool)
+ | C_ILLEGAL (g__30) => (execute_C_ILLEGAL g__30) : M (bool)
+| _ => Fail "Unexpanded instruction"
+ end.
+
+Definition assembly_forwards (arg_ : ast)
+: M (string) :=
+ (match arg_ with
+ | UTYPE (imm,rd,op) =>
+ returnm ((string_append (utype_mnemonic_forwards op)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt) (string_append (string_of_bits imm) "")))))
+ : string)
+ | RISCV_JAL (imm,rd) =>
+ returnm ((string_append "jal"
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt) (string_append (string_of_bits imm) "")))))
+ : string)
+ | RISCV_JALR (imm,rs1,rd) =>
+ returnm ((string_append "jalr"
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (string_of_bits imm) "")))))))
+ : string)
+ | BTYPE (imm,rs2,rs1,op) =>
+ returnm ((string_append (btype_mnemonic_forwards op)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2)
+ (string_append (sep_forwards tt)
+ (string_append (string_of_bits imm) "")))))))
+ : string)
+ | ITYPE (imm,rs1,rd,op) =>
+ returnm ((string_append (itype_mnemonic_forwards op)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (string_of_bits imm) "")))))))
+ : string)
+ | SHIFTIOP (shamt,rs1,rd,op) =>
+ returnm ((string_append (shiftiop_mnemonic_forwards op)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (string_of_bits shamt) ""))))))
+ : string)
+ | RTYPE (rs2,rs1,rd,op) =>
+ returnm ((string_append (rtype_mnemonic_forwards op)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) "")))))))
+ : string)
+ | LOAD (imm,rs1,rd,is_unsigned,size,aq,rl) =>
+ returnm ((string_append "l"
+ (string_append (size_mnemonic_forwards size)
+ (string_append (maybe_u_forwards is_unsigned)
+ (string_append (maybe_aq_forwards aq)
+ (string_append (maybe_rl_forwards rl)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (string_of_bits imm) "")))))))))))
+ : string)
+ | STORE (imm,rs1,rd,size,aq,rl) =>
+ returnm ((string_append "s"
+ (string_append (size_mnemonic_forwards size)
+ (string_append (maybe_aq_forwards aq)
+ (string_append (maybe_rl_forwards rl)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (string_of_bits imm) ""))))))))))
+ : string)
+ | ADDIW (imm,rs1,rd) =>
+ returnm ((string_append "addiw"
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (string_of_bits imm) "")))))))
+ : string)
+ | SHIFTW (shamt,rs1,rd,op) =>
+ returnm ((string_append (shiftw_mnemonic_forwards op)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (string_of_bits shamt) "")))))))
+ : string)
+ | RTYPEW (rs2,rs1,rd,op) =>
+ returnm ((string_append (rtypew_mnemonic_forwards op)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) "")))))))
+ : string)
+ | SHIFTIWOP (shamt,rs1,rd,op) =>
+ returnm ((string_append (shiftiwop_mnemonic_forwards op)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (string_of_bits shamt) ""))))))
+ : string)
+ | MUL (rs2,rs1,rd,high,signed1,signed2) =>
+ mul_mnemonic_forwards high signed1 signed2 >>= fun w__0 : string =>
+ returnm ((string_append w__0
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) "")))))))
+ : string)
+ | DIV (rs2,rs1,rd,s) =>
+ returnm ((string_append "div"
+ (string_append (maybe_not_u_forwards s)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) ""))))))))
+ : string)
+ | REM (rs2,rs1,rd,s) =>
+ returnm ((string_append "rem"
+ (string_append (maybe_not_u_forwards s)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) ""))))))))
+ : string)
+ | MULW (rs2,rs1,rd) =>
+ returnm ((string_append "mulw"
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) "")))))))
+ : string)
+ | DIVW (rs2,rs1,rd,s) =>
+ returnm ((string_append "div"
+ (string_append (maybe_not_u_forwards s)
+ (string_append "w"
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) "")))))))))
+ : string)
+ | REMW (rs2,rs1,rd,s) =>
+ returnm ((string_append "rem"
+ (string_append (maybe_not_u_forwards s)
+ (string_append "w"
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) "")))))))))
+ : string)
+ | FENCE (pred,succ) =>
+ returnm ((string_append "fence"
+ (string_append (spc_forwards tt)
+ (string_append (fence_bits_forwards pred)
+ (string_append (sep_forwards tt)
+ (string_append (fence_bits_forwards succ) "")))))
+ : string)
+ | FENCEI (tt) => returnm ("fence.i" : string)
+ | ECALL (tt) => returnm ("ecall" : string)
+ | MRET (tt) => returnm ("mret" : string)
+ | SRET (tt) => returnm ("sret" : string)
+ | EBREAK (tt) => returnm ("ebreak" : string)
+ | WFI (tt) => returnm ("wfi" : string)
+ | SFENCE_VMA (rs1,rs2) =>
+ returnm ((string_append "sfence.vma"
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt) (string_append (reg_name_forwards rs2) "")))))
+ : string)
+ | LOADRES (aq,rl,rs1,size,rd) =>
+ returnm ((string_append "lr."
+ (string_append (maybe_aq_forwards aq)
+ (string_append (maybe_rl_forwards rl)
+ (string_append (size_mnemonic_forwards size)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1) ""))))))))
+ : string)
+ | STORECON (aq,rl,rs2,rs1,size,rd) =>
+ returnm ((string_append "sc."
+ (string_append (maybe_aq_forwards aq)
+ (string_append (maybe_rl_forwards rl)
+ (string_append (size_mnemonic_forwards size)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) ""))))))))))
+ : string)
+ | AMO (op,aq,rl,rs2,rs1,width,rd) =>
+ returnm ((string_append (amo_mnemonic_forwards op)
+ (string_append "."
+ (string_append (size_mnemonic_forwards width)
+ (string_append (maybe_aq_forwards aq)
+ (string_append (maybe_rl_forwards rl)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs2) "")))))))))))
+ : string)
+ | CSR (csr,rs1,rd,true,op) =>
+ returnm ((string_append (csr_mnemonic_forwards op)
+ (string_append "i"
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (string_of_bits rs1)
+ (string_append (sep_forwards tt)
+ (string_append (csr_name_map_forwards csr) ""))))))))
+ : string)
+ | CSR (csr,rs1,rd,false,op) =>
+ returnm ((string_append (csr_mnemonic_forwards op)
+ (string_append (spc_forwards tt)
+ (string_append (reg_name_forwards rd)
+ (string_append (sep_forwards tt)
+ (string_append (reg_name_forwards rs1)
+ (string_append (sep_forwards tt)
+ (string_append (csr_name_map_forwards csr) "")))))))
+ : string)
+ | ILLEGAL (s) =>
+ returnm ((string_append "illegal"
+ (string_append (spc_forwards tt) (string_append (string_of_bits s) "")))
+ : string)
+ | _ => exit tt : M (string)
+ end)
+ : M (string).
+(*
+Definition assembly_backwards (arg_ : string)
+: M (ast) :=
+ let _stringappend_1112_ := arg_ in
+ match (utype_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1113_,(existT _ _stringappend_1114_ _)) =>
+ let _stringappend_1115_ := string_drop _stringappend_1112_ (build_ex _stringappend_1114_) in
+ match (spc_matches_prefix _stringappend_1115_) with
+ | Some (_stringappend_1116_,(existT _ _stringappend_1117_ _)) =>
+ let _stringappend_1118_ := string_drop _stringappend_1115_ (build_ex _stringappend_1117_) in
+ match (reg_name_matches_prefix _stringappend_1118_) with
+ | Some (_stringappend_1119_,(existT _ _stringappend_1120_ _)) =>
+ let _stringappend_1121_ :=
+ string_drop _stringappend_1118_ (build_ex _stringappend_1120_) in
+ sep_matches_prefix _stringappend_1121_ >>= fun w__0 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__0 with
+ | Some (_stringappend_1122_,(existT _ _stringappend_1123_ _)) =>
+ let _stringappend_1124_ :=
+ string_drop _stringappend_1121_ (build_ex _stringappend_1123_) in
+ if ((match (hex_bits_20_matches_prefix _stringappend_1124_) with
+ | Some (_stringappend_1125_,(existT _ _stringappend_1126_ _)) =>
+ match (string_drop _stringappend_1124_
+ (build_ex
+ _stringappend_1126_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__1 : bool =>
+ returnm ((if (w__1) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__2 : bool =>
+ returnm ((if (w__2) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__3 : bool =>
+ (if (w__3) then
+ match (utype_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1113_,(existT _ _stringappend_1114_ _)) =>
+ returnm ((_stringappend_1113_, build_ex _stringappend_1114_)
+ : (uop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((uop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__5 : (uop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_1114_ _) := w__5 : (uop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1115_ := string_drop _stringappend_1112_ (build_ex _stringappend_1114_) in
+ match (spc_matches_prefix _stringappend_1115_) with
+ | Some (_stringappend_1116_,(existT _ _stringappend_1117_ _)) =>
+ returnm ((_stringappend_1116_, build_ex _stringappend_1117_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__7 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1117_ _) := w__7 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1118_ := string_drop _stringappend_1115_ (build_ex _stringappend_1117_) in
+ match (reg_name_matches_prefix _stringappend_1118_) with
+ | Some (_stringappend_1119_,(existT _ _stringappend_1120_ _)) =>
+ returnm ((_stringappend_1119_, build_ex _stringappend_1120_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__9 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1120_ _) := w__9 : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1121_ := string_drop _stringappend_1118_ (build_ex _stringappend_1120_) in
+ sep_matches_prefix _stringappend_1121_ >>= fun w__10 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__10 with
+ | Some (_stringappend_1122_,(existT _ _stringappend_1123_ _)) =>
+ returnm ((_stringappend_1122_, build_ex _stringappend_1123_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__12 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1123_ _) := w__12 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1124_ := string_drop _stringappend_1121_ (build_ex _stringappend_1123_) in
+ match (hex_bits_20_matches_prefix _stringappend_1124_) with
+ | Some (_stringappend_1125_,(existT _ _stringappend_1126_ _)) =>
+ returnm ((_stringappend_1125_, build_ex _stringappend_1126_)
+ : (mword 20 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 20 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__14 : (mword 20 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_1126_ _) :=
+ w__14
+ : (mword 20 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1124_ (build_ex _stringappend_1126_)) with
+ | "" => returnm ((UTYPE (imm,rd,op)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM (returnm ((string_startswith _stringappend_1112_ "jal") : bool))
+ (let _stringappend_1128_ := string_drop _stringappend_1112_ (string_length "jal") in
+ match (spc_matches_prefix _stringappend_1128_) with
+ | Some (_stringappend_1129_,(existT _ _stringappend_1130_ _)) =>
+ let _stringappend_1131_ := string_drop _stringappend_1128_ (build_ex _stringappend_1130_) in
+ match (reg_name_matches_prefix _stringappend_1131_) with
+ | Some (_stringappend_1132_,(existT _ _stringappend_1133_ _)) =>
+ let _stringappend_1134_ :=
+ string_drop _stringappend_1131_ (build_ex _stringappend_1133_) in
+ sep_matches_prefix _stringappend_1134_ >>= fun w__17 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__17 with
+ | Some (_stringappend_1135_,(existT _ _stringappend_1136_ _)) =>
+ let _stringappend_1137_ :=
+ string_drop _stringappend_1134_ (build_ex _stringappend_1136_) in
+ if ((match (hex_bits_21_matches_prefix _stringappend_1137_) with
+ | Some (_stringappend_1138_,(existT _ _stringappend_1139_ _)) =>
+ match (string_drop _stringappend_1137_
+ (build_ex
+ _stringappend_1139_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__18 : bool =>
+ returnm ((if (w__18) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__19 : bool =>
+ returnm ((if (w__19) then true
+ else false)
+ : bool)) >>= fun w__20 : bool =>
+ (if (w__20) then
+ let _stringappend_1128_ := string_drop _stringappend_1112_ (string_length "jal") in
+ match (spc_matches_prefix _stringappend_1128_) with
+ | Some (_stringappend_1129_,(existT _ _stringappend_1130_ _)) =>
+ returnm ((_stringappend_1129_, build_ex _stringappend_1130_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__22 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1130_ _) := w__22 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1131_ := string_drop _stringappend_1128_ (build_ex _stringappend_1130_) in
+ match (reg_name_matches_prefix _stringappend_1131_) with
+ | Some (_stringappend_1132_,(existT _ _stringappend_1133_ _)) =>
+ returnm ((_stringappend_1132_, build_ex _stringappend_1133_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__24 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1133_ _) :=
+ w__24
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1134_ := string_drop _stringappend_1131_ (build_ex _stringappend_1133_) in
+ sep_matches_prefix _stringappend_1134_ >>= fun w__25 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__25 with
+ | Some (_stringappend_1135_,(existT _ _stringappend_1136_ _)) =>
+ returnm ((_stringappend_1135_, build_ex _stringappend_1136_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__27 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1136_ _) := w__27 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1137_ := string_drop _stringappend_1134_ (build_ex _stringappend_1136_) in
+ match (hex_bits_21_matches_prefix _stringappend_1137_) with
+ | Some (_stringappend_1138_,(existT _ _stringappend_1139_ _)) =>
+ returnm ((_stringappend_1138_, build_ex _stringappend_1139_)
+ : (mword 21 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 21 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__29 : (mword 21 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_1139_ _) :=
+ w__29
+ : (mword 21 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1137_ (build_ex _stringappend_1139_)) with
+ | "" => returnm ((RISCV_JAL (imm,rd)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM (returnm ((string_startswith _stringappend_1112_ "jalr") : bool))
+ (let _stringappend_1141_ := string_drop _stringappend_1112_ (string_length "jalr") in
+ match (spc_matches_prefix _stringappend_1141_) with
+ | Some (_stringappend_1142_,(existT _ _stringappend_1143_ _)) =>
+ let _stringappend_1144_ :=
+ string_drop _stringappend_1141_ (build_ex _stringappend_1143_) in
+ match (reg_name_matches_prefix _stringappend_1144_) with
+ | Some (_stringappend_1145_,(existT _ _stringappend_1146_ _)) =>
+ let _stringappend_1147_ :=
+ string_drop _stringappend_1144_ (build_ex _stringappend_1146_) in
+ sep_matches_prefix _stringappend_1147_ >>= fun w__32 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__32 with
+ | Some (_stringappend_1148_,(existT _ _stringappend_1149_ _)) =>
+ let _stringappend_1150_ :=
+ string_drop _stringappend_1147_ (build_ex _stringappend_1149_) in
+ match (reg_name_matches_prefix _stringappend_1150_) with
+ | Some (_stringappend_1151_,(existT _ _stringappend_1152_ _)) =>
+ let _stringappend_1153_ :=
+ string_drop _stringappend_1150_ (build_ex _stringappend_1152_) in
+ sep_matches_prefix _stringappend_1153_ >>= fun w__33 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__33 with
+ | Some (_stringappend_1154_,(existT _ _stringappend_1155_ _)) =>
+ let _stringappend_1156_ :=
+ string_drop _stringappend_1153_
+ (build_ex
+ _stringappend_1155_) in
+ if ((match (hex_bits_12_matches_prefix _stringappend_1156_) with
+ | Some
+ (_stringappend_1157_,(existT _ _stringappend_1158_ _)) =>
+ match (string_drop _stringappend_1156_
+ (build_ex
+ _stringappend_1158_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__34 : bool =>
+ returnm ((if (w__34) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__35 : bool =>
+ returnm ((if (w__35) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__36 : bool =>
+ returnm ((if (w__36) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__37 : bool =>
+ returnm ((if (w__37) then true
+ else false)
+ : bool)) >>= fun w__38 : bool =>
+ (if (w__38) then
+ let _stringappend_1141_ := string_drop _stringappend_1112_ (string_length "jalr") in
+ match (spc_matches_prefix _stringappend_1141_) with
+ | Some (_stringappend_1142_,(existT _ _stringappend_1143_ _)) =>
+ returnm ((_stringappend_1142_, build_ex _stringappend_1143_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__40 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1143_ _) :=
+ w__40
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1144_ :=
+ string_drop _stringappend_1141_ (build_ex _stringappend_1143_) in
+ match (reg_name_matches_prefix _stringappend_1144_) with
+ | Some (_stringappend_1145_,(existT _ _stringappend_1146_ _)) =>
+ returnm ((_stringappend_1145_, build_ex _stringappend_1146_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__42 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1146_ _) :=
+ w__42
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1147_ :=
+ string_drop _stringappend_1144_ (build_ex _stringappend_1146_) in
+ sep_matches_prefix _stringappend_1147_ >>= fun w__43 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__43 with
+ | Some (_stringappend_1148_,(existT _ _stringappend_1149_ _)) =>
+ returnm ((_stringappend_1148_, build_ex _stringappend_1149_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__45 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1149_ _) :=
+ w__45
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1150_ :=
+ string_drop _stringappend_1147_ (build_ex _stringappend_1149_) in
+ match (reg_name_matches_prefix _stringappend_1150_) with
+ | Some (_stringappend_1151_,(existT _ _stringappend_1152_ _)) =>
+ returnm ((_stringappend_1151_, build_ex _stringappend_1152_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__47 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1152_ _) :=
+ w__47
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1153_ :=
+ string_drop _stringappend_1150_ (build_ex _stringappend_1152_) in
+ sep_matches_prefix _stringappend_1153_ >>= fun w__48 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__48 with
+ | Some (_stringappend_1154_,(existT _ _stringappend_1155_ _)) =>
+ returnm ((_stringappend_1154_, build_ex _stringappend_1155_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__50 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1155_ _) :=
+ w__50
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1156_ :=
+ string_drop _stringappend_1153_ (build_ex _stringappend_1155_) in
+ match (hex_bits_12_matches_prefix _stringappend_1156_) with
+ | Some (_stringappend_1157_,(existT _ _stringappend_1158_ _)) =>
+ returnm ((_stringappend_1157_, build_ex _stringappend_1158_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__52 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_1158_ _) :=
+ w__52
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1156_ (build_ex _stringappend_1158_)) with
+ | "" => returnm ((RISCV_JALR (imm,rs1,rd)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ match (btype_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1160_,(existT _ _stringappend_1161_ _)) =>
+ let _stringappend_1162_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1161_) in
+ match (spc_matches_prefix _stringappend_1162_) with
+ | Some (_stringappend_1163_,(existT _ _stringappend_1164_ _)) =>
+ let _stringappend_1165_ :=
+ string_drop _stringappend_1162_ (build_ex _stringappend_1164_) in
+ match (reg_name_matches_prefix _stringappend_1165_) with
+ | Some (_stringappend_1166_,(existT _ _stringappend_1167_ _)) =>
+ let _stringappend_1168_ :=
+ string_drop _stringappend_1165_ (build_ex _stringappend_1167_) in
+ sep_matches_prefix _stringappend_1168_ >>= fun w__55 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__55 with
+ | Some (_stringappend_1169_,(existT _ _stringappend_1170_ _)) =>
+ let _stringappend_1171_ :=
+ string_drop _stringappend_1168_ (build_ex _stringappend_1170_) in
+ match (reg_name_matches_prefix _stringappend_1171_) with
+ | Some (_stringappend_1172_,(existT _ _stringappend_1173_ _)) =>
+ let _stringappend_1174_ :=
+ string_drop _stringappend_1171_ (build_ex _stringappend_1173_) in
+ sep_matches_prefix _stringappend_1174_ >>= fun w__56 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__56 with
+ | Some
+ (_stringappend_1175_,(existT _ _stringappend_1176_ _)) =>
+ let _stringappend_1177_ :=
+ string_drop _stringappend_1174_
+ (build_ex
+ _stringappend_1176_) in
+ if ((match (hex_bits_13_matches_prefix
+ _stringappend_1177_) with
+ | Some
+ (_stringappend_1178_,(existT _ _stringappend_1179_ _)) =>
+ match (string_drop _stringappend_1177_
+ (build_ex
+ _stringappend_1179_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__57 : bool =>
+ returnm ((if (w__57) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__58 : bool =>
+ returnm ((if (w__58) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__59 : bool =>
+ returnm ((if (w__59) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__60 : bool =>
+ returnm ((if (w__60) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__61 : bool =>
+ (if (w__61) then
+ match (btype_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1160_,(existT _ _stringappend_1161_ _)) =>
+ returnm ((_stringappend_1160_, build_ex _stringappend_1161_)
+ : (bop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__63 : (bop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_1161_ _) :=
+ w__63
+ : (bop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1162_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1161_) in
+ match (spc_matches_prefix _stringappend_1162_) with
+ | Some (_stringappend_1163_,(existT _ _stringappend_1164_ _)) =>
+ returnm ((_stringappend_1163_, build_ex _stringappend_1164_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__65 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1164_ _) :=
+ w__65
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1165_ :=
+ string_drop _stringappend_1162_ (build_ex _stringappend_1164_) in
+ match (reg_name_matches_prefix _stringappend_1165_) with
+ | Some (_stringappend_1166_,(existT _ _stringappend_1167_ _)) =>
+ returnm ((_stringappend_1166_, build_ex _stringappend_1167_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__67 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1167_ _) :=
+ w__67
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1168_ :=
+ string_drop _stringappend_1165_ (build_ex _stringappend_1167_) in
+ sep_matches_prefix _stringappend_1168_ >>= fun w__68 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__68 with
+ | Some (_stringappend_1169_,(existT _ _stringappend_1170_ _)) =>
+ returnm ((_stringappend_1169_, build_ex _stringappend_1170_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__70 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1170_ _) :=
+ w__70
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1171_ :=
+ string_drop _stringappend_1168_ (build_ex _stringappend_1170_) in
+ match (reg_name_matches_prefix _stringappend_1171_) with
+ | Some (_stringappend_1172_,(existT _ _stringappend_1173_ _)) =>
+ returnm ((_stringappend_1172_, build_ex _stringappend_1173_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__72 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs2, existT _ _stringappend_1173_ _) :=
+ w__72
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1174_ :=
+ string_drop _stringappend_1171_ (build_ex _stringappend_1173_) in
+ sep_matches_prefix _stringappend_1174_ >>= fun w__73 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__73 with
+ | Some (_stringappend_1175_,(existT _ _stringappend_1176_ _)) =>
+ returnm ((_stringappend_1175_, build_ex _stringappend_1176_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__75 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1176_ _) :=
+ w__75
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1177_ :=
+ string_drop _stringappend_1174_ (build_ex _stringappend_1176_) in
+ match (hex_bits_13_matches_prefix _stringappend_1177_) with
+ | Some (_stringappend_1178_,(existT _ _stringappend_1179_ _)) =>
+ returnm ((_stringappend_1178_, build_ex _stringappend_1179_)
+ : (mword 13 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 13 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__77 : (mword 13 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_1179_ _) :=
+ w__77
+ : (mword 13 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1177_ (build_ex _stringappend_1179_)) with
+ | "" => returnm ((BTYPE (imm,rs2,rs1,op)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ match (itype_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1181_,(existT _ _stringappend_1182_ _)) =>
+ let _stringappend_1183_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1182_) in
+ match (spc_matches_prefix _stringappend_1183_) with
+ | Some (_stringappend_1184_,(existT _ _stringappend_1185_ _)) =>
+ let _stringappend_1186_ :=
+ string_drop _stringappend_1183_ (build_ex _stringappend_1185_) in
+ match (reg_name_matches_prefix _stringappend_1186_) with
+ | Some (_stringappend_1187_,(existT _ _stringappend_1188_ _)) =>
+ let _stringappend_1189_ :=
+ string_drop _stringappend_1186_ (build_ex _stringappend_1188_) in
+ sep_matches_prefix _stringappend_1189_ >>= fun w__80 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__80 with
+ | Some (_stringappend_1190_,(existT _ _stringappend_1191_ _)) =>
+ let _stringappend_1192_ :=
+ string_drop _stringappend_1189_ (build_ex _stringappend_1191_) in
+ match (reg_name_matches_prefix _stringappend_1192_) with
+ | Some (_stringappend_1193_,(existT _ _stringappend_1194_ _)) =>
+ let _stringappend_1195_ :=
+ string_drop _stringappend_1192_ (build_ex _stringappend_1194_) in
+ sep_matches_prefix _stringappend_1195_ >>= fun w__81 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__81 with
+ | Some
+ (_stringappend_1196_,(existT _ _stringappend_1197_ _)) =>
+ let _stringappend_1198_ :=
+ string_drop _stringappend_1195_
+ (build_ex
+ _stringappend_1197_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_1198_) with
+ | Some
+ (_stringappend_1199_,(existT _ _stringappend_1200_ _)) =>
+ match (string_drop _stringappend_1198_
+ (build_ex
+ _stringappend_1200_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__82 : bool =>
+ returnm ((if (w__82) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__83 : bool =>
+ returnm ((if (w__83) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__84 : bool =>
+ returnm ((if (w__84) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__85 : bool =>
+ returnm ((if (w__85) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__86 : bool =>
+ (if (w__86) then
+ match (itype_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1181_,(existT _ _stringappend_1182_ _)) =>
+ returnm ((_stringappend_1181_, build_ex _stringappend_1182_)
+ : (iop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((iop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__88 : (iop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_1182_ _) :=
+ w__88
+ : (iop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1183_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1182_) in
+ match (spc_matches_prefix _stringappend_1183_) with
+ | Some (_stringappend_1184_,(existT _ _stringappend_1185_ _)) =>
+ returnm ((_stringappend_1184_, build_ex _stringappend_1185_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__90 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1185_ _) :=
+ w__90
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1186_ :=
+ string_drop _stringappend_1183_ (build_ex _stringappend_1185_) in
+ match (reg_name_matches_prefix _stringappend_1186_) with
+ | Some (_stringappend_1187_,(existT _ _stringappend_1188_ _)) =>
+ returnm ((_stringappend_1187_, build_ex _stringappend_1188_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__92 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1188_ _) :=
+ w__92
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1189_ :=
+ string_drop _stringappend_1186_ (build_ex _stringappend_1188_) in
+ sep_matches_prefix _stringappend_1189_ >>= fun w__93 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__93 with
+ | Some (_stringappend_1190_,(existT _ _stringappend_1191_ _)) =>
+ returnm ((_stringappend_1190_, build_ex _stringappend_1191_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__95 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1191_ _) :=
+ w__95
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1192_ :=
+ string_drop _stringappend_1189_ (build_ex _stringappend_1191_) in
+ match (reg_name_matches_prefix _stringappend_1192_) with
+ | Some (_stringappend_1193_,(existT _ _stringappend_1194_ _)) =>
+ returnm ((_stringappend_1193_, build_ex _stringappend_1194_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__97 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1194_ _) :=
+ w__97
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1195_ :=
+ string_drop _stringappend_1192_ (build_ex _stringappend_1194_) in
+ sep_matches_prefix _stringappend_1195_ >>= fun w__98 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__98 with
+ | Some (_stringappend_1196_,(existT _ _stringappend_1197_ _)) =>
+ returnm ((_stringappend_1196_, build_ex _stringappend_1197_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__100 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1197_ _) :=
+ w__100
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1198_ :=
+ string_drop _stringappend_1195_ (build_ex _stringappend_1197_) in
+ match (hex_bits_12_matches_prefix _stringappend_1198_) with
+ | Some (_stringappend_1199_,(existT _ _stringappend_1200_ _)) =>
+ returnm ((_stringappend_1199_, build_ex _stringappend_1200_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__102 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_1200_ _) :=
+ w__102
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1198_ (build_ex _stringappend_1200_)) with
+ | "" => returnm ((ITYPE (imm,rs1,rd,op)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ match (shiftiop_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1202_,(existT _ _stringappend_1203_ _)) =>
+ let _stringappend_1204_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1203_) in
+ match (spc_matches_prefix _stringappend_1204_) with
+ | Some (_stringappend_1205_,(existT _ _stringappend_1206_ _)) =>
+ let _stringappend_1207_ :=
+ string_drop _stringappend_1204_ (build_ex _stringappend_1206_) in
+ match (reg_name_matches_prefix _stringappend_1207_) with
+ | Some (_stringappend_1208_,(existT _ _stringappend_1209_ _)) =>
+ let _stringappend_1210_ :=
+ string_drop _stringappend_1207_ (build_ex _stringappend_1209_) in
+ sep_matches_prefix _stringappend_1210_ >>= fun w__105 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__105 with
+ | Some
+ (_stringappend_1211_,(existT _ _stringappend_1212_ _)) =>
+ let _stringappend_1213_ :=
+ string_drop _stringappend_1210_
+ (build_ex
+ _stringappend_1212_) in
+ if ((match (reg_name_matches_prefix _stringappend_1213_) with
+ | Some
+ (_stringappend_1214_,(existT _ _stringappend_1215_ _)) =>
+ let _stringappend_1216_ :=
+ string_drop _stringappend_1213_
+ (build_ex
+ _stringappend_1215_) in
+ if ((match (hex_bits_6_matches_prefix
+ _stringappend_1216_) with
+ | Some
+ (_stringappend_1217_,(existT _ _stringappend_1218_ _)) =>
+ match (string_drop _stringappend_1216_
+ (build_ex
+ _stringappend_1218_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__106 : bool =>
+ returnm ((if (w__106) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__107 : bool =>
+ returnm ((if (w__107) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__108 : bool =>
+ (if (w__108) then
+ match (shiftiop_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1202_,(existT _ _stringappend_1203_ _)) =>
+ returnm ((_stringappend_1202_, build_ex _stringappend_1203_)
+ : (sop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((sop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__110 : (sop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_1203_ _) :=
+ w__110
+ : (sop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1204_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1203_) in
+ match (spc_matches_prefix _stringappend_1204_) with
+ | Some (_stringappend_1205_,(existT _ _stringappend_1206_ _)) =>
+ returnm ((_stringappend_1205_, build_ex _stringappend_1206_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__112 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1206_ _) :=
+ w__112
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1207_ :=
+ string_drop _stringappend_1204_ (build_ex _stringappend_1206_) in
+ match (reg_name_matches_prefix _stringappend_1207_) with
+ | Some (_stringappend_1208_,(existT _ _stringappend_1209_ _)) =>
+ returnm ((_stringappend_1208_, build_ex _stringappend_1209_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__114 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1209_ _) :=
+ w__114
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1210_ :=
+ string_drop _stringappend_1207_ (build_ex _stringappend_1209_) in
+ sep_matches_prefix _stringappend_1210_ >>= fun w__115 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__115 with
+ | Some (_stringappend_1211_,(existT _ _stringappend_1212_ _)) =>
+ returnm ((_stringappend_1211_, build_ex _stringappend_1212_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__117 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1212_ _) :=
+ w__117
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1213_ :=
+ string_drop _stringappend_1210_ (build_ex _stringappend_1212_) in
+ match (reg_name_matches_prefix _stringappend_1213_) with
+ | Some (_stringappend_1214_,(existT _ _stringappend_1215_ _)) =>
+ returnm ((_stringappend_1214_, build_ex _stringappend_1215_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__119 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1215_ _) :=
+ w__119
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1216_ :=
+ string_drop _stringappend_1213_ (build_ex _stringappend_1215_) in
+ match (hex_bits_6_matches_prefix _stringappend_1216_) with
+ | Some (_stringappend_1217_,(existT _ _stringappend_1218_ _)) =>
+ returnm ((_stringappend_1217_, build_ex _stringappend_1218_)
+ : (mword 6 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 6 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__121 : (mword 6 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(shamt, existT _ _stringappend_1218_ _) :=
+ w__121
+ : (mword 6 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1216_ (build_ex _stringappend_1218_)) with
+ | "" => returnm ((SHIFTIOP (shamt,rs1,rd,op)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ match (rtype_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1220_,(existT _ _stringappend_1221_ _)) =>
+ let _stringappend_1222_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1221_) in
+ match (spc_matches_prefix _stringappend_1222_) with
+ | Some (_stringappend_1223_,(existT _ _stringappend_1224_ _)) =>
+ let _stringappend_1225_ :=
+ string_drop _stringappend_1222_ (build_ex _stringappend_1224_) in
+ match (reg_name_matches_prefix _stringappend_1225_) with
+ | Some (_stringappend_1226_,(existT _ _stringappend_1227_ _)) =>
+ let _stringappend_1228_ :=
+ string_drop _stringappend_1225_ (build_ex _stringappend_1227_) in
+ sep_matches_prefix _stringappend_1228_ >>= fun w__124 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__124 with
+ | Some (_stringappend_1229_,(existT _ _stringappend_1230_ _)) =>
+ let _stringappend_1231_ :=
+ string_drop _stringappend_1228_ (build_ex _stringappend_1230_) in
+ match (reg_name_matches_prefix _stringappend_1231_) with
+ | Some (_stringappend_1232_,(existT _ _stringappend_1233_ _)) =>
+ let _stringappend_1234_ :=
+ string_drop _stringappend_1231_ (build_ex _stringappend_1233_) in
+ sep_matches_prefix _stringappend_1234_ >>= fun w__125 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__125 with
+ | Some
+ (_stringappend_1235_,(existT _ _stringappend_1236_ _)) =>
+ let _stringappend_1237_ :=
+ string_drop _stringappend_1234_
+ (build_ex
+ _stringappend_1236_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1237_) with
+ | Some
+ (_stringappend_1238_,(existT _ _stringappend_1239_ _)) =>
+ match (string_drop _stringappend_1237_
+ (build_ex
+ _stringappend_1239_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__126 : bool =>
+ returnm ((if (w__126) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__127 : bool =>
+ returnm ((if (w__127) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__128 : bool =>
+ returnm ((if (w__128) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__129 : bool =>
+ returnm ((if (w__129) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__130 : bool =>
+ (if (w__130) then
+ match (rtype_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1220_,(existT _ _stringappend_1221_ _)) =>
+ returnm ((_stringappend_1220_, build_ex _stringappend_1221_)
+ : (rop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((rop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__132 : (rop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_1221_ _) :=
+ w__132
+ : (rop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1222_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1221_) in
+ match (spc_matches_prefix _stringappend_1222_) with
+ | Some (_stringappend_1223_,(existT _ _stringappend_1224_ _)) =>
+ returnm ((_stringappend_1223_, build_ex _stringappend_1224_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__134 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1224_ _) :=
+ w__134
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1225_ :=
+ string_drop _stringappend_1222_ (build_ex _stringappend_1224_) in
+ match (reg_name_matches_prefix _stringappend_1225_) with
+ | Some (_stringappend_1226_,(existT _ _stringappend_1227_ _)) =>
+ returnm ((_stringappend_1226_, build_ex _stringappend_1227_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__136 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1227_ _) :=
+ w__136
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1228_ :=
+ string_drop _stringappend_1225_ (build_ex _stringappend_1227_) in
+ sep_matches_prefix _stringappend_1228_ >>= fun w__137 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__137 with
+ | Some (_stringappend_1229_,(existT _ _stringappend_1230_ _)) =>
+ returnm ((_stringappend_1229_, build_ex _stringappend_1230_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__139 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1230_ _) :=
+ w__139
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1231_ :=
+ string_drop _stringappend_1228_ (build_ex _stringappend_1230_) in
+ match (reg_name_matches_prefix _stringappend_1231_) with
+ | Some (_stringappend_1232_,(existT _ _stringappend_1233_ _)) =>
+ returnm ((_stringappend_1232_, build_ex _stringappend_1233_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__141 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1233_ _) :=
+ w__141
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1234_ :=
+ string_drop _stringappend_1231_ (build_ex _stringappend_1233_) in
+ sep_matches_prefix _stringappend_1234_ >>= fun w__142 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__142 with
+ | Some (_stringappend_1235_,(existT _ _stringappend_1236_ _)) =>
+ returnm ((_stringappend_1235_, build_ex _stringappend_1236_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__144 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1236_ _) :=
+ w__144
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1237_ :=
+ string_drop _stringappend_1234_ (build_ex _stringappend_1236_) in
+ match (reg_name_matches_prefix _stringappend_1237_) with
+ | Some (_stringappend_1238_,(existT _ _stringappend_1239_ _)) =>
+ returnm ((_stringappend_1238_, build_ex _stringappend_1239_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__146 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs2, existT _ _stringappend_1239_ _) :=
+ w__146
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1237_ (build_ex _stringappend_1239_)) with
+ | "" => returnm ((RTYPE (rs2,rs1,rd,op)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM (returnm ((string_startswith _stringappend_1112_ "l") : bool))
+ (let _stringappend_1241_ :=
+ string_drop _stringappend_1112_ (string_length "l") in
+ match (size_mnemonic_matches_prefix _stringappend_1241_) with
+ | Some (_stringappend_1242_,(existT _ _stringappend_1243_ _)) =>
+ let _stringappend_1244_ :=
+ string_drop _stringappend_1241_ (build_ex _stringappend_1243_) in
+ match (maybe_u_matches_prefix _stringappend_1244_) with
+ | Some (_stringappend_1245_,(existT _ _stringappend_1246_ _)) =>
+ let _stringappend_1247_ :=
+ string_drop _stringappend_1244_ (build_ex _stringappend_1246_) in
+ match (maybe_aq_matches_prefix _stringappend_1247_) with
+ | Some (_stringappend_1248_,(existT _ _stringappend_1249_ _)) =>
+ let _stringappend_1250_ :=
+ string_drop _stringappend_1247_ (build_ex _stringappend_1249_) in
+ match (maybe_rl_matches_prefix _stringappend_1250_) with
+ | Some (_stringappend_1251_,(existT _ _stringappend_1252_ _)) =>
+ let _stringappend_1253_ :=
+ string_drop _stringappend_1250_
+ (build_ex
+ _stringappend_1252_) in
+ match (spc_matches_prefix _stringappend_1253_) with
+ | Some (_stringappend_1254_,(existT _ _stringappend_1255_ _)) =>
+ let _stringappend_1256_ :=
+ string_drop _stringappend_1253_
+ (build_ex
+ _stringappend_1255_) in
+ match (reg_name_matches_prefix _stringappend_1256_) with
+ | Some
+ (_stringappend_1257_,(existT _ _stringappend_1258_ _)) =>
+ let _stringappend_1259_ :=
+ string_drop _stringappend_1256_
+ (build_ex
+ _stringappend_1258_) in
+ sep_matches_prefix _stringappend_1259_ >>= fun w__149 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__149 with
+ | Some
+ (_stringappend_1260_,(existT _ _stringappend_1261_ _)) =>
+ let _stringappend_1262_ :=
+ string_drop _stringappend_1259_
+ (build_ex
+ _stringappend_1261_) in
+ match (reg_name_matches_prefix _stringappend_1262_) with
+ | Some
+ (_stringappend_1263_,(existT _ _stringappend_1264_ _)) =>
+ let _stringappend_1265_ :=
+ string_drop _stringappend_1262_
+ (build_ex
+ _stringappend_1264_) in
+ sep_matches_prefix _stringappend_1265_ >>= fun w__150 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__150 with
+ | Some
+ (_stringappend_1266_,(existT _ _stringappend_1267_ _)) =>
+ let _stringappend_1268_ :=
+ string_drop
+ _stringappend_1265_
+ (build_ex
+ _stringappend_1267_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_1268_) with
+ | Some
+ (_stringappend_1269_,(existT _ _stringappend_1270_ _)) =>
+ match (string_drop
+ _stringappend_1268_
+ (build_ex
+ _stringappend_1270_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__151 : bool =>
+ returnm ((if (w__151) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__152 : bool =>
+ returnm ((if (w__152) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__153 : bool =>
+ returnm ((if (w__153) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__154 : bool =>
+ returnm ((if (w__154) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__155 : bool =>
+ returnm ((if (w__155) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__156 : bool =>
+ returnm ((if (w__156) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__157 : bool =>
+ returnm ((if (w__157) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__158 : bool =>
+ returnm ((if (w__158) then true
+ else false)
+ : bool)) >>= fun w__159 : bool =>
+ (if (w__159) then
+ let _stringappend_1241_ :=
+ string_drop _stringappend_1112_ (string_length "l") in
+ match (size_mnemonic_matches_prefix _stringappend_1241_) with
+ | Some (_stringappend_1242_,(existT _ _stringappend_1243_ _)) =>
+ returnm ((_stringappend_1242_, build_ex _stringappend_1243_)
+ : (word_width * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((word_width * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__161 : (word_width * {n : Z & ArithFact (n >= 0)}) =>
+ let '(size, existT _ _stringappend_1243_ _) :=
+ w__161
+ : (word_width * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1244_ :=
+ string_drop _stringappend_1241_ (build_ex _stringappend_1243_) in
+ match (maybe_u_matches_prefix _stringappend_1244_) with
+ | Some (_stringappend_1245_,(existT _ _stringappend_1246_ _)) =>
+ returnm ((_stringappend_1245_, build_ex _stringappend_1246_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__163 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(is_unsigned, existT _ _stringappend_1246_ _) :=
+ w__163
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1247_ :=
+ string_drop _stringappend_1244_ (build_ex _stringappend_1246_) in
+ match (maybe_aq_matches_prefix _stringappend_1247_) with
+ | Some (_stringappend_1248_,(existT _ _stringappend_1249_ _)) =>
+ returnm ((_stringappend_1248_, build_ex _stringappend_1249_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__165 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(aq, existT _ _stringappend_1249_ _) :=
+ w__165
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1250_ :=
+ string_drop _stringappend_1247_ (build_ex _stringappend_1249_) in
+ match (maybe_rl_matches_prefix _stringappend_1250_) with
+ | Some (_stringappend_1251_,(existT _ _stringappend_1252_ _)) =>
+ returnm ((_stringappend_1251_, build_ex _stringappend_1252_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__167 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rl, existT _ _stringappend_1252_ _) :=
+ w__167
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1253_ :=
+ string_drop _stringappend_1250_ (build_ex _stringappend_1252_) in
+ match (spc_matches_prefix _stringappend_1253_) with
+ | Some (_stringappend_1254_,(existT _ _stringappend_1255_ _)) =>
+ returnm ((_stringappend_1254_, build_ex _stringappend_1255_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__169 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1255_ _) :=
+ w__169
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1256_ :=
+ string_drop _stringappend_1253_ (build_ex _stringappend_1255_) in
+ match (reg_name_matches_prefix _stringappend_1256_) with
+ | Some (_stringappend_1257_,(existT _ _stringappend_1258_ _)) =>
+ returnm ((_stringappend_1257_, build_ex _stringappend_1258_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__171 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1258_ _) :=
+ w__171
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1259_ :=
+ string_drop _stringappend_1256_ (build_ex _stringappend_1258_) in
+ sep_matches_prefix _stringappend_1259_ >>= fun w__172 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__172 with
+ | Some (_stringappend_1260_,(existT _ _stringappend_1261_ _)) =>
+ returnm ((_stringappend_1260_, build_ex _stringappend_1261_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__174 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1261_ _) :=
+ w__174
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1262_ :=
+ string_drop _stringappend_1259_ (build_ex _stringappend_1261_) in
+ match (reg_name_matches_prefix _stringappend_1262_) with
+ | Some (_stringappend_1263_,(existT _ _stringappend_1264_ _)) =>
+ returnm ((_stringappend_1263_, build_ex _stringappend_1264_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__176 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1264_ _) :=
+ w__176
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1265_ :=
+ string_drop _stringappend_1262_ (build_ex _stringappend_1264_) in
+ sep_matches_prefix _stringappend_1265_ >>= fun w__177 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__177 with
+ | Some (_stringappend_1266_,(existT _ _stringappend_1267_ _)) =>
+ returnm ((_stringappend_1266_, build_ex _stringappend_1267_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__179 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1267_ _) :=
+ w__179
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1268_ :=
+ string_drop _stringappend_1265_ (build_ex _stringappend_1267_) in
+ match (hex_bits_12_matches_prefix _stringappend_1268_) with
+ | Some (_stringappend_1269_,(existT _ _stringappend_1270_ _)) =>
+ returnm ((_stringappend_1269_, build_ex _stringappend_1270_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__181 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_1270_ _) :=
+ w__181
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1268_ (build_ex _stringappend_1270_)) with
+ | "" => returnm ((LOAD (imm,rs1,rd,is_unsigned,size,aq,rl)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM (returnm ((string_startswith _stringappend_1112_ "s") : bool))
+ (let _stringappend_1272_ :=
+ string_drop _stringappend_1112_ (string_length "s") in
+ match (size_mnemonic_matches_prefix _stringappend_1272_) with
+ | Some (_stringappend_1273_,(existT _ _stringappend_1274_ _)) =>
+ let _stringappend_1275_ :=
+ string_drop _stringappend_1272_ (build_ex _stringappend_1274_) in
+ match (maybe_aq_matches_prefix _stringappend_1275_) with
+ | Some (_stringappend_1276_,(existT _ _stringappend_1277_ _)) =>
+ let _stringappend_1278_ :=
+ string_drop _stringappend_1275_ (build_ex _stringappend_1277_) in
+ match (maybe_rl_matches_prefix _stringappend_1278_) with
+ | Some (_stringappend_1279_,(existT _ _stringappend_1280_ _)) =>
+ let _stringappend_1281_ :=
+ string_drop _stringappend_1278_
+ (build_ex
+ _stringappend_1280_) in
+ match (spc_matches_prefix _stringappend_1281_) with
+ | Some (_stringappend_1282_,(existT _ _stringappend_1283_ _)) =>
+ let _stringappend_1284_ :=
+ string_drop _stringappend_1281_
+ (build_ex
+ _stringappend_1283_) in
+ match (reg_name_matches_prefix _stringappend_1284_) with
+ | Some
+ (_stringappend_1285_,(existT _ _stringappend_1286_ _)) =>
+ let _stringappend_1287_ :=
+ string_drop _stringappend_1284_
+ (build_ex
+ _stringappend_1286_) in
+ sep_matches_prefix _stringappend_1287_ >>= fun w__184 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__184 with
+ | Some
+ (_stringappend_1288_,(existT _ _stringappend_1289_ _)) =>
+ let _stringappend_1290_ :=
+ string_drop _stringappend_1287_
+ (build_ex
+ _stringappend_1289_) in
+ match (reg_name_matches_prefix _stringappend_1290_) with
+ | Some
+ (_stringappend_1291_,(existT _ _stringappend_1292_ _)) =>
+ let _stringappend_1293_ :=
+ string_drop _stringappend_1290_
+ (build_ex
+ _stringappend_1292_) in
+ sep_matches_prefix _stringappend_1293_ >>= fun w__185 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__185 with
+ | Some
+ (_stringappend_1294_,(existT _ _stringappend_1295_ _)) =>
+ let _stringappend_1296_ :=
+ string_drop
+ _stringappend_1293_
+ (build_ex
+ _stringappend_1295_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_1296_) with
+ | Some
+ (_stringappend_1297_,(existT _ _stringappend_1298_ _)) =>
+ match (string_drop
+ _stringappend_1296_
+ (build_ex
+ _stringappend_1298_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__186 : bool =>
+ returnm ((if (w__186) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__187 : bool =>
+ returnm ((if (w__187) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__188 : bool =>
+ returnm ((if (w__188) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__189 : bool =>
+ returnm ((if (w__189) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__190 : bool =>
+ returnm ((if (w__190) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__191 : bool =>
+ returnm ((if (w__191) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__192 : bool =>
+ returnm ((if (w__192) then true
+ else false)
+ : bool)) >>= fun w__193 : bool =>
+ (if (w__193) then
+ let _stringappend_1272_ :=
+ string_drop _stringappend_1112_ (string_length "s") in
+ match (size_mnemonic_matches_prefix _stringappend_1272_) with
+ | Some (_stringappend_1273_,(existT _ _stringappend_1274_ _)) =>
+ returnm ((_stringappend_1273_, build_ex _stringappend_1274_)
+ : (word_width * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((word_width * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__195 : (word_width * {n : Z & ArithFact (n >= 0)}) =>
+ let '(size, existT _ _stringappend_1274_ _) :=
+ w__195
+ : (word_width * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1275_ :=
+ string_drop _stringappend_1272_ (build_ex _stringappend_1274_) in
+ match (maybe_aq_matches_prefix _stringappend_1275_) with
+ | Some (_stringappend_1276_,(existT _ _stringappend_1277_ _)) =>
+ returnm ((_stringappend_1276_, build_ex _stringappend_1277_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__197 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(aq, existT _ _stringappend_1277_ _) :=
+ w__197
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1278_ :=
+ string_drop _stringappend_1275_ (build_ex _stringappend_1277_) in
+ match (maybe_rl_matches_prefix _stringappend_1278_) with
+ | Some (_stringappend_1279_,(existT _ _stringappend_1280_ _)) =>
+ returnm ((_stringappend_1279_, build_ex _stringappend_1280_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__199 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rl, existT _ _stringappend_1280_ _) :=
+ w__199
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1281_ :=
+ string_drop _stringappend_1278_ (build_ex _stringappend_1280_) in
+ match (spc_matches_prefix _stringappend_1281_) with
+ | Some (_stringappend_1282_,(existT _ _stringappend_1283_ _)) =>
+ returnm ((_stringappend_1282_, build_ex _stringappend_1283_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__201 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1283_ _) :=
+ w__201
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1284_ :=
+ string_drop _stringappend_1281_ (build_ex _stringappend_1283_) in
+ match (reg_name_matches_prefix _stringappend_1284_) with
+ | Some (_stringappend_1285_,(existT _ _stringappend_1286_ _)) =>
+ returnm ((_stringappend_1285_, build_ex _stringappend_1286_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__203 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1286_ _) :=
+ w__203
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1287_ :=
+ string_drop _stringappend_1284_ (build_ex _stringappend_1286_) in
+ sep_matches_prefix _stringappend_1287_ >>= fun w__204 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__204 with
+ | Some (_stringappend_1288_,(existT _ _stringappend_1289_ _)) =>
+ returnm ((_stringappend_1288_, build_ex _stringappend_1289_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__206 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1289_ _) :=
+ w__206
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1290_ :=
+ string_drop _stringappend_1287_ (build_ex _stringappend_1289_) in
+ match (reg_name_matches_prefix _stringappend_1290_) with
+ | Some (_stringappend_1291_,(existT _ _stringappend_1292_ _)) =>
+ returnm ((_stringappend_1291_, build_ex _stringappend_1292_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__208 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1292_ _) :=
+ w__208
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1293_ :=
+ string_drop _stringappend_1290_ (build_ex _stringappend_1292_) in
+ sep_matches_prefix _stringappend_1293_ >>= fun w__209 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__209 with
+ | Some (_stringappend_1294_,(existT _ _stringappend_1295_ _)) =>
+ returnm ((_stringappend_1294_, build_ex _stringappend_1295_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__211 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1295_ _) :=
+ w__211
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1296_ :=
+ string_drop _stringappend_1293_ (build_ex _stringappend_1295_) in
+ match (hex_bits_12_matches_prefix _stringappend_1296_) with
+ | Some (_stringappend_1297_,(existT _ _stringappend_1298_ _)) =>
+ returnm ((_stringappend_1297_, build_ex _stringappend_1298_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__213 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_1298_ _) :=
+ w__213
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1296_ (build_ex _stringappend_1298_)) with
+ | "" => returnm ((STORE (imm,rs1,rd,size,aq,rl)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_1112_ "addiw")
+ : bool))
+ (let _stringappend_1300_ :=
+ string_drop _stringappend_1112_ (string_length "addiw") in
+ match (spc_matches_prefix _stringappend_1300_) with
+ | Some (_stringappend_1301_,(existT _ _stringappend_1302_ _)) =>
+ let _stringappend_1303_ :=
+ string_drop _stringappend_1300_ (build_ex _stringappend_1302_) in
+ match (reg_name_matches_prefix _stringappend_1303_) with
+ | Some (_stringappend_1304_,(existT _ _stringappend_1305_ _)) =>
+ let _stringappend_1306_ :=
+ string_drop _stringappend_1303_
+ (build_ex
+ _stringappend_1305_) in
+ sep_matches_prefix _stringappend_1306_ >>= fun w__216 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__216 with
+ | Some (_stringappend_1307_,(existT _ _stringappend_1308_ _)) =>
+ let _stringappend_1309_ :=
+ string_drop _stringappend_1306_
+ (build_ex
+ _stringappend_1308_) in
+ match (reg_name_matches_prefix _stringappend_1309_) with
+ | Some
+ (_stringappend_1310_,(existT _ _stringappend_1311_ _)) =>
+ let _stringappend_1312_ :=
+ string_drop _stringappend_1309_
+ (build_ex
+ _stringappend_1311_) in
+ sep_matches_prefix _stringappend_1312_ >>= fun w__217 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__217 with
+ | Some
+ (_stringappend_1313_,(existT _ _stringappend_1314_ _)) =>
+ let _stringappend_1315_ :=
+ string_drop _stringappend_1312_
+ (build_ex
+ _stringappend_1314_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_1315_) with
+ | Some
+ (_stringappend_1316_,(existT _ _stringappend_1317_ _)) =>
+ match (string_drop
+ _stringappend_1315_
+ (build_ex
+ _stringappend_1317_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__218 : bool =>
+ returnm ((if (w__218) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__219 : bool =>
+ returnm ((if (w__219) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__220 : bool =>
+ returnm ((if (w__220) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__221 : bool =>
+ returnm ((if (w__221) then true
+ else false)
+ : bool)) >>= fun w__222 : bool =>
+ (if (w__222) then
+ let _stringappend_1300_ :=
+ string_drop _stringappend_1112_ (string_length "addiw") in
+ match (spc_matches_prefix _stringappend_1300_) with
+ | Some (_stringappend_1301_,(existT _ _stringappend_1302_ _)) =>
+ returnm ((_stringappend_1301_, build_ex _stringappend_1302_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__224 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1302_ _) :=
+ w__224
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1303_ :=
+ string_drop _stringappend_1300_ (build_ex _stringappend_1302_) in
+ match (reg_name_matches_prefix _stringappend_1303_) with
+ | Some (_stringappend_1304_,(existT _ _stringappend_1305_ _)) =>
+ returnm ((_stringappend_1304_, build_ex _stringappend_1305_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__226 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1305_ _) :=
+ w__226
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1306_ :=
+ string_drop _stringappend_1303_ (build_ex _stringappend_1305_) in
+ sep_matches_prefix _stringappend_1306_ >>= fun w__227 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__227 with
+ | Some (_stringappend_1307_,(existT _ _stringappend_1308_ _)) =>
+ returnm ((_stringappend_1307_, build_ex _stringappend_1308_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__229 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1308_ _) :=
+ w__229
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1309_ :=
+ string_drop _stringappend_1306_ (build_ex _stringappend_1308_) in
+ match (reg_name_matches_prefix _stringappend_1309_) with
+ | Some (_stringappend_1310_,(existT _ _stringappend_1311_ _)) =>
+ returnm ((_stringappend_1310_, build_ex _stringappend_1311_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__231 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1311_ _) :=
+ w__231
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1312_ :=
+ string_drop _stringappend_1309_ (build_ex _stringappend_1311_) in
+ sep_matches_prefix _stringappend_1312_ >>= fun w__232 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__232 with
+ | Some (_stringappend_1313_,(existT _ _stringappend_1314_ _)) =>
+ returnm ((_stringappend_1313_, build_ex _stringappend_1314_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__234 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1314_ _) :=
+ w__234
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1315_ :=
+ string_drop _stringappend_1312_ (build_ex _stringappend_1314_) in
+ match (hex_bits_12_matches_prefix _stringappend_1315_) with
+ | Some (_stringappend_1316_,(existT _ _stringappend_1317_ _)) =>
+ returnm ((_stringappend_1316_, build_ex _stringappend_1317_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__236 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_1317_ _) :=
+ w__236
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1315_
+ (build_ex
+ _stringappend_1317_)) with
+ | "" => returnm ((ADDIW (imm,rs1,rd)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ match (shiftw_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1319_,(existT _ _stringappend_1320_ _)) =>
+ let _stringappend_1321_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1320_) in
+ match (spc_matches_prefix _stringappend_1321_) with
+ | Some (_stringappend_1322_,(existT _ _stringappend_1323_ _)) =>
+ let _stringappend_1324_ :=
+ string_drop _stringappend_1321_
+ (build_ex
+ _stringappend_1323_) in
+ match (reg_name_matches_prefix _stringappend_1324_) with
+ | Some (_stringappend_1325_,(existT _ _stringappend_1326_ _)) =>
+ let _stringappend_1327_ :=
+ string_drop _stringappend_1324_
+ (build_ex
+ _stringappend_1326_) in
+ sep_matches_prefix _stringappend_1327_ >>= fun w__239 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__239 with
+ | Some
+ (_stringappend_1328_,(existT _ _stringappend_1329_ _)) =>
+ let _stringappend_1330_ :=
+ string_drop _stringappend_1327_
+ (build_ex
+ _stringappend_1329_) in
+ match (reg_name_matches_prefix _stringappend_1330_) with
+ | Some
+ (_stringappend_1331_,(existT _ _stringappend_1332_ _)) =>
+ let _stringappend_1333_ :=
+ string_drop _stringappend_1330_
+ (build_ex
+ _stringappend_1332_) in
+ sep_matches_prefix _stringappend_1333_ >>= fun w__240 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__240 with
+ | Some
+ (_stringappend_1334_,(existT _ _stringappend_1335_ _)) =>
+ let _stringappend_1336_ :=
+ string_drop _stringappend_1333_
+ (build_ex
+ _stringappend_1335_) in
+ if ((match (hex_bits_5_matches_prefix
+ _stringappend_1336_) with
+ | Some
+ (_stringappend_1337_,(existT _ _stringappend_1338_ _)) =>
+ match (string_drop
+ _stringappend_1336_
+ (build_ex
+ _stringappend_1338_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__241 : bool =>
+ returnm ((if (w__241) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__242 : bool =>
+ returnm ((if (w__242) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__243 : bool =>
+ returnm ((if (w__243) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__244 : bool =>
+ returnm ((if (w__244) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__245 : bool =>
+ (if (w__245) then
+ match (shiftw_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1319_,(existT _ _stringappend_1320_ _)) =>
+ returnm ((_stringappend_1319_, build_ex _stringappend_1320_)
+ : (sop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((sop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__247 : (sop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_1320_ _) :=
+ w__247
+ : (sop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1321_ :=
+ string_drop _stringappend_1112_ (build_ex _stringappend_1320_) in
+ match (spc_matches_prefix _stringappend_1321_) with
+ | Some (_stringappend_1322_,(existT _ _stringappend_1323_ _)) =>
+ returnm ((_stringappend_1322_, build_ex _stringappend_1323_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__249 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1323_ _) :=
+ w__249
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1324_ :=
+ string_drop _stringappend_1321_ (build_ex _stringappend_1323_) in
+ match (reg_name_matches_prefix _stringappend_1324_) with
+ | Some (_stringappend_1325_,(existT _ _stringappend_1326_ _)) =>
+ returnm ((_stringappend_1325_, build_ex _stringappend_1326_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__251 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1326_ _) :=
+ w__251
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1327_ :=
+ string_drop _stringappend_1324_ (build_ex _stringappend_1326_) in
+ sep_matches_prefix _stringappend_1327_ >>= fun w__252 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__252 with
+ | Some (_stringappend_1328_,(existT _ _stringappend_1329_ _)) =>
+ returnm ((_stringappend_1328_, build_ex _stringappend_1329_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__254 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1329_ _) :=
+ w__254
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1330_ :=
+ string_drop _stringappend_1327_ (build_ex _stringappend_1329_) in
+ match (reg_name_matches_prefix _stringappend_1330_) with
+ | Some (_stringappend_1331_,(existT _ _stringappend_1332_ _)) =>
+ returnm ((_stringappend_1331_, build_ex _stringappend_1332_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__256 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1332_ _) :=
+ w__256
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1333_ :=
+ string_drop _stringappend_1330_ (build_ex _stringappend_1332_) in
+ sep_matches_prefix _stringappend_1333_ >>= fun w__257 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__257 with
+ | Some (_stringappend_1334_,(existT _ _stringappend_1335_ _)) =>
+ returnm ((_stringappend_1334_, build_ex _stringappend_1335_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__259 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1335_ _) :=
+ w__259
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1336_ :=
+ string_drop _stringappend_1333_ (build_ex _stringappend_1335_) in
+ match (hex_bits_5_matches_prefix _stringappend_1336_) with
+ | Some (_stringappend_1337_,(existT _ _stringappend_1338_ _)) =>
+ returnm ((_stringappend_1337_, build_ex _stringappend_1338_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__261 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(shamt, existT _ _stringappend_1338_ _) :=
+ w__261
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1336_
+ (build_ex
+ _stringappend_1338_)) with
+ | "" => returnm ((SHIFTW (shamt,rs1,rd,op)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ match (rtypew_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1340_,(existT _ _stringappend_1341_ _)) =>
+ let _stringappend_1342_ :=
+ string_drop _stringappend_1112_
+ (build_ex
+ _stringappend_1341_) in
+ match (spc_matches_prefix _stringappend_1342_) with
+ | Some (_stringappend_1343_,(existT _ _stringappend_1344_ _)) =>
+ let _stringappend_1345_ :=
+ string_drop _stringappend_1342_
+ (build_ex
+ _stringappend_1344_) in
+ match (reg_name_matches_prefix _stringappend_1345_) with
+ | Some
+ (_stringappend_1346_,(existT _ _stringappend_1347_ _)) =>
+ let _stringappend_1348_ :=
+ string_drop _stringappend_1345_
+ (build_ex
+ _stringappend_1347_) in
+ sep_matches_prefix _stringappend_1348_ >>= fun w__264 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__264 with
+ | Some
+ (_stringappend_1349_,(existT _ _stringappend_1350_ _)) =>
+ let _stringappend_1351_ :=
+ string_drop _stringappend_1348_
+ (build_ex
+ _stringappend_1350_) in
+ match (reg_name_matches_prefix _stringappend_1351_) with
+ | Some
+ (_stringappend_1352_,(existT _ _stringappend_1353_ _)) =>
+ let _stringappend_1354_ :=
+ string_drop _stringappend_1351_
+ (build_ex
+ _stringappend_1353_) in
+ sep_matches_prefix _stringappend_1354_ >>= fun w__265 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__265 with
+ | Some
+ (_stringappend_1355_,(existT _ _stringappend_1356_ _)) =>
+ let _stringappend_1357_ :=
+ string_drop
+ _stringappend_1354_
+ (build_ex
+ _stringappend_1356_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1357_) with
+ | Some
+ (_stringappend_1358_,(existT _ _stringappend_1359_ _)) =>
+ match (string_drop
+ _stringappend_1357_
+ (build_ex
+ _stringappend_1359_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__266 : bool =>
+ returnm ((if (w__266) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__267 : bool =>
+ returnm ((if (w__267) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__268 : bool =>
+ returnm ((if (w__268) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__269 : bool =>
+ returnm ((if (w__269) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__270 : bool =>
+ (if (w__270) then
+ match (rtypew_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1340_,(existT _ _stringappend_1341_ _)) =>
+ returnm ((_stringappend_1340_,
+ build_ex
+ _stringappend_1341_)
+ : (ropw * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((ropw * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__272 : (ropw * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_1341_ _) :=
+ w__272
+ : (ropw * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1342_ :=
+ string_drop _stringappend_1112_
+ (build_ex
+ _stringappend_1341_) in
+ match (spc_matches_prefix _stringappend_1342_) with
+ | Some (_stringappend_1343_,(existT _ _stringappend_1344_ _)) =>
+ returnm ((_stringappend_1343_,
+ build_ex
+ _stringappend_1344_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__274 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1344_ _) :=
+ w__274
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1345_ :=
+ string_drop _stringappend_1342_
+ (build_ex
+ _stringappend_1344_) in
+ match (reg_name_matches_prefix _stringappend_1345_) with
+ | Some (_stringappend_1346_,(existT _ _stringappend_1347_ _)) =>
+ returnm ((_stringappend_1346_,
+ build_ex
+ _stringappend_1347_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__276 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1347_ _) :=
+ w__276
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1348_ :=
+ string_drop _stringappend_1345_
+ (build_ex
+ _stringappend_1347_) in
+ sep_matches_prefix _stringappend_1348_ >>= fun w__277 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__277 with
+ | Some (_stringappend_1349_,(existT _ _stringappend_1350_ _)) =>
+ returnm ((_stringappend_1349_,
+ build_ex
+ _stringappend_1350_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__279 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1350_ _) :=
+ w__279
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1351_ :=
+ string_drop _stringappend_1348_
+ (build_ex
+ _stringappend_1350_) in
+ match (reg_name_matches_prefix _stringappend_1351_) with
+ | Some (_stringappend_1352_,(existT _ _stringappend_1353_ _)) =>
+ returnm ((_stringappend_1352_,
+ build_ex
+ _stringappend_1353_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__281 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1353_ _) :=
+ w__281
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1354_ :=
+ string_drop _stringappend_1351_
+ (build_ex
+ _stringappend_1353_) in
+ sep_matches_prefix _stringappend_1354_ >>= fun w__282 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__282 with
+ | Some (_stringappend_1355_,(existT _ _stringappend_1356_ _)) =>
+ returnm ((_stringappend_1355_,
+ build_ex
+ _stringappend_1356_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__284 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1356_ _) :=
+ w__284
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1357_ :=
+ string_drop _stringappend_1354_
+ (build_ex
+ _stringappend_1356_) in
+ match (reg_name_matches_prefix _stringappend_1357_) with
+ | Some (_stringappend_1358_,(existT _ _stringappend_1359_ _)) =>
+ returnm ((_stringappend_1358_,
+ build_ex
+ _stringappend_1359_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__286 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs2, existT _ _stringappend_1359_ _) :=
+ w__286
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1357_
+ (build_ex
+ _stringappend_1359_)) with
+ | "" => returnm ((RTYPEW (rs2,rs1,rd,op)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ match (shiftiwop_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some (_stringappend_1361_,(existT _ _stringappend_1362_ _)) =>
+ let _stringappend_1363_ :=
+ string_drop _stringappend_1112_
+ (build_ex
+ _stringappend_1362_) in
+ match (spc_matches_prefix _stringappend_1363_) with
+ | Some
+ (_stringappend_1364_,(existT _ _stringappend_1365_ _)) =>
+ let _stringappend_1366_ :=
+ string_drop _stringappend_1363_
+ (build_ex
+ _stringappend_1365_) in
+ match (reg_name_matches_prefix _stringappend_1366_) with
+ | Some
+ (_stringappend_1367_,(existT _ _stringappend_1368_ _)) =>
+ let _stringappend_1369_ :=
+ string_drop _stringappend_1366_
+ (build_ex
+ _stringappend_1368_) in
+ sep_matches_prefix _stringappend_1369_ >>= fun w__289 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__289 with
+ | Some
+ (_stringappend_1370_,(existT _ _stringappend_1371_ _)) =>
+ let _stringappend_1372_ :=
+ string_drop _stringappend_1369_
+ (build_ex
+ _stringappend_1371_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1372_) with
+ | Some
+ (_stringappend_1373_,(existT _ _stringappend_1374_ _)) =>
+ let _stringappend_1375_ :=
+ string_drop
+ _stringappend_1372_
+ (build_ex
+ _stringappend_1374_) in
+ if ((match (hex_bits_5_matches_prefix
+ _stringappend_1375_) with
+ | Some
+ (_stringappend_1376_,(existT _ _stringappend_1377_ _)) =>
+ match (string_drop
+ _stringappend_1375_
+ (build_ex
+ _stringappend_1377_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__290 : bool =>
+ returnm ((if (w__290) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__291 : bool =>
+ returnm ((if (w__291) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__292 : bool =>
+ (if (w__292) then
+ match (shiftiwop_mnemonic_matches_prefix
+ _stringappend_1112_) with
+ | Some
+ (_stringappend_1361_,(existT _ _stringappend_1362_ _)) =>
+ returnm ((_stringappend_1361_,
+ build_ex
+ _stringappend_1362_)
+ : (sopw * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((sopw * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__294 : (sopw * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_1362_ _) :=
+ w__294
+ : (sopw * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1363_ :=
+ string_drop _stringappend_1112_
+ (build_ex
+ _stringappend_1362_) in
+ match (spc_matches_prefix _stringappend_1363_) with
+ | Some
+ (_stringappend_1364_,(existT _ _stringappend_1365_ _)) =>
+ returnm ((_stringappend_1364_,
+ build_ex
+ _stringappend_1365_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__296 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1365_ _) :=
+ w__296
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1366_ :=
+ string_drop _stringappend_1363_
+ (build_ex
+ _stringappend_1365_) in
+ match (reg_name_matches_prefix _stringappend_1366_) with
+ | Some
+ (_stringappend_1367_,(existT _ _stringappend_1368_ _)) =>
+ returnm ((_stringappend_1367_,
+ build_ex
+ _stringappend_1368_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__298 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_1368_ _) :=
+ w__298
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1369_ :=
+ string_drop _stringappend_1366_
+ (build_ex
+ _stringappend_1368_) in
+ sep_matches_prefix _stringappend_1369_ >>= fun w__299 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__299 with
+ | Some
+ (_stringappend_1370_,(existT _ _stringappend_1371_ _)) =>
+ returnm ((_stringappend_1370_,
+ build_ex
+ _stringappend_1371_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__301 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1371_ _) :=
+ w__301
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1372_ :=
+ string_drop _stringappend_1369_
+ (build_ex
+ _stringappend_1371_) in
+ match (reg_name_matches_prefix _stringappend_1372_) with
+ | Some
+ (_stringappend_1373_,(existT _ _stringappend_1374_ _)) =>
+ returnm ((_stringappend_1373_,
+ build_ex
+ _stringappend_1374_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__303 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_1374_ _) :=
+ w__303
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1375_ :=
+ string_drop _stringappend_1372_
+ (build_ex
+ _stringappend_1374_) in
+ match (hex_bits_5_matches_prefix _stringappend_1375_) with
+ | Some
+ (_stringappend_1376_,(existT _ _stringappend_1377_ _)) =>
+ returnm ((_stringappend_1376_,
+ build_ex
+ _stringappend_1377_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__305 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(shamt, existT _ _stringappend_1377_ _) :=
+ w__305
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1375_
+ (build_ex
+ _stringappend_1377_)) with
+ | "" => returnm ((SHIFTIWOP (shamt,rs1,rd,op)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ match (mul_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some
+ (_stringappend_1379_,(existT _ _stringappend_1380_ _)) =>
+ let _stringappend_1381_ :=
+ string_drop _stringappend_1112_
+ (build_ex
+ _stringappend_1380_) in
+ match (spc_matches_prefix _stringappend_1381_) with
+ | Some
+ (_stringappend_1382_,(existT _ _stringappend_1383_ _)) =>
+ let _stringappend_1384_ :=
+ string_drop _stringappend_1381_
+ (build_ex
+ _stringappend_1383_) in
+ match (reg_name_matches_prefix _stringappend_1384_) with
+ | Some
+ (_stringappend_1385_,(existT _ _stringappend_1386_ _)) =>
+ let _stringappend_1387_ :=
+ string_drop _stringappend_1384_
+ (build_ex
+ _stringappend_1386_) in
+ sep_matches_prefix _stringappend_1387_ >>= fun w__308 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__308 with
+ | Some
+ (_stringappend_1388_,(existT _ _stringappend_1389_ _)) =>
+ let _stringappend_1390_ :=
+ string_drop _stringappend_1387_
+ (build_ex
+ _stringappend_1389_) in
+ match (reg_name_matches_prefix
+ _stringappend_1390_) with
+ | Some
+ (_stringappend_1391_,(existT _ _stringappend_1392_ _)) =>
+ let _stringappend_1393_ :=
+ string_drop _stringappend_1390_
+ (build_ex
+ _stringappend_1392_) in
+ sep_matches_prefix _stringappend_1393_ >>= fun w__309 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__309 with
+ | Some
+ (_stringappend_1394_,(existT _ _stringappend_1395_ _)) =>
+ let _stringappend_1396_ :=
+ string_drop
+ _stringappend_1393_
+ (build_ex
+ _stringappend_1395_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1396_) with
+ | Some
+ (_stringappend_1397_,(existT _ _stringappend_1398_ _)) =>
+ match (string_drop
+ _stringappend_1396_
+ (build_ex
+ _stringappend_1398_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__310 : bool =>
+ returnm ((if (w__310) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__311 : bool =>
+ returnm ((if (w__311) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__312 : bool =>
+ returnm ((if (w__312) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__313 : bool =>
+ returnm ((if (w__313) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__314 : bool =>
+ (if (w__314) then
+ match (mul_mnemonic_matches_prefix _stringappend_1112_) with
+ | Some
+ (_stringappend_1379_,(existT _ _stringappend_1380_ _)) =>
+ returnm ((_stringappend_1379_,
+ build_ex
+ _stringappend_1380_)
+ : ((bool * bool * bool) * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M (((bool * bool * bool) * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__316 : ((bool * bool * bool) * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '((high, signed1, signed2), existT _ _stringappend_1380_ _) :=
+ w__316
+ : ((bool * bool * bool) * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1381_ :=
+ string_drop _stringappend_1112_
+ (build_ex
+ _stringappend_1380_) in
+ match (spc_matches_prefix _stringappend_1381_) with
+ | Some
+ (_stringappend_1382_,(existT _ _stringappend_1383_ _)) =>
+ returnm ((_stringappend_1382_,
+ build_ex
+ _stringappend_1383_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__318 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1383_ _) :=
+ w__318
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1384_ :=
+ string_drop _stringappend_1381_
+ (build_ex
+ _stringappend_1383_) in
+ match (reg_name_matches_prefix _stringappend_1384_) with
+ | Some
+ (_stringappend_1385_,(existT _ _stringappend_1386_ _)) =>
+ returnm ((_stringappend_1385_,
+ build_ex
+ _stringappend_1386_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__320 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1386_ _) :=
+ w__320
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1387_ :=
+ string_drop _stringappend_1384_
+ (build_ex
+ _stringappend_1386_) in
+ sep_matches_prefix _stringappend_1387_ >>= fun w__321 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__321 with
+ | Some
+ (_stringappend_1388_,(existT _ _stringappend_1389_ _)) =>
+ returnm ((_stringappend_1388_,
+ build_ex
+ _stringappend_1389_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__323 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1389_ _) :=
+ w__323
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1390_ :=
+ string_drop _stringappend_1387_
+ (build_ex
+ _stringappend_1389_) in
+ match (reg_name_matches_prefix _stringappend_1390_) with
+ | Some
+ (_stringappend_1391_,(existT _ _stringappend_1392_ _)) =>
+ returnm ((_stringappend_1391_,
+ build_ex
+ _stringappend_1392_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__325 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1392_ _) :=
+ w__325
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1393_ :=
+ string_drop _stringappend_1390_
+ (build_ex
+ _stringappend_1392_) in
+ sep_matches_prefix _stringappend_1393_ >>= fun w__326 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__326 with
+ | Some
+ (_stringappend_1394_,(existT _ _stringappend_1395_ _)) =>
+ returnm ((_stringappend_1394_,
+ build_ex
+ _stringappend_1395_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__328 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_1395_ _) :=
+ w__328
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1396_ :=
+ string_drop _stringappend_1393_
+ (build_ex
+ _stringappend_1395_) in
+ match (reg_name_matches_prefix _stringappend_1396_) with
+ | Some
+ (_stringappend_1397_,(existT _ _stringappend_1398_ _)) =>
+ returnm ((_stringappend_1397_,
+ build_ex
+ _stringappend_1398_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__330 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1398_ _) :=
+ w__330
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1396_
+ (build_ex
+ _stringappend_1398_)) with
+ | "" =>
+ returnm ((MUL (rs2,rs1,rd,high,signed1,signed2))
+ : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_1112_
+ "div")
+ : bool))
+ (let _stringappend_1400_ :=
+ string_drop _stringappend_1112_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix _stringappend_1400_) with
+ | Some
+ (_stringappend_1401_,(existT _ _stringappend_1402_ _)) =>
+ let _stringappend_1403_ :=
+ string_drop _stringappend_1400_
+ (build_ex
+ _stringappend_1402_) in
+ match (spc_matches_prefix _stringappend_1403_) with
+ | Some
+ (_stringappend_1404_,(existT _ _stringappend_1405_ _)) =>
+ let _stringappend_1406_ :=
+ string_drop _stringappend_1403_
+ (build_ex
+ _stringappend_1405_) in
+ match (reg_name_matches_prefix
+ _stringappend_1406_) with
+ | Some
+ (_stringappend_1407_,(existT _ _stringappend_1408_ _)) =>
+ let _stringappend_1409_ :=
+ string_drop _stringappend_1406_
+ (build_ex
+ _stringappend_1408_) in
+ sep_matches_prefix _stringappend_1409_ >>= fun w__333 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__333 with
+ | Some
+ (_stringappend_1410_,(existT _ _stringappend_1411_ _)) =>
+ let _stringappend_1412_ :=
+ string_drop _stringappend_1409_
+ (build_ex
+ _stringappend_1411_) in
+ match (reg_name_matches_prefix
+ _stringappend_1412_) with
+ | Some
+ (_stringappend_1413_,(existT _ _stringappend_1414_ _)) =>
+ let _stringappend_1415_ :=
+ string_drop _stringappend_1412_
+ (build_ex
+ _stringappend_1414_) in
+ sep_matches_prefix _stringappend_1415_ >>= fun w__334 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__334 with
+ | Some
+ (_stringappend_1416_,(existT _ _stringappend_1417_ _)) =>
+ let _stringappend_1418_ :=
+ string_drop
+ _stringappend_1415_
+ (build_ex
+ _stringappend_1417_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1418_) with
+ | Some
+ (_stringappend_1419_,(existT _ _stringappend_1420_ _)) =>
+ match (string_drop
+ _stringappend_1418_
+ (build_ex
+ _stringappend_1420_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__335 : bool =>
+ returnm ((if (w__335) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__336 : bool =>
+ returnm ((if (w__336) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__337 : bool =>
+ returnm ((if (w__337) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__338 : bool =>
+ returnm ((if (w__338) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__339 : bool =>
+ returnm ((if (w__339) then true
+ else false)
+ : bool)) >>= fun w__340 : bool =>
+ (if (w__340) then
+ let _stringappend_1400_ :=
+ string_drop _stringappend_1112_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_1400_) with
+ | Some
+ (_stringappend_1401_,(existT _ _stringappend_1402_ _)) =>
+ returnm ((_stringappend_1401_,
+ build_ex
+ _stringappend_1402_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__342 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_1402_ _) :=
+ w__342
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1403_ :=
+ string_drop _stringappend_1400_
+ (build_ex
+ _stringappend_1402_) in
+ match (spc_matches_prefix _stringappend_1403_) with
+ | Some
+ (_stringappend_1404_,(existT _ _stringappend_1405_ _)) =>
+ returnm ((_stringappend_1404_,
+ build_ex
+ _stringappend_1405_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__344 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1405_ _) :=
+ w__344
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1406_ :=
+ string_drop _stringappend_1403_
+ (build_ex
+ _stringappend_1405_) in
+ match (reg_name_matches_prefix _stringappend_1406_) with
+ | Some
+ (_stringappend_1407_,(existT _ _stringappend_1408_ _)) =>
+ returnm ((_stringappend_1407_,
+ build_ex
+ _stringappend_1408_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__346 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1408_ _) :=
+ w__346
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1409_ :=
+ string_drop _stringappend_1406_
+ (build_ex
+ _stringappend_1408_) in
+ sep_matches_prefix _stringappend_1409_ >>= fun w__347 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__347 with
+ | Some
+ (_stringappend_1410_,(existT _ _stringappend_1411_ _)) =>
+ returnm ((_stringappend_1410_,
+ build_ex
+ _stringappend_1411_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__349 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1411_ _) :=
+ w__349
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1412_ :=
+ string_drop _stringappend_1409_
+ (build_ex
+ _stringappend_1411_) in
+ match (reg_name_matches_prefix _stringappend_1412_) with
+ | Some
+ (_stringappend_1413_,(existT _ _stringappend_1414_ _)) =>
+ returnm ((_stringappend_1413_,
+ build_ex
+ _stringappend_1414_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__351 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1414_ _) :=
+ w__351
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1415_ :=
+ string_drop _stringappend_1412_
+ (build_ex
+ _stringappend_1414_) in
+ sep_matches_prefix _stringappend_1415_ >>= fun w__352 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__352 with
+ | Some
+ (_stringappend_1416_,(existT _ _stringappend_1417_ _)) =>
+ returnm ((_stringappend_1416_,
+ build_ex
+ _stringappend_1417_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__354 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1417_ _) :=
+ w__354
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1418_ :=
+ string_drop _stringappend_1415_
+ (build_ex
+ _stringappend_1417_) in
+ match (reg_name_matches_prefix _stringappend_1418_) with
+ | Some
+ (_stringappend_1419_,(existT _ _stringappend_1420_ _)) =>
+ returnm ((_stringappend_1419_,
+ build_ex
+ _stringappend_1420_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__356 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1420_ _) :=
+ w__356
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1418_
+ (build_ex
+ _stringappend_1420_)) with
+ | "" => returnm ((DIV (rs2,rs1,rd,s)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_1112_
+ "rem")
+ : bool))
+ (let _stringappend_1422_ :=
+ string_drop _stringappend_1112_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_1422_) with
+ | Some
+ (_stringappend_1423_,(existT _ _stringappend_1424_ _)) =>
+ let _stringappend_1425_ :=
+ string_drop _stringappend_1422_
+ (build_ex
+ _stringappend_1424_) in
+ match (spc_matches_prefix _stringappend_1425_) with
+ | Some
+ (_stringappend_1426_,(existT _ _stringappend_1427_ _)) =>
+ let _stringappend_1428_ :=
+ string_drop _stringappend_1425_
+ (build_ex
+ _stringappend_1427_) in
+ match (reg_name_matches_prefix
+ _stringappend_1428_) with
+ | Some
+ (_stringappend_1429_,(existT _ _stringappend_1430_ _)) =>
+ let _stringappend_1431_ :=
+ string_drop _stringappend_1428_
+ (build_ex
+ _stringappend_1430_) in
+ sep_matches_prefix _stringappend_1431_ >>= fun w__359 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__359 with
+ | Some
+ (_stringappend_1432_,(existT _ _stringappend_1433_ _)) =>
+ let _stringappend_1434_ :=
+ string_drop _stringappend_1431_
+ (build_ex
+ _stringappend_1433_) in
+ match (reg_name_matches_prefix
+ _stringappend_1434_) with
+ | Some
+ (_stringappend_1435_,(existT _ _stringappend_1436_ _)) =>
+ let _stringappend_1437_ :=
+ string_drop _stringappend_1434_
+ (build_ex
+ _stringappend_1436_) in
+ sep_matches_prefix
+ _stringappend_1437_ >>= fun w__360 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__360 with
+ | Some
+ (_stringappend_1438_,(existT _ _stringappend_1439_ _)) =>
+ let _stringappend_1440_ :=
+ string_drop
+ _stringappend_1437_
+ (build_ex
+ _stringappend_1439_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1440_) with
+ | Some
+ (_stringappend_1441_,(existT _ _stringappend_1442_ _)) =>
+ match (string_drop
+ _stringappend_1440_
+ (build_ex
+ _stringappend_1442_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__361 : bool =>
+ returnm ((if (w__361) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__362 : bool =>
+ returnm ((if (w__362) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__363 : bool =>
+ returnm ((if (w__363) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__364 : bool =>
+ returnm ((if (w__364) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__365 : bool =>
+ returnm ((if (w__365) then true
+ else false)
+ : bool)) >>= fun w__366 : bool =>
+ (if (w__366) then
+ let _stringappend_1422_ :=
+ string_drop _stringappend_1112_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_1422_) with
+ | Some
+ (_stringappend_1423_,(existT _ _stringappend_1424_ _)) =>
+ returnm ((_stringappend_1423_,
+ build_ex
+ _stringappend_1424_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__368 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_1424_ _) :=
+ w__368
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1425_ :=
+ string_drop _stringappend_1422_
+ (build_ex
+ _stringappend_1424_) in
+ match (spc_matches_prefix _stringappend_1425_) with
+ | Some
+ (_stringappend_1426_,(existT _ _stringappend_1427_ _)) =>
+ returnm ((_stringappend_1426_,
+ build_ex
+ _stringappend_1427_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__370 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1427_ _) :=
+ w__370
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1428_ :=
+ string_drop _stringappend_1425_
+ (build_ex
+ _stringappend_1427_) in
+ match (reg_name_matches_prefix
+ _stringappend_1428_) with
+ | Some
+ (_stringappend_1429_,(existT _ _stringappend_1430_ _)) =>
+ returnm ((_stringappend_1429_,
+ build_ex
+ _stringappend_1430_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__372 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1430_ _) :=
+ w__372
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1431_ :=
+ string_drop _stringappend_1428_
+ (build_ex
+ _stringappend_1430_) in
+ sep_matches_prefix _stringappend_1431_ >>= fun w__373 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__373 with
+ | Some
+ (_stringappend_1432_,(existT _ _stringappend_1433_ _)) =>
+ returnm ((_stringappend_1432_,
+ build_ex
+ _stringappend_1433_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__375 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1433_ _) :=
+ w__375
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1434_ :=
+ string_drop _stringappend_1431_
+ (build_ex
+ _stringappend_1433_) in
+ match (reg_name_matches_prefix
+ _stringappend_1434_) with
+ | Some
+ (_stringappend_1435_,(existT _ _stringappend_1436_ _)) =>
+ returnm ((_stringappend_1435_,
+ build_ex
+ _stringappend_1436_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__377 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1436_ _) :=
+ w__377
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1437_ :=
+ string_drop _stringappend_1434_
+ (build_ex
+ _stringappend_1436_) in
+ sep_matches_prefix _stringappend_1437_ >>= fun w__378 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__378 with
+ | Some
+ (_stringappend_1438_,(existT _ _stringappend_1439_ _)) =>
+ returnm ((_stringappend_1438_,
+ build_ex
+ _stringappend_1439_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__380 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1439_ _) :=
+ w__380
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1440_ :=
+ string_drop _stringappend_1437_
+ (build_ex
+ _stringappend_1439_) in
+ match (reg_name_matches_prefix
+ _stringappend_1440_) with
+ | Some
+ (_stringappend_1441_,(existT _ _stringappend_1442_ _)) =>
+ returnm ((_stringappend_1441_,
+ build_ex
+ _stringappend_1442_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__382 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1442_ _) :=
+ w__382
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1440_
+ (build_ex
+ _stringappend_1442_)) with
+ | "" => returnm ((REM (rs2,rs1,rd,s)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1112_ "mulw")
+ : bool))
+ (let _stringappend_1444_ :=
+ string_drop _stringappend_1112_
+ (string_length "mulw") in
+ match (spc_matches_prefix _stringappend_1444_) with
+ | Some
+ (_stringappend_1445_,(existT _ _stringappend_1446_ _)) =>
+ let _stringappend_1447_ :=
+ string_drop _stringappend_1444_
+ (build_ex
+ _stringappend_1446_) in
+ match (reg_name_matches_prefix
+ _stringappend_1447_) with
+ | Some
+ (_stringappend_1448_,(existT _ _stringappend_1449_ _)) =>
+ let _stringappend_1450_ :=
+ string_drop _stringappend_1447_
+ (build_ex
+ _stringappend_1449_) in
+ sep_matches_prefix _stringappend_1450_ >>= fun w__385 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__385 with
+ | Some
+ (_stringappend_1451_,(existT _ _stringappend_1452_ _)) =>
+ let _stringappend_1453_ :=
+ string_drop _stringappend_1450_
+ (build_ex
+ _stringappend_1452_) in
+ match (reg_name_matches_prefix
+ _stringappend_1453_) with
+ | Some
+ (_stringappend_1454_,(existT _ _stringappend_1455_ _)) =>
+ let _stringappend_1456_ :=
+ string_drop _stringappend_1453_
+ (build_ex
+ _stringappend_1455_) in
+ sep_matches_prefix
+ _stringappend_1456_ >>= fun w__386 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__386 with
+ | Some
+ (_stringappend_1457_,(existT _ _stringappend_1458_ _)) =>
+ let _stringappend_1459_ :=
+ string_drop
+ _stringappend_1456_
+ (build_ex
+ _stringappend_1458_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1459_) with
+ | Some
+ (_stringappend_1460_,(existT _ _stringappend_1461_ _)) =>
+ match (string_drop
+ _stringappend_1459_
+ (build_ex
+ _stringappend_1461_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__387 : bool =>
+ returnm ((if (w__387) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__388 : bool =>
+ returnm ((if (w__388) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__389 : bool =>
+ returnm ((if (w__389) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__390 : bool =>
+ returnm ((if (w__390) then true
+ else false)
+ : bool)) >>= fun w__391 : bool =>
+ (if (w__391) then
+ let _stringappend_1444_ :=
+ string_drop _stringappend_1112_
+ (string_length "mulw") in
+ match (spc_matches_prefix _stringappend_1444_) with
+ | Some
+ (_stringappend_1445_,(existT _ _stringappend_1446_ _)) =>
+ returnm ((_stringappend_1445_,
+ build_ex
+ _stringappend_1446_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__393 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1446_ _) :=
+ w__393
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1447_ :=
+ string_drop _stringappend_1444_
+ (build_ex
+ _stringappend_1446_) in
+ match (reg_name_matches_prefix
+ _stringappend_1447_) with
+ | Some
+ (_stringappend_1448_,(existT _ _stringappend_1449_ _)) =>
+ returnm ((_stringappend_1448_,
+ build_ex
+ _stringappend_1449_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__395 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1449_ _) :=
+ w__395
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1450_ :=
+ string_drop _stringappend_1447_
+ (build_ex
+ _stringappend_1449_) in
+ sep_matches_prefix _stringappend_1450_ >>= fun w__396 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__396 with
+ | Some
+ (_stringappend_1451_,(existT _ _stringappend_1452_ _)) =>
+ returnm ((_stringappend_1451_,
+ build_ex
+ _stringappend_1452_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__398 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1452_ _) :=
+ w__398
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1453_ :=
+ string_drop _stringappend_1450_
+ (build_ex
+ _stringappend_1452_) in
+ match (reg_name_matches_prefix
+ _stringappend_1453_) with
+ | Some
+ (_stringappend_1454_,(existT _ _stringappend_1455_ _)) =>
+ returnm ((_stringappend_1454_,
+ build_ex
+ _stringappend_1455_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__400 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1455_ _) :=
+ w__400
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1456_ :=
+ string_drop _stringappend_1453_
+ (build_ex
+ _stringappend_1455_) in
+ sep_matches_prefix _stringappend_1456_ >>= fun w__401 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__401 with
+ | Some
+ (_stringappend_1457_,(existT _ _stringappend_1458_ _)) =>
+ returnm ((_stringappend_1457_,
+ build_ex
+ _stringappend_1458_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__403 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1458_ _) :=
+ w__403
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1459_ :=
+ string_drop _stringappend_1456_
+ (build_ex
+ _stringappend_1458_) in
+ match (reg_name_matches_prefix
+ _stringappend_1459_) with
+ | Some
+ (_stringappend_1460_,(existT _ _stringappend_1461_ _)) =>
+ returnm ((_stringappend_1460_,
+ build_ex
+ _stringappend_1461_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__405 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1461_ _) :=
+ w__405
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1459_
+ (build_ex
+ _stringappend_1461_)) with
+ | "" => returnm ((MULW (rs2,rs1,rd)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1112_ "div")
+ : bool))
+ (let _stringappend_1463_ :=
+ string_drop _stringappend_1112_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_1463_) with
+ | Some
+ (_stringappend_1464_,(existT _ _stringappend_1465_ _)) =>
+ let _stringappend_1466_ :=
+ string_drop _stringappend_1463_
+ (build_ex
+ _stringappend_1465_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1466_ "w")
+ : bool))
+ (let _stringappend_1467_ :=
+ string_drop _stringappend_1466_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_1467_) with
+ | Some
+ (_stringappend_1468_,(existT _ _stringappend_1469_ _)) =>
+ let _stringappend_1470_ :=
+ string_drop _stringappend_1467_
+ (build_ex
+ _stringappend_1469_) in
+ match (reg_name_matches_prefix
+ _stringappend_1470_) with
+ | Some
+ (_stringappend_1471_,(existT _ _stringappend_1472_ _)) =>
+ let _stringappend_1473_ :=
+ string_drop _stringappend_1470_
+ (build_ex
+ _stringappend_1472_) in
+ sep_matches_prefix
+ _stringappend_1473_ >>= fun w__408 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__408 with
+ | Some
+ (_stringappend_1474_,(existT _ _stringappend_1475_ _)) =>
+ let _stringappend_1476_ :=
+ string_drop
+ _stringappend_1473_
+ (build_ex
+ _stringappend_1475_) in
+ match (reg_name_matches_prefix
+ _stringappend_1476_) with
+ | Some
+ (_stringappend_1477_,(existT _ _stringappend_1478_ _)) =>
+ let _stringappend_1479_ :=
+ string_drop
+ _stringappend_1476_
+ (build_ex
+ _stringappend_1478_) in
+ sep_matches_prefix
+ _stringappend_1479_ >>= fun w__409 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__409 with
+ | Some
+ (_stringappend_1480_,(existT _ _stringappend_1481_ _)) =>
+ let _stringappend_1482_ :=
+ string_drop
+ _stringappend_1479_
+ (build_ex
+ _stringappend_1481_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1482_) with
+ | Some
+ (_stringappend_1483_,(existT _ _stringappend_1484_ _)) =>
+ match (string_drop
+ _stringappend_1482_
+ (build_ex
+ _stringappend_1484_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__410 : bool =>
+ returnm ((if (w__410) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__411 : bool =>
+ returnm ((if (w__411) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__412 : bool =>
+ returnm ((if (w__412) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__413 : bool =>
+ returnm ((if (w__413) then true
+ else false)
+ : bool)) >>= fun w__414 : bool =>
+ returnm ((if (w__414) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__415 : bool =>
+ returnm ((if (w__415) then true
+ else false)
+ : bool)) >>= fun w__416 : bool =>
+ (if (w__416) then
+ let _stringappend_1463_ :=
+ string_drop _stringappend_1112_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_1463_) with
+ | Some
+ (_stringappend_1464_,(existT _ _stringappend_1465_ _)) =>
+ returnm ((_stringappend_1464_,
+ build_ex
+ _stringappend_1465_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__418 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_1465_ _) :=
+ w__418
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1466_ :=
+ string_drop _stringappend_1463_
+ (build_ex
+ _stringappend_1465_) in
+ let _stringappend_1467_ :=
+ string_drop _stringappend_1466_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_1467_) with
+ | Some
+ (_stringappend_1468_,(existT _ _stringappend_1469_ _)) =>
+ returnm ((_stringappend_1468_,
+ build_ex
+ _stringappend_1469_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__420 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1469_ _) :=
+ w__420
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1470_ :=
+ string_drop _stringappend_1467_
+ (build_ex
+ _stringappend_1469_) in
+ match (reg_name_matches_prefix
+ _stringappend_1470_) with
+ | Some
+ (_stringappend_1471_,(existT _ _stringappend_1472_ _)) =>
+ returnm ((_stringappend_1471_,
+ build_ex
+ _stringappend_1472_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__422 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1472_ _) :=
+ w__422
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1473_ :=
+ string_drop _stringappend_1470_
+ (build_ex
+ _stringappend_1472_) in
+ sep_matches_prefix _stringappend_1473_ >>= fun w__423 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__423 with
+ | Some
+ (_stringappend_1474_,(existT _ _stringappend_1475_ _)) =>
+ returnm ((_stringappend_1474_,
+ build_ex
+ _stringappend_1475_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__425 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1475_ _) :=
+ w__425
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1476_ :=
+ string_drop _stringappend_1473_
+ (build_ex
+ _stringappend_1475_) in
+ match (reg_name_matches_prefix
+ _stringappend_1476_) with
+ | Some
+ (_stringappend_1477_,(existT _ _stringappend_1478_ _)) =>
+ returnm ((_stringappend_1477_,
+ build_ex
+ _stringappend_1478_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__427 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1478_ _) :=
+ w__427
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1479_ :=
+ string_drop _stringappend_1476_
+ (build_ex
+ _stringappend_1478_) in
+ sep_matches_prefix _stringappend_1479_ >>= fun w__428 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__428 with
+ | Some
+ (_stringappend_1480_,(existT _ _stringappend_1481_ _)) =>
+ returnm ((_stringappend_1480_,
+ build_ex
+ _stringappend_1481_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__430 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1481_ _) :=
+ w__430
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1482_ :=
+ string_drop _stringappend_1479_
+ (build_ex
+ _stringappend_1481_) in
+ match (reg_name_matches_prefix
+ _stringappend_1482_) with
+ | Some
+ (_stringappend_1483_,(existT _ _stringappend_1484_ _)) =>
+ returnm ((_stringappend_1483_,
+ build_ex
+ _stringappend_1484_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__432 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1484_ _) :=
+ w__432
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_1482_
+ (build_ex
+ _stringappend_1484_)) with
+ | "" =>
+ returnm ((DIVW (rs2,rs1,rd,s)) : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1112_ "rem")
+ : bool))
+ (let _stringappend_1486_ :=
+ string_drop _stringappend_1112_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_1486_) with
+ | Some
+ (_stringappend_1487_,(existT _ _stringappend_1488_ _)) =>
+ let _stringappend_1489_ :=
+ string_drop _stringappend_1486_
+ (build_ex
+ _stringappend_1488_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1489_ "w")
+ : bool))
+ (let _stringappend_1490_ :=
+ string_drop _stringappend_1489_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_1490_) with
+ | Some
+ (_stringappend_1491_,(existT _ _stringappend_1492_ _)) =>
+ let _stringappend_1493_ :=
+ string_drop _stringappend_1490_
+ (build_ex
+ _stringappend_1492_) in
+ match (reg_name_matches_prefix
+ _stringappend_1493_) with
+ | Some
+ (_stringappend_1494_,(existT _ _stringappend_1495_ _)) =>
+ let _stringappend_1496_ :=
+ string_drop
+ _stringappend_1493_
+ (build_ex
+ _stringappend_1495_) in
+ sep_matches_prefix
+ _stringappend_1496_ >>= fun w__435 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__435 with
+ | Some
+ (_stringappend_1497_,(existT _ _stringappend_1498_ _)) =>
+ let _stringappend_1499_ :=
+ string_drop
+ _stringappend_1496_
+ (build_ex
+ _stringappend_1498_) in
+ match (reg_name_matches_prefix
+ _stringappend_1499_) with
+ | Some
+ (_stringappend_1500_,(existT _ _stringappend_1501_ _)) =>
+ let _stringappend_1502_ :=
+ string_drop
+ _stringappend_1499_
+ (build_ex
+ _stringappend_1501_) in
+ sep_matches_prefix
+ _stringappend_1502_ >>= fun w__436 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__436 with
+ | Some
+ (_stringappend_1503_,(existT _ _stringappend_1504_ _)) =>
+ let _stringappend_1505_ :=
+ string_drop
+ _stringappend_1502_
+ (build_ex
+ _stringappend_1504_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1505_) with
+ | Some
+ (_stringappend_1506_,(existT _ _stringappend_1507_ _)) =>
+ match (string_drop
+ _stringappend_1505_
+ (build_ex
+ _stringappend_1507_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__437 : bool =>
+ returnm ((if (w__437) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__438 : bool =>
+ returnm ((if (w__438) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__439 : bool =>
+ returnm ((if (w__439) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__440 : bool =>
+ returnm ((if (w__440) then true
+ else false)
+ : bool)) >>= fun w__441 : bool =>
+ returnm ((if (w__441) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__442 : bool =>
+ returnm ((if (w__442) then true
+ else false)
+ : bool)) >>= fun w__443 : bool =>
+ (if (w__443) then
+ let _stringappend_1486_ :=
+ string_drop _stringappend_1112_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_1486_) with
+ | Some
+ (_stringappend_1487_,(existT _ _stringappend_1488_ _)) =>
+ returnm ((_stringappend_1487_,
+ build_ex
+ _stringappend_1488_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__445 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_1488_ _) :=
+ w__445
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1489_ :=
+ string_drop _stringappend_1486_
+ (build_ex
+ _stringappend_1488_) in
+ let _stringappend_1490_ :=
+ string_drop _stringappend_1489_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_1490_) with
+ | Some
+ (_stringappend_1491_,(existT _ _stringappend_1492_ _)) =>
+ returnm ((_stringappend_1491_,
+ build_ex
+ _stringappend_1492_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__447 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1492_ _) :=
+ w__447
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1493_ :=
+ string_drop _stringappend_1490_
+ (build_ex
+ _stringappend_1492_) in
+ match (reg_name_matches_prefix
+ _stringappend_1493_) with
+ | Some
+ (_stringappend_1494_,(existT _ _stringappend_1495_ _)) =>
+ returnm ((_stringappend_1494_,
+ build_ex
+ _stringappend_1495_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__449 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1495_ _) :=
+ w__449
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1496_ :=
+ string_drop _stringappend_1493_
+ (build_ex
+ _stringappend_1495_) in
+ sep_matches_prefix _stringappend_1496_ >>= fun w__450 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__450 with
+ | Some
+ (_stringappend_1497_,(existT _ _stringappend_1498_ _)) =>
+ returnm ((_stringappend_1497_,
+ build_ex
+ _stringappend_1498_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__452 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1498_ _) :=
+ w__452
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1499_ :=
+ string_drop _stringappend_1496_
+ (build_ex
+ _stringappend_1498_) in
+ match (reg_name_matches_prefix
+ _stringappend_1499_) with
+ | Some
+ (_stringappend_1500_,(existT _ _stringappend_1501_ _)) =>
+ returnm ((_stringappend_1500_,
+ build_ex
+ _stringappend_1501_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__454 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1501_ _) :=
+ w__454
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1502_ :=
+ string_drop _stringappend_1499_
+ (build_ex
+ _stringappend_1501_) in
+ sep_matches_prefix _stringappend_1502_ >>= fun w__455 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__455 with
+ | Some
+ (_stringappend_1503_,(existT _ _stringappend_1504_ _)) =>
+ returnm ((_stringappend_1503_,
+ build_ex
+ _stringappend_1504_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__457 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1504_ _) :=
+ w__457
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_1505_ :=
+ string_drop _stringappend_1502_
+ (build_ex
+ _stringappend_1504_) in
+ match (reg_name_matches_prefix
+ _stringappend_1505_) with
+ | Some
+ (_stringappend_1506_,(existT _ _stringappend_1507_ _)) =>
+ returnm ((_stringappend_1506_,
+ build_ex
+ _stringappend_1507_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__459 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1507_ _) :=
+ w__459
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop _stringappend_1505_
+ (build_ex
+ _stringappend_1507_)) with
+ | "" =>
+ returnm ((REMW (rs2,rs1,rd,s))
+ : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1112_
+ "fence")
+ : bool))
+ (let _stringappend_1509_ :=
+ string_drop _stringappend_1112_
+ (string_length "fence") in
+ match (spc_matches_prefix
+ _stringappend_1509_) with
+ | Some
+ (_stringappend_1510_,(existT _ _stringappend_1511_ _)) =>
+ let _stringappend_1512_ :=
+ string_drop _stringappend_1509_
+ (build_ex
+ _stringappend_1511_) in
+ fence_bits_matches_prefix
+ _stringappend_1512_ >>= fun w__462 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__462 with
+ | Some
+ (_stringappend_1513_,(existT _ _stringappend_1514_ _)) =>
+ let _stringappend_1515_ :=
+ string_drop
+ _stringappend_1512_
+ (build_ex
+ _stringappend_1514_) in
+ sep_matches_prefix
+ _stringappend_1515_ >>= fun w__463 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__463 with
+ | Some
+ (_stringappend_1516_,(existT _ _stringappend_1517_ _)) =>
+ let _stringappend_1518_ :=
+ string_drop
+ _stringappend_1515_
+ (build_ex
+ _stringappend_1517_) in
+ fence_bits_matches_prefix
+ _stringappend_1518_ >>= fun w__464 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__464 with
+ | Some
+ (_stringappend_1519_,(existT _ _stringappend_1520_ _)) =>
+ match (string_drop
+ _stringappend_1518_
+ (build_ex
+ _stringappend_1520_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__465 : bool =>
+ returnm ((if (w__465) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__466 : bool =>
+ returnm ((if (w__466) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__467 : bool =>
+ returnm ((if (w__467) then true
+ else false)
+ : bool)) >>= fun w__468 : bool =>
+ (if (w__468) then
+ let _stringappend_1509_ :=
+ string_drop _stringappend_1112_
+ (string_length "fence") in
+ match (spc_matches_prefix
+ _stringappend_1509_) with
+ | Some
+ (_stringappend_1510_,(existT _ _stringappend_1511_ _)) =>
+ returnm ((_stringappend_1510_,
+ build_ex
+ _stringappend_1511_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__470 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1511_ _) :=
+ w__470
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1512_ :=
+ string_drop _stringappend_1509_
+ (build_ex
+ _stringappend_1511_) in
+ fence_bits_matches_prefix
+ _stringappend_1512_ >>= fun w__471 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__471 with
+ | Some
+ (_stringappend_1513_,(existT _ _stringappend_1514_ _)) =>
+ returnm ((_stringappend_1513_,
+ build_ex
+ _stringappend_1514_)
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__473 : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(pred, existT _ _stringappend_1514_ _) :=
+ w__473
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1515_ :=
+ string_drop _stringappend_1512_
+ (build_ex
+ _stringappend_1514_) in
+ sep_matches_prefix
+ _stringappend_1515_ >>= fun w__474 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__474 with
+ | Some
+ (_stringappend_1516_,(existT _ _stringappend_1517_ _)) =>
+ returnm ((_stringappend_1516_,
+ build_ex
+ _stringappend_1517_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__476 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1517_ _) :=
+ w__476
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1518_ :=
+ string_drop _stringappend_1515_
+ (build_ex
+ _stringappend_1517_) in
+ fence_bits_matches_prefix
+ _stringappend_1518_ >>= fun w__477 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__477 with
+ | Some
+ (_stringappend_1519_,(existT _ _stringappend_1520_ _)) =>
+ returnm ((_stringappend_1519_,
+ build_ex
+ _stringappend_1520_)
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__479 : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(succ, existT _ _stringappend_1520_ _) :=
+ w__479
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1518_
+ (build_ex
+ _stringappend_1520_)) with
+ | "" =>
+ returnm ((FENCE (pred,succ))
+ : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ (match _stringappend_1112_ with
+ | "fence.i" =>
+ returnm ((FENCEI tt) : ast)
+ | "ecall" =>
+ returnm ((ECALL tt) : ast)
+ | "mret" =>
+ returnm ((MRET tt) : ast)
+ | "sret" =>
+ returnm ((SRET tt) : ast)
+ | "ebreak" =>
+ returnm ((EBREAK tt) : ast)
+ | "wfi" => returnm ((WFI tt) : ast)
+ | _stringappend_1112_ =>
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1112_
+ "sfence.vma")
+ : bool))
+ (let _stringappend_1522_ :=
+ string_drop
+ _stringappend_1112_
+ (string_length "sfence.vma") in
+ match (spc_matches_prefix
+ _stringappend_1522_) with
+ | Some
+ (_stringappend_1523_,(existT _ _stringappend_1524_ _)) =>
+ let _stringappend_1525_ :=
+ string_drop
+ _stringappend_1522_
+ (build_ex
+ _stringappend_1524_) in
+ match (reg_name_matches_prefix
+ _stringappend_1525_) with
+ | Some
+ (_stringappend_1526_,(existT _ _stringappend_1527_ _)) =>
+ let _stringappend_1528_ :=
+ string_drop
+ _stringappend_1525_
+ (build_ex
+ _stringappend_1527_) in
+ sep_matches_prefix
+ _stringappend_1528_ >>= fun w__482 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__482 with
+ | Some
+ (_stringappend_1529_,(existT _ _stringappend_1530_ _)) =>
+ let _stringappend_1531_ :=
+ string_drop
+ _stringappend_1528_
+ (build_ex
+ _stringappend_1530_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_1531_) with
+ | Some
+ (_stringappend_1532_,(existT _ _stringappend_1533_ _)) =>
+ match (string_drop
+ _stringappend_1531_
+ (build_ex
+ _stringappend_1533_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__483 : bool =>
+ returnm ((if (w__483) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__484 : bool =>
+ returnm ((if (w__484) then true
+ else false)
+ : bool)) >>= fun w__485 : bool =>
+ (if (w__485) then
+ let _stringappend_1522_ :=
+ string_drop
+ _stringappend_1112_
+ (string_length
+ "sfence.vma") in
+ match (spc_matches_prefix
+ _stringappend_1522_) with
+ | Some
+ (_stringappend_1523_,(existT _ _stringappend_1524_ _)) =>
+ returnm ((_stringappend_1523_,
+ build_ex
+ _stringappend_1524_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__487 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1524_ _) :=
+ w__487
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1525_ :=
+ string_drop
+ _stringappend_1522_
+ (build_ex
+ _stringappend_1524_) in
+ match (reg_name_matches_prefix
+ _stringappend_1525_) with
+ | Some
+ (_stringappend_1526_,(existT _ _stringappend_1527_ _)) =>
+ returnm ((_stringappend_1526_,
+ build_ex
+ _stringappend_1527_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__489 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1527_ _) :=
+ w__489
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1528_ :=
+ string_drop
+ _stringappend_1525_
+ (build_ex
+ _stringappend_1527_) in
+ sep_matches_prefix
+ _stringappend_1528_ >>= fun w__490 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__490 with
+ | Some
+ (_stringappend_1529_,(existT _ _stringappend_1530_ _)) =>
+ returnm ((_stringappend_1529_,
+ build_ex
+ _stringappend_1530_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__492 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1530_ _) :=
+ w__492
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1531_ :=
+ string_drop
+ _stringappend_1528_
+ (build_ex
+ _stringappend_1530_) in
+ match (reg_name_matches_prefix
+ _stringappend_1531_) with
+ | Some
+ (_stringappend_1532_,(existT _ _stringappend_1533_ _)) =>
+ returnm ((_stringappend_1532_,
+ build_ex
+ _stringappend_1533_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__494 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1533_ _) :=
+ w__494
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1531_
+ (build_ex
+ _stringappend_1533_)) with
+ | "" =>
+ returnm ((SFENCE_VMA (rs1,rs2))
+ : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1112_
+ "lr.")
+ : bool))
+ (let _stringappend_1535_ :=
+ string_drop
+ _stringappend_1112_
+ (string_length "lr.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_1535_) with
+ | Some
+ (_stringappend_1536_,(existT _ _stringappend_1537_ _)) =>
+ let _stringappend_1538_ :=
+ string_drop
+ _stringappend_1535_
+ (build_ex
+ _stringappend_1537_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1538_) with
+ | Some
+ (_stringappend_1539_,(existT _ _stringappend_1540_ _)) =>
+ let _stringappend_1541_ :=
+ string_drop
+ _stringappend_1538_
+ (build_ex
+ _stringappend_1540_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1541_) with
+ | Some
+ (_stringappend_1542_,(existT _ _stringappend_1543_ _)) =>
+ let _stringappend_1544_ :=
+ string_drop
+ _stringappend_1541_
+ (build_ex
+ _stringappend_1543_) in
+ match (spc_matches_prefix
+ _stringappend_1544_) with
+ | Some
+ (_stringappend_1545_,(existT _ _stringappend_1546_ _)) =>
+ let _stringappend_1547_ :=
+ string_drop
+ _stringappend_1544_
+ (build_ex
+ _stringappend_1546_) in
+ match (reg_name_matches_prefix
+ _stringappend_1547_) with
+ | Some
+ (_stringappend_1548_,(existT _ _stringappend_1549_ _)) =>
+ let _stringappend_1550_ :=
+ string_drop
+ _stringappend_1547_
+ (build_ex
+ _stringappend_1549_) in
+ sep_matches_prefix
+ _stringappend_1550_ >>= fun w__497 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__497 with
+ | Some
+ (_stringappend_1551_,(existT _ _stringappend_1552_ _)) =>
+ let _stringappend_1553_ :=
+ string_drop
+ _stringappend_1550_
+ (build_ex
+ _stringappend_1552_) in
+ if
+ ((match (reg_name_matches_prefix
+ _stringappend_1553_) with
+ | Some
+ (_stringappend_1554_,(existT _ _stringappend_1555_ _)) =>
+ match (string_drop
+ _stringappend_1553_
+ (build_ex
+ _stringappend_1555_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__498 : bool =>
+ returnm ((if (w__498)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__499 : bool =>
+ returnm ((if (w__499)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__500 : bool =>
+ returnm ((if (w__500)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__501 : bool =>
+ returnm ((if (w__501)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__502 : bool =>
+ returnm ((if (w__502) then
+ true
+ else false)
+ : bool)) >>= fun w__503 : bool =>
+ (if (w__503) then
+ let _stringappend_1535_ :=
+ string_drop
+ _stringappend_1112_
+ (string_length "lr.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_1535_) with
+ | Some
+ (_stringappend_1536_,(existT _ _stringappend_1537_ _)) =>
+ returnm ((_stringappend_1536_,
+ build_ex
+ _stringappend_1537_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__505 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(aq, existT _ _stringappend_1537_ _) :=
+ w__505
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1538_ :=
+ string_drop
+ _stringappend_1535_
+ (build_ex
+ _stringappend_1537_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1538_) with
+ | Some
+ (_stringappend_1539_,(existT _ _stringappend_1540_ _)) =>
+ returnm ((_stringappend_1539_,
+ build_ex
+ _stringappend_1540_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__507 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rl, existT _ _stringappend_1540_ _) :=
+ w__507
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1541_ :=
+ string_drop
+ _stringappend_1538_
+ (build_ex
+ _stringappend_1540_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1541_) with
+ | Some
+ (_stringappend_1542_,(existT _ _stringappend_1543_ _)) =>
+ returnm ((_stringappend_1542_,
+ build_ex
+ _stringappend_1543_)
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__509 : (word_width * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(size, existT _ _stringappend_1543_ _) :=
+ w__509
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1544_ :=
+ string_drop
+ _stringappend_1541_
+ (build_ex
+ _stringappend_1543_) in
+ match (spc_matches_prefix
+ _stringappend_1544_) with
+ | Some
+ (_stringappend_1545_,(existT _ _stringappend_1546_ _)) =>
+ returnm ((_stringappend_1545_,
+ build_ex
+ _stringappend_1546_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__511 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1546_ _) :=
+ w__511
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1547_ :=
+ string_drop
+ _stringappend_1544_
+ (build_ex
+ _stringappend_1546_) in
+ match (reg_name_matches_prefix
+ _stringappend_1547_) with
+ | Some
+ (_stringappend_1548_,(existT _ _stringappend_1549_ _)) =>
+ returnm ((_stringappend_1548_,
+ build_ex
+ _stringappend_1549_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__513 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1549_ _) :=
+ w__513
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1550_ :=
+ string_drop
+ _stringappend_1547_
+ (build_ex
+ _stringappend_1549_) in
+ sep_matches_prefix
+ _stringappend_1550_ >>= fun w__514 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__514 with
+ | Some
+ (_stringappend_1551_,(existT _ _stringappend_1552_ _)) =>
+ returnm ((_stringappend_1551_,
+ build_ex
+ _stringappend_1552_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__516 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1552_ _) :=
+ w__516
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1553_ :=
+ string_drop
+ _stringappend_1550_
+ (build_ex
+ _stringappend_1552_) in
+ match (reg_name_matches_prefix
+ _stringappend_1553_) with
+ | Some
+ (_stringappend_1554_,(existT _ _stringappend_1555_ _)) =>
+ returnm ((_stringappend_1554_,
+ build_ex
+ _stringappend_1555_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__518 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1555_ _) :=
+ w__518
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1553_
+ (build_ex
+ _stringappend_1555_)) with
+ | "" =>
+ returnm ((LOADRES (aq,rl,rs1,size,rd))
+ : ast)
+ | _ => exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1112_
+ "sc.")
+ : bool))
+ (let _stringappend_1557_ :=
+ string_drop
+ _stringappend_1112_
+ (string_length "sc.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_1557_) with
+ | Some
+ (_stringappend_1558_,(existT _ _stringappend_1559_ _)) =>
+ let _stringappend_1560_ :=
+ string_drop
+ _stringappend_1557_
+ (build_ex
+ _stringappend_1559_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1560_) with
+ | Some
+ (_stringappend_1561_,(existT _ _stringappend_1562_ _)) =>
+ let _stringappend_1563_ :=
+ string_drop
+ _stringappend_1560_
+ (build_ex
+ _stringappend_1562_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1563_) with
+ | Some
+ (_stringappend_1564_,(existT _ _stringappend_1565_ _)) =>
+ let _stringappend_1566_ :=
+ string_drop
+ _stringappend_1563_
+ (build_ex
+ _stringappend_1565_) in
+ match (spc_matches_prefix
+ _stringappend_1566_) with
+ | Some
+ (_stringappend_1567_,(existT _ _stringappend_1568_ _)) =>
+ let _stringappend_1569_ :=
+ string_drop
+ _stringappend_1566_
+ (build_ex
+ _stringappend_1568_) in
+ match (reg_name_matches_prefix
+ _stringappend_1569_) with
+ | Some
+ (_stringappend_1570_,(existT _ _stringappend_1571_ _)) =>
+ let _stringappend_1572_ :=
+ string_drop
+ _stringappend_1569_
+ (build_ex
+ _stringappend_1571_) in
+ sep_matches_prefix
+ _stringappend_1572_ >>= fun w__521 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__521 with
+ | Some
+ (_stringappend_1573_,(existT _ _stringappend_1574_ _)) =>
+ let _stringappend_1575_ :=
+ string_drop
+ _stringappend_1572_
+ (build_ex
+ _stringappend_1574_) in
+ match (reg_name_matches_prefix
+ _stringappend_1575_) with
+ | Some
+ (_stringappend_1576_,(existT _ _stringappend_1577_ _)) =>
+ let _stringappend_1578_ :=
+ string_drop
+ _stringappend_1575_
+ (build_ex
+ _stringappend_1577_) in
+ sep_matches_prefix
+ _stringappend_1578_ >>= fun w__522 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__522 with
+ | Some
+ (_stringappend_1579_,(existT _ _stringappend_1580_ _)) =>
+ let _stringappend_1581_ :=
+ string_drop
+ _stringappend_1578_
+ (build_ex
+ _stringappend_1580_) in
+ if
+ ((match (reg_name_matches_prefix
+ _stringappend_1581_) with
+ | Some
+ (_stringappend_1582_,(existT _ _stringappend_1583_ _)) =>
+ match (string_drop
+ _stringappend_1581_
+ (build_ex
+ _stringappend_1583_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__523 : bool =>
+ returnm ((if
+ (w__523)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__524 : bool =>
+ returnm ((if
+ (w__524)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__525 : bool =>
+ returnm ((if (w__525)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__526 : bool =>
+ returnm ((if (w__526)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__527 : bool =>
+ returnm ((if (w__527)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__528 : bool =>
+ returnm ((if (w__528)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__529 : bool =>
+ returnm ((if (w__529)
+ then
+ true
+ else false)
+ : bool)) >>= fun w__530 : bool =>
+ (if (w__530) then
+ let _stringappend_1557_ :=
+ string_drop
+ _stringappend_1112_
+ (string_length "sc.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_1557_) with
+ | Some
+ (_stringappend_1558_,(existT _ _stringappend_1559_ _)) =>
+ returnm ((_stringappend_1558_,
+ build_ex
+ _stringappend_1559_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__532 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(aq, existT _ _stringappend_1559_ _) :=
+ w__532
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1560_ :=
+ string_drop
+ _stringappend_1557_
+ (build_ex
+ _stringappend_1559_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1560_) with
+ | Some
+ (_stringappend_1561_,(existT _ _stringappend_1562_ _)) =>
+ returnm ((_stringappend_1561_,
+ build_ex
+ _stringappend_1562_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__534 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rl, existT _ _stringappend_1562_ _) :=
+ w__534
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1563_ :=
+ string_drop
+ _stringappend_1560_
+ (build_ex
+ _stringappend_1562_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1563_) with
+ | Some
+ (_stringappend_1564_,(existT _ _stringappend_1565_ _)) =>
+ returnm ((_stringappend_1564_,
+ build_ex
+ _stringappend_1565_)
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__536 : (word_width * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(size, existT _ _stringappend_1565_ _) :=
+ w__536
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1566_ :=
+ string_drop
+ _stringappend_1563_
+ (build_ex
+ _stringappend_1565_) in
+ match (spc_matches_prefix
+ _stringappend_1566_) with
+ | Some
+ (_stringappend_1567_,(existT _ _stringappend_1568_ _)) =>
+ returnm ((_stringappend_1567_,
+ build_ex
+ _stringappend_1568_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__538 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1568_ _) :=
+ w__538
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1569_ :=
+ string_drop
+ _stringappend_1566_
+ (build_ex
+ _stringappend_1568_) in
+ match (reg_name_matches_prefix
+ _stringappend_1569_) with
+ | Some
+ (_stringappend_1570_,(existT _ _stringappend_1571_ _)) =>
+ returnm ((_stringappend_1570_,
+ build_ex
+ _stringappend_1571_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__540 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1571_ _) :=
+ w__540
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1572_ :=
+ string_drop
+ _stringappend_1569_
+ (build_ex
+ _stringappend_1571_) in
+ sep_matches_prefix
+ _stringappend_1572_ >>= fun w__541 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__541 with
+ | Some
+ (_stringappend_1573_,(existT _ _stringappend_1574_ _)) =>
+ returnm ((_stringappend_1573_,
+ build_ex
+ _stringappend_1574_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__543 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1574_ _) :=
+ w__543
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1575_ :=
+ string_drop
+ _stringappend_1572_
+ (build_ex
+ _stringappend_1574_) in
+ match (reg_name_matches_prefix
+ _stringappend_1575_) with
+ | Some
+ (_stringappend_1576_,(existT _ _stringappend_1577_ _)) =>
+ returnm ((_stringappend_1576_,
+ build_ex
+ _stringappend_1577_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__545 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1577_ _) :=
+ w__545
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1578_ :=
+ string_drop
+ _stringappend_1575_
+ (build_ex
+ _stringappend_1577_) in
+ sep_matches_prefix
+ _stringappend_1578_ >>= fun w__546 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__546 with
+ | Some
+ (_stringappend_1579_,(existT _ _stringappend_1580_ _)) =>
+ returnm ((_stringappend_1579_,
+ build_ex
+ _stringappend_1580_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__548 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1580_ _) :=
+ w__548
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1581_ :=
+ string_drop
+ _stringappend_1578_
+ (build_ex
+ _stringappend_1580_) in
+ match (reg_name_matches_prefix
+ _stringappend_1581_) with
+ | Some
+ (_stringappend_1582_,(existT _ _stringappend_1583_ _)) =>
+ returnm ((_stringappend_1582_,
+ build_ex
+ _stringappend_1583_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__550 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1583_ _) :=
+ w__550
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1581_
+ (build_ex
+ _stringappend_1583_)) with
+ | "" =>
+ returnm ((STORECON (aq,rl,rs2,rs1,size,rd))
+ : ast)
+ | _ =>
+ exit tt : M (ast)
+ end)
+ : M (ast)
+ else
+ match (amo_mnemonic_matches_prefix
+ _stringappend_1112_) with
+ | Some
+ (_stringappend_1585_,(existT _ _stringappend_1586_ _)) =>
+ let _stringappend_1587_ :=
+ string_drop
+ _stringappend_1112_
+ (build_ex
+ _stringappend_1586_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1587_
+ ".")
+ : bool))
+ (let _stringappend_1588_ :=
+ string_drop
+ _stringappend_1587_
+ (string_length
+ ".") in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1588_) with
+ | Some
+ (_stringappend_1589_,(existT _ _stringappend_1590_ _)) =>
+ let _stringappend_1591_ :=
+ string_drop
+ _stringappend_1588_
+ (build_ex
+ _stringappend_1590_) in
+ match (maybe_aq_matches_prefix
+ _stringappend_1591_) with
+ | Some
+ (_stringappend_1592_,(existT _ _stringappend_1593_ _)) =>
+ let _stringappend_1594_ :=
+ string_drop
+ _stringappend_1591_
+ (build_ex
+ _stringappend_1593_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1594_) with
+ | Some
+ (_stringappend_1595_,(existT _ _stringappend_1596_ _)) =>
+ let _stringappend_1597_ :=
+ string_drop
+ _stringappend_1594_
+ (build_ex
+ _stringappend_1596_) in
+ match (spc_matches_prefix
+ _stringappend_1597_) with
+ | Some
+ (_stringappend_1598_,(existT _ _stringappend_1599_ _)) =>
+ let _stringappend_1600_ :=
+ string_drop
+ _stringappend_1597_
+ (build_ex
+ _stringappend_1599_) in
+ match (reg_name_matches_prefix
+ _stringappend_1600_) with
+ | Some
+ (_stringappend_1601_,(existT _ _stringappend_1602_ _)) =>
+ let _stringappend_1603_ :=
+ string_drop
+ _stringappend_1600_
+ (build_ex
+ _stringappend_1602_) in
+ sep_matches_prefix
+ _stringappend_1603_ >>= fun w__553 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__553 with
+ | Some
+ (_stringappend_1604_,(existT _ _stringappend_1605_ _)) =>
+ let _stringappend_1606_ :=
+ string_drop
+ _stringappend_1603_
+ (build_ex
+ _stringappend_1605_) in
+ match (reg_name_matches_prefix
+ _stringappend_1606_) with
+ | Some
+ (_stringappend_1607_,(existT _ _stringappend_1608_ _)) =>
+ let _stringappend_1609_ :=
+ string_drop
+ _stringappend_1606_
+ (build_ex
+ _stringappend_1608_) in
+ sep_matches_prefix
+ _stringappend_1609_ >>= fun w__554 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__554 with
+ | Some
+ (_stringappend_1610_,(existT _ _stringappend_1611_ _)) =>
+ let _stringappend_1612_ :=
+ string_drop
+ _stringappend_1609_
+ (build_ex
+ _stringappend_1611_) in
+ if
+ ((match (reg_name_matches_prefix
+ _stringappend_1612_) with
+ | Some
+ (_stringappend_1613_,(existT _ _stringappend_1614_ _)) =>
+ match (string_drop
+ _stringappend_1612_
+ (build_ex
+ _stringappend_1614_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__555 : bool =>
+ returnm ((if
+ (w__555)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__556 : bool =>
+ returnm ((if
+ (w__556)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__557 : bool =>
+ returnm ((if
+ (w__557)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__558 : bool =>
+ returnm ((if
+ (w__558)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__559 : bool =>
+ returnm ((if (w__559)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__560 : bool =>
+ returnm ((if (w__560)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__561 : bool =>
+ returnm ((if (w__561)
+ then
+ true
+ else
+ false)
+ : bool)) >>= fun w__562 : bool =>
+ returnm ((if (w__562)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__563 : bool =>
+ (if (w__563) then
+ match (amo_mnemonic_matches_prefix
+ _stringappend_1112_) with
+ | Some
+ (_stringappend_1585_,(existT _ _stringappend_1586_ _)) =>
+ returnm ((_stringappend_1585_,
+ build_ex
+ _stringappend_1586_)
+ : (amoop * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((amoop * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__565 : (amoop * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(op, existT _ _stringappend_1586_ _) :=
+ w__565
+ : (amoop * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1587_ :=
+ string_drop
+ _stringappend_1112_
+ (build_ex
+ _stringappend_1586_) in
+ let _stringappend_1588_ :=
+ string_drop
+ _stringappend_1587_
+ (string_length
+ ".") in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1588_) with
+ | Some
+ (_stringappend_1589_,(existT _ _stringappend_1590_ _)) =>
+ returnm ((_stringappend_1589_,
+ build_ex
+ _stringappend_1590_)
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__567 : (word_width * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(width, existT _ _stringappend_1590_ _) :=
+ w__567
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1591_ :=
+ string_drop
+ _stringappend_1588_
+ (build_ex
+ _stringappend_1590_) in
+ match (maybe_aq_matches_prefix
+ _stringappend_1591_) with
+ | Some
+ (_stringappend_1592_,(existT _ _stringappend_1593_ _)) =>
+ returnm ((_stringappend_1592_,
+ build_ex
+ _stringappend_1593_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__569 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(aq, existT _ _stringappend_1593_ _) :=
+ w__569
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1594_ :=
+ string_drop
+ _stringappend_1591_
+ (build_ex
+ _stringappend_1593_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1594_) with
+ | Some
+ (_stringappend_1595_,(existT _ _stringappend_1596_ _)) =>
+ returnm ((_stringappend_1595_,
+ build_ex
+ _stringappend_1596_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__571 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rl, existT _ _stringappend_1596_ _) :=
+ w__571
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1597_ :=
+ string_drop
+ _stringappend_1594_
+ (build_ex
+ _stringappend_1596_) in
+ match (spc_matches_prefix
+ _stringappend_1597_) with
+ | Some
+ (_stringappend_1598_,(existT _ _stringappend_1599_ _)) =>
+ returnm ((_stringappend_1598_,
+ build_ex
+ _stringappend_1599_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__573 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1599_ _) :=
+ w__573
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1600_ :=
+ string_drop
+ _stringappend_1597_
+ (build_ex
+ _stringappend_1599_) in
+ match (reg_name_matches_prefix
+ _stringappend_1600_) with
+ | Some
+ (_stringappend_1601_,(existT _ _stringappend_1602_ _)) =>
+ returnm ((_stringappend_1601_,
+ build_ex
+ _stringappend_1602_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__575 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1602_ _) :=
+ w__575
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1603_ :=
+ string_drop
+ _stringappend_1600_
+ (build_ex
+ _stringappend_1602_) in
+ sep_matches_prefix
+ _stringappend_1603_ >>= fun w__576 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__576 with
+ | Some
+ (_stringappend_1604_,(existT _ _stringappend_1605_ _)) =>
+ returnm ((_stringappend_1604_,
+ build_ex
+ _stringappend_1605_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__578 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1605_ _) :=
+ w__578
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1606_ :=
+ string_drop
+ _stringappend_1603_
+ (build_ex
+ _stringappend_1605_) in
+ match (reg_name_matches_prefix
+ _stringappend_1606_) with
+ | Some
+ (_stringappend_1607_,(existT _ _stringappend_1608_ _)) =>
+ returnm ((_stringappend_1607_,
+ build_ex
+ _stringappend_1608_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__580 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1608_ _) :=
+ w__580
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1609_ :=
+ string_drop
+ _stringappend_1606_
+ (build_ex
+ _stringappend_1608_) in
+ sep_matches_prefix
+ _stringappend_1609_ >>= fun w__581 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__581 with
+ | Some
+ (_stringappend_1610_,(existT _ _stringappend_1611_ _)) =>
+ returnm ((_stringappend_1610_,
+ build_ex
+ _stringappend_1611_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__583 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1611_ _) :=
+ w__583
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1612_ :=
+ string_drop
+ _stringappend_1609_
+ (build_ex
+ _stringappend_1611_) in
+ match (reg_name_matches_prefix
+ _stringappend_1612_) with
+ | Some
+ (_stringappend_1613_,(existT _ _stringappend_1614_ _)) =>
+ returnm ((_stringappend_1613_,
+ build_ex
+ _stringappend_1614_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__585 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1614_ _) :=
+ w__585
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1612_
+ (build_ex
+ _stringappend_1614_)) with
+ | "" =>
+ returnm ((AMO (op,aq,rl,rs2,rs1,width,rd))
+ : ast)
+ | _ =>
+ exit tt
+ : M (ast)
+ end)
+ : M (ast)
+ else
+ match (csr_mnemonic_matches_prefix
+ _stringappend_1112_) with
+ | Some
+ (_stringappend_1616_,(existT _ _stringappend_1617_ _)) =>
+ let _stringappend_1618_ :=
+ string_drop
+ _stringappend_1112_
+ (build_ex
+ _stringappend_1617_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1618_
+ "i")
+ : bool))
+ (let _stringappend_1619_ :=
+ string_drop
+ _stringappend_1618_
+ (string_length
+ "i") in
+ match (spc_matches_prefix
+ _stringappend_1619_) with
+ | Some
+ (_stringappend_1620_,(existT _ _stringappend_1621_ _)) =>
+ let _stringappend_1622_ :=
+ string_drop
+ _stringappend_1619_
+ (build_ex
+ _stringappend_1621_) in
+ match (reg_name_matches_prefix
+ _stringappend_1622_) with
+ | Some
+ (_stringappend_1623_,(existT _ _stringappend_1624_ _)) =>
+ let _stringappend_1625_ :=
+ string_drop
+ _stringappend_1622_
+ (build_ex
+ _stringappend_1624_) in
+ sep_matches_prefix
+ _stringappend_1625_ >>= fun w__588 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__588 with
+ | Some
+ (_stringappend_1626_,(existT _ _stringappend_1627_ _)) =>
+ let _stringappend_1628_ :=
+ string_drop
+ _stringappend_1625_
+ (build_ex
+ _stringappend_1627_) in
+ match (hex_bits_5_matches_prefix
+ _stringappend_1628_) with
+ | Some
+ (_stringappend_1629_,(existT _ _stringappend_1630_ _)) =>
+ let _stringappend_1631_ :=
+ string_drop
+ _stringappend_1628_
+ (build_ex
+ _stringappend_1630_) in
+ sep_matches_prefix
+ _stringappend_1631_ >>= fun w__589 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__589 with
+ | Some
+ (_stringappend_1632_,(existT _ _stringappend_1633_ _)) =>
+ let _stringappend_1634_ :=
+ string_drop
+ _stringappend_1631_
+ (build_ex
+ _stringappend_1633_) in
+ if
+ ((match (csr_name_map_matches_prefix
+ _stringappend_1634_) with
+ | Some
+ (_stringappend_1635_,(existT _ _stringappend_1636_ _)) =>
+ match (string_drop
+ _stringappend_1634_
+ (build_ex
+ _stringappend_1636_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__590 : bool =>
+ returnm ((if
+ (w__590)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__591 : bool =>
+ returnm ((if
+ (w__591)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__592 : bool =>
+ returnm ((if (w__592)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__593 : bool =>
+ returnm ((if (w__593)
+ then
+ true
+ else
+ false)
+ : bool)) >>= fun w__594 : bool =>
+ returnm ((if (w__594)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__595 : bool =>
+ (if (w__595) then
+ match (csr_mnemonic_matches_prefix
+ _stringappend_1112_) with
+ | Some
+ (_stringappend_1616_,(existT _ _stringappend_1617_ _)) =>
+ returnm ((_stringappend_1616_,
+ build_ex
+ _stringappend_1617_)
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__597 : (csrop * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(op, existT _ _stringappend_1617_ _) :=
+ w__597
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1618_ :=
+ string_drop
+ _stringappend_1112_
+ (build_ex
+ _stringappend_1617_) in
+ let _stringappend_1619_ :=
+ string_drop
+ _stringappend_1618_
+ (string_length
+ "i") in
+ match (spc_matches_prefix
+ _stringappend_1619_) with
+ | Some
+ (_stringappend_1620_,(existT _ _stringappend_1621_ _)) =>
+ returnm ((_stringappend_1620_,
+ build_ex
+ _stringappend_1621_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__599 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1621_ _) :=
+ w__599
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1622_ :=
+ string_drop
+ _stringappend_1619_
+ (build_ex
+ _stringappend_1621_) in
+ match (reg_name_matches_prefix
+ _stringappend_1622_) with
+ | Some
+ (_stringappend_1623_,(existT _ _stringappend_1624_ _)) =>
+ returnm ((_stringappend_1623_,
+ build_ex
+ _stringappend_1624_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__601 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1624_ _) :=
+ w__601
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1625_ :=
+ string_drop
+ _stringappend_1622_
+ (build_ex
+ _stringappend_1624_) in
+ sep_matches_prefix
+ _stringappend_1625_ >>= fun w__602 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__602 with
+ | Some
+ (_stringappend_1626_,(existT _ _stringappend_1627_ _)) =>
+ returnm ((_stringappend_1626_,
+ build_ex
+ _stringappend_1627_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__604 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1627_ _) :=
+ w__604
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1628_ :=
+ string_drop
+ _stringappend_1625_
+ (build_ex
+ _stringappend_1627_) in
+ match (hex_bits_5_matches_prefix
+ _stringappend_1628_) with
+ | Some
+ (_stringappend_1629_,(existT _ _stringappend_1630_ _)) =>
+ returnm ((_stringappend_1629_,
+ build_ex
+ _stringappend_1630_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__606 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1630_ _) :=
+ w__606
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1631_ :=
+ string_drop
+ _stringappend_1628_
+ (build_ex
+ _stringappend_1630_) in
+ sep_matches_prefix
+ _stringappend_1631_ >>= fun w__607 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__607 with
+ | Some
+ (_stringappend_1632_,(existT _ _stringappend_1633_ _)) =>
+ returnm ((_stringappend_1632_,
+ build_ex
+ _stringappend_1633_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__609 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1633_ _) :=
+ w__609
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1634_ :=
+ string_drop
+ _stringappend_1631_
+ (build_ex
+ _stringappend_1633_) in
+ match (csr_name_map_matches_prefix
+ _stringappend_1634_) with
+ | Some
+ (_stringappend_1635_,(existT _ _stringappend_1636_ _)) =>
+ returnm ((_stringappend_1635_,
+ build_ex
+ _stringappend_1636_)
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__611 : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(csr, existT _ _stringappend_1636_ _) :=
+ w__611
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1634_
+ (build_ex
+ _stringappend_1636_)) with
+ | "" =>
+ returnm ((CSR (csr,rs1,rd,true,op))
+ : ast)
+ | _ =>
+ exit tt
+ : M (ast)
+ end)
+ : M (ast)
+ else
+ match (csr_mnemonic_matches_prefix
+ _stringappend_1112_) with
+ | Some
+ (_stringappend_1638_,(existT _ _stringappend_1639_ _)) =>
+ let _stringappend_1640_ :=
+ string_drop
+ _stringappend_1112_
+ (build_ex
+ _stringappend_1639_) in
+ match (spc_matches_prefix
+ _stringappend_1640_) with
+ | Some
+ (_stringappend_1641_,(existT _ _stringappend_1642_ _)) =>
+ let _stringappend_1643_ :=
+ string_drop
+ _stringappend_1640_
+ (build_ex
+ _stringappend_1642_) in
+ match (reg_name_matches_prefix
+ _stringappend_1643_) with
+ | Some
+ (_stringappend_1644_,(existT _ _stringappend_1645_ _)) =>
+ let _stringappend_1646_ :=
+ string_drop
+ _stringappend_1643_
+ (build_ex
+ _stringappend_1645_) in
+ sep_matches_prefix
+ _stringappend_1646_ >>= fun w__614 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__614 with
+ | Some
+ (_stringappend_1647_,(existT _ _stringappend_1648_ _)) =>
+ let _stringappend_1649_ :=
+ string_drop
+ _stringappend_1646_
+ (build_ex
+ _stringappend_1648_) in
+ match (reg_name_matches_prefix
+ _stringappend_1649_) with
+ | Some
+ (_stringappend_1650_,(existT _ _stringappend_1651_ _)) =>
+ let _stringappend_1652_ :=
+ string_drop
+ _stringappend_1649_
+ (build_ex
+ _stringappend_1651_) in
+ sep_matches_prefix
+ _stringappend_1652_ >>= fun w__615 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__615 with
+ | Some
+ (_stringappend_1653_,(existT _ _stringappend_1654_ _)) =>
+ let _stringappend_1655_ :=
+ string_drop
+ _stringappend_1652_
+ (build_ex
+ _stringappend_1654_) in
+ if
+ ((match (csr_name_map_matches_prefix
+ _stringappend_1655_) with
+ | Some
+ (_stringappend_1656_,(existT _ _stringappend_1657_ _)) =>
+ match (string_drop
+ _stringappend_1655_
+ (build_ex
+ _stringappend_1657_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__616 : bool =>
+ returnm ((if
+ (w__616)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__617 : bool =>
+ returnm ((if
+ (w__617)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__618 : bool =>
+ returnm ((if
+ (w__618)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__619 : bool =>
+ returnm ((if (w__619)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__620 : bool =>
+ (if (w__620) then
+ match (csr_mnemonic_matches_prefix
+ _stringappend_1112_) with
+ | Some
+ (_stringappend_1638_,(existT _ _stringappend_1639_ _)) =>
+ returnm ((_stringappend_1638_,
+ build_ex
+ _stringappend_1639_)
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__622 : (csrop * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(op, existT _ _stringappend_1639_ _) :=
+ w__622
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1640_ :=
+ string_drop
+ _stringappend_1112_
+ (build_ex
+ _stringappend_1639_) in
+ match (spc_matches_prefix
+ _stringappend_1640_) with
+ | Some
+ (_stringappend_1641_,(existT _ _stringappend_1642_ _)) =>
+ returnm ((_stringappend_1641_,
+ build_ex
+ _stringappend_1642_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__624 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1642_ _) :=
+ w__624
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1643_ :=
+ string_drop
+ _stringappend_1640_
+ (build_ex
+ _stringappend_1642_) in
+ match (reg_name_matches_prefix
+ _stringappend_1643_) with
+ | Some
+ (_stringappend_1644_,(existT _ _stringappend_1645_ _)) =>
+ returnm ((_stringappend_1644_,
+ build_ex
+ _stringappend_1645_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__626 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1645_ _) :=
+ w__626
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1646_ :=
+ string_drop
+ _stringappend_1643_
+ (build_ex
+ _stringappend_1645_) in
+ sep_matches_prefix
+ _stringappend_1646_ >>= fun w__627 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__627 with
+ | Some
+ (_stringappend_1647_,(existT _ _stringappend_1648_ _)) =>
+ returnm ((_stringappend_1647_,
+ build_ex
+ _stringappend_1648_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__629 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1648_ _) :=
+ w__629
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1649_ :=
+ string_drop
+ _stringappend_1646_
+ (build_ex
+ _stringappend_1648_) in
+ match (reg_name_matches_prefix
+ _stringappend_1649_) with
+ | Some
+ (_stringappend_1650_,(existT _ _stringappend_1651_ _)) =>
+ returnm ((_stringappend_1650_,
+ build_ex
+ _stringappend_1651_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__631 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1651_ _) :=
+ w__631
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1652_ :=
+ string_drop
+ _stringappend_1649_
+ (build_ex
+ _stringappend_1651_) in
+ sep_matches_prefix
+ _stringappend_1652_ >>= fun w__632 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__632 with
+ | Some
+ (_stringappend_1653_,(existT _ _stringappend_1654_ _)) =>
+ returnm ((_stringappend_1653_,
+ build_ex
+ _stringappend_1654_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__634 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1654_ _) :=
+ w__634
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1655_ :=
+ string_drop
+ _stringappend_1652_
+ (build_ex
+ _stringappend_1654_) in
+ match (csr_name_map_matches_prefix
+ _stringappend_1655_) with
+ | Some
+ (_stringappend_1656_,(existT _ _stringappend_1657_ _)) =>
+ returnm ((_stringappend_1656_,
+ build_ex
+ _stringappend_1657_)
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__636 : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(csr, existT _ _stringappend_1657_ _) :=
+ w__636
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1655_
+ (build_ex
+ _stringappend_1657_)) with
+ | "" =>
+ returnm ((CSR (csr,rs1,rd,false,op))
+ : ast)
+ | _ =>
+ exit tt
+ : M (ast)
+ end)
+ : M (ast)
+ else
+ let _stringappend_1659_ :=
+ string_drop
+ _stringappend_1112_
+ (string_length
+ "illegal") in
+ match (spc_matches_prefix
+ _stringappend_1659_) with
+ | Some
+ (_stringappend_1660_,(existT _ _stringappend_1661_ _)) =>
+ returnm ((_stringappend_1660_,
+ build_ex
+ _stringappend_1661_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__640 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1661_ _) :=
+ w__640
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1662_ :=
+ string_drop
+ _stringappend_1659_
+ (build_ex
+ _stringappend_1661_) in
+ match (hex_bits_32_matches_prefix
+ _stringappend_1662_) with
+ | Some
+ (_stringappend_1663_,(existT _ _stringappend_1664_ _)) =>
+ returnm ((_stringappend_1663_,
+ build_ex
+ _stringappend_1664_)
+ : (mword 32 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 32 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__642 : (mword 32 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_1664_ _) :=
+ w__642
+ : (mword 32 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1662_
+ (build_ex
+ _stringappend_1664_)) with
+ | "" =>
+ returnm ((ILLEGAL s)
+ : ast)
+ | _ =>
+ exit tt
+ : M (ast)
+ end)
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast)
+ end)
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast))
+ : M (ast).
+
+Definition assembly_forwards_matches (arg_ : ast)
+: bool :=
+ match arg_ with
+ | UTYPE (imm,rd,op) => true
+ | RISCV_JAL (imm,rd) => true
+ | RISCV_JALR (imm,rs1,rd) => true
+ | BTYPE (imm,rs2,rs1,op) => true
+ | ITYPE (imm,rs1,rd,op) => true
+ | SHIFTIOP (shamt,rs1,rd,op) => true
+ | RTYPE (rs2,rs1,rd,op) => true
+ | LOAD (imm,rs1,rd,is_unsigned,size,aq,rl) => true
+ | STORE (imm,rs1,rd,size,aq,rl) => true
+ | ADDIW (imm,rs1,rd) => true
+ | SHIFTW (shamt,rs1,rd,op) => true
+ | RTYPEW (rs2,rs1,rd,op) => true
+ | SHIFTIWOP (shamt,rs1,rd,op) => true
+ | MUL (rs2,rs1,rd,high,signed1,signed2) => true
+ | DIV (rs2,rs1,rd,s) => true
+ | REM (rs2,rs1,rd,s) => true
+ | MULW (rs2,rs1,rd) => true
+ | DIVW (rs2,rs1,rd,s) => true
+ | REMW (rs2,rs1,rd,s) => true
+ | FENCE (pred,succ) => true
+ | FENCEI (tt) => true
+ | ECALL (tt) => true
+ | MRET (tt) => true
+ | SRET (tt) => true
+ | EBREAK (tt) => true
+ | WFI (tt) => true
+ | SFENCE_VMA (rs1,rs2) => true
+ | LOADRES (aq,rl,rs1,size,rd) => true
+ | STORECON (aq,rl,rs2,rs1,size,rd) => true
+ | AMO (op,aq,rl,rs2,rs1,width,rd) => true
+ | CSR (csr,rs1,rd,true,op) => true
+ | CSR (csr,rs1,rd,false,op) => true
+ | ILLEGAL (s) => true
+ | _ => false
+ end.
+
+Definition assembly_backwards_matches (arg_ : string)
+: M (bool) :=
+ let _stringappend_559_ := arg_ in
+ match (utype_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_560_,(existT _ _stringappend_561_ _)) =>
+ let _stringappend_562_ := string_drop _stringappend_559_ (build_ex _stringappend_561_) in
+ match (spc_matches_prefix _stringappend_562_) with
+ | Some (_stringappend_563_,(existT _ _stringappend_564_ _)) =>
+ let _stringappend_565_ := string_drop _stringappend_562_ (build_ex _stringappend_564_) in
+ match (reg_name_matches_prefix _stringappend_565_) with
+ | Some (_stringappend_566_,(existT _ _stringappend_567_ _)) =>
+ let _stringappend_568_ := string_drop _stringappend_565_ (build_ex _stringappend_567_) in
+ sep_matches_prefix _stringappend_568_ >>= fun w__0 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__0 with
+ | Some (_stringappend_569_,(existT _ _stringappend_570_ _)) =>
+ let _stringappend_571_ :=
+ string_drop _stringappend_568_ (build_ex _stringappend_570_) in
+ if ((match (hex_bits_20_matches_prefix _stringappend_571_) with
+ | Some (_stringappend_572_,(existT _ _stringappend_573_ _)) =>
+ match (string_drop _stringappend_571_
+ (build_ex
+ _stringappend_573_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__1 : bool =>
+ returnm ((if (w__1) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__2 : bool =>
+ returnm ((if (w__2) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__3 : bool =>
+ (if (w__3) then
+ match (utype_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_560_,(existT _ _stringappend_561_ _)) =>
+ returnm ((_stringappend_560_, build_ex _stringappend_561_)
+ : (uop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((uop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__5 : (uop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_561_ _) := w__5 : (uop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_562_ := string_drop _stringappend_559_ (build_ex _stringappend_561_) in
+ match (spc_matches_prefix _stringappend_562_) with
+ | Some (_stringappend_563_,(existT _ _stringappend_564_ _)) =>
+ returnm ((_stringappend_563_, build_ex _stringappend_564_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__7 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_564_ _) := w__7 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_565_ := string_drop _stringappend_562_ (build_ex _stringappend_564_) in
+ match (reg_name_matches_prefix _stringappend_565_) with
+ | Some (_stringappend_566_,(existT _ _stringappend_567_ _)) =>
+ returnm ((_stringappend_566_, build_ex _stringappend_567_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__9 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_567_ _) := w__9 : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_568_ := string_drop _stringappend_565_ (build_ex _stringappend_567_) in
+ sep_matches_prefix _stringappend_568_ >>= fun w__10 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__10 with
+ | Some (_stringappend_569_,(existT _ _stringappend_570_ _)) =>
+ returnm ((_stringappend_569_, build_ex _stringappend_570_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__12 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_570_ _) := w__12 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_571_ := string_drop _stringappend_568_ (build_ex _stringappend_570_) in
+ match (hex_bits_20_matches_prefix _stringappend_571_) with
+ | Some (_stringappend_572_,(existT _ _stringappend_573_ _)) =>
+ returnm ((_stringappend_572_, build_ex _stringappend_573_)
+ : (mword 20 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 20 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__14 : (mword 20 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_573_ _) :=
+ w__14
+ : (mword 20 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_571_ (build_ex _stringappend_573_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM (returnm ((string_startswith _stringappend_559_ "jal") : bool))
+ (let _stringappend_575_ := string_drop _stringappend_559_ (string_length "jal") in
+ match (spc_matches_prefix _stringappend_575_) with
+ | Some (_stringappend_576_,(existT _ _stringappend_577_ _)) =>
+ let _stringappend_578_ := string_drop _stringappend_575_ (build_ex _stringappend_577_) in
+ match (reg_name_matches_prefix _stringappend_578_) with
+ | Some (_stringappend_579_,(existT _ _stringappend_580_ _)) =>
+ let _stringappend_581_ := string_drop _stringappend_578_ (build_ex _stringappend_580_) in
+ sep_matches_prefix _stringappend_581_ >>= fun w__17 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__17 with
+ | Some (_stringappend_582_,(existT _ _stringappend_583_ _)) =>
+ let _stringappend_584_ :=
+ string_drop _stringappend_581_ (build_ex _stringappend_583_) in
+ if ((match (hex_bits_21_matches_prefix _stringappend_584_) with
+ | Some (_stringappend_585_,(existT _ _stringappend_586_ _)) =>
+ match (string_drop _stringappend_584_
+ (build_ex
+ _stringappend_586_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__18 : bool =>
+ returnm ((if (w__18) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__19 : bool =>
+ returnm ((if (w__19) then true
+ else false)
+ : bool)) >>= fun w__20 : bool =>
+ (if (w__20) then
+ let _stringappend_575_ := string_drop _stringappend_559_ (string_length "jal") in
+ match (spc_matches_prefix _stringappend_575_) with
+ | Some (_stringappend_576_,(existT _ _stringappend_577_ _)) =>
+ returnm ((_stringappend_576_, build_ex _stringappend_577_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__22 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_577_ _) := w__22 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_578_ := string_drop _stringappend_575_ (build_ex _stringappend_577_) in
+ match (reg_name_matches_prefix _stringappend_578_) with
+ | Some (_stringappend_579_,(existT _ _stringappend_580_ _)) =>
+ returnm ((_stringappend_579_, build_ex _stringappend_580_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__24 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_580_ _) :=
+ w__24
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_581_ := string_drop _stringappend_578_ (build_ex _stringappend_580_) in
+ sep_matches_prefix _stringappend_581_ >>= fun w__25 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__25 with
+ | Some (_stringappend_582_,(existT _ _stringappend_583_ _)) =>
+ returnm ((_stringappend_582_, build_ex _stringappend_583_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__27 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_583_ _) := w__27 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_584_ := string_drop _stringappend_581_ (build_ex _stringappend_583_) in
+ match (hex_bits_21_matches_prefix _stringappend_584_) with
+ | Some (_stringappend_585_,(existT _ _stringappend_586_ _)) =>
+ returnm ((_stringappend_585_, build_ex _stringappend_586_)
+ : (mword 21 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 21 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__29 : (mword 21 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_586_ _) :=
+ w__29
+ : (mword 21 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_584_ (build_ex _stringappend_586_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM (returnm ((string_startswith _stringappend_559_ "jalr") : bool))
+ (let _stringappend_588_ := string_drop _stringappend_559_ (string_length "jalr") in
+ match (spc_matches_prefix _stringappend_588_) with
+ | Some (_stringappend_589_,(existT _ _stringappend_590_ _)) =>
+ let _stringappend_591_ := string_drop _stringappend_588_ (build_ex _stringappend_590_) in
+ match (reg_name_matches_prefix _stringappend_591_) with
+ | Some (_stringappend_592_,(existT _ _stringappend_593_ _)) =>
+ let _stringappend_594_ :=
+ string_drop _stringappend_591_ (build_ex _stringappend_593_) in
+ sep_matches_prefix _stringappend_594_ >>= fun w__32 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__32 with
+ | Some (_stringappend_595_,(existT _ _stringappend_596_ _)) =>
+ let _stringappend_597_ :=
+ string_drop _stringappend_594_ (build_ex _stringappend_596_) in
+ match (reg_name_matches_prefix _stringappend_597_) with
+ | Some (_stringappend_598_,(existT _ _stringappend_599_ _)) =>
+ let _stringappend_600_ :=
+ string_drop _stringappend_597_ (build_ex _stringappend_599_) in
+ sep_matches_prefix _stringappend_600_ >>= fun w__33 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__33 with
+ | Some (_stringappend_601_,(existT _ _stringappend_602_ _)) =>
+ let _stringappend_603_ :=
+ string_drop _stringappend_600_
+ (build_ex
+ _stringappend_602_) in
+ if ((match (hex_bits_12_matches_prefix _stringappend_603_) with
+ | Some
+ (_stringappend_604_,(existT _ _stringappend_605_ _)) =>
+ match (string_drop _stringappend_603_
+ (build_ex
+ _stringappend_605_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__34 : bool =>
+ returnm ((if (w__34) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__35 : bool =>
+ returnm ((if (w__35) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__36 : bool =>
+ returnm ((if (w__36) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__37 : bool =>
+ returnm ((if (w__37) then true
+ else false)
+ : bool)) >>= fun w__38 : bool =>
+ (if (w__38) then
+ let _stringappend_588_ := string_drop _stringappend_559_ (string_length "jalr") in
+ match (spc_matches_prefix _stringappend_588_) with
+ | Some (_stringappend_589_,(existT _ _stringappend_590_ _)) =>
+ returnm ((_stringappend_589_, build_ex _stringappend_590_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__40 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_590_ _) :=
+ w__40
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_591_ := string_drop _stringappend_588_ (build_ex _stringappend_590_) in
+ match (reg_name_matches_prefix _stringappend_591_) with
+ | Some (_stringappend_592_,(existT _ _stringappend_593_ _)) =>
+ returnm ((_stringappend_592_, build_ex _stringappend_593_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__42 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_593_ _) :=
+ w__42
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_594_ := string_drop _stringappend_591_ (build_ex _stringappend_593_) in
+ sep_matches_prefix _stringappend_594_ >>= fun w__43 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__43 with
+ | Some (_stringappend_595_,(existT _ _stringappend_596_ _)) =>
+ returnm ((_stringappend_595_, build_ex _stringappend_596_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__45 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_596_ _) :=
+ w__45
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_597_ := string_drop _stringappend_594_ (build_ex _stringappend_596_) in
+ match (reg_name_matches_prefix _stringappend_597_) with
+ | Some (_stringappend_598_,(existT _ _stringappend_599_ _)) =>
+ returnm ((_stringappend_598_, build_ex _stringappend_599_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__47 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_599_ _) :=
+ w__47
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_600_ := string_drop _stringappend_597_ (build_ex _stringappend_599_) in
+ sep_matches_prefix _stringappend_600_ >>= fun w__48 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__48 with
+ | Some (_stringappend_601_,(existT _ _stringappend_602_ _)) =>
+ returnm ((_stringappend_601_, build_ex _stringappend_602_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__50 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_602_ _) :=
+ w__50
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_603_ := string_drop _stringappend_600_ (build_ex _stringappend_602_) in
+ match (hex_bits_12_matches_prefix _stringappend_603_) with
+ | Some (_stringappend_604_,(existT _ _stringappend_605_ _)) =>
+ returnm ((_stringappend_604_, build_ex _stringappend_605_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__52 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_605_ _) :=
+ w__52
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_603_ (build_ex _stringappend_605_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ match (btype_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_607_,(existT _ _stringappend_608_ _)) =>
+ let _stringappend_609_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_608_) in
+ match (spc_matches_prefix _stringappend_609_) with
+ | Some (_stringappend_610_,(existT _ _stringappend_611_ _)) =>
+ let _stringappend_612_ :=
+ string_drop _stringappend_609_ (build_ex _stringappend_611_) in
+ match (reg_name_matches_prefix _stringappend_612_) with
+ | Some (_stringappend_613_,(existT _ _stringappend_614_ _)) =>
+ let _stringappend_615_ :=
+ string_drop _stringappend_612_ (build_ex _stringappend_614_) in
+ sep_matches_prefix _stringappend_615_ >>= fun w__55 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__55 with
+ | Some (_stringappend_616_,(existT _ _stringappend_617_ _)) =>
+ let _stringappend_618_ :=
+ string_drop _stringappend_615_ (build_ex _stringappend_617_) in
+ match (reg_name_matches_prefix _stringappend_618_) with
+ | Some (_stringappend_619_,(existT _ _stringappend_620_ _)) =>
+ let _stringappend_621_ :=
+ string_drop _stringappend_618_ (build_ex _stringappend_620_) in
+ sep_matches_prefix _stringappend_621_ >>= fun w__56 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__56 with
+ | Some
+ (_stringappend_622_,(existT _ _stringappend_623_ _)) =>
+ let _stringappend_624_ :=
+ string_drop _stringappend_621_
+ (build_ex
+ _stringappend_623_) in
+ if ((match (hex_bits_13_matches_prefix
+ _stringappend_624_) with
+ | Some
+ (_stringappend_625_,(existT _ _stringappend_626_ _)) =>
+ match (string_drop _stringappend_624_
+ (build_ex
+ _stringappend_626_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__57 : bool =>
+ returnm ((if (w__57) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__58 : bool =>
+ returnm ((if (w__58) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__59 : bool =>
+ returnm ((if (w__59) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__60 : bool =>
+ returnm ((if (w__60) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__61 : bool =>
+ (if (w__61) then
+ match (btype_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_607_,(existT _ _stringappend_608_ _)) =>
+ returnm ((_stringappend_607_, build_ex _stringappend_608_)
+ : (bop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__63 : (bop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_608_ _) :=
+ w__63
+ : (bop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_609_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_608_) in
+ match (spc_matches_prefix _stringappend_609_) with
+ | Some (_stringappend_610_,(existT _ _stringappend_611_ _)) =>
+ returnm ((_stringappend_610_, build_ex _stringappend_611_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__65 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_611_ _) :=
+ w__65
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_612_ :=
+ string_drop _stringappend_609_ (build_ex _stringappend_611_) in
+ match (reg_name_matches_prefix _stringappend_612_) with
+ | Some (_stringappend_613_,(existT _ _stringappend_614_ _)) =>
+ returnm ((_stringappend_613_, build_ex _stringappend_614_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__67 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_614_ _) :=
+ w__67
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_615_ :=
+ string_drop _stringappend_612_ (build_ex _stringappend_614_) in
+ sep_matches_prefix _stringappend_615_ >>= fun w__68 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__68 with
+ | Some (_stringappend_616_,(existT _ _stringappend_617_ _)) =>
+ returnm ((_stringappend_616_, build_ex _stringappend_617_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__70 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_617_ _) :=
+ w__70
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_618_ :=
+ string_drop _stringappend_615_ (build_ex _stringappend_617_) in
+ match (reg_name_matches_prefix _stringappend_618_) with
+ | Some (_stringappend_619_,(existT _ _stringappend_620_ _)) =>
+ returnm ((_stringappend_619_, build_ex _stringappend_620_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__72 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs2, existT _ _stringappend_620_ _) :=
+ w__72
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_621_ :=
+ string_drop _stringappend_618_ (build_ex _stringappend_620_) in
+ sep_matches_prefix _stringappend_621_ >>= fun w__73 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__73 with
+ | Some (_stringappend_622_,(existT _ _stringappend_623_ _)) =>
+ returnm ((_stringappend_622_, build_ex _stringappend_623_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__75 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_623_ _) :=
+ w__75
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_624_ :=
+ string_drop _stringappend_621_ (build_ex _stringappend_623_) in
+ match (hex_bits_13_matches_prefix _stringappend_624_) with
+ | Some (_stringappend_625_,(existT _ _stringappend_626_ _)) =>
+ returnm ((_stringappend_625_, build_ex _stringappend_626_)
+ : (mword 13 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 13 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__77 : (mword 13 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_626_ _) :=
+ w__77
+ : (mword 13 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_624_ (build_ex _stringappend_626_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ match (itype_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_628_,(existT _ _stringappend_629_ _)) =>
+ let _stringappend_630_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_629_) in
+ match (spc_matches_prefix _stringappend_630_) with
+ | Some (_stringappend_631_,(existT _ _stringappend_632_ _)) =>
+ let _stringappend_633_ :=
+ string_drop _stringappend_630_ (build_ex _stringappend_632_) in
+ match (reg_name_matches_prefix _stringappend_633_) with
+ | Some (_stringappend_634_,(existT _ _stringappend_635_ _)) =>
+ let _stringappend_636_ :=
+ string_drop _stringappend_633_ (build_ex _stringappend_635_) in
+ sep_matches_prefix _stringappend_636_ >>= fun w__80 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__80 with
+ | Some (_stringappend_637_,(existT _ _stringappend_638_ _)) =>
+ let _stringappend_639_ :=
+ string_drop _stringappend_636_ (build_ex _stringappend_638_) in
+ match (reg_name_matches_prefix _stringappend_639_) with
+ | Some (_stringappend_640_,(existT _ _stringappend_641_ _)) =>
+ let _stringappend_642_ :=
+ string_drop _stringappend_639_ (build_ex _stringappend_641_) in
+ sep_matches_prefix _stringappend_642_ >>= fun w__81 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__81 with
+ | Some
+ (_stringappend_643_,(existT _ _stringappend_644_ _)) =>
+ let _stringappend_645_ :=
+ string_drop _stringappend_642_
+ (build_ex
+ _stringappend_644_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_645_) with
+ | Some
+ (_stringappend_646_,(existT _ _stringappend_647_ _)) =>
+ match (string_drop _stringappend_645_
+ (build_ex
+ _stringappend_647_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__82 : bool =>
+ returnm ((if (w__82) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__83 : bool =>
+ returnm ((if (w__83) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__84 : bool =>
+ returnm ((if (w__84) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__85 : bool =>
+ returnm ((if (w__85) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__86 : bool =>
+ (if (w__86) then
+ match (itype_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_628_,(existT _ _stringappend_629_ _)) =>
+ returnm ((_stringappend_628_, build_ex _stringappend_629_)
+ : (iop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((iop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__88 : (iop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_629_ _) :=
+ w__88
+ : (iop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_630_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_629_) in
+ match (spc_matches_prefix _stringappend_630_) with
+ | Some (_stringappend_631_,(existT _ _stringappend_632_ _)) =>
+ returnm ((_stringappend_631_, build_ex _stringappend_632_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__90 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_632_ _) :=
+ w__90
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_633_ :=
+ string_drop _stringappend_630_ (build_ex _stringappend_632_) in
+ match (reg_name_matches_prefix _stringappend_633_) with
+ | Some (_stringappend_634_,(existT _ _stringappend_635_ _)) =>
+ returnm ((_stringappend_634_, build_ex _stringappend_635_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__92 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_635_ _) :=
+ w__92
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_636_ :=
+ string_drop _stringappend_633_ (build_ex _stringappend_635_) in
+ sep_matches_prefix _stringappend_636_ >>= fun w__93 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__93 with
+ | Some (_stringappend_637_,(existT _ _stringappend_638_ _)) =>
+ returnm ((_stringappend_637_, build_ex _stringappend_638_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__95 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_638_ _) :=
+ w__95
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_639_ :=
+ string_drop _stringappend_636_ (build_ex _stringappend_638_) in
+ match (reg_name_matches_prefix _stringappend_639_) with
+ | Some (_stringappend_640_,(existT _ _stringappend_641_ _)) =>
+ returnm ((_stringappend_640_, build_ex _stringappend_641_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__97 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_641_ _) :=
+ w__97
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_642_ :=
+ string_drop _stringappend_639_ (build_ex _stringappend_641_) in
+ sep_matches_prefix _stringappend_642_ >>= fun w__98 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__98 with
+ | Some (_stringappend_643_,(existT _ _stringappend_644_ _)) =>
+ returnm ((_stringappend_643_, build_ex _stringappend_644_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__100 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_644_ _) :=
+ w__100
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_645_ :=
+ string_drop _stringappend_642_ (build_ex _stringappend_644_) in
+ match (hex_bits_12_matches_prefix _stringappend_645_) with
+ | Some (_stringappend_646_,(existT _ _stringappend_647_ _)) =>
+ returnm ((_stringappend_646_, build_ex _stringappend_647_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__102 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_647_ _) :=
+ w__102
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_645_ (build_ex _stringappend_647_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ match (shiftiop_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_649_,(existT _ _stringappend_650_ _)) =>
+ let _stringappend_651_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_650_) in
+ match (spc_matches_prefix _stringappend_651_) with
+ | Some (_stringappend_652_,(existT _ _stringappend_653_ _)) =>
+ let _stringappend_654_ :=
+ string_drop _stringappend_651_ (build_ex _stringappend_653_) in
+ match (reg_name_matches_prefix _stringappend_654_) with
+ | Some (_stringappend_655_,(existT _ _stringappend_656_ _)) =>
+ let _stringappend_657_ :=
+ string_drop _stringappend_654_ (build_ex _stringappend_656_) in
+ sep_matches_prefix _stringappend_657_ >>= fun w__105 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__105 with
+ | Some
+ (_stringappend_658_,(existT _ _stringappend_659_ _)) =>
+ let _stringappend_660_ :=
+ string_drop _stringappend_657_
+ (build_ex
+ _stringappend_659_) in
+ if ((match (reg_name_matches_prefix _stringappend_660_) with
+ | Some
+ (_stringappend_661_,(existT _ _stringappend_662_ _)) =>
+ let _stringappend_663_ :=
+ string_drop _stringappend_660_
+ (build_ex
+ _stringappend_662_) in
+ if ((match (hex_bits_6_matches_prefix
+ _stringappend_663_) with
+ | Some
+ (_stringappend_664_,(existT _ _stringappend_665_ _)) =>
+ match (string_drop _stringappend_663_
+ (build_ex
+ _stringappend_665_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__106 : bool =>
+ returnm ((if (w__106) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__107 : bool =>
+ returnm ((if (w__107) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__108 : bool =>
+ (if (w__108) then
+ match (shiftiop_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_649_,(existT _ _stringappend_650_ _)) =>
+ returnm ((_stringappend_649_, build_ex _stringappend_650_)
+ : (sop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((sop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__110 : (sop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_650_ _) :=
+ w__110
+ : (sop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_651_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_650_) in
+ match (spc_matches_prefix _stringappend_651_) with
+ | Some (_stringappend_652_,(existT _ _stringappend_653_ _)) =>
+ returnm ((_stringappend_652_, build_ex _stringappend_653_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__112 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_653_ _) :=
+ w__112
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_654_ :=
+ string_drop _stringappend_651_ (build_ex _stringappend_653_) in
+ match (reg_name_matches_prefix _stringappend_654_) with
+ | Some (_stringappend_655_,(existT _ _stringappend_656_ _)) =>
+ returnm ((_stringappend_655_, build_ex _stringappend_656_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__114 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_656_ _) :=
+ w__114
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_657_ :=
+ string_drop _stringappend_654_ (build_ex _stringappend_656_) in
+ sep_matches_prefix _stringappend_657_ >>= fun w__115 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__115 with
+ | Some (_stringappend_658_,(existT _ _stringappend_659_ _)) =>
+ returnm ((_stringappend_658_, build_ex _stringappend_659_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__117 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_659_ _) :=
+ w__117
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_660_ :=
+ string_drop _stringappend_657_ (build_ex _stringappend_659_) in
+ match (reg_name_matches_prefix _stringappend_660_) with
+ | Some (_stringappend_661_,(existT _ _stringappend_662_ _)) =>
+ returnm ((_stringappend_661_, build_ex _stringappend_662_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__119 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_662_ _) :=
+ w__119
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_663_ :=
+ string_drop _stringappend_660_ (build_ex _stringappend_662_) in
+ match (hex_bits_6_matches_prefix _stringappend_663_) with
+ | Some (_stringappend_664_,(existT _ _stringappend_665_ _)) =>
+ returnm ((_stringappend_664_, build_ex _stringappend_665_)
+ : (mword 6 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 6 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__121 : (mword 6 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(shamt, existT _ _stringappend_665_ _) :=
+ w__121
+ : (mword 6 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_663_ (build_ex _stringappend_665_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ match (rtype_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_667_,(existT _ _stringappend_668_ _)) =>
+ let _stringappend_669_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_668_) in
+ match (spc_matches_prefix _stringappend_669_) with
+ | Some (_stringappend_670_,(existT _ _stringappend_671_ _)) =>
+ let _stringappend_672_ :=
+ string_drop _stringappend_669_ (build_ex _stringappend_671_) in
+ match (reg_name_matches_prefix _stringappend_672_) with
+ | Some (_stringappend_673_,(existT _ _stringappend_674_ _)) =>
+ let _stringappend_675_ :=
+ string_drop _stringappend_672_ (build_ex _stringappend_674_) in
+ sep_matches_prefix _stringappend_675_ >>= fun w__124 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__124 with
+ | Some (_stringappend_676_,(existT _ _stringappend_677_ _)) =>
+ let _stringappend_678_ :=
+ string_drop _stringappend_675_ (build_ex _stringappend_677_) in
+ match (reg_name_matches_prefix _stringappend_678_) with
+ | Some (_stringappend_679_,(existT _ _stringappend_680_ _)) =>
+ let _stringappend_681_ :=
+ string_drop _stringappend_678_ (build_ex _stringappend_680_) in
+ sep_matches_prefix _stringappend_681_ >>= fun w__125 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__125 with
+ | Some
+ (_stringappend_682_,(existT _ _stringappend_683_ _)) =>
+ let _stringappend_684_ :=
+ string_drop _stringappend_681_
+ (build_ex
+ _stringappend_683_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_684_) with
+ | Some
+ (_stringappend_685_,(existT _ _stringappend_686_ _)) =>
+ match (string_drop _stringappend_684_
+ (build_ex
+ _stringappend_686_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__126 : bool =>
+ returnm ((if (w__126) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__127 : bool =>
+ returnm ((if (w__127) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__128 : bool =>
+ returnm ((if (w__128) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__129 : bool =>
+ returnm ((if (w__129) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__130 : bool =>
+ (if (w__130) then
+ match (rtype_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_667_,(existT _ _stringappend_668_ _)) =>
+ returnm ((_stringappend_667_, build_ex _stringappend_668_)
+ : (rop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((rop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__132 : (rop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_668_ _) :=
+ w__132
+ : (rop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_669_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_668_) in
+ match (spc_matches_prefix _stringappend_669_) with
+ | Some (_stringappend_670_,(existT _ _stringappend_671_ _)) =>
+ returnm ((_stringappend_670_, build_ex _stringappend_671_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__134 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_671_ _) :=
+ w__134
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_672_ :=
+ string_drop _stringappend_669_ (build_ex _stringappend_671_) in
+ match (reg_name_matches_prefix _stringappend_672_) with
+ | Some (_stringappend_673_,(existT _ _stringappend_674_ _)) =>
+ returnm ((_stringappend_673_, build_ex _stringappend_674_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__136 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_674_ _) :=
+ w__136
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_675_ :=
+ string_drop _stringappend_672_ (build_ex _stringappend_674_) in
+ sep_matches_prefix _stringappend_675_ >>= fun w__137 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__137 with
+ | Some (_stringappend_676_,(existT _ _stringappend_677_ _)) =>
+ returnm ((_stringappend_676_, build_ex _stringappend_677_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__139 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_677_ _) :=
+ w__139
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_678_ :=
+ string_drop _stringappend_675_ (build_ex _stringappend_677_) in
+ match (reg_name_matches_prefix _stringappend_678_) with
+ | Some (_stringappend_679_,(existT _ _stringappend_680_ _)) =>
+ returnm ((_stringappend_679_, build_ex _stringappend_680_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__141 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_680_ _) :=
+ w__141
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_681_ :=
+ string_drop _stringappend_678_ (build_ex _stringappend_680_) in
+ sep_matches_prefix _stringappend_681_ >>= fun w__142 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__142 with
+ | Some (_stringappend_682_,(existT _ _stringappend_683_ _)) =>
+ returnm ((_stringappend_682_, build_ex _stringappend_683_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__144 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_683_ _) :=
+ w__144
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_684_ :=
+ string_drop _stringappend_681_ (build_ex _stringappend_683_) in
+ match (reg_name_matches_prefix _stringappend_684_) with
+ | Some (_stringappend_685_,(existT _ _stringappend_686_ _)) =>
+ returnm ((_stringappend_685_, build_ex _stringappend_686_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__146 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs2, existT _ _stringappend_686_ _) :=
+ w__146
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_684_ (build_ex _stringappend_686_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM (returnm ((string_startswith _stringappend_559_ "l") : bool))
+ (let _stringappend_688_ :=
+ string_drop _stringappend_559_ (string_length "l") in
+ match (size_mnemonic_matches_prefix _stringappend_688_) with
+ | Some (_stringappend_689_,(existT _ _stringappend_690_ _)) =>
+ let _stringappend_691_ :=
+ string_drop _stringappend_688_ (build_ex _stringappend_690_) in
+ match (maybe_u_matches_prefix _stringappend_691_) with
+ | Some (_stringappend_692_,(existT _ _stringappend_693_ _)) =>
+ let _stringappend_694_ :=
+ string_drop _stringappend_691_ (build_ex _stringappend_693_) in
+ match (maybe_aq_matches_prefix _stringappend_694_) with
+ | Some (_stringappend_695_,(existT _ _stringappend_696_ _)) =>
+ let _stringappend_697_ :=
+ string_drop _stringappend_694_ (build_ex _stringappend_696_) in
+ match (maybe_rl_matches_prefix _stringappend_697_) with
+ | Some (_stringappend_698_,(existT _ _stringappend_699_ _)) =>
+ let _stringappend_700_ :=
+ string_drop _stringappend_697_ (build_ex _stringappend_699_) in
+ match (spc_matches_prefix _stringappend_700_) with
+ | Some (_stringappend_701_,(existT _ _stringappend_702_ _)) =>
+ let _stringappend_703_ :=
+ string_drop _stringappend_700_
+ (build_ex
+ _stringappend_702_) in
+ match (reg_name_matches_prefix _stringappend_703_) with
+ | Some (_stringappend_704_,(existT _ _stringappend_705_ _)) =>
+ let _stringappend_706_ :=
+ string_drop _stringappend_703_
+ (build_ex
+ _stringappend_705_) in
+ sep_matches_prefix _stringappend_706_ >>= fun w__149 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__149 with
+ | Some
+ (_stringappend_707_,(existT _ _stringappend_708_ _)) =>
+ let _stringappend_709_ :=
+ string_drop _stringappend_706_
+ (build_ex
+ _stringappend_708_) in
+ match (reg_name_matches_prefix _stringappend_709_) with
+ | Some
+ (_stringappend_710_,(existT _ _stringappend_711_ _)) =>
+ let _stringappend_712_ :=
+ string_drop _stringappend_709_
+ (build_ex
+ _stringappend_711_) in
+ sep_matches_prefix _stringappend_712_ >>= fun w__150 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__150 with
+ | Some
+ (_stringappend_713_,(existT _ _stringappend_714_ _)) =>
+ let _stringappend_715_ :=
+ string_drop _stringappend_712_
+ (build_ex
+ _stringappend_714_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_715_) with
+ | Some
+ (_stringappend_716_,(existT _ _stringappend_717_ _)) =>
+ match (string_drop
+ _stringappend_715_
+ (build_ex
+ _stringappend_717_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__151 : bool =>
+ returnm ((if (w__151) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__152 : bool =>
+ returnm ((if (w__152) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__153 : bool =>
+ returnm ((if (w__153) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__154 : bool =>
+ returnm ((if (w__154) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__155 : bool =>
+ returnm ((if (w__155) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__156 : bool =>
+ returnm ((if (w__156) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__157 : bool =>
+ returnm ((if (w__157) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__158 : bool =>
+ returnm ((if (w__158) then true
+ else false)
+ : bool)) >>= fun w__159 : bool =>
+ (if (w__159) then
+ let _stringappend_688_ :=
+ string_drop _stringappend_559_ (string_length "l") in
+ match (size_mnemonic_matches_prefix _stringappend_688_) with
+ | Some (_stringappend_689_,(existT _ _stringappend_690_ _)) =>
+ returnm ((_stringappend_689_, build_ex _stringappend_690_)
+ : (word_width * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((word_width * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__161 : (word_width * {n : Z & ArithFact (n >= 0)}) =>
+ let '(size, existT _ _stringappend_690_ _) :=
+ w__161
+ : (word_width * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_691_ :=
+ string_drop _stringappend_688_ (build_ex _stringappend_690_) in
+ match (maybe_u_matches_prefix _stringappend_691_) with
+ | Some (_stringappend_692_,(existT _ _stringappend_693_ _)) =>
+ returnm ((_stringappend_692_, build_ex _stringappend_693_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__163 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(is_unsigned, existT _ _stringappend_693_ _) :=
+ w__163
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_694_ :=
+ string_drop _stringappend_691_ (build_ex _stringappend_693_) in
+ match (maybe_aq_matches_prefix _stringappend_694_) with
+ | Some (_stringappend_695_,(existT _ _stringappend_696_ _)) =>
+ returnm ((_stringappend_695_, build_ex _stringappend_696_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__165 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(aq, existT _ _stringappend_696_ _) :=
+ w__165
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_697_ :=
+ string_drop _stringappend_694_ (build_ex _stringappend_696_) in
+ match (maybe_rl_matches_prefix _stringappend_697_) with
+ | Some (_stringappend_698_,(existT _ _stringappend_699_ _)) =>
+ returnm ((_stringappend_698_, build_ex _stringappend_699_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__167 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rl, existT _ _stringappend_699_ _) :=
+ w__167
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_700_ :=
+ string_drop _stringappend_697_ (build_ex _stringappend_699_) in
+ match (spc_matches_prefix _stringappend_700_) with
+ | Some (_stringappend_701_,(existT _ _stringappend_702_ _)) =>
+ returnm ((_stringappend_701_, build_ex _stringappend_702_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__169 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_702_ _) :=
+ w__169
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_703_ :=
+ string_drop _stringappend_700_ (build_ex _stringappend_702_) in
+ match (reg_name_matches_prefix _stringappend_703_) with
+ | Some (_stringappend_704_,(existT _ _stringappend_705_ _)) =>
+ returnm ((_stringappend_704_, build_ex _stringappend_705_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__171 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_705_ _) :=
+ w__171
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_706_ :=
+ string_drop _stringappend_703_ (build_ex _stringappend_705_) in
+ sep_matches_prefix _stringappend_706_ >>= fun w__172 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__172 with
+ | Some (_stringappend_707_,(existT _ _stringappend_708_ _)) =>
+ returnm ((_stringappend_707_, build_ex _stringappend_708_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__174 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_708_ _) :=
+ w__174
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_709_ :=
+ string_drop _stringappend_706_ (build_ex _stringappend_708_) in
+ match (reg_name_matches_prefix _stringappend_709_) with
+ | Some (_stringappend_710_,(existT _ _stringappend_711_ _)) =>
+ returnm ((_stringappend_710_, build_ex _stringappend_711_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__176 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_711_ _) :=
+ w__176
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_712_ :=
+ string_drop _stringappend_709_ (build_ex _stringappend_711_) in
+ sep_matches_prefix _stringappend_712_ >>= fun w__177 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__177 with
+ | Some (_stringappend_713_,(existT _ _stringappend_714_ _)) =>
+ returnm ((_stringappend_713_, build_ex _stringappend_714_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__179 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_714_ _) :=
+ w__179
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_715_ :=
+ string_drop _stringappend_712_ (build_ex _stringappend_714_) in
+ match (hex_bits_12_matches_prefix _stringappend_715_) with
+ | Some (_stringappend_716_,(existT _ _stringappend_717_ _)) =>
+ returnm ((_stringappend_716_, build_ex _stringappend_717_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__181 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_717_ _) :=
+ w__181
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_715_ (build_ex _stringappend_717_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM (returnm ((string_startswith _stringappend_559_ "s") : bool))
+ (let _stringappend_719_ :=
+ string_drop _stringappend_559_ (string_length "s") in
+ match (size_mnemonic_matches_prefix _stringappend_719_) with
+ | Some (_stringappend_720_,(existT _ _stringappend_721_ _)) =>
+ let _stringappend_722_ :=
+ string_drop _stringappend_719_ (build_ex _stringappend_721_) in
+ match (maybe_aq_matches_prefix _stringappend_722_) with
+ | Some (_stringappend_723_,(existT _ _stringappend_724_ _)) =>
+ let _stringappend_725_ :=
+ string_drop _stringappend_722_ (build_ex _stringappend_724_) in
+ match (maybe_rl_matches_prefix _stringappend_725_) with
+ | Some (_stringappend_726_,(existT _ _stringappend_727_ _)) =>
+ let _stringappend_728_ :=
+ string_drop _stringappend_725_ (build_ex _stringappend_727_) in
+ match (spc_matches_prefix _stringappend_728_) with
+ | Some (_stringappend_729_,(existT _ _stringappend_730_ _)) =>
+ let _stringappend_731_ :=
+ string_drop _stringappend_728_
+ (build_ex
+ _stringappend_730_) in
+ match (reg_name_matches_prefix _stringappend_731_) with
+ | Some (_stringappend_732_,(existT _ _stringappend_733_ _)) =>
+ let _stringappend_734_ :=
+ string_drop _stringappend_731_
+ (build_ex
+ _stringappend_733_) in
+ sep_matches_prefix _stringappend_734_ >>= fun w__184 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__184 with
+ | Some
+ (_stringappend_735_,(existT _ _stringappend_736_ _)) =>
+ let _stringappend_737_ :=
+ string_drop _stringappend_734_
+ (build_ex
+ _stringappend_736_) in
+ match (reg_name_matches_prefix _stringappend_737_) with
+ | Some
+ (_stringappend_738_,(existT _ _stringappend_739_ _)) =>
+ let _stringappend_740_ :=
+ string_drop _stringappend_737_
+ (build_ex
+ _stringappend_739_) in
+ sep_matches_prefix _stringappend_740_ >>= fun w__185 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__185 with
+ | Some
+ (_stringappend_741_,(existT _ _stringappend_742_ _)) =>
+ let _stringappend_743_ :=
+ string_drop _stringappend_740_
+ (build_ex
+ _stringappend_742_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_743_) with
+ | Some
+ (_stringappend_744_,(existT _ _stringappend_745_ _)) =>
+ match (string_drop
+ _stringappend_743_
+ (build_ex
+ _stringappend_745_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__186 : bool =>
+ returnm ((if (w__186) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__187 : bool =>
+ returnm ((if (w__187) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__188 : bool =>
+ returnm ((if (w__188) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__189 : bool =>
+ returnm ((if (w__189) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__190 : bool =>
+ returnm ((if (w__190) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__191 : bool =>
+ returnm ((if (w__191) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__192 : bool =>
+ returnm ((if (w__192) then true
+ else false)
+ : bool)) >>= fun w__193 : bool =>
+ (if (w__193) then
+ let _stringappend_719_ :=
+ string_drop _stringappend_559_ (string_length "s") in
+ match (size_mnemonic_matches_prefix _stringappend_719_) with
+ | Some (_stringappend_720_,(existT _ _stringappend_721_ _)) =>
+ returnm ((_stringappend_720_, build_ex _stringappend_721_)
+ : (word_width * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((word_width * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__195 : (word_width * {n : Z & ArithFact (n >= 0)}) =>
+ let '(size, existT _ _stringappend_721_ _) :=
+ w__195
+ : (word_width * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_722_ :=
+ string_drop _stringappend_719_ (build_ex _stringappend_721_) in
+ match (maybe_aq_matches_prefix _stringappend_722_) with
+ | Some (_stringappend_723_,(existT _ _stringappend_724_ _)) =>
+ returnm ((_stringappend_723_, build_ex _stringappend_724_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__197 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(aq, existT _ _stringappend_724_ _) :=
+ w__197
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_725_ :=
+ string_drop _stringappend_722_ (build_ex _stringappend_724_) in
+ match (maybe_rl_matches_prefix _stringappend_725_) with
+ | Some (_stringappend_726_,(existT _ _stringappend_727_ _)) =>
+ returnm ((_stringappend_726_, build_ex _stringappend_727_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__199 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rl, existT _ _stringappend_727_ _) :=
+ w__199
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_728_ :=
+ string_drop _stringappend_725_ (build_ex _stringappend_727_) in
+ match (spc_matches_prefix _stringappend_728_) with
+ | Some (_stringappend_729_,(existT _ _stringappend_730_ _)) =>
+ returnm ((_stringappend_729_, build_ex _stringappend_730_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__201 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_730_ _) :=
+ w__201
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_731_ :=
+ string_drop _stringappend_728_ (build_ex _stringappend_730_) in
+ match (reg_name_matches_prefix _stringappend_731_) with
+ | Some (_stringappend_732_,(existT _ _stringappend_733_ _)) =>
+ returnm ((_stringappend_732_, build_ex _stringappend_733_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__203 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_733_ _) :=
+ w__203
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_734_ :=
+ string_drop _stringappend_731_ (build_ex _stringappend_733_) in
+ sep_matches_prefix _stringappend_734_ >>= fun w__204 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__204 with
+ | Some (_stringappend_735_,(existT _ _stringappend_736_ _)) =>
+ returnm ((_stringappend_735_, build_ex _stringappend_736_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__206 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_736_ _) :=
+ w__206
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_737_ :=
+ string_drop _stringappend_734_ (build_ex _stringappend_736_) in
+ match (reg_name_matches_prefix _stringappend_737_) with
+ | Some (_stringappend_738_,(existT _ _stringappend_739_ _)) =>
+ returnm ((_stringappend_738_, build_ex _stringappend_739_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__208 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_739_ _) :=
+ w__208
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_740_ :=
+ string_drop _stringappend_737_ (build_ex _stringappend_739_) in
+ sep_matches_prefix _stringappend_740_ >>= fun w__209 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__209 with
+ | Some (_stringappend_741_,(existT _ _stringappend_742_ _)) =>
+ returnm ((_stringappend_741_, build_ex _stringappend_742_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__211 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_742_ _) :=
+ w__211
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_743_ :=
+ string_drop _stringappend_740_ (build_ex _stringappend_742_) in
+ match (hex_bits_12_matches_prefix _stringappend_743_) with
+ | Some (_stringappend_744_,(existT _ _stringappend_745_ _)) =>
+ returnm ((_stringappend_744_, build_ex _stringappend_745_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__213 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_745_ _) :=
+ w__213
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_743_ (build_ex _stringappend_745_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_559_ "addiw")
+ : bool))
+ (let _stringappend_747_ :=
+ string_drop _stringappend_559_ (string_length "addiw") in
+ match (spc_matches_prefix _stringappend_747_) with
+ | Some (_stringappend_748_,(existT _ _stringappend_749_ _)) =>
+ let _stringappend_750_ :=
+ string_drop _stringappend_747_ (build_ex _stringappend_749_) in
+ match (reg_name_matches_prefix _stringappend_750_) with
+ | Some (_stringappend_751_,(existT _ _stringappend_752_ _)) =>
+ let _stringappend_753_ :=
+ string_drop _stringappend_750_ (build_ex _stringappend_752_) in
+ sep_matches_prefix _stringappend_753_ >>= fun w__216 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__216 with
+ | Some (_stringappend_754_,(existT _ _stringappend_755_ _)) =>
+ let _stringappend_756_ :=
+ string_drop _stringappend_753_
+ (build_ex
+ _stringappend_755_) in
+ match (reg_name_matches_prefix _stringappend_756_) with
+ | Some (_stringappend_757_,(existT _ _stringappend_758_ _)) =>
+ let _stringappend_759_ :=
+ string_drop _stringappend_756_
+ (build_ex
+ _stringappend_758_) in
+ sep_matches_prefix _stringappend_759_ >>= fun w__217 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__217 with
+ | Some
+ (_stringappend_760_,(existT _ _stringappend_761_ _)) =>
+ let _stringappend_762_ :=
+ string_drop _stringappend_759_
+ (build_ex
+ _stringappend_761_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_762_) with
+ | Some
+ (_stringappend_763_,(existT _ _stringappend_764_ _)) =>
+ match (string_drop
+ _stringappend_762_
+ (build_ex
+ _stringappend_764_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__218 : bool =>
+ returnm ((if (w__218) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__219 : bool =>
+ returnm ((if (w__219) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__220 : bool =>
+ returnm ((if (w__220) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__221 : bool =>
+ returnm ((if (w__221) then true
+ else false)
+ : bool)) >>= fun w__222 : bool =>
+ (if (w__222) then
+ let _stringappend_747_ :=
+ string_drop _stringappend_559_ (string_length "addiw") in
+ match (spc_matches_prefix _stringappend_747_) with
+ | Some (_stringappend_748_,(existT _ _stringappend_749_ _)) =>
+ returnm ((_stringappend_748_, build_ex _stringappend_749_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__224 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_749_ _) :=
+ w__224
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_750_ :=
+ string_drop _stringappend_747_ (build_ex _stringappend_749_) in
+ match (reg_name_matches_prefix _stringappend_750_) with
+ | Some (_stringappend_751_,(existT _ _stringappend_752_ _)) =>
+ returnm ((_stringappend_751_, build_ex _stringappend_752_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__226 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_752_ _) :=
+ w__226
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_753_ :=
+ string_drop _stringappend_750_ (build_ex _stringappend_752_) in
+ sep_matches_prefix _stringappend_753_ >>= fun w__227 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__227 with
+ | Some (_stringappend_754_,(existT _ _stringappend_755_ _)) =>
+ returnm ((_stringappend_754_, build_ex _stringappend_755_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__229 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_755_ _) :=
+ w__229
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_756_ :=
+ string_drop _stringappend_753_ (build_ex _stringappend_755_) in
+ match (reg_name_matches_prefix _stringappend_756_) with
+ | Some (_stringappend_757_,(existT _ _stringappend_758_ _)) =>
+ returnm ((_stringappend_757_, build_ex _stringappend_758_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__231 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_758_ _) :=
+ w__231
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_759_ :=
+ string_drop _stringappend_756_ (build_ex _stringappend_758_) in
+ sep_matches_prefix _stringappend_759_ >>= fun w__232 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__232 with
+ | Some (_stringappend_760_,(existT _ _stringappend_761_ _)) =>
+ returnm ((_stringappend_760_, build_ex _stringappend_761_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__234 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_761_ _) :=
+ w__234
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_762_ :=
+ string_drop _stringappend_759_ (build_ex _stringappend_761_) in
+ match (hex_bits_12_matches_prefix _stringappend_762_) with
+ | Some (_stringappend_763_,(existT _ _stringappend_764_ _)) =>
+ returnm ((_stringappend_763_, build_ex _stringappend_764_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__236 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_764_ _) :=
+ w__236
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_762_
+ (build_ex
+ _stringappend_764_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ match (shiftw_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_766_,(existT _ _stringappend_767_ _)) =>
+ let _stringappend_768_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_767_) in
+ match (spc_matches_prefix _stringappend_768_) with
+ | Some (_stringappend_769_,(existT _ _stringappend_770_ _)) =>
+ let _stringappend_771_ :=
+ string_drop _stringappend_768_
+ (build_ex
+ _stringappend_770_) in
+ match (reg_name_matches_prefix _stringappend_771_) with
+ | Some (_stringappend_772_,(existT _ _stringappend_773_ _)) =>
+ let _stringappend_774_ :=
+ string_drop _stringappend_771_
+ (build_ex
+ _stringappend_773_) in
+ sep_matches_prefix _stringappend_774_ >>= fun w__239 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__239 with
+ | Some
+ (_stringappend_775_,(existT _ _stringappend_776_ _)) =>
+ let _stringappend_777_ :=
+ string_drop _stringappend_774_
+ (build_ex
+ _stringappend_776_) in
+ match (reg_name_matches_prefix _stringappend_777_) with
+ | Some
+ (_stringappend_778_,(existT _ _stringappend_779_ _)) =>
+ let _stringappend_780_ :=
+ string_drop _stringappend_777_
+ (build_ex
+ _stringappend_779_) in
+ sep_matches_prefix _stringappend_780_ >>= fun w__240 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__240 with
+ | Some
+ (_stringappend_781_,(existT _ _stringappend_782_ _)) =>
+ let _stringappend_783_ :=
+ string_drop _stringappend_780_
+ (build_ex
+ _stringappend_782_) in
+ if ((match (hex_bits_5_matches_prefix
+ _stringappend_783_) with
+ | Some
+ (_stringappend_784_,(existT _ _stringappend_785_ _)) =>
+ match (string_drop
+ _stringappend_783_
+ (build_ex
+ _stringappend_785_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__241 : bool =>
+ returnm ((if (w__241) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__242 : bool =>
+ returnm ((if (w__242) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__243 : bool =>
+ returnm ((if (w__243) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__244 : bool =>
+ returnm ((if (w__244) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__245 : bool =>
+ (if (w__245) then
+ match (shiftw_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_766_,(existT _ _stringappend_767_ _)) =>
+ returnm ((_stringappend_766_, build_ex _stringappend_767_)
+ : (sop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((sop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__247 : (sop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_767_ _) :=
+ w__247
+ : (sop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_768_ :=
+ string_drop _stringappend_559_ (build_ex _stringappend_767_) in
+ match (spc_matches_prefix _stringappend_768_) with
+ | Some (_stringappend_769_,(existT _ _stringappend_770_ _)) =>
+ returnm ((_stringappend_769_, build_ex _stringappend_770_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__249 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_770_ _) :=
+ w__249
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_771_ :=
+ string_drop _stringappend_768_ (build_ex _stringappend_770_) in
+ match (reg_name_matches_prefix _stringappend_771_) with
+ | Some (_stringappend_772_,(existT _ _stringappend_773_ _)) =>
+ returnm ((_stringappend_772_, build_ex _stringappend_773_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__251 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_773_ _) :=
+ w__251
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_774_ :=
+ string_drop _stringappend_771_ (build_ex _stringappend_773_) in
+ sep_matches_prefix _stringappend_774_ >>= fun w__252 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__252 with
+ | Some (_stringappend_775_,(existT _ _stringappend_776_ _)) =>
+ returnm ((_stringappend_775_, build_ex _stringappend_776_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__254 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_776_ _) :=
+ w__254
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_777_ :=
+ string_drop _stringappend_774_ (build_ex _stringappend_776_) in
+ match (reg_name_matches_prefix _stringappend_777_) with
+ | Some (_stringappend_778_,(existT _ _stringappend_779_ _)) =>
+ returnm ((_stringappend_778_, build_ex _stringappend_779_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__256 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_779_ _) :=
+ w__256
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_780_ :=
+ string_drop _stringappend_777_ (build_ex _stringappend_779_) in
+ sep_matches_prefix _stringappend_780_ >>= fun w__257 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__257 with
+ | Some (_stringappend_781_,(existT _ _stringappend_782_ _)) =>
+ returnm ((_stringappend_781_, build_ex _stringappend_782_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__259 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_782_ _) :=
+ w__259
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_783_ :=
+ string_drop _stringappend_780_ (build_ex _stringappend_782_) in
+ match (hex_bits_5_matches_prefix _stringappend_783_) with
+ | Some (_stringappend_784_,(existT _ _stringappend_785_ _)) =>
+ returnm ((_stringappend_784_, build_ex _stringappend_785_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__261 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(shamt, existT _ _stringappend_785_ _) :=
+ w__261
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_783_
+ (build_ex
+ _stringappend_785_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ match (rtypew_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_787_,(existT _ _stringappend_788_ _)) =>
+ let _stringappend_789_ :=
+ string_drop _stringappend_559_
+ (build_ex
+ _stringappend_788_) in
+ match (spc_matches_prefix _stringappend_789_) with
+ | Some (_stringappend_790_,(existT _ _stringappend_791_ _)) =>
+ let _stringappend_792_ :=
+ string_drop _stringappend_789_
+ (build_ex
+ _stringappend_791_) in
+ match (reg_name_matches_prefix _stringappend_792_) with
+ | Some
+ (_stringappend_793_,(existT _ _stringappend_794_ _)) =>
+ let _stringappend_795_ :=
+ string_drop _stringappend_792_
+ (build_ex
+ _stringappend_794_) in
+ sep_matches_prefix _stringappend_795_ >>= fun w__264 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__264 with
+ | Some
+ (_stringappend_796_,(existT _ _stringappend_797_ _)) =>
+ let _stringappend_798_ :=
+ string_drop _stringappend_795_
+ (build_ex
+ _stringappend_797_) in
+ match (reg_name_matches_prefix _stringappend_798_) with
+ | Some
+ (_stringappend_799_,(existT _ _stringappend_800_ _)) =>
+ let _stringappend_801_ :=
+ string_drop _stringappend_798_
+ (build_ex
+ _stringappend_800_) in
+ sep_matches_prefix _stringappend_801_ >>= fun w__265 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__265 with
+ | Some
+ (_stringappend_802_,(existT _ _stringappend_803_ _)) =>
+ let _stringappend_804_ :=
+ string_drop
+ _stringappend_801_
+ (build_ex
+ _stringappend_803_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_804_) with
+ | Some
+ (_stringappend_805_,(existT _ _stringappend_806_ _)) =>
+ match (string_drop
+ _stringappend_804_
+ (build_ex
+ _stringappend_806_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__266 : bool =>
+ returnm ((if (w__266) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__267 : bool =>
+ returnm ((if (w__267) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__268 : bool =>
+ returnm ((if (w__268) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__269 : bool =>
+ returnm ((if (w__269) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__270 : bool =>
+ (if (w__270) then
+ match (rtypew_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_787_,(existT _ _stringappend_788_ _)) =>
+ returnm ((_stringappend_787_, build_ex _stringappend_788_)
+ : (ropw * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((ropw * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__272 : (ropw * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_788_ _) :=
+ w__272
+ : (ropw * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_789_ :=
+ string_drop _stringappend_559_
+ (build_ex
+ _stringappend_788_) in
+ match (spc_matches_prefix _stringappend_789_) with
+ | Some (_stringappend_790_,(existT _ _stringappend_791_ _)) =>
+ returnm ((_stringappend_790_, build_ex _stringappend_791_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__274 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_791_ _) :=
+ w__274
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_792_ :=
+ string_drop _stringappend_789_
+ (build_ex
+ _stringappend_791_) in
+ match (reg_name_matches_prefix _stringappend_792_) with
+ | Some (_stringappend_793_,(existT _ _stringappend_794_ _)) =>
+ returnm ((_stringappend_793_, build_ex _stringappend_794_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__276 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_794_ _) :=
+ w__276
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_795_ :=
+ string_drop _stringappend_792_
+ (build_ex
+ _stringappend_794_) in
+ sep_matches_prefix _stringappend_795_ >>= fun w__277 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__277 with
+ | Some (_stringappend_796_,(existT _ _stringappend_797_ _)) =>
+ returnm ((_stringappend_796_, build_ex _stringappend_797_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__279 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_797_ _) :=
+ w__279
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_798_ :=
+ string_drop _stringappend_795_
+ (build_ex
+ _stringappend_797_) in
+ match (reg_name_matches_prefix _stringappend_798_) with
+ | Some (_stringappend_799_,(existT _ _stringappend_800_ _)) =>
+ returnm ((_stringappend_799_, build_ex _stringappend_800_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__281 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_800_ _) :=
+ w__281
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_801_ :=
+ string_drop _stringappend_798_
+ (build_ex
+ _stringappend_800_) in
+ sep_matches_prefix _stringappend_801_ >>= fun w__282 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__282 with
+ | Some (_stringappend_802_,(existT _ _stringappend_803_ _)) =>
+ returnm ((_stringappend_802_, build_ex _stringappend_803_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__284 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_803_ _) :=
+ w__284
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_804_ :=
+ string_drop _stringappend_801_
+ (build_ex
+ _stringappend_803_) in
+ match (reg_name_matches_prefix _stringappend_804_) with
+ | Some (_stringappend_805_,(existT _ _stringappend_806_ _)) =>
+ returnm ((_stringappend_805_, build_ex _stringappend_806_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__286 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs2, existT _ _stringappend_806_ _) :=
+ w__286
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_804_
+ (build_ex
+ _stringappend_806_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ match (shiftiwop_mnemonic_matches_prefix _stringappend_559_) with
+ | Some (_stringappend_808_,(existT _ _stringappend_809_ _)) =>
+ let _stringappend_810_ :=
+ string_drop _stringappend_559_
+ (build_ex
+ _stringappend_809_) in
+ match (spc_matches_prefix _stringappend_810_) with
+ | Some
+ (_stringappend_811_,(existT _ _stringappend_812_ _)) =>
+ let _stringappend_813_ :=
+ string_drop _stringappend_810_
+ (build_ex
+ _stringappend_812_) in
+ match (reg_name_matches_prefix _stringappend_813_) with
+ | Some
+ (_stringappend_814_,(existT _ _stringappend_815_ _)) =>
+ let _stringappend_816_ :=
+ string_drop _stringappend_813_
+ (build_ex
+ _stringappend_815_) in
+ sep_matches_prefix _stringappend_816_ >>= fun w__289 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__289 with
+ | Some
+ (_stringappend_817_,(existT _ _stringappend_818_ _)) =>
+ let _stringappend_819_ :=
+ string_drop _stringappend_816_
+ (build_ex
+ _stringappend_818_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_819_) with
+ | Some
+ (_stringappend_820_,(existT _ _stringappend_821_ _)) =>
+ let _stringappend_822_ :=
+ string_drop
+ _stringappend_819_
+ (build_ex
+ _stringappend_821_) in
+ if ((match (hex_bits_5_matches_prefix
+ _stringappend_822_) with
+ | Some
+ (_stringappend_823_,(existT _ _stringappend_824_ _)) =>
+ match (string_drop
+ _stringappend_822_
+ (build_ex
+ _stringappend_824_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__290 : bool =>
+ returnm ((if (w__290) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__291 : bool =>
+ returnm ((if (w__291) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__292 : bool =>
+ (if (w__292) then
+ match (shiftiwop_mnemonic_matches_prefix
+ _stringappend_559_) with
+ | Some
+ (_stringappend_808_,(existT _ _stringappend_809_ _)) =>
+ returnm ((_stringappend_808_,
+ build_ex
+ _stringappend_809_)
+ : (sopw * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((sopw * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__294 : (sopw * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_809_ _) :=
+ w__294
+ : (sopw * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_810_ :=
+ string_drop _stringappend_559_
+ (build_ex
+ _stringappend_809_) in
+ match (spc_matches_prefix _stringappend_810_) with
+ | Some
+ (_stringappend_811_,(existT _ _stringappend_812_ _)) =>
+ returnm ((_stringappend_811_,
+ build_ex
+ _stringappend_812_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__296 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_812_ _) :=
+ w__296
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_813_ :=
+ string_drop _stringappend_810_
+ (build_ex
+ _stringappend_812_) in
+ match (reg_name_matches_prefix _stringappend_813_) with
+ | Some
+ (_stringappend_814_,(existT _ _stringappend_815_ _)) =>
+ returnm ((_stringappend_814_,
+ build_ex
+ _stringappend_815_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__298 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_815_ _) :=
+ w__298
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_816_ :=
+ string_drop _stringappend_813_
+ (build_ex
+ _stringappend_815_) in
+ sep_matches_prefix _stringappend_816_ >>= fun w__299 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__299 with
+ | Some
+ (_stringappend_817_,(existT _ _stringappend_818_ _)) =>
+ returnm ((_stringappend_817_,
+ build_ex
+ _stringappend_818_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__301 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_818_ _) :=
+ w__301
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_819_ :=
+ string_drop _stringappend_816_
+ (build_ex
+ _stringappend_818_) in
+ match (reg_name_matches_prefix _stringappend_819_) with
+ | Some
+ (_stringappend_820_,(existT _ _stringappend_821_ _)) =>
+ returnm ((_stringappend_820_,
+ build_ex
+ _stringappend_821_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__303 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_821_ _) :=
+ w__303
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_822_ :=
+ string_drop _stringappend_819_
+ (build_ex
+ _stringappend_821_) in
+ match (hex_bits_5_matches_prefix _stringappend_822_) with
+ | Some
+ (_stringappend_823_,(existT _ _stringappend_824_ _)) =>
+ returnm ((_stringappend_823_,
+ build_ex
+ _stringappend_824_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__305 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(shamt, existT _ _stringappend_824_ _) :=
+ w__305
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_822_
+ (build_ex
+ _stringappend_824_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ match (mul_mnemonic_matches_prefix _stringappend_559_) with
+ | Some
+ (_stringappend_826_,(existT _ _stringappend_827_ _)) =>
+ let _stringappend_828_ :=
+ string_drop _stringappend_559_
+ (build_ex
+ _stringappend_827_) in
+ match (spc_matches_prefix _stringappend_828_) with
+ | Some
+ (_stringappend_829_,(existT _ _stringappend_830_ _)) =>
+ let _stringappend_831_ :=
+ string_drop _stringappend_828_
+ (build_ex
+ _stringappend_830_) in
+ match (reg_name_matches_prefix _stringappend_831_) with
+ | Some
+ (_stringappend_832_,(existT _ _stringappend_833_ _)) =>
+ let _stringappend_834_ :=
+ string_drop _stringappend_831_
+ (build_ex
+ _stringappend_833_) in
+ sep_matches_prefix _stringappend_834_ >>= fun w__308 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__308 with
+ | Some
+ (_stringappend_835_,(existT _ _stringappend_836_ _)) =>
+ let _stringappend_837_ :=
+ string_drop _stringappend_834_
+ (build_ex
+ _stringappend_836_) in
+ match (reg_name_matches_prefix
+ _stringappend_837_) with
+ | Some
+ (_stringappend_838_,(existT _ _stringappend_839_ _)) =>
+ let _stringappend_840_ :=
+ string_drop _stringappend_837_
+ (build_ex
+ _stringappend_839_) in
+ sep_matches_prefix _stringappend_840_ >>= fun w__309 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__309 with
+ | Some
+ (_stringappend_841_,(existT _ _stringappend_842_ _)) =>
+ let _stringappend_843_ :=
+ string_drop
+ _stringappend_840_
+ (build_ex
+ _stringappend_842_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_843_) with
+ | Some
+ (_stringappend_844_,(existT _ _stringappend_845_ _)) =>
+ match (string_drop
+ _stringappend_843_
+ (build_ex
+ _stringappend_845_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__310 : bool =>
+ returnm ((if (w__310) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__311 : bool =>
+ returnm ((if (w__311) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__312 : bool =>
+ returnm ((if (w__312) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__313 : bool =>
+ returnm ((if (w__313) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__314 : bool =>
+ (if (w__314) then
+ match (mul_mnemonic_matches_prefix _stringappend_559_) with
+ | Some
+ (_stringappend_826_,(existT _ _stringappend_827_ _)) =>
+ returnm ((_stringappend_826_,
+ build_ex
+ _stringappend_827_)
+ : ((bool * bool * bool) * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M (((bool * bool * bool) * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__316 : ((bool * bool * bool) * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '((high, signed1, signed2), existT _ _stringappend_827_ _) :=
+ w__316
+ : ((bool * bool * bool) * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_828_ :=
+ string_drop _stringappend_559_
+ (build_ex
+ _stringappend_827_) in
+ match (spc_matches_prefix _stringappend_828_) with
+ | Some
+ (_stringappend_829_,(existT _ _stringappend_830_ _)) =>
+ returnm ((_stringappend_829_,
+ build_ex
+ _stringappend_830_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__318 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_830_ _) :=
+ w__318
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_831_ :=
+ string_drop _stringappend_828_
+ (build_ex
+ _stringappend_830_) in
+ match (reg_name_matches_prefix _stringappend_831_) with
+ | Some
+ (_stringappend_832_,(existT _ _stringappend_833_ _)) =>
+ returnm ((_stringappend_832_,
+ build_ex
+ _stringappend_833_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__320 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_833_ _) :=
+ w__320
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_834_ :=
+ string_drop _stringappend_831_
+ (build_ex
+ _stringappend_833_) in
+ sep_matches_prefix _stringappend_834_ >>= fun w__321 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__321 with
+ | Some
+ (_stringappend_835_,(existT _ _stringappend_836_ _)) =>
+ returnm ((_stringappend_835_,
+ build_ex
+ _stringappend_836_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__323 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_836_ _) :=
+ w__323
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_837_ :=
+ string_drop _stringappend_834_
+ (build_ex
+ _stringappend_836_) in
+ match (reg_name_matches_prefix _stringappend_837_) with
+ | Some
+ (_stringappend_838_,(existT _ _stringappend_839_ _)) =>
+ returnm ((_stringappend_838_,
+ build_ex
+ _stringappend_839_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__325 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_839_ _) :=
+ w__325
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_840_ :=
+ string_drop _stringappend_837_
+ (build_ex
+ _stringappend_839_) in
+ sep_matches_prefix _stringappend_840_ >>= fun w__326 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__326 with
+ | Some
+ (_stringappend_841_,(existT _ _stringappend_842_ _)) =>
+ returnm ((_stringappend_841_,
+ build_ex
+ _stringappend_842_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__328 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_842_ _) :=
+ w__328
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_843_ :=
+ string_drop _stringappend_840_
+ (build_ex
+ _stringappend_842_) in
+ match (reg_name_matches_prefix _stringappend_843_) with
+ | Some
+ (_stringappend_844_,(existT _ _stringappend_845_ _)) =>
+ returnm ((_stringappend_844_,
+ build_ex
+ _stringappend_845_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__330 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_845_ _) :=
+ w__330
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_843_
+ (build_ex
+ _stringappend_845_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_559_ "div")
+ : bool))
+ (let _stringappend_847_ :=
+ string_drop _stringappend_559_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix _stringappend_847_) with
+ | Some
+ (_stringappend_848_,(existT _ _stringappend_849_ _)) =>
+ let _stringappend_850_ :=
+ string_drop _stringappend_847_
+ (build_ex
+ _stringappend_849_) in
+ match (spc_matches_prefix _stringappend_850_) with
+ | Some
+ (_stringappend_851_,(existT _ _stringappend_852_ _)) =>
+ let _stringappend_853_ :=
+ string_drop _stringappend_850_
+ (build_ex
+ _stringappend_852_) in
+ match (reg_name_matches_prefix
+ _stringappend_853_) with
+ | Some
+ (_stringappend_854_,(existT _ _stringappend_855_ _)) =>
+ let _stringappend_856_ :=
+ string_drop _stringappend_853_
+ (build_ex
+ _stringappend_855_) in
+ sep_matches_prefix _stringappend_856_ >>= fun w__333 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__333 with
+ | Some
+ (_stringappend_857_,(existT _ _stringappend_858_ _)) =>
+ let _stringappend_859_ :=
+ string_drop _stringappend_856_
+ (build_ex
+ _stringappend_858_) in
+ match (reg_name_matches_prefix
+ _stringappend_859_) with
+ | Some
+ (_stringappend_860_,(existT _ _stringappend_861_ _)) =>
+ let _stringappend_862_ :=
+ string_drop _stringappend_859_
+ (build_ex
+ _stringappend_861_) in
+ sep_matches_prefix _stringappend_862_ >>= fun w__334 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__334 with
+ | Some
+ (_stringappend_863_,(existT _ _stringappend_864_ _)) =>
+ let _stringappend_865_ :=
+ string_drop
+ _stringappend_862_
+ (build_ex
+ _stringappend_864_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_865_) with
+ | Some
+ (_stringappend_866_,(existT _ _stringappend_867_ _)) =>
+ match (string_drop
+ _stringappend_865_
+ (build_ex
+ _stringappend_867_)) with
+ | "" => true
+ | _ => false
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__335 : bool =>
+ returnm ((if (w__335) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__336 : bool =>
+ returnm ((if (w__336) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__337 : bool =>
+ returnm ((if (w__337) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__338 : bool =>
+ returnm ((if (w__338) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__339 : bool =>
+ returnm ((if (w__339) then true
+ else false)
+ : bool)) >>= fun w__340 : bool =>
+ (if (w__340) then
+ let _stringappend_847_ :=
+ string_drop _stringappend_559_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix _stringappend_847_) with
+ | Some
+ (_stringappend_848_,(existT _ _stringappend_849_ _)) =>
+ returnm ((_stringappend_848_,
+ build_ex
+ _stringappend_849_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__342 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_849_ _) :=
+ w__342
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_850_ :=
+ string_drop _stringappend_847_
+ (build_ex
+ _stringappend_849_) in
+ match (spc_matches_prefix _stringappend_850_) with
+ | Some
+ (_stringappend_851_,(existT _ _stringappend_852_ _)) =>
+ returnm ((_stringappend_851_,
+ build_ex
+ _stringappend_852_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__344 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_852_ _) :=
+ w__344
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_853_ :=
+ string_drop _stringappend_850_
+ (build_ex
+ _stringappend_852_) in
+ match (reg_name_matches_prefix _stringappend_853_) with
+ | Some
+ (_stringappend_854_,(existT _ _stringappend_855_ _)) =>
+ returnm ((_stringappend_854_,
+ build_ex
+ _stringappend_855_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__346 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_855_ _) :=
+ w__346
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_856_ :=
+ string_drop _stringappend_853_
+ (build_ex
+ _stringappend_855_) in
+ sep_matches_prefix _stringappend_856_ >>= fun w__347 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__347 with
+ | Some
+ (_stringappend_857_,(existT _ _stringappend_858_ _)) =>
+ returnm ((_stringappend_857_,
+ build_ex
+ _stringappend_858_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__349 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_858_ _) :=
+ w__349
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_859_ :=
+ string_drop _stringappend_856_
+ (build_ex
+ _stringappend_858_) in
+ match (reg_name_matches_prefix _stringappend_859_) with
+ | Some
+ (_stringappend_860_,(existT _ _stringappend_861_ _)) =>
+ returnm ((_stringappend_860_,
+ build_ex
+ _stringappend_861_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__351 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_861_ _) :=
+ w__351
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_862_ :=
+ string_drop _stringappend_859_
+ (build_ex
+ _stringappend_861_) in
+ sep_matches_prefix _stringappend_862_ >>= fun w__352 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__352 with
+ | Some
+ (_stringappend_863_,(existT _ _stringappend_864_ _)) =>
+ returnm ((_stringappend_863_,
+ build_ex
+ _stringappend_864_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__354 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_864_ _) :=
+ w__354
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_865_ :=
+ string_drop _stringappend_862_
+ (build_ex
+ _stringappend_864_) in
+ match (reg_name_matches_prefix _stringappend_865_) with
+ | Some
+ (_stringappend_866_,(existT _ _stringappend_867_ _)) =>
+ returnm ((_stringappend_866_,
+ build_ex
+ _stringappend_867_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__356 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_867_ _) :=
+ w__356
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_865_
+ (build_ex
+ _stringappend_867_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_559_
+ "rem")
+ : bool))
+ (let _stringappend_869_ :=
+ string_drop _stringappend_559_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_869_) with
+ | Some
+ (_stringappend_870_,(existT _ _stringappend_871_ _)) =>
+ let _stringappend_872_ :=
+ string_drop _stringappend_869_
+ (build_ex
+ _stringappend_871_) in
+ match (spc_matches_prefix _stringappend_872_) with
+ | Some
+ (_stringappend_873_,(existT _ _stringappend_874_ _)) =>
+ let _stringappend_875_ :=
+ string_drop _stringappend_872_
+ (build_ex
+ _stringappend_874_) in
+ match (reg_name_matches_prefix
+ _stringappend_875_) with
+ | Some
+ (_stringappend_876_,(existT _ _stringappend_877_ _)) =>
+ let _stringappend_878_ :=
+ string_drop _stringappend_875_
+ (build_ex
+ _stringappend_877_) in
+ sep_matches_prefix _stringappend_878_ >>= fun w__359 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__359 with
+ | Some
+ (_stringappend_879_,(existT _ _stringappend_880_ _)) =>
+ let _stringappend_881_ :=
+ string_drop _stringappend_878_
+ (build_ex
+ _stringappend_880_) in
+ match (reg_name_matches_prefix
+ _stringappend_881_) with
+ | Some
+ (_stringappend_882_,(existT _ _stringappend_883_ _)) =>
+ let _stringappend_884_ :=
+ string_drop _stringappend_881_
+ (build_ex
+ _stringappend_883_) in
+ sep_matches_prefix
+ _stringappend_884_ >>= fun w__360 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__360 with
+ | Some
+ (_stringappend_885_,(existT _ _stringappend_886_ _)) =>
+ let _stringappend_887_ :=
+ string_drop
+ _stringappend_884_
+ (build_ex
+ _stringappend_886_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_887_) with
+ | Some
+ (_stringappend_888_,(existT _ _stringappend_889_ _)) =>
+ match (string_drop
+ _stringappend_887_
+ (build_ex
+ _stringappend_889_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__361 : bool =>
+ returnm ((if (w__361) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__362 : bool =>
+ returnm ((if (w__362) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__363 : bool =>
+ returnm ((if (w__363) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__364 : bool =>
+ returnm ((if (w__364) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__365 : bool =>
+ returnm ((if (w__365) then true
+ else false)
+ : bool)) >>= fun w__366 : bool =>
+ (if (w__366) then
+ let _stringappend_869_ :=
+ string_drop _stringappend_559_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_869_) with
+ | Some
+ (_stringappend_870_,(existT _ _stringappend_871_ _)) =>
+ returnm ((_stringappend_870_,
+ build_ex
+ _stringappend_871_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__368 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_871_ _) :=
+ w__368
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_872_ :=
+ string_drop _stringappend_869_
+ (build_ex
+ _stringappend_871_) in
+ match (spc_matches_prefix _stringappend_872_) with
+ | Some
+ (_stringappend_873_,(existT _ _stringappend_874_ _)) =>
+ returnm ((_stringappend_873_,
+ build_ex
+ _stringappend_874_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__370 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_874_ _) :=
+ w__370
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_875_ :=
+ string_drop _stringappend_872_
+ (build_ex
+ _stringappend_874_) in
+ match (reg_name_matches_prefix _stringappend_875_) with
+ | Some
+ (_stringappend_876_,(existT _ _stringappend_877_ _)) =>
+ returnm ((_stringappend_876_,
+ build_ex
+ _stringappend_877_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__372 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_877_ _) :=
+ w__372
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_878_ :=
+ string_drop _stringappend_875_
+ (build_ex
+ _stringappend_877_) in
+ sep_matches_prefix _stringappend_878_ >>= fun w__373 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__373 with
+ | Some
+ (_stringappend_879_,(existT _ _stringappend_880_ _)) =>
+ returnm ((_stringappend_879_,
+ build_ex
+ _stringappend_880_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__375 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_880_ _) :=
+ w__375
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_881_ :=
+ string_drop _stringappend_878_
+ (build_ex
+ _stringappend_880_) in
+ match (reg_name_matches_prefix _stringappend_881_) with
+ | Some
+ (_stringappend_882_,(existT _ _stringappend_883_ _)) =>
+ returnm ((_stringappend_882_,
+ build_ex
+ _stringappend_883_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__377 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_883_ _) :=
+ w__377
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_884_ :=
+ string_drop _stringappend_881_
+ (build_ex
+ _stringappend_883_) in
+ sep_matches_prefix _stringappend_884_ >>= fun w__378 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__378 with
+ | Some
+ (_stringappend_885_,(existT _ _stringappend_886_ _)) =>
+ returnm ((_stringappend_885_,
+ build_ex
+ _stringappend_886_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__380 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_886_ _) :=
+ w__380
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_887_ :=
+ string_drop _stringappend_884_
+ (build_ex
+ _stringappend_886_) in
+ match (reg_name_matches_prefix _stringappend_887_) with
+ | Some
+ (_stringappend_888_,(existT _ _stringappend_889_ _)) =>
+ returnm ((_stringappend_888_,
+ build_ex
+ _stringappend_889_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__382 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_889_ _) :=
+ w__382
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_887_
+ (build_ex
+ _stringappend_889_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_559_
+ "mulw")
+ : bool))
+ (let _stringappend_891_ :=
+ string_drop _stringappend_559_
+ (string_length "mulw") in
+ match (spc_matches_prefix _stringappend_891_) with
+ | Some
+ (_stringappend_892_,(existT _ _stringappend_893_ _)) =>
+ let _stringappend_894_ :=
+ string_drop _stringappend_891_
+ (build_ex
+ _stringappend_893_) in
+ match (reg_name_matches_prefix
+ _stringappend_894_) with
+ | Some
+ (_stringappend_895_,(existT _ _stringappend_896_ _)) =>
+ let _stringappend_897_ :=
+ string_drop _stringappend_894_
+ (build_ex
+ _stringappend_896_) in
+ sep_matches_prefix _stringappend_897_ >>= fun w__385 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__385 with
+ | Some
+ (_stringappend_898_,(existT _ _stringappend_899_ _)) =>
+ let _stringappend_900_ :=
+ string_drop _stringappend_897_
+ (build_ex
+ _stringappend_899_) in
+ match (reg_name_matches_prefix
+ _stringappend_900_) with
+ | Some
+ (_stringappend_901_,(existT _ _stringappend_902_ _)) =>
+ let _stringappend_903_ :=
+ string_drop _stringappend_900_
+ (build_ex
+ _stringappend_902_) in
+ sep_matches_prefix
+ _stringappend_903_ >>= fun w__386 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__386 with
+ | Some
+ (_stringappend_904_,(existT _ _stringappend_905_ _)) =>
+ let _stringappend_906_ :=
+ string_drop
+ _stringappend_903_
+ (build_ex
+ _stringappend_905_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_906_) with
+ | Some
+ (_stringappend_907_,(existT _ _stringappend_908_ _)) =>
+ match (string_drop
+ _stringappend_906_
+ (build_ex
+ _stringappend_908_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__387 : bool =>
+ returnm ((if (w__387) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__388 : bool =>
+ returnm ((if (w__388) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__389 : bool =>
+ returnm ((if (w__389) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__390 : bool =>
+ returnm ((if (w__390) then true
+ else false)
+ : bool)) >>= fun w__391 : bool =>
+ (if (w__391) then
+ let _stringappend_891_ :=
+ string_drop _stringappend_559_
+ (string_length "mulw") in
+ match (spc_matches_prefix _stringappend_891_) with
+ | Some
+ (_stringappend_892_,(existT _ _stringappend_893_ _)) =>
+ returnm ((_stringappend_892_,
+ build_ex
+ _stringappend_893_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__393 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_893_ _) :=
+ w__393
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_894_ :=
+ string_drop _stringappend_891_
+ (build_ex
+ _stringappend_893_) in
+ match (reg_name_matches_prefix
+ _stringappend_894_) with
+ | Some
+ (_stringappend_895_,(existT _ _stringappend_896_ _)) =>
+ returnm ((_stringappend_895_,
+ build_ex
+ _stringappend_896_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__395 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_896_ _) :=
+ w__395
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_897_ :=
+ string_drop _stringappend_894_
+ (build_ex
+ _stringappend_896_) in
+ sep_matches_prefix _stringappend_897_ >>= fun w__396 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__396 with
+ | Some
+ (_stringappend_898_,(existT _ _stringappend_899_ _)) =>
+ returnm ((_stringappend_898_,
+ build_ex
+ _stringappend_899_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__398 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_899_ _) :=
+ w__398
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_900_ :=
+ string_drop _stringappend_897_
+ (build_ex
+ _stringappend_899_) in
+ match (reg_name_matches_prefix
+ _stringappend_900_) with
+ | Some
+ (_stringappend_901_,(existT _ _stringappend_902_ _)) =>
+ returnm ((_stringappend_901_,
+ build_ex
+ _stringappend_902_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__400 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_902_ _) :=
+ w__400
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_903_ :=
+ string_drop _stringappend_900_
+ (build_ex
+ _stringappend_902_) in
+ sep_matches_prefix _stringappend_903_ >>= fun w__401 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__401 with
+ | Some
+ (_stringappend_904_,(existT _ _stringappend_905_ _)) =>
+ returnm ((_stringappend_904_,
+ build_ex
+ _stringappend_905_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__403 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_905_ _) :=
+ w__403
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_906_ :=
+ string_drop _stringappend_903_
+ (build_ex
+ _stringappend_905_) in
+ match (reg_name_matches_prefix
+ _stringappend_906_) with
+ | Some
+ (_stringappend_907_,(existT _ _stringappend_908_ _)) =>
+ returnm ((_stringappend_907_,
+ build_ex
+ _stringappend_908_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__405 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_908_ _) :=
+ w__405
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_906_
+ (build_ex
+ _stringappend_908_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_559_ "div")
+ : bool))
+ (let _stringappend_910_ :=
+ string_drop _stringappend_559_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_910_) with
+ | Some
+ (_stringappend_911_,(existT _ _stringappend_912_ _)) =>
+ let _stringappend_913_ :=
+ string_drop _stringappend_910_
+ (build_ex
+ _stringappend_912_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_913_ "w")
+ : bool))
+ (let _stringappend_914_ :=
+ string_drop _stringappend_913_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_914_) with
+ | Some
+ (_stringappend_915_,(existT _ _stringappend_916_ _)) =>
+ let _stringappend_917_ :=
+ string_drop _stringappend_914_
+ (build_ex
+ _stringappend_916_) in
+ match (reg_name_matches_prefix
+ _stringappend_917_) with
+ | Some
+ (_stringappend_918_,(existT _ _stringappend_919_ _)) =>
+ let _stringappend_920_ :=
+ string_drop _stringappend_917_
+ (build_ex
+ _stringappend_919_) in
+ sep_matches_prefix
+ _stringappend_920_ >>= fun w__408 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__408 with
+ | Some
+ (_stringappend_921_,(existT _ _stringappend_922_ _)) =>
+ let _stringappend_923_ :=
+ string_drop
+ _stringappend_920_
+ (build_ex
+ _stringappend_922_) in
+ match (reg_name_matches_prefix
+ _stringappend_923_) with
+ | Some
+ (_stringappend_924_,(existT _ _stringappend_925_ _)) =>
+ let _stringappend_926_ :=
+ string_drop
+ _stringappend_923_
+ (build_ex
+ _stringappend_925_) in
+ sep_matches_prefix
+ _stringappend_926_ >>= fun w__409 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__409 with
+ | Some
+ (_stringappend_927_,(existT _ _stringappend_928_ _)) =>
+ let _stringappend_929_ :=
+ string_drop
+ _stringappend_926_
+ (build_ex
+ _stringappend_928_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_929_) with
+ | Some
+ (_stringappend_930_,(existT _ _stringappend_931_ _)) =>
+ match (string_drop
+ _stringappend_929_
+ (build_ex
+ _stringappend_931_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__410 : bool =>
+ returnm ((if (w__410) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__411 : bool =>
+ returnm ((if (w__411) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__412 : bool =>
+ returnm ((if (w__412) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__413 : bool =>
+ returnm ((if (w__413) then true
+ else false)
+ : bool)) >>= fun w__414 : bool =>
+ returnm ((if (w__414) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__415 : bool =>
+ returnm ((if (w__415) then true
+ else false)
+ : bool)) >>= fun w__416 : bool =>
+ (if (w__416) then
+ let _stringappend_910_ :=
+ string_drop _stringappend_559_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_910_) with
+ | Some
+ (_stringappend_911_,(existT _ _stringappend_912_ _)) =>
+ returnm ((_stringappend_911_,
+ build_ex
+ _stringappend_912_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__418 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_912_ _) :=
+ w__418
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_913_ :=
+ string_drop _stringappend_910_
+ (build_ex
+ _stringappend_912_) in
+ let _stringappend_914_ :=
+ string_drop _stringappend_913_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_914_) with
+ | Some
+ (_stringappend_915_,(existT _ _stringappend_916_ _)) =>
+ returnm ((_stringappend_915_,
+ build_ex
+ _stringappend_916_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__420 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_916_ _) :=
+ w__420
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_917_ :=
+ string_drop _stringappend_914_
+ (build_ex
+ _stringappend_916_) in
+ match (reg_name_matches_prefix
+ _stringappend_917_) with
+ | Some
+ (_stringappend_918_,(existT _ _stringappend_919_ _)) =>
+ returnm ((_stringappend_918_,
+ build_ex
+ _stringappend_919_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__422 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_919_ _) :=
+ w__422
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_920_ :=
+ string_drop _stringappend_917_
+ (build_ex
+ _stringappend_919_) in
+ sep_matches_prefix _stringappend_920_ >>= fun w__423 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__423 with
+ | Some
+ (_stringappend_921_,(existT _ _stringappend_922_ _)) =>
+ returnm ((_stringappend_921_,
+ build_ex
+ _stringappend_922_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__425 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_922_ _) :=
+ w__425
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_923_ :=
+ string_drop _stringappend_920_
+ (build_ex
+ _stringappend_922_) in
+ match (reg_name_matches_prefix
+ _stringappend_923_) with
+ | Some
+ (_stringappend_924_,(existT _ _stringappend_925_ _)) =>
+ returnm ((_stringappend_924_,
+ build_ex
+ _stringappend_925_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__427 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_925_ _) :=
+ w__427
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_926_ :=
+ string_drop _stringappend_923_
+ (build_ex
+ _stringappend_925_) in
+ sep_matches_prefix _stringappend_926_ >>= fun w__428 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__428 with
+ | Some
+ (_stringappend_927_,(existT _ _stringappend_928_ _)) =>
+ returnm ((_stringappend_927_,
+ build_ex
+ _stringappend_928_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__430 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_928_ _) :=
+ w__430
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_929_ :=
+ string_drop _stringappend_926_
+ (build_ex
+ _stringappend_928_) in
+ match (reg_name_matches_prefix
+ _stringappend_929_) with
+ | Some
+ (_stringappend_930_,(existT _ _stringappend_931_ _)) =>
+ returnm ((_stringappend_930_,
+ build_ex
+ _stringappend_931_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__432 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_931_ _) :=
+ w__432
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ (match (string_drop _stringappend_929_
+ (build_ex
+ _stringappend_931_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_559_ "rem")
+ : bool))
+ (let _stringappend_933_ :=
+ string_drop _stringappend_559_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_933_) with
+ | Some
+ (_stringappend_934_,(existT _ _stringappend_935_ _)) =>
+ let _stringappend_936_ :=
+ string_drop _stringappend_933_
+ (build_ex
+ _stringappend_935_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_936_ "w")
+ : bool))
+ (let _stringappend_937_ :=
+ string_drop _stringappend_936_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_937_) with
+ | Some
+ (_stringappend_938_,(existT _ _stringappend_939_ _)) =>
+ let _stringappend_940_ :=
+ string_drop _stringappend_937_
+ (build_ex
+ _stringappend_939_) in
+ match (reg_name_matches_prefix
+ _stringappend_940_) with
+ | Some
+ (_stringappend_941_,(existT _ _stringappend_942_ _)) =>
+ let _stringappend_943_ :=
+ string_drop
+ _stringappend_940_
+ (build_ex
+ _stringappend_942_) in
+ sep_matches_prefix
+ _stringappend_943_ >>= fun w__435 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__435 with
+ | Some
+ (_stringappend_944_,(existT _ _stringappend_945_ _)) =>
+ let _stringappend_946_ :=
+ string_drop
+ _stringappend_943_
+ (build_ex
+ _stringappend_945_) in
+ match (reg_name_matches_prefix
+ _stringappend_946_) with
+ | Some
+ (_stringappend_947_,(existT _ _stringappend_948_ _)) =>
+ let _stringappend_949_ :=
+ string_drop
+ _stringappend_946_
+ (build_ex
+ _stringappend_948_) in
+ sep_matches_prefix
+ _stringappend_949_ >>= fun w__436 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__436 with
+ | Some
+ (_stringappend_950_,(existT _ _stringappend_951_ _)) =>
+ let _stringappend_952_ :=
+ string_drop
+ _stringappend_949_
+ (build_ex
+ _stringappend_951_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_952_) with
+ | Some
+ (_stringappend_953_,(existT _ _stringappend_954_ _)) =>
+ match (string_drop
+ _stringappend_952_
+ (build_ex
+ _stringappend_954_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__437 : bool =>
+ returnm ((if (w__437) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__438 : bool =>
+ returnm ((if (w__438) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__439 : bool =>
+ returnm ((if (w__439) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__440 : bool =>
+ returnm ((if (w__440) then true
+ else false)
+ : bool)) >>= fun w__441 : bool =>
+ returnm ((if (w__441) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__442 : bool =>
+ returnm ((if (w__442) then true
+ else false)
+ : bool)) >>= fun w__443 : bool =>
+ (if (w__443) then
+ let _stringappend_933_ :=
+ string_drop _stringappend_559_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_933_) with
+ | Some
+ (_stringappend_934_,(existT _ _stringappend_935_ _)) =>
+ returnm ((_stringappend_934_,
+ build_ex
+ _stringappend_935_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__445 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_935_ _) :=
+ w__445
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_936_ :=
+ string_drop _stringappend_933_
+ (build_ex
+ _stringappend_935_) in
+ let _stringappend_937_ :=
+ string_drop _stringappend_936_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_937_) with
+ | Some
+ (_stringappend_938_,(existT _ _stringappend_939_ _)) =>
+ returnm ((_stringappend_938_,
+ build_ex
+ _stringappend_939_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__447 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_939_ _) :=
+ w__447
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_940_ :=
+ string_drop _stringappend_937_
+ (build_ex
+ _stringappend_939_) in
+ match (reg_name_matches_prefix
+ _stringappend_940_) with
+ | Some
+ (_stringappend_941_,(existT _ _stringappend_942_ _)) =>
+ returnm ((_stringappend_941_,
+ build_ex
+ _stringappend_942_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__449 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_942_ _) :=
+ w__449
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_943_ :=
+ string_drop _stringappend_940_
+ (build_ex
+ _stringappend_942_) in
+ sep_matches_prefix _stringappend_943_ >>= fun w__450 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__450 with
+ | Some
+ (_stringappend_944_,(existT _ _stringappend_945_ _)) =>
+ returnm ((_stringappend_944_,
+ build_ex
+ _stringappend_945_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__452 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_945_ _) :=
+ w__452
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_946_ :=
+ string_drop _stringappend_943_
+ (build_ex
+ _stringappend_945_) in
+ match (reg_name_matches_prefix
+ _stringappend_946_) with
+ | Some
+ (_stringappend_947_,(existT _ _stringappend_948_ _)) =>
+ returnm ((_stringappend_947_,
+ build_ex
+ _stringappend_948_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__454 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_948_ _) :=
+ w__454
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_949_ :=
+ string_drop _stringappend_946_
+ (build_ex
+ _stringappend_948_) in
+ sep_matches_prefix _stringappend_949_ >>= fun w__455 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__455 with
+ | Some
+ (_stringappend_950_,(existT _ _stringappend_951_ _)) =>
+ returnm ((_stringappend_950_,
+ build_ex
+ _stringappend_951_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__457 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_951_ _) :=
+ w__457
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_952_ :=
+ string_drop _stringappend_949_
+ (build_ex
+ _stringappend_951_) in
+ match (reg_name_matches_prefix
+ _stringappend_952_) with
+ | Some
+ (_stringappend_953_,(existT _ _stringappend_954_ _)) =>
+ returnm ((_stringappend_953_,
+ build_ex
+ _stringappend_954_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__459 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_954_ _) :=
+ w__459
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop _stringappend_952_
+ (build_ex
+ _stringappend_954_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_559_
+ "fence")
+ : bool))
+ (let _stringappend_956_ :=
+ string_drop _stringappend_559_
+ (string_length "fence") in
+ match (spc_matches_prefix
+ _stringappend_956_) with
+ | Some
+ (_stringappend_957_,(existT _ _stringappend_958_ _)) =>
+ let _stringappend_959_ :=
+ string_drop _stringappend_956_
+ (build_ex
+ _stringappend_958_) in
+ fence_bits_matches_prefix
+ _stringappend_959_ >>= fun w__462 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__462 with
+ | Some
+ (_stringappend_960_,(existT _ _stringappend_961_ _)) =>
+ let _stringappend_962_ :=
+ string_drop _stringappend_959_
+ (build_ex
+ _stringappend_961_) in
+ sep_matches_prefix
+ _stringappend_962_ >>= fun w__463 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__463 with
+ | Some
+ (_stringappend_963_,(existT _ _stringappend_964_ _)) =>
+ let _stringappend_965_ :=
+ string_drop
+ _stringappend_962_
+ (build_ex
+ _stringappend_964_) in
+ fence_bits_matches_prefix
+ _stringappend_965_ >>= fun w__464 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__464 with
+ | Some
+ (_stringappend_966_,(existT _ _stringappend_967_ _)) =>
+ match (string_drop
+ _stringappend_965_
+ (build_ex
+ _stringappend_967_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__465 : bool =>
+ returnm ((if (w__465) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__466 : bool =>
+ returnm ((if (w__466) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__467 : bool =>
+ returnm ((if (w__467) then true
+ else false)
+ : bool)) >>= fun w__468 : bool =>
+ (if (w__468) then
+ let _stringappend_956_ :=
+ string_drop _stringappend_559_
+ (string_length "fence") in
+ match (spc_matches_prefix
+ _stringappend_956_) with
+ | Some
+ (_stringappend_957_,(existT _ _stringappend_958_ _)) =>
+ returnm ((_stringappend_957_,
+ build_ex
+ _stringappend_958_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__470 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_958_ _) :=
+ w__470
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_959_ :=
+ string_drop _stringappend_956_
+ (build_ex
+ _stringappend_958_) in
+ fence_bits_matches_prefix
+ _stringappend_959_ >>= fun w__471 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__471 with
+ | Some
+ (_stringappend_960_,(existT _ _stringappend_961_ _)) =>
+ returnm ((_stringappend_960_,
+ build_ex
+ _stringappend_961_)
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__473 : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(pred, existT _ _stringappend_961_ _) :=
+ w__473
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_962_ :=
+ string_drop _stringappend_959_
+ (build_ex
+ _stringappend_961_) in
+ sep_matches_prefix _stringappend_962_ >>= fun w__474 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__474 with
+ | Some
+ (_stringappend_963_,(existT _ _stringappend_964_ _)) =>
+ returnm ((_stringappend_963_,
+ build_ex
+ _stringappend_964_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__476 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_964_ _) :=
+ w__476
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_965_ :=
+ string_drop _stringappend_962_
+ (build_ex
+ _stringappend_964_) in
+ fence_bits_matches_prefix
+ _stringappend_965_ >>= fun w__477 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__477 with
+ | Some
+ (_stringappend_966_,(existT _ _stringappend_967_ _)) =>
+ returnm ((_stringappend_966_,
+ build_ex
+ _stringappend_967_)
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__479 : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(succ, existT _ _stringappend_967_ _) :=
+ w__479
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_965_
+ (build_ex
+ _stringappend_967_)) with
+ | "" => returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ (match _stringappend_559_ with
+ | "fence.i" =>
+ returnm (true : bool)
+ | "ecall" => returnm (true : bool)
+ | "mret" => returnm (true : bool)
+ | "sret" => returnm (true : bool)
+ | "ebreak" => returnm (true : bool)
+ | "wfi" => returnm (true : bool)
+ | _stringappend_559_ =>
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_559_
+ "sfence.vma")
+ : bool))
+ (let _stringappend_969_ :=
+ string_drop
+ _stringappend_559_
+ (string_length "sfence.vma") in
+ match (spc_matches_prefix
+ _stringappend_969_) with
+ | Some
+ (_stringappend_970_,(existT _ _stringappend_971_ _)) =>
+ let _stringappend_972_ :=
+ string_drop
+ _stringappend_969_
+ (build_ex
+ _stringappend_971_) in
+ match (reg_name_matches_prefix
+ _stringappend_972_) with
+ | Some
+ (_stringappend_973_,(existT _ _stringappend_974_ _)) =>
+ let _stringappend_975_ :=
+ string_drop
+ _stringappend_972_
+ (build_ex
+ _stringappend_974_) in
+ sep_matches_prefix
+ _stringappend_975_ >>= fun w__482 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__482 with
+ | Some
+ (_stringappend_976_,(existT _ _stringappend_977_ _)) =>
+ let _stringappend_978_ :=
+ string_drop
+ _stringappend_975_
+ (build_ex
+ _stringappend_977_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_978_) with
+ | Some
+ (_stringappend_979_,(existT _ _stringappend_980_ _)) =>
+ match (string_drop
+ _stringappend_978_
+ (build_ex
+ _stringappend_980_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__483 : bool =>
+ returnm ((if (w__483) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__484 : bool =>
+ returnm ((if (w__484) then true
+ else false)
+ : bool)) >>= fun w__485 : bool =>
+ (if (w__485) then
+ let _stringappend_969_ :=
+ string_drop
+ _stringappend_559_
+ (string_length
+ "sfence.vma") in
+ match (spc_matches_prefix
+ _stringappend_969_) with
+ | Some
+ (_stringappend_970_,(existT _ _stringappend_971_ _)) =>
+ returnm ((_stringappend_970_,
+ build_ex
+ _stringappend_971_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__487 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_971_ _) :=
+ w__487
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_972_ :=
+ string_drop
+ _stringappend_969_
+ (build_ex
+ _stringappend_971_) in
+ match (reg_name_matches_prefix
+ _stringappend_972_) with
+ | Some
+ (_stringappend_973_,(existT _ _stringappend_974_ _)) =>
+ returnm ((_stringappend_973_,
+ build_ex
+ _stringappend_974_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__489 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_974_ _) :=
+ w__489
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_975_ :=
+ string_drop
+ _stringappend_972_
+ (build_ex
+ _stringappend_974_) in
+ sep_matches_prefix
+ _stringappend_975_ >>= fun w__490 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__490 with
+ | Some
+ (_stringappend_976_,(existT _ _stringappend_977_ _)) =>
+ returnm ((_stringappend_976_,
+ build_ex
+ _stringappend_977_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__492 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_977_ _) :=
+ w__492
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_978_ :=
+ string_drop
+ _stringappend_975_
+ (build_ex
+ _stringappend_977_) in
+ match (reg_name_matches_prefix
+ _stringappend_978_) with
+ | Some
+ (_stringappend_979_,(existT _ _stringappend_980_ _)) =>
+ returnm ((_stringappend_979_,
+ build_ex
+ _stringappend_980_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__494 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_980_ _) :=
+ w__494
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_978_
+ (build_ex
+ _stringappend_980_)) with
+ | "" =>
+ returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_559_
+ "lr.")
+ : bool))
+ (let _stringappend_982_ :=
+ string_drop
+ _stringappend_559_
+ (string_length "lr.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_982_) with
+ | Some
+ (_stringappend_983_,(existT _ _stringappend_984_ _)) =>
+ let _stringappend_985_ :=
+ string_drop
+ _stringappend_982_
+ (build_ex
+ _stringappend_984_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_985_) with
+ | Some
+ (_stringappend_986_,(existT _ _stringappend_987_ _)) =>
+ let _stringappend_988_ :=
+ string_drop
+ _stringappend_985_
+ (build_ex
+ _stringappend_987_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_988_) with
+ | Some
+ (_stringappend_989_,(existT _ _stringappend_990_ _)) =>
+ let _stringappend_991_ :=
+ string_drop
+ _stringappend_988_
+ (build_ex
+ _stringappend_990_) in
+ match (spc_matches_prefix
+ _stringappend_991_) with
+ | Some
+ (_stringappend_992_,(existT _ _stringappend_993_ _)) =>
+ let _stringappend_994_ :=
+ string_drop
+ _stringappend_991_
+ (build_ex
+ _stringappend_993_) in
+ match (reg_name_matches_prefix
+ _stringappend_994_) with
+ | Some
+ (_stringappend_995_,(existT _ _stringappend_996_ _)) =>
+ let _stringappend_997_ :=
+ string_drop
+ _stringappend_994_
+ (build_ex
+ _stringappend_996_) in
+ sep_matches_prefix
+ _stringappend_997_ >>= fun w__497 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__497 with
+ | Some
+ (_stringappend_998_,(existT _ _stringappend_999_ _)) =>
+ let _stringappend_1000_ :=
+ string_drop
+ _stringappend_997_
+ (build_ex
+ _stringappend_999_) in
+ if
+ ((match (reg_name_matches_prefix
+ _stringappend_1000_) with
+ | Some
+ (_stringappend_1001_,(existT _ _stringappend_1002_ _)) =>
+ match (string_drop
+ _stringappend_1000_
+ (build_ex
+ _stringappend_1002_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__498 : bool =>
+ returnm ((if (w__498)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__499 : bool =>
+ returnm ((if (w__499)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__500 : bool =>
+ returnm ((if (w__500)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__501 : bool =>
+ returnm ((if (w__501)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__502 : bool =>
+ returnm ((if (w__502) then
+ true
+ else false)
+ : bool)) >>= fun w__503 : bool =>
+ (if (w__503) then
+ let _stringappend_982_ :=
+ string_drop
+ _stringappend_559_
+ (string_length "lr.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_982_) with
+ | Some
+ (_stringappend_983_,(existT _ _stringappend_984_ _)) =>
+ returnm ((_stringappend_983_,
+ build_ex
+ _stringappend_984_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__505 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(aq, existT _ _stringappend_984_ _) :=
+ w__505
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_985_ :=
+ string_drop
+ _stringappend_982_
+ (build_ex
+ _stringappend_984_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_985_) with
+ | Some
+ (_stringappend_986_,(existT _ _stringappend_987_ _)) =>
+ returnm ((_stringappend_986_,
+ build_ex
+ _stringappend_987_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__507 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rl, existT _ _stringappend_987_ _) :=
+ w__507
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_988_ :=
+ string_drop
+ _stringappend_985_
+ (build_ex
+ _stringappend_987_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_988_) with
+ | Some
+ (_stringappend_989_,(existT _ _stringappend_990_ _)) =>
+ returnm ((_stringappend_989_,
+ build_ex
+ _stringappend_990_)
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__509 : (word_width * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(size, existT _ _stringappend_990_ _) :=
+ w__509
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_991_ :=
+ string_drop
+ _stringappend_988_
+ (build_ex
+ _stringappend_990_) in
+ match (spc_matches_prefix
+ _stringappend_991_) with
+ | Some
+ (_stringappend_992_,(existT _ _stringappend_993_ _)) =>
+ returnm ((_stringappend_992_,
+ build_ex
+ _stringappend_993_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__511 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_993_ _) :=
+ w__511
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_994_ :=
+ string_drop
+ _stringappend_991_
+ (build_ex
+ _stringappend_993_) in
+ match (reg_name_matches_prefix
+ _stringappend_994_) with
+ | Some
+ (_stringappend_995_,(existT _ _stringappend_996_ _)) =>
+ returnm ((_stringappend_995_,
+ build_ex
+ _stringappend_996_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__513 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_996_ _) :=
+ w__513
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_997_ :=
+ string_drop
+ _stringappend_994_
+ (build_ex
+ _stringappend_996_) in
+ sep_matches_prefix
+ _stringappend_997_ >>= fun w__514 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__514 with
+ | Some
+ (_stringappend_998_,(existT _ _stringappend_999_ _)) =>
+ returnm ((_stringappend_998_,
+ build_ex
+ _stringappend_999_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__516 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_999_ _) :=
+ w__516
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1000_ :=
+ string_drop
+ _stringappend_997_
+ (build_ex
+ _stringappend_999_) in
+ match (reg_name_matches_prefix
+ _stringappend_1000_) with
+ | Some
+ (_stringappend_1001_,(existT _ _stringappend_1002_ _)) =>
+ returnm ((_stringappend_1001_,
+ build_ex
+ _stringappend_1002_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__518 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1002_ _) :=
+ w__518
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1000_
+ (build_ex
+ _stringappend_1002_)) with
+ | "" =>
+ returnm (true : bool)
+ | _ => exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_559_
+ "sc.")
+ : bool))
+ (let _stringappend_1004_ :=
+ string_drop
+ _stringappend_559_
+ (string_length "sc.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_1004_) with
+ | Some
+ (_stringappend_1005_,(existT _ _stringappend_1006_ _)) =>
+ let _stringappend_1007_ :=
+ string_drop
+ _stringappend_1004_
+ (build_ex
+ _stringappend_1006_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1007_) with
+ | Some
+ (_stringappend_1008_,(existT _ _stringappend_1009_ _)) =>
+ let _stringappend_1010_ :=
+ string_drop
+ _stringappend_1007_
+ (build_ex
+ _stringappend_1009_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1010_) with
+ | Some
+ (_stringappend_1011_,(existT _ _stringappend_1012_ _)) =>
+ let _stringappend_1013_ :=
+ string_drop
+ _stringappend_1010_
+ (build_ex
+ _stringappend_1012_) in
+ match (spc_matches_prefix
+ _stringappend_1013_) with
+ | Some
+ (_stringappend_1014_,(existT _ _stringappend_1015_ _)) =>
+ let _stringappend_1016_ :=
+ string_drop
+ _stringappend_1013_
+ (build_ex
+ _stringappend_1015_) in
+ match (reg_name_matches_prefix
+ _stringappend_1016_) with
+ | Some
+ (_stringappend_1017_,(existT _ _stringappend_1018_ _)) =>
+ let _stringappend_1019_ :=
+ string_drop
+ _stringappend_1016_
+ (build_ex
+ _stringappend_1018_) in
+ sep_matches_prefix
+ _stringappend_1019_ >>= fun w__521 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__521 with
+ | Some
+ (_stringappend_1020_,(existT _ _stringappend_1021_ _)) =>
+ let _stringappend_1022_ :=
+ string_drop
+ _stringappend_1019_
+ (build_ex
+ _stringappend_1021_) in
+ match (reg_name_matches_prefix
+ _stringappend_1022_) with
+ | Some
+ (_stringappend_1023_,(existT _ _stringappend_1024_ _)) =>
+ let _stringappend_1025_ :=
+ string_drop
+ _stringappend_1022_
+ (build_ex
+ _stringappend_1024_) in
+ sep_matches_prefix
+ _stringappend_1025_ >>= fun w__522 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__522 with
+ | Some
+ (_stringappend_1026_,(existT _ _stringappend_1027_ _)) =>
+ let _stringappend_1028_ :=
+ string_drop
+ _stringappend_1025_
+ (build_ex
+ _stringappend_1027_) in
+ if
+ ((match (reg_name_matches_prefix
+ _stringappend_1028_) with
+ | Some
+ (_stringappend_1029_,(existT _ _stringappend_1030_ _)) =>
+ match (string_drop
+ _stringappend_1028_
+ (build_ex
+ _stringappend_1030_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__523 : bool =>
+ returnm ((if
+ (w__523)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__524 : bool =>
+ returnm ((if
+ (w__524)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__525 : bool =>
+ returnm ((if (w__525)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__526 : bool =>
+ returnm ((if (w__526)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__527 : bool =>
+ returnm ((if (w__527)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__528 : bool =>
+ returnm ((if (w__528)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__529 : bool =>
+ returnm ((if (w__529)
+ then
+ true
+ else false)
+ : bool)) >>= fun w__530 : bool =>
+ (if (w__530) then
+ let _stringappend_1004_ :=
+ string_drop
+ _stringappend_559_
+ (string_length "sc.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_1004_) with
+ | Some
+ (_stringappend_1005_,(existT _ _stringappend_1006_ _)) =>
+ returnm ((_stringappend_1005_,
+ build_ex
+ _stringappend_1006_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__532 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(aq, existT _ _stringappend_1006_ _) :=
+ w__532
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1007_ :=
+ string_drop
+ _stringappend_1004_
+ (build_ex
+ _stringappend_1006_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1007_) with
+ | Some
+ (_stringappend_1008_,(existT _ _stringappend_1009_ _)) =>
+ returnm ((_stringappend_1008_,
+ build_ex
+ _stringappend_1009_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__534 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rl, existT _ _stringappend_1009_ _) :=
+ w__534
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1010_ :=
+ string_drop
+ _stringappend_1007_
+ (build_ex
+ _stringappend_1009_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1010_) with
+ | Some
+ (_stringappend_1011_,(existT _ _stringappend_1012_ _)) =>
+ returnm ((_stringappend_1011_,
+ build_ex
+ _stringappend_1012_)
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__536 : (word_width * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(size, existT _ _stringappend_1012_ _) :=
+ w__536
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1013_ :=
+ string_drop
+ _stringappend_1010_
+ (build_ex
+ _stringappend_1012_) in
+ match (spc_matches_prefix
+ _stringappend_1013_) with
+ | Some
+ (_stringappend_1014_,(existT _ _stringappend_1015_ _)) =>
+ returnm ((_stringappend_1014_,
+ build_ex
+ _stringappend_1015_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__538 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1015_ _) :=
+ w__538
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1016_ :=
+ string_drop
+ _stringappend_1013_
+ (build_ex
+ _stringappend_1015_) in
+ match (reg_name_matches_prefix
+ _stringappend_1016_) with
+ | Some
+ (_stringappend_1017_,(existT _ _stringappend_1018_ _)) =>
+ returnm ((_stringappend_1017_,
+ build_ex
+ _stringappend_1018_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__540 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1018_ _) :=
+ w__540
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1019_ :=
+ string_drop
+ _stringappend_1016_
+ (build_ex
+ _stringappend_1018_) in
+ sep_matches_prefix
+ _stringappend_1019_ >>= fun w__541 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__541 with
+ | Some
+ (_stringappend_1020_,(existT _ _stringappend_1021_ _)) =>
+ returnm ((_stringappend_1020_,
+ build_ex
+ _stringappend_1021_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__543 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1021_ _) :=
+ w__543
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1022_ :=
+ string_drop
+ _stringappend_1019_
+ (build_ex
+ _stringappend_1021_) in
+ match (reg_name_matches_prefix
+ _stringappend_1022_) with
+ | Some
+ (_stringappend_1023_,(existT _ _stringappend_1024_ _)) =>
+ returnm ((_stringappend_1023_,
+ build_ex
+ _stringappend_1024_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__545 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1024_ _) :=
+ w__545
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1025_ :=
+ string_drop
+ _stringappend_1022_
+ (build_ex
+ _stringappend_1024_) in
+ sep_matches_prefix
+ _stringappend_1025_ >>= fun w__546 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__546 with
+ | Some
+ (_stringappend_1026_,(existT _ _stringappend_1027_ _)) =>
+ returnm ((_stringappend_1026_,
+ build_ex
+ _stringappend_1027_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__548 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1027_ _) :=
+ w__548
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1028_ :=
+ string_drop
+ _stringappend_1025_
+ (build_ex
+ _stringappend_1027_) in
+ match (reg_name_matches_prefix
+ _stringappend_1028_) with
+ | Some
+ (_stringappend_1029_,(existT _ _stringappend_1030_ _)) =>
+ returnm ((_stringappend_1029_,
+ build_ex
+ _stringappend_1030_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__550 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1030_ _) :=
+ w__550
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1028_
+ (build_ex
+ _stringappend_1030_)) with
+ | "" =>
+ returnm (true
+ : bool)
+ | _ =>
+ exit tt : M (bool)
+ end)
+ : M (bool)
+ else
+ match (amo_mnemonic_matches_prefix
+ _stringappend_559_) with
+ | Some
+ (_stringappend_1032_,(existT _ _stringappend_1033_ _)) =>
+ let _stringappend_1034_ :=
+ string_drop
+ _stringappend_559_
+ (build_ex
+ _stringappend_1033_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1034_
+ ".")
+ : bool))
+ (let _stringappend_1035_ :=
+ string_drop
+ _stringappend_1034_
+ (string_length
+ ".") in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1035_) with
+ | Some
+ (_stringappend_1036_,(existT _ _stringappend_1037_ _)) =>
+ let _stringappend_1038_ :=
+ string_drop
+ _stringappend_1035_
+ (build_ex
+ _stringappend_1037_) in
+ match (maybe_aq_matches_prefix
+ _stringappend_1038_) with
+ | Some
+ (_stringappend_1039_,(existT _ _stringappend_1040_ _)) =>
+ let _stringappend_1041_ :=
+ string_drop
+ _stringappend_1038_
+ (build_ex
+ _stringappend_1040_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1041_) with
+ | Some
+ (_stringappend_1042_,(existT _ _stringappend_1043_ _)) =>
+ let _stringappend_1044_ :=
+ string_drop
+ _stringappend_1041_
+ (build_ex
+ _stringappend_1043_) in
+ match (spc_matches_prefix
+ _stringappend_1044_) with
+ | Some
+ (_stringappend_1045_,(existT _ _stringappend_1046_ _)) =>
+ let _stringappend_1047_ :=
+ string_drop
+ _stringappend_1044_
+ (build_ex
+ _stringappend_1046_) in
+ match (reg_name_matches_prefix
+ _stringappend_1047_) with
+ | Some
+ (_stringappend_1048_,(existT _ _stringappend_1049_ _)) =>
+ let _stringappend_1050_ :=
+ string_drop
+ _stringappend_1047_
+ (build_ex
+ _stringappend_1049_) in
+ sep_matches_prefix
+ _stringappend_1050_ >>= fun w__553 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__553 with
+ | Some
+ (_stringappend_1051_,(existT _ _stringappend_1052_ _)) =>
+ let _stringappend_1053_ :=
+ string_drop
+ _stringappend_1050_
+ (build_ex
+ _stringappend_1052_) in
+ match (reg_name_matches_prefix
+ _stringappend_1053_) with
+ | Some
+ (_stringappend_1054_,(existT _ _stringappend_1055_ _)) =>
+ let _stringappend_1056_ :=
+ string_drop
+ _stringappend_1053_
+ (build_ex
+ _stringappend_1055_) in
+ sep_matches_prefix
+ _stringappend_1056_ >>= fun w__554 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__554 with
+ | Some
+ (_stringappend_1057_,(existT _ _stringappend_1058_ _)) =>
+ let _stringappend_1059_ :=
+ string_drop
+ _stringappend_1056_
+ (build_ex
+ _stringappend_1058_) in
+ if
+ ((match (reg_name_matches_prefix
+ _stringappend_1059_) with
+ | Some
+ (_stringappend_1060_,(existT _ _stringappend_1061_ _)) =>
+ match (string_drop
+ _stringappend_1059_
+ (build_ex
+ _stringappend_1061_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__555 : bool =>
+ returnm ((if
+ (w__555)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__556 : bool =>
+ returnm ((if
+ (w__556)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__557 : bool =>
+ returnm ((if
+ (w__557)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__558 : bool =>
+ returnm ((if
+ (w__558)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__559 : bool =>
+ returnm ((if (w__559)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__560 : bool =>
+ returnm ((if (w__560)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__561 : bool =>
+ returnm ((if (w__561)
+ then
+ true
+ else
+ false)
+ : bool)) >>= fun w__562 : bool =>
+ returnm ((if (w__562)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__563 : bool =>
+ (if (w__563) then
+ match (amo_mnemonic_matches_prefix
+ _stringappend_559_) with
+ | Some
+ (_stringappend_1032_,(existT _ _stringappend_1033_ _)) =>
+ returnm ((_stringappend_1032_,
+ build_ex
+ _stringappend_1033_)
+ : (amoop * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((amoop * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__565 : (amoop * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(op, existT _ _stringappend_1033_ _) :=
+ w__565
+ : (amoop * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1034_ :=
+ string_drop
+ _stringappend_559_
+ (build_ex
+ _stringappend_1033_) in
+ let _stringappend_1035_ :=
+ string_drop
+ _stringappend_1034_
+ (string_length
+ ".") in
+ match (size_mnemonic_matches_prefix
+ _stringappend_1035_) with
+ | Some
+ (_stringappend_1036_,(existT _ _stringappend_1037_ _)) =>
+ returnm ((_stringappend_1036_,
+ build_ex
+ _stringappend_1037_)
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__567 : (word_width * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(width, existT _ _stringappend_1037_ _) :=
+ w__567
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1038_ :=
+ string_drop
+ _stringappend_1035_
+ (build_ex
+ _stringappend_1037_) in
+ match (maybe_aq_matches_prefix
+ _stringappend_1038_) with
+ | Some
+ (_stringappend_1039_,(existT _ _stringappend_1040_ _)) =>
+ returnm ((_stringappend_1039_,
+ build_ex
+ _stringappend_1040_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__569 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(aq, existT _ _stringappend_1040_ _) :=
+ w__569
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1041_ :=
+ string_drop
+ _stringappend_1038_
+ (build_ex
+ _stringappend_1040_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_1041_) with
+ | Some
+ (_stringappend_1042_,(existT _ _stringappend_1043_ _)) =>
+ returnm ((_stringappend_1042_,
+ build_ex
+ _stringappend_1043_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__571 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rl, existT _ _stringappend_1043_ _) :=
+ w__571
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1044_ :=
+ string_drop
+ _stringappend_1041_
+ (build_ex
+ _stringappend_1043_) in
+ match (spc_matches_prefix
+ _stringappend_1044_) with
+ | Some
+ (_stringappend_1045_,(existT _ _stringappend_1046_ _)) =>
+ returnm ((_stringappend_1045_,
+ build_ex
+ _stringappend_1046_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__573 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1046_ _) :=
+ w__573
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1047_ :=
+ string_drop
+ _stringappend_1044_
+ (build_ex
+ _stringappend_1046_) in
+ match (reg_name_matches_prefix
+ _stringappend_1047_) with
+ | Some
+ (_stringappend_1048_,(existT _ _stringappend_1049_ _)) =>
+ returnm ((_stringappend_1048_,
+ build_ex
+ _stringappend_1049_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__575 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1049_ _) :=
+ w__575
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1050_ :=
+ string_drop
+ _stringappend_1047_
+ (build_ex
+ _stringappend_1049_) in
+ sep_matches_prefix
+ _stringappend_1050_ >>= fun w__576 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__576 with
+ | Some
+ (_stringappend_1051_,(existT _ _stringappend_1052_ _)) =>
+ returnm ((_stringappend_1051_,
+ build_ex
+ _stringappend_1052_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__578 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1052_ _) :=
+ w__578
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1053_ :=
+ string_drop
+ _stringappend_1050_
+ (build_ex
+ _stringappend_1052_) in
+ match (reg_name_matches_prefix
+ _stringappend_1053_) with
+ | Some
+ (_stringappend_1054_,(existT _ _stringappend_1055_ _)) =>
+ returnm ((_stringappend_1054_,
+ build_ex
+ _stringappend_1055_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__580 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1055_ _) :=
+ w__580
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1056_ :=
+ string_drop
+ _stringappend_1053_
+ (build_ex
+ _stringappend_1055_) in
+ sep_matches_prefix
+ _stringappend_1056_ >>= fun w__581 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__581 with
+ | Some
+ (_stringappend_1057_,(existT _ _stringappend_1058_ _)) =>
+ returnm ((_stringappend_1057_,
+ build_ex
+ _stringappend_1058_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__583 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1058_ _) :=
+ w__583
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1059_ :=
+ string_drop
+ _stringappend_1056_
+ (build_ex
+ _stringappend_1058_) in
+ match (reg_name_matches_prefix
+ _stringappend_1059_) with
+ | Some
+ (_stringappend_1060_,(existT _ _stringappend_1061_ _)) =>
+ returnm ((_stringappend_1060_,
+ build_ex
+ _stringappend_1061_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__585 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_1061_ _) :=
+ w__585
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1059_
+ (build_ex
+ _stringappend_1061_)) with
+ | "" =>
+ returnm (true
+ : bool)
+ | _ =>
+ exit tt
+ : M (bool)
+ end)
+ : M (bool)
+ else
+ match (csr_mnemonic_matches_prefix
+ _stringappend_559_) with
+ | Some
+ (_stringappend_1063_,(existT _ _stringappend_1064_ _)) =>
+ let _stringappend_1065_ :=
+ string_drop
+ _stringappend_559_
+ (build_ex
+ _stringappend_1064_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_1065_
+ "i")
+ : bool))
+ (let _stringappend_1066_ :=
+ string_drop
+ _stringappend_1065_
+ (string_length
+ "i") in
+ match (spc_matches_prefix
+ _stringappend_1066_) with
+ | Some
+ (_stringappend_1067_,(existT _ _stringappend_1068_ _)) =>
+ let _stringappend_1069_ :=
+ string_drop
+ _stringappend_1066_
+ (build_ex
+ _stringappend_1068_) in
+ match (reg_name_matches_prefix
+ _stringappend_1069_) with
+ | Some
+ (_stringappend_1070_,(existT _ _stringappend_1071_ _)) =>
+ let _stringappend_1072_ :=
+ string_drop
+ _stringappend_1069_
+ (build_ex
+ _stringappend_1071_) in
+ sep_matches_prefix
+ _stringappend_1072_ >>= fun w__588 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__588 with
+ | Some
+ (_stringappend_1073_,(existT _ _stringappend_1074_ _)) =>
+ let _stringappend_1075_ :=
+ string_drop
+ _stringappend_1072_
+ (build_ex
+ _stringappend_1074_) in
+ match (hex_bits_5_matches_prefix
+ _stringappend_1075_) with
+ | Some
+ (_stringappend_1076_,(existT _ _stringappend_1077_ _)) =>
+ let _stringappend_1078_ :=
+ string_drop
+ _stringappend_1075_
+ (build_ex
+ _stringappend_1077_) in
+ sep_matches_prefix
+ _stringappend_1078_ >>= fun w__589 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__589 with
+ | Some
+ (_stringappend_1079_,(existT _ _stringappend_1080_ _)) =>
+ let _stringappend_1081_ :=
+ string_drop
+ _stringappend_1078_
+ (build_ex
+ _stringappend_1080_) in
+ if
+ ((match (csr_name_map_matches_prefix
+ _stringappend_1081_) with
+ | Some
+ (_stringappend_1082_,(existT _ _stringappend_1083_ _)) =>
+ match (string_drop
+ _stringappend_1081_
+ (build_ex
+ _stringappend_1083_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__590 : bool =>
+ returnm ((if
+ (w__590)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__591 : bool =>
+ returnm ((if
+ (w__591)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__592 : bool =>
+ returnm ((if (w__592)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__593 : bool =>
+ returnm ((if (w__593)
+ then
+ true
+ else
+ false)
+ : bool)) >>= fun w__594 : bool =>
+ returnm ((if (w__594)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__595 : bool =>
+ (if (w__595) then
+ match (csr_mnemonic_matches_prefix
+ _stringappend_559_) with
+ | Some
+ (_stringappend_1063_,(existT _ _stringappend_1064_ _)) =>
+ returnm ((_stringappend_1063_,
+ build_ex
+ _stringappend_1064_)
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__597 : (csrop * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(op, existT _ _stringappend_1064_ _) :=
+ w__597
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1065_ :=
+ string_drop
+ _stringappend_559_
+ (build_ex
+ _stringappend_1064_) in
+ let _stringappend_1066_ :=
+ string_drop
+ _stringappend_1065_
+ (string_length
+ "i") in
+ match (spc_matches_prefix
+ _stringappend_1066_) with
+ | Some
+ (_stringappend_1067_,(existT _ _stringappend_1068_ _)) =>
+ returnm ((_stringappend_1067_,
+ build_ex
+ _stringappend_1068_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__599 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1068_ _) :=
+ w__599
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1069_ :=
+ string_drop
+ _stringappend_1066_
+ (build_ex
+ _stringappend_1068_) in
+ match (reg_name_matches_prefix
+ _stringappend_1069_) with
+ | Some
+ (_stringappend_1070_,(existT _ _stringappend_1071_ _)) =>
+ returnm ((_stringappend_1070_,
+ build_ex
+ _stringappend_1071_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__601 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1071_ _) :=
+ w__601
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1072_ :=
+ string_drop
+ _stringappend_1069_
+ (build_ex
+ _stringappend_1071_) in
+ sep_matches_prefix
+ _stringappend_1072_ >>= fun w__602 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__602 with
+ | Some
+ (_stringappend_1073_,(existT _ _stringappend_1074_ _)) =>
+ returnm ((_stringappend_1073_,
+ build_ex
+ _stringappend_1074_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__604 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1074_ _) :=
+ w__604
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1075_ :=
+ string_drop
+ _stringappend_1072_
+ (build_ex
+ _stringappend_1074_) in
+ match (hex_bits_5_matches_prefix
+ _stringappend_1075_) with
+ | Some
+ (_stringappend_1076_,(existT _ _stringappend_1077_ _)) =>
+ returnm ((_stringappend_1076_,
+ build_ex
+ _stringappend_1077_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__606 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1077_ _) :=
+ w__606
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1078_ :=
+ string_drop
+ _stringappend_1075_
+ (build_ex
+ _stringappend_1077_) in
+ sep_matches_prefix
+ _stringappend_1078_ >>= fun w__607 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__607 with
+ | Some
+ (_stringappend_1079_,(existT _ _stringappend_1080_ _)) =>
+ returnm ((_stringappend_1079_,
+ build_ex
+ _stringappend_1080_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__609 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1080_ _) :=
+ w__609
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1081_ :=
+ string_drop
+ _stringappend_1078_
+ (build_ex
+ _stringappend_1080_) in
+ match (csr_name_map_matches_prefix
+ _stringappend_1081_) with
+ | Some
+ (_stringappend_1082_,(existT _ _stringappend_1083_ _)) =>
+ returnm ((_stringappend_1082_,
+ build_ex
+ _stringappend_1083_)
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__611 : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(csr, existT _ _stringappend_1083_ _) :=
+ w__611
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1081_
+ (build_ex
+ _stringappend_1083_)) with
+ | "" =>
+ returnm (true
+ : bool)
+ | _ =>
+ exit tt
+ : M (bool)
+ end)
+ : M (bool)
+ else
+ match (csr_mnemonic_matches_prefix
+ _stringappend_559_) with
+ | Some
+ (_stringappend_1085_,(existT _ _stringappend_1086_ _)) =>
+ let _stringappend_1087_ :=
+ string_drop
+ _stringappend_559_
+ (build_ex
+ _stringappend_1086_) in
+ match (spc_matches_prefix
+ _stringappend_1087_) with
+ | Some
+ (_stringappend_1088_,(existT _ _stringappend_1089_ _)) =>
+ let _stringappend_1090_ :=
+ string_drop
+ _stringappend_1087_
+ (build_ex
+ _stringappend_1089_) in
+ match (reg_name_matches_prefix
+ _stringappend_1090_) with
+ | Some
+ (_stringappend_1091_,(existT _ _stringappend_1092_ _)) =>
+ let _stringappend_1093_ :=
+ string_drop
+ _stringappend_1090_
+ (build_ex
+ _stringappend_1092_) in
+ sep_matches_prefix
+ _stringappend_1093_ >>= fun w__614 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__614 with
+ | Some
+ (_stringappend_1094_,(existT _ _stringappend_1095_ _)) =>
+ let _stringappend_1096_ :=
+ string_drop
+ _stringappend_1093_
+ (build_ex
+ _stringappend_1095_) in
+ match (reg_name_matches_prefix
+ _stringappend_1096_) with
+ | Some
+ (_stringappend_1097_,(existT _ _stringappend_1098_ _)) =>
+ let _stringappend_1099_ :=
+ string_drop
+ _stringappend_1096_
+ (build_ex
+ _stringappend_1098_) in
+ sep_matches_prefix
+ _stringappend_1099_ >>= fun w__615 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__615 with
+ | Some
+ (_stringappend_1100_,(existT _ _stringappend_1101_ _)) =>
+ let _stringappend_1102_ :=
+ string_drop
+ _stringappend_1099_
+ (build_ex
+ _stringappend_1101_) in
+ if
+ ((match (csr_name_map_matches_prefix
+ _stringappend_1102_) with
+ | Some
+ (_stringappend_1103_,(existT _ _stringappend_1104_ _)) =>
+ match (string_drop
+ _stringappend_1102_
+ (build_ex
+ _stringappend_1104_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__616 : bool =>
+ returnm ((if
+ (w__616)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__617 : bool =>
+ returnm ((if
+ (w__617)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__618 : bool =>
+ returnm ((if
+ (w__618)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__619 : bool =>
+ returnm ((if (w__619)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__620 : bool =>
+ (if (w__620) then
+ match (csr_mnemonic_matches_prefix
+ _stringappend_559_) with
+ | Some
+ (_stringappend_1085_,(existT _ _stringappend_1086_ _)) =>
+ returnm ((_stringappend_1085_,
+ build_ex
+ _stringappend_1086_)
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__622 : (csrop * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(op, existT _ _stringappend_1086_ _) :=
+ w__622
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1087_ :=
+ string_drop
+ _stringappend_559_
+ (build_ex
+ _stringappend_1086_) in
+ match (spc_matches_prefix
+ _stringappend_1087_) with
+ | Some
+ (_stringappend_1088_,(existT _ _stringappend_1089_ _)) =>
+ returnm ((_stringappend_1088_,
+ build_ex
+ _stringappend_1089_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__624 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1089_ _) :=
+ w__624
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1090_ :=
+ string_drop
+ _stringappend_1087_
+ (build_ex
+ _stringappend_1089_) in
+ match (reg_name_matches_prefix
+ _stringappend_1090_) with
+ | Some
+ (_stringappend_1091_,(existT _ _stringappend_1092_ _)) =>
+ returnm ((_stringappend_1091_,
+ build_ex
+ _stringappend_1092_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__626 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_1092_ _) :=
+ w__626
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1093_ :=
+ string_drop
+ _stringappend_1090_
+ (build_ex
+ _stringappend_1092_) in
+ sep_matches_prefix
+ _stringappend_1093_ >>= fun w__627 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__627 with
+ | Some
+ (_stringappend_1094_,(existT _ _stringappend_1095_ _)) =>
+ returnm ((_stringappend_1094_,
+ build_ex
+ _stringappend_1095_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__629 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1095_ _) :=
+ w__629
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1096_ :=
+ string_drop
+ _stringappend_1093_
+ (build_ex
+ _stringappend_1095_) in
+ match (reg_name_matches_prefix
+ _stringappend_1096_) with
+ | Some
+ (_stringappend_1097_,(existT _ _stringappend_1098_ _)) =>
+ returnm ((_stringappend_1097_,
+ build_ex
+ _stringappend_1098_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__631 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_1098_ _) :=
+ w__631
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1099_ :=
+ string_drop
+ _stringappend_1096_
+ (build_ex
+ _stringappend_1098_) in
+ sep_matches_prefix
+ _stringappend_1099_ >>= fun w__632 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__632 with
+ | Some
+ (_stringappend_1100_,(existT _ _stringappend_1101_ _)) =>
+ returnm ((_stringappend_1100_,
+ build_ex
+ _stringappend_1101_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__634 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1101_ _) :=
+ w__634
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1102_ :=
+ string_drop
+ _stringappend_1099_
+ (build_ex
+ _stringappend_1101_) in
+ match (csr_name_map_matches_prefix
+ _stringappend_1102_) with
+ | Some
+ (_stringappend_1103_,(existT _ _stringappend_1104_ _)) =>
+ returnm ((_stringappend_1103_,
+ build_ex
+ _stringappend_1104_)
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__636 : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(csr, existT _ _stringappend_1104_ _) :=
+ w__636
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1102_
+ (build_ex
+ _stringappend_1104_)) with
+ | "" =>
+ returnm (true
+ : bool)
+ | _ =>
+ exit tt
+ : M (bool)
+ end)
+ : M (bool)
+ else if ((andb
+ (string_startswith
+ _stringappend_559_
+ "illegal")
+ (let _stringappend_1106_ :=
+ string_drop
+ _stringappend_559_
+ (string_length
+ "illegal") in
+ if ((match (spc_matches_prefix
+ _stringappend_1106_) with
+ | Some
+ (_stringappend_1107_,(existT _ _stringappend_1108_ _)) =>
+ let _stringappend_1109_ :=
+ string_drop
+ _stringappend_1106_
+ (build_ex
+ _stringappend_1108_) in
+ if
+ ((match (hex_bits_32_matches_prefix
+ _stringappend_1109_) with
+ | Some
+ (_stringappend_1110_,(existT _ _stringappend_1111_ _)) =>
+ match (string_drop
+ _stringappend_1109_
+ (build_ex
+ _stringappend_1111_)) with
+ | "" =>
+ true
+ | _ =>
+ false
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)))
+ then
+ let _stringappend_1106_ :=
+ string_drop
+ _stringappend_559_
+ (string_length
+ "illegal") in
+ match (spc_matches_prefix
+ _stringappend_1106_) with
+ | Some
+ (_stringappend_1107_,(existT _ _stringappend_1108_ _)) =>
+ returnm ((_stringappend_1107_,
+ build_ex
+ _stringappend_1108_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__640 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_1108_ _) :=
+ w__640
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_1109_ :=
+ string_drop
+ _stringappend_1106_
+ (build_ex
+ _stringappend_1108_) in
+ match (hex_bits_32_matches_prefix
+ _stringappend_1109_) with
+ | Some
+ (_stringappend_1110_,(existT _ _stringappend_1111_ _)) =>
+ returnm ((_stringappend_1110_,
+ build_ex
+ _stringappend_1111_)
+ : (mword 32 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 32 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__642 : (mword 32 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_1111_ _) :=
+ w__642
+ : (mword 32 * {n : Z & ArithFact (n >=
+ 0)}) in
+ (match (string_drop
+ _stringappend_1109_
+ (build_ex
+ _stringappend_1111_)) with
+ | "" =>
+ returnm (true
+ : bool)
+ | _ =>
+ exit tt
+ : M (bool)
+ end)
+ : M (bool)
+ else
+ returnm (false
+ : bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool)
+ end)
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool))
+ : M (bool).
+
+Definition assembly_matches_prefix (arg_ : string)
+: M (option ((ast * {n : Z & ArithFact (n >= 0)}))) :=
+ let _stringappend_0_ := arg_ in
+ match (utype_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_1_,(existT _ _stringappend_2_ _)) =>
+ let _stringappend_3_ := string_drop _stringappend_0_ (build_ex _stringappend_2_) in
+ match (spc_matches_prefix _stringappend_3_) with
+ | Some (_stringappend_4_,(existT _ _stringappend_5_ _)) =>
+ let _stringappend_6_ := string_drop _stringappend_3_ (build_ex _stringappend_5_) in
+ match (reg_name_matches_prefix _stringappend_6_) with
+ | Some (_stringappend_7_,(existT _ _stringappend_8_ _)) =>
+ let _stringappend_9_ := string_drop _stringappend_6_ (build_ex _stringappend_8_) in
+ sep_matches_prefix _stringappend_9_ >>= fun w__0 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__0 with
+ | Some (_stringappend_10_,(existT _ _stringappend_11_ _)) =>
+ let _stringappend_12_ :=
+ string_drop _stringappend_9_ (build_ex _stringappend_11_) in
+ if ((match (hex_bits_20_matches_prefix _stringappend_12_) with
+ | Some (_stringappend_13_,(existT _ _stringappend_14_ _)) =>
+ match (string_drop _stringappend_12_
+ (build_ex
+ _stringappend_14_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__1 : bool =>
+ returnm ((if (w__1) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__2 : bool =>
+ returnm ((if (w__2) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__3 : bool =>
+ (if (w__3) then
+ match (utype_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_1_,(existT _ _stringappend_2_ _)) =>
+ returnm ((_stringappend_1_, build_ex _stringappend_2_)
+ : (uop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((uop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__5 : (uop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_2_ _) := w__5 : (uop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_3_ := string_drop _stringappend_0_ (build_ex _stringappend_2_) in
+ match (spc_matches_prefix _stringappend_3_) with
+ | Some (_stringappend_4_,(existT _ _stringappend_5_ _)) =>
+ returnm ((_stringappend_4_, build_ex _stringappend_5_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__7 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_5_ _) := w__7 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_6_ := string_drop _stringappend_3_ (build_ex _stringappend_5_) in
+ match (reg_name_matches_prefix _stringappend_6_) with
+ | Some (_stringappend_7_,(existT _ _stringappend_8_ _)) =>
+ returnm ((_stringappend_7_, build_ex _stringappend_8_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__9 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_8_ _) := w__9 : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_9_ := string_drop _stringappend_6_ (build_ex _stringappend_8_) in
+ sep_matches_prefix _stringappend_9_ >>= fun w__10 : option ((unit * {n : Z & ArithFact (n >= 0)})) =>
+ match w__10 with
+ | Some (_stringappend_10_,(existT _ _stringappend_11_ _)) =>
+ returnm ((_stringappend_10_, build_ex _stringappend_11_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__12 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_11_ _) := w__12 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_12_ := string_drop _stringappend_9_ (build_ex _stringappend_11_) in
+ match (hex_bits_20_matches_prefix _stringappend_12_) with
+ | Some (_stringappend_13_,(existT _ _stringappend_14_ _)) =>
+ returnm ((_stringappend_13_, build_ex _stringappend_14_)
+ : (mword 20 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 20 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__14 : (mword 20 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_14_ _) := w__14 : (mword 20 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_12_ (build_ex _stringappend_14_)) with
+ | s_ => Some (UTYPE (imm,rd,op), sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ and_boolM (returnm ((string_startswith _stringappend_0_ "jal") : bool))
+ (let _stringappend_16_ := string_drop _stringappend_0_ (string_length "jal") in
+ match (spc_matches_prefix _stringappend_16_) with
+ | Some (_stringappend_17_,(existT _ _stringappend_18_ _)) =>
+ let _stringappend_19_ := string_drop _stringappend_16_ (build_ex _stringappend_18_) in
+ match (reg_name_matches_prefix _stringappend_19_) with
+ | Some (_stringappend_20_,(existT _ _stringappend_21_ _)) =>
+ let _stringappend_22_ := string_drop _stringappend_19_ (build_ex _stringappend_21_) in
+ sep_matches_prefix _stringappend_22_ >>= fun w__15 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__15 with
+ | Some (_stringappend_23_,(existT _ _stringappend_24_ _)) =>
+ let _stringappend_25_ :=
+ string_drop _stringappend_22_ (build_ex _stringappend_24_) in
+ if ((match (hex_bits_21_matches_prefix _stringappend_25_) with
+ | Some (_stringappend_26_,(existT _ _stringappend_27_ _)) =>
+ match (string_drop _stringappend_25_
+ (build_ex
+ _stringappend_27_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__16 : bool =>
+ returnm ((if (w__16) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__17 : bool =>
+ returnm ((if (w__17) then true
+ else false)
+ : bool)) >>= fun w__18 : bool =>
+ (if (w__18) then
+ let _stringappend_16_ := string_drop _stringappend_0_ (string_length "jal") in
+ match (spc_matches_prefix _stringappend_16_) with
+ | Some (_stringappend_17_,(existT _ _stringappend_18_ _)) =>
+ returnm ((_stringappend_17_, build_ex _stringappend_18_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__20 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_18_ _) := w__20 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_19_ := string_drop _stringappend_16_ (build_ex _stringappend_18_) in
+ match (reg_name_matches_prefix _stringappend_19_) with
+ | Some (_stringappend_20_,(existT _ _stringappend_21_ _)) =>
+ returnm ((_stringappend_20_, build_ex _stringappend_21_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__22 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_21_ _) :=
+ w__22
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_22_ := string_drop _stringappend_19_ (build_ex _stringappend_21_) in
+ sep_matches_prefix _stringappend_22_ >>= fun w__23 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__23 with
+ | Some (_stringappend_23_,(existT _ _stringappend_24_ _)) =>
+ returnm ((_stringappend_23_, build_ex _stringappend_24_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__25 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_24_ _) := w__25 : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_25_ := string_drop _stringappend_22_ (build_ex _stringappend_24_) in
+ match (hex_bits_21_matches_prefix _stringappend_25_) with
+ | Some (_stringappend_26_,(existT _ _stringappend_27_ _)) =>
+ returnm ((_stringappend_26_, build_ex _stringappend_27_)
+ : (mword 21 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 21 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__27 : (mword 21 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_27_ _) :=
+ w__27
+ : (mword 21 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_25_ (build_ex _stringappend_27_)) with
+ | s_ =>
+ Some (RISCV_JAL (imm,rd), sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ and_boolM (returnm ((string_startswith _stringappend_0_ "jalr") : bool))
+ (let _stringappend_29_ := string_drop _stringappend_0_ (string_length "jalr") in
+ match (spc_matches_prefix _stringappend_29_) with
+ | Some (_stringappend_30_,(existT _ _stringappend_31_ _)) =>
+ let _stringappend_32_ := string_drop _stringappend_29_ (build_ex _stringappend_31_) in
+ match (reg_name_matches_prefix _stringappend_32_) with
+ | Some (_stringappend_33_,(existT _ _stringappend_34_ _)) =>
+ let _stringappend_35_ := string_drop _stringappend_32_ (build_ex _stringappend_34_) in
+ sep_matches_prefix _stringappend_35_ >>= fun w__28 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__28 with
+ | Some (_stringappend_36_,(existT _ _stringappend_37_ _)) =>
+ let _stringappend_38_ :=
+ string_drop _stringappend_35_ (build_ex _stringappend_37_) in
+ match (reg_name_matches_prefix _stringappend_38_) with
+ | Some (_stringappend_39_,(existT _ _stringappend_40_ _)) =>
+ let _stringappend_41_ :=
+ string_drop _stringappend_38_ (build_ex _stringappend_40_) in
+ sep_matches_prefix _stringappend_41_ >>= fun w__29 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__29 with
+ | Some (_stringappend_42_,(existT _ _stringappend_43_ _)) =>
+ let _stringappend_44_ :=
+ string_drop _stringappend_41_
+ (build_ex
+ _stringappend_43_) in
+ if ((match (hex_bits_12_matches_prefix _stringappend_44_) with
+ | Some
+ (_stringappend_45_,(existT _ _stringappend_46_ _)) =>
+ match (string_drop _stringappend_44_
+ (build_ex
+ _stringappend_46_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__30 : bool =>
+ returnm ((if (w__30) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__31 : bool =>
+ returnm ((if (w__31) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__32 : bool =>
+ returnm ((if (w__32) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__33 : bool =>
+ returnm ((if (w__33) then true
+ else false)
+ : bool)) >>= fun w__34 : bool =>
+ (if (w__34) then
+ let _stringappend_29_ := string_drop _stringappend_0_ (string_length "jalr") in
+ match (spc_matches_prefix _stringappend_29_) with
+ | Some (_stringappend_30_,(existT _ _stringappend_31_ _)) =>
+ returnm ((_stringappend_30_, build_ex _stringappend_31_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__36 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_31_ _) :=
+ w__36
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_32_ := string_drop _stringappend_29_ (build_ex _stringappend_31_) in
+ match (reg_name_matches_prefix _stringappend_32_) with
+ | Some (_stringappend_33_,(existT _ _stringappend_34_ _)) =>
+ returnm ((_stringappend_33_, build_ex _stringappend_34_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__38 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_34_ _) :=
+ w__38
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_35_ := string_drop _stringappend_32_ (build_ex _stringappend_34_) in
+ sep_matches_prefix _stringappend_35_ >>= fun w__39 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__39 with
+ | Some (_stringappend_36_,(existT _ _stringappend_37_ _)) =>
+ returnm ((_stringappend_36_, build_ex _stringappend_37_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__41 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_37_ _) :=
+ w__41
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_38_ := string_drop _stringappend_35_ (build_ex _stringappend_37_) in
+ match (reg_name_matches_prefix _stringappend_38_) with
+ | Some (_stringappend_39_,(existT _ _stringappend_40_ _)) =>
+ returnm ((_stringappend_39_, build_ex _stringappend_40_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__43 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_40_ _) :=
+ w__43
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_41_ := string_drop _stringappend_38_ (build_ex _stringappend_40_) in
+ sep_matches_prefix _stringappend_41_ >>= fun w__44 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__44 with
+ | Some (_stringappend_42_,(existT _ _stringappend_43_ _)) =>
+ returnm ((_stringappend_42_, build_ex _stringappend_43_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__46 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_43_ _) :=
+ w__46
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_44_ := string_drop _stringappend_41_ (build_ex _stringappend_43_) in
+ match (hex_bits_12_matches_prefix _stringappend_44_) with
+ | Some (_stringappend_45_,(existT _ _stringappend_46_ _)) =>
+ returnm ((_stringappend_45_, build_ex _stringappend_46_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__48 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_46_ _) :=
+ w__48
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_44_ (build_ex _stringappend_46_)) with
+ | s_ =>
+ Some (RISCV_JALR (imm,rs1,rd),
+ sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ match (btype_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_48_,(existT _ _stringappend_49_ _)) =>
+ let _stringappend_50_ := string_drop _stringappend_0_ (build_ex _stringappend_49_) in
+ match (spc_matches_prefix _stringappend_50_) with
+ | Some (_stringappend_51_,(existT _ _stringappend_52_ _)) =>
+ let _stringappend_53_ :=
+ string_drop _stringappend_50_ (build_ex _stringappend_52_) in
+ match (reg_name_matches_prefix _stringappend_53_) with
+ | Some (_stringappend_54_,(existT _ _stringappend_55_ _)) =>
+ let _stringappend_56_ :=
+ string_drop _stringappend_53_ (build_ex _stringappend_55_) in
+ sep_matches_prefix _stringappend_56_ >>= fun w__49 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__49 with
+ | Some (_stringappend_57_,(existT _ _stringappend_58_ _)) =>
+ let _stringappend_59_ :=
+ string_drop _stringappend_56_ (build_ex _stringappend_58_) in
+ match (reg_name_matches_prefix _stringappend_59_) with
+ | Some (_stringappend_60_,(existT _ _stringappend_61_ _)) =>
+ let _stringappend_62_ :=
+ string_drop _stringappend_59_ (build_ex _stringappend_61_) in
+ sep_matches_prefix _stringappend_62_ >>= fun w__50 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__50 with
+ | Some (_stringappend_63_,(existT _ _stringappend_64_ _)) =>
+ let _stringappend_65_ :=
+ string_drop _stringappend_62_
+ (build_ex
+ _stringappend_64_) in
+ if ((match (hex_bits_13_matches_prefix
+ _stringappend_65_) with
+ | Some
+ (_stringappend_66_,(existT _ _stringappend_67_ _)) =>
+ match (string_drop _stringappend_65_
+ (build_ex
+ _stringappend_67_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__51 : bool =>
+ returnm ((if (w__51) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__52 : bool =>
+ returnm ((if (w__52) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__53 : bool =>
+ returnm ((if (w__53) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__54 : bool =>
+ returnm ((if (w__54) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__55 : bool =>
+ (if (w__55) then
+ match (btype_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_48_,(existT _ _stringappend_49_ _)) =>
+ returnm ((_stringappend_48_, build_ex _stringappend_49_)
+ : (bop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__57 : (bop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_49_ _) :=
+ w__57
+ : (bop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_50_ := string_drop _stringappend_0_ (build_ex _stringappend_49_) in
+ match (spc_matches_prefix _stringappend_50_) with
+ | Some (_stringappend_51_,(existT _ _stringappend_52_ _)) =>
+ returnm ((_stringappend_51_, build_ex _stringappend_52_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__59 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_52_ _) :=
+ w__59
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_53_ := string_drop _stringappend_50_ (build_ex _stringappend_52_) in
+ match (reg_name_matches_prefix _stringappend_53_) with
+ | Some (_stringappend_54_,(existT _ _stringappend_55_ _)) =>
+ returnm ((_stringappend_54_, build_ex _stringappend_55_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__61 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_55_ _) :=
+ w__61
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_56_ := string_drop _stringappend_53_ (build_ex _stringappend_55_) in
+ sep_matches_prefix _stringappend_56_ >>= fun w__62 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__62 with
+ | Some (_stringappend_57_,(existT _ _stringappend_58_ _)) =>
+ returnm ((_stringappend_57_, build_ex _stringappend_58_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__64 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_58_ _) :=
+ w__64
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_59_ := string_drop _stringappend_56_ (build_ex _stringappend_58_) in
+ match (reg_name_matches_prefix _stringappend_59_) with
+ | Some (_stringappend_60_,(existT _ _stringappend_61_ _)) =>
+ returnm ((_stringappend_60_, build_ex _stringappend_61_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__66 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs2, existT _ _stringappend_61_ _) :=
+ w__66
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_62_ := string_drop _stringappend_59_ (build_ex _stringappend_61_) in
+ sep_matches_prefix _stringappend_62_ >>= fun w__67 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__67 with
+ | Some (_stringappend_63_,(existT _ _stringappend_64_ _)) =>
+ returnm ((_stringappend_63_, build_ex _stringappend_64_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__69 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_64_ _) :=
+ w__69
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_65_ := string_drop _stringappend_62_ (build_ex _stringappend_64_) in
+ match (hex_bits_13_matches_prefix _stringappend_65_) with
+ | Some (_stringappend_66_,(existT _ _stringappend_67_ _)) =>
+ returnm ((_stringappend_66_, build_ex _stringappend_67_)
+ : (mword 13 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 13 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__71 : (mword 13 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_67_ _) :=
+ w__71
+ : (mword 13 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_65_ (build_ex _stringappend_67_)) with
+ | s_ =>
+ Some (BTYPE (imm,rs2,rs1,op),
+ sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ match (itype_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_69_,(existT _ _stringappend_70_ _)) =>
+ let _stringappend_71_ := string_drop _stringappend_0_ (build_ex _stringappend_70_) in
+ match (spc_matches_prefix _stringappend_71_) with
+ | Some (_stringappend_72_,(existT _ _stringappend_73_ _)) =>
+ let _stringappend_74_ :=
+ string_drop _stringappend_71_ (build_ex _stringappend_73_) in
+ match (reg_name_matches_prefix _stringappend_74_) with
+ | Some (_stringappend_75_,(existT _ _stringappend_76_ _)) =>
+ let _stringappend_77_ :=
+ string_drop _stringappend_74_ (build_ex _stringappend_76_) in
+ sep_matches_prefix _stringappend_77_ >>= fun w__72 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__72 with
+ | Some (_stringappend_78_,(existT _ _stringappend_79_ _)) =>
+ let _stringappend_80_ :=
+ string_drop _stringappend_77_ (build_ex _stringappend_79_) in
+ match (reg_name_matches_prefix _stringappend_80_) with
+ | Some (_stringappend_81_,(existT _ _stringappend_82_ _)) =>
+ let _stringappend_83_ :=
+ string_drop _stringappend_80_ (build_ex _stringappend_82_) in
+ sep_matches_prefix _stringappend_83_ >>= fun w__73 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__73 with
+ | Some
+ (_stringappend_84_,(existT _ _stringappend_85_ _)) =>
+ let _stringappend_86_ :=
+ string_drop _stringappend_83_
+ (build_ex
+ _stringappend_85_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_86_) with
+ | Some
+ (_stringappend_87_,(existT _ _stringappend_88_ _)) =>
+ match (string_drop _stringappend_86_
+ (build_ex
+ _stringappend_88_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__74 : bool =>
+ returnm ((if (w__74) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__75 : bool =>
+ returnm ((if (w__75) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__76 : bool =>
+ returnm ((if (w__76) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__77 : bool =>
+ returnm ((if (w__77) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__78 : bool =>
+ (if (w__78) then
+ match (itype_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_69_,(existT _ _stringappend_70_ _)) =>
+ returnm ((_stringappend_69_, build_ex _stringappend_70_)
+ : (iop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((iop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__80 : (iop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_70_ _) :=
+ w__80
+ : (iop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_71_ := string_drop _stringappend_0_ (build_ex _stringappend_70_) in
+ match (spc_matches_prefix _stringappend_71_) with
+ | Some (_stringappend_72_,(existT _ _stringappend_73_ _)) =>
+ returnm ((_stringappend_72_, build_ex _stringappend_73_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__82 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_73_ _) :=
+ w__82
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_74_ :=
+ string_drop _stringappend_71_ (build_ex _stringappend_73_) in
+ match (reg_name_matches_prefix _stringappend_74_) with
+ | Some (_stringappend_75_,(existT _ _stringappend_76_ _)) =>
+ returnm ((_stringappend_75_, build_ex _stringappend_76_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__84 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_76_ _) :=
+ w__84
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_77_ :=
+ string_drop _stringappend_74_ (build_ex _stringappend_76_) in
+ sep_matches_prefix _stringappend_77_ >>= fun w__85 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__85 with
+ | Some (_stringappend_78_,(existT _ _stringappend_79_ _)) =>
+ returnm ((_stringappend_78_, build_ex _stringappend_79_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__87 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_79_ _) :=
+ w__87
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_80_ :=
+ string_drop _stringappend_77_ (build_ex _stringappend_79_) in
+ match (reg_name_matches_prefix _stringappend_80_) with
+ | Some (_stringappend_81_,(existT _ _stringappend_82_ _)) =>
+ returnm ((_stringappend_81_, build_ex _stringappend_82_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__89 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_82_ _) :=
+ w__89
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_83_ :=
+ string_drop _stringappend_80_ (build_ex _stringappend_82_) in
+ sep_matches_prefix _stringappend_83_ >>= fun w__90 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__90 with
+ | Some (_stringappend_84_,(existT _ _stringappend_85_ _)) =>
+ returnm ((_stringappend_84_, build_ex _stringappend_85_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__92 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_85_ _) :=
+ w__92
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_86_ :=
+ string_drop _stringappend_83_ (build_ex _stringappend_85_) in
+ match (hex_bits_12_matches_prefix _stringappend_86_) with
+ | Some (_stringappend_87_,(existT _ _stringappend_88_ _)) =>
+ returnm ((_stringappend_87_, build_ex _stringappend_88_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__94 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_88_ _) :=
+ w__94
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_86_ (build_ex _stringappend_88_)) with
+ | s_ =>
+ Some (ITYPE (imm,rs1,rd,op),
+ sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ match (shiftiop_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_90_,(existT _ _stringappend_91_ _)) =>
+ let _stringappend_92_ :=
+ string_drop _stringappend_0_ (build_ex _stringappend_91_) in
+ match (spc_matches_prefix _stringappend_92_) with
+ | Some (_stringappend_93_,(existT _ _stringappend_94_ _)) =>
+ let _stringappend_95_ :=
+ string_drop _stringappend_92_ (build_ex _stringappend_94_) in
+ match (reg_name_matches_prefix _stringappend_95_) with
+ | Some (_stringappend_96_,(existT _ _stringappend_97_ _)) =>
+ let _stringappend_98_ :=
+ string_drop _stringappend_95_ (build_ex _stringappend_97_) in
+ sep_matches_prefix _stringappend_98_ >>= fun w__95 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__95 with
+ | Some (_stringappend_99_,(existT _ _stringappend_100_ _)) =>
+ let _stringappend_101_ :=
+ string_drop _stringappend_98_
+ (build_ex
+ _stringappend_100_) in
+ if ((match (reg_name_matches_prefix _stringappend_101_) with
+ | Some
+ (_stringappend_102_,(existT _ _stringappend_103_ _)) =>
+ let _stringappend_104_ :=
+ string_drop _stringappend_101_
+ (build_ex
+ _stringappend_103_) in
+ if ((match (hex_bits_6_matches_prefix
+ _stringappend_104_) with
+ | Some
+ (_stringappend_105_,(existT _ _stringappend_106_ _)) =>
+ match (string_drop _stringappend_104_
+ (build_ex
+ _stringappend_106_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__96 : bool =>
+ returnm ((if (w__96) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__97 : bool =>
+ returnm ((if (w__97) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__98 : bool =>
+ (if (w__98) then
+ match (shiftiop_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_90_,(existT _ _stringappend_91_ _)) =>
+ returnm ((_stringappend_90_, build_ex _stringappend_91_)
+ : (sop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((sop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__100 : (sop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_91_ _) :=
+ w__100
+ : (sop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_92_ :=
+ string_drop _stringappend_0_ (build_ex _stringappend_91_) in
+ match (spc_matches_prefix _stringappend_92_) with
+ | Some (_stringappend_93_,(existT _ _stringappend_94_ _)) =>
+ returnm ((_stringappend_93_, build_ex _stringappend_94_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__102 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_94_ _) :=
+ w__102
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_95_ :=
+ string_drop _stringappend_92_ (build_ex _stringappend_94_) in
+ match (reg_name_matches_prefix _stringappend_95_) with
+ | Some (_stringappend_96_,(existT _ _stringappend_97_ _)) =>
+ returnm ((_stringappend_96_, build_ex _stringappend_97_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__104 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_97_ _) :=
+ w__104
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_98_ :=
+ string_drop _stringappend_95_ (build_ex _stringappend_97_) in
+ sep_matches_prefix _stringappend_98_ >>= fun w__105 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__105 with
+ | Some (_stringappend_99_,(existT _ _stringappend_100_ _)) =>
+ returnm ((_stringappend_99_, build_ex _stringappend_100_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__107 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_100_ _) :=
+ w__107
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_101_ :=
+ string_drop _stringappend_98_ (build_ex _stringappend_100_) in
+ match (reg_name_matches_prefix _stringappend_101_) with
+ | Some (_stringappend_102_,(existT _ _stringappend_103_ _)) =>
+ returnm ((_stringappend_102_, build_ex _stringappend_103_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__109 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_103_ _) :=
+ w__109
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_104_ :=
+ string_drop _stringappend_101_ (build_ex _stringappend_103_) in
+ match (hex_bits_6_matches_prefix _stringappend_104_) with
+ | Some (_stringappend_105_,(existT _ _stringappend_106_ _)) =>
+ returnm ((_stringappend_105_, build_ex _stringappend_106_)
+ : (mword 6 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 6 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__111 : (mword 6 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(shamt, existT _ _stringappend_106_ _) :=
+ w__111
+ : (mword 6 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_104_ (build_ex _stringappend_106_)) with
+ | s_ =>
+ Some (SHIFTIOP (shamt,rs1,rd,op),
+ sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ match (rtype_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_108_,(existT _ _stringappend_109_ _)) =>
+ let _stringappend_110_ :=
+ string_drop _stringappend_0_ (build_ex _stringappend_109_) in
+ match (spc_matches_prefix _stringappend_110_) with
+ | Some (_stringappend_111_,(existT _ _stringappend_112_ _)) =>
+ let _stringappend_113_ :=
+ string_drop _stringappend_110_ (build_ex _stringappend_112_) in
+ match (reg_name_matches_prefix _stringappend_113_) with
+ | Some (_stringappend_114_,(existT _ _stringappend_115_ _)) =>
+ let _stringappend_116_ :=
+ string_drop _stringappend_113_ (build_ex _stringappend_115_) in
+ sep_matches_prefix _stringappend_116_ >>= fun w__112 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__112 with
+ | Some (_stringappend_117_,(existT _ _stringappend_118_ _)) =>
+ let _stringappend_119_ :=
+ string_drop _stringappend_116_ (build_ex _stringappend_118_) in
+ match (reg_name_matches_prefix _stringappend_119_) with
+ | Some (_stringappend_120_,(existT _ _stringappend_121_ _)) =>
+ let _stringappend_122_ :=
+ string_drop _stringappend_119_ (build_ex _stringappend_121_) in
+ sep_matches_prefix _stringappend_122_ >>= fun w__113 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__113 with
+ | Some
+ (_stringappend_123_,(existT _ _stringappend_124_ _)) =>
+ let _stringappend_125_ :=
+ string_drop _stringappend_122_
+ (build_ex
+ _stringappend_124_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_125_) with
+ | Some
+ (_stringappend_126_,(existT _ _stringappend_127_ _)) =>
+ match (string_drop _stringappend_125_
+ (build_ex
+ _stringappend_127_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__114 : bool =>
+ returnm ((if (w__114) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__115 : bool =>
+ returnm ((if (w__115) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__116 : bool =>
+ returnm ((if (w__116) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__117 : bool =>
+ returnm ((if (w__117) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__118 : bool =>
+ (if (w__118) then
+ match (rtype_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_108_,(existT _ _stringappend_109_ _)) =>
+ returnm ((_stringappend_108_, build_ex _stringappend_109_)
+ : (rop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((rop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__120 : (rop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_109_ _) :=
+ w__120
+ : (rop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_110_ :=
+ string_drop _stringappend_0_ (build_ex _stringappend_109_) in
+ match (spc_matches_prefix _stringappend_110_) with
+ | Some (_stringappend_111_,(existT _ _stringappend_112_ _)) =>
+ returnm ((_stringappend_111_, build_ex _stringappend_112_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__122 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_112_ _) :=
+ w__122
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_113_ :=
+ string_drop _stringappend_110_ (build_ex _stringappend_112_) in
+ match (reg_name_matches_prefix _stringappend_113_) with
+ | Some (_stringappend_114_,(existT _ _stringappend_115_ _)) =>
+ returnm ((_stringappend_114_, build_ex _stringappend_115_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__124 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_115_ _) :=
+ w__124
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_116_ :=
+ string_drop _stringappend_113_ (build_ex _stringappend_115_) in
+ sep_matches_prefix _stringappend_116_ >>= fun w__125 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__125 with
+ | Some (_stringappend_117_,(existT _ _stringappend_118_ _)) =>
+ returnm ((_stringappend_117_, build_ex _stringappend_118_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__127 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_118_ _) :=
+ w__127
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_119_ :=
+ string_drop _stringappend_116_ (build_ex _stringappend_118_) in
+ match (reg_name_matches_prefix _stringappend_119_) with
+ | Some (_stringappend_120_,(existT _ _stringappend_121_ _)) =>
+ returnm ((_stringappend_120_, build_ex _stringappend_121_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__129 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_121_ _) :=
+ w__129
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_122_ :=
+ string_drop _stringappend_119_ (build_ex _stringappend_121_) in
+ sep_matches_prefix _stringappend_122_ >>= fun w__130 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__130 with
+ | Some (_stringappend_123_,(existT _ _stringappend_124_ _)) =>
+ returnm ((_stringappend_123_, build_ex _stringappend_124_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__132 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_124_ _) :=
+ w__132
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_125_ :=
+ string_drop _stringappend_122_ (build_ex _stringappend_124_) in
+ match (reg_name_matches_prefix _stringappend_125_) with
+ | Some (_stringappend_126_,(existT _ _stringappend_127_ _)) =>
+ returnm ((_stringappend_126_, build_ex _stringappend_127_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__134 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs2, existT _ _stringappend_127_ _) :=
+ w__134
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_125_
+ (build_ex
+ _stringappend_127_)) with
+ | s_ =>
+ Some (RTYPE (rs2,rs1,rd,op),
+ sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ and_boolM (returnm ((string_startswith _stringappend_0_ "l") : bool))
+ (let _stringappend_129_ :=
+ string_drop _stringappend_0_ (string_length "l") in
+ match (size_mnemonic_matches_prefix _stringappend_129_) with
+ | Some (_stringappend_130_,(existT _ _stringappend_131_ _)) =>
+ let _stringappend_132_ :=
+ string_drop _stringappend_129_ (build_ex _stringappend_131_) in
+ match (maybe_u_matches_prefix _stringappend_132_) with
+ | Some (_stringappend_133_,(existT _ _stringappend_134_ _)) =>
+ let _stringappend_135_ :=
+ string_drop _stringappend_132_ (build_ex _stringappend_134_) in
+ match (maybe_aq_matches_prefix _stringappend_135_) with
+ | Some (_stringappend_136_,(existT _ _stringappend_137_ _)) =>
+ let _stringappend_138_ :=
+ string_drop _stringappend_135_ (build_ex _stringappend_137_) in
+ match (maybe_rl_matches_prefix _stringappend_138_) with
+ | Some (_stringappend_139_,(existT _ _stringappend_140_ _)) =>
+ let _stringappend_141_ :=
+ string_drop _stringappend_138_ (build_ex _stringappend_140_) in
+ match (spc_matches_prefix _stringappend_141_) with
+ | Some (_stringappend_142_,(existT _ _stringappend_143_ _)) =>
+ let _stringappend_144_ :=
+ string_drop _stringappend_141_
+ (build_ex
+ _stringappend_143_) in
+ match (reg_name_matches_prefix _stringappend_144_) with
+ | Some (_stringappend_145_,(existT _ _stringappend_146_ _)) =>
+ let _stringappend_147_ :=
+ string_drop _stringappend_144_
+ (build_ex
+ _stringappend_146_) in
+ sep_matches_prefix _stringappend_147_ >>= fun w__135 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__135 with
+ | Some
+ (_stringappend_148_,(existT _ _stringappend_149_ _)) =>
+ let _stringappend_150_ :=
+ string_drop _stringappend_147_
+ (build_ex
+ _stringappend_149_) in
+ match (reg_name_matches_prefix _stringappend_150_) with
+ | Some
+ (_stringappend_151_,(existT _ _stringappend_152_ _)) =>
+ let _stringappend_153_ :=
+ string_drop _stringappend_150_
+ (build_ex
+ _stringappend_152_) in
+ sep_matches_prefix _stringappend_153_ >>= fun w__136 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__136 with
+ | Some
+ (_stringappend_154_,(existT _ _stringappend_155_ _)) =>
+ let _stringappend_156_ :=
+ string_drop _stringappend_153_
+ (build_ex
+ _stringappend_155_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_156_) with
+ | Some
+ (_stringappend_157_,(existT _ _stringappend_158_ _)) =>
+ match (string_drop
+ _stringappend_156_
+ (build_ex
+ _stringappend_158_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__137 : bool =>
+ returnm ((if (w__137) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__138 : bool =>
+ returnm ((if (w__138) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__139 : bool =>
+ returnm ((if (w__139) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__140 : bool =>
+ returnm ((if (w__140) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__141 : bool =>
+ returnm ((if (w__141) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__142 : bool =>
+ returnm ((if (w__142) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__143 : bool =>
+ returnm ((if (w__143) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__144 : bool =>
+ returnm ((if (w__144) then true
+ else false)
+ : bool)) >>= fun w__145 : bool =>
+ (if (w__145) then
+ let _stringappend_129_ :=
+ string_drop _stringappend_0_ (string_length "l") in
+ match (size_mnemonic_matches_prefix _stringappend_129_) with
+ | Some (_stringappend_130_,(existT _ _stringappend_131_ _)) =>
+ returnm ((_stringappend_130_, build_ex _stringappend_131_)
+ : (word_width * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((word_width * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__147 : (word_width * {n : Z & ArithFact (n >= 0)}) =>
+ let '(size, existT _ _stringappend_131_ _) :=
+ w__147
+ : (word_width * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_132_ :=
+ string_drop _stringappend_129_ (build_ex _stringappend_131_) in
+ match (maybe_u_matches_prefix _stringappend_132_) with
+ | Some (_stringappend_133_,(existT _ _stringappend_134_ _)) =>
+ returnm ((_stringappend_133_, build_ex _stringappend_134_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__149 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(is_unsigned, existT _ _stringappend_134_ _) :=
+ w__149
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_135_ :=
+ string_drop _stringappend_132_ (build_ex _stringappend_134_) in
+ match (maybe_aq_matches_prefix _stringappend_135_) with
+ | Some (_stringappend_136_,(existT _ _stringappend_137_ _)) =>
+ returnm ((_stringappend_136_, build_ex _stringappend_137_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__151 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(aq, existT _ _stringappend_137_ _) :=
+ w__151
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_138_ :=
+ string_drop _stringappend_135_ (build_ex _stringappend_137_) in
+ match (maybe_rl_matches_prefix _stringappend_138_) with
+ | Some (_stringappend_139_,(existT _ _stringappend_140_ _)) =>
+ returnm ((_stringappend_139_, build_ex _stringappend_140_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__153 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rl, existT _ _stringappend_140_ _) :=
+ w__153
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_141_ :=
+ string_drop _stringappend_138_ (build_ex _stringappend_140_) in
+ match (spc_matches_prefix _stringappend_141_) with
+ | Some (_stringappend_142_,(existT _ _stringappend_143_ _)) =>
+ returnm ((_stringappend_142_, build_ex _stringappend_143_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__155 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_143_ _) :=
+ w__155
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_144_ :=
+ string_drop _stringappend_141_ (build_ex _stringappend_143_) in
+ match (reg_name_matches_prefix _stringappend_144_) with
+ | Some (_stringappend_145_,(existT _ _stringappend_146_ _)) =>
+ returnm ((_stringappend_145_, build_ex _stringappend_146_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__157 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_146_ _) :=
+ w__157
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_147_ :=
+ string_drop _stringappend_144_ (build_ex _stringappend_146_) in
+ sep_matches_prefix _stringappend_147_ >>= fun w__158 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__158 with
+ | Some (_stringappend_148_,(existT _ _stringappend_149_ _)) =>
+ returnm ((_stringappend_148_, build_ex _stringappend_149_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__160 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_149_ _) :=
+ w__160
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_150_ :=
+ string_drop _stringappend_147_ (build_ex _stringappend_149_) in
+ match (reg_name_matches_prefix _stringappend_150_) with
+ | Some (_stringappend_151_,(existT _ _stringappend_152_ _)) =>
+ returnm ((_stringappend_151_, build_ex _stringappend_152_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__162 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_152_ _) :=
+ w__162
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_153_ :=
+ string_drop _stringappend_150_ (build_ex _stringappend_152_) in
+ sep_matches_prefix _stringappend_153_ >>= fun w__163 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__163 with
+ | Some (_stringappend_154_,(existT _ _stringappend_155_ _)) =>
+ returnm ((_stringappend_154_, build_ex _stringappend_155_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__165 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_155_ _) :=
+ w__165
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_156_ :=
+ string_drop _stringappend_153_ (build_ex _stringappend_155_) in
+ match (hex_bits_12_matches_prefix _stringappend_156_) with
+ | Some (_stringappend_157_,(existT _ _stringappend_158_ _)) =>
+ returnm ((_stringappend_157_, build_ex _stringappend_158_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__167 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_158_ _) :=
+ w__167
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_156_
+ (build_ex
+ _stringappend_158_)) with
+ | s_ =>
+ Some (LOAD (imm,rs1,rd,is_unsigned,size,aq,rl),
+ sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ and_boolM (returnm ((string_startswith _stringappend_0_ "s") : bool))
+ (let _stringappend_160_ :=
+ string_drop _stringappend_0_ (string_length "s") in
+ match (size_mnemonic_matches_prefix _stringappend_160_) with
+ | Some (_stringappend_161_,(existT _ _stringappend_162_ _)) =>
+ let _stringappend_163_ :=
+ string_drop _stringappend_160_ (build_ex _stringappend_162_) in
+ match (maybe_aq_matches_prefix _stringappend_163_) with
+ | Some (_stringappend_164_,(existT _ _stringappend_165_ _)) =>
+ let _stringappend_166_ :=
+ string_drop _stringappend_163_ (build_ex _stringappend_165_) in
+ match (maybe_rl_matches_prefix _stringappend_166_) with
+ | Some (_stringappend_167_,(existT _ _stringappend_168_ _)) =>
+ let _stringappend_169_ :=
+ string_drop _stringappend_166_ (build_ex _stringappend_168_) in
+ match (spc_matches_prefix _stringappend_169_) with
+ | Some (_stringappend_170_,(existT _ _stringappend_171_ _)) =>
+ let _stringappend_172_ :=
+ string_drop _stringappend_169_
+ (build_ex
+ _stringappend_171_) in
+ match (reg_name_matches_prefix _stringappend_172_) with
+ | Some (_stringappend_173_,(existT _ _stringappend_174_ _)) =>
+ let _stringappend_175_ :=
+ string_drop _stringappend_172_
+ (build_ex
+ _stringappend_174_) in
+ sep_matches_prefix _stringappend_175_ >>= fun w__168 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__168 with
+ | Some
+ (_stringappend_176_,(existT _ _stringappend_177_ _)) =>
+ let _stringappend_178_ :=
+ string_drop _stringappend_175_
+ (build_ex
+ _stringappend_177_) in
+ match (reg_name_matches_prefix _stringappend_178_) with
+ | Some
+ (_stringappend_179_,(existT _ _stringappend_180_ _)) =>
+ let _stringappend_181_ :=
+ string_drop _stringappend_178_
+ (build_ex
+ _stringappend_180_) in
+ sep_matches_prefix _stringappend_181_ >>= fun w__169 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__169 with
+ | Some
+ (_stringappend_182_,(existT _ _stringappend_183_ _)) =>
+ let _stringappend_184_ :=
+ string_drop _stringappend_181_
+ (build_ex
+ _stringappend_183_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_184_) with
+ | Some
+ (_stringappend_185_,(existT _ _stringappend_186_ _)) =>
+ match (string_drop
+ _stringappend_184_
+ (build_ex
+ _stringappend_186_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__170 : bool =>
+ returnm ((if (w__170) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__171 : bool =>
+ returnm ((if (w__171) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__172 : bool =>
+ returnm ((if (w__172) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__173 : bool =>
+ returnm ((if (w__173) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__174 : bool =>
+ returnm ((if (w__174) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__175 : bool =>
+ returnm ((if (w__175) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__176 : bool =>
+ returnm ((if (w__176) then true
+ else false)
+ : bool)) >>= fun w__177 : bool =>
+ (if (w__177) then
+ let _stringappend_160_ :=
+ string_drop _stringappend_0_ (string_length "s") in
+ match (size_mnemonic_matches_prefix _stringappend_160_) with
+ | Some (_stringappend_161_,(existT _ _stringappend_162_ _)) =>
+ returnm ((_stringappend_161_, build_ex _stringappend_162_)
+ : (word_width * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((word_width * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__179 : (word_width * {n : Z & ArithFact (n >= 0)}) =>
+ let '(size, existT _ _stringappend_162_ _) :=
+ w__179
+ : (word_width * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_163_ :=
+ string_drop _stringappend_160_ (build_ex _stringappend_162_) in
+ match (maybe_aq_matches_prefix _stringappend_163_) with
+ | Some (_stringappend_164_,(existT _ _stringappend_165_ _)) =>
+ returnm ((_stringappend_164_, build_ex _stringappend_165_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__181 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(aq, existT _ _stringappend_165_ _) :=
+ w__181
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_166_ :=
+ string_drop _stringappend_163_ (build_ex _stringappend_165_) in
+ match (maybe_rl_matches_prefix _stringappend_166_) with
+ | Some (_stringappend_167_,(existT _ _stringappend_168_ _)) =>
+ returnm ((_stringappend_167_, build_ex _stringappend_168_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__183 : (bool * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rl, existT _ _stringappend_168_ _) :=
+ w__183
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_169_ :=
+ string_drop _stringappend_166_ (build_ex _stringappend_168_) in
+ match (spc_matches_prefix _stringappend_169_) with
+ | Some (_stringappend_170_,(existT _ _stringappend_171_ _)) =>
+ returnm ((_stringappend_170_, build_ex _stringappend_171_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__185 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_171_ _) :=
+ w__185
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_172_ :=
+ string_drop _stringappend_169_ (build_ex _stringappend_171_) in
+ match (reg_name_matches_prefix _stringappend_172_) with
+ | Some (_stringappend_173_,(existT _ _stringappend_174_ _)) =>
+ returnm ((_stringappend_173_, build_ex _stringappend_174_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__187 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_174_ _) :=
+ w__187
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_175_ :=
+ string_drop _stringappend_172_ (build_ex _stringappend_174_) in
+ sep_matches_prefix _stringappend_175_ >>= fun w__188 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__188 with
+ | Some (_stringappend_176_,(existT _ _stringappend_177_ _)) =>
+ returnm ((_stringappend_176_, build_ex _stringappend_177_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__190 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_177_ _) :=
+ w__190
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_178_ :=
+ string_drop _stringappend_175_ (build_ex _stringappend_177_) in
+ match (reg_name_matches_prefix _stringappend_178_) with
+ | Some (_stringappend_179_,(existT _ _stringappend_180_ _)) =>
+ returnm ((_stringappend_179_, build_ex _stringappend_180_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__192 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_180_ _) :=
+ w__192
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_181_ :=
+ string_drop _stringappend_178_ (build_ex _stringappend_180_) in
+ sep_matches_prefix _stringappend_181_ >>= fun w__193 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__193 with
+ | Some (_stringappend_182_,(existT _ _stringappend_183_ _)) =>
+ returnm ((_stringappend_182_, build_ex _stringappend_183_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__195 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_183_ _) :=
+ w__195
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_184_ :=
+ string_drop _stringappend_181_ (build_ex _stringappend_183_) in
+ match (hex_bits_12_matches_prefix _stringappend_184_) with
+ | Some (_stringappend_185_,(existT _ _stringappend_186_ _)) =>
+ returnm ((_stringappend_185_, build_ex _stringappend_186_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__197 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_186_ _) :=
+ w__197
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_184_
+ (build_ex
+ _stringappend_186_)) with
+ | s_ =>
+ Some (STORE (imm,rs1,rd,size,aq,rl),
+ sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_0_ "addiw")
+ : bool))
+ (let _stringappend_188_ :=
+ string_drop _stringappend_0_ (string_length "addiw") in
+ match (spc_matches_prefix _stringappend_188_) with
+ | Some (_stringappend_189_,(existT _ _stringappend_190_ _)) =>
+ let _stringappend_191_ :=
+ string_drop _stringappend_188_ (build_ex _stringappend_190_) in
+ match (reg_name_matches_prefix _stringappend_191_) with
+ | Some (_stringappend_192_,(existT _ _stringappend_193_ _)) =>
+ let _stringappend_194_ :=
+ string_drop _stringappend_191_ (build_ex _stringappend_193_) in
+ sep_matches_prefix _stringappend_194_ >>= fun w__198 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__198 with
+ | Some (_stringappend_195_,(existT _ _stringappend_196_ _)) =>
+ let _stringappend_197_ :=
+ string_drop _stringappend_194_
+ (build_ex
+ _stringappend_196_) in
+ match (reg_name_matches_prefix _stringappend_197_) with
+ | Some (_stringappend_198_,(existT _ _stringappend_199_ _)) =>
+ let _stringappend_200_ :=
+ string_drop _stringappend_197_
+ (build_ex
+ _stringappend_199_) in
+ sep_matches_prefix _stringappend_200_ >>= fun w__199 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__199 with
+ | Some
+ (_stringappend_201_,(existT _ _stringappend_202_ _)) =>
+ let _stringappend_203_ :=
+ string_drop _stringappend_200_
+ (build_ex
+ _stringappend_202_) in
+ if ((match (hex_bits_12_matches_prefix
+ _stringappend_203_) with
+ | Some
+ (_stringappend_204_,(existT _ _stringappend_205_ _)) =>
+ match (string_drop
+ _stringappend_203_
+ (build_ex
+ _stringappend_205_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__200 : bool =>
+ returnm ((if (w__200) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__201 : bool =>
+ returnm ((if (w__201) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__202 : bool =>
+ returnm ((if (w__202) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__203 : bool =>
+ returnm ((if (w__203) then true
+ else false)
+ : bool)) >>= fun w__204 : bool =>
+ (if (w__204) then
+ let _stringappend_188_ :=
+ string_drop _stringappend_0_ (string_length "addiw") in
+ match (spc_matches_prefix _stringappend_188_) with
+ | Some (_stringappend_189_,(existT _ _stringappend_190_ _)) =>
+ returnm ((_stringappend_189_, build_ex _stringappend_190_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__206 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_190_ _) :=
+ w__206
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_191_ :=
+ string_drop _stringappend_188_ (build_ex _stringappend_190_) in
+ match (reg_name_matches_prefix _stringappend_191_) with
+ | Some (_stringappend_192_,(existT _ _stringappend_193_ _)) =>
+ returnm ((_stringappend_192_, build_ex _stringappend_193_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__208 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_193_ _) :=
+ w__208
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_194_ :=
+ string_drop _stringappend_191_ (build_ex _stringappend_193_) in
+ sep_matches_prefix _stringappend_194_ >>= fun w__209 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__209 with
+ | Some (_stringappend_195_,(existT _ _stringappend_196_ _)) =>
+ returnm ((_stringappend_195_, build_ex _stringappend_196_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__211 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_196_ _) :=
+ w__211
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_197_ :=
+ string_drop _stringappend_194_ (build_ex _stringappend_196_) in
+ match (reg_name_matches_prefix _stringappend_197_) with
+ | Some (_stringappend_198_,(existT _ _stringappend_199_ _)) =>
+ returnm ((_stringappend_198_, build_ex _stringappend_199_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__213 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_199_ _) :=
+ w__213
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_200_ :=
+ string_drop _stringappend_197_ (build_ex _stringappend_199_) in
+ sep_matches_prefix _stringappend_200_ >>= fun w__214 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__214 with
+ | Some (_stringappend_201_,(existT _ _stringappend_202_ _)) =>
+ returnm ((_stringappend_201_, build_ex _stringappend_202_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__216 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_202_ _) :=
+ w__216
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_203_ :=
+ string_drop _stringappend_200_ (build_ex _stringappend_202_) in
+ match (hex_bits_12_matches_prefix _stringappend_203_) with
+ | Some (_stringappend_204_,(existT _ _stringappend_205_ _)) =>
+ returnm ((_stringappend_204_, build_ex _stringappend_205_)
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 12 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__218 : (mword 12 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(imm, existT _ _stringappend_205_ _) :=
+ w__218
+ : (mword 12 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_203_
+ (build_ex
+ _stringappend_205_)) with
+ | s_ =>
+ Some (ADDIW (imm,rs1,rd),
+ sub_nat (string_length arg_) (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ match (shiftw_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_207_,(existT _ _stringappend_208_ _)) =>
+ let _stringappend_209_ :=
+ string_drop _stringappend_0_ (build_ex _stringappend_208_) in
+ match (spc_matches_prefix _stringappend_209_) with
+ | Some (_stringappend_210_,(existT _ _stringappend_211_ _)) =>
+ let _stringappend_212_ :=
+ string_drop _stringappend_209_
+ (build_ex
+ _stringappend_211_) in
+ match (reg_name_matches_prefix _stringappend_212_) with
+ | Some (_stringappend_213_,(existT _ _stringappend_214_ _)) =>
+ let _stringappend_215_ :=
+ string_drop _stringappend_212_
+ (build_ex
+ _stringappend_214_) in
+ sep_matches_prefix _stringappend_215_ >>= fun w__219 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__219 with
+ | Some
+ (_stringappend_216_,(existT _ _stringappend_217_ _)) =>
+ let _stringappend_218_ :=
+ string_drop _stringappend_215_
+ (build_ex
+ _stringappend_217_) in
+ match (reg_name_matches_prefix _stringappend_218_) with
+ | Some
+ (_stringappend_219_,(existT _ _stringappend_220_ _)) =>
+ let _stringappend_221_ :=
+ string_drop _stringappend_218_
+ (build_ex
+ _stringappend_220_) in
+ sep_matches_prefix _stringappend_221_ >>= fun w__220 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__220 with
+ | Some
+ (_stringappend_222_,(existT _ _stringappend_223_ _)) =>
+ let _stringappend_224_ :=
+ string_drop _stringappend_221_
+ (build_ex
+ _stringappend_223_) in
+ if ((match (hex_bits_5_matches_prefix
+ _stringappend_224_) with
+ | Some
+ (_stringappend_225_,(existT _ _stringappend_226_ _)) =>
+ match (string_drop
+ _stringappend_224_
+ (build_ex
+ _stringappend_226_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__221 : bool =>
+ returnm ((if (w__221) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__222 : bool =>
+ returnm ((if (w__222) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__223 : bool =>
+ returnm ((if (w__223) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__224 : bool =>
+ returnm ((if (w__224) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__225 : bool =>
+ (if (w__225) then
+ match (shiftw_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_207_,(existT _ _stringappend_208_ _)) =>
+ returnm ((_stringappend_207_, build_ex _stringappend_208_)
+ : (sop * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((sop * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__227 : (sop * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_208_ _) :=
+ w__227
+ : (sop * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_209_ :=
+ string_drop _stringappend_0_ (build_ex _stringappend_208_) in
+ match (spc_matches_prefix _stringappend_209_) with
+ | Some (_stringappend_210_,(existT _ _stringappend_211_ _)) =>
+ returnm ((_stringappend_210_, build_ex _stringappend_211_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__229 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_211_ _) :=
+ w__229
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_212_ :=
+ string_drop _stringappend_209_ (build_ex _stringappend_211_) in
+ match (reg_name_matches_prefix _stringappend_212_) with
+ | Some (_stringappend_213_,(existT _ _stringappend_214_ _)) =>
+ returnm ((_stringappend_213_, build_ex _stringappend_214_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__231 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_214_ _) :=
+ w__231
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_215_ :=
+ string_drop _stringappend_212_ (build_ex _stringappend_214_) in
+ sep_matches_prefix _stringappend_215_ >>= fun w__232 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__232 with
+ | Some (_stringappend_216_,(existT _ _stringappend_217_ _)) =>
+ returnm ((_stringappend_216_, build_ex _stringappend_217_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__234 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_217_ _) :=
+ w__234
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_218_ :=
+ string_drop _stringappend_215_ (build_ex _stringappend_217_) in
+ match (reg_name_matches_prefix _stringappend_218_) with
+ | Some (_stringappend_219_,(existT _ _stringappend_220_ _)) =>
+ returnm ((_stringappend_219_, build_ex _stringappend_220_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__236 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_220_ _) :=
+ w__236
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_221_ :=
+ string_drop _stringappend_218_ (build_ex _stringappend_220_) in
+ sep_matches_prefix _stringappend_221_ >>= fun w__237 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__237 with
+ | Some (_stringappend_222_,(existT _ _stringappend_223_ _)) =>
+ returnm ((_stringappend_222_, build_ex _stringappend_223_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__239 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_223_ _) :=
+ w__239
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_224_ :=
+ string_drop _stringappend_221_ (build_ex _stringappend_223_) in
+ match (hex_bits_5_matches_prefix _stringappend_224_) with
+ | Some (_stringappend_225_,(existT _ _stringappend_226_ _)) =>
+ returnm ((_stringappend_225_, build_ex _stringappend_226_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__241 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(shamt, existT _ _stringappend_226_ _) :=
+ w__241
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_224_
+ (build_ex
+ _stringappend_226_)) with
+ | s_ =>
+ Some (SHIFTW (shamt,rs1,rd,op),
+ sub_nat (string_length arg_)
+ (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ match (rtypew_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_228_,(existT _ _stringappend_229_ _)) =>
+ let _stringappend_230_ :=
+ string_drop _stringappend_0_ (build_ex _stringappend_229_) in
+ match (spc_matches_prefix _stringappend_230_) with
+ | Some (_stringappend_231_,(existT _ _stringappend_232_ _)) =>
+ let _stringappend_233_ :=
+ string_drop _stringappend_230_
+ (build_ex
+ _stringappend_232_) in
+ match (reg_name_matches_prefix _stringappend_233_) with
+ | Some
+ (_stringappend_234_,(existT _ _stringappend_235_ _)) =>
+ let _stringappend_236_ :=
+ string_drop _stringappend_233_
+ (build_ex
+ _stringappend_235_) in
+ sep_matches_prefix _stringappend_236_ >>= fun w__242 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__242 with
+ | Some
+ (_stringappend_237_,(existT _ _stringappend_238_ _)) =>
+ let _stringappend_239_ :=
+ string_drop _stringappend_236_
+ (build_ex
+ _stringappend_238_) in
+ match (reg_name_matches_prefix _stringappend_239_) with
+ | Some
+ (_stringappend_240_,(existT _ _stringappend_241_ _)) =>
+ let _stringappend_242_ :=
+ string_drop _stringappend_239_
+ (build_ex
+ _stringappend_241_) in
+ sep_matches_prefix _stringappend_242_ >>= fun w__243 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__243 with
+ | Some
+ (_stringappend_243_,(existT _ _stringappend_244_ _)) =>
+ let _stringappend_245_ :=
+ string_drop
+ _stringappend_242_
+ (build_ex
+ _stringappend_244_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_245_) with
+ | Some
+ (_stringappend_246_,(existT _ _stringappend_247_ _)) =>
+ match (string_drop
+ _stringappend_245_
+ (build_ex
+ _stringappend_247_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__244 : bool =>
+ returnm ((if (w__244) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__245 : bool =>
+ returnm ((if (w__245) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__246 : bool =>
+ returnm ((if (w__246) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__247 : bool =>
+ returnm ((if (w__247) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__248 : bool =>
+ (if (w__248) then
+ match (rtypew_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_228_,(existT _ _stringappend_229_ _)) =>
+ returnm ((_stringappend_228_, build_ex _stringappend_229_)
+ : (ropw * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((ropw * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__250 : (ropw * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_229_ _) :=
+ w__250
+ : (ropw * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_230_ :=
+ string_drop _stringappend_0_ (build_ex _stringappend_229_) in
+ match (spc_matches_prefix _stringappend_230_) with
+ | Some (_stringappend_231_,(existT _ _stringappend_232_ _)) =>
+ returnm ((_stringappend_231_, build_ex _stringappend_232_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__252 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_232_ _) :=
+ w__252
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_233_ :=
+ string_drop _stringappend_230_
+ (build_ex
+ _stringappend_232_) in
+ match (reg_name_matches_prefix _stringappend_233_) with
+ | Some (_stringappend_234_,(existT _ _stringappend_235_ _)) =>
+ returnm ((_stringappend_234_, build_ex _stringappend_235_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__254 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_235_ _) :=
+ w__254
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_236_ :=
+ string_drop _stringappend_233_
+ (build_ex
+ _stringappend_235_) in
+ sep_matches_prefix _stringappend_236_ >>= fun w__255 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__255 with
+ | Some (_stringappend_237_,(existT _ _stringappend_238_ _)) =>
+ returnm ((_stringappend_237_, build_ex _stringappend_238_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__257 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_238_ _) :=
+ w__257
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_239_ :=
+ string_drop _stringappend_236_
+ (build_ex
+ _stringappend_238_) in
+ match (reg_name_matches_prefix _stringappend_239_) with
+ | Some (_stringappend_240_,(existT _ _stringappend_241_ _)) =>
+ returnm ((_stringappend_240_, build_ex _stringappend_241_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__259 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_241_ _) :=
+ w__259
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_242_ :=
+ string_drop _stringappend_239_
+ (build_ex
+ _stringappend_241_) in
+ sep_matches_prefix _stringappend_242_ >>= fun w__260 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__260 with
+ | Some (_stringappend_243_,(existT _ _stringappend_244_ _)) =>
+ returnm ((_stringappend_243_, build_ex _stringappend_244_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ => exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__262 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_244_ _) :=
+ w__262
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_245_ :=
+ string_drop _stringappend_242_
+ (build_ex
+ _stringappend_244_) in
+ match (reg_name_matches_prefix _stringappend_245_) with
+ | Some (_stringappend_246_,(existT _ _stringappend_247_ _)) =>
+ returnm ((_stringappend_246_, build_ex _stringappend_247_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__264 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs2, existT _ _stringappend_247_ _) :=
+ w__264
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_245_
+ (build_ex
+ _stringappend_247_)) with
+ | s_ =>
+ Some (RTYPEW (rs2,rs1,rd,op),
+ sub_nat (string_length arg_)
+ (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ match (shiftiwop_mnemonic_matches_prefix _stringappend_0_) with
+ | Some (_stringappend_249_,(existT _ _stringappend_250_ _)) =>
+ let _stringappend_251_ :=
+ string_drop _stringappend_0_
+ (build_ex
+ _stringappend_250_) in
+ match (spc_matches_prefix _stringappend_251_) with
+ | Some
+ (_stringappend_252_,(existT _ _stringappend_253_ _)) =>
+ let _stringappend_254_ :=
+ string_drop _stringappend_251_
+ (build_ex
+ _stringappend_253_) in
+ match (reg_name_matches_prefix _stringappend_254_) with
+ | Some
+ (_stringappend_255_,(existT _ _stringappend_256_ _)) =>
+ let _stringappend_257_ :=
+ string_drop _stringappend_254_
+ (build_ex
+ _stringappend_256_) in
+ sep_matches_prefix _stringappend_257_ >>= fun w__265 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__265 with
+ | Some
+ (_stringappend_258_,(existT _ _stringappend_259_ _)) =>
+ let _stringappend_260_ :=
+ string_drop _stringappend_257_
+ (build_ex
+ _stringappend_259_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_260_) with
+ | Some
+ (_stringappend_261_,(existT _ _stringappend_262_ _)) =>
+ let _stringappend_263_ :=
+ string_drop
+ _stringappend_260_
+ (build_ex
+ _stringappend_262_) in
+ if ((match (hex_bits_5_matches_prefix
+ _stringappend_263_) with
+ | Some
+ (_stringappend_264_,(existT _ _stringappend_265_ _)) =>
+ match (string_drop
+ _stringappend_263_
+ (build_ex
+ _stringappend_265_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__266 : bool =>
+ returnm ((if (w__266) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__267 : bool =>
+ returnm ((if (w__267) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__268 : bool =>
+ (if (w__268) then
+ match (shiftiwop_mnemonic_matches_prefix _stringappend_0_) with
+ | Some
+ (_stringappend_249_,(existT _ _stringappend_250_ _)) =>
+ returnm ((_stringappend_249_,
+ build_ex
+ _stringappend_250_)
+ : (sopw * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((sopw * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__270 : (sopw * {n : Z & ArithFact (n >= 0)}) =>
+ let '(op, existT _ _stringappend_250_ _) :=
+ w__270
+ : (sopw * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_251_ :=
+ string_drop _stringappend_0_
+ (build_ex
+ _stringappend_250_) in
+ match (spc_matches_prefix _stringappend_251_) with
+ | Some
+ (_stringappend_252_,(existT _ _stringappend_253_ _)) =>
+ returnm ((_stringappend_252_,
+ build_ex
+ _stringappend_253_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__272 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_253_ _) :=
+ w__272
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_254_ :=
+ string_drop _stringappend_251_
+ (build_ex
+ _stringappend_253_) in
+ match (reg_name_matches_prefix _stringappend_254_) with
+ | Some
+ (_stringappend_255_,(existT _ _stringappend_256_ _)) =>
+ returnm ((_stringappend_255_,
+ build_ex
+ _stringappend_256_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__274 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rd, existT _ _stringappend_256_ _) :=
+ w__274
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_257_ :=
+ string_drop _stringappend_254_
+ (build_ex
+ _stringappend_256_) in
+ sep_matches_prefix _stringappend_257_ >>= fun w__275 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__275 with
+ | Some
+ (_stringappend_258_,(existT _ _stringappend_259_ _)) =>
+ returnm ((_stringappend_258_,
+ build_ex
+ _stringappend_259_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__277 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_259_ _) :=
+ w__277
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_260_ :=
+ string_drop _stringappend_257_
+ (build_ex
+ _stringappend_259_) in
+ match (reg_name_matches_prefix _stringappend_260_) with
+ | Some
+ (_stringappend_261_,(existT _ _stringappend_262_ _)) =>
+ returnm ((_stringappend_261_,
+ build_ex
+ _stringappend_262_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__279 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(rs1, existT _ _stringappend_262_ _) :=
+ w__279
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_263_ :=
+ string_drop _stringappend_260_
+ (build_ex
+ _stringappend_262_) in
+ match (hex_bits_5_matches_prefix _stringappend_263_) with
+ | Some
+ (_stringappend_264_,(existT _ _stringappend_265_ _)) =>
+ returnm ((_stringappend_264_,
+ build_ex
+ _stringappend_265_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__281 : (mword 5 * {n : Z & ArithFact (n >= 0)}) =>
+ let '(shamt, existT _ _stringappend_265_ _) :=
+ w__281
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_263_
+ (build_ex
+ _stringappend_265_)) with
+ | s_ =>
+ Some (SHIFTIWOP (shamt,rs1,rd,op),
+ sub_nat (string_length arg_)
+ (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ match (mul_mnemonic_matches_prefix _stringappend_0_) with
+ | Some
+ (_stringappend_267_,(existT _ _stringappend_268_ _)) =>
+ let _stringappend_269_ :=
+ string_drop _stringappend_0_
+ (build_ex
+ _stringappend_268_) in
+ match (spc_matches_prefix _stringappend_269_) with
+ | Some
+ (_stringappend_270_,(existT _ _stringappend_271_ _)) =>
+ let _stringappend_272_ :=
+ string_drop _stringappend_269_
+ (build_ex
+ _stringappend_271_) in
+ match (reg_name_matches_prefix _stringappend_272_) with
+ | Some
+ (_stringappend_273_,(existT _ _stringappend_274_ _)) =>
+ let _stringappend_275_ :=
+ string_drop _stringappend_272_
+ (build_ex
+ _stringappend_274_) in
+ sep_matches_prefix _stringappend_275_ >>= fun w__282 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__282 with
+ | Some
+ (_stringappend_276_,(existT _ _stringappend_277_ _)) =>
+ let _stringappend_278_ :=
+ string_drop _stringappend_275_
+ (build_ex
+ _stringappend_277_) in
+ match (reg_name_matches_prefix
+ _stringappend_278_) with
+ | Some
+ (_stringappend_279_,(existT _ _stringappend_280_ _)) =>
+ let _stringappend_281_ :=
+ string_drop _stringappend_278_
+ (build_ex
+ _stringappend_280_) in
+ sep_matches_prefix _stringappend_281_ >>= fun w__283 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__283 with
+ | Some
+ (_stringappend_282_,(existT _ _stringappend_283_ _)) =>
+ let _stringappend_284_ :=
+ string_drop
+ _stringappend_281_
+ (build_ex
+ _stringappend_283_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_284_) with
+ | Some
+ (_stringappend_285_,(existT _ _stringappend_286_ _)) =>
+ match (string_drop
+ _stringappend_284_
+ (build_ex
+ _stringappend_286_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__284 : bool =>
+ returnm ((if (w__284) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__285 : bool =>
+ returnm ((if (w__285) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__286 : bool =>
+ returnm ((if (w__286) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__287 : bool =>
+ returnm ((if (w__287) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__288 : bool =>
+ (if (w__288) then
+ match (mul_mnemonic_matches_prefix _stringappend_0_) with
+ | Some
+ (_stringappend_267_,(existT _ _stringappend_268_ _)) =>
+ returnm ((_stringappend_267_,
+ build_ex
+ _stringappend_268_)
+ : ((bool * bool * bool) * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M (((bool * bool * bool) * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__290 : ((bool * bool * bool) * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '((high, signed1, signed2), existT _ _stringappend_268_ _) :=
+ w__290
+ : ((bool * bool * bool) * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_269_ :=
+ string_drop _stringappend_0_
+ (build_ex
+ _stringappend_268_) in
+ match (spc_matches_prefix _stringappend_269_) with
+ | Some
+ (_stringappend_270_,(existT _ _stringappend_271_ _)) =>
+ returnm ((_stringappend_270_,
+ build_ex
+ _stringappend_271_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__292 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_271_ _) :=
+ w__292
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_272_ :=
+ string_drop _stringappend_269_
+ (build_ex
+ _stringappend_271_) in
+ match (reg_name_matches_prefix _stringappend_272_) with
+ | Some
+ (_stringappend_273_,(existT _ _stringappend_274_ _)) =>
+ returnm ((_stringappend_273_,
+ build_ex
+ _stringappend_274_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__294 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_274_ _) :=
+ w__294
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_275_ :=
+ string_drop _stringappend_272_
+ (build_ex
+ _stringappend_274_) in
+ sep_matches_prefix _stringappend_275_ >>= fun w__295 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__295 with
+ | Some
+ (_stringappend_276_,(existT _ _stringappend_277_ _)) =>
+ returnm ((_stringappend_276_,
+ build_ex
+ _stringappend_277_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__297 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_277_ _) :=
+ w__297
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_278_ :=
+ string_drop _stringappend_275_
+ (build_ex
+ _stringappend_277_) in
+ match (reg_name_matches_prefix _stringappend_278_) with
+ | Some
+ (_stringappend_279_,(existT _ _stringappend_280_ _)) =>
+ returnm ((_stringappend_279_,
+ build_ex
+ _stringappend_280_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__299 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_280_ _) :=
+ w__299
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_281_ :=
+ string_drop _stringappend_278_
+ (build_ex
+ _stringappend_280_) in
+ sep_matches_prefix _stringappend_281_ >>= fun w__300 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__300 with
+ | Some
+ (_stringappend_282_,(existT _ _stringappend_283_ _)) =>
+ returnm ((_stringappend_282_,
+ build_ex
+ _stringappend_283_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__302 : (unit * {n : Z & ArithFact (n >= 0)}) =>
+ let '(tt, existT _ _stringappend_283_ _) :=
+ w__302
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_284_ :=
+ string_drop _stringappend_281_
+ (build_ex
+ _stringappend_283_) in
+ match (reg_name_matches_prefix _stringappend_284_) with
+ | Some
+ (_stringappend_285_,(existT _ _stringappend_286_ _)) =>
+ returnm ((_stringappend_285_,
+ build_ex
+ _stringappend_286_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__304 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_286_ _) :=
+ w__304
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_284_
+ (build_ex
+ _stringappend_286_)) with
+ | s_ =>
+ Some (MUL (rs2,rs1,rd,high,signed1,signed2),
+ sub_nat (string_length arg_)
+ (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_0_ "div")
+ : bool))
+ (let _stringappend_288_ :=
+ string_drop _stringappend_0_ (string_length "div") in
+ match (maybe_not_u_matches_prefix _stringappend_288_) with
+ | Some
+ (_stringappend_289_,(existT _ _stringappend_290_ _)) =>
+ let _stringappend_291_ :=
+ string_drop _stringappend_288_
+ (build_ex
+ _stringappend_290_) in
+ match (spc_matches_prefix _stringappend_291_) with
+ | Some
+ (_stringappend_292_,(existT _ _stringappend_293_ _)) =>
+ let _stringappend_294_ :=
+ string_drop _stringappend_291_
+ (build_ex
+ _stringappend_293_) in
+ match (reg_name_matches_prefix
+ _stringappend_294_) with
+ | Some
+ (_stringappend_295_,(existT _ _stringappend_296_ _)) =>
+ let _stringappend_297_ :=
+ string_drop _stringappend_294_
+ (build_ex
+ _stringappend_296_) in
+ sep_matches_prefix _stringappend_297_ >>= fun w__305 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__305 with
+ | Some
+ (_stringappend_298_,(existT _ _stringappend_299_ _)) =>
+ let _stringappend_300_ :=
+ string_drop _stringappend_297_
+ (build_ex
+ _stringappend_299_) in
+ match (reg_name_matches_prefix
+ _stringappend_300_) with
+ | Some
+ (_stringappend_301_,(existT _ _stringappend_302_ _)) =>
+ let _stringappend_303_ :=
+ string_drop _stringappend_300_
+ (build_ex
+ _stringappend_302_) in
+ sep_matches_prefix _stringappend_303_ >>= fun w__306 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__306 with
+ | Some
+ (_stringappend_304_,(existT _ _stringappend_305_ _)) =>
+ let _stringappend_306_ :=
+ string_drop
+ _stringappend_303_
+ (build_ex
+ _stringappend_305_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_306_) with
+ | Some
+ (_stringappend_307_,(existT _ _stringappend_308_ _)) =>
+ match (string_drop
+ _stringappend_306_
+ (build_ex
+ _stringappend_308_)) with
+ | s_ => true
+ end
+ | None => false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__307 : bool =>
+ returnm ((if (w__307) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__308 : bool =>
+ returnm ((if (w__308) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__309 : bool =>
+ returnm ((if (w__309) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__310 : bool =>
+ returnm ((if (w__310) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__311 : bool =>
+ returnm ((if (w__311) then true
+ else false)
+ : bool)) >>= fun w__312 : bool =>
+ (if (w__312) then
+ let _stringappend_288_ :=
+ string_drop _stringappend_0_ (string_length "div") in
+ match (maybe_not_u_matches_prefix _stringappend_288_) with
+ | Some
+ (_stringappend_289_,(existT _ _stringappend_290_ _)) =>
+ returnm ((_stringappend_289_,
+ build_ex
+ _stringappend_290_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__314 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_290_ _) :=
+ w__314
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_291_ :=
+ string_drop _stringappend_288_
+ (build_ex
+ _stringappend_290_) in
+ match (spc_matches_prefix _stringappend_291_) with
+ | Some
+ (_stringappend_292_,(existT _ _stringappend_293_ _)) =>
+ returnm ((_stringappend_292_,
+ build_ex
+ _stringappend_293_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__316 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_293_ _) :=
+ w__316
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_294_ :=
+ string_drop _stringappend_291_
+ (build_ex
+ _stringappend_293_) in
+ match (reg_name_matches_prefix _stringappend_294_) with
+ | Some
+ (_stringappend_295_,(existT _ _stringappend_296_ _)) =>
+ returnm ((_stringappend_295_,
+ build_ex
+ _stringappend_296_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__318 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_296_ _) :=
+ w__318
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_297_ :=
+ string_drop _stringappend_294_
+ (build_ex
+ _stringappend_296_) in
+ sep_matches_prefix _stringappend_297_ >>= fun w__319 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__319 with
+ | Some
+ (_stringappend_298_,(existT _ _stringappend_299_ _)) =>
+ returnm ((_stringappend_298_,
+ build_ex
+ _stringappend_299_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__321 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_299_ _) :=
+ w__321
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_300_ :=
+ string_drop _stringappend_297_
+ (build_ex
+ _stringappend_299_) in
+ match (reg_name_matches_prefix _stringappend_300_) with
+ | Some
+ (_stringappend_301_,(existT _ _stringappend_302_ _)) =>
+ returnm ((_stringappend_301_,
+ build_ex
+ _stringappend_302_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__323 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_302_ _) :=
+ w__323
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_303_ :=
+ string_drop _stringappend_300_
+ (build_ex
+ _stringappend_302_) in
+ sep_matches_prefix _stringappend_303_ >>= fun w__324 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__324 with
+ | Some
+ (_stringappend_304_,(existT _ _stringappend_305_ _)) =>
+ returnm ((_stringappend_304_,
+ build_ex
+ _stringappend_305_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__326 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_305_ _) :=
+ w__326
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_306_ :=
+ string_drop _stringappend_303_
+ (build_ex
+ _stringappend_305_) in
+ match (reg_name_matches_prefix _stringappend_306_) with
+ | Some
+ (_stringappend_307_,(existT _ _stringappend_308_ _)) =>
+ returnm ((_stringappend_307_,
+ build_ex
+ _stringappend_308_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__328 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_308_ _) :=
+ w__328
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_306_
+ (build_ex
+ _stringappend_308_)) with
+ | s_ =>
+ Some (DIV (rs2,rs1,rd,s),
+ sub_nat (string_length arg_)
+ (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_0_
+ "rem")
+ : bool))
+ (let _stringappend_310_ :=
+ string_drop _stringappend_0_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_310_) with
+ | Some
+ (_stringappend_311_,(existT _ _stringappend_312_ _)) =>
+ let _stringappend_313_ :=
+ string_drop _stringappend_310_
+ (build_ex
+ _stringappend_312_) in
+ match (spc_matches_prefix _stringappend_313_) with
+ | Some
+ (_stringappend_314_,(existT _ _stringappend_315_ _)) =>
+ let _stringappend_316_ :=
+ string_drop _stringappend_313_
+ (build_ex
+ _stringappend_315_) in
+ match (reg_name_matches_prefix
+ _stringappend_316_) with
+ | Some
+ (_stringappend_317_,(existT _ _stringappend_318_ _)) =>
+ let _stringappend_319_ :=
+ string_drop _stringappend_316_
+ (build_ex
+ _stringappend_318_) in
+ sep_matches_prefix _stringappend_319_ >>= fun w__329 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__329 with
+ | Some
+ (_stringappend_320_,(existT _ _stringappend_321_ _)) =>
+ let _stringappend_322_ :=
+ string_drop _stringappend_319_
+ (build_ex
+ _stringappend_321_) in
+ match (reg_name_matches_prefix
+ _stringappend_322_) with
+ | Some
+ (_stringappend_323_,(existT _ _stringappend_324_ _)) =>
+ let _stringappend_325_ :=
+ string_drop _stringappend_322_
+ (build_ex
+ _stringappend_324_) in
+ sep_matches_prefix
+ _stringappend_325_ >>= fun w__330 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__330 with
+ | Some
+ (_stringappend_326_,(existT _ _stringappend_327_ _)) =>
+ let _stringappend_328_ :=
+ string_drop
+ _stringappend_325_
+ (build_ex
+ _stringappend_327_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_328_) with
+ | Some
+ (_stringappend_329_,(existT _ _stringappend_330_ _)) =>
+ match (string_drop
+ _stringappend_328_
+ (build_ex
+ _stringappend_330_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__331 : bool =>
+ returnm ((if (w__331) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__332 : bool =>
+ returnm ((if (w__332) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__333 : bool =>
+ returnm ((if (w__333) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__334 : bool =>
+ returnm ((if (w__334) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__335 : bool =>
+ returnm ((if (w__335) then true
+ else false)
+ : bool)) >>= fun w__336 : bool =>
+ (if (w__336) then
+ let _stringappend_310_ :=
+ string_drop _stringappend_0_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_310_) with
+ | Some
+ (_stringappend_311_,(existT _ _stringappend_312_ _)) =>
+ returnm ((_stringappend_311_,
+ build_ex
+ _stringappend_312_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__338 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_312_ _) :=
+ w__338
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_313_ :=
+ string_drop _stringappend_310_
+ (build_ex
+ _stringappend_312_) in
+ match (spc_matches_prefix _stringappend_313_) with
+ | Some
+ (_stringappend_314_,(existT _ _stringappend_315_ _)) =>
+ returnm ((_stringappend_314_,
+ build_ex
+ _stringappend_315_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__340 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_315_ _) :=
+ w__340
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_316_ :=
+ string_drop _stringappend_313_
+ (build_ex
+ _stringappend_315_) in
+ match (reg_name_matches_prefix _stringappend_316_) with
+ | Some
+ (_stringappend_317_,(existT _ _stringappend_318_ _)) =>
+ returnm ((_stringappend_317_,
+ build_ex
+ _stringappend_318_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__342 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_318_ _) :=
+ w__342
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_319_ :=
+ string_drop _stringappend_316_
+ (build_ex
+ _stringappend_318_) in
+ sep_matches_prefix _stringappend_319_ >>= fun w__343 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__343 with
+ | Some
+ (_stringappend_320_,(existT _ _stringappend_321_ _)) =>
+ returnm ((_stringappend_320_,
+ build_ex
+ _stringappend_321_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__345 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_321_ _) :=
+ w__345
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_322_ :=
+ string_drop _stringappend_319_
+ (build_ex
+ _stringappend_321_) in
+ match (reg_name_matches_prefix _stringappend_322_) with
+ | Some
+ (_stringappend_323_,(existT _ _stringappend_324_ _)) =>
+ returnm ((_stringappend_323_,
+ build_ex
+ _stringappend_324_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__347 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_324_ _) :=
+ w__347
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_325_ :=
+ string_drop _stringappend_322_
+ (build_ex
+ _stringappend_324_) in
+ sep_matches_prefix _stringappend_325_ >>= fun w__348 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__348 with
+ | Some
+ (_stringappend_326_,(existT _ _stringappend_327_ _)) =>
+ returnm ((_stringappend_326_,
+ build_ex
+ _stringappend_327_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__350 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_327_ _) :=
+ w__350
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_328_ :=
+ string_drop _stringappend_325_
+ (build_ex
+ _stringappend_327_) in
+ match (reg_name_matches_prefix _stringappend_328_) with
+ | Some
+ (_stringappend_329_,(existT _ _stringappend_330_ _)) =>
+ returnm ((_stringappend_329_,
+ build_ex
+ _stringappend_330_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__352 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_330_ _) :=
+ w__352
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop _stringappend_328_
+ (build_ex
+ _stringappend_330_)) with
+ | s_ =>
+ Some (REM (rs2,rs1,rd,s),
+ sub_nat (string_length arg_)
+ (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith _stringappend_0_
+ "mulw")
+ : bool))
+ (let _stringappend_332_ :=
+ string_drop _stringappend_0_
+ (string_length "mulw") in
+ match (spc_matches_prefix _stringappend_332_) with
+ | Some
+ (_stringappend_333_,(existT _ _stringappend_334_ _)) =>
+ let _stringappend_335_ :=
+ string_drop _stringappend_332_
+ (build_ex
+ _stringappend_334_) in
+ match (reg_name_matches_prefix
+ _stringappend_335_) with
+ | Some
+ (_stringappend_336_,(existT _ _stringappend_337_ _)) =>
+ let _stringappend_338_ :=
+ string_drop _stringappend_335_
+ (build_ex
+ _stringappend_337_) in
+ sep_matches_prefix _stringappend_338_ >>= fun w__353 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__353 with
+ | Some
+ (_stringappend_339_,(existT _ _stringappend_340_ _)) =>
+ let _stringappend_341_ :=
+ string_drop _stringappend_338_
+ (build_ex
+ _stringappend_340_) in
+ match (reg_name_matches_prefix
+ _stringappend_341_) with
+ | Some
+ (_stringappend_342_,(existT _ _stringappend_343_ _)) =>
+ let _stringappend_344_ :=
+ string_drop _stringappend_341_
+ (build_ex
+ _stringappend_343_) in
+ sep_matches_prefix
+ _stringappend_344_ >>= fun w__354 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__354 with
+ | Some
+ (_stringappend_345_,(existT _ _stringappend_346_ _)) =>
+ let _stringappend_347_ :=
+ string_drop
+ _stringappend_344_
+ (build_ex
+ _stringappend_346_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_347_) with
+ | Some
+ (_stringappend_348_,(existT _ _stringappend_349_ _)) =>
+ match (string_drop
+ _stringappend_347_
+ (build_ex
+ _stringappend_349_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end)) then
+ true
+ else false
+ | None => false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__355 : bool =>
+ returnm ((if (w__355) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__356 : bool =>
+ returnm ((if (w__356) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__357 : bool =>
+ returnm ((if (w__357) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__358 : bool =>
+ returnm ((if (w__358) then true
+ else false)
+ : bool)) >>= fun w__359 : bool =>
+ (if (w__359) then
+ let _stringappend_332_ :=
+ string_drop _stringappend_0_
+ (string_length "mulw") in
+ match (spc_matches_prefix _stringappend_332_) with
+ | Some
+ (_stringappend_333_,(existT _ _stringappend_334_ _)) =>
+ returnm ((_stringappend_333_,
+ build_ex
+ _stringappend_334_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__361 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_334_ _) :=
+ w__361
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_335_ :=
+ string_drop _stringappend_332_
+ (build_ex
+ _stringappend_334_) in
+ match (reg_name_matches_prefix
+ _stringappend_335_) with
+ | Some
+ (_stringappend_336_,(existT _ _stringappend_337_ _)) =>
+ returnm ((_stringappend_336_,
+ build_ex
+ _stringappend_337_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__363 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_337_ _) :=
+ w__363
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_338_ :=
+ string_drop _stringappend_335_
+ (build_ex
+ _stringappend_337_) in
+ sep_matches_prefix _stringappend_338_ >>= fun w__364 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__364 with
+ | Some
+ (_stringappend_339_,(existT _ _stringappend_340_ _)) =>
+ returnm ((_stringappend_339_,
+ build_ex
+ _stringappend_340_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__366 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_340_ _) :=
+ w__366
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_341_ :=
+ string_drop _stringappend_338_
+ (build_ex
+ _stringappend_340_) in
+ match (reg_name_matches_prefix
+ _stringappend_341_) with
+ | Some
+ (_stringappend_342_,(existT _ _stringappend_343_ _)) =>
+ returnm ((_stringappend_342_,
+ build_ex
+ _stringappend_343_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__368 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_343_ _) :=
+ w__368
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_344_ :=
+ string_drop _stringappend_341_
+ (build_ex
+ _stringappend_343_) in
+ sep_matches_prefix _stringappend_344_ >>= fun w__369 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__369 with
+ | Some
+ (_stringappend_345_,(existT _ _stringappend_346_ _)) =>
+ returnm ((_stringappend_345_,
+ build_ex
+ _stringappend_346_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__371 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_346_ _) :=
+ w__371
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_347_ :=
+ string_drop _stringappend_344_
+ (build_ex
+ _stringappend_346_) in
+ match (reg_name_matches_prefix
+ _stringappend_347_) with
+ | Some
+ (_stringappend_348_,(existT _ _stringappend_349_ _)) =>
+ returnm ((_stringappend_348_,
+ build_ex
+ _stringappend_349_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__373 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_349_ _) :=
+ w__373
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop
+ _stringappend_347_
+ (build_ex
+ _stringappend_349_)) with
+ | s_ =>
+ Some (MULW (rs2,rs1,rd),
+ sub_nat
+ (string_length arg_)
+ (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >= 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_0_ "div")
+ : bool))
+ (let _stringappend_351_ :=
+ string_drop _stringappend_0_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_351_) with
+ | Some
+ (_stringappend_352_,(existT _ _stringappend_353_ _)) =>
+ let _stringappend_354_ :=
+ string_drop _stringappend_351_
+ (build_ex
+ _stringappend_353_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_354_ "w")
+ : bool))
+ (let _stringappend_355_ :=
+ string_drop _stringappend_354_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_355_) with
+ | Some
+ (_stringappend_356_,(existT _ _stringappend_357_ _)) =>
+ let _stringappend_358_ :=
+ string_drop _stringappend_355_
+ (build_ex
+ _stringappend_357_) in
+ match (reg_name_matches_prefix
+ _stringappend_358_) with
+ | Some
+ (_stringappend_359_,(existT _ _stringappend_360_ _)) =>
+ let _stringappend_361_ :=
+ string_drop _stringappend_358_
+ (build_ex
+ _stringappend_360_) in
+ sep_matches_prefix
+ _stringappend_361_ >>= fun w__374 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__374 with
+ | Some
+ (_stringappend_362_,(existT _ _stringappend_363_ _)) =>
+ let _stringappend_364_ :=
+ string_drop
+ _stringappend_361_
+ (build_ex
+ _stringappend_363_) in
+ match (reg_name_matches_prefix
+ _stringappend_364_) with
+ | Some
+ (_stringappend_365_,(existT _ _stringappend_366_ _)) =>
+ let _stringappend_367_ :=
+ string_drop
+ _stringappend_364_
+ (build_ex
+ _stringappend_366_) in
+ sep_matches_prefix
+ _stringappend_367_ >>= fun w__375 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__375 with
+ | Some
+ (_stringappend_368_,(existT _ _stringappend_369_ _)) =>
+ let _stringappend_370_ :=
+ string_drop
+ _stringappend_367_
+ (build_ex
+ _stringappend_369_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_370_) with
+ | Some
+ (_stringappend_371_,(existT _ _stringappend_372_ _)) =>
+ match (string_drop
+ _stringappend_370_
+ (build_ex
+ _stringappend_372_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__376 : bool =>
+ returnm ((if (w__376) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__377 : bool =>
+ returnm ((if (w__377) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__378 : bool =>
+ returnm ((if (w__378) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__379 : bool =>
+ returnm ((if (w__379) then true
+ else false)
+ : bool)) >>= fun w__380 : bool =>
+ returnm ((if (w__380) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__381 : bool =>
+ returnm ((if (w__381) then true
+ else false)
+ : bool)) >>= fun w__382 : bool =>
+ (if (w__382) then
+ let _stringappend_351_ :=
+ string_drop _stringappend_0_
+ (string_length "div") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_351_) with
+ | Some
+ (_stringappend_352_,(existT _ _stringappend_353_ _)) =>
+ returnm ((_stringappend_352_,
+ build_ex
+ _stringappend_353_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__384 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_353_ _) :=
+ w__384
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_354_ :=
+ string_drop _stringappend_351_
+ (build_ex
+ _stringappend_353_) in
+ let _stringappend_355_ :=
+ string_drop _stringappend_354_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_355_) with
+ | Some
+ (_stringappend_356_,(existT _ _stringappend_357_ _)) =>
+ returnm ((_stringappend_356_,
+ build_ex
+ _stringappend_357_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__386 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_357_ _) :=
+ w__386
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_358_ :=
+ string_drop _stringappend_355_
+ (build_ex
+ _stringappend_357_) in
+ match (reg_name_matches_prefix
+ _stringappend_358_) with
+ | Some
+ (_stringappend_359_,(existT _ _stringappend_360_ _)) =>
+ returnm ((_stringappend_359_,
+ build_ex
+ _stringappend_360_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__388 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_360_ _) :=
+ w__388
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_361_ :=
+ string_drop _stringappend_358_
+ (build_ex
+ _stringappend_360_) in
+ sep_matches_prefix _stringappend_361_ >>= fun w__389 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__389 with
+ | Some
+ (_stringappend_362_,(existT _ _stringappend_363_ _)) =>
+ returnm ((_stringappend_362_,
+ build_ex
+ _stringappend_363_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__391 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_363_ _) :=
+ w__391
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_364_ :=
+ string_drop _stringappend_361_
+ (build_ex
+ _stringappend_363_) in
+ match (reg_name_matches_prefix
+ _stringappend_364_) with
+ | Some
+ (_stringappend_365_,(existT _ _stringappend_366_ _)) =>
+ returnm ((_stringappend_365_,
+ build_ex
+ _stringappend_366_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__393 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_366_ _) :=
+ w__393
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_367_ :=
+ string_drop _stringappend_364_
+ (build_ex
+ _stringappend_366_) in
+ sep_matches_prefix _stringappend_367_ >>= fun w__394 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__394 with
+ | Some
+ (_stringappend_368_,(existT _ _stringappend_369_ _)) =>
+ returnm ((_stringappend_368_,
+ build_ex
+ _stringappend_369_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >= 0)}))
+ end >>= fun w__396 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_369_ _) :=
+ w__396
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_370_ :=
+ string_drop _stringappend_367_
+ (build_ex
+ _stringappend_369_) in
+ match (reg_name_matches_prefix
+ _stringappend_370_) with
+ | Some
+ (_stringappend_371_,(existT _ _stringappend_372_ _)) =>
+ returnm ((_stringappend_371_,
+ build_ex
+ _stringappend_372_)
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__398 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_372_ _) :=
+ w__398
+ : (mword 5 * {n : Z & ArithFact (n >= 0)}) in
+ returnm ((match (string_drop
+ _stringappend_370_
+ (build_ex
+ _stringappend_372_)) with
+ | s_ =>
+ Some (DIVW (rs2,rs1,rd,s),
+ sub_nat
+ (string_length arg_)
+ (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_0_ "rem")
+ : bool))
+ (let _stringappend_374_ :=
+ string_drop _stringappend_0_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_374_) with
+ | Some
+ (_stringappend_375_,(existT _ _stringappend_376_ _)) =>
+ let _stringappend_377_ :=
+ string_drop _stringappend_374_
+ (build_ex
+ _stringappend_376_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_377_ "w")
+ : bool))
+ (let _stringappend_378_ :=
+ string_drop _stringappend_377_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_378_) with
+ | Some
+ (_stringappend_379_,(existT _ _stringappend_380_ _)) =>
+ let _stringappend_381_ :=
+ string_drop _stringappend_378_
+ (build_ex
+ _stringappend_380_) in
+ match (reg_name_matches_prefix
+ _stringappend_381_) with
+ | Some
+ (_stringappend_382_,(existT _ _stringappend_383_ _)) =>
+ let _stringappend_384_ :=
+ string_drop
+ _stringappend_381_
+ (build_ex
+ _stringappend_383_) in
+ sep_matches_prefix
+ _stringappend_384_ >>= fun w__399 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__399 with
+ | Some
+ (_stringappend_385_,(existT _ _stringappend_386_ _)) =>
+ let _stringappend_387_ :=
+ string_drop
+ _stringappend_384_
+ (build_ex
+ _stringappend_386_) in
+ match (reg_name_matches_prefix
+ _stringappend_387_) with
+ | Some
+ (_stringappend_388_,(existT _ _stringappend_389_ _)) =>
+ let _stringappend_390_ :=
+ string_drop
+ _stringappend_387_
+ (build_ex
+ _stringappend_389_) in
+ sep_matches_prefix
+ _stringappend_390_ >>= fun w__400 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__400 with
+ | Some
+ (_stringappend_391_,(existT _ _stringappend_392_ _)) =>
+ let _stringappend_393_ :=
+ string_drop
+ _stringappend_390_
+ (build_ex
+ _stringappend_392_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_393_) with
+ | Some
+ (_stringappend_394_,(existT _ _stringappend_395_ _)) =>
+ match (string_drop
+ _stringappend_393_
+ (build_ex
+ _stringappend_395_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__401 : bool =>
+ returnm ((if (w__401) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__402 : bool =>
+ returnm ((if (w__402) then
+ true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__403 : bool =>
+ returnm ((if (w__403) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__404 : bool =>
+ returnm ((if (w__404) then true
+ else false)
+ : bool)) >>= fun w__405 : bool =>
+ returnm ((if (w__405) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__406 : bool =>
+ returnm ((if (w__406) then true
+ else false)
+ : bool)) >>= fun w__407 : bool =>
+ (if (w__407) then
+ let _stringappend_374_ :=
+ string_drop _stringappend_0_
+ (string_length "rem") in
+ match (maybe_not_u_matches_prefix
+ _stringappend_374_) with
+ | Some
+ (_stringappend_375_,(existT _ _stringappend_376_ _)) =>
+ returnm ((_stringappend_375_,
+ build_ex
+ _stringappend_376_)
+ : (bool * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__409 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_376_ _) :=
+ w__409
+ : (bool * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_377_ :=
+ string_drop _stringappend_374_
+ (build_ex
+ _stringappend_376_) in
+ let _stringappend_378_ :=
+ string_drop _stringappend_377_
+ (string_length "w") in
+ match (spc_matches_prefix
+ _stringappend_378_) with
+ | Some
+ (_stringappend_379_,(existT _ _stringappend_380_ _)) =>
+ returnm ((_stringappend_379_,
+ build_ex
+ _stringappend_380_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__411 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_380_ _) :=
+ w__411
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_381_ :=
+ string_drop _stringappend_378_
+ (build_ex
+ _stringappend_380_) in
+ match (reg_name_matches_prefix
+ _stringappend_381_) with
+ | Some
+ (_stringappend_382_,(existT _ _stringappend_383_ _)) =>
+ returnm ((_stringappend_382_,
+ build_ex
+ _stringappend_383_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__413 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_383_ _) :=
+ w__413
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_384_ :=
+ string_drop _stringappend_381_
+ (build_ex
+ _stringappend_383_) in
+ sep_matches_prefix _stringappend_384_ >>= fun w__414 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__414 with
+ | Some
+ (_stringappend_385_,(existT _ _stringappend_386_ _)) =>
+ returnm ((_stringappend_385_,
+ build_ex
+ _stringappend_386_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__416 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_386_ _) :=
+ w__416
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_387_ :=
+ string_drop _stringappend_384_
+ (build_ex
+ _stringappend_386_) in
+ match (reg_name_matches_prefix
+ _stringappend_387_) with
+ | Some
+ (_stringappend_388_,(existT _ _stringappend_389_ _)) =>
+ returnm ((_stringappend_388_,
+ build_ex
+ _stringappend_389_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__418 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_389_ _) :=
+ w__418
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_390_ :=
+ string_drop _stringappend_387_
+ (build_ex
+ _stringappend_389_) in
+ sep_matches_prefix _stringappend_390_ >>= fun w__419 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__419 with
+ | Some
+ (_stringappend_391_,(existT _ _stringappend_392_ _)) =>
+ returnm ((_stringappend_391_,
+ build_ex
+ _stringappend_392_)
+ : (unit * {n : Z & ArithFact (n >= 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__421 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_392_ _) :=
+ w__421
+ : (unit * {n : Z & ArithFact (n >= 0)}) in
+ let _stringappend_393_ :=
+ string_drop _stringappend_390_
+ (build_ex
+ _stringappend_392_) in
+ match (reg_name_matches_prefix
+ _stringappend_393_) with
+ | Some
+ (_stringappend_394_,(existT _ _stringappend_395_ _)) =>
+ returnm ((_stringappend_394_,
+ build_ex
+ _stringappend_395_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__423 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_395_ _) :=
+ w__423
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ returnm ((match (string_drop
+ _stringappend_393_
+ (build_ex
+ _stringappend_395_)) with
+ | s_ =>
+ Some (REMW (rs2,rs1,rd,s),
+ sub_nat
+ (string_length arg_)
+ (string_length s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_0_ "fence")
+ : bool))
+ (let _stringappend_397_ :=
+ string_drop _stringappend_0_
+ (string_length "fence") in
+ match (spc_matches_prefix
+ _stringappend_397_) with
+ | Some
+ (_stringappend_398_,(existT _ _stringappend_399_ _)) =>
+ let _stringappend_400_ :=
+ string_drop _stringappend_397_
+ (build_ex
+ _stringappend_399_) in
+ fence_bits_matches_prefix
+ _stringappend_400_ >>= fun w__424 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__424 with
+ | Some
+ (_stringappend_401_,(existT _ _stringappend_402_ _)) =>
+ let _stringappend_403_ :=
+ string_drop _stringappend_400_
+ (build_ex
+ _stringappend_402_) in
+ sep_matches_prefix
+ _stringappend_403_ >>= fun w__425 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__425 with
+ | Some
+ (_stringappend_404_,(existT _ _stringappend_405_ _)) =>
+ let _stringappend_406_ :=
+ string_drop
+ _stringappend_403_
+ (build_ex
+ _stringappend_405_) in
+ fence_bits_matches_prefix
+ _stringappend_406_ >>= fun w__426 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__426 with
+ | Some
+ (_stringappend_407_,(existT _ _stringappend_408_ _)) =>
+ match (string_drop
+ _stringappend_406_
+ (build_ex
+ _stringappend_408_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__427 : bool =>
+ returnm ((if (w__427) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__428 : bool =>
+ returnm ((if (w__428) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__429 : bool =>
+ returnm ((if (w__429) then true
+ else false)
+ : bool)) >>= fun w__430 : bool =>
+ (if (w__430) then
+ let _stringappend_397_ :=
+ string_drop _stringappend_0_
+ (string_length "fence") in
+ match (spc_matches_prefix
+ _stringappend_397_) with
+ | Some
+ (_stringappend_398_,(existT _ _stringappend_399_ _)) =>
+ returnm ((_stringappend_398_,
+ build_ex
+ _stringappend_399_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__432 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_399_ _) :=
+ w__432
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_400_ :=
+ string_drop _stringappend_397_
+ (build_ex
+ _stringappend_399_) in
+ fence_bits_matches_prefix
+ _stringappend_400_ >>= fun w__433 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__433 with
+ | Some
+ (_stringappend_401_,(existT _ _stringappend_402_ _)) =>
+ returnm ((_stringappend_401_,
+ build_ex
+ _stringappend_402_)
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__435 : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(pred, existT _ _stringappend_402_ _) :=
+ w__435
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_403_ :=
+ string_drop _stringappend_400_
+ (build_ex
+ _stringappend_402_) in
+ sep_matches_prefix _stringappend_403_ >>= fun w__436 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__436 with
+ | Some
+ (_stringappend_404_,(existT _ _stringappend_405_ _)) =>
+ returnm ((_stringappend_404_,
+ build_ex
+ _stringappend_405_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__438 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_405_ _) :=
+ w__438
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_406_ :=
+ string_drop _stringappend_403_
+ (build_ex
+ _stringappend_405_) in
+ fence_bits_matches_prefix
+ _stringappend_406_ >>= fun w__439 : option ((mword 4 * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__439 with
+ | Some
+ (_stringappend_407_,(existT _ _stringappend_408_ _)) =>
+ returnm ((_stringappend_407_,
+ build_ex
+ _stringappend_408_)
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 4 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__441 : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(succ, existT _ _stringappend_408_ _) :=
+ w__441
+ : (mword 4 * {n : Z & ArithFact (n >=
+ 0)}) in
+ returnm ((match (string_drop
+ _stringappend_406_
+ (build_ex
+ _stringappend_408_)) with
+ | s_ =>
+ Some (FENCE (pred,succ),
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else if ((andb
+ (string_startswith
+ _stringappend_0_
+ "fence.i")
+ (match (string_drop
+ _stringappend_0_
+ (string_length
+ "fence.i")) with
+ | s_ => true
+ end))) then
+ returnm ((match (string_drop
+ _stringappend_0_
+ (string_length
+ "fence.i")) with
+ | s_ =>
+ Some (FENCEI tt,
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else if ((andb
+ (string_startswith
+ _stringappend_0_ "ecall")
+ (match (string_drop
+ _stringappend_0_
+ (string_length
+ "ecall")) with
+ | s_ => true
+ end))) then
+ returnm ((match (string_drop
+ _stringappend_0_
+ (string_length
+ "ecall")) with
+ | s_ =>
+ Some (ECALL tt,
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else if ((andb
+ (string_startswith
+ _stringappend_0_ "mret")
+ (match (string_drop
+ _stringappend_0_
+ (string_length
+ "mret")) with
+ | s_ => true
+ end))) then
+ returnm ((match (string_drop
+ _stringappend_0_
+ (string_length
+ "mret")) with
+ | s_ =>
+ Some (MRET tt,
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else if ((andb
+ (string_startswith
+ _stringappend_0_ "sret")
+ (match (string_drop
+ _stringappend_0_
+ (string_length
+ "sret")) with
+ | s_ => true
+ end))) then
+ returnm ((match (string_drop
+ _stringappend_0_
+ (string_length
+ "sret")) with
+ | s_ =>
+ Some (SRET tt,
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else if ((andb
+ (string_startswith
+ _stringappend_0_
+ "ebreak")
+ (match (string_drop
+ _stringappend_0_
+ (string_length
+ "ebreak")) with
+ | s_ => true
+ end))) then
+ returnm ((match (string_drop
+ _stringappend_0_
+ (string_length
+ "ebreak")) with
+ | s_ =>
+ Some (EBREAK tt,
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else if ((andb
+ (string_startswith
+ _stringappend_0_ "wfi")
+ (match (string_drop
+ _stringappend_0_
+ (string_length
+ "wfi")) with
+ | s_ => true
+ end))) then
+ returnm ((match (string_drop
+ _stringappend_0_
+ (string_length
+ "wfi")) with
+ | s_ =>
+ Some (WFI tt,
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_0_
+ "sfence.vma")
+ : bool))
+ (let _stringappend_416_ :=
+ string_drop _stringappend_0_
+ (string_length "sfence.vma") in
+ match (spc_matches_prefix
+ _stringappend_416_) with
+ | Some
+ (_stringappend_417_,(existT _ _stringappend_418_ _)) =>
+ let _stringappend_419_ :=
+ string_drop _stringappend_416_
+ (build_ex
+ _stringappend_418_) in
+ match (reg_name_matches_prefix
+ _stringappend_419_) with
+ | Some
+ (_stringappend_420_,(existT _ _stringappend_421_ _)) =>
+ let _stringappend_422_ :=
+ string_drop
+ _stringappend_419_
+ (build_ex
+ _stringappend_421_) in
+ sep_matches_prefix
+ _stringappend_422_ >>= fun w__442 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__442 with
+ | Some
+ (_stringappend_423_,(existT _ _stringappend_424_ _)) =>
+ let _stringappend_425_ :=
+ string_drop
+ _stringappend_422_
+ (build_ex
+ _stringappend_424_) in
+ if ((match (reg_name_matches_prefix
+ _stringappend_425_) with
+ | Some
+ (_stringappend_426_,(existT _ _stringappend_427_ _)) =>
+ match (string_drop
+ _stringappend_425_
+ (build_ex
+ _stringappend_427_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else false
+ | None =>
+ false
+ end)) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__443 : bool =>
+ returnm ((if (w__443) then true
+ else false)
+ : bool)
+ | None => returnm (false : bool)
+ end >>= fun w__444 : bool =>
+ returnm ((if (w__444) then true
+ else false)
+ : bool)) >>= fun w__445 : bool =>
+ (if (w__445) then
+ let _stringappend_416_ :=
+ string_drop _stringappend_0_
+ (string_length "sfence.vma") in
+ match (spc_matches_prefix
+ _stringappend_416_) with
+ | Some
+ (_stringappend_417_,(existT _ _stringappend_418_ _)) =>
+ returnm ((_stringappend_417_,
+ build_ex
+ _stringappend_418_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__447 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_418_ _) :=
+ w__447
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_419_ :=
+ string_drop _stringappend_416_
+ (build_ex
+ _stringappend_418_) in
+ match (reg_name_matches_prefix
+ _stringappend_419_) with
+ | Some
+ (_stringappend_420_,(existT _ _stringappend_421_ _)) =>
+ returnm ((_stringappend_420_,
+ build_ex
+ _stringappend_421_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__449 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_421_ _) :=
+ w__449
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_422_ :=
+ string_drop _stringappend_419_
+ (build_ex
+ _stringappend_421_) in
+ sep_matches_prefix
+ _stringappend_422_ >>= fun w__450 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__450 with
+ | Some
+ (_stringappend_423_,(existT _ _stringappend_424_ _)) =>
+ returnm ((_stringappend_423_,
+ build_ex
+ _stringappend_424_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__452 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_424_ _) :=
+ w__452
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_425_ :=
+ string_drop _stringappend_422_
+ (build_ex
+ _stringappend_424_) in
+ match (reg_name_matches_prefix
+ _stringappend_425_) with
+ | Some
+ (_stringappend_426_,(existT _ _stringappend_427_ _)) =>
+ returnm ((_stringappend_426_,
+ build_ex
+ _stringappend_427_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__454 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_427_ _) :=
+ w__454
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ returnm ((match (string_drop
+ _stringappend_425_
+ (build_ex
+ _stringappend_427_)) with
+ | s_ =>
+ Some (SFENCE_VMA (rs1,rs2),
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_0_
+ "lr.")
+ : bool))
+ (let _stringappend_429_ :=
+ string_drop _stringappend_0_
+ (string_length "lr.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_429_) with
+ | Some
+ (_stringappend_430_,(existT _ _stringappend_431_ _)) =>
+ let _stringappend_432_ :=
+ string_drop
+ _stringappend_429_
+ (build_ex
+ _stringappend_431_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_432_) with
+ | Some
+ (_stringappend_433_,(existT _ _stringappend_434_ _)) =>
+ let _stringappend_435_ :=
+ string_drop
+ _stringappend_432_
+ (build_ex
+ _stringappend_434_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_435_) with
+ | Some
+ (_stringappend_436_,(existT _ _stringappend_437_ _)) =>
+ let _stringappend_438_ :=
+ string_drop
+ _stringappend_435_
+ (build_ex
+ _stringappend_437_) in
+ match (spc_matches_prefix
+ _stringappend_438_) with
+ | Some
+ (_stringappend_439_,(existT _ _stringappend_440_ _)) =>
+ let _stringappend_441_ :=
+ string_drop
+ _stringappend_438_
+ (build_ex
+ _stringappend_440_) in
+ match (reg_name_matches_prefix
+ _stringappend_441_) with
+ | Some
+ (_stringappend_442_,(existT _ _stringappend_443_ _)) =>
+ let _stringappend_444_ :=
+ string_drop
+ _stringappend_441_
+ (build_ex
+ _stringappend_443_) in
+ sep_matches_prefix
+ _stringappend_444_ >>= fun w__455 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if ((match w__455 with
+ | Some
+ (_stringappend_445_,(existT _ _stringappend_446_ _)) =>
+ let _stringappend_447_ :=
+ string_drop
+ _stringappend_444_
+ (build_ex
+ _stringappend_446_) in
+ if
+ ((match (reg_name_matches_prefix
+ _stringappend_447_) with
+ | Some
+ (_stringappend_448_,(existT _ _stringappend_449_ _)) =>
+ match (string_drop
+ _stringappend_447_
+ (build_ex
+ _stringappend_449_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__456 : bool =>
+ returnm ((if (w__456)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__457 : bool =>
+ returnm ((if (w__457)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__458 : bool =>
+ returnm ((if (w__458) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__459 : bool =>
+ returnm ((if (w__459) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__460 : bool =>
+ returnm ((if (w__460) then true
+ else false)
+ : bool)) >>= fun w__461 : bool =>
+ (if (w__461) then
+ let _stringappend_429_ :=
+ string_drop _stringappend_0_
+ (string_length "lr.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_429_) with
+ | Some
+ (_stringappend_430_,(existT _ _stringappend_431_ _)) =>
+ returnm ((_stringappend_430_,
+ build_ex
+ _stringappend_431_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__463 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(aq, existT _ _stringappend_431_ _) :=
+ w__463
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_432_ :=
+ string_drop
+ _stringappend_429_
+ (build_ex
+ _stringappend_431_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_432_) with
+ | Some
+ (_stringappend_433_,(existT _ _stringappend_434_ _)) =>
+ returnm ((_stringappend_433_,
+ build_ex
+ _stringappend_434_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__465 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rl, existT _ _stringappend_434_ _) :=
+ w__465
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_435_ :=
+ string_drop
+ _stringappend_432_
+ (build_ex
+ _stringappend_434_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_435_) with
+ | Some
+ (_stringappend_436_,(existT _ _stringappend_437_ _)) =>
+ returnm ((_stringappend_436_,
+ build_ex
+ _stringappend_437_)
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__467 : (word_width * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(size, existT _ _stringappend_437_ _) :=
+ w__467
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_438_ :=
+ string_drop
+ _stringappend_435_
+ (build_ex
+ _stringappend_437_) in
+ match (spc_matches_prefix
+ _stringappend_438_) with
+ | Some
+ (_stringappend_439_,(existT _ _stringappend_440_ _)) =>
+ returnm ((_stringappend_439_,
+ build_ex
+ _stringappend_440_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__469 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_440_ _) :=
+ w__469
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_441_ :=
+ string_drop
+ _stringappend_438_
+ (build_ex
+ _stringappend_440_) in
+ match (reg_name_matches_prefix
+ _stringappend_441_) with
+ | Some
+ (_stringappend_442_,(existT _ _stringappend_443_ _)) =>
+ returnm ((_stringappend_442_,
+ build_ex
+ _stringappend_443_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__471 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_443_ _) :=
+ w__471
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_444_ :=
+ string_drop
+ _stringappend_441_
+ (build_ex
+ _stringappend_443_) in
+ sep_matches_prefix
+ _stringappend_444_ >>= fun w__472 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__472 with
+ | Some
+ (_stringappend_445_,(existT _ _stringappend_446_ _)) =>
+ returnm ((_stringappend_445_,
+ build_ex
+ _stringappend_446_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__474 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_446_ _) :=
+ w__474
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_447_ :=
+ string_drop
+ _stringappend_444_
+ (build_ex
+ _stringappend_446_) in
+ match (reg_name_matches_prefix
+ _stringappend_447_) with
+ | Some
+ (_stringappend_448_,(existT _ _stringappend_449_ _)) =>
+ returnm ((_stringappend_448_,
+ build_ex
+ _stringappend_449_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__476 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_449_ _) :=
+ w__476
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ returnm ((match (string_drop
+ _stringappend_447_
+ (build_ex
+ _stringappend_449_)) with
+ | s_ =>
+ Some (LOADRES (aq,rl,rs1,size,rd),
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_0_
+ "sc.")
+ : bool))
+ (let _stringappend_451_ :=
+ string_drop
+ _stringappend_0_
+ (string_length "sc.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_451_) with
+ | Some
+ (_stringappend_452_,(existT _ _stringappend_453_ _)) =>
+ let _stringappend_454_ :=
+ string_drop
+ _stringappend_451_
+ (build_ex
+ _stringappend_453_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_454_) with
+ | Some
+ (_stringappend_455_,(existT _ _stringappend_456_ _)) =>
+ let _stringappend_457_ :=
+ string_drop
+ _stringappend_454_
+ (build_ex
+ _stringappend_456_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_457_) with
+ | Some
+ (_stringappend_458_,(existT _ _stringappend_459_ _)) =>
+ let _stringappend_460_ :=
+ string_drop
+ _stringappend_457_
+ (build_ex
+ _stringappend_459_) in
+ match (spc_matches_prefix
+ _stringappend_460_) with
+ | Some
+ (_stringappend_461_,(existT _ _stringappend_462_ _)) =>
+ let _stringappend_463_ :=
+ string_drop
+ _stringappend_460_
+ (build_ex
+ _stringappend_462_) in
+ match (reg_name_matches_prefix
+ _stringappend_463_) with
+ | Some
+ (_stringappend_464_,(existT _ _stringappend_465_ _)) =>
+ let _stringappend_466_ :=
+ string_drop
+ _stringappend_463_
+ (build_ex
+ _stringappend_465_) in
+ sep_matches_prefix
+ _stringappend_466_ >>= fun w__477 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__477 with
+ | Some
+ (_stringappend_467_,(existT _ _stringappend_468_ _)) =>
+ let _stringappend_469_ :=
+ string_drop
+ _stringappend_466_
+ (build_ex
+ _stringappend_468_) in
+ match (reg_name_matches_prefix
+ _stringappend_469_) with
+ | Some
+ (_stringappend_470_,(existT _ _stringappend_471_ _)) =>
+ let _stringappend_472_ :=
+ string_drop
+ _stringappend_469_
+ (build_ex
+ _stringappend_471_) in
+ sep_matches_prefix
+ _stringappend_472_ >>= fun w__478 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__478 with
+ | Some
+ (_stringappend_473_,(existT _ _stringappend_474_ _)) =>
+ let _stringappend_475_ :=
+ string_drop
+ _stringappend_472_
+ (build_ex
+ _stringappend_474_) in
+ if
+ ((match (reg_name_matches_prefix
+ _stringappend_475_) with
+ | Some
+ (_stringappend_476_,(existT _ _stringappend_477_ _)) =>
+ match (string_drop
+ _stringappend_475_
+ (build_ex
+ _stringappend_477_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__479 : bool =>
+ returnm ((if
+ (w__479)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__480 : bool =>
+ returnm ((if (w__480)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__481 : bool =>
+ returnm ((if (w__481)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__482 : bool =>
+ returnm ((if (w__482)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__483 : bool =>
+ returnm ((if (w__483)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__484 : bool =>
+ returnm ((if (w__484) then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__485 : bool =>
+ returnm ((if (w__485) then
+ true
+ else false)
+ : bool)) >>= fun w__486 : bool =>
+ (if (w__486) then
+ let _stringappend_451_ :=
+ string_drop
+ _stringappend_0_
+ (string_length "sc.") in
+ match (maybe_aq_matches_prefix
+ _stringappend_451_) with
+ | Some
+ (_stringappend_452_,(existT _ _stringappend_453_ _)) =>
+ returnm ((_stringappend_452_,
+ build_ex
+ _stringappend_453_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__488 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(aq, existT _ _stringappend_453_ _) :=
+ w__488
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_454_ :=
+ string_drop
+ _stringappend_451_
+ (build_ex
+ _stringappend_453_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_454_) with
+ | Some
+ (_stringappend_455_,(existT _ _stringappend_456_ _)) =>
+ returnm ((_stringappend_455_,
+ build_ex
+ _stringappend_456_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__490 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rl, existT _ _stringappend_456_ _) :=
+ w__490
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_457_ :=
+ string_drop
+ _stringappend_454_
+ (build_ex
+ _stringappend_456_) in
+ match (size_mnemonic_matches_prefix
+ _stringappend_457_) with
+ | Some
+ (_stringappend_458_,(existT _ _stringappend_459_ _)) =>
+ returnm ((_stringappend_458_,
+ build_ex
+ _stringappend_459_)
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__492 : (word_width * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(size, existT _ _stringappend_459_ _) :=
+ w__492
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_460_ :=
+ string_drop
+ _stringappend_457_
+ (build_ex
+ _stringappend_459_) in
+ match (spc_matches_prefix
+ _stringappend_460_) with
+ | Some
+ (_stringappend_461_,(existT _ _stringappend_462_ _)) =>
+ returnm ((_stringappend_461_,
+ build_ex
+ _stringappend_462_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__494 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_462_ _) :=
+ w__494
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_463_ :=
+ string_drop
+ _stringappend_460_
+ (build_ex
+ _stringappend_462_) in
+ match (reg_name_matches_prefix
+ _stringappend_463_) with
+ | Some
+ (_stringappend_464_,(existT _ _stringappend_465_ _)) =>
+ returnm ((_stringappend_464_,
+ build_ex
+ _stringappend_465_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__496 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_465_ _) :=
+ w__496
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_466_ :=
+ string_drop
+ _stringappend_463_
+ (build_ex
+ _stringappend_465_) in
+ sep_matches_prefix
+ _stringappend_466_ >>= fun w__497 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__497 with
+ | Some
+ (_stringappend_467_,(existT _ _stringappend_468_ _)) =>
+ returnm ((_stringappend_467_,
+ build_ex
+ _stringappend_468_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__499 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_468_ _) :=
+ w__499
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_469_ :=
+ string_drop
+ _stringappend_466_
+ (build_ex
+ _stringappend_468_) in
+ match (reg_name_matches_prefix
+ _stringappend_469_) with
+ | Some
+ (_stringappend_470_,(existT _ _stringappend_471_ _)) =>
+ returnm ((_stringappend_470_,
+ build_ex
+ _stringappend_471_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__501 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_471_ _) :=
+ w__501
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_472_ :=
+ string_drop
+ _stringappend_469_
+ (build_ex
+ _stringappend_471_) in
+ sep_matches_prefix
+ _stringappend_472_ >>= fun w__502 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__502 with
+ | Some
+ (_stringappend_473_,(existT _ _stringappend_474_ _)) =>
+ returnm ((_stringappend_473_,
+ build_ex
+ _stringappend_474_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__504 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_474_ _) :=
+ w__504
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_475_ :=
+ string_drop
+ _stringappend_472_
+ (build_ex
+ _stringappend_474_) in
+ match (reg_name_matches_prefix
+ _stringappend_475_) with
+ | Some
+ (_stringappend_476_,(existT _ _stringappend_477_ _)) =>
+ returnm ((_stringappend_476_,
+ build_ex
+ _stringappend_477_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__506 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_477_ _) :=
+ w__506
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ returnm ((match (string_drop
+ _stringappend_475_
+ (build_ex
+ _stringappend_477_)) with
+ | s_ =>
+ Some (STORECON (aq,rl,rs2,rs1,size,rd),
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else
+ match (amo_mnemonic_matches_prefix
+ _stringappend_0_) with
+ | Some
+ (_stringappend_479_,(existT _ _stringappend_480_ _)) =>
+ let _stringappend_481_ :=
+ string_drop
+ _stringappend_0_
+ (build_ex
+ _stringappend_480_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_481_
+ ".")
+ : bool))
+ (let _stringappend_482_ :=
+ string_drop
+ _stringappend_481_
+ (string_length ".") in
+ match (size_mnemonic_matches_prefix
+ _stringappend_482_) with
+ | Some
+ (_stringappend_483_,(existT _ _stringappend_484_ _)) =>
+ let _stringappend_485_ :=
+ string_drop
+ _stringappend_482_
+ (build_ex
+ _stringappend_484_) in
+ match (maybe_aq_matches_prefix
+ _stringappend_485_) with
+ | Some
+ (_stringappend_486_,(existT _ _stringappend_487_ _)) =>
+ let _stringappend_488_ :=
+ string_drop
+ _stringappend_485_
+ (build_ex
+ _stringappend_487_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_488_) with
+ | Some
+ (_stringappend_489_,(existT _ _stringappend_490_ _)) =>
+ let _stringappend_491_ :=
+ string_drop
+ _stringappend_488_
+ (build_ex
+ _stringappend_490_) in
+ match (spc_matches_prefix
+ _stringappend_491_) with
+ | Some
+ (_stringappend_492_,(existT _ _stringappend_493_ _)) =>
+ let _stringappend_494_ :=
+ string_drop
+ _stringappend_491_
+ (build_ex
+ _stringappend_493_) in
+ match (reg_name_matches_prefix
+ _stringappend_494_) with
+ | Some
+ (_stringappend_495_,(existT _ _stringappend_496_ _)) =>
+ let _stringappend_497_ :=
+ string_drop
+ _stringappend_494_
+ (build_ex
+ _stringappend_496_) in
+ sep_matches_prefix
+ _stringappend_497_ >>= fun w__507 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__507 with
+ | Some
+ (_stringappend_498_,(existT _ _stringappend_499_ _)) =>
+ let _stringappend_500_ :=
+ string_drop
+ _stringappend_497_
+ (build_ex
+ _stringappend_499_) in
+ match (reg_name_matches_prefix
+ _stringappend_500_) with
+ | Some
+ (_stringappend_501_,(existT _ _stringappend_502_ _)) =>
+ let _stringappend_503_ :=
+ string_drop
+ _stringappend_500_
+ (build_ex
+ _stringappend_502_) in
+ sep_matches_prefix
+ _stringappend_503_ >>= fun w__508 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__508 with
+ | Some
+ (_stringappend_504_,(existT _ _stringappend_505_ _)) =>
+ let _stringappend_506_ :=
+ string_drop
+ _stringappend_503_
+ (build_ex
+ _stringappend_505_) in
+ if
+ ((match (reg_name_matches_prefix
+ _stringappend_506_) with
+ | Some
+ (_stringappend_507_,(existT _ _stringappend_508_ _)) =>
+ match (string_drop
+ _stringappend_506_
+ (build_ex
+ _stringappend_508_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__509 : bool =>
+ returnm ((if
+ (w__509)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__510 : bool =>
+ returnm ((if
+ (w__510)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__511 : bool =>
+ returnm ((if
+ (w__511)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__512 : bool =>
+ returnm ((if (w__512)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__513 : bool =>
+ returnm ((if (w__513)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__514 : bool =>
+ returnm ((if (w__514)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__515 : bool =>
+ returnm ((if (w__515)
+ then
+ true
+ else false)
+ : bool)) >>= fun w__516 : bool =>
+ returnm ((if (w__516)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false : bool)
+ end >>= fun w__517 : bool =>
+ (if (w__517) then
+ match (amo_mnemonic_matches_prefix
+ _stringappend_0_) with
+ | Some
+ (_stringappend_479_,(existT _ _stringappend_480_ _)) =>
+ returnm ((_stringappend_479_,
+ build_ex
+ _stringappend_480_)
+ : (amoop * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((amoop * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__519 : (amoop * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(op, existT _ _stringappend_480_ _) :=
+ w__519
+ : (amoop * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_481_ :=
+ string_drop
+ _stringappend_0_
+ (build_ex
+ _stringappend_480_) in
+ let _stringappend_482_ :=
+ string_drop
+ _stringappend_481_
+ (string_length ".") in
+ match (size_mnemonic_matches_prefix
+ _stringappend_482_) with
+ | Some
+ (_stringappend_483_,(existT _ _stringappend_484_ _)) =>
+ returnm ((_stringappend_483_,
+ build_ex
+ _stringappend_484_)
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((word_width * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__521 : (word_width * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(width, existT _ _stringappend_484_ _) :=
+ w__521
+ : (word_width * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_485_ :=
+ string_drop
+ _stringappend_482_
+ (build_ex
+ _stringappend_484_) in
+ match (maybe_aq_matches_prefix
+ _stringappend_485_) with
+ | Some
+ (_stringappend_486_,(existT _ _stringappend_487_ _)) =>
+ returnm ((_stringappend_486_,
+ build_ex
+ _stringappend_487_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__523 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(aq, existT _ _stringappend_487_ _) :=
+ w__523
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_488_ :=
+ string_drop
+ _stringappend_485_
+ (build_ex
+ _stringappend_487_) in
+ match (maybe_rl_matches_prefix
+ _stringappend_488_) with
+ | Some
+ (_stringappend_489_,(existT _ _stringappend_490_ _)) =>
+ returnm ((_stringappend_489_,
+ build_ex
+ _stringappend_490_)
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((bool * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__525 : (bool * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rl, existT _ _stringappend_490_ _) :=
+ w__525
+ : (bool * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_491_ :=
+ string_drop
+ _stringappend_488_
+ (build_ex
+ _stringappend_490_) in
+ match (spc_matches_prefix
+ _stringappend_491_) with
+ | Some
+ (_stringappend_492_,(existT _ _stringappend_493_ _)) =>
+ returnm ((_stringappend_492_,
+ build_ex
+ _stringappend_493_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__527 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_493_ _) :=
+ w__527
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_494_ :=
+ string_drop
+ _stringappend_491_
+ (build_ex
+ _stringappend_493_) in
+ match (reg_name_matches_prefix
+ _stringappend_494_) with
+ | Some
+ (_stringappend_495_,(existT _ _stringappend_496_ _)) =>
+ returnm ((_stringappend_495_,
+ build_ex
+ _stringappend_496_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__529 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_496_ _) :=
+ w__529
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_497_ :=
+ string_drop
+ _stringappend_494_
+ (build_ex
+ _stringappend_496_) in
+ sep_matches_prefix
+ _stringappend_497_ >>= fun w__530 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__530 with
+ | Some
+ (_stringappend_498_,(existT _ _stringappend_499_ _)) =>
+ returnm ((_stringappend_498_,
+ build_ex
+ _stringappend_499_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__532 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_499_ _) :=
+ w__532
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_500_ :=
+ string_drop
+ _stringappend_497_
+ (build_ex
+ _stringappend_499_) in
+ match (reg_name_matches_prefix
+ _stringappend_500_) with
+ | Some
+ (_stringappend_501_,(existT _ _stringappend_502_ _)) =>
+ returnm ((_stringappend_501_,
+ build_ex
+ _stringappend_502_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__534 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_502_ _) :=
+ w__534
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_503_ :=
+ string_drop
+ _stringappend_500_
+ (build_ex
+ _stringappend_502_) in
+ sep_matches_prefix
+ _stringappend_503_ >>= fun w__535 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__535 with
+ | Some
+ (_stringappend_504_,(existT _ _stringappend_505_ _)) =>
+ returnm ((_stringappend_504_,
+ build_ex
+ _stringappend_505_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__537 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_505_ _) :=
+ w__537
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_506_ :=
+ string_drop
+ _stringappend_503_
+ (build_ex
+ _stringappend_505_) in
+ match (reg_name_matches_prefix
+ _stringappend_506_) with
+ | Some
+ (_stringappend_507_,(existT _ _stringappend_508_ _)) =>
+ returnm ((_stringappend_507_,
+ build_ex
+ _stringappend_508_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__539 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs2, existT _ _stringappend_508_ _) :=
+ w__539
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ returnm ((match (string_drop
+ _stringappend_506_
+ (build_ex
+ _stringappend_508_)) with
+ | s_ =>
+ Some (AMO (op,aq,rl,rs2,rs1,width,rd),
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else
+ match (csr_mnemonic_matches_prefix
+ _stringappend_0_) with
+ | Some
+ (_stringappend_510_,(existT _ _stringappend_511_ _)) =>
+ let _stringappend_512_ :=
+ string_drop
+ _stringappend_0_
+ (build_ex
+ _stringappend_511_) in
+ and_boolM
+ (returnm ((string_startswith
+ _stringappend_512_
+ "i")
+ : bool))
+ (let _stringappend_513_ :=
+ string_drop
+ _stringappend_512_
+ (string_length
+ "i") in
+ match (spc_matches_prefix
+ _stringappend_513_) with
+ | Some
+ (_stringappend_514_,(existT _ _stringappend_515_ _)) =>
+ let _stringappend_516_ :=
+ string_drop
+ _stringappend_513_
+ (build_ex
+ _stringappend_515_) in
+ match (reg_name_matches_prefix
+ _stringappend_516_) with
+ | Some
+ (_stringappend_517_,(existT _ _stringappend_518_ _)) =>
+ let _stringappend_519_ :=
+ string_drop
+ _stringappend_516_
+ (build_ex
+ _stringappend_518_) in
+ sep_matches_prefix
+ _stringappend_519_ >>= fun w__540 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__540 with
+ | Some
+ (_stringappend_520_,(existT _ _stringappend_521_ _)) =>
+ let _stringappend_522_ :=
+ string_drop
+ _stringappend_519_
+ (build_ex
+ _stringappend_521_) in
+ match (hex_bits_5_matches_prefix
+ _stringappend_522_) with
+ | Some
+ (_stringappend_523_,(existT _ _stringappend_524_ _)) =>
+ let _stringappend_525_ :=
+ string_drop
+ _stringappend_522_
+ (build_ex
+ _stringappend_524_) in
+ sep_matches_prefix
+ _stringappend_525_ >>= fun w__541 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__541 with
+ | Some
+ (_stringappend_526_,(existT _ _stringappend_527_ _)) =>
+ let _stringappend_528_ :=
+ string_drop
+ _stringappend_525_
+ (build_ex
+ _stringappend_527_) in
+ if
+ ((match (csr_name_map_matches_prefix
+ _stringappend_528_) with
+ | Some
+ (_stringappend_529_,(existT _ _stringappend_530_ _)) =>
+ match (string_drop
+ _stringappend_528_
+ (build_ex
+ _stringappend_530_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__542 : bool =>
+ returnm ((if
+ (w__542)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__543 : bool =>
+ returnm ((if (w__543)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__544 : bool =>
+ returnm ((if (w__544)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__545 : bool =>
+ returnm ((if (w__545)
+ then
+ true
+ else false)
+ : bool)) >>= fun w__546 : bool =>
+ returnm ((if (w__546)
+ then
+ true
+ else false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__547 : bool =>
+ (if (w__547) then
+ match (csr_mnemonic_matches_prefix
+ _stringappend_0_) with
+ | Some
+ (_stringappend_510_,(existT _ _stringappend_511_ _)) =>
+ returnm ((_stringappend_510_,
+ build_ex
+ _stringappend_511_)
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__549 : (csrop * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(op, existT _ _stringappend_511_ _) :=
+ w__549
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_512_ :=
+ string_drop
+ _stringappend_0_
+ (build_ex
+ _stringappend_511_) in
+ let _stringappend_513_ :=
+ string_drop
+ _stringappend_512_
+ (string_length "i") in
+ match (spc_matches_prefix
+ _stringappend_513_) with
+ | Some
+ (_stringappend_514_,(existT _ _stringappend_515_ _)) =>
+ returnm ((_stringappend_514_,
+ build_ex
+ _stringappend_515_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__551 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_515_ _) :=
+ w__551
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_516_ :=
+ string_drop
+ _stringappend_513_
+ (build_ex
+ _stringappend_515_) in
+ match (reg_name_matches_prefix
+ _stringappend_516_) with
+ | Some
+ (_stringappend_517_,(existT _ _stringappend_518_ _)) =>
+ returnm ((_stringappend_517_,
+ build_ex
+ _stringappend_518_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__553 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_518_ _) :=
+ w__553
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_519_ :=
+ string_drop
+ _stringappend_516_
+ (build_ex
+ _stringappend_518_) in
+ sep_matches_prefix
+ _stringappend_519_ >>= fun w__554 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__554 with
+ | Some
+ (_stringappend_520_,(existT _ _stringappend_521_ _)) =>
+ returnm ((_stringappend_520_,
+ build_ex
+ _stringappend_521_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__556 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_521_ _) :=
+ w__556
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_522_ :=
+ string_drop
+ _stringappend_519_
+ (build_ex
+ _stringappend_521_) in
+ match (hex_bits_5_matches_prefix
+ _stringappend_522_) with
+ | Some
+ (_stringappend_523_,(existT _ _stringappend_524_ _)) =>
+ returnm ((_stringappend_523_,
+ build_ex
+ _stringappend_524_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__558 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_524_ _) :=
+ w__558
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_525_ :=
+ string_drop
+ _stringappend_522_
+ (build_ex
+ _stringappend_524_) in
+ sep_matches_prefix
+ _stringappend_525_ >>= fun w__559 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__559 with
+ | Some
+ (_stringappend_526_,(existT _ _stringappend_527_ _)) =>
+ returnm ((_stringappend_526_,
+ build_ex
+ _stringappend_527_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__561 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_527_ _) :=
+ w__561
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_528_ :=
+ string_drop
+ _stringappend_525_
+ (build_ex
+ _stringappend_527_) in
+ match (csr_name_map_matches_prefix
+ _stringappend_528_) with
+ | Some
+ (_stringappend_529_,(existT _ _stringappend_530_ _)) =>
+ returnm ((_stringappend_529_,
+ build_ex
+ _stringappend_530_)
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__563 : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(csr, existT _ _stringappend_530_ _) :=
+ w__563
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) in
+ returnm ((match (string_drop
+ _stringappend_528_
+ (build_ex
+ _stringappend_530_)) with
+ | s_ =>
+ Some (CSR (csr,rs1,rd,true,op),
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else
+ match (csr_mnemonic_matches_prefix
+ _stringappend_0_) with
+ | Some
+ (_stringappend_532_,(existT _ _stringappend_533_ _)) =>
+ let _stringappend_534_ :=
+ string_drop
+ _stringappend_0_
+ (build_ex
+ _stringappend_533_) in
+ match (spc_matches_prefix
+ _stringappend_534_) with
+ | Some
+ (_stringappend_535_,(existT _ _stringappend_536_ _)) =>
+ let _stringappend_537_ :=
+ string_drop
+ _stringappend_534_
+ (build_ex
+ _stringappend_536_) in
+ match (reg_name_matches_prefix
+ _stringappend_537_) with
+ | Some
+ (_stringappend_538_,(existT _ _stringappend_539_ _)) =>
+ let _stringappend_540_ :=
+ string_drop
+ _stringappend_537_
+ (build_ex
+ _stringappend_539_) in
+ sep_matches_prefix
+ _stringappend_540_ >>= fun w__564 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__564 with
+ | Some
+ (_stringappend_541_,(existT _ _stringappend_542_ _)) =>
+ let _stringappend_543_ :=
+ string_drop
+ _stringappend_540_
+ (build_ex
+ _stringappend_542_) in
+ match (reg_name_matches_prefix
+ _stringappend_543_) with
+ | Some
+ (_stringappend_544_,(existT _ _stringappend_545_ _)) =>
+ let _stringappend_546_ :=
+ string_drop
+ _stringappend_543_
+ (build_ex
+ _stringappend_545_) in
+ sep_matches_prefix
+ _stringappend_546_ >>= fun w__565 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ returnm ((if
+ ((match w__565 with
+ | Some
+ (_stringappend_547_,(existT _ _stringappend_548_ _)) =>
+ let _stringappend_549_ :=
+ string_drop
+ _stringappend_546_
+ (build_ex
+ _stringappend_548_) in
+ if
+ ((match (csr_name_map_matches_prefix
+ _stringappend_549_) with
+ | Some
+ (_stringappend_550_,(existT _ _stringappend_551_ _)) =>
+ match (string_drop
+ _stringappend_549_
+ (build_ex
+ _stringappend_551_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__566 : bool =>
+ returnm ((if
+ (w__566)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__567 : bool =>
+ returnm ((if (w__567)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__568 : bool =>
+ returnm ((if (w__568)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__569 : bool =>
+ returnm ((if (w__569)
+ then
+ true
+ else
+ false)
+ : bool)
+ | None =>
+ returnm (false
+ : bool)
+ end >>= fun w__570 : bool =>
+ (if (w__570) then
+ match (csr_mnemonic_matches_prefix
+ _stringappend_0_) with
+ | Some
+ (_stringappend_532_,(existT _ _stringappend_533_ _)) =>
+ returnm ((_stringappend_532_,
+ build_ex
+ _stringappend_533_)
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((csrop * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__572 : (csrop * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(op, existT _ _stringappend_533_ _) :=
+ w__572
+ : (csrop * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_534_ :=
+ string_drop
+ _stringappend_0_
+ (build_ex
+ _stringappend_533_) in
+ match (spc_matches_prefix
+ _stringappend_534_) with
+ | Some
+ (_stringappend_535_,(existT _ _stringappend_536_ _)) =>
+ returnm ((_stringappend_535_,
+ build_ex
+ _stringappend_536_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__574 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_536_ _) :=
+ w__574
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_537_ :=
+ string_drop
+ _stringappend_534_
+ (build_ex
+ _stringappend_536_) in
+ match (reg_name_matches_prefix
+ _stringappend_537_) with
+ | Some
+ (_stringappend_538_,(existT _ _stringappend_539_ _)) =>
+ returnm ((_stringappend_538_,
+ build_ex
+ _stringappend_539_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__576 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rd, existT _ _stringappend_539_ _) :=
+ w__576
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_540_ :=
+ string_drop
+ _stringappend_537_
+ (build_ex
+ _stringappend_539_) in
+ sep_matches_prefix
+ _stringappend_540_ >>= fun w__577 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__577 with
+ | Some
+ (_stringappend_541_,(existT _ _stringappend_542_ _)) =>
+ returnm ((_stringappend_541_,
+ build_ex
+ _stringappend_542_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__579 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_542_ _) :=
+ w__579
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_543_ :=
+ string_drop
+ _stringappend_540_
+ (build_ex
+ _stringappend_542_) in
+ match (reg_name_matches_prefix
+ _stringappend_543_) with
+ | Some
+ (_stringappend_544_,(existT _ _stringappend_545_ _)) =>
+ returnm ((_stringappend_544_,
+ build_ex
+ _stringappend_545_)
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 5 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__581 : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(rs1, existT _ _stringappend_545_ _) :=
+ w__581
+ : (mword 5 * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_546_ :=
+ string_drop
+ _stringappend_543_
+ (build_ex
+ _stringappend_545_) in
+ sep_matches_prefix
+ _stringappend_546_ >>= fun w__582 : option ((unit * {n : Z & ArithFact (n >=
+ 0)})) =>
+ match w__582 with
+ | Some
+ (_stringappend_547_,(existT _ _stringappend_548_ _)) =>
+ returnm ((_stringappend_547_,
+ build_ex
+ _stringappend_548_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__584 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_548_ _) :=
+ w__584
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_549_ :=
+ string_drop
+ _stringappend_546_
+ (build_ex
+ _stringappend_548_) in
+ match (csr_name_map_matches_prefix
+ _stringappend_549_) with
+ | Some
+ (_stringappend_550_,(existT _ _stringappend_551_ _)) =>
+ returnm ((_stringappend_550_,
+ build_ex
+ _stringappend_551_)
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 12 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__586 : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(csr, existT _ _stringappend_551_ _) :=
+ w__586
+ : (mword 12 * {n : Z & ArithFact (n >=
+ 0)}) in
+ returnm ((match (string_drop
+ _stringappend_549_
+ (build_ex
+ _stringappend_551_)) with
+ | s_ =>
+ Some (CSR (csr,rs1,rd,false,op),
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else if ((andb
+ (string_startswith
+ _stringappend_0_
+ "illegal")
+ (let _stringappend_553_ :=
+ string_drop
+ _stringappend_0_
+ (string_length
+ "illegal") in
+ if ((match (spc_matches_prefix
+ _stringappend_553_) with
+ | Some
+ (_stringappend_554_,(existT _ _stringappend_555_ _)) =>
+ let _stringappend_556_ :=
+ string_drop
+ _stringappend_553_
+ (build_ex
+ _stringappend_555_) in
+ if
+ ((match (hex_bits_32_matches_prefix
+ _stringappend_556_) with
+ | Some
+ (_stringappend_557_,(existT _ _stringappend_558_ _)) =>
+ match (string_drop
+ _stringappend_556_
+ (build_ex
+ _stringappend_558_)) with
+ | s_ =>
+ true
+ end
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false
+ | None =>
+ false
+ end))
+ then
+ true
+ else
+ false)))
+ then
+ let _stringappend_553_ :=
+ string_drop
+ _stringappend_0_
+ (string_length
+ "illegal") in
+ match (spc_matches_prefix
+ _stringappend_553_) with
+ | Some
+ (_stringappend_554_,(existT _ _stringappend_555_ _)) =>
+ returnm ((_stringappend_554_,
+ build_ex
+ _stringappend_555_)
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((unit * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__588 : (unit * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(tt, existT _ _stringappend_555_ _) :=
+ w__588
+ : (unit * {n : Z & ArithFact (n >=
+ 0)}) in
+ let _stringappend_556_ :=
+ string_drop
+ _stringappend_553_
+ (build_ex
+ _stringappend_555_) in
+ match (hex_bits_32_matches_prefix
+ _stringappend_556_) with
+ | Some
+ (_stringappend_557_,(existT _ _stringappend_558_ _)) =>
+ returnm ((_stringappend_557_,
+ build_ex
+ _stringappend_558_)
+ : (mword 32 * {n : Z & ArithFact (n >=
+ 0)}))
+ | _ =>
+ exit tt
+ : M ((mword 32 * {n : Z & ArithFact (n >=
+ 0)}))
+ end >>= fun w__590 : (mword 32 * {n : Z & ArithFact (n >=
+ 0)}) =>
+ let '(s, existT _ _stringappend_558_ _) :=
+ w__590
+ : (mword 32 * {n : Z & ArithFact (n >=
+ 0)}) in
+ returnm ((match (string_drop
+ _stringappend_556_
+ (build_ex
+ _stringappend_558_)) with
+ | s_ =>
+ Some (ILLEGAL s,
+ sub_nat
+ (string_length
+ arg_)
+ (string_length
+ s_))
+ end)
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)})))
+ else
+ returnm (None
+ : option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >=
+ 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))))
+ : M (option ((ast * {n : Z & ArithFact (n >= 0)}))).
+*)
+Definition encdec_forwards (arg_ : ast)
+: M (mword 32) :=
+ (match arg_ with
+ | UTYPE (imm,rd,op) =>
+ returnm ((concat_vec (imm : mword 20) (concat_vec (rd : mword 5) (encdec_uop_forwards op)))
+ : mword 32)
+ | RISCV_JAL (v__172,rd) =>
+ let imm_19 : bits 1 := subrange_vec_dec v__172 20 20 in
+ let imm_7_0 : bits 8 := subrange_vec_dec v__172 19 12 in
+ let imm_8 : bits 1 := subrange_vec_dec v__172 11 11 in
+ let imm_18_13 : bits 6 := subrange_vec_dec v__172 10 5 in
+ let imm_12_9 : bits 4 := subrange_vec_dec v__172 4 1 in
+ returnm ((concat_vec (imm_19 : bits 1)
+ (concat_vec (imm_18_13 : bits 6)
+ (concat_vec (imm_12_9 : bits 4)
+ (concat_vec (imm_8 : bits 1)
+ (concat_vec (imm_7_0 : bits 8)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B1;B1;B0;B1;B1;B1;B1] : mword 7)))))))
+ : mword 32)
+ | RISCV_JALR (imm,rs1,rd) =>
+ returnm ((concat_vec (imm : mword 12)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (rd : mword 5) (vec_of_bits [B1;B1;B0;B0;B1;B1;B1] : mword 7)))))
+ : mword 32)
+ | BTYPE (v__173,rs2,rs1,op) =>
+ let imm7_6 : bits 1 := subrange_vec_dec v__173 12 12 in
+ let imm5_0 : bits 1 := subrange_vec_dec v__173 11 11 in
+ let imm7_5_0 : bits 6 := subrange_vec_dec v__173 10 5 in
+ let imm5_4_1 : bits 4 := subrange_vec_dec v__173 4 1 in
+ returnm ((concat_vec (imm7_6 : bits 1)
+ (concat_vec (imm7_5_0 : bits 6)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (encdec_bop_forwards op)
+ (concat_vec (imm5_4_1 : bits 4)
+ (concat_vec (imm5_0 : bits 1)
+ (vec_of_bits [B1;B1;B0;B0;B0;B1;B1] : mword 7))))))))
+ : mword 32)
+ | ITYPE (imm,rs1,rd,op) =>
+ returnm ((concat_vec (imm : mword 12)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (encdec_iop_forwards op)
+ (concat_vec (rd : mword 5) (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7)))))
+ : mword 32)
+ | SHIFTIOP (shamt,rs1,rd,RISCV_SLLI) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6)
+ (concat_vec (shamt : mword 6)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | SHIFTIOP (shamt,rs1,rd,RISCV_SRLI) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6)
+ (concat_vec (shamt : mword 6)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | SHIFTIOP (shamt,rs1,rd,RISCV_SRAI) =>
+ returnm ((concat_vec (vec_of_bits [B0;B1;B0;B0;B0;B0] : mword 6)
+ (concat_vec (shamt : mword 6)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_ADD) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_SUB) =>
+ returnm ((concat_vec (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_SLL) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_SLT) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B1;B0] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_SLTU) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B1;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_XOR) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B0] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_SRL) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_SRA) =>
+ returnm ((concat_vec (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_OR) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B1;B0] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPE (rs2,rs1,rd,RISCV_AND) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B1;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | LOAD (imm,rs1,rd,is_unsigned,size,false,false) =>
+ returnm ((concat_vec (imm : mword 12)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (bool_bits_forwards is_unsigned)
+ (concat_vec (size_bits_forwards size)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B0;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | STORE (v__174,rs2,rs1,size,false,false) =>
+ let imm7 : bits 7 := subrange_vec_dec v__174 11 5 in
+ let imm5 : bits 5 := subrange_vec_dec v__174 4 0 in
+ returnm ((concat_vec (imm7 : bits 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0] : mword 1)
+ (concat_vec (size_bits_forwards size)
+ (concat_vec (imm5 : bits 5)
+ (vec_of_bits [B0;B1;B0;B0;B0;B1;B1] : mword 7)))))))
+ : mword 32)
+ | ADDIW (imm,rs1,rd) =>
+ returnm ((concat_vec (imm : mword 12)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (rd : mword 5) (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7)))))
+ : mword 32)
+ | SHIFTW (shamt,rs1,rd,RISCV_SLLI) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (shamt : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | SHIFTW (shamt,rs1,rd,RISCV_SRLI) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (shamt : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | SHIFTW (shamt,rs1,rd,RISCV_SRAI) =>
+ returnm ((concat_vec (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (shamt : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPEW (rs2,rs1,rd,RISCV_ADDW) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPEW (rs2,rs1,rd,RISCV_SUBW) =>
+ returnm ((concat_vec (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPEW (rs2,rs1,rd,RISCV_SLLW) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPEW (rs2,rs1,rd,RISCV_SRLW) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | RTYPEW (rs2,rs1,rd,RISCV_SRAW) =>
+ returnm ((concat_vec (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | SHIFTIWOP (shamt,rs1,rd,RISCV_SLLIW) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (shamt : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | SHIFTIWOP (shamt,rs1,rd,RISCV_SRLIW) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (shamt : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | SHIFTIWOP (shamt,rs1,rd,RISCV_SRAIW) =>
+ returnm ((concat_vec (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)
+ (concat_vec (shamt : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0;B1] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | MUL (rs2,rs1,rd,high,signed1,signed2) =>
+ encdec_mul_op_forwards high signed1 signed2 >>= fun w__0 : bits 3 =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (w__0 : bits 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | DIV (rs2,rs1,rd,s) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0] : mword 2)
+ (concat_vec (bool_not_bits_forwards s)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7)))))))
+ : mword 32)
+ | REM (rs2,rs1,rd,s) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B1] : mword 2)
+ (concat_vec (bool_not_bits_forwards s)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7)))))))
+ : mword 32)
+ | MULW (rs2,rs1,rd) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | DIVW (rs2,rs1,rd,s) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B0] : mword 2)
+ (concat_vec (bool_not_bits_forwards s)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7)))))))
+ : mword 32)
+ | REMW (rs2,rs1,rd,s) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B1;B1] : mword 2)
+ (concat_vec (bool_not_bits_forwards s)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7)))))))
+ : mword 32)
+ | FENCE (pred,succ) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0] : mword 4)
+ (concat_vec (pred : mword 4)
+ (concat_vec (succ : mword 4)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (vec_of_bits [B0;B0;B0;B1;B1;B1;B1] : mword 7)))))))
+ : mword 32)
+ | FENCEI (tt) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B1] : mword 3)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (vec_of_bits [B0;B0;B0;B1;B1;B1;B1] : mword 7)))))
+ : mword 32)
+ | ECALL (tt) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7)))))
+ : mword 32)
+ | MRET (tt) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B1;B1;B0;B0;B0] : mword 7)
+ (concat_vec (vec_of_bits [B0;B0;B0;B1;B0] : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | SRET (tt) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B1;B0;B0;B0] : mword 7)
+ (concat_vec (vec_of_bits [B0;B0;B0;B1;B0] : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | EBREAK (tt) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7)))))
+ : mword 32)
+ | WFI (tt) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7)))))
+ : mword 32)
+ | SFENCE_VMA (rs1,rs2) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B1;B0;B0;B1] : mword 7)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0;B0;B0] : mword 3)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | LOADRES (aq,rl,rs1,size,rd) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B1;B0] : mword 5)
+ (concat_vec (bool_bits_forwards aq)
+ (concat_vec (bool_bits_forwards rl)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0] : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0] : mword 1)
+ (concat_vec (size_bits_forwards size)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B0;B1;B1;B1;B1] : mword 7)))))))))
+ : mword 32)
+ | STORECON (aq,rl,rs2,rs1,size,rd) =>
+ returnm ((concat_vec (vec_of_bits [B0;B0;B0;B1;B1] : mword 5)
+ (concat_vec (bool_bits_forwards aq)
+ (concat_vec (bool_bits_forwards rl)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0] : mword 1)
+ (concat_vec (size_bits_forwards size)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B0;B1;B1;B1;B1] : mword 7)))))))))
+ : mword 32)
+ | AMO (op,aq,rl,rs2,rs1,size,rd) =>
+ returnm ((concat_vec (encdec_amoop_forwards op)
+ (concat_vec (bool_bits_forwards aq)
+ (concat_vec (bool_bits_forwards rl)
+ (concat_vec (rs2 : mword 5)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (vec_of_bits [B0] : mword 1)
+ (concat_vec (size_bits_forwards size)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B0;B1;B0;B1;B1;B1;B1] : mword 7)))))))))
+ : mword 32)
+ | CSR (csr,rs1,rd,is_imm,op) =>
+ returnm ((concat_vec (csr : mword 12)
+ (concat_vec (rs1 : mword 5)
+ (concat_vec (bool_bits_forwards is_imm)
+ (concat_vec (encdec_csrop_forwards op)
+ (concat_vec (rd : mword 5)
+ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))))))
+ : mword 32)
+ | STOP_FETCHING (tt) =>
+ returnm ((concat_vec
+ (vec_of_bits [B1;B1;B1;B1;B1;B0;B1;B0;B1;B1;B0;B1;B1;B1;B1;B0] : mword 16)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0] : mword 8)
+ (concat_vec (vec_of_bits [B0] : mword 1)
+ (concat_vec (vec_of_bits [B0;B0] : mword 2)
+ (concat_vec (vec_of_bits [B0;B1;B0] : mword 3)
+ (vec_of_bits [B1;B1] : mword 2))))))
+ : mword 32)
+ | THREAD_START (tt) =>
+ returnm ((concat_vec
+ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B1;B1;B0;B1;B1;B1;B1;B0] : mword 16)
+ (concat_vec (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0] : mword 8)
+ (concat_vec (vec_of_bits [B0] : mword 1)
+ (concat_vec (vec_of_bits [B0;B0] : mword 2)
+ (concat_vec (vec_of_bits [B0;B1;B0] : mword 3)
+ (vec_of_bits [B1;B1] : mword 2))))))
+ : mword 32)
+ | ILLEGAL (s) => returnm (s : mword 32)
+ | _ => exit tt : M (mword 32)
+ end)
+ : M (mword 32).
+
+Definition encdec_backwards (arg_ : mword 32)
+: ast :=
+ let v__175 := arg_ in
+ if ((let _mappingpatterns_23_ := subrange_vec_dec v__175 6 0 in
+ encdec_uop_backwards_matches _mappingpatterns_23_)) then
+ let imm : mword 20 := subrange_vec_dec v__175 31 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let _mappingpatterns_23_ := subrange_vec_dec v__175 6 0 in
+ let op := encdec_uop_backwards _mappingpatterns_23_ in
+ UTYPE (imm,rd,op)
+ else if ((let p0_ := subrange_vec_dec v__175 6 0 in
+ eq_vec p0_ (vec_of_bits [B1;B1;B0;B1;B1;B1;B1] : mword 7))) then
+ let imm_19 : bits 1 := subrange_vec_dec v__175 31 31 in
+ let imm_18_13 : bits 6 := subrange_vec_dec v__175 30 25 in
+ let imm_12_9 : bits 4 := subrange_vec_dec v__175 24 21 in
+ let imm_8 : bits 1 := subrange_vec_dec v__175 20 20 in
+ let imm_7_0 : bits 8 := subrange_vec_dec v__175 19 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RISCV_JAL (concat_vec (imm_19 : bits 1)
+ (concat_vec (imm_7_0 : bits 8)
+ (concat_vec (imm_8 : bits 1)
+ (concat_vec (imm_18_13 : bits 6)
+ (concat_vec (imm_12_9 : bits 4) (vec_of_bits [B0] : mword 1))))),rd)
+ else if ((let p0_ := subrange_vec_dec v__175 14 12 in
+ let p1_ := subrange_vec_dec v__175 6 0 in
+ andb (eq_vec p1_ (vec_of_bits [B1;B1;B0;B0;B1;B1;B1] : mword 7))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3)))) then
+ let imm : mword 12 := subrange_vec_dec v__175 31 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RISCV_JALR (imm,rs1,rd)
+ else if ((let _mappingpatterns_24_ := subrange_vec_dec v__175 14 12 in
+ let p0_ := subrange_vec_dec v__175 6 0 in
+ andb (encdec_bop_backwards_matches _mappingpatterns_24_)
+ (eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B1;B1] : mword 7)))) then
+ let imm7_6 : bits 1 := subrange_vec_dec v__175 31 31 in
+ let imm7_5_0 : bits 6 := subrange_vec_dec v__175 30 25 in
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_24_ := subrange_vec_dec v__175 14 12 in
+ let imm5_4_1 : bits 4 := subrange_vec_dec v__175 11 8 in
+ let imm5_0 : bits 1 := subrange_vec_dec v__175 7 7 in
+ let op := encdec_bop_backwards _mappingpatterns_24_ in
+ BTYPE (concat_vec (imm7_6 : bits 1)
+ (concat_vec (imm5_0 : bits 1)
+ (concat_vec (imm7_5_0 : bits 6)
+ (concat_vec (imm5_4_1 : bits 4) (vec_of_bits [B0] : mword 1)))),rs2,rs1,op)
+ else if ((let _mappingpatterns_25_ := subrange_vec_dec v__175 14 12 in
+ let p0_ := subrange_vec_dec v__175 6 0 in
+ andb (encdec_iop_backwards_matches _mappingpatterns_25_)
+ (eq_vec p0_ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7)))) then
+ let imm : mword 12 := subrange_vec_dec v__175 31 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_25_ := subrange_vec_dec v__175 14 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let op := encdec_iop_backwards _mappingpatterns_25_ in
+ ITYPE (imm,rs1,rd,op)
+ else if ((let p0_ := subrange_vec_dec v__175 31 26 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6)))) then
+ let shamt : mword 6 := subrange_vec_dec v__175 25 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ SHIFTIOP (shamt,rs1,rd,RISCV_SLLI)
+ else if ((let p0_ := subrange_vec_dec v__175 31 26 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6)))) then
+ let shamt : mword 6 := subrange_vec_dec v__175 25 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ SHIFTIOP (shamt,rs1,rd,RISCV_SRLI)
+ else if ((let p0_ := subrange_vec_dec v__175 31 26 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0] : mword 6)))) then
+ let shamt : mword 6 := subrange_vec_dec v__175 25 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ SHIFTIOP (shamt,rs1,rd,RISCV_SRAI)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_ADD)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_SUB)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_SLL)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B1;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_SLT)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B1;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_SLTU)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_XOR)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_SRL)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_SRA)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B1;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_OR)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B1;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPE (rs2,rs1,rd,RISCV_AND)
+ else if ((let _mappingpatterns_26_ := subrange_vec_dec v__175 14 14 in
+ let _mappingpatterns_27_ := subrange_vec_dec v__175 13 12 in
+ let p0_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (size_bits_backwards_matches _mappingpatterns_27_)
+ (bool_bits_backwards_matches _mappingpatterns_26_))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B1] : mword 7)))) then
+ let imm : mword 12 := subrange_vec_dec v__175 31 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_26_ := subrange_vec_dec v__175 14 14 in
+ let _mappingpatterns_27_ := subrange_vec_dec v__175 13 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let size := size_bits_backwards _mappingpatterns_27_ in
+ let is_unsigned := bool_bits_backwards _mappingpatterns_26_ in
+ LOAD (imm,rs1,rd,is_unsigned,size,false,false)
+ else if ((let p0_ := subrange_vec_dec v__175 14 14 in
+ let _mappingpatterns_28_ := subrange_vec_dec v__175 13 12 in
+ let p1_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (size_bits_backwards_matches _mappingpatterns_28_)
+ (eq_vec p1_ (vec_of_bits [B0;B1;B0;B0;B0;B1;B1] : mword 7)))
+ (eq_vec p0_ (vec_of_bits [B0] : mword 1)))) then
+ let imm7 : bits 7 := subrange_vec_dec v__175 31 25 in
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_28_ := subrange_vec_dec v__175 13 12 in
+ let imm5 : bits 5 := subrange_vec_dec v__175 11 7 in
+ let size := size_bits_backwards _mappingpatterns_28_ in
+ STORE (concat_vec (imm7 : bits 7) (imm5 : bits 5),rs2,rs1,size,false,false)
+ else if ((let p0_ := subrange_vec_dec v__175 14 12 in
+ let p1_ := subrange_vec_dec v__175 6 0 in
+ andb (eq_vec p1_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3)))) then
+ let imm : mword 12 := subrange_vec_dec v__175 31 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ ADDIW (imm,rs1,rd)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let shamt : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ SHIFTW (shamt,rs1,rd,RISCV_SLLI)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let shamt : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ SHIFTW (shamt,rs1,rd,RISCV_SRLI)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ let shamt : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ SHIFTW (shamt,rs1,rd,RISCV_SRAI)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPEW (rs2,rs1,rd,RISCV_ADDW)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPEW (rs2,rs1,rd,RISCV_SUBW)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPEW (rs2,rs1,rd,RISCV_SLLW)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPEW (rs2,rs1,rd,RISCV_SRLW)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ RTYPEW (rs2,rs1,rd,RISCV_SRAW)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let shamt : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ SHIFTIWOP (shamt,rs1,rd,RISCV_SLLIW)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ let shamt : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ SHIFTIWOP (shamt,rs1,rd,RISCV_SRLIW)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ let shamt : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ SHIFTIWOP (shamt,rs1,rd,RISCV_SRAIW)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let _mappingpatterns_29_ : bits 3 := subrange_vec_dec v__175 14 12 in
+ let p1_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (encdec_mul_op_backwards_matches _mappingpatterns_29_)
+ (eq_vec p1_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_29_ : bits 3 := subrange_vec_dec v__175 14 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let '(high, signed1, signed2) := encdec_mul_op_backwards _mappingpatterns_29_ in
+ MUL (rs2,rs1,rd,high,signed1,signed2)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 13 in
+ let _mappingpatterns_30_ := subrange_vec_dec v__175 12 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb (bool_not_bits_backwards_matches _mappingpatterns_30_)
+ (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B1;B0] : mword 2)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_30_ := subrange_vec_dec v__175 12 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let s := bool_not_bits_backwards _mappingpatterns_30_ in
+ DIV (rs2,rs1,rd,s)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 13 in
+ let _mappingpatterns_31_ := subrange_vec_dec v__175 12 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb (bool_not_bits_backwards_matches _mappingpatterns_31_)
+ (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B1;B1] : mword 2)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_31_ := subrange_vec_dec v__175 12 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let s := bool_not_bits_backwards _mappingpatterns_31_ in
+ REM (rs2,rs1,rd,s)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ MULW (rs2,rs1,rd)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 13 in
+ let _mappingpatterns_32_ := subrange_vec_dec v__175 12 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb (bool_not_bits_backwards_matches _mappingpatterns_32_)
+ (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B1;B0] : mword 2)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_32_ := subrange_vec_dec v__175 12 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let s := bool_not_bits_backwards _mappingpatterns_32_ in
+ DIVW (rs2,rs1,rd,s)
+ else if ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 13 in
+ let _mappingpatterns_33_ := subrange_vec_dec v__175 12 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb (bool_not_bits_backwards_matches _mappingpatterns_33_)
+ (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B1;B1] : mword 2)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_33_ := subrange_vec_dec v__175 12 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let s := bool_not_bits_backwards _mappingpatterns_33_ in
+ REMW (rs2,rs1,rd,s)
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 28 in
+ let p1_ := subrange_vec_dec v__175 19 15 in
+ let p2_ := subrange_vec_dec v__175 14 12 in
+ let p3_ := subrange_vec_dec v__175 11 7 in
+ let p4_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B0;B0;B0;B1;B1;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0] : mword 4)))) then
+ let pred : mword 4 := subrange_vec_dec v__175 27 24 in
+ let succ : mword 4 := subrange_vec_dec v__175 23 20 in
+ FENCE (pred,succ)
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 20 in
+ let p1_ := subrange_vec_dec v__175 19 15 in
+ let p2_ := subrange_vec_dec v__175 14 12 in
+ let p3_ := subrange_vec_dec v__175 11 7 in
+ let p4_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B0;B0;B0;B1;B1;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12)))) then
+ FENCEI tt
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 20 in
+ let p1_ := subrange_vec_dec v__175 19 15 in
+ let p2_ := subrange_vec_dec v__175 14 12 in
+ let p3_ := subrange_vec_dec v__175 11 7 in
+ let p4_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12)))) then
+ ECALL tt
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 24 20 in
+ let p2_ := subrange_vec_dec v__175 19 15 in
+ let p3_ := subrange_vec_dec v__175 14 12 in
+ let p4_ := subrange_vec_dec v__175 11 7 in
+ let p5_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (eq_vec p5_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p4_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p3_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p2_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0] : mword 7)))) then
+ MRET tt
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 24 20 in
+ let p2_ := subrange_vec_dec v__175 19 15 in
+ let p3_ := subrange_vec_dec v__175 14 12 in
+ let p4_ := subrange_vec_dec v__175 11 7 in
+ let p5_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (eq_vec p5_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p4_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p3_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p2_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0] : mword 7)))) then
+ SRET tt
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 20 in
+ let p1_ := subrange_vec_dec v__175 19 15 in
+ let p2_ := subrange_vec_dec v__175 14 12 in
+ let p3_ := subrange_vec_dec v__175 11 7 in
+ let p4_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12)))) then
+ EBREAK tt
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 20 in
+ let p1_ := subrange_vec_dec v__175 19 15 in
+ let p2_ := subrange_vec_dec v__175 14 12 in
+ let p3_ := subrange_vec_dec v__175 11 7 in
+ let p4_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12)))) then
+ WFI tt
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 25 in
+ let p1_ := subrange_vec_dec v__175 14 12 in
+ let p2_ := subrange_vec_dec v__175 11 7 in
+ let p3_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb (eq_vec p3_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p2_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B1] : mword 7)))) then
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ SFENCE_VMA (rs1,rs2)
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 27 in
+ let _mappingpatterns_34_ := subrange_vec_dec v__175 26 26 in
+ let _mappingpatterns_35_ := subrange_vec_dec v__175 25 25 in
+ let p1_ := subrange_vec_dec v__175 24 20 in
+ let p2_ := subrange_vec_dec v__175 14 14 in
+ let _mappingpatterns_36_ := subrange_vec_dec v__175 13 12 in
+ let p3_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb
+ (andb (size_bits_backwards_matches _mappingpatterns_36_)
+ (bool_bits_backwards_matches _mappingpatterns_35_))
+ (bool_bits_backwards_matches _mappingpatterns_34_))
+ (eq_vec p3_ (vec_of_bits [B0;B1;B0;B1;B1;B1;B1] : mword 7)))
+ (eq_vec p2_ (vec_of_bits [B0] : mword 1)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (Z.eqb (projT1 ((regbits_to_regno p0_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ let _mappingpatterns_34_ := subrange_vec_dec v__175 26 26 in
+ let _mappingpatterns_35_ := subrange_vec_dec v__175 25 25 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_36_ := subrange_vec_dec v__175 13 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let size := size_bits_backwards _mappingpatterns_36_ in
+ let rl := bool_bits_backwards _mappingpatterns_35_ in
+ let aq := bool_bits_backwards _mappingpatterns_34_ in
+ LOADRES (aq,rl,rs1,size,rd)
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__175 31 27 in
+ let _mappingpatterns_37_ := subrange_vec_dec v__175 26 26 in
+ let _mappingpatterns_38_ := subrange_vec_dec v__175 25 25 in
+ let p1_ := subrange_vec_dec v__175 14 14 in
+ let _mappingpatterns_39_ := subrange_vec_dec v__175 13 12 in
+ let p2_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (size_bits_backwards_matches _mappingpatterns_39_)
+ (bool_bits_backwards_matches _mappingpatterns_38_))
+ (bool_bits_backwards_matches _mappingpatterns_37_))
+ (eq_vec p2_ (vec_of_bits [B0;B1;B0;B1;B1;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B0] : mword 1)))
+ (Z.eqb (projT1 ((regbits_to_regno p0_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ let _mappingpatterns_37_ := subrange_vec_dec v__175 26 26 in
+ let _mappingpatterns_38_ := subrange_vec_dec v__175 25 25 in
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_39_ := subrange_vec_dec v__175 13 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let size := size_bits_backwards _mappingpatterns_39_ in
+ let rl := bool_bits_backwards _mappingpatterns_38_ in
+ let aq := bool_bits_backwards _mappingpatterns_37_ in
+ STORECON (aq,rl,rs2,rs1,size,rd)
+ else if ((let _mappingpatterns_40_ := subrange_vec_dec v__175 31 27 in
+ let _mappingpatterns_41_ := subrange_vec_dec v__175 26 26 in
+ let _mappingpatterns_42_ := subrange_vec_dec v__175 25 25 in
+ let p0_ := subrange_vec_dec v__175 14 14 in
+ let _mappingpatterns_43_ := subrange_vec_dec v__175 13 12 in
+ let p1_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (size_bits_backwards_matches _mappingpatterns_43_)
+ (bool_bits_backwards_matches _mappingpatterns_42_))
+ (bool_bits_backwards_matches _mappingpatterns_41_))
+ (encdec_amoop_backwards_matches _mappingpatterns_40_))
+ (eq_vec p1_ (vec_of_bits [B0;B1;B0;B1;B1;B1;B1] : mword 7)))
+ (eq_vec p0_ (vec_of_bits [B0] : mword 1)))) then
+ let _mappingpatterns_40_ := subrange_vec_dec v__175 31 27 in
+ let _mappingpatterns_41_ := subrange_vec_dec v__175 26 26 in
+ let _mappingpatterns_42_ := subrange_vec_dec v__175 25 25 in
+ let rs2 : mword 5 := subrange_vec_dec v__175 24 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_43_ := subrange_vec_dec v__175 13 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let size := size_bits_backwards _mappingpatterns_43_ in
+ let rl := bool_bits_backwards _mappingpatterns_42_ in
+ let aq := bool_bits_backwards _mappingpatterns_41_ in
+ let op := encdec_amoop_backwards _mappingpatterns_40_ in
+ AMO (op,aq,rl,rs2,rs1,size,rd)
+ else if ((let _mappingpatterns_44_ := subrange_vec_dec v__175 14 14 in
+ let _mappingpatterns_45_ := subrange_vec_dec v__175 13 12 in
+ let p0_ := subrange_vec_dec v__175 6 0 in
+ andb
+ (andb (encdec_csrop_backwards_matches _mappingpatterns_45_)
+ (bool_bits_backwards_matches _mappingpatterns_44_))
+ (eq_vec p0_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7)))) then
+ let csr : mword 12 := subrange_vec_dec v__175 31 20 in
+ let rs1 : mword 5 := subrange_vec_dec v__175 19 15 in
+ let _mappingpatterns_44_ := subrange_vec_dec v__175 14 14 in
+ let _mappingpatterns_45_ := subrange_vec_dec v__175 13 12 in
+ let rd : mword 5 := subrange_vec_dec v__175 11 7 in
+ let op := encdec_csrop_backwards _mappingpatterns_45_ in
+ let is_imm := bool_bits_backwards _mappingpatterns_44_ in
+ CSR (csr,rs1,rd,is_imm,op)
+ else if ((let p0_ := subrange_vec_dec v__175 31 16 in
+ let p1_ := subrange_vec_dec v__175 15 8 in
+ let p2_ := subrange_vec_dec v__175 7 7 in
+ let p3_ := subrange_vec_dec v__175 6 5 in
+ let p4_ := subrange_vec_dec v__175 4 2 in
+ let p5_ := subrange_vec_dec v__175 1 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (eq_vec p5_ (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec p4_ (vec_of_bits [B0;B1;B0] : mword 3)))
+ (eq_vec p3_ (vec_of_bits [B0;B0] : mword 2)))
+ (eq_vec p2_ (vec_of_bits [B0] : mword 1)))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0] : mword 8)))
+ (eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B1;B0;B1;B0;B1;B1;B0;B1;B1;B1;B1;B0] : mword 16))))
+ then
+ STOP_FETCHING tt
+ else if ((let p0_ := subrange_vec_dec v__175 31 16 in
+ let p1_ := subrange_vec_dec v__175 15 8 in
+ let p2_ := subrange_vec_dec v__175 7 7 in
+ let p3_ := subrange_vec_dec v__175 6 5 in
+ let p4_ := subrange_vec_dec v__175 4 2 in
+ let p5_ := subrange_vec_dec v__175 1 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (eq_vec p5_ (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec p4_ (vec_of_bits [B0;B1;B0] : mword 3)))
+ (eq_vec p3_ (vec_of_bits [B0;B0] : mword 2)))
+ (eq_vec p2_ (vec_of_bits [B0] : mword 1)))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0] : mword 8)))
+ (eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B1;B1;B0;B1;B1;B1;B1;B0] : mword 16))))
+ then
+ THREAD_START tt
+ else ILLEGAL v__175.
+
+Definition encdec_forwards_matches (arg_ : ast)
+: bool :=
+ match arg_ with
+ | UTYPE (imm,rd,op) => true
+ | RISCV_JAL (v__227,rd) =>
+ if ((let p0_ := subrange_vec_dec v__227 0 0 in
+ eq_vec p0_ (vec_of_bits [B0] : mword 1))) then
+ true
+ else
+ let g__17 := RISCV_JAL (v__227,rd) in
+ false
+ | RISCV_JALR (imm,rs1,rd) => true
+ | BTYPE (v__228,rs2,rs1,op) =>
+ if ((let p0_ := subrange_vec_dec v__228 0 0 in
+ eq_vec p0_ (vec_of_bits [B0] : mword 1))) then
+ true
+ else
+ let g__17 := BTYPE (v__228,rs2,rs1,op) in
+ false
+ | ITYPE (imm,rs1,rd,op) => true
+ | SHIFTIOP (shamt,rs1,rd,RISCV_SLLI) => true
+ | SHIFTIOP (shamt,rs1,rd,RISCV_SRLI) => true
+ | SHIFTIOP (shamt,rs1,rd,RISCV_SRAI) => true
+ | RTYPE (rs2,rs1,rd,RISCV_ADD) => true
+ | RTYPE (rs2,rs1,rd,RISCV_SUB) => true
+ | RTYPE (rs2,rs1,rd,RISCV_SLL) => true
+ | RTYPE (rs2,rs1,rd,RISCV_SLT) => true
+ | RTYPE (rs2,rs1,rd,RISCV_SLTU) => true
+ | RTYPE (rs2,rs1,rd,RISCV_XOR) => true
+ | RTYPE (rs2,rs1,rd,RISCV_SRL) => true
+ | RTYPE (rs2,rs1,rd,RISCV_SRA) => true
+ | RTYPE (rs2,rs1,rd,RISCV_OR) => true
+ | RTYPE (rs2,rs1,rd,RISCV_AND) => true
+ | LOAD (imm,rs1,rd,is_unsigned,size,false,false) => true
+ | STORE (v__229,rs2,rs1,size,false,false) => true
+ | ADDIW (imm,rs1,rd) => true
+ | SHIFTW (shamt,rs1,rd,RISCV_SLLI) => true
+ | SHIFTW (shamt,rs1,rd,RISCV_SRLI) => true
+ | SHIFTW (shamt,rs1,rd,RISCV_SRAI) => true
+ | RTYPEW (rs2,rs1,rd,RISCV_ADDW) => true
+ | RTYPEW (rs2,rs1,rd,RISCV_SUBW) => true
+ | RTYPEW (rs2,rs1,rd,RISCV_SLLW) => true
+ | RTYPEW (rs2,rs1,rd,RISCV_SRLW) => true
+ | RTYPEW (rs2,rs1,rd,RISCV_SRAW) => true
+ | SHIFTIWOP (shamt,rs1,rd,RISCV_SLLIW) => true
+ | SHIFTIWOP (shamt,rs1,rd,RISCV_SRLIW) => true
+ | SHIFTIWOP (shamt,rs1,rd,RISCV_SRAIW) => true
+ | MUL (rs2,rs1,rd,high,signed1,signed2) => true
+ | DIV (rs2,rs1,rd,s) => true
+ | REM (rs2,rs1,rd,s) => true
+ | MULW (rs2,rs1,rd) => true
+ | DIVW (rs2,rs1,rd,s) => true
+ | REMW (rs2,rs1,rd,s) => true
+ | FENCE (pred,succ) => true
+ | FENCEI (tt) => true
+ | ECALL (tt) => true
+ | MRET (tt) => true
+ | SRET (tt) => true
+ | EBREAK (tt) => true
+ | WFI (tt) => true
+ | SFENCE_VMA (rs1,rs2) => true
+ | LOADRES (aq,rl,rs1,size,rd) => true
+ | STORECON (aq,rl,rs2,rs1,size,rd) => true
+ | AMO (op,aq,rl,rs2,rs1,size,rd) => true
+ | CSR (csr,rs1,rd,is_imm,op) => true
+ | STOP_FETCHING (tt) => true
+ | THREAD_START (tt) => true
+ | ILLEGAL (s) => true
+ | g__17 => false
+ end.
+
+Definition encdec_backwards_matches (arg_ : mword 32)
+: bool :=
+ let v__230 := arg_ in
+ if ((let _mappingpatterns_0_ := subrange_vec_dec v__230 6 0 in
+ encdec_uop_backwards_matches _mappingpatterns_0_)) then
+ let _mappingpatterns_0_ := subrange_vec_dec v__230 6 0 in
+ let op := encdec_uop_backwards _mappingpatterns_0_ in
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 6 0 in
+ eq_vec p0_ (vec_of_bits [B1;B1;B0;B1;B1;B1;B1] : mword 7))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 14 12 in
+ let p1_ := subrange_vec_dec v__230 6 0 in
+ andb (eq_vec p1_ (vec_of_bits [B1;B1;B0;B0;B1;B1;B1] : mword 7))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3)))) then
+ true
+ else if ((let _mappingpatterns_1_ := subrange_vec_dec v__230 14 12 in
+ let p0_ := subrange_vec_dec v__230 6 0 in
+ andb (encdec_bop_backwards_matches _mappingpatterns_1_)
+ (eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B1;B1] : mword 7)))) then
+ let _mappingpatterns_1_ := subrange_vec_dec v__230 14 12 in
+ let op := encdec_bop_backwards _mappingpatterns_1_ in
+ true
+ else if ((let _mappingpatterns_2_ := subrange_vec_dec v__230 14 12 in
+ let p0_ := subrange_vec_dec v__230 6 0 in
+ andb (encdec_iop_backwards_matches _mappingpatterns_2_)
+ (eq_vec p0_ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7)))) then
+ let _mappingpatterns_2_ := subrange_vec_dec v__230 14 12 in
+ let op := encdec_iop_backwards _mappingpatterns_2_ in
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 26 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 26 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0] : mword 6)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 26 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0] : mword 6)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B1;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B1;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B1;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B1;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let _mappingpatterns_3_ := subrange_vec_dec v__230 14 14 in
+ let _mappingpatterns_4_ := subrange_vec_dec v__230 13 12 in
+ let p0_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (size_bits_backwards_matches _mappingpatterns_4_)
+ (bool_bits_backwards_matches _mappingpatterns_3_))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B1;B1] : mword 7)))) then
+ let _mappingpatterns_3_ := subrange_vec_dec v__230 14 14 in
+ let _mappingpatterns_4_ := subrange_vec_dec v__230 13 12 in
+ let size := size_bits_backwards _mappingpatterns_4_ in
+ let is_unsigned := bool_bits_backwards _mappingpatterns_3_ in
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 14 14 in
+ let _mappingpatterns_5_ := subrange_vec_dec v__230 13 12 in
+ let p1_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (size_bits_backwards_matches _mappingpatterns_5_)
+ (eq_vec p1_ (vec_of_bits [B0;B1;B0;B0;B0;B1;B1] : mword 7)))
+ (eq_vec p0_ (vec_of_bits [B0] : mword 1)))) then
+ let _mappingpatterns_5_ := subrange_vec_dec v__230 13 12 in
+ let size := size_bits_backwards _mappingpatterns_5_ in
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 14 12 in
+ let p1_ := subrange_vec_dec v__230 6 0 in
+ andb (eq_vec p1_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0] : mword 3)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B0;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B1;B0;B1] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B1;B0;B0;B0;B0;B0] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let _mappingpatterns_6_ : bits 3 := subrange_vec_dec v__230 14 12 in
+ let p1_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (encdec_mul_op_backwards_matches _mappingpatterns_6_)
+ (eq_vec p1_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let _mappingpatterns_6_ : bits 3 := subrange_vec_dec v__230 14 12 in
+ let '(high, signed1, signed2) := encdec_mul_op_backwards _mappingpatterns_6_ in
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 13 in
+ let _mappingpatterns_7_ := subrange_vec_dec v__230 12 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb (bool_not_bits_backwards_matches _mappingpatterns_7_)
+ (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B1;B0] : mword 2)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let _mappingpatterns_7_ := subrange_vec_dec v__230 12 12 in
+ let s := bool_not_bits_backwards _mappingpatterns_7_ in
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 13 in
+ let _mappingpatterns_8_ := subrange_vec_dec v__230 12 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb (bool_not_bits_backwards_matches _mappingpatterns_8_)
+ (eq_vec p2_ (vec_of_bits [B0;B1;B1;B0;B0;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B1;B1] : mword 2)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let _mappingpatterns_8_ := subrange_vec_dec v__230 12 12 in
+ let s := bool_not_bits_backwards _mappingpatterns_8_ in
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 13 in
+ let _mappingpatterns_9_ := subrange_vec_dec v__230 12 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb (bool_not_bits_backwards_matches _mappingpatterns_9_)
+ (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B1;B0] : mword 2)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let _mappingpatterns_9_ := subrange_vec_dec v__230 12 12 in
+ let s := bool_not_bits_backwards _mappingpatterns_9_ in
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 13 in
+ let _mappingpatterns_10_ := subrange_vec_dec v__230 12 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb (bool_not_bits_backwards_matches _mappingpatterns_10_)
+ (eq_vec p2_ (vec_of_bits [B0;B1;B1;B1;B0;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B1;B1] : mword 2)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B1] : mword 7)))) then
+ let _mappingpatterns_10_ := subrange_vec_dec v__230 12 12 in
+ let s := bool_not_bits_backwards _mappingpatterns_10_ in
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 28 in
+ let p1_ := subrange_vec_dec v__230 19 15 in
+ let p2_ := subrange_vec_dec v__230 14 12 in
+ let p3_ := subrange_vec_dec v__230 11 7 in
+ let p4_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B0;B0;B0;B1;B1;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0] : mword 4)))) then
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 20 in
+ let p1_ := subrange_vec_dec v__230 19 15 in
+ let p2_ := subrange_vec_dec v__230 14 12 in
+ let p3_ := subrange_vec_dec v__230 11 7 in
+ let p4_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B0;B0;B0;B1;B1;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B1] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12)))) then
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 20 in
+ let p1_ := subrange_vec_dec v__230 19 15 in
+ let p2_ := subrange_vec_dec v__230 14 12 in
+ let p3_ := subrange_vec_dec v__230 11 7 in
+ let p4_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] : mword 12)))) then
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 24 20 in
+ let p2_ := subrange_vec_dec v__230 19 15 in
+ let p3_ := subrange_vec_dec v__230 14 12 in
+ let p4_ := subrange_vec_dec v__230 11 7 in
+ let p5_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (eq_vec p5_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p4_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p3_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p2_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B1;B1;B0;B0;B0] : mword 7)))) then
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 24 20 in
+ let p2_ := subrange_vec_dec v__230 19 15 in
+ let p3_ := subrange_vec_dec v__230 14 12 in
+ let p4_ := subrange_vec_dec v__230 11 7 in
+ let p5_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (eq_vec p5_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p4_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p3_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p2_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0] : mword 7)))) then
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 20 in
+ let p1_ := subrange_vec_dec v__230 19 15 in
+ let p2_ := subrange_vec_dec v__230 14 12 in
+ let p3_ := subrange_vec_dec v__230 11 7 in
+ let p4_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B1] : mword 12)))) then
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 20 in
+ let p1_ := subrange_vec_dec v__230 19 15 in
+ let p2_ := subrange_vec_dec v__230 14 12 in
+ let p3_ := subrange_vec_dec v__230 11 7 in
+ let p4_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb (eq_vec p4_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p3_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p2_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B0;B0;B0;B1;B0;B1] : mword 12)))) then
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 25 in
+ let p1_ := subrange_vec_dec v__230 14 12 in
+ let p2_ := subrange_vec_dec v__230 11 7 in
+ let p3_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb (eq_vec p3_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7))
+ (Z.eqb
+ (projT1 ((regbits_to_regno p2_)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0] : mword 3)))
+ (eq_vec p0_ (vec_of_bits [B0;B0;B0;B1;B0;B0;B1] : mword 7)))) then
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 27 in
+ let _mappingpatterns_11_ := subrange_vec_dec v__230 26 26 in
+ let _mappingpatterns_12_ := subrange_vec_dec v__230 25 25 in
+ let p1_ := subrange_vec_dec v__230 24 20 in
+ let p2_ := subrange_vec_dec v__230 14 14 in
+ let _mappingpatterns_13_ := subrange_vec_dec v__230 13 12 in
+ let p3_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb
+ (andb (size_bits_backwards_matches _mappingpatterns_13_)
+ (bool_bits_backwards_matches _mappingpatterns_12_))
+ (bool_bits_backwards_matches _mappingpatterns_11_))
+ (eq_vec p3_ (vec_of_bits [B0;B1;B0;B1;B1;B1;B1] : mword 7)))
+ (eq_vec p2_ (vec_of_bits [B0] : mword 1)))
+ (Z.eqb (projT1 ((regbits_to_regno p1_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B0;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))
+ (Z.eqb (projT1 ((regbits_to_regno p0_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B0] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ let _mappingpatterns_11_ := subrange_vec_dec v__230 26 26 in
+ let _mappingpatterns_12_ := subrange_vec_dec v__230 25 25 in
+ let _mappingpatterns_13_ := subrange_vec_dec v__230 13 12 in
+ let size := size_bits_backwards _mappingpatterns_13_ in
+ let rl := bool_bits_backwards _mappingpatterns_12_ in
+ let aq := bool_bits_backwards _mappingpatterns_11_ in
+ true
+ else if sumbool_of_bool ((let p0_ := subrange_vec_dec v__230 31 27 in
+ let _mappingpatterns_14_ := subrange_vec_dec v__230 26 26 in
+ let _mappingpatterns_15_ := subrange_vec_dec v__230 25 25 in
+ let p1_ := subrange_vec_dec v__230 14 14 in
+ let _mappingpatterns_16_ := subrange_vec_dec v__230 13 12 in
+ let p2_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (size_bits_backwards_matches _mappingpatterns_16_)
+ (bool_bits_backwards_matches _mappingpatterns_15_))
+ (bool_bits_backwards_matches _mappingpatterns_14_))
+ (eq_vec p2_ (vec_of_bits [B0;B1;B0;B1;B1;B1;B1] : mword 7)))
+ (eq_vec p1_ (vec_of_bits [B0] : mword 1)))
+ (Z.eqb (projT1 ((regbits_to_regno p0_) : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))
+ (projT1 ((regbits_to_regno (vec_of_bits [B0;B0;B0;B1;B1] : mword 5))
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)}))))) then
+ let _mappingpatterns_14_ := subrange_vec_dec v__230 26 26 in
+ let _mappingpatterns_15_ := subrange_vec_dec v__230 25 25 in
+ let _mappingpatterns_16_ := subrange_vec_dec v__230 13 12 in
+ let size := size_bits_backwards _mappingpatterns_16_ in
+ let rl := bool_bits_backwards _mappingpatterns_15_ in
+ let aq := bool_bits_backwards _mappingpatterns_14_ in
+ true
+ else if ((let _mappingpatterns_17_ := subrange_vec_dec v__230 31 27 in
+ let _mappingpatterns_18_ := subrange_vec_dec v__230 26 26 in
+ let _mappingpatterns_19_ := subrange_vec_dec v__230 25 25 in
+ let p0_ := subrange_vec_dec v__230 14 14 in
+ let _mappingpatterns_20_ := subrange_vec_dec v__230 13 12 in
+ let p1_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (size_bits_backwards_matches _mappingpatterns_20_)
+ (bool_bits_backwards_matches _mappingpatterns_19_))
+ (bool_bits_backwards_matches _mappingpatterns_18_))
+ (encdec_amoop_backwards_matches _mappingpatterns_17_))
+ (eq_vec p1_ (vec_of_bits [B0;B1;B0;B1;B1;B1;B1] : mword 7)))
+ (eq_vec p0_ (vec_of_bits [B0] : mword 1)))) then
+ let _mappingpatterns_17_ := subrange_vec_dec v__230 31 27 in
+ let _mappingpatterns_18_ := subrange_vec_dec v__230 26 26 in
+ let _mappingpatterns_19_ := subrange_vec_dec v__230 25 25 in
+ let _mappingpatterns_20_ := subrange_vec_dec v__230 13 12 in
+ let size := size_bits_backwards _mappingpatterns_20_ in
+ let rl := bool_bits_backwards _mappingpatterns_19_ in
+ let aq := bool_bits_backwards _mappingpatterns_18_ in
+ let op := encdec_amoop_backwards _mappingpatterns_17_ in
+ true
+ else if ((let _mappingpatterns_21_ := subrange_vec_dec v__230 14 14 in
+ let _mappingpatterns_22_ := subrange_vec_dec v__230 13 12 in
+ let p0_ := subrange_vec_dec v__230 6 0 in
+ andb
+ (andb (encdec_csrop_backwards_matches _mappingpatterns_22_)
+ (bool_bits_backwards_matches _mappingpatterns_21_))
+ (eq_vec p0_ (vec_of_bits [B1;B1;B1;B0;B0;B1;B1] : mword 7)))) then
+ let _mappingpatterns_21_ := subrange_vec_dec v__230 14 14 in
+ let _mappingpatterns_22_ := subrange_vec_dec v__230 13 12 in
+ let op := encdec_csrop_backwards _mappingpatterns_22_ in
+ let is_imm := bool_bits_backwards _mappingpatterns_21_ in
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 16 in
+ let p1_ := subrange_vec_dec v__230 15 8 in
+ let p2_ := subrange_vec_dec v__230 7 7 in
+ let p3_ := subrange_vec_dec v__230 6 5 in
+ let p4_ := subrange_vec_dec v__230 4 2 in
+ let p5_ := subrange_vec_dec v__230 1 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (eq_vec p5_ (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec p4_ (vec_of_bits [B0;B1;B0] : mword 3)))
+ (eq_vec p3_ (vec_of_bits [B0;B0] : mword 2)))
+ (eq_vec p2_ (vec_of_bits [B0] : mword 1)))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0] : mword 8)))
+ (eq_vec p0_ (vec_of_bits [B1;B1;B1;B1;B1;B0;B1;B0;B1;B1;B0;B1;B1;B1;B1;B0] : mword 16))))
+ then
+ true
+ else if ((let p0_ := subrange_vec_dec v__230 31 16 in
+ let p1_ := subrange_vec_dec v__230 15 8 in
+ let p2_ := subrange_vec_dec v__230 7 7 in
+ let p3_ := subrange_vec_dec v__230 6 5 in
+ let p4_ := subrange_vec_dec v__230 4 2 in
+ let p5_ := subrange_vec_dec v__230 1 0 in
+ andb
+ (andb
+ (andb
+ (andb
+ (andb (eq_vec p5_ (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec p4_ (vec_of_bits [B0;B1;B0] : mword 3)))
+ (eq_vec p3_ (vec_of_bits [B0;B0] : mword 2)))
+ (eq_vec p2_ (vec_of_bits [B0] : mword 1)))
+ (eq_vec p1_ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0] : mword 8)))
+ (eq_vec p0_ (vec_of_bits [B1;B1;B0;B0;B0;B0;B0;B0;B1;B1;B0;B1;B1;B1;B1;B0] : mword 16))))
+ then
+ true
+ else true.
+
+Definition print_insn (merge_var : ast)
+: M (string) :=
+ match merge_var with
+ | NOP (g__13) => returnm ("nop" : string)
+ | C_ADDI4SPN (rdc,nzimm) =>
+ returnm ((String.append "c.addi4spn "
+ (String.append ((reg_name_abi (creg2reg_bits rdc)) : string)
+ (String.append ", " (string_of_bits nzimm))))
+ : string)
+ | C_LW (uimm,rsc,rdc) =>
+ returnm ((String.append "c.lw "
+ (String.append ((reg_name_abi (creg2reg_bits rdc)) : string)
+ (String.append ", "
+ (String.append ((reg_name_abi (creg2reg_bits rsc)) : string)
+ (String.append ", " (string_of_bits uimm))))))
+ : string)
+ | C_LD (uimm,rsc,rdc) =>
+ returnm ((String.append "c.ld "
+ (String.append ((reg_name_abi (creg2reg_bits rdc)) : string)
+ (String.append ", "
+ (String.append ((reg_name_abi (creg2reg_bits rsc)) : string)
+ (String.append ", " (string_of_bits uimm))))))
+ : string)
+ | C_SW (uimm,rsc1,rsc2) =>
+ returnm ((String.append "c.sw "
+ (String.append ((reg_name_abi (creg2reg_bits rsc1)) : string)
+ (String.append ", "
+ (String.append ((reg_name_abi (creg2reg_bits rsc2)) : string)
+ (String.append ", " (string_of_bits uimm))))))
+ : string)
+ | C_SD (uimm,rsc1,rsc2) =>
+ returnm ((String.append "c.sd "
+ (String.append ((reg_name_abi (creg2reg_bits rsc1)) : string)
+ (String.append ", "
+ (String.append ((reg_name_abi (creg2reg_bits rsc2)) : string)
+ (String.append ", " (string_of_bits uimm))))))
+ : string)
+ | C_ADDI (nzi,rsd) =>
+ returnm ((String.append "c.addi "
+ (String.append ((reg_name_abi rsd) : string)
+ (String.append ", " (string_of_bits nzi))))
+ : string)
+ | C_JAL (imm) => returnm ((String.append "c.jal " (string_of_bits imm)) : string)
+ | C_ADDIW (imm,rsd) =>
+ returnm ((String.append "c.addiw "
+ (String.append ((reg_name_abi rsd) : string)
+ (String.append ", " (string_of_bits imm))))
+ : string)
+ | C_LI (imm,rd) =>
+ returnm ((String.append "c.li "
+ (String.append ((reg_name_abi rd) : string)
+ (String.append ", " (string_of_bits imm))))
+ : string)
+ | C_ADDI16SP (imm) => returnm ((String.append "c.addi16sp " (string_of_bits imm)) : string)
+ | C_LUI (imm,rd) =>
+ returnm ((String.append "c.lui "
+ (String.append ((reg_name_abi rd) : string)
+ (String.append ", " (string_of_bits imm))))
+ : string)
+ | C_SRLI (shamt,rsd) =>
+ returnm ((String.append "c.srli "
+ (String.append ((reg_name_abi (creg2reg_bits rsd)) : string)
+ (String.append ", " (string_of_bits shamt))))
+ : string)
+ | C_SRAI (shamt,rsd) =>
+ returnm ((String.append "c.srai "
+ (String.append ((reg_name_abi (creg2reg_bits rsd)) : string)
+ (String.append ", " (string_of_bits shamt))))
+ : string)
+ | C_ANDI (imm,rsd) =>
+ returnm ((String.append "c.andi "
+ (String.append ((reg_name_abi (creg2reg_bits rsd)) : string)
+ (String.append ", " (string_of_bits imm))))
+ : string)
+ | C_SUB (rsd,rs2) =>
+ returnm ((String.append "c.sub "
+ (String.append ((reg_name_abi (creg2reg_bits rsd)) : string)
+ (String.append ", " ((reg_name_abi (creg2reg_bits rs2)) : string))))
+ : string)
+ | C_XOR (rsd,rs2) =>
+ returnm ((String.append "c.xor "
+ (String.append ((reg_name_abi (creg2reg_bits rsd)) : string)
+ (String.append ", " ((reg_name_abi (creg2reg_bits rs2)) : string))))
+ : string)
+ | C_OR (rsd,rs2) =>
+ returnm ((String.append "c.or "
+ (String.append ((reg_name_abi (creg2reg_bits rsd)) : string)
+ (String.append ", " ((reg_name_abi (creg2reg_bits rs2)) : string))))
+ : string)
+ | C_AND (rsd,rs2) =>
+ returnm ((String.append "c.and "
+ (String.append ((reg_name_abi (creg2reg_bits rsd)) : string)
+ (String.append ", " ((reg_name_abi (creg2reg_bits rs2)) : string))))
+ : string)
+ | C_SUBW (rsd,rs2) =>
+ returnm ((String.append "c.subw "
+ (String.append ((reg_name_abi (creg2reg_bits rsd)) : string)
+ (String.append ", " ((reg_name_abi (creg2reg_bits rs2)) : string))))
+ : string)
+ | C_ADDW (rsd,rs2) =>
+ returnm ((String.append "c.addw "
+ (String.append ((reg_name_abi (creg2reg_bits rsd)) : string)
+ (String.append ", " ((reg_name_abi (creg2reg_bits rs2)) : string))))
+ : string)
+ | C_J (imm) => returnm ((String.append "c.j " (string_of_bits imm)) : string)
+ | C_BEQZ (imm,rs) =>
+ returnm ((String.append "c.beqz "
+ (String.append ((reg_name_abi (creg2reg_bits rs)) : string)
+ (String.append ", " (string_of_bits imm))))
+ : string)
+ | C_BNEZ (imm,rs) =>
+ returnm ((String.append "c.bnez "
+ (String.append ((reg_name_abi (creg2reg_bits rs)) : string)
+ (String.append ", " (string_of_bits imm))))
+ : string)
+ | C_SLLI (shamt,rsd) =>
+ returnm ((String.append "c.slli "
+ (String.append ((reg_name_abi rsd) : string)
+ (String.append ", " (string_of_bits shamt))))
+ : string)
+ | C_LWSP (uimm,rd) =>
+ returnm ((String.append "c.lwsp "
+ (String.append ((reg_name_abi rd) : string)
+ (String.append ", " (string_of_bits uimm))))
+ : string)
+ | C_LDSP (uimm,rd) =>
+ returnm ((String.append "c.ldsp "
+ (String.append ((reg_name_abi rd) : string)
+ (String.append ", " (string_of_bits uimm))))
+ : string)
+ | C_SWSP (uimm,rd) =>
+ returnm ((String.append "c.swsp "
+ (String.append ((reg_name_abi rd) : string)
+ (String.append ", " (string_of_bits uimm))))
+ : string)
+ | C_SDSP (uimm,rd) =>
+ returnm ((String.append "c.sdsp "
+ (String.append ((reg_name_abi rd) : string)
+ (String.append ", " (string_of_bits uimm))))
+ : string)
+ | C_JR (rs1) => returnm ((String.append "c.jr " ((reg_name_abi rs1) : string)) : string)
+ | C_JALR (rs1) => returnm ((String.append "c.jalr " ((reg_name_abi rs1) : string)) : string)
+ | C_MV (rd,rs2) =>
+ returnm ((String.append "c.mv "
+ (String.append ((reg_name_abi rd) : string)
+ (String.append ", " ((reg_name_abi rs2) : string))))
+ : string)
+ | C_ADD (rsd,rs2) =>
+ returnm ((String.append "c.add "
+ (String.append ((reg_name_abi rsd) : string)
+ (String.append ", " ((reg_name_abi rs2) : string))))
+ : string)
+ | STOP_FETCHING (g__14) => returnm ("stop_fetching" : string)
+ | THREAD_START (g__15) => returnm ("thread_start" : string)
+ | ILLEGAL (s) => returnm ((String.append "illegal " (string_of_bits s)) : string)
+ | C_ILLEGAL (g__16) => returnm ("c.illegal" : string)
+ | insn => (assembly_forwards insn) : M (string)
+ end.
+
+Definition decode (bv : mword 32) : option ast := Some (encdec_backwards bv).
+
+Definition isRVC (h : mword 16)
+: bool :=
+ negb (eq_vec (subrange_vec_dec h 1 0) (vec_of_bits [B1;B1] : mword 2)).
+
+Definition fetch '(tt : unit)
+: M (FetchResult) :=
+ or_boolM
+ ((read_reg PC_ref : M (mword 64)) >>= fun w__0 : xlenbits =>
+ cast_unit_vec (access_vec_dec w__0 0) >>= fun w__1 : mword 1 =>
+ returnm ((neq_vec (w__1 : mword 1) (vec_of_bits [B0] : mword 1))
+ : bool))
+ ((and_boolM
+ ((read_reg PC_ref : M (mword 64)) >>= fun w__2 : xlenbits =>
+ cast_unit_vec (access_vec_dec w__2 1) >>= fun w__3 : mword 1 =>
+ returnm ((neq_vec (w__3 : mword 1) (vec_of_bits [B0] : mword 1))
+ : bool)) (haveRVC tt >>= fun w__4 : bool => returnm ((negb w__4) : bool)))
+ : M (bool)) >>= fun w__6 : bool =>
+ (if (w__6) then
+ (read_reg PC_ref : M (mword 64)) >>= fun w__7 : mword 64 =>
+ returnm ((F_Error (E_Fetch_Addr_Align,w__7))
+ : FetchResult)
+ else
+ (read_reg PC_ref : M (mword 64)) >>= fun w__8 : mword 64 =>
+ translateAddr w__8 Execute Instruction >>= fun w__9 : TR_Result =>
+ (match w__9 with
+ | TR_Failure (e) =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__10 : mword 64 =>
+ returnm ((F_Error (e,w__10))
+ : FetchResult)
+ | TR_Address (ppclo) =>
+ checked_mem_read Instruction ppclo 2 >>= fun w__11 : MemoryOpResult (mword 16) =>
+ (match w__11 with
+ | MemException (e) =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__12 : mword 64 =>
+ returnm ((F_Error (E_Fetch_Access_Fault,w__12))
+ : FetchResult)
+ | MemValue (ilo) =>
+ (if ((isRVC ilo)) then returnm ((F_RVC ilo) : FetchResult)
+ else
+ (read_reg PC_ref : M (mword 64)) >>= fun w__13 : mword 64 =>
+ let PChi : xlenbits := add_vec_int w__13 2 in
+ translateAddr PChi Execute Instruction >>= fun w__14 : TR_Result =>
+ (match w__14 with
+ | TR_Failure (e) => returnm ((F_Error (e,PChi)) : FetchResult)
+ | TR_Address (ppchi) =>
+ checked_mem_read Instruction ppchi 2 >>= fun w__15 : MemoryOpResult (mword 16) =>
+ returnm ((match w__15 with
+ | MemException (e) => F_Error (E_Fetch_Access_Fault,PChi)
+ | MemValue (ihi) => F_Base (concat_vec ihi ilo)
+ end)
+ : FetchResult)
+ end)
+ : M (FetchResult))
+ : M (FetchResult)
+ end)
+ : M (FetchResult)
+ end)
+ : M (FetchResult))
+ : M (FetchResult).
+
+Definition step (step_no : Z)
+: M ((bool * bool)) :=
+ read_reg cur_privilege_ref >>= fun w__0 : Privilege =>
+ read_reg mip_ref >>= fun w__1 : Minterrupts =>
+ read_reg mie_ref >>= fun w__2 : Minterrupts =>
+ read_reg mideleg_ref >>= fun w__3 : Minterrupts =>
+ curInterrupt w__0 w__1 w__2 w__3 >>= fun w__4 : option ((InterruptType * Privilege)) =>
+ (match w__4 with
+ | Some (intr,priv) =>
+ let '_ :=
+ (print_bits "Handling interrupt: " ((interruptType_to_bits intr) : mword 4))
+ : unit in
+ handle_interrupt intr priv >> returnm ((false, false) : (bool * bool))
+ | None =>
+ fetch tt >>= fun w__5 : FetchResult =>
+ (match w__5 with
+ | F_Error (e,addr) =>
+ handle_mem_exception addr e >> returnm ((false, false) : (bool * bool))
+ | F_RVC (h) =>
+ (match (decodeCompressed h) with
+ | None =>
+ read_reg cur_privilege_ref >>= fun w__6 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__7 : xlenbits =>
+ let '_ :=
+ (print_endline
+ (String.append "["
+ (String.append (string_of_int step_no)
+ (String.append "] ["
+ (String.append ((privLevel_to_str w__6) : string)
+ (String.append "]: "
+ (String.append (string_of_bits w__7)
+ (String.append " ("
+ (String.append (string_of_bits h) ") <no-decode>")))))))))
+ : unit in
+ handle_decode_exception (EXTZ 64 h) >> returnm ((false, true) : (bool * bool))
+ | Some (ast) =>
+ read_reg cur_privilege_ref >>= fun w__8 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__9 : xlenbits =>
+ print_insn ast >>= fun w__10 : string =>
+ let '_ :=
+ (print_endline
+ (String.append "["
+ (String.append (string_of_int step_no)
+ (String.append "] ["
+ (String.append ((privLevel_to_str w__8) : string)
+ (String.append "]: "
+ (String.append (string_of_bits w__9)
+ (String.append " ("
+ (String.append (string_of_bits h)
+ (String.append ") " (w__10 : string)))))))))))
+ : unit in
+ (read_reg PC_ref : M (mword 64)) >>= fun w__11 : mword 64 =>
+ write_reg nextPC_ref (add_vec_int w__11 2) >>
+ execute ast >>= fun w__12 : bool => returnm ((w__12, true) : (bool * bool))
+ end)
+ : M ((bool * bool))
+ | F_Base (w) =>
+ (match (decode w) with
+ | None =>
+ read_reg cur_privilege_ref >>= fun w__14 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__15 : xlenbits =>
+ let '_ :=
+ (print_endline
+ (String.append "["
+ (String.append (string_of_int step_no)
+ (String.append "] ["
+ (String.append ((privLevel_to_str w__14) : string)
+ (String.append "]: "
+ (String.append (string_of_bits w__15)
+ (String.append " ("
+ (String.append (string_of_bits w) ") <no-decode>")))))))))
+ : unit in
+ handle_decode_exception (EXTZ 64 w) >> returnm ((false, true) : (bool * bool))
+ | Some (ast) =>
+ read_reg cur_privilege_ref >>= fun w__16 : Privilege =>
+ (read_reg PC_ref : M (mword 64)) >>= fun w__17 : xlenbits =>
+ print_insn ast >>= fun w__18 : string =>
+ let '_ :=
+ (print_endline
+ (String.append "["
+ (String.append (string_of_int step_no)
+ (String.append "] ["
+ (String.append ((privLevel_to_str w__16) : string)
+ (String.append "]: "
+ (String.append (string_of_bits w__17)
+ (String.append " ("
+ (String.append (string_of_bits w)
+ (String.append ") " (w__18 : string)))))))))))
+ : unit in
+ (read_reg PC_ref : M (mword 64)) >>= fun w__19 : mword 64 =>
+ write_reg nextPC_ref (add_vec_int w__19 4) >>
+ execute ast >>= fun w__20 : bool => returnm ((w__20, true) : (bool * bool))
+ end)
+ : M ((bool * bool))
+ end)
+ : M ((bool * bool))
+ end)
+ : M ((bool * bool)).
+(*
+Definition loop '(tt : unit)
+: M (unit) :=
+ let insns_per_tick := plat_insns_per_tick tt in
+ let i : Z := 0 in
+ let step_no : Z := 0 in
+ (whileM (i, step_no)
+ (fun varstup => let '(i, step_no) := varstup in
+ read_reg htif_done_ref >>= fun w__0 : bool => returnm ((negb w__0) : bool))
+ (fun varstup => let '(i, step_no) := varstup in
+ write_reg minstret_written_ref false >>
+ step step_no >>= fun '(retired, stepped) =>
+ (read_reg nextPC_ref : M (mword 64)) >>= fun w__1 : xlenbits =>
+ write_reg PC_ref w__1 >>
+ (if (retired) then (retire_instruction tt) : M (unit)
+ else returnm (tt : unit)) >>
+ let step_no : Z :=
+ if (stepped) then
+ projT1 (add_range ((ex_int step_no) : {n : Z & ArithFact (True)}) (build_ex 1))
+ else step_no in
+ read_reg htif_done_ref >>= fun w__2 : bool =>
+ (if (w__2) then
+ (read_reg htif_exit_code_ref : M (mword 64)) >>= fun w__3 : xlenbits =>
+ let '(existT _ exit_val _) := uint w__3 in
+ returnm (let '_ :=
+ (if sumbool_of_bool ((Z.eqb exit_val 0)) then print_endline "SUCCESS"
+ else print_int "FAILURE: " exit_val)
+ : unit in
+ i)
+ else
+ let i := (projT1 (add_range ((ex_int i) : {n : Z & ArithFact (True)}) (build_ex 1))) : Z in
+ (if sumbool_of_bool ((Z.eqb (projT1 ((ex_int i) : {n : Z & ArithFact (True)}))
+ insns_per_tick)) then
+ tick_clock tt >> tick_platform tt >> returnm 0
+ else returnm i)
+ : M (Z)) >>= fun i : Z =>
+ returnm (i, step_no))) >>= fun '(i, step_no) =>
+ returnm (tt
+ : unit).
+*)
+Definition read_kind_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 11)}
+: read_kind :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then Read_plain
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then Read_reserve
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then Read_acquire
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then Read_exclusive
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then Read_exclusive_acquire
+ else if sumbool_of_bool ((Z.eqb p0_ 5)) then Read_stream
+ else if sumbool_of_bool ((Z.eqb p0_ 6)) then Read_RISCV_acquire
+ else if sumbool_of_bool ((Z.eqb p0_ 7)) then Read_RISCV_strong_acquire
+ else if sumbool_of_bool ((Z.eqb p0_ 8)) then Read_RISCV_reserved
+ else if sumbool_of_bool ((Z.eqb p0_ 9)) then Read_RISCV_reserved_acquire
+ else if sumbool_of_bool ((Z.eqb p0_ 10)) then Read_RISCV_reserved_strong_acquire
+ else Read_X86_locked.
+
+Definition num_of_read_kind (arg_ : read_kind)
+: {e : Z & ArithFact (0 <= e /\ e <= 11)} :=
+ match arg_ with
+ | Read_plain => build_ex 0
+ | Read_reserve => build_ex 1
+ | Read_acquire => build_ex 2
+ | Read_exclusive => build_ex 3
+ | Read_exclusive_acquire => build_ex 4
+ | Read_stream => build_ex 5
+ | Read_RISCV_acquire => build_ex 6
+ | Read_RISCV_strong_acquire => build_ex 7
+ | Read_RISCV_reserved => build_ex 8
+ | Read_RISCV_reserved_acquire => build_ex 9
+ | Read_RISCV_reserved_strong_acquire => build_ex 10
+ | Read_X86_locked => build_ex 11
+ end.
+
+Definition write_kind_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 10)}
+: write_kind :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then Write_plain
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then Write_conditional
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then Write_release
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then Write_exclusive
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then Write_exclusive_release
+ else if sumbool_of_bool ((Z.eqb p0_ 5)) then Write_RISCV_release
+ else if sumbool_of_bool ((Z.eqb p0_ 6)) then Write_RISCV_strong_release
+ else if sumbool_of_bool ((Z.eqb p0_ 7)) then Write_RISCV_conditional
+ else if sumbool_of_bool ((Z.eqb p0_ 8)) then Write_RISCV_conditional_release
+ else if sumbool_of_bool ((Z.eqb p0_ 9)) then Write_RISCV_conditional_strong_release
+ else Write_X86_locked.
+
+Definition num_of_write_kind (arg_ : write_kind)
+: {e : Z & ArithFact (0 <= e /\ e <= 10)} :=
+ match arg_ with
+ | Write_plain => build_ex 0
+ | Write_conditional => build_ex 1
+ | Write_release => build_ex 2
+ | Write_exclusive => build_ex 3
+ | Write_exclusive_release => build_ex 4
+ | Write_RISCV_release => build_ex 5
+ | Write_RISCV_strong_release => build_ex 6
+ | Write_RISCV_conditional => build_ex 7
+ | Write_RISCV_conditional_release => build_ex 8
+ | Write_RISCV_conditional_strong_release => build_ex 9
+ | Write_X86_locked => build_ex 10
+ end.
+
+Definition barrier_kind_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 22)}
+: barrier_kind :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then Barrier_Sync
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then Barrier_LwSync
+ else if sumbool_of_bool ((Z.eqb p0_ 2)) then Barrier_Eieio
+ else if sumbool_of_bool ((Z.eqb p0_ 3)) then Barrier_Isync
+ else if sumbool_of_bool ((Z.eqb p0_ 4)) then Barrier_DMB
+ else if sumbool_of_bool ((Z.eqb p0_ 5)) then Barrier_DMB_ST
+ else if sumbool_of_bool ((Z.eqb p0_ 6)) then Barrier_DMB_LD
+ else if sumbool_of_bool ((Z.eqb p0_ 7)) then Barrier_DSB
+ else if sumbool_of_bool ((Z.eqb p0_ 8)) then Barrier_DSB_ST
+ else if sumbool_of_bool ((Z.eqb p0_ 9)) then Barrier_DSB_LD
+ else if sumbool_of_bool ((Z.eqb p0_ 10)) then Barrier_ISB
+ else if sumbool_of_bool ((Z.eqb p0_ 11)) then Barrier_MIPS_SYNC
+ else if sumbool_of_bool ((Z.eqb p0_ 12)) then Barrier_RISCV_rw_rw
+ else if sumbool_of_bool ((Z.eqb p0_ 13)) then Barrier_RISCV_r_rw
+ else if sumbool_of_bool ((Z.eqb p0_ 14)) then Barrier_RISCV_r_r
+ else if sumbool_of_bool ((Z.eqb p0_ 15)) then Barrier_RISCV_rw_w
+ else if sumbool_of_bool ((Z.eqb p0_ 16)) then Barrier_RISCV_w_w
+ else if sumbool_of_bool ((Z.eqb p0_ 17)) then Barrier_RISCV_w_rw
+ else if sumbool_of_bool ((Z.eqb p0_ 18)) then Barrier_RISCV_rw_r
+ else if sumbool_of_bool ((Z.eqb p0_ 19)) then Barrier_RISCV_r_w
+ else if sumbool_of_bool ((Z.eqb p0_ 20)) then Barrier_RISCV_w_r
+ else if sumbool_of_bool ((Z.eqb p0_ 21)) then Barrier_RISCV_i
+ else Barrier_x86_MFENCE.
+(*
+Definition num_of_barrier_kind (arg_ : barrier_kind)
+: {e : Z & ArithFact (0 <= e /\ e <= 22)} :=
+ match arg_ with
+ | Barrier_Sync => build_ex 0
+ | Barrier_LwSync => build_ex 1
+ | Barrier_Eieio => build_ex 2
+ | Barrier_Isync => build_ex 3
+ | Barrier_DMB => build_ex 4
+ | Barrier_DMB_ST => build_ex 5
+ | Barrier_DMB_LD => build_ex 6
+ | Barrier_DSB => build_ex 7
+ | Barrier_DSB_ST => build_ex 8
+ | Barrier_DSB_LD => build_ex 9
+ | Barrier_ISB => build_ex 10
+ | Barrier_MIPS_SYNC => build_ex 11
+ | Barrier_RISCV_rw_rw => build_ex 12
+ | Barrier_RISCV_r_rw => build_ex 13
+ | Barrier_RISCV_r_r => build_ex 14
+ | Barrier_RISCV_rw_w => build_ex 15
+ | Barrier_RISCV_w_w => build_ex 16
+ | Barrier_RISCV_w_rw => build_ex 17
+ | Barrier_RISCV_rw_r => build_ex 18
+ | Barrier_RISCV_r_w => build_ex 19
+ | Barrier_RISCV_w_r => build_ex 20
+ | Barrier_RISCV_i => build_ex 21
+ | Barrier_x86_MFENCE => build_ex 22
+ end.
+*)
+Definition trans_kind_of_num (arg_ : Z) `{ArithFact (0 <= arg_ /\ arg_ <= 2)}
+: trans_kind :=
+ let p0_ := arg_ in
+ if sumbool_of_bool ((Z.eqb p0_ 0)) then Transaction_start
+ else if sumbool_of_bool ((Z.eqb p0_ 1)) then Transaction_commit
+ else Transaction_abort.
+
+Definition num_of_trans_kind (arg_ : trans_kind)
+: {e : Z & ArithFact (0 <= e /\ e <= 2)} :=
+ match arg_ with
+ | Transaction_start => build_ex 0
+ | Transaction_commit => build_ex 1
+ | Transaction_abort => build_ex 2
+ end.
+
+Let GPRstr : vec string 32 :=
+vec_of_list_len ["x31";"x30";"x29";"x28";"x27";"x26";"x25";"x24";"x23";"x22";"x21";"x20";"x19";"x18";"x17";"x16";"x15";"x14";"x13";"x12";"x11";
+ "x10";"x9";"x8";"x7";"x6";"x5";"x4";"x3";"x2";"x1";"x0"].
+Let CIA_fp := RFull "CIA".
+Let NIA_fp := RFull "NIA".
+(*
+Definition initial_analysis (instr : ast)
+: M ((list regfp * list regfp * list regfp * list niafp * diafp * instruction_kind)) :=
+ let iR := [] : regfps in
+ let oR := [] : regfps in
+ let aR := [] : regfps in
+ let ik := (IK_simple tt) : instruction_kind in
+ let Nias := [NIAFP_successor tt] : niafps in
+ let Dia := (DIAFP_none tt) : diafp in
+ match instr with
+ | EBREAK (_) => returnm (Nias, aR, iR, ik, oR)
+ | UTYPE (imm,rd,op) =>
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ returnm (Nias, aR, iR, ik, oR)
+ | RISCV_JAL (imm,rd) =>
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ let offset : bits 64 := EXTS 64 imm in
+ (read_reg PC_ref : M (mword 64)) >>= fun w__0 : mword 64 =>
+ let Nias : niafps := [NIAFP_concrete_address (add_vec w__0 offset)] in
+ let ik : instruction_kind := IK_branch tt in
+ returnm (Nias, aR, iR, ik, oR)
+ | RISCV_JALR (imm,rs,rd) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ let offset : bits 64 := EXTS 64 imm in
+ let Nias : niafps := [NIAFP_indirect_address tt] in
+ let ik : instruction_kind := IK_branch tt in
+ returnm (Nias, aR, iR, ik, oR)
+ | BTYPE (imm,rs2,rs1,op) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let ik := (IK_branch tt) : instruction_kind in
+ let offset : bits 64 := EXTS 64 imm in
+ (read_reg PC_ref : M (mword 64)) >>= fun w__1 : mword 64 =>
+ let Nias : niafps := [NIAFP_concrete_address (add_vec w__1 offset);NIAFP_successor tt] in
+ returnm (Nias, aR, iR, ik, oR)
+ | ITYPE (imm,rs,rd,op) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ returnm (Nias, aR, iR, ik, oR)
+ | SHIFTIOP (imm,rs,rd,op) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ returnm (Nias, aR, iR, ik, oR)
+ | RTYPE (rs2,rs1,rd,op) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ returnm (Nias, aR, iR, ik, oR)
+ | CSR (csr,rs1,rd,is_imm,op) =>
+ let isWrite : bool :=
+ match op with
+ | CSRRW => true
+ | _ => if (is_imm) then neq_int (projT1 (uint rs1)) 0 else neq_int (projT1 (uint rs1)) 0
+ end in
+ let iR : regfps := (RFull (csr_name csr)) :: iR in
+ let iR : regfps :=
+ if ((negb is_imm)) then
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR
+ else iR in
+ let oR : regfps := if (isWrite) then (RFull (csr_name csr)) :: oR else oR in
+ let oR : regfps :=
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ returnm (Nias, aR, iR, ik, oR)
+ | LOAD (imm,rs,rd,unsign,width,aq,rl) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ let aR := iR : regfps in
+ match (aq, rl) with
+ | (false, false) => returnm ((IK_mem_read Read_plain) : instruction_kind)
+ | (true, false) => returnm ((IK_mem_read Read_RISCV_acquire) : instruction_kind)
+ | (true, true) => returnm ((IK_mem_read Read_RISCV_strong_acquire) : instruction_kind)
+ | _ =>
+ (internal_error "LOAD type not implemented in initial_analysis") : M (instruction_kind)
+ end >>= fun w__3 : instruction_kind =>
+ let ik : instruction_kind := w__3 in
+ returnm (Nias, aR, iR, ik, oR)
+ | STORE (imm,rs2,rs1,width,aq,rl) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let aR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ aR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ aR in
+ match (aq, rl) with
+ | (false, false) => returnm ((IK_mem_write Write_plain) : instruction_kind)
+ | (false, true) => returnm ((IK_mem_write Write_RISCV_release) : instruction_kind)
+ | (true, true) => returnm ((IK_mem_write Write_RISCV_strong_release) : instruction_kind)
+ | _ =>
+ (internal_error "STORE type not implemented in initial_analysis") : M (instruction_kind)
+ end >>= fun w__5 : instruction_kind =>
+ let ik : instruction_kind := w__5 in
+ returnm (Nias, aR, iR, ik, oR)
+ | ADDIW (imm,rs,rd) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ returnm (Nias, aR, iR, ik, oR)
+ | SHIFTW (imm,rs,rd,op) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ returnm (Nias, aR, iR, ik, oR)
+ | RTYPEW (rs2,rs1,rd,op) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ returnm (Nias, aR, iR, ik, oR)
+ | FENCE (pred,succ) =>
+ match (pred, succ) with
+ | (v__282, v__283) =>
+ (if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B1;B1] : mword 2)))) then
+ returnm ((IK_barrier Barrier_RISCV_rw_rw)
+ : instruction_kind)
+ else if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B1;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B1;B1] : mword 2)))) then
+ returnm ((IK_barrier Barrier_RISCV_r_rw)
+ : instruction_kind)
+ else if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B1;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ returnm ((IK_barrier Barrier_RISCV_r_r)
+ : instruction_kind)
+ else if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ returnm ((IK_barrier Barrier_RISCV_rw_w)
+ : instruction_kind)
+ else if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B0;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ returnm ((IK_barrier Barrier_RISCV_w_w)
+ : instruction_kind)
+ else if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B0;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B1;B1] : mword 2)))) then
+ returnm ((IK_barrier Barrier_RISCV_w_rw)
+ : instruction_kind)
+ else if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B1;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ returnm ((IK_barrier Barrier_RISCV_rw_r)
+ : instruction_kind)
+ else if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B1;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B0;B1] : mword 2)))) then
+ returnm ((IK_barrier Barrier_RISCV_r_w)
+ : instruction_kind)
+ else if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B0;B1] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B1;B0] : mword 2)))) then
+ returnm ((IK_barrier Barrier_RISCV_w_r)
+ : instruction_kind)
+ else if ((andb (eq_vec (subrange_vec_dec v__282 1 0) (vec_of_bits [B0;B0] : mword 2))
+ (eq_vec (subrange_vec_dec v__283 1 0) (vec_of_bits [B0;B0] : mword 2)))) then
+ returnm ((IK_simple tt)
+ : instruction_kind)
+ else
+ (internal_error "barrier type not implemented in initial_analysis")
+ : M (instruction_kind))
+ : M (instruction_kind)
+ end >>= fun w__17 : instruction_kind =>
+ let ik : instruction_kind := w__17 in
+ returnm (Nias, aR, iR, ik, oR)
+ | FENCEI (_) =>
+ let ik : instruction_kind := IK_simple tt in
+ returnm (Nias, aR, iR, ik, oR)
+ | LOADRES (aq,rl,rs1,width,rd) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ let aR := iR : regfps in
+ match (aq, rl) with
+ | (false, false) => returnm ((IK_mem_read Read_RISCV_reserved) : instruction_kind)
+ | (true, false) => returnm ((IK_mem_read Read_RISCV_reserved_acquire) : instruction_kind)
+ | (true, true) =>
+ returnm ((IK_mem_read Read_RISCV_reserved_strong_acquire) : instruction_kind)
+ | (false, true) =>
+ (internal_error "LOADRES type not implemented in initial_analysis") : M (instruction_kind)
+ end >>= fun w__19 : instruction_kind =>
+ let ik : instruction_kind := w__19 in
+ returnm (Nias, aR, iR, ik, oR)
+ | STORECON (aq,rl,rs2,rs1,width,rd) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let aR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ aR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ aR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ match (aq, rl) with
+ | (false, false) => returnm ((IK_mem_write Write_RISCV_conditional) : instruction_kind)
+ | (false, true) =>
+ returnm ((IK_mem_write Write_RISCV_conditional_release) : instruction_kind)
+ | (true, true) =>
+ returnm ((IK_mem_write Write_RISCV_conditional_strong_release) : instruction_kind)
+ | (true, false) =>
+ (internal_error "STORECON type not implemented in initial_analysis")
+ : M (instruction_kind)
+ end >>= fun w__21 : instruction_kind =>
+ let ik : instruction_kind := w__21 in
+ returnm (Nias, aR, iR, ik, oR)
+ | AMO (op,aq,rl,rs2,rs1,width,rd) =>
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs2)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let iR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ iR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ iR in
+ let aR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ aR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rs1)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ aR in
+ let oR : regfps :=
+ if sumbool_of_bool ((Z.eqb
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})) 0)) then
+ oR
+ else
+ (RFull (vec_access_dec GPRstr
+ (projT1 ((regbits_to_regno rd)
+ : {n : Z & ArithFact (0 <= n /\ (n + 1) <= 32)})))) ::
+ oR in
+ let ik : instruction_kind :=
+ match (aq, rl) with
+ | (false, false) => IK_mem_rmw (Read_RISCV_reserved,Write_RISCV_conditional)
+ | (false, true) => IK_mem_rmw (Read_RISCV_reserved,Write_RISCV_conditional_release)
+ | (true, false) => IK_mem_rmw (Read_RISCV_reserved_acquire,Write_RISCV_conditional)
+ | (true, true) => IK_mem_rmw (Read_RISCV_reserved_acquire,Write_RISCV_conditional_release)
+ end in
+ returnm (Nias, aR, iR, ik, oR)
+ | _ => returnm (Nias, aR, iR, ik, oR)
+ end >>= fun '(Nias, aR, iR, ik, oR) =>
+ returnm ((iR, oR, aR, Nias, Dia, ik)
+ : (list regfp * list regfp * list regfp * list niafp * diafp * instruction_kind)).
+*)
+Let initial_regstate : regstate :=
+{| tlb39 := None;
+ htif_exit_code :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ htif_done := false;
+ htif_tohost :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ mtimecmp :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ tselect :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ stval :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ scause :=
+ ({| Mcause_Mcause_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ sepc :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ sscratch :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ stvec :=
+ ({| Mtvec_Mtvec_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ satp :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ sideleg :=
+ ({| Sinterrupts_Sinterrupts_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ sedeleg :=
+ ({| Sedeleg_Sedeleg_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ pmpcfg0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ pmpaddr0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ mhartid :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ marchid :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ mimpid :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ mvendorid :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ minstret_written := false;
+ minstret :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ mtime :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ mcycle :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ scounteren :=
+ ({| Counteren_Counteren_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0]
+ : mword 32) |});
+ mcounteren :=
+ ({| Counteren_Counteren_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0]
+ : mword 32) |});
+ mscratch :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ mtval :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ mepc :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ mcause :=
+ ({| Mcause_Mcause_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ mtvec :=
+ ({| Mtvec_Mtvec_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ medeleg :=
+ ({| Medeleg_Medeleg_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ mideleg :=
+ ({| Minterrupts_Minterrupts_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ mie :=
+ ({| Minterrupts_Minterrupts_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ mip :=
+ ({| Minterrupts_Minterrupts_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ mstatus :=
+ ({| Mstatus_Mstatus_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ misa :=
+ ({| Misa_Misa_chunk_0 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |});
+ cur_inst :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ cur_privilege := User;
+ x31 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x30 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x29 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x28 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x27 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x26 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x25 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x24 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x23 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x22 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x21 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x20 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x19 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x18 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x17 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x16 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x15 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x14 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x13 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x12 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x11 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x10 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x9 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x8 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x7 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x6 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x5 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x4 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x3 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x2 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ x1 :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ Xs :=
+ (vec_of_list_len [(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);(vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64)]);
+ nextPC :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64);
+ PC :=
+ (vec_of_bits [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;
+ B0]
+ : mword 64) |}.
+
+End Content.
diff --git a/snapshots/coq-riscv/sail/riscv/riscv_extras.v b/snapshots/coq-riscv/sail/riscv/riscv_extras.v
new file mode 100644
index 00000000..3f1fe7e0
--- /dev/null
+++ b/snapshots/coq-riscv/sail/riscv/riscv_extras.v
@@ -0,0 +1,162 @@
+Require Import Sail2_instr_kinds.
+Require Import Sail2_values.
+Require Import Sail2_operators_mwords.
+Require Import Sail2_prompt_monad.
+Require Import Sail2_prompt.
+Require Import String.
+Require Import List.
+Import List.ListNotations.
+
+Axiom real : Type.
+
+(*
+val MEMr : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> monad 'regval 'b 'e
+val MEMr_reserve : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> monad 'regval 'b 'e
+val MEMr_tag : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> monad 'regval (bool * 'b) 'e
+val MEMr_tag_reserve : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> monad 'regval (bool * 'b) 'e
+*)
+Definition MEMr {regval a b e} `{ArithFact (b >= 0)} (addr : mword a) size : monad regval (mword b) e := read_mem Read_plain addr size.
+Definition MEMr_reserve {regval a b e} `{ArithFact (b >= 0)} (addr : mword a) size : monad regval (mword b) e := read_mem Read_reserve addr size.
+
+(*val read_tag_bool : forall 'regval 'a 'e. Bitvector 'a => 'a -> monad 'regval bool 'e*)
+Definition read_tag_bool {regval a e} (addr : mword a) : monad regval bool e :=
+ read_tag addr >>= fun t =>
+ maybe_fail "read_tag_bool" (bool_of_bitU t).
+
+(*val write_tag_bool : forall 'regval 'a 'e. Bitvector 'a => 'a -> bool -> monad 'regval unit 'e*)
+Definition write_tag_bool {regval a e} (addr : mword a) t : monad regval unit e :=
+ write_tag addr (bitU_of_bool t) >>= fun _ => returnm tt.
+
+Definition MEMr_tag {regval a b e} `{ArithFact (b >= 0)} (addr : mword a) size : monad regval (bool * mword b) e :=
+ read_mem Read_plain addr size >>= fun v =>
+ read_tag_bool addr >>= fun t =>
+ returnm (t, v).
+
+Definition MEMr_tag_reserve {regval a b e} `{ArithFact (b >= 0)} (addr : mword a) size : monad regval (bool * mword b) e :=
+ read_mem Read_plain addr size >>= fun v =>
+ read_tag_bool addr >>= fun t =>
+ returnm (t, v).
+
+(*
+val MEMea : forall 'regval 'a 'e. Bitvector 'a => 'a -> integer -> monad 'regval unit 'e
+val MEMea_conditional : forall 'regval 'a 'e. Bitvector 'a => 'a -> integer -> monad 'regval unit 'e
+val MEMea_tag : forall 'regval 'a 'e. Bitvector 'a => 'a -> integer -> monad 'regval unit 'e
+val MEMea_tag_conditional : forall 'regval 'a 'e. Bitvector 'a => 'a -> integer -> monad 'regval unit 'e
+*)
+Definition MEMea {regval a e} (addr : mword a) size : monad regval unit e := write_mem_ea Write_plain addr size.
+Definition MEMea_conditional {regval a e} (addr : mword a) size : monad regval unit e := write_mem_ea Write_conditional addr size.
+
+Definition MEMea_tag {regval a e} (addr : mword a) size : monad regval unit e := write_mem_ea Write_plain addr size.
+Definition MEMea_tag_conditional {regval a e} (addr : mword a) size : monad regval unit e := write_mem_ea Write_conditional addr size.
+
+(*
+val MEMval : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> 'b -> monad 'regval unit 'e
+val MEMval_conditional : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> 'b -> monad 'regval bool 'e
+val MEMval_tag : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> bool -> 'b -> monad 'regval unit 'e
+val MEMval_tag_conditional : forall 'regval 'a 'b 'e. Bitvector 'a, Bitvector 'b => 'a -> integer -> bool -> 'b -> monad 'regval bool 'e
+*)
+Definition MEMval {regval a b e} (_ : mword a) (size : Z) (v : mword b) : monad regval unit e := write_mem_val v >>= fun _ => returnm tt.
+Definition MEMval_conditional {regval a b e} (_ : mword a) (size : Z) (v : mword b) : monad regval bool e := write_mem_val v >>= fun b => returnm (if b then true else false).
+Definition MEMval_tag {regval a b e} (addr : mword a) (size : Z) t (v : mword b) : monad regval unit e := write_mem_val v >>= fun _ => write_tag_bool addr t >>= fun _ => returnm tt.
+Definition MEMval_tag_conditional {regval a b e} (addr : mword a) (size : Z) t (v : mword b) : monad regval bool e := write_mem_val v >>= fun b => write_tag_bool addr t >>= fun _ => returnm (if b then true else false).
+
+(*val MEM_sync : forall 'regval 'e. unit -> monad 'regval unit 'e*)
+
+Definition MEM_sync {regval e} (_:unit) : monad regval unit e := barrier Barrier_MIPS_SYNC.
+
+(* Some wrappers copied from aarch64_extras *)
+(* TODO: Harmonise into a common library *)
+(*
+Definition get_slice_int_bl len n lo :=
+ (* TODO: Is this the intended behaviour? *)
+ let hi := lo + len - 1 in
+ let bs := bools_of_int (hi + 1) n in
+ subrange_list false bs hi lo
+
+val get_slice_int : forall 'a. Bitvector 'a => integer -> integer -> integer -> 'a
+Definition get_slice_int len n lo := of_bools (get_slice_int_bl len n lo)
+*)
+Definition write_ram {rv e} m size (hexRAM : mword m) (addr : mword m) (data : mword (8 * size)) : monad rv bool e :=
+ write_mem_val data.
+
+Definition read_ram {rv e} m size `{ArithFact (size >= 0)} (_ : mword m) (addr : mword m) : monad rv (mword (8 * size)) e :=
+ read_mem Read_plain addr size.
+(*
+Definition string_of_bits bs := string_of_bv (bits_of bs).
+Definition string_of_int := show
+
+Definition _sign_extend bits len := maybe_failwith (of_bits (exts_bv len bits))
+Definition _zero_extend bits len := maybe_failwith (of_bits (extz_bv len bits))
+*)
+Definition shift_bits_left {a b} (v : mword a) (n : mword b) : mword a :=
+ shiftl v (int_of_mword false n).
+
+Definition shift_bits_right {a b} (v : mword a) (n : mword b) : mword a :=
+ shiftr v (int_of_mword false n).
+
+Definition shift_bits_right_arith {a b} (v : mword a) (n : mword b) : mword a :=
+ arith_shiftr v (int_of_mword false n).
+
+(* Use constants for undefined values for now *)
+Definition internal_pick {rv a e} (vs : list a) : monad rv a e :=
+match vs with
+| (h::_) => returnm h
+| _ => Fail "empty list in internal_pick"
+end.
+Definition undefined_string {rv e} (_:unit) : monad rv string e := returnm ""%string.
+Definition undefined_unit {rv e} (_:unit) : monad rv unit e := returnm tt.
+Definition undefined_int {rv e} (_:unit) : monad rv Z e := returnm (0:ii).
+(*val undefined_vector : forall 'rv 'a 'e. integer -> 'a -> monad 'rv (list 'a) 'e*)
+Definition undefined_vector {rv a e} len (u : a) `{ArithFact (len >= 0)} : monad rv (vec a len) e := returnm (vec_init u len).
+(*val undefined_bitvector : forall 'rv 'a 'e. Bitvector 'a => integer -> monad 'rv 'a 'e*)
+Definition undefined_bitvector {rv e} len `{ArithFact (len >= 0)} : monad rv (mword len) e := returnm (mword_of_int 0).
+(*val undefined_bits : forall 'rv 'a 'e. Bitvector 'a => integer -> monad 'rv 'a 'e*)
+Definition undefined_bits {rv e} := @undefined_bitvector rv e.
+Definition undefined_bit {rv e} (_:unit) : monad rv bitU e := returnm BU.
+(*Definition undefined_real {rv e} (_:unit) : monad rv real e := returnm (realFromFrac 0 1).*)
+Definition undefined_range {rv e} i j `{ArithFact (i <= j)} : monad rv {z : Z & ArithFact (i <= z /\ z <= j)} e := returnm (build_ex i).
+Definition undefined_atom {rv e} i : monad rv Z e := returnm i.
+Definition undefined_nat {rv e} (_:unit) : monad rv Z e := returnm (0:ii).
+
+Definition skip {rv e} (_:unit) : monad rv unit e := returnm tt.
+
+(*val elf_entry : unit -> integer*)
+Definition elf_entry (_:unit) : Z := 0.
+(*declare ocaml target_rep function elf_entry := `Elf_loader.elf_entry`*)
+
+Definition print_bits {n} msg (bs : mword n) := prerr_endline (msg ++ (string_of_bits bs)).
+
+(*val get_time_ns : unit -> integer*)
+Definition get_time_ns (_:unit) : Z := 0.
+(*declare ocaml target_rep function get_time_ns := `(fun () -> Big_int.of_int (int_of_float (1e9 *. Unix.gettimeofday ())))`*)
+
+Definition eq_bit (x : bitU) (y : bitU) : bool :=
+ match x, y with
+ | B0, B0 => true
+ | B1, B1 => true
+ | BU, BU => true
+ | _,_ => false
+ end.
+
+Require Import Zeuclid.
+Definition euclid_modulo (m n : Z) `{ArithFact (n > 0)} : {z : Z & ArithFact (0 <= z <= n-1)}.
+apply existT with (x := ZEuclid.modulo m n).
+constructor.
+destruct H.
+assert (Z.abs n = n). { rewrite Z.abs_eq; auto with zarith. }
+rewrite <- H at 3.
+lapply (ZEuclid.mod_always_pos m n); omega.
+Qed.
+
+(* Override the more general version *)
+
+Definition mults_vec {n} (l : mword n) (r : mword n) : mword (2 * n) := mults_vec l r.
+Definition mult_vec {n} (l : mword n) (r : mword n) : mword (2 * n) := mult_vec l r.
+
+
+Definition print_endline (_:string) : unit := tt.
+Definition prerr_endline (_:string) : unit := tt.
+Definition prerr_string (_:string) : unit := tt.
+Definition putchar {T} (_:T) : unit := tt.
+Require DecimalString.
+Definition string_of_int z := DecimalString.NilZero.string_of_int (Z.to_int z).
diff --git a/snapshots/coq-riscv/sail/riscv/riscv_types.v b/snapshots/coq-riscv/sail/riscv/riscv_types.v
new file mode 100644
index 00000000..2bcebd62
--- /dev/null
+++ b/snapshots/coq-riscv/sail/riscv/riscv_types.v
@@ -0,0 +1,1387 @@
+(*Generated by Sail from riscv.*)
+Require Import Sail2_instr_kinds.
+Require Import Sail2_values.
+Require Import Sail2_string.
+Require Import Sail2_operators_mwords.
+Require Import Sail2_prompt_monad.
+Require Import Sail2_prompt.
+Require Import Sail2_state.
+Definition bits (n : Z) : Type := mword n.
+
+
+
+Definition xlenbits : Type := bits 64.
+
+Definition half : Type := bits 16.
+
+Definition word : Type := bits 32.
+
+Definition regbits : Type := bits 5.
+
+Definition cregbits : Type := bits 3.
+
+Definition csreg : Type := bits 12.
+
+Definition regno (n : Z)`{ArithFact (0 <= n /\ (n + 1) <= 32)} : Type := Z.
+
+Definition opcode : Type := bits 7.
+
+Definition imm12 : Type := bits 12.
+
+Definition imm20 : Type := bits 20.
+
+Definition amo : Type := bits 1.
+
+Inductive Architecture := RV32 | RV64 | RV128.
+Scheme Equality for Architecture.
+Instance Decidable_eq_Architecture : forall (x y : Architecture), Decidable (x = y) :=
+Decidable_eq_from_dec Architecture_eq_dec.
+
+
+Definition arch_xlen : Type := bits 2.
+
+Definition priv_level : Type := bits 2.
+
+Inductive Privilege := User | Supervisor | Machine.
+Scheme Equality for Privilege.
+Instance Decidable_eq_Privilege : forall (x y : Privilege), Decidable (x = y) :=
+Decidable_eq_from_dec Privilege_eq_dec.
+
+
+Inductive AccessType := Read | Write | ReadWrite | Execute.
+Scheme Equality for AccessType.
+Instance Decidable_eq_AccessType : forall (x y : AccessType), Decidable (x = y) :=
+Decidable_eq_from_dec AccessType_eq_dec.
+
+
+Inductive ReadType := Instruction | Data.
+Scheme Equality for ReadType.
+Instance Decidable_eq_ReadType : forall (x y : ReadType), Decidable (x = y) :=
+Decidable_eq_from_dec ReadType_eq_dec.
+
+
+Inductive word_width := BYTE | HALF | WORD | DOUBLE.
+Scheme Equality for word_width.
+Instance Decidable_eq_word_width : forall (x y : word_width), Decidable (x = y) :=
+Decidable_eq_from_dec word_width_eq_dec.
+
+
+Definition exc_code : Type := bits 4.
+
+Inductive InterruptType :=
+ I_U_Software
+ | I_S_Software
+ | I_M_Software
+ | I_U_Timer
+ | I_S_Timer
+ | I_M_Timer
+ | I_U_External
+ | I_S_External
+ | I_M_External.
+Scheme Equality for InterruptType.
+Instance Decidable_eq_InterruptType : forall (x y : InterruptType), Decidable (x = y) :=
+Decidable_eq_from_dec InterruptType_eq_dec.
+
+
+Inductive ExceptionType :=
+ E_Fetch_Addr_Align
+ | E_Fetch_Access_Fault
+ | E_Illegal_Instr
+ | E_Breakpoint
+ | E_Load_Addr_Align
+ | E_Load_Access_Fault
+ | E_SAMO_Addr_Align
+ | E_SAMO_Access_Fault
+ | E_U_EnvCall
+ | E_S_EnvCall
+ | E_Reserved_10
+ | E_M_EnvCall
+ | E_Fetch_Page_Fault
+ | E_Load_Page_Fault
+ | E_Reserved_14
+ | E_SAMO_Page_Fault.
+Scheme Equality for ExceptionType.
+Instance Decidable_eq_ExceptionType : forall (x y : ExceptionType), Decidable (x = y) :=
+Decidable_eq_from_dec ExceptionType_eq_dec.
+
+
+Inductive exception :=
+ Error_not_implemented : string -> exception | Error_internal_error : unit -> exception.
+Arguments exception : clear implicits.
+
+
+
+Definition tv_mode : Type := bits 2.
+
+Inductive TrapVectorMode := TV_Direct | TV_Vector | TV_Reserved.
+Scheme Equality for TrapVectorMode.
+Instance Decidable_eq_TrapVectorMode : forall (x y : TrapVectorMode), Decidable (x = y) :=
+Decidable_eq_from_dec TrapVectorMode_eq_dec.
+
+
+Definition ext_status : Type := bits 2.
+
+Inductive ExtStatus := Off | Initial | Clean | Dirty.
+Scheme Equality for ExtStatus.
+Instance Decidable_eq_ExtStatus : forall (x y : ExtStatus), Decidable (x = y) :=
+Decidable_eq_from_dec ExtStatus_eq_dec.
+
+
+Definition satp_mode : Type := bits 4.
+
+Inductive SATPMode := Sbare | Sv32 | Sv39.
+Scheme Equality for SATPMode.
+Instance Decidable_eq_SATPMode : forall (x y : SATPMode), Decidable (x = y) :=
+Decidable_eq_from_dec SATPMode_eq_dec.
+
+
+Definition csrRW : Type := bits 2.
+
+Inductive uop := RISCV_LUI | RISCV_AUIPC.
+Scheme Equality for uop.
+Instance Decidable_eq_uop : forall (x y : uop), Decidable (x = y) :=
+Decidable_eq_from_dec uop_eq_dec.
+
+
+Inductive bop := RISCV_BEQ | RISCV_BNE | RISCV_BLT | RISCV_BGE | RISCV_BLTU | RISCV_BGEU.
+Scheme Equality for bop.
+Instance Decidable_eq_bop : forall (x y : bop), Decidable (x = y) :=
+Decidable_eq_from_dec bop_eq_dec.
+
+
+Inductive iop := RISCV_ADDI | RISCV_SLTI | RISCV_SLTIU | RISCV_XORI | RISCV_ORI | RISCV_ANDI.
+Scheme Equality for iop.
+Instance Decidable_eq_iop : forall (x y : iop), Decidable (x = y) :=
+Decidable_eq_from_dec iop_eq_dec.
+
+
+Inductive sop := RISCV_SLLI | RISCV_SRLI | RISCV_SRAI.
+Scheme Equality for sop.
+Instance Decidable_eq_sop : forall (x y : sop), Decidable (x = y) :=
+Decidable_eq_from_dec sop_eq_dec.
+
+
+Inductive rop :=
+ RISCV_ADD
+ | RISCV_SUB
+ | RISCV_SLL
+ | RISCV_SLT
+ | RISCV_SLTU
+ | RISCV_XOR
+ | RISCV_SRL
+ | RISCV_SRA
+ | RISCV_OR
+ | RISCV_AND.
+Scheme Equality for rop.
+Instance Decidable_eq_rop : forall (x y : rop), Decidable (x = y) :=
+Decidable_eq_from_dec rop_eq_dec.
+
+
+Inductive ropw := RISCV_ADDW | RISCV_SUBW | RISCV_SLLW | RISCV_SRLW | RISCV_SRAW.
+Scheme Equality for ropw.
+Instance Decidable_eq_ropw : forall (x y : ropw), Decidable (x = y) :=
+Decidable_eq_from_dec ropw_eq_dec.
+
+
+Inductive sopw := RISCV_SLLIW | RISCV_SRLIW | RISCV_SRAIW.
+Scheme Equality for sopw.
+Instance Decidable_eq_sopw : forall (x y : sopw), Decidable (x = y) :=
+Decidable_eq_from_dec sopw_eq_dec.
+
+
+Inductive amoop := AMOSWAP | AMOADD | AMOXOR | AMOAND | AMOOR | AMOMIN | AMOMAX | AMOMINU | AMOMAXU.
+Scheme Equality for amoop.
+Instance Decidable_eq_amoop : forall (x y : amoop), Decidable (x = y) :=
+Decidable_eq_from_dec amoop_eq_dec.
+
+
+Inductive csrop := CSRRW | CSRRS | CSRRC.
+Scheme Equality for csrop.
+Instance Decidable_eq_csrop : forall (x y : csrop), Decidable (x = y) :=
+Decidable_eq_from_dec csrop_eq_dec.
+
+
+Record Misa := { Misa_Misa_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Misa_Misa_chunk_0' := e ]}" := ({| Misa_Misa_chunk_0 := e |}).
+
+Record SV39_PTE := { SV39_PTE_SV39_PTE_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'SV39_PTE_SV39_PTE_chunk_0' := e ]}" := ({| SV39_PTE_SV39_PTE_chunk_0 := e |}).
+
+Record PTE_Bits := { PTE_Bits_PTE_Bits_chunk_0 : mword 8; }.
+Notation "{[ r 'with' 'PTE_Bits_PTE_Bits_chunk_0' := e ]}" := ({| PTE_Bits_PTE_Bits_chunk_0 := e |}).
+
+Record Mstatus := { Mstatus_Mstatus_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Mstatus_Mstatus_chunk_0' := e ]}" := ({| Mstatus_Mstatus_chunk_0 := e |}).
+
+Record Sstatus := { Sstatus_Sstatus_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Sstatus_Sstatus_chunk_0' := e ]}" := ({| Sstatus_Sstatus_chunk_0 := e |}).
+
+Record Minterrupts := { Minterrupts_Minterrupts_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Minterrupts_Minterrupts_chunk_0' := e ]}" := ({| Minterrupts_Minterrupts_chunk_0 := e |}).
+
+Record Sinterrupts := { Sinterrupts_Sinterrupts_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Sinterrupts_Sinterrupts_chunk_0' := e ]}" := ({| Sinterrupts_Sinterrupts_chunk_0 := e |}).
+
+Record Medeleg := { Medeleg_Medeleg_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Medeleg_Medeleg_chunk_0' := e ]}" := ({| Medeleg_Medeleg_chunk_0 := e |}).
+
+Record Sedeleg := { Sedeleg_Sedeleg_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Sedeleg_Sedeleg_chunk_0' := e ]}" := ({| Sedeleg_Sedeleg_chunk_0 := e |}).
+
+Record Mtvec := { Mtvec_Mtvec_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Mtvec_Mtvec_chunk_0' := e ]}" := ({| Mtvec_Mtvec_chunk_0 := e |}).
+
+Record Satp64 := { Satp64_Satp64_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Satp64_Satp64_chunk_0' := e ]}" := ({| Satp64_Satp64_chunk_0 := e |}).
+
+Record Mcause := { Mcause_Mcause_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'Mcause_Mcause_chunk_0' := e ]}" := ({| Mcause_Mcause_chunk_0 := e |}).
+
+Record Counteren := { Counteren_Counteren_chunk_0 : mword 32; }.
+Notation "{[ r 'with' 'Counteren_Counteren_chunk_0' := e ]}" := ({| Counteren_Counteren_chunk_0 := e |}).
+
+Record sync_exception :=
+ { sync_exception_trap : ExceptionType; sync_exception_excinfo : option xlenbits; }.
+Notation "{[ r 'with' 'sync_exception_trap' := e ]}" := ({| sync_exception_trap := e; sync_exception_excinfo := sync_exception_excinfo r |}).
+Notation "{[ r 'with' 'sync_exception_excinfo' := e ]}" := ({| sync_exception_excinfo := e; sync_exception_trap := sync_exception_trap r |}).
+
+Inductive ctl_result :=
+ CTL_TRAP : sync_exception -> ctl_result
+ | CTL_SRET : unit -> ctl_result
+ | CTL_MRET : unit -> ctl_result.
+Arguments ctl_result : clear implicits.
+
+
+
+Inductive MemoryOpResult {a : Type} :=
+ MemValue : a -> MemoryOpResult | MemException : ExceptionType -> MemoryOpResult.
+Arguments MemoryOpResult : clear implicits.
+
+
+
+Record htif_cmd := { htif_cmd_htif_cmd_chunk_0 : mword 64; }.
+Notation "{[ r 'with' 'htif_cmd_htif_cmd_chunk_0' := e ]}" := ({| htif_cmd_htif_cmd_chunk_0 := e |}).
+
+Definition pteAttribs : Type := bits 8.
+
+Inductive PTW_Error :=
+ PTW_Access | PTW_Invalid_PTE | PTW_No_Permission | PTW_Misaligned | PTW_PTE_Update.
+Scheme Equality for PTW_Error.
+Instance Decidable_eq_PTW_Error : forall (x y : PTW_Error), Decidable (x = y) :=
+Decidable_eq_from_dec PTW_Error_eq_dec.
+
+
+Definition vaddr39 : Type := bits 39.
+
+Definition paddr39 : Type := bits 56.
+
+Definition pte39 : Type := xlenbits.
+
+Record SV39_Vaddr := { SV39_Vaddr_SV39_Vaddr_chunk_0 : mword 39; }.
+Notation "{[ r 'with' 'SV39_Vaddr_SV39_Vaddr_chunk_0' := e ]}" := ({| SV39_Vaddr_SV39_Vaddr_chunk_0 := e |}).
+
+Record SV39_Paddr := { SV39_Paddr_SV39_Paddr_chunk_0 : mword 56; }.
+Notation "{[ r 'with' 'SV39_Paddr_SV39_Paddr_chunk_0' := e ]}" := ({| SV39_Paddr_SV39_Paddr_chunk_0 := e |}).
+
+Definition asid64 : Type := bits 16.
+
+Inductive PTW_Result :=
+ PTW_Success : (paddr39 * SV39_PTE * paddr39 * {n : Z & ArithFact (n >= 0)} * bool) -> PTW_Result
+ | PTW_Failure : PTW_Error -> PTW_Result.
+Arguments PTW_Result : clear implicits.
+
+
+
+Record TLB39_Entry :=
+ { TLB39_Entry_asid : asid64;
+ TLB39_Entry_global : bool;
+ TLB39_Entry_vAddr : vaddr39;
+ TLB39_Entry_pAddr : paddr39;
+ TLB39_Entry_vMatchMask : vaddr39;
+ TLB39_Entry_vAddrMask : vaddr39;
+ TLB39_Entry_pte : SV39_PTE;
+ TLB39_Entry_pteAddr : paddr39;
+ TLB39_Entry_age : xlenbits; }.
+Notation "{[ r 'with' 'TLB39_Entry_asid' := e ]}" := ({| TLB39_Entry_asid := e; TLB39_Entry_global := TLB39_Entry_global r; TLB39_Entry_vAddr := TLB39_Entry_vAddr r; TLB39_Entry_pAddr := TLB39_Entry_pAddr r; TLB39_Entry_vMatchMask := TLB39_Entry_vMatchMask r; TLB39_Entry_vAddrMask := TLB39_Entry_vAddrMask r; TLB39_Entry_pte := TLB39_Entry_pte r; TLB39_Entry_pteAddr := TLB39_Entry_pteAddr r; TLB39_Entry_age := TLB39_Entry_age r |}).
+Notation "{[ r 'with' 'TLB39_Entry_global' := e ]}" := ({| TLB39_Entry_global := e; TLB39_Entry_asid := TLB39_Entry_asid r; TLB39_Entry_vAddr := TLB39_Entry_vAddr r; TLB39_Entry_pAddr := TLB39_Entry_pAddr r; TLB39_Entry_vMatchMask := TLB39_Entry_vMatchMask r; TLB39_Entry_vAddrMask := TLB39_Entry_vAddrMask r; TLB39_Entry_pte := TLB39_Entry_pte r; TLB39_Entry_pteAddr := TLB39_Entry_pteAddr r; TLB39_Entry_age := TLB39_Entry_age r |}).
+Notation "{[ r 'with' 'TLB39_Entry_vAddr' := e ]}" := ({| TLB39_Entry_vAddr := e; TLB39_Entry_asid := TLB39_Entry_asid r; TLB39_Entry_global := TLB39_Entry_global r; TLB39_Entry_pAddr := TLB39_Entry_pAddr r; TLB39_Entry_vMatchMask := TLB39_Entry_vMatchMask r; TLB39_Entry_vAddrMask := TLB39_Entry_vAddrMask r; TLB39_Entry_pte := TLB39_Entry_pte r; TLB39_Entry_pteAddr := TLB39_Entry_pteAddr r; TLB39_Entry_age := TLB39_Entry_age r |}).
+Notation "{[ r 'with' 'TLB39_Entry_pAddr' := e ]}" := ({| TLB39_Entry_pAddr := e; TLB39_Entry_asid := TLB39_Entry_asid r; TLB39_Entry_global := TLB39_Entry_global r; TLB39_Entry_vAddr := TLB39_Entry_vAddr r; TLB39_Entry_vMatchMask := TLB39_Entry_vMatchMask r; TLB39_Entry_vAddrMask := TLB39_Entry_vAddrMask r; TLB39_Entry_pte := TLB39_Entry_pte r; TLB39_Entry_pteAddr := TLB39_Entry_pteAddr r; TLB39_Entry_age := TLB39_Entry_age r |}).
+Notation "{[ r 'with' 'TLB39_Entry_vMatchMask' := e ]}" := ({| TLB39_Entry_vMatchMask := e; TLB39_Entry_asid := TLB39_Entry_asid r; TLB39_Entry_global := TLB39_Entry_global r; TLB39_Entry_vAddr := TLB39_Entry_vAddr r; TLB39_Entry_pAddr := TLB39_Entry_pAddr r; TLB39_Entry_vAddrMask := TLB39_Entry_vAddrMask r; TLB39_Entry_pte := TLB39_Entry_pte r; TLB39_Entry_pteAddr := TLB39_Entry_pteAddr r; TLB39_Entry_age := TLB39_Entry_age r |}).
+Notation "{[ r 'with' 'TLB39_Entry_vAddrMask' := e ]}" := ({| TLB39_Entry_vAddrMask := e; TLB39_Entry_asid := TLB39_Entry_asid r; TLB39_Entry_global := TLB39_Entry_global r; TLB39_Entry_vAddr := TLB39_Entry_vAddr r; TLB39_Entry_pAddr := TLB39_Entry_pAddr r; TLB39_Entry_vMatchMask := TLB39_Entry_vMatchMask r; TLB39_Entry_pte := TLB39_Entry_pte r; TLB39_Entry_pteAddr := TLB39_Entry_pteAddr r; TLB39_Entry_age := TLB39_Entry_age r |}).
+Notation "{[ r 'with' 'TLB39_Entry_pte' := e ]}" := ({| TLB39_Entry_pte := e; TLB39_Entry_asid := TLB39_Entry_asid r; TLB39_Entry_global := TLB39_Entry_global r; TLB39_Entry_vAddr := TLB39_Entry_vAddr r; TLB39_Entry_pAddr := TLB39_Entry_pAddr r; TLB39_Entry_vMatchMask := TLB39_Entry_vMatchMask r; TLB39_Entry_vAddrMask := TLB39_Entry_vAddrMask r; TLB39_Entry_pteAddr := TLB39_Entry_pteAddr r; TLB39_Entry_age := TLB39_Entry_age r |}).
+Notation "{[ r 'with' 'TLB39_Entry_pteAddr' := e ]}" := ({| TLB39_Entry_pteAddr := e; TLB39_Entry_asid := TLB39_Entry_asid r; TLB39_Entry_global := TLB39_Entry_global r; TLB39_Entry_vAddr := TLB39_Entry_vAddr r; TLB39_Entry_pAddr := TLB39_Entry_pAddr r; TLB39_Entry_vMatchMask := TLB39_Entry_vMatchMask r; TLB39_Entry_vAddrMask := TLB39_Entry_vAddrMask r; TLB39_Entry_pte := TLB39_Entry_pte r; TLB39_Entry_age := TLB39_Entry_age r |}).
+Notation "{[ r 'with' 'TLB39_Entry_age' := e ]}" := ({| TLB39_Entry_age := e; TLB39_Entry_asid := TLB39_Entry_asid r; TLB39_Entry_global := TLB39_Entry_global r; TLB39_Entry_vAddr := TLB39_Entry_vAddr r; TLB39_Entry_pAddr := TLB39_Entry_pAddr r; TLB39_Entry_vMatchMask := TLB39_Entry_vMatchMask r; TLB39_Entry_vAddrMask := TLB39_Entry_vAddrMask r; TLB39_Entry_pte := TLB39_Entry_pte r; TLB39_Entry_pteAddr := TLB39_Entry_pteAddr r |}).
+
+Inductive TR39_Result :=
+ TR39_Address : paddr39 -> TR39_Result | TR39_Failure : PTW_Error -> TR39_Result.
+Arguments TR39_Result : clear implicits.
+
+
+
+Inductive TR_Result := TR_Address : xlenbits -> TR_Result | TR_Failure : ExceptionType -> TR_Result.
+Arguments TR_Result : clear implicits.
+
+
+
+Inductive ast :=
+ UTYPE : (bits 20 * regbits * uop) -> ast
+ | RISCV_JAL : (bits 21 * regbits) -> ast
+ | RISCV_JALR : (bits 12 * regbits * regbits) -> ast
+ | BTYPE : (bits 13 * regbits * regbits * bop) -> ast
+ | ITYPE : (bits 12 * regbits * regbits * iop) -> ast
+ | SHIFTIOP : (bits 6 * regbits * regbits * sop) -> ast
+ | RTYPE : (regbits * regbits * regbits * rop) -> ast
+ | LOAD : (bits 12 * regbits * regbits * bool * word_width * bool * bool) -> ast
+ | STORE : (bits 12 * regbits * regbits * word_width * bool * bool) -> ast
+ | ADDIW : (bits 12 * regbits * regbits) -> ast
+ | SHIFTW : (bits 5 * regbits * regbits * sop) -> ast
+ | RTYPEW : (regbits * regbits * regbits * ropw) -> ast
+ | SHIFTIWOP : (bits 5 * regbits * regbits * sopw) -> ast
+ | MUL : (regbits * regbits * regbits * bool * bool * bool) -> ast
+ | DIV : (regbits * regbits * regbits * bool) -> ast
+ | REM : (regbits * regbits * regbits * bool) -> ast
+ | MULW : (regbits * regbits * regbits) -> ast
+ | DIVW : (regbits * regbits * regbits * bool) -> ast
+ | REMW : (regbits * regbits * regbits * bool) -> ast
+ | FENCE : (bits 4 * bits 4) -> ast
+ | FENCEI : unit -> ast
+ | ECALL : unit -> ast
+ | MRET : unit -> ast
+ | SRET : unit -> ast
+ | EBREAK : unit -> ast
+ | WFI : unit -> ast
+ | SFENCE_VMA : (regbits * regbits) -> ast
+ | LOADRES : (bool * bool * regbits * word_width * regbits) -> ast
+ | STORECON : (bool * bool * regbits * regbits * word_width * regbits) -> ast
+ | AMO : (amoop * bool * bool * regbits * regbits * word_width * regbits) -> ast
+ | CSR : (bits 12 * regbits * regbits * bool * csrop) -> ast
+ | NOP : unit -> ast
+ | C_ADDI4SPN : (cregbits * bits 8) -> ast
+ | C_LW : (bits 5 * cregbits * cregbits) -> ast
+ | C_LD : (bits 5 * cregbits * cregbits) -> ast
+ | C_SW : (bits 5 * cregbits * cregbits) -> ast
+ | C_SD : (bits 5 * cregbits * cregbits) -> ast
+ | C_ADDI : (bits 6 * regbits) -> ast
+ | C_JAL : bits 11 -> ast
+ | C_ADDIW : (bits 6 * regbits) -> ast
+ | C_LI : (bits 6 * regbits) -> ast
+ | C_ADDI16SP : bits 6 -> ast
+ | C_LUI : (bits 6 * regbits) -> ast
+ | C_SRLI : (bits 6 * cregbits) -> ast
+ | C_SRAI : (bits 6 * cregbits) -> ast
+ | C_ANDI : (bits 6 * cregbits) -> ast
+ | C_SUB : (cregbits * cregbits) -> ast
+ | C_XOR : (cregbits * cregbits) -> ast
+ | C_OR : (cregbits * cregbits) -> ast
+ | C_AND : (cregbits * cregbits) -> ast
+ | C_SUBW : (cregbits * cregbits) -> ast
+ | C_ADDW : (cregbits * cregbits) -> ast
+ | C_J : bits 11 -> ast
+ | C_BEQZ : (bits 8 * cregbits) -> ast
+ | C_BNEZ : (bits 8 * cregbits) -> ast
+ | C_SLLI : (bits 6 * regbits) -> ast
+ | C_LWSP : (bits 6 * regbits) -> ast
+ | C_LDSP : (bits 6 * regbits) -> ast
+ | C_SWSP : (bits 6 * regbits) -> ast
+ | C_SDSP : (bits 6 * regbits) -> ast
+ | C_JR : regbits -> ast
+ | C_JALR : regbits -> ast
+ | C_MV : (regbits * regbits) -> ast
+ | C_ADD : (regbits * regbits) -> ast
+ | STOP_FETCHING : unit -> ast
+ | THREAD_START : unit -> ast
+ | ILLEGAL : word -> ast
+ | C_ILLEGAL : unit -> ast.
+Arguments ast : clear implicits.
+
+
+
+Inductive FetchResult :=
+ F_Base : word -> FetchResult
+ | F_RVC : half -> FetchResult
+ | F_Error : (ExceptionType * xlenbits) -> FetchResult.
+Arguments FetchResult : clear implicits.
+
+
+
+Inductive regfp :=
+ RFull : string -> regfp
+ | RSlice : (string * {n : Z & ArithFact (n >= 0)} * {n : Z & ArithFact (n >= 0)}) -> regfp
+ | RSliceBit : (string * {n : Z & ArithFact (n >= 0)}) -> regfp
+ | RField : (string * string) -> regfp.
+Arguments regfp : clear implicits.
+
+
+
+Definition regfps : Type := list regfp.
+
+Inductive niafp :=
+ NIAFP_successor : unit -> niafp
+ | NIAFP_concrete_address : bits 64 -> niafp
+ | NIAFP_indirect_address : unit -> niafp.
+Arguments niafp : clear implicits.
+
+
+
+Definition niafps : Type := list niafp.
+
+Inductive diafp :=
+ DIAFP_none : unit -> diafp | DIAFP_concrete : bits 64 -> diafp | DIAFP_reg : regfp -> diafp.
+Arguments diafp : clear implicits.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Inductive register_value :=
+ Regval_vector : (Z * bool * list register_value) -> register_value
+ | Regval_list : list register_value -> register_value
+ | Regval_option : option register_value -> register_value
+ | Regval_Counteren : Counteren -> register_value
+ | Regval_Mcause : Mcause -> register_value
+ | Regval_Medeleg : Medeleg -> register_value
+ | Regval_Minterrupts : Minterrupts -> register_value
+ | Regval_Misa : Misa -> register_value
+ | Regval_Mstatus : Mstatus -> register_value
+ | Regval_Mtvec : Mtvec -> register_value
+ | Regval_Privilege : Privilege -> register_value
+ | Regval_Sedeleg : Sedeleg -> register_value
+ | Regval_Sinterrupts : Sinterrupts -> register_value
+ | Regval_TLB39_Entry : TLB39_Entry -> register_value
+ | Regval_bool : bool -> register_value
+ | Regval_vector_64_dec_bit : mword 64 -> register_value.
+Arguments register_value : clear implicits.
+
+
+
+Record regstate :=
+ { tlb39 : option TLB39_Entry;
+ htif_exit_code : mword 64;
+ htif_done : bool;
+ htif_tohost : mword 64;
+ mtimecmp : mword 64;
+ tselect : mword 64;
+ stval : mword 64;
+ scause : Mcause;
+ sepc : mword 64;
+ sscratch : mword 64;
+ stvec : Mtvec;
+ satp : mword 64;
+ sideleg : Sinterrupts;
+ sedeleg : Sedeleg;
+ pmpcfg0 : mword 64;
+ pmpaddr0 : mword 64;
+ mhartid : mword 64;
+ marchid : mword 64;
+ mimpid : mword 64;
+ mvendorid : mword 64;
+ minstret_written : bool;
+ minstret : mword 64;
+ mtime : mword 64;
+ mcycle : mword 64;
+ scounteren : Counteren;
+ mcounteren : Counteren;
+ mscratch : mword 64;
+ mtval : mword 64;
+ mepc : mword 64;
+ mcause : Mcause;
+ mtvec : Mtvec;
+ medeleg : Medeleg;
+ mideleg : Minterrupts;
+ mie : Minterrupts;
+ mip : Minterrupts;
+ mstatus : Mstatus;
+ misa : Misa;
+ cur_inst : mword 64;
+ cur_privilege : Privilege;
+ x31 : mword 64;
+ x30 : mword 64;
+ x29 : mword 64;
+ x28 : mword 64;
+ x27 : mword 64;
+ x26 : mword 64;
+ x25 : mword 64;
+ x24 : mword 64;
+ x23 : mword 64;
+ x22 : mword 64;
+ x21 : mword 64;
+ x20 : mword 64;
+ x19 : mword 64;
+ x18 : mword 64;
+ x17 : mword 64;
+ x16 : mword 64;
+ x15 : mword 64;
+ x14 : mword 64;
+ x13 : mword 64;
+ x12 : mword 64;
+ x11 : mword 64;
+ x10 : mword 64;
+ x9 : mword 64;
+ x8 : mword 64;
+ x7 : mword 64;
+ x6 : mword 64;
+ x5 : mword 64;
+ x4 : mword 64;
+ x3 : mword 64;
+ x2 : mword 64;
+ x1 : mword 64;
+ Xs : vec (mword 64) 32;
+ nextPC : mword 64;
+ PC : mword 64; }.
+Notation "{[ r 'with' 'tlb39' := e ]}" := ({| tlb39 := e; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'htif_exit_code' := e ]}" := ({| htif_exit_code := e; tlb39 := tlb39 r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'htif_done' := e ]}" := ({| htif_done := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'htif_tohost' := e ]}" := ({| htif_tohost := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mtimecmp' := e ]}" := ({| mtimecmp := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'tselect' := e ]}" := ({| tselect := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'stval' := e ]}" := ({| stval := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'scause' := e ]}" := ({| scause := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'sepc' := e ]}" := ({| sepc := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'sscratch' := e ]}" := ({| sscratch := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'stvec' := e ]}" := ({| stvec := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'satp' := e ]}" := ({| satp := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'sideleg' := e ]}" := ({| sideleg := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'sedeleg' := e ]}" := ({| sedeleg := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'pmpcfg0' := e ]}" := ({| pmpcfg0 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'pmpaddr0' := e ]}" := ({| pmpaddr0 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mhartid' := e ]}" := ({| mhartid := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'marchid' := e ]}" := ({| marchid := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mimpid' := e ]}" := ({| mimpid := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mvendorid' := e ]}" := ({| mvendorid := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'minstret_written' := e ]}" := ({| minstret_written := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'minstret' := e ]}" := ({| minstret := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mtime' := e ]}" := ({| mtime := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mcycle' := e ]}" := ({| mcycle := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'scounteren' := e ]}" := ({| scounteren := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mcounteren' := e ]}" := ({| mcounteren := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mscratch' := e ]}" := ({| mscratch := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mtval' := e ]}" := ({| mtval := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mepc' := e ]}" := ({| mepc := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mcause' := e ]}" := ({| mcause := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mtvec' := e ]}" := ({| mtvec := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'medeleg' := e ]}" := ({| medeleg := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mideleg' := e ]}" := ({| mideleg := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mie' := e ]}" := ({| mie := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mip' := e ]}" := ({| mip := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'mstatus' := e ]}" := ({| mstatus := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'misa' := e ]}" := ({| misa := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'cur_inst' := e ]}" := ({| cur_inst := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'cur_privilege' := e ]}" := ({| cur_privilege := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x31' := e ]}" := ({| x31 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x30' := e ]}" := ({| x30 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x29' := e ]}" := ({| x29 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x28' := e ]}" := ({| x28 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x27' := e ]}" := ({| x27 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x26' := e ]}" := ({| x26 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x25' := e ]}" := ({| x25 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x24' := e ]}" := ({| x24 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x23' := e ]}" := ({| x23 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x22' := e ]}" := ({| x22 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x21' := e ]}" := ({| x21 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x20' := e ]}" := ({| x20 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x19' := e ]}" := ({| x19 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x18' := e ]}" := ({| x18 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x17' := e ]}" := ({| x17 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x16' := e ]}" := ({| x16 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x15' := e ]}" := ({| x15 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x14' := e ]}" := ({| x14 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x13' := e ]}" := ({| x13 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x12' := e ]}" := ({| x12 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x11' := e ]}" := ({| x11 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x10' := e ]}" := ({| x10 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x9' := e ]}" := ({| x9 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x8' := e ]}" := ({| x8 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x7' := e ]}" := ({| x7 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x6' := e ]}" := ({| x6 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x5' := e ]}" := ({| x5 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x4' := e ]}" := ({| x4 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x3' := e ]}" := ({| x3 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x2' := e ]}" := ({| x2 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'x1' := e ]}" := ({| x1 := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; Xs := Xs r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'Xs' := e ]}" := ({| Xs := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; nextPC := nextPC r; PC := PC r |}).
+Notation "{[ r 'with' 'nextPC' := e ]}" := ({| nextPC := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; PC := PC r |}).
+Notation "{[ r 'with' 'PC' := e ]}" := ({| PC := e; tlb39 := tlb39 r; htif_exit_code := htif_exit_code r; htif_done := htif_done r; htif_tohost := htif_tohost r; mtimecmp := mtimecmp r; tselect := tselect r; stval := stval r; scause := scause r; sepc := sepc r; sscratch := sscratch r; stvec := stvec r; satp := satp r; sideleg := sideleg r; sedeleg := sedeleg r; pmpcfg0 := pmpcfg0 r; pmpaddr0 := pmpaddr0 r; mhartid := mhartid r; marchid := marchid r; mimpid := mimpid r; mvendorid := mvendorid r; minstret_written := minstret_written r; minstret := minstret r; mtime := mtime r; mcycle := mcycle r; scounteren := scounteren r; mcounteren := mcounteren r; mscratch := mscratch r; mtval := mtval r; mepc := mepc r; mcause := mcause r; mtvec := mtvec r; medeleg := medeleg r; mideleg := mideleg r; mie := mie r; mip := mip r; mstatus := mstatus r; misa := misa r; cur_inst := cur_inst r; cur_privilege := cur_privilege r; x31 := x31 r; x30 := x30 r; x29 := x29 r; x28 := x28 r; x27 := x27 r; x26 := x26 r; x25 := x25 r; x24 := x24 r; x23 := x23 r; x22 := x22 r; x21 := x21 r; x20 := x20 r; x19 := x19 r; x18 := x18 r; x17 := x17 r; x16 := x16 r; x15 := x15 r; x14 := x14 r; x13 := x13 r; x12 := x12 r; x11 := x11 r; x10 := x10 r; x9 := x9 r; x8 := x8 r; x7 := x7 r; x6 := x6 r; x5 := x5 r; x4 := x4 r; x3 := x3 r; x2 := x2 r; x1 := x1 r; Xs := Xs r; nextPC := nextPC r |}).
+
+
+
+Definition Counteren_of_regval (merge_var : register_value)
+: option Counteren :=
+ match merge_var with | Regval_Counteren (v) => Some v | g__12 => None end.
+
+Definition regval_of_Counteren (v : Counteren) : register_value := Regval_Counteren v.
+
+Definition Mcause_of_regval (merge_var : register_value)
+: option Mcause :=
+ match merge_var with | Regval_Mcause (v) => Some v | g__11 => None end.
+
+Definition regval_of_Mcause (v : Mcause) : register_value := Regval_Mcause v.
+
+Definition Medeleg_of_regval (merge_var : register_value)
+: option Medeleg :=
+ match merge_var with | Regval_Medeleg (v) => Some v | g__10 => None end.
+
+Definition regval_of_Medeleg (v : Medeleg) : register_value := Regval_Medeleg v.
+
+Definition Minterrupts_of_regval (merge_var : register_value)
+: option Minterrupts :=
+ match merge_var with | Regval_Minterrupts (v) => Some v | g__9 => None end.
+
+Definition regval_of_Minterrupts (v : Minterrupts) : register_value := Regval_Minterrupts v.
+
+Definition Misa_of_regval (merge_var : register_value)
+: option Misa :=
+ match merge_var with | Regval_Misa (v) => Some v | g__8 => None end.
+
+Definition regval_of_Misa (v : Misa) : register_value := Regval_Misa v.
+
+Definition Mstatus_of_regval (merge_var : register_value)
+: option Mstatus :=
+ match merge_var with | Regval_Mstatus (v) => Some v | g__7 => None end.
+
+Definition regval_of_Mstatus (v : Mstatus) : register_value := Regval_Mstatus v.
+
+Definition Mtvec_of_regval (merge_var : register_value)
+: option Mtvec :=
+ match merge_var with | Regval_Mtvec (v) => Some v | g__6 => None end.
+
+Definition regval_of_Mtvec (v : Mtvec) : register_value := Regval_Mtvec v.
+
+Definition Privilege_of_regval (merge_var : register_value)
+: option Privilege :=
+ match merge_var with | Regval_Privilege (v) => Some v | g__5 => None end.
+
+Definition regval_of_Privilege (v : Privilege) : register_value := Regval_Privilege v.
+
+Definition Sedeleg_of_regval (merge_var : register_value)
+: option Sedeleg :=
+ match merge_var with | Regval_Sedeleg (v) => Some v | g__4 => None end.
+
+Definition regval_of_Sedeleg (v : Sedeleg) : register_value := Regval_Sedeleg v.
+
+Definition Sinterrupts_of_regval (merge_var : register_value)
+: option Sinterrupts :=
+ match merge_var with | Regval_Sinterrupts (v) => Some v | g__3 => None end.
+
+Definition regval_of_Sinterrupts (v : Sinterrupts) : register_value := Regval_Sinterrupts v.
+
+Definition TLB39_Entry_of_regval (merge_var : register_value)
+: option TLB39_Entry :=
+ match merge_var with | Regval_TLB39_Entry (v) => Some v | g__2 => None end.
+
+Definition regval_of_TLB39_Entry (v : TLB39_Entry) : register_value := Regval_TLB39_Entry v.
+
+Definition bool_of_regval (merge_var : register_value)
+: option bool :=
+ match merge_var with | Regval_bool (v) => Some v | g__1 => None end.
+
+Definition regval_of_bool (v : bool) : register_value := Regval_bool v.
+
+Definition vector_64_dec_bit_of_regval (merge_var : register_value)
+: option (mword 64) :=
+ match merge_var with | Regval_vector_64_dec_bit (v) => Some v | g__0 => None end.
+
+Definition regval_of_vector_64_dec_bit (v : mword 64)
+: register_value :=
+ Regval_vector_64_dec_bit v.
+
+
+
+Definition vector_of_regval {a} n (of_regval : register_value -> option a) (rv : register_value) : option (vec a n) := match rv with
+ | Regval_vector (n', _, v) => if n =? n' then map_bind (vec_of_list n) (just_list (List.map of_regval v)) else None
+ | _ => None
+end.
+
+Definition regval_of_vector {a} (regval_of : a -> register_value) (size : Z) (is_inc : bool) (xs : vec a size) : register_value := Regval_vector (size, is_inc, List.map regval_of (list_of_vec xs)).
+
+Definition list_of_regval {a} (of_regval : register_value -> option a) (rv : register_value) : option (list a) := match rv with
+ | Regval_list v => just_list (List.map of_regval v)
+ | _ => None
+end.
+
+Definition regval_of_list {a} (regval_of : a -> register_value) (xs : list a) : register_value := Regval_list (List.map regval_of xs).
+
+Definition option_of_regval {a} (of_regval : register_value -> option a) (rv : register_value) : option (option a) := match rv with
+ | Regval_option v => option_map of_regval v
+ | _ => None
+end.
+
+Definition regval_of_option {a} (regval_of : a -> register_value) (v : option a) := Regval_option (option_map regval_of v).
+
+
+Definition tlb39_ref := {|
+ name := "tlb39";
+ read_from := (fun s => s.(tlb39));
+ write_to := (fun v s => ({[ s with tlb39 := v ]}));
+ of_regval := (fun v => option_of_regval (fun v => TLB39_Entry_of_regval v) v);
+ regval_of := (fun v => regval_of_option (fun v => regval_of_TLB39_Entry v) v) |}.
+
+Definition htif_exit_code_ref := {|
+ name := "htif_exit_code";
+ read_from := (fun s => s.(htif_exit_code));
+ write_to := (fun v s => ({[ s with htif_exit_code := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition htif_done_ref := {|
+ name := "htif_done";
+ read_from := (fun s => s.(htif_done));
+ write_to := (fun v s => ({[ s with htif_done := v ]}));
+ of_regval := (fun v => bool_of_regval v);
+ regval_of := (fun v => regval_of_bool v) |}.
+
+Definition htif_tohost_ref := {|
+ name := "htif_tohost";
+ read_from := (fun s => s.(htif_tohost));
+ write_to := (fun v s => ({[ s with htif_tohost := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition mtimecmp_ref := {|
+ name := "mtimecmp";
+ read_from := (fun s => s.(mtimecmp));
+ write_to := (fun v s => ({[ s with mtimecmp := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition tselect_ref := {|
+ name := "tselect";
+ read_from := (fun s => s.(tselect));
+ write_to := (fun v s => ({[ s with tselect := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition stval_ref := {|
+ name := "stval";
+ read_from := (fun s => s.(stval));
+ write_to := (fun v s => ({[ s with stval := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition scause_ref := {|
+ name := "scause";
+ read_from := (fun s => s.(scause));
+ write_to := (fun v s => ({[ s with scause := v ]}));
+ of_regval := (fun v => Mcause_of_regval v);
+ regval_of := (fun v => regval_of_Mcause v) |}.
+
+Definition sepc_ref := {|
+ name := "sepc";
+ read_from := (fun s => s.(sepc));
+ write_to := (fun v s => ({[ s with sepc := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition sscratch_ref := {|
+ name := "sscratch";
+ read_from := (fun s => s.(sscratch));
+ write_to := (fun v s => ({[ s with sscratch := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition stvec_ref := {|
+ name := "stvec";
+ read_from := (fun s => s.(stvec));
+ write_to := (fun v s => ({[ s with stvec := v ]}));
+ of_regval := (fun v => Mtvec_of_regval v);
+ regval_of := (fun v => regval_of_Mtvec v) |}.
+
+Definition satp_ref := {|
+ name := "satp";
+ read_from := (fun s => s.(satp));
+ write_to := (fun v s => ({[ s with satp := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition sideleg_ref := {|
+ name := "sideleg";
+ read_from := (fun s => s.(sideleg));
+ write_to := (fun v s => ({[ s with sideleg := v ]}));
+ of_regval := (fun v => Sinterrupts_of_regval v);
+ regval_of := (fun v => regval_of_Sinterrupts v) |}.
+
+Definition sedeleg_ref := {|
+ name := "sedeleg";
+ read_from := (fun s => s.(sedeleg));
+ write_to := (fun v s => ({[ s with sedeleg := v ]}));
+ of_regval := (fun v => Sedeleg_of_regval v);
+ regval_of := (fun v => regval_of_Sedeleg v) |}.
+
+Definition pmpcfg0_ref := {|
+ name := "pmpcfg0";
+ read_from := (fun s => s.(pmpcfg0));
+ write_to := (fun v s => ({[ s with pmpcfg0 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition pmpaddr0_ref := {|
+ name := "pmpaddr0";
+ read_from := (fun s => s.(pmpaddr0));
+ write_to := (fun v s => ({[ s with pmpaddr0 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition mhartid_ref := {|
+ name := "mhartid";
+ read_from := (fun s => s.(mhartid));
+ write_to := (fun v s => ({[ s with mhartid := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition marchid_ref := {|
+ name := "marchid";
+ read_from := (fun s => s.(marchid));
+ write_to := (fun v s => ({[ s with marchid := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition mimpid_ref := {|
+ name := "mimpid";
+ read_from := (fun s => s.(mimpid));
+ write_to := (fun v s => ({[ s with mimpid := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition mvendorid_ref := {|
+ name := "mvendorid";
+ read_from := (fun s => s.(mvendorid));
+ write_to := (fun v s => ({[ s with mvendorid := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition minstret_written_ref := {|
+ name := "minstret_written";
+ read_from := (fun s => s.(minstret_written));
+ write_to := (fun v s => ({[ s with minstret_written := v ]}));
+ of_regval := (fun v => bool_of_regval v);
+ regval_of := (fun v => regval_of_bool v) |}.
+
+Definition minstret_ref := {|
+ name := "minstret";
+ read_from := (fun s => s.(minstret));
+ write_to := (fun v s => ({[ s with minstret := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition mtime_ref := {|
+ name := "mtime";
+ read_from := (fun s => s.(mtime));
+ write_to := (fun v s => ({[ s with mtime := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition mcycle_ref := {|
+ name := "mcycle";
+ read_from := (fun s => s.(mcycle));
+ write_to := (fun v s => ({[ s with mcycle := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition scounteren_ref := {|
+ name := "scounteren";
+ read_from := (fun s => s.(scounteren));
+ write_to := (fun v s => ({[ s with scounteren := v ]}));
+ of_regval := (fun v => Counteren_of_regval v);
+ regval_of := (fun v => regval_of_Counteren v) |}.
+
+Definition mcounteren_ref := {|
+ name := "mcounteren";
+ read_from := (fun s => s.(mcounteren));
+ write_to := (fun v s => ({[ s with mcounteren := v ]}));
+ of_regval := (fun v => Counteren_of_regval v);
+ regval_of := (fun v => regval_of_Counteren v) |}.
+
+Definition mscratch_ref := {|
+ name := "mscratch";
+ read_from := (fun s => s.(mscratch));
+ write_to := (fun v s => ({[ s with mscratch := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition mtval_ref := {|
+ name := "mtval";
+ read_from := (fun s => s.(mtval));
+ write_to := (fun v s => ({[ s with mtval := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition mepc_ref := {|
+ name := "mepc";
+ read_from := (fun s => s.(mepc));
+ write_to := (fun v s => ({[ s with mepc := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition mcause_ref := {|
+ name := "mcause";
+ read_from := (fun s => s.(mcause));
+ write_to := (fun v s => ({[ s with mcause := v ]}));
+ of_regval := (fun v => Mcause_of_regval v);
+ regval_of := (fun v => regval_of_Mcause v) |}.
+
+Definition mtvec_ref := {|
+ name := "mtvec";
+ read_from := (fun s => s.(mtvec));
+ write_to := (fun v s => ({[ s with mtvec := v ]}));
+ of_regval := (fun v => Mtvec_of_regval v);
+ regval_of := (fun v => regval_of_Mtvec v) |}.
+
+Definition medeleg_ref := {|
+ name := "medeleg";
+ read_from := (fun s => s.(medeleg));
+ write_to := (fun v s => ({[ s with medeleg := v ]}));
+ of_regval := (fun v => Medeleg_of_regval v);
+ regval_of := (fun v => regval_of_Medeleg v) |}.
+
+Definition mideleg_ref := {|
+ name := "mideleg";
+ read_from := (fun s => s.(mideleg));
+ write_to := (fun v s => ({[ s with mideleg := v ]}));
+ of_regval := (fun v => Minterrupts_of_regval v);
+ regval_of := (fun v => regval_of_Minterrupts v) |}.
+
+Definition mie_ref := {|
+ name := "mie";
+ read_from := (fun s => s.(mie));
+ write_to := (fun v s => ({[ s with mie := v ]}));
+ of_regval := (fun v => Minterrupts_of_regval v);
+ regval_of := (fun v => regval_of_Minterrupts v) |}.
+
+Definition mip_ref := {|
+ name := "mip";
+ read_from := (fun s => s.(mip));
+ write_to := (fun v s => ({[ s with mip := v ]}));
+ of_regval := (fun v => Minterrupts_of_regval v);
+ regval_of := (fun v => regval_of_Minterrupts v) |}.
+
+Definition mstatus_ref := {|
+ name := "mstatus";
+ read_from := (fun s => s.(mstatus));
+ write_to := (fun v s => ({[ s with mstatus := v ]}));
+ of_regval := (fun v => Mstatus_of_regval v);
+ regval_of := (fun v => regval_of_Mstatus v) |}.
+
+Definition misa_ref := {|
+ name := "misa";
+ read_from := (fun s => s.(misa));
+ write_to := (fun v s => ({[ s with misa := v ]}));
+ of_regval := (fun v => Misa_of_regval v);
+ regval_of := (fun v => regval_of_Misa v) |}.
+
+Definition cur_inst_ref := {|
+ name := "cur_inst";
+ read_from := (fun s => s.(cur_inst));
+ write_to := (fun v s => ({[ s with cur_inst := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition cur_privilege_ref := {|
+ name := "cur_privilege";
+ read_from := (fun s => s.(cur_privilege));
+ write_to := (fun v s => ({[ s with cur_privilege := v ]}));
+ of_regval := (fun v => Privilege_of_regval v);
+ regval_of := (fun v => regval_of_Privilege v) |}.
+
+Definition x31_ref := {|
+ name := "x31";
+ read_from := (fun s => s.(x31));
+ write_to := (fun v s => ({[ s with x31 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x30_ref := {|
+ name := "x30";
+ read_from := (fun s => s.(x30));
+ write_to := (fun v s => ({[ s with x30 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x29_ref := {|
+ name := "x29";
+ read_from := (fun s => s.(x29));
+ write_to := (fun v s => ({[ s with x29 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x28_ref := {|
+ name := "x28";
+ read_from := (fun s => s.(x28));
+ write_to := (fun v s => ({[ s with x28 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x27_ref := {|
+ name := "x27";
+ read_from := (fun s => s.(x27));
+ write_to := (fun v s => ({[ s with x27 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x26_ref := {|
+ name := "x26";
+ read_from := (fun s => s.(x26));
+ write_to := (fun v s => ({[ s with x26 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x25_ref := {|
+ name := "x25";
+ read_from := (fun s => s.(x25));
+ write_to := (fun v s => ({[ s with x25 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x24_ref := {|
+ name := "x24";
+ read_from := (fun s => s.(x24));
+ write_to := (fun v s => ({[ s with x24 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x23_ref := {|
+ name := "x23";
+ read_from := (fun s => s.(x23));
+ write_to := (fun v s => ({[ s with x23 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x22_ref := {|
+ name := "x22";
+ read_from := (fun s => s.(x22));
+ write_to := (fun v s => ({[ s with x22 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x21_ref := {|
+ name := "x21";
+ read_from := (fun s => s.(x21));
+ write_to := (fun v s => ({[ s with x21 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x20_ref := {|
+ name := "x20";
+ read_from := (fun s => s.(x20));
+ write_to := (fun v s => ({[ s with x20 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x19_ref := {|
+ name := "x19";
+ read_from := (fun s => s.(x19));
+ write_to := (fun v s => ({[ s with x19 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x18_ref := {|
+ name := "x18";
+ read_from := (fun s => s.(x18));
+ write_to := (fun v s => ({[ s with x18 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x17_ref := {|
+ name := "x17";
+ read_from := (fun s => s.(x17));
+ write_to := (fun v s => ({[ s with x17 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x16_ref := {|
+ name := "x16";
+ read_from := (fun s => s.(x16));
+ write_to := (fun v s => ({[ s with x16 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x15_ref := {|
+ name := "x15";
+ read_from := (fun s => s.(x15));
+ write_to := (fun v s => ({[ s with x15 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x14_ref := {|
+ name := "x14";
+ read_from := (fun s => s.(x14));
+ write_to := (fun v s => ({[ s with x14 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x13_ref := {|
+ name := "x13";
+ read_from := (fun s => s.(x13));
+ write_to := (fun v s => ({[ s with x13 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x12_ref := {|
+ name := "x12";
+ read_from := (fun s => s.(x12));
+ write_to := (fun v s => ({[ s with x12 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x11_ref := {|
+ name := "x11";
+ read_from := (fun s => s.(x11));
+ write_to := (fun v s => ({[ s with x11 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x10_ref := {|
+ name := "x10";
+ read_from := (fun s => s.(x10));
+ write_to := (fun v s => ({[ s with x10 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x9_ref := {|
+ name := "x9";
+ read_from := (fun s => s.(x9));
+ write_to := (fun v s => ({[ s with x9 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x8_ref := {|
+ name := "x8";
+ read_from := (fun s => s.(x8));
+ write_to := (fun v s => ({[ s with x8 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x7_ref := {|
+ name := "x7";
+ read_from := (fun s => s.(x7));
+ write_to := (fun v s => ({[ s with x7 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x6_ref := {|
+ name := "x6";
+ read_from := (fun s => s.(x6));
+ write_to := (fun v s => ({[ s with x6 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x5_ref := {|
+ name := "x5";
+ read_from := (fun s => s.(x5));
+ write_to := (fun v s => ({[ s with x5 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x4_ref := {|
+ name := "x4";
+ read_from := (fun s => s.(x4));
+ write_to := (fun v s => ({[ s with x4 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x3_ref := {|
+ name := "x3";
+ read_from := (fun s => s.(x3));
+ write_to := (fun v s => ({[ s with x3 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x2_ref := {|
+ name := "x2";
+ read_from := (fun s => s.(x2));
+ write_to := (fun v s => ({[ s with x2 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition x1_ref := {|
+ name := "x1";
+ read_from := (fun s => s.(x1));
+ write_to := (fun v s => ({[ s with x1 := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition Xs_ref := {|
+ name := "Xs";
+ read_from := (fun s => s.(Xs));
+ write_to := (fun v s => ({[ s with Xs := v ]}));
+ of_regval := (fun v => vector_of_regval 32 (fun v => vector_64_dec_bit_of_regval v) v);
+ regval_of := (fun v => regval_of_vector (fun v => regval_of_vector_64_dec_bit v) 32 false v) |}.
+
+Definition nextPC_ref := {|
+ name := "nextPC";
+ read_from := (fun s => s.(nextPC));
+ write_to := (fun v s => ({[ s with nextPC := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Definition PC_ref := {|
+ name := "PC";
+ read_from := (fun s => s.(PC));
+ write_to := (fun v s => ({[ s with PC := v ]}));
+ of_regval := (fun v => vector_64_dec_bit_of_regval v);
+ regval_of := (fun v => regval_of_vector_64_dec_bit v) |}.
+
+Local Open Scope string.
+Definition get_regval (reg_name : string) (s : regstate) : option register_value :=
+ if string_dec reg_name "tlb39" then Some (tlb39_ref.(regval_of) (tlb39_ref.(read_from) s)) else
+ if string_dec reg_name "htif_exit_code" then Some (htif_exit_code_ref.(regval_of) (htif_exit_code_ref.(read_from) s)) else
+ if string_dec reg_name "htif_done" then Some (htif_done_ref.(regval_of) (htif_done_ref.(read_from) s)) else
+ if string_dec reg_name "htif_tohost" then Some (htif_tohost_ref.(regval_of) (htif_tohost_ref.(read_from) s)) else
+ if string_dec reg_name "mtimecmp" then Some (mtimecmp_ref.(regval_of) (mtimecmp_ref.(read_from) s)) else
+ if string_dec reg_name "tselect" then Some (tselect_ref.(regval_of) (tselect_ref.(read_from) s)) else
+ if string_dec reg_name "stval" then Some (stval_ref.(regval_of) (stval_ref.(read_from) s)) else
+ if string_dec reg_name "scause" then Some (scause_ref.(regval_of) (scause_ref.(read_from) s)) else
+ if string_dec reg_name "sepc" then Some (sepc_ref.(regval_of) (sepc_ref.(read_from) s)) else
+ if string_dec reg_name "sscratch" then Some (sscratch_ref.(regval_of) (sscratch_ref.(read_from) s)) else
+ if string_dec reg_name "stvec" then Some (stvec_ref.(regval_of) (stvec_ref.(read_from) s)) else
+ if string_dec reg_name "satp" then Some (satp_ref.(regval_of) (satp_ref.(read_from) s)) else
+ if string_dec reg_name "sideleg" then Some (sideleg_ref.(regval_of) (sideleg_ref.(read_from) s)) else
+ if string_dec reg_name "sedeleg" then Some (sedeleg_ref.(regval_of) (sedeleg_ref.(read_from) s)) else
+ if string_dec reg_name "pmpcfg0" then Some (pmpcfg0_ref.(regval_of) (pmpcfg0_ref.(read_from) s)) else
+ if string_dec reg_name "pmpaddr0" then Some (pmpaddr0_ref.(regval_of) (pmpaddr0_ref.(read_from) s)) else
+ if string_dec reg_name "mhartid" then Some (mhartid_ref.(regval_of) (mhartid_ref.(read_from) s)) else
+ if string_dec reg_name "marchid" then Some (marchid_ref.(regval_of) (marchid_ref.(read_from) s)) else
+ if string_dec reg_name "mimpid" then Some (mimpid_ref.(regval_of) (mimpid_ref.(read_from) s)) else
+ if string_dec reg_name "mvendorid" then Some (mvendorid_ref.(regval_of) (mvendorid_ref.(read_from) s)) else
+ if string_dec reg_name "minstret_written" then Some (minstret_written_ref.(regval_of) (minstret_written_ref.(read_from) s)) else
+ if string_dec reg_name "minstret" then Some (minstret_ref.(regval_of) (minstret_ref.(read_from) s)) else
+ if string_dec reg_name "mtime" then Some (mtime_ref.(regval_of) (mtime_ref.(read_from) s)) else
+ if string_dec reg_name "mcycle" then Some (mcycle_ref.(regval_of) (mcycle_ref.(read_from) s)) else
+ if string_dec reg_name "scounteren" then Some (scounteren_ref.(regval_of) (scounteren_ref.(read_from) s)) else
+ if string_dec reg_name "mcounteren" then Some (mcounteren_ref.(regval_of) (mcounteren_ref.(read_from) s)) else
+ if string_dec reg_name "mscratch" then Some (mscratch_ref.(regval_of) (mscratch_ref.(read_from) s)) else
+ if string_dec reg_name "mtval" then Some (mtval_ref.(regval_of) (mtval_ref.(read_from) s)) else
+ if string_dec reg_name "mepc" then Some (mepc_ref.(regval_of) (mepc_ref.(read_from) s)) else
+ if string_dec reg_name "mcause" then Some (mcause_ref.(regval_of) (mcause_ref.(read_from) s)) else
+ if string_dec reg_name "mtvec" then Some (mtvec_ref.(regval_of) (mtvec_ref.(read_from) s)) else
+ if string_dec reg_name "medeleg" then Some (medeleg_ref.(regval_of) (medeleg_ref.(read_from) s)) else
+ if string_dec reg_name "mideleg" then Some (mideleg_ref.(regval_of) (mideleg_ref.(read_from) s)) else
+ if string_dec reg_name "mie" then Some (mie_ref.(regval_of) (mie_ref.(read_from) s)) else
+ if string_dec reg_name "mip" then Some (mip_ref.(regval_of) (mip_ref.(read_from) s)) else
+ if string_dec reg_name "mstatus" then Some (mstatus_ref.(regval_of) (mstatus_ref.(read_from) s)) else
+ if string_dec reg_name "misa" then Some (misa_ref.(regval_of) (misa_ref.(read_from) s)) else
+ if string_dec reg_name "cur_inst" then Some (cur_inst_ref.(regval_of) (cur_inst_ref.(read_from) s)) else
+ if string_dec reg_name "cur_privilege" then Some (cur_privilege_ref.(regval_of) (cur_privilege_ref.(read_from) s)) else
+ if string_dec reg_name "x31" then Some (x31_ref.(regval_of) (x31_ref.(read_from) s)) else
+ if string_dec reg_name "x30" then Some (x30_ref.(regval_of) (x30_ref.(read_from) s)) else
+ if string_dec reg_name "x29" then Some (x29_ref.(regval_of) (x29_ref.(read_from) s)) else
+ if string_dec reg_name "x28" then Some (x28_ref.(regval_of) (x28_ref.(read_from) s)) else
+ if string_dec reg_name "x27" then Some (x27_ref.(regval_of) (x27_ref.(read_from) s)) else
+ if string_dec reg_name "x26" then Some (x26_ref.(regval_of) (x26_ref.(read_from) s)) else
+ if string_dec reg_name "x25" then Some (x25_ref.(regval_of) (x25_ref.(read_from) s)) else
+ if string_dec reg_name "x24" then Some (x24_ref.(regval_of) (x24_ref.(read_from) s)) else
+ if string_dec reg_name "x23" then Some (x23_ref.(regval_of) (x23_ref.(read_from) s)) else
+ if string_dec reg_name "x22" then Some (x22_ref.(regval_of) (x22_ref.(read_from) s)) else
+ if string_dec reg_name "x21" then Some (x21_ref.(regval_of) (x21_ref.(read_from) s)) else
+ if string_dec reg_name "x20" then Some (x20_ref.(regval_of) (x20_ref.(read_from) s)) else
+ if string_dec reg_name "x19" then Some (x19_ref.(regval_of) (x19_ref.(read_from) s)) else
+ if string_dec reg_name "x18" then Some (x18_ref.(regval_of) (x18_ref.(read_from) s)) else
+ if string_dec reg_name "x17" then Some (x17_ref.(regval_of) (x17_ref.(read_from) s)) else
+ if string_dec reg_name "x16" then Some (x16_ref.(regval_of) (x16_ref.(read_from) s)) else
+ if string_dec reg_name "x15" then Some (x15_ref.(regval_of) (x15_ref.(read_from) s)) else
+ if string_dec reg_name "x14" then Some (x14_ref.(regval_of) (x14_ref.(read_from) s)) else
+ if string_dec reg_name "x13" then Some (x13_ref.(regval_of) (x13_ref.(read_from) s)) else
+ if string_dec reg_name "x12" then Some (x12_ref.(regval_of) (x12_ref.(read_from) s)) else
+ if string_dec reg_name "x11" then Some (x11_ref.(regval_of) (x11_ref.(read_from) s)) else
+ if string_dec reg_name "x10" then Some (x10_ref.(regval_of) (x10_ref.(read_from) s)) else
+ if string_dec reg_name "x9" then Some (x9_ref.(regval_of) (x9_ref.(read_from) s)) else
+ if string_dec reg_name "x8" then Some (x8_ref.(regval_of) (x8_ref.(read_from) s)) else
+ if string_dec reg_name "x7" then Some (x7_ref.(regval_of) (x7_ref.(read_from) s)) else
+ if string_dec reg_name "x6" then Some (x6_ref.(regval_of) (x6_ref.(read_from) s)) else
+ if string_dec reg_name "x5" then Some (x5_ref.(regval_of) (x5_ref.(read_from) s)) else
+ if string_dec reg_name "x4" then Some (x4_ref.(regval_of) (x4_ref.(read_from) s)) else
+ if string_dec reg_name "x3" then Some (x3_ref.(regval_of) (x3_ref.(read_from) s)) else
+ if string_dec reg_name "x2" then Some (x2_ref.(regval_of) (x2_ref.(read_from) s)) else
+ if string_dec reg_name "x1" then Some (x1_ref.(regval_of) (x1_ref.(read_from) s)) else
+ if string_dec reg_name "Xs" then Some (Xs_ref.(regval_of) (Xs_ref.(read_from) s)) else
+ if string_dec reg_name "nextPC" then Some (nextPC_ref.(regval_of) (nextPC_ref.(read_from) s)) else
+ if string_dec reg_name "PC" then Some (PC_ref.(regval_of) (PC_ref.(read_from) s)) else
+ None.
+
+Definition set_regval (reg_name : string) (v : register_value) (s : regstate) : option regstate :=
+ if string_dec reg_name "tlb39" then option_map (fun v => tlb39_ref.(write_to) v s) (tlb39_ref.(of_regval) v) else
+ if string_dec reg_name "htif_exit_code" then option_map (fun v => htif_exit_code_ref.(write_to) v s) (htif_exit_code_ref.(of_regval) v) else
+ if string_dec reg_name "htif_done" then option_map (fun v => htif_done_ref.(write_to) v s) (htif_done_ref.(of_regval) v) else
+ if string_dec reg_name "htif_tohost" then option_map (fun v => htif_tohost_ref.(write_to) v s) (htif_tohost_ref.(of_regval) v) else
+ if string_dec reg_name "mtimecmp" then option_map (fun v => mtimecmp_ref.(write_to) v s) (mtimecmp_ref.(of_regval) v) else
+ if string_dec reg_name "tselect" then option_map (fun v => tselect_ref.(write_to) v s) (tselect_ref.(of_regval) v) else
+ if string_dec reg_name "stval" then option_map (fun v => stval_ref.(write_to) v s) (stval_ref.(of_regval) v) else
+ if string_dec reg_name "scause" then option_map (fun v => scause_ref.(write_to) v s) (scause_ref.(of_regval) v) else
+ if string_dec reg_name "sepc" then option_map (fun v => sepc_ref.(write_to) v s) (sepc_ref.(of_regval) v) else
+ if string_dec reg_name "sscratch" then option_map (fun v => sscratch_ref.(write_to) v s) (sscratch_ref.(of_regval) v) else
+ if string_dec reg_name "stvec" then option_map (fun v => stvec_ref.(write_to) v s) (stvec_ref.(of_regval) v) else
+ if string_dec reg_name "satp" then option_map (fun v => satp_ref.(write_to) v s) (satp_ref.(of_regval) v) else
+ if string_dec reg_name "sideleg" then option_map (fun v => sideleg_ref.(write_to) v s) (sideleg_ref.(of_regval) v) else
+ if string_dec reg_name "sedeleg" then option_map (fun v => sedeleg_ref.(write_to) v s) (sedeleg_ref.(of_regval) v) else
+ if string_dec reg_name "pmpcfg0" then option_map (fun v => pmpcfg0_ref.(write_to) v s) (pmpcfg0_ref.(of_regval) v) else
+ if string_dec reg_name "pmpaddr0" then option_map (fun v => pmpaddr0_ref.(write_to) v s) (pmpaddr0_ref.(of_regval) v) else
+ if string_dec reg_name "mhartid" then option_map (fun v => mhartid_ref.(write_to) v s) (mhartid_ref.(of_regval) v) else
+ if string_dec reg_name "marchid" then option_map (fun v => marchid_ref.(write_to) v s) (marchid_ref.(of_regval) v) else
+ if string_dec reg_name "mimpid" then option_map (fun v => mimpid_ref.(write_to) v s) (mimpid_ref.(of_regval) v) else
+ if string_dec reg_name "mvendorid" then option_map (fun v => mvendorid_ref.(write_to) v s) (mvendorid_ref.(of_regval) v) else
+ if string_dec reg_name "minstret_written" then option_map (fun v => minstret_written_ref.(write_to) v s) (minstret_written_ref.(of_regval) v) else
+ if string_dec reg_name "minstret" then option_map (fun v => minstret_ref.(write_to) v s) (minstret_ref.(of_regval) v) else
+ if string_dec reg_name "mtime" then option_map (fun v => mtime_ref.(write_to) v s) (mtime_ref.(of_regval) v) else
+ if string_dec reg_name "mcycle" then option_map (fun v => mcycle_ref.(write_to) v s) (mcycle_ref.(of_regval) v) else
+ if string_dec reg_name "scounteren" then option_map (fun v => scounteren_ref.(write_to) v s) (scounteren_ref.(of_regval) v) else
+ if string_dec reg_name "mcounteren" then option_map (fun v => mcounteren_ref.(write_to) v s) (mcounteren_ref.(of_regval) v) else
+ if string_dec reg_name "mscratch" then option_map (fun v => mscratch_ref.(write_to) v s) (mscratch_ref.(of_regval) v) else
+ if string_dec reg_name "mtval" then option_map (fun v => mtval_ref.(write_to) v s) (mtval_ref.(of_regval) v) else
+ if string_dec reg_name "mepc" then option_map (fun v => mepc_ref.(write_to) v s) (mepc_ref.(of_regval) v) else
+ if string_dec reg_name "mcause" then option_map (fun v => mcause_ref.(write_to) v s) (mcause_ref.(of_regval) v) else
+ if string_dec reg_name "mtvec" then option_map (fun v => mtvec_ref.(write_to) v s) (mtvec_ref.(of_regval) v) else
+ if string_dec reg_name "medeleg" then option_map (fun v => medeleg_ref.(write_to) v s) (medeleg_ref.(of_regval) v) else
+ if string_dec reg_name "mideleg" then option_map (fun v => mideleg_ref.(write_to) v s) (mideleg_ref.(of_regval) v) else
+ if string_dec reg_name "mie" then option_map (fun v => mie_ref.(write_to) v s) (mie_ref.(of_regval) v) else
+ if string_dec reg_name "mip" then option_map (fun v => mip_ref.(write_to) v s) (mip_ref.(of_regval) v) else
+ if string_dec reg_name "mstatus" then option_map (fun v => mstatus_ref.(write_to) v s) (mstatus_ref.(of_regval) v) else
+ if string_dec reg_name "misa" then option_map (fun v => misa_ref.(write_to) v s) (misa_ref.(of_regval) v) else
+ if string_dec reg_name "cur_inst" then option_map (fun v => cur_inst_ref.(write_to) v s) (cur_inst_ref.(of_regval) v) else
+ if string_dec reg_name "cur_privilege" then option_map (fun v => cur_privilege_ref.(write_to) v s) (cur_privilege_ref.(of_regval) v) else
+ if string_dec reg_name "x31" then option_map (fun v => x31_ref.(write_to) v s) (x31_ref.(of_regval) v) else
+ if string_dec reg_name "x30" then option_map (fun v => x30_ref.(write_to) v s) (x30_ref.(of_regval) v) else
+ if string_dec reg_name "x29" then option_map (fun v => x29_ref.(write_to) v s) (x29_ref.(of_regval) v) else
+ if string_dec reg_name "x28" then option_map (fun v => x28_ref.(write_to) v s) (x28_ref.(of_regval) v) else
+ if string_dec reg_name "x27" then option_map (fun v => x27_ref.(write_to) v s) (x27_ref.(of_regval) v) else
+ if string_dec reg_name "x26" then option_map (fun v => x26_ref.(write_to) v s) (x26_ref.(of_regval) v) else
+ if string_dec reg_name "x25" then option_map (fun v => x25_ref.(write_to) v s) (x25_ref.(of_regval) v) else
+ if string_dec reg_name "x24" then option_map (fun v => x24_ref.(write_to) v s) (x24_ref.(of_regval) v) else
+ if string_dec reg_name "x23" then option_map (fun v => x23_ref.(write_to) v s) (x23_ref.(of_regval) v) else
+ if string_dec reg_name "x22" then option_map (fun v => x22_ref.(write_to) v s) (x22_ref.(of_regval) v) else
+ if string_dec reg_name "x21" then option_map (fun v => x21_ref.(write_to) v s) (x21_ref.(of_regval) v) else
+ if string_dec reg_name "x20" then option_map (fun v => x20_ref.(write_to) v s) (x20_ref.(of_regval) v) else
+ if string_dec reg_name "x19" then option_map (fun v => x19_ref.(write_to) v s) (x19_ref.(of_regval) v) else
+ if string_dec reg_name "x18" then option_map (fun v => x18_ref.(write_to) v s) (x18_ref.(of_regval) v) else
+ if string_dec reg_name "x17" then option_map (fun v => x17_ref.(write_to) v s) (x17_ref.(of_regval) v) else
+ if string_dec reg_name "x16" then option_map (fun v => x16_ref.(write_to) v s) (x16_ref.(of_regval) v) else
+ if string_dec reg_name "x15" then option_map (fun v => x15_ref.(write_to) v s) (x15_ref.(of_regval) v) else
+ if string_dec reg_name "x14" then option_map (fun v => x14_ref.(write_to) v s) (x14_ref.(of_regval) v) else
+ if string_dec reg_name "x13" then option_map (fun v => x13_ref.(write_to) v s) (x13_ref.(of_regval) v) else
+ if string_dec reg_name "x12" then option_map (fun v => x12_ref.(write_to) v s) (x12_ref.(of_regval) v) else
+ if string_dec reg_name "x11" then option_map (fun v => x11_ref.(write_to) v s) (x11_ref.(of_regval) v) else
+ if string_dec reg_name "x10" then option_map (fun v => x10_ref.(write_to) v s) (x10_ref.(of_regval) v) else
+ if string_dec reg_name "x9" then option_map (fun v => x9_ref.(write_to) v s) (x9_ref.(of_regval) v) else
+ if string_dec reg_name "x8" then option_map (fun v => x8_ref.(write_to) v s) (x8_ref.(of_regval) v) else
+ if string_dec reg_name "x7" then option_map (fun v => x7_ref.(write_to) v s) (x7_ref.(of_regval) v) else
+ if string_dec reg_name "x6" then option_map (fun v => x6_ref.(write_to) v s) (x6_ref.(of_regval) v) else
+ if string_dec reg_name "x5" then option_map (fun v => x5_ref.(write_to) v s) (x5_ref.(of_regval) v) else
+ if string_dec reg_name "x4" then option_map (fun v => x4_ref.(write_to) v s) (x4_ref.(of_regval) v) else
+ if string_dec reg_name "x3" then option_map (fun v => x3_ref.(write_to) v s) (x3_ref.(of_regval) v) else
+ if string_dec reg_name "x2" then option_map (fun v => x2_ref.(write_to) v s) (x2_ref.(of_regval) v) else
+ if string_dec reg_name "x1" then option_map (fun v => x1_ref.(write_to) v s) (x1_ref.(of_regval) v) else
+ if string_dec reg_name "Xs" then option_map (fun v => Xs_ref.(write_to) v s) (Xs_ref.(of_regval) v) else
+ if string_dec reg_name "nextPC" then option_map (fun v => nextPC_ref.(write_to) v s) (nextPC_ref.(of_regval) v) else
+ if string_dec reg_name "PC" then option_map (fun v => PC_ref.(write_to) v s) (PC_ref.(of_regval) v) else
+ None.
+
+Definition register_accessors := (get_regval, set_regval).
+
+
+Definition MR a r := monadR register_value a r exception.
+Definition M a := monad register_value a exception.