(*Generated by Sail from mips.*)
Require Import Sail.Base.
Require Import Sail.Real.
Require Import mips_types.
Require Import mips_extras.
Import ListNotations.
Open Scope string.
Open Scope bool.
Open Scope Z.

Definition trace : bool := false.
Hint Unfold trace : sail.
Definition eq_unit (_ : unit) (_ : unit) : {_bool : bool & ArithFact (_bool)} := build_ex (true).

Definition neq_int (x : Z) (y : Z) : {_bool : bool & ArithFact (Bool.eqb (negb (x =? y)) _bool)} :=
   build_ex (negb (Z.eqb x y)).

Definition neq_bool (x : bool) (y : bool) : bool := negb (Bool.eqb x y).

Definition __id (x : Z) : {_retval : Z & ArithFact (_retval =? x)} := build_ex (x).

Definition _shl_int_general (m : Z) (n : Z) : Z :=
   if sumbool_of_bool (Z.geb n 0) then shl_int m n else shr_int m (Z.opp n).

Definition _shr_int_general (m : Z) (n : Z) : Z :=
   if sumbool_of_bool (Z.geb n 0) then shr_int m n else shl_int m (Z.opp n).

Definition fdiv_int (n : Z) (m : Z) : Z :=
   if sumbool_of_bool (andb (Z.ltb n 0) (Z.gtb m 0)) then Z.sub (Z.quot (Z.add n 1) m) 1
   else if sumbool_of_bool (andb (Z.gtb n 0) (Z.ltb m 0)) then Z.sub (Z.quot (Z.sub n 1) m) 1
   else Z.quot n m.

Definition fmod_int (n : Z) (m : Z) : Z := Z.sub n (Z.mul m (fdiv_int n m)).

Definition undefined_option {a : Type} (typ_a : a) : M (option a) :=
   (undefined_unit tt) >>= fun u_0 : unit =>
   let u_1 : a := typ_a in
   (internal_pick [Some u_1; None])
    : M (option a).

Definition is_none {a : Type} (opt : option a) : bool :=
   match opt with | Some _ => false | None => true end.

Definition is_some {a : Type} (opt : option a) : bool :=
   match opt with | Some _ => true | None => false end.

Definition sail_mask {v0 : Z} (len : Z) (v : mword v0) `{ArithFact ((len >=? 0) && (v0 >=? 0))}
: mword len :=
   if sumbool_of_bool (Z.leb len (length_mword v)) then vector_truncate v len else zero_extend v len.

Definition sail_ones (n : Z) `{ArithFact (n >=? 0)} : mword n := not_vec (zeros n).

Definition slice_mask (n : Z) (i : Z) (l : Z) `{ArithFact (n >=? 0)} : mword n :=
   if sumbool_of_bool (Z.geb l n) then shiftl (sail_ones n) i
   else
     let one : bits n := sail_mask n ('b"1"  : bits 1) in
     shiftl (sub_vec (shiftl one l) one) i.

Definition concat_str_bits {n : Z} (str : string) (x : mword n) : string :=
   String.append str (string_of_bits x).

Definition concat_str_dec (str : string) (x : Z) : string := String.append str (dec_str x).

Definition cast_unit_vec (b : bitU) : mword 1 :=
   match b with | B0 => 'b"0"  : mword 1 | _ => 'b"1"  : mword 1 end.

Definition __MIPS_write (addr : mword 64) (width : Z) (data : mword (8 * width)) : M (unit) :=
   (write_ram 64 width (Ox"0000000000000000"  : mword 64) addr data) >> returnm tt.

Definition __MIPS_read (addr : mword 64) (width : Z) `{ArithFact (width >=? 0)}
: M (mword (8 * width)) :=
   (read_ram 64 width (Ox"0000000000000000"  : mword 64) addr)  : M (mword (8 * width)).

Definition zopz0zQzQ {n0 : Z} (bs : mword n0) (n : Z) `{ArithFact (n >=? 0)} : mword (n0 * n) :=
   replicate_bits bs n.

Definition undefined_exception '(tt : unit) : M (exception) :=
   (undefined_string tt) >>= fun u_0 : string =>
   (undefined_unit tt) >>= fun u_1 : unit =>
   (internal_pick
      [ISAException u_1;
      Error_not_implemented u_0;
      Error_misaligned_access u_1;
      Error_EBREAK u_1;
      Error_internal_error u_1])
    : M (exception).

Definition mips_sign_extend {n : Z} (m : Z) (v : mword n) `{ArithFact (m >=? n)} : mword m :=
   sign_extend v m.

Definition mips_zero_extend {n : Z} (m : Z) (v : mword n) `{ArithFact (m >=? n)} : mword m :=
   zero_extend v m.

Definition zeros_implicit (n : Z) (_ : unit) `{ArithFact (n >=? 0)} : mword n := zeros n.

Definition ones_implicit (n : Z) (_ : unit) `{ArithFact (n >=? 0)} : mword n := sail_ones n.

Definition zopz0zI_s {n : Z} (x : mword n) (y : mword n) `{ArithFact (n >? 0)} : bool :=
   Z.ltb (projT1 (sint x)) (projT1 (sint y)).

Definition zopz0zKzJ_s {n : Z} (x : mword n) (y : mword n) `{ArithFact (n >? 0)} : bool :=
   Z.geb (projT1 (sint x)) (projT1 (sint y)).

Definition zopz0zI_u {n : Z} (x : mword n) (y : mword n) `{ArithFact (n >=? 0)} : bool :=
   Z.ltb (projT1 (uint x)) (projT1 (uint y)).

Definition zopz0zKzJ_u {n : Z} (x : mword n) (y : mword n) `{ArithFact (n >=? 0)} : bool :=
   Z.geb (projT1 (uint x)) (projT1 (uint y)).

Definition bool_to_bits (x : bool) : mword 1 :=
   if sumbool_of_bool x then 'b"1"  : mword 1 else 'b"0"  : mword 1.

Definition bool_to_bit (x : bool) : bitU := if sumbool_of_bool x then B1 else B0.

Definition bit_to_bool (b : bitU) : bool := match b with | B1 => true | _ => false end.

Definition bits_to_bool (x : mword 1) : bool := bit_to_bool (access_vec_dec x 0).

Definition to_bits (l : Z) (n : Z) `{ArithFact (l >=? 0)} : mword l := get_slice_int l n 0.

Definition mask {m : Z} (n : Z) (bs : mword m) `{ArithFact ((m >=? n) && (n >? 0))} : mword n :=
   autocast (subrange_vec_dec bs (Z.sub n 1) 0).

Definition undefined_CauseReg '(tt : unit) : M (CauseReg) :=
   (undefined_bitvector 32) >>= fun w__0 : mword 32 =>
   returnm ({| CauseReg_CauseReg_chunk_0 := w__0 |}).

Definition Mk_CauseReg (v : mword 32) : CauseReg :=
   {| CauseReg_CauseReg_chunk_0 := (subrange_vec_dec v 31 0) |}.

Definition _get_CauseReg_bits (v : CauseReg) : mword 32 :=
   subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 31 0.

Definition _set_CauseReg_bits (r_ref : register_ref regstate register_value CauseReg) (v : mword 32)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       CauseReg_CauseReg_chunk_0 :=
         (update_subrange_vec_dec r.(CauseReg_CauseReg_chunk_0) 31 0 (subrange_vec_dec v 31 0)) ]}
      : CauseReg in
   write_reg r_ref r
    : M (unit).

Definition _update_CauseReg_bits (v : CauseReg) (x : mword 32) : CauseReg :=
   {[ v with
     CauseReg_CauseReg_chunk_0 :=
       (update_subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 31 0 (subrange_vec_dec x 31 0)) ]}.

Definition _get_CauseReg_BD (v : CauseReg) : mword 1 :=
   subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 31 31.

Definition _set_CauseReg_BD (r_ref : register_ref regstate register_value CauseReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       CauseReg_CauseReg_chunk_0 :=
         (update_subrange_vec_dec r.(CauseReg_CauseReg_chunk_0) 31 31 (subrange_vec_dec v 0 0)) ]}
      : CauseReg in
   write_reg r_ref r
    : M (unit).

Definition _update_CauseReg_BD (v : CauseReg) (x : mword 1) : CauseReg :=
   {[ v with
     CauseReg_CauseReg_chunk_0 :=
       (update_subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 31 31 (subrange_vec_dec x 0 0)) ]}.

Definition _get_CauseReg_CE (v : CauseReg) : mword 2 :=
   subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 29 28.

Definition _set_CauseReg_CE (r_ref : register_ref regstate register_value CauseReg) (v : mword 2)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       CauseReg_CauseReg_chunk_0 :=
         (update_subrange_vec_dec r.(CauseReg_CauseReg_chunk_0) 29 28 (subrange_vec_dec v 1 0)) ]}
      : CauseReg in
   write_reg r_ref r
    : M (unit).

Definition _update_CauseReg_CE (v : CauseReg) (x : mword 2) : CauseReg :=
   {[ v with
     CauseReg_CauseReg_chunk_0 :=
       (update_subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 29 28 (subrange_vec_dec x 1 0)) ]}.

Definition _get_CauseReg_IV (v : CauseReg) : mword 1 :=
   subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 23 23.

Definition _set_CauseReg_IV (r_ref : register_ref regstate register_value CauseReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       CauseReg_CauseReg_chunk_0 :=
         (update_subrange_vec_dec r.(CauseReg_CauseReg_chunk_0) 23 23 (subrange_vec_dec v 0 0)) ]}
      : CauseReg in
   write_reg r_ref r
    : M (unit).

Definition _update_CauseReg_IV (v : CauseReg) (x : mword 1) : CauseReg :=
   {[ v with
     CauseReg_CauseReg_chunk_0 :=
       (update_subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 23 23 (subrange_vec_dec x 0 0)) ]}.

Definition _get_CauseReg_WP (v : CauseReg) : mword 1 :=
   subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 22 22.

Definition _set_CauseReg_WP (r_ref : register_ref regstate register_value CauseReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       CauseReg_CauseReg_chunk_0 :=
         (update_subrange_vec_dec r.(CauseReg_CauseReg_chunk_0) 22 22 (subrange_vec_dec v 0 0)) ]}
      : CauseReg in
   write_reg r_ref r
    : M (unit).

Definition _update_CauseReg_WP (v : CauseReg) (x : mword 1) : CauseReg :=
   {[ v with
     CauseReg_CauseReg_chunk_0 :=
       (update_subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 22 22 (subrange_vec_dec x 0 0)) ]}.

Definition _get_CauseReg_IP (v : CauseReg) : mword 8 :=
   subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 15 8.

Definition _set_CauseReg_IP (r_ref : register_ref regstate register_value CauseReg) (v : mword 8)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       CauseReg_CauseReg_chunk_0 :=
         (update_subrange_vec_dec r.(CauseReg_CauseReg_chunk_0) 15 8 (subrange_vec_dec v 7 0)) ]}
      : CauseReg in
   write_reg r_ref r
    : M (unit).

Definition _update_CauseReg_IP (v : CauseReg) (x : mword 8) : CauseReg :=
   {[ v with
     CauseReg_CauseReg_chunk_0 :=
       (update_subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 15 8 (subrange_vec_dec x 7 0)) ]}.

Definition _get_CauseReg_ExcCode (v : CauseReg) : mword 5 :=
   subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 6 2.

Definition _set_CauseReg_ExcCode
(r_ref : register_ref regstate register_value CauseReg) (v : mword 5)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       CauseReg_CauseReg_chunk_0 :=
         (update_subrange_vec_dec r.(CauseReg_CauseReg_chunk_0) 6 2 (subrange_vec_dec v 4 0)) ]}
      : CauseReg in
   write_reg r_ref r
    : M (unit).

Definition _update_CauseReg_ExcCode (v : CauseReg) (x : mword 5) : CauseReg :=
   {[ v with
     CauseReg_CauseReg_chunk_0 :=
       (update_subrange_vec_dec v.(CauseReg_CauseReg_chunk_0) 6 2 (subrange_vec_dec x 4 0)) ]}.

Definition undefined_TLBEntryLoReg '(tt : unit) : M (TLBEntryLoReg) :=
   (undefined_bitvector 64) >>= fun w__0 : mword 64 =>
   returnm ({| TLBEntryLoReg_TLBEntryLoReg_chunk_0 := w__0 |}).

Definition Mk_TLBEntryLoReg (v : mword 64) : TLBEntryLoReg :=
   {| TLBEntryLoReg_TLBEntryLoReg_chunk_0 := (subrange_vec_dec v 63 0) |}.

Definition _get_TLBEntryLoReg_bits (v : TLBEntryLoReg) : mword 64 :=
   subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 63 0.

Definition _set_TLBEntryLoReg_bits
(r_ref : register_ref regstate register_value TLBEntryLoReg) (v : mword 64)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 63 0
            (subrange_vec_dec v 63 0)) ]}
      : TLBEntryLoReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryLoReg_bits (v : TLBEntryLoReg) (x : mword 64) : TLBEntryLoReg :=
   {[ v with
     TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 63 0
          (subrange_vec_dec x 63 0)) ]}.

Definition _get_TLBEntryLoReg_CapS (v : TLBEntryLoReg) : mword 1 :=
   subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 63 63.

Definition _set_TLBEntryLoReg_CapS
(r_ref : register_ref regstate register_value TLBEntryLoReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 63 63
            (subrange_vec_dec v 0 0)) ]}
      : TLBEntryLoReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryLoReg_CapS (v : TLBEntryLoReg) (x : mword 1) : TLBEntryLoReg :=
   {[ v with
     TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 63 63
          (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntryLoReg_CapL (v : TLBEntryLoReg) : mword 1 :=
   subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 62 62.

Definition _set_TLBEntryLoReg_CapL
(r_ref : register_ref regstate register_value TLBEntryLoReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 62 62
            (subrange_vec_dec v 0 0)) ]}
      : TLBEntryLoReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryLoReg_CapL (v : TLBEntryLoReg) (x : mword 1) : TLBEntryLoReg :=
   {[ v with
     TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 62 62
          (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntryLoReg_CapLG (v : TLBEntryLoReg) : mword 1 :=
   subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 61 61.

Definition _set_TLBEntryLoReg_CapLG
(r_ref : register_ref regstate register_value TLBEntryLoReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 61 61
            (subrange_vec_dec v 0 0)) ]}
      : TLBEntryLoReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryLoReg_CapLG (v : TLBEntryLoReg) (x : mword 1) : TLBEntryLoReg :=
   {[ v with
     TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 61 61
          (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntryLoReg_PFN (v : TLBEntryLoReg) : mword 24 :=
   subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 29 6.

Definition _set_TLBEntryLoReg_PFN
(r_ref : register_ref regstate register_value TLBEntryLoReg) (v : mword 24)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 29 6
            (subrange_vec_dec v 23 0)) ]}
      : TLBEntryLoReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryLoReg_PFN (v : TLBEntryLoReg) (x : mword 24) : TLBEntryLoReg :=
   {[ v with
     TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 29 6
          (subrange_vec_dec x 23 0)) ]}.

Definition _get_TLBEntryLoReg_C (v : TLBEntryLoReg) : mword 3 :=
   subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 5 3.

Definition _set_TLBEntryLoReg_C
(r_ref : register_ref regstate register_value TLBEntryLoReg) (v : mword 3)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 5 3
            (subrange_vec_dec v 2 0)) ]}
      : TLBEntryLoReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryLoReg_C (v : TLBEntryLoReg) (x : mword 3) : TLBEntryLoReg :=
   {[ v with
     TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 5 3 (subrange_vec_dec x 2 0)) ]}.

Definition _get_TLBEntryLoReg_D (v : TLBEntryLoReg) : mword 1 :=
   subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 2 2.

Definition _set_TLBEntryLoReg_D
(r_ref : register_ref regstate register_value TLBEntryLoReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 2 2
            (subrange_vec_dec v 0 0)) ]}
      : TLBEntryLoReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryLoReg_D (v : TLBEntryLoReg) (x : mword 1) : TLBEntryLoReg :=
   {[ v with
     TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 2 2 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntryLoReg_V (v : TLBEntryLoReg) : mword 1 :=
   subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 1 1.

Definition _set_TLBEntryLoReg_V
(r_ref : register_ref regstate register_value TLBEntryLoReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 1 1
            (subrange_vec_dec v 0 0)) ]}
      : TLBEntryLoReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryLoReg_V (v : TLBEntryLoReg) (x : mword 1) : TLBEntryLoReg :=
   {[ v with
     TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntryLoReg_G (v : TLBEntryLoReg) : mword 1 :=
   subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 0 0.

Definition _set_TLBEntryLoReg_G
(r_ref : register_ref regstate register_value TLBEntryLoReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 0 0
            (subrange_vec_dec v 0 0)) ]}
      : TLBEntryLoReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryLoReg_G (v : TLBEntryLoReg) (x : mword 1) : TLBEntryLoReg :=
   {[ v with
     TLBEntryLoReg_TLBEntryLoReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryLoReg_TLBEntryLoReg_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.

Definition undefined_TLBEntryHiReg '(tt : unit) : M (TLBEntryHiReg) :=
   (undefined_bitvector 64) >>= fun w__0 : mword 64 =>
   returnm ({| TLBEntryHiReg_TLBEntryHiReg_chunk_0 := w__0 |}).

Definition Mk_TLBEntryHiReg (v : mword 64) : TLBEntryHiReg :=
   {| TLBEntryHiReg_TLBEntryHiReg_chunk_0 := (subrange_vec_dec v 63 0) |}.

Definition _get_TLBEntryHiReg_bits (v : TLBEntryHiReg) : mword 64 :=
   subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 63 0.

Definition _set_TLBEntryHiReg_bits
(r_ref : register_ref regstate register_value TLBEntryHiReg) (v : mword 64)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 63 0
            (subrange_vec_dec v 63 0)) ]}
      : TLBEntryHiReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryHiReg_bits (v : TLBEntryHiReg) (x : mword 64) : TLBEntryHiReg :=
   {[ v with
     TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 63 0
          (subrange_vec_dec x 63 0)) ]}.

Definition _get_TLBEntryHiReg_R (v : TLBEntryHiReg) : mword 2 :=
   subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 63 62.

Definition _set_TLBEntryHiReg_R
(r_ref : register_ref regstate register_value TLBEntryHiReg) (v : mword 2)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 63 62
            (subrange_vec_dec v 1 0)) ]}
      : TLBEntryHiReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryHiReg_R (v : TLBEntryHiReg) (x : mword 2) : TLBEntryHiReg :=
   {[ v with
     TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 63 62
          (subrange_vec_dec x 1 0)) ]}.

Definition _get_TLBEntryHiReg_CLGK (v : TLBEntryHiReg) : mword 1 :=
   subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 61 61.

Definition _set_TLBEntryHiReg_CLGK
(r_ref : register_ref regstate register_value TLBEntryHiReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 61 61
            (subrange_vec_dec v 0 0)) ]}
      : TLBEntryHiReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryHiReg_CLGK (v : TLBEntryHiReg) (x : mword 1) : TLBEntryHiReg :=
   {[ v with
     TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 61 61
          (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntryHiReg_CLGS (v : TLBEntryHiReg) : mword 1 :=
   subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 60 60.

Definition _set_TLBEntryHiReg_CLGS
(r_ref : register_ref regstate register_value TLBEntryHiReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 60 60
            (subrange_vec_dec v 0 0)) ]}
      : TLBEntryHiReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryHiReg_CLGS (v : TLBEntryHiReg) (x : mword 1) : TLBEntryHiReg :=
   {[ v with
     TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 60 60
          (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntryHiReg_CLGU (v : TLBEntryHiReg) : mword 1 :=
   subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 59 59.

Definition _set_TLBEntryHiReg_CLGU
(r_ref : register_ref regstate register_value TLBEntryHiReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 59 59
            (subrange_vec_dec v 0 0)) ]}
      : TLBEntryHiReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryHiReg_CLGU (v : TLBEntryHiReg) (x : mword 1) : TLBEntryHiReg :=
   {[ v with
     TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 59 59
          (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntryHiReg_VPN2 (v : TLBEntryHiReg) : mword 27 :=
   subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 39 13.

Definition _set_TLBEntryHiReg_VPN2
(r_ref : register_ref regstate register_value TLBEntryHiReg) (v : mword 27)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 39 13
            (subrange_vec_dec v 26 0)) ]}
      : TLBEntryHiReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryHiReg_VPN2 (v : TLBEntryHiReg) (x : mword 27) : TLBEntryHiReg :=
   {[ v with
     TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 39 13
          (subrange_vec_dec x 26 0)) ]}.

Definition _get_TLBEntryHiReg_ASID (v : TLBEntryHiReg) : mword 8 :=
   subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 7 0.

Definition _set_TLBEntryHiReg_ASID
(r_ref : register_ref regstate register_value TLBEntryHiReg) (v : mword 8)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 7 0
            (subrange_vec_dec v 7 0)) ]}
      : TLBEntryHiReg in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntryHiReg_ASID (v : TLBEntryHiReg) (x : mword 8) : TLBEntryHiReg :=
   {[ v with
     TLBEntryHiReg_TLBEntryHiReg_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntryHiReg_TLBEntryHiReg_chunk_0) 7 0 (subrange_vec_dec x 7 0)) ]}.

Definition undefined_ContextReg '(tt : unit) : M (ContextReg) :=
   (undefined_bitvector 64) >>= fun w__0 : mword 64 =>
   returnm ({| ContextReg_ContextReg_chunk_0 := w__0 |}).

Definition Mk_ContextReg (v : mword 64) : ContextReg :=
   {| ContextReg_ContextReg_chunk_0 := (subrange_vec_dec v 63 0) |}.

Definition _get_ContextReg_bits (v : ContextReg) : mword 64 :=
   subrange_vec_dec v.(ContextReg_ContextReg_chunk_0) 63 0.

Definition _set_ContextReg_bits
(r_ref : register_ref regstate register_value ContextReg) (v : mword 64)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       ContextReg_ContextReg_chunk_0 :=
         (update_subrange_vec_dec r.(ContextReg_ContextReg_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
      : ContextReg in
   write_reg r_ref r
    : M (unit).

Definition _update_ContextReg_bits (v : ContextReg) (x : mword 64) : ContextReg :=
   {[ v with
     ContextReg_ContextReg_chunk_0 :=
       (update_subrange_vec_dec v.(ContextReg_ContextReg_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.

Definition _get_ContextReg_PTEBase (v : ContextReg) : mword 41 :=
   subrange_vec_dec v.(ContextReg_ContextReg_chunk_0) 63 23.

Definition _set_ContextReg_PTEBase
(r_ref : register_ref regstate register_value ContextReg) (v : mword 41)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       ContextReg_ContextReg_chunk_0 :=
         (update_subrange_vec_dec r.(ContextReg_ContextReg_chunk_0) 63 23 (subrange_vec_dec v 40 0)) ]}
      : ContextReg in
   write_reg r_ref r
    : M (unit).

Definition _update_ContextReg_PTEBase (v : ContextReg) (x : mword 41) : ContextReg :=
   {[ v with
     ContextReg_ContextReg_chunk_0 :=
       (update_subrange_vec_dec v.(ContextReg_ContextReg_chunk_0) 63 23 (subrange_vec_dec x 40 0)) ]}.

Definition _get_ContextReg_BadVPN2 (v : ContextReg) : mword 19 :=
   subrange_vec_dec v.(ContextReg_ContextReg_chunk_0) 22 4.

Definition _set_ContextReg_BadVPN2
(r_ref : register_ref regstate register_value ContextReg) (v : mword 19)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       ContextReg_ContextReg_chunk_0 :=
         (update_subrange_vec_dec r.(ContextReg_ContextReg_chunk_0) 22 4 (subrange_vec_dec v 18 0)) ]}
      : ContextReg in
   write_reg r_ref r
    : M (unit).

Definition _update_ContextReg_BadVPN2 (v : ContextReg) (x : mword 19) : ContextReg :=
   {[ v with
     ContextReg_ContextReg_chunk_0 :=
       (update_subrange_vec_dec v.(ContextReg_ContextReg_chunk_0) 22 4 (subrange_vec_dec x 18 0)) ]}.

Definition undefined_XContextReg '(tt : unit) : M (XContextReg) :=
   (undefined_bitvector 64) >>= fun w__0 : mword 64 =>
   returnm ({| XContextReg_XContextReg_chunk_0 := w__0 |}).

Definition Mk_XContextReg (v : mword 64) : XContextReg :=
   {| XContextReg_XContextReg_chunk_0 := (subrange_vec_dec v 63 0) |}.

Definition _get_XContextReg_bits (v : XContextReg) : mword 64 :=
   subrange_vec_dec v.(XContextReg_XContextReg_chunk_0) 63 0.

Definition _set_XContextReg_bits
(r_ref : register_ref regstate register_value XContextReg) (v : mword 64)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       XContextReg_XContextReg_chunk_0 :=
         (update_subrange_vec_dec r.(XContextReg_XContextReg_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
      : XContextReg in
   write_reg r_ref r
    : M (unit).

Definition _update_XContextReg_bits (v : XContextReg) (x : mword 64) : XContextReg :=
   {[ v with
     XContextReg_XContextReg_chunk_0 :=
       (update_subrange_vec_dec v.(XContextReg_XContextReg_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.

Definition _get_XContextReg_XPTEBase (v : XContextReg) : mword 31 :=
   subrange_vec_dec v.(XContextReg_XContextReg_chunk_0) 63 33.

Definition _set_XContextReg_XPTEBase
(r_ref : register_ref regstate register_value XContextReg) (v : mword 31)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       XContextReg_XContextReg_chunk_0 :=
         (update_subrange_vec_dec r.(XContextReg_XContextReg_chunk_0) 63 33
            (subrange_vec_dec v 30 0)) ]}
      : XContextReg in
   write_reg r_ref r
    : M (unit).

Definition _update_XContextReg_XPTEBase (v : XContextReg) (x : mword 31) : XContextReg :=
   {[ v with
     XContextReg_XContextReg_chunk_0 :=
       (update_subrange_vec_dec v.(XContextReg_XContextReg_chunk_0) 63 33 (subrange_vec_dec x 30 0)) ]}.

Definition _get_XContextReg_XR (v : XContextReg) : mword 2 :=
   subrange_vec_dec v.(XContextReg_XContextReg_chunk_0) 32 31.

Definition _set_XContextReg_XR
(r_ref : register_ref regstate register_value XContextReg) (v : mword 2)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       XContextReg_XContextReg_chunk_0 :=
         (update_subrange_vec_dec r.(XContextReg_XContextReg_chunk_0) 32 31 (subrange_vec_dec v 1 0)) ]}
      : XContextReg in
   write_reg r_ref r
    : M (unit).

Definition _update_XContextReg_XR (v : XContextReg) (x : mword 2) : XContextReg :=
   {[ v with
     XContextReg_XContextReg_chunk_0 :=
       (update_subrange_vec_dec v.(XContextReg_XContextReg_chunk_0) 32 31 (subrange_vec_dec x 1 0)) ]}.

Definition _get_XContextReg_XBadVPN2 (v : XContextReg) : mword 27 :=
   subrange_vec_dec v.(XContextReg_XContextReg_chunk_0) 30 4.

Definition _set_XContextReg_XBadVPN2
(r_ref : register_ref regstate register_value XContextReg) (v : mword 27)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       XContextReg_XContextReg_chunk_0 :=
         (update_subrange_vec_dec r.(XContextReg_XContextReg_chunk_0) 30 4 (subrange_vec_dec v 26 0)) ]}
      : XContextReg in
   write_reg r_ref r
    : M (unit).

Definition _update_XContextReg_XBadVPN2 (v : XContextReg) (x : mword 27) : XContextReg :=
   {[ v with
     XContextReg_XContextReg_chunk_0 :=
       (update_subrange_vec_dec v.(XContextReg_XContextReg_chunk_0) 30 4 (subrange_vec_dec x 26 0)) ]}.

Definition TLBNumEntries := 64.
Hint Unfold TLBNumEntries : sail.
Definition TLBIndexMax : TLBIndexT := 'b"111111"  : mword 6.
Hint Unfold TLBIndexMax : sail.
Definition MAX (n : Z) `{ArithFact (n >=? 0)} : {_retval : Z & ArithFact (_retval =? (2 ^ n - 1))} :=
   build_ex (Z.sub (projT1 (pow2 n)) 1).

Definition MAX_U64 := projT1 (MAX 64).
Hint Unfold MAX_U64 : sail.
Definition MAX_VA := projT1 (MAX 40).
Hint Unfold MAX_VA : sail.
Definition MAX_PA := projT1 (MAX 36).
Hint Unfold MAX_PA : sail.
Definition undefined_TLBEntry '(tt : unit) : M (TLBEntry) :=
   (undefined_bitvector 55) >>= fun w__0 : mword 55 =>
   (undefined_bitvector 64) >>= fun w__1 : mword 64 =>
   returnm ({| TLBEntry_TLBEntry_chunk_1 := w__0;  TLBEntry_TLBEntry_chunk_0 := w__1 |}).

Definition Mk_TLBEntry (v : mword 119) : TLBEntry :=
   {| TLBEntry_TLBEntry_chunk_1 := (subrange_vec_dec v 118 64);
      TLBEntry_TLBEntry_chunk_0 := (subrange_vec_dec v 63 0) |}.

Definition _get_TLBEntry_bits (v : TLBEntry) : mword 119 :=
   concat_vec (subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 54 0)
     (subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 63 0).

Definition _set_TLBEntry_bits
(r_ref : register_ref regstate register_value TLBEntry) (v : mword 119)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_1 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_1) 54 0 (subrange_vec_dec v 118 64)) ]}
      : TLBEntry in
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 63 0 (subrange_vec_dec v 63 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_bits (v : TLBEntry) (x : mword 119) : TLBEntry :=
   let v :=
     {[ v with
       TLBEntry_TLBEntry_chunk_1 :=
         (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 54 0 (subrange_vec_dec x 118 64)) ]} in
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 63 0 (subrange_vec_dec x 63 0)) ]}.

Definition _get_TLBEntry_pagemask (v : TLBEntry) : mword 16 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 54 39.

Definition _set_TLBEntry_pagemask
(r_ref : register_ref regstate register_value TLBEntry) (v : mword 16)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_1 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_1) 54 39 (subrange_vec_dec v 15 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_pagemask (v : TLBEntry) (x : mword 16) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_1 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 54 39 (subrange_vec_dec x 15 0)) ]}.

Definition _get_TLBEntry_r (v : TLBEntry) : mword 2 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 38 37.

Definition _set_TLBEntry_r (r_ref : register_ref regstate register_value TLBEntry) (v : mword 2)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_1 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_1) 38 37 (subrange_vec_dec v 1 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_r (v : TLBEntry) (x : mword 2) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_1 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 38 37 (subrange_vec_dec x 1 0)) ]}.

Definition _get_TLBEntry_vpn2 (v : TLBEntry) : mword 27 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 36 10.

Definition _set_TLBEntry_vpn2 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 27)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_1 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_1) 36 10 (subrange_vec_dec v 26 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_vpn2 (v : TLBEntry) (x : mword 27) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_1 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 36 10 (subrange_vec_dec x 26 0)) ]}.

Definition _get_TLBEntry_asid (v : TLBEntry) : mword 8 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 9 2.

Definition _set_TLBEntry_asid (r_ref : register_ref regstate register_value TLBEntry) (v : mword 8)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_1 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_1) 9 2 (subrange_vec_dec v 7 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_asid (v : TLBEntry) (x : mword 8) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_1 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 9 2 (subrange_vec_dec x 7 0)) ]}.

Definition _get_TLBEntry_g (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 1 1.

Definition _set_TLBEntry_g (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_1 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_1) 1 1 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_g (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_1 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 1 1 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_valid (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 0 0.

Definition _set_TLBEntry_valid (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_1 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_1) 0 0 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_valid (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_1 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_1) 0 0 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_caplg1 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 63 63.

Definition _set_TLBEntry_caplg1
(r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 63 63 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_caplg1 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 63 63 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_caps1 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 62 62.

Definition _set_TLBEntry_caps1 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 62 62 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_caps1 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 62 62 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_capl1 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 61 61.

Definition _set_TLBEntry_capl1 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 61 61 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_capl1 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 61 61 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_pfn1 (v : TLBEntry) : mword 24 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 60 37.

Definition _set_TLBEntry_pfn1 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 24)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 60 37 (subrange_vec_dec v 23 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_pfn1 (v : TLBEntry) (x : mword 24) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 60 37 (subrange_vec_dec x 23 0)) ]}.

Definition _get_TLBEntry_c1 (v : TLBEntry) : mword 3 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 36 34.

Definition _set_TLBEntry_c1 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 3)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 36 34 (subrange_vec_dec v 2 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_c1 (v : TLBEntry) (x : mword 3) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 36 34 (subrange_vec_dec x 2 0)) ]}.

Definition _get_TLBEntry_d1 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 33 33.

Definition _set_TLBEntry_d1 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 33 33 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_d1 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 33 33 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_v1 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 32 32.

Definition _set_TLBEntry_v1 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 32 32 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_v1 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 32 32 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_caplg0 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 31 31.

Definition _set_TLBEntry_caplg0
(r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 31 31 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_caplg0 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 31 31 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_caps0 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 30 30.

Definition _set_TLBEntry_caps0 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 30 30 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_caps0 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 30 30 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_capl0 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 29 29.

Definition _set_TLBEntry_capl0 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 29 29 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_capl0 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 29 29 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_pfn0 (v : TLBEntry) : mword 24 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 28 5.

Definition _set_TLBEntry_pfn0 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 24)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 28 5 (subrange_vec_dec v 23 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_pfn0 (v : TLBEntry) (x : mword 24) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 28 5 (subrange_vec_dec x 23 0)) ]}.

Definition _get_TLBEntry_c0 (v : TLBEntry) : mword 3 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 4 2.

Definition _set_TLBEntry_c0 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 3)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 4 2 (subrange_vec_dec v 2 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_c0 (v : TLBEntry) (x : mword 3) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 4 2 (subrange_vec_dec x 2 0)) ]}.

Definition _get_TLBEntry_d0 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 1 1.

Definition _set_TLBEntry_d0 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_d0 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.

Definition _get_TLBEntry_v0 (v : TLBEntry) : mword 1 :=
   subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 0 0.

Definition _set_TLBEntry_v0 (r_ref : register_ref regstate register_value TLBEntry) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       TLBEntry_TLBEntry_chunk_0 :=
         (update_subrange_vec_dec r.(TLBEntry_TLBEntry_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
      : TLBEntry in
   write_reg r_ref r
    : M (unit).

Definition _update_TLBEntry_v0 (v : TLBEntry) (x : mword 1) : TLBEntry :=
   {[ v with
     TLBEntry_TLBEntry_chunk_0 :=
       (update_subrange_vec_dec v.(TLBEntry_TLBEntry_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.

Definition TLBEntries : vec (register_ref regstate register_value TLBEntry) 64 :=
vec_of_list_len [TLBEntry63_ref;TLBEntry62_ref;TLBEntry61_ref;TLBEntry60_ref;TLBEntry59_ref;
                 TLBEntry58_ref;TLBEntry57_ref;TLBEntry56_ref;TLBEntry55_ref;TLBEntry54_ref;
                 TLBEntry53_ref;TLBEntry52_ref;TLBEntry51_ref;TLBEntry50_ref;TLBEntry49_ref;
                 TLBEntry48_ref;TLBEntry47_ref;TLBEntry46_ref;TLBEntry45_ref;TLBEntry44_ref;
                 TLBEntry43_ref;TLBEntry42_ref;TLBEntry41_ref;TLBEntry40_ref;TLBEntry39_ref;
                 TLBEntry38_ref;TLBEntry37_ref;TLBEntry36_ref;TLBEntry35_ref;TLBEntry34_ref;
                 TLBEntry33_ref;TLBEntry32_ref;TLBEntry31_ref;TLBEntry30_ref;TLBEntry29_ref;
                 TLBEntry28_ref;TLBEntry27_ref;TLBEntry26_ref;TLBEntry25_ref;TLBEntry24_ref;
                 TLBEntry23_ref;TLBEntry22_ref;TLBEntry21_ref;TLBEntry20_ref;TLBEntry19_ref;
                 TLBEntry18_ref;TLBEntry17_ref;TLBEntry16_ref;TLBEntry15_ref;TLBEntry14_ref;
                 TLBEntry13_ref;TLBEntry12_ref;TLBEntry11_ref;TLBEntry10_ref;TLBEntry09_ref;
                 TLBEntry08_ref;TLBEntry07_ref;TLBEntry06_ref;TLBEntry05_ref;TLBEntry04_ref;
                 TLBEntry03_ref;TLBEntry02_ref;TLBEntry01_ref;TLBEntry00_ref].
Hint Unfold TLBEntries : sail.
Definition undefined_StatusReg '(tt : unit) : M (StatusReg) :=
   (undefined_bitvector 32) >>= fun w__0 : mword 32 =>
   returnm ({| StatusReg_StatusReg_chunk_0 := w__0 |}).

Definition Mk_StatusReg (v : mword 32) : StatusReg :=
   {| StatusReg_StatusReg_chunk_0 := (subrange_vec_dec v 31 0) |}.

Definition _get_StatusReg_bits (v : StatusReg) : mword 32 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 31 0.

Definition _set_StatusReg_bits
(r_ref : register_ref regstate register_value StatusReg) (v : mword 32)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 31 0 (subrange_vec_dec v 31 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_bits (v : StatusReg) (x : mword 32) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 31 0 (subrange_vec_dec x 31 0)) ]}.

Definition _get_StatusReg_CU (v : StatusReg) : mword 4 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 31 28.

Definition _set_StatusReg_CU (r_ref : register_ref regstate register_value StatusReg) (v : mword 4)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 31 28 (subrange_vec_dec v 3 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_CU (v : StatusReg) (x : mword 4) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 31 28 (subrange_vec_dec x 3 0)) ]}.

Definition _get_StatusReg_BEV (v : StatusReg) : mword 1 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 22 22.

Definition _set_StatusReg_BEV (r_ref : register_ref regstate register_value StatusReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 22 22 (subrange_vec_dec v 0 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_BEV (v : StatusReg) (x : mword 1) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 22 22 (subrange_vec_dec x 0 0)) ]}.

Definition _get_StatusReg_IM (v : StatusReg) : mword 8 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 15 8.

Definition _set_StatusReg_IM (r_ref : register_ref regstate register_value StatusReg) (v : mword 8)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 15 8 (subrange_vec_dec v 7 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_IM (v : StatusReg) (x : mword 8) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 15 8 (subrange_vec_dec x 7 0)) ]}.

Definition _get_StatusReg_KX (v : StatusReg) : mword 1 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 7 7.

Definition _set_StatusReg_KX (r_ref : register_ref regstate register_value StatusReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 7 7 (subrange_vec_dec v 0 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_KX (v : StatusReg) (x : mword 1) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 7 7 (subrange_vec_dec x 0 0)) ]}.

Definition _get_StatusReg_SX (v : StatusReg) : mword 1 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 6 6.

Definition _set_StatusReg_SX (r_ref : register_ref regstate register_value StatusReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 6 6 (subrange_vec_dec v 0 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_SX (v : StatusReg) (x : mword 1) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 6 6 (subrange_vec_dec x 0 0)) ]}.

Definition _get_StatusReg_UX (v : StatusReg) : mword 1 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 5 5.

Definition _set_StatusReg_UX (r_ref : register_ref regstate register_value StatusReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 5 5 (subrange_vec_dec v 0 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_UX (v : StatusReg) (x : mword 1) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 5 5 (subrange_vec_dec x 0 0)) ]}.

Definition _get_StatusReg_KSU (v : StatusReg) : mword 2 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 4 3.

Definition _set_StatusReg_KSU (r_ref : register_ref regstate register_value StatusReg) (v : mword 2)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 4 3 (subrange_vec_dec v 1 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_KSU (v : StatusReg) (x : mword 2) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 4 3 (subrange_vec_dec x 1 0)) ]}.

Definition _get_StatusReg_ERL (v : StatusReg) : mword 1 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 2 2.

Definition _set_StatusReg_ERL (r_ref : register_ref regstate register_value StatusReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 2 2 (subrange_vec_dec v 0 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_ERL (v : StatusReg) (x : mword 1) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 2 2 (subrange_vec_dec x 0 0)) ]}.

Definition _get_StatusReg_EXL (v : StatusReg) : mword 1 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 1 1.

Definition _set_StatusReg_EXL (r_ref : register_ref regstate register_value StatusReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 1 1 (subrange_vec_dec v 0 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_EXL (v : StatusReg) (x : mword 1) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 1 1 (subrange_vec_dec x 0 0)) ]}.

Definition _get_StatusReg_IE (v : StatusReg) : mword 1 :=
   subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 0 0.

Definition _set_StatusReg_IE (r_ref : register_ref regstate register_value StatusReg) (v : mword 1)
: M (unit) :=
   (reg_deref r_ref) >>= fun r =>
   let r :=
     {[ r with
       StatusReg_StatusReg_chunk_0 :=
         (update_subrange_vec_dec r.(StatusReg_StatusReg_chunk_0) 0 0 (subrange_vec_dec v 0 0)) ]}
      : StatusReg in
   write_reg r_ref r
    : M (unit).

Definition _update_StatusReg_IE (v : StatusReg) (x : mword 1) : StatusReg :=
   {[ v with
     StatusReg_StatusReg_chunk_0 :=
       (update_subrange_vec_dec v.(StatusReg_StatusReg_chunk_0) 0 0 (subrange_vec_dec x 0 0)) ]}.

Definition execute_branch_mips (pc : mword 64) : M (unit) :=
   write_reg DelayedPC_ref pc >>
   write_reg BranchPending_ref ('b"1"  : mword 1) >>
   write_reg NextInBranchDelay_ref ('b"1"  : mword 1)
    : M (unit).

Definition NotWordVal (word : mword 64) : bool :=
   neq_vec (zopz0zQzQ (cast_unit_vec (access_vec_dec word 31)) 32) (subrange_vec_dec word 63 32).

Definition rGPR (idx : mword 5) : M (mword 64) :=
   let i := projT1 (uint idx) in
   (if sumbool_of_bool (Z.eqb i 0) then returnm (Ox"0000000000000000"  : mword 64)
    else read_reg GPR_ref >>= fun w__0 : vec (mword 64) 32 => returnm (vec_access_dec w__0 i))
    : M (mword 64).

Definition wGPR (idx : mword 5) (v : mword 64) : M (unit) :=
   let i := projT1 (uint idx) in
   (if sumbool_of_bool (projT1 (neq_int i 0)) then
      let '_ :=
        (if sumbool_of_bool trace then
           let '_ := (prerr (string_of_int i))  : unit in
           prerr_bits " <- " v
         else tt)
         : unit in
      read_reg GPR_ref >>= fun w__0 : vec (mword 64) 32 =>
      write_reg GPR_ref (vec_update_dec w__0 i v)
       : M (unit)
    else returnm tt)
    : M (unit).

Definition Exception_of_num (arg_ : Z) `{ArithFact ((0 <=? arg_) && (arg_ <=? 18))} : Exception :=
   let l__70 := arg_ in
   if sumbool_of_bool (Z.eqb l__70 0) then Interrupt
   else if sumbool_of_bool (Z.eqb l__70 1) then TLBMod
   else if sumbool_of_bool (Z.eqb l__70 2) then TLBL
   else if sumbool_of_bool (Z.eqb l__70 3) then TLBS
   else if sumbool_of_bool (Z.eqb l__70 4) then AdEL
   else if sumbool_of_bool (Z.eqb l__70 5) then AdES
   else if sumbool_of_bool (Z.eqb l__70 6) then Sys
   else if sumbool_of_bool (Z.eqb l__70 7) then Bp
   else if sumbool_of_bool (Z.eqb l__70 8) then ResI
   else if sumbool_of_bool (Z.eqb l__70 9) then CpU
   else if sumbool_of_bool (Z.eqb l__70 10) then Ov
   else if sumbool_of_bool (Z.eqb l__70 11) then Tr
   else if sumbool_of_bool (Z.eqb l__70 12) then C2E
   else if sumbool_of_bool (Z.eqb l__70 13) then C2Trap
   else if sumbool_of_bool (Z.eqb l__70 14) then XTLBRefillL
   else if sumbool_of_bool (Z.eqb l__70 15) then XTLBRefillS
   else if sumbool_of_bool (Z.eqb l__70 16) then XTLBInvL
   else if sumbool_of_bool (Z.eqb l__70 17) then XTLBInvS
   else MCheck.

Definition num_of_Exception (arg_ : Exception) : {e : Z & ArithFact ((0 <=? e) && (e <=? 18))} :=
   build_ex (
      match arg_ with
      | Interrupt => 0
      | TLBMod => 1
      | TLBL => 2
      | TLBS => 3
      | AdEL => 4
      | AdES => 5
      | Sys => 6
      | Bp => 7
      | ResI => 8
      | CpU => 9
      | Ov => 10
      | Tr => 11
      | C2E => 12
      | C2Trap => 13
      | XTLBRefillL => 14
      | XTLBRefillS => 15
      | XTLBInvL => 16
      | XTLBInvS => 17
      | MCheck => 18
      end
   ).

Definition undefined_Exception '(tt : unit) : M (Exception) :=
   (internal_pick
      [Interrupt;
      TLBMod;
      TLBL;
      TLBS;
      AdEL;
      AdES;
      Sys;
      Bp;
      ResI;
      CpU;
      Ov;
      Tr;
      C2E;
      C2Trap;
      XTLBRefillL;
      XTLBRefillS;
      XTLBInvL;
      XTLBInvS;
      MCheck])
    : M (Exception).

Definition ExceptionCode (ex : Exception) : mword 5 :=
   let x : bits 8 :=
     match ex with
     | Interrupt => Ox"00"  : mword 8
     | TLBMod => Ox"01"  : mword 8
     | TLBL => Ox"02"  : mword 8
     | TLBS => Ox"03"  : mword 8
     | AdEL => Ox"04"  : mword 8
     | AdES => Ox"05"  : mword 8
     | Sys => Ox"08"  : mword 8
     | Bp => Ox"09"  : mword 8
     | ResI => Ox"0A"  : mword 8
     | CpU => Ox"0B"  : mword 8
     | Ov => Ox"0C"  : mword 8
     | Tr => Ox"0D"  : mword 8
     | C2E => Ox"12"  : mword 8
     | C2Trap => Ox"12"  : mword 8
     | XTLBRefillL => Ox"02"  : mword 8
     | XTLBRefillS => Ox"03"  : mword 8
     | XTLBInvL => Ox"02"  : mword 8
     | XTLBInvS => Ox"03"  : mword 8
     | MCheck => Ox"18"  : mword 8
     end in
   subrange_vec_dec x 4 0.

Definition string_of_exception (ex : Exception) : string :=
   match ex with
   | Interrupt => "Interrupt"
   | TLBMod => "TLBMod"
   | TLBL => "TLBL"
   | TLBS => "TLBS"
   | AdEL => "AdEL"
   | AdES => "AdES"
   | Sys => "Sys"
   | Bp => "Bp  "
   | ResI => "ResI"
   | CpU => "CpU"
   | Ov => "Ov"
   | Tr => "Tr"
   | C2E => "C2E"
   | C2Trap => "C2Trap"
   | XTLBRefillL => "XTLBRefillL"
   | XTLBRefillS => "XTLBRefillS"
   | XTLBInvL => "XTLBInvL"
   | XTLBInvS => "XTLBInvS"
   | MCheck => "MCheck"
   end.

Definition traceException (ex : Exception) : unit :=
   if sumbool_of_bool trace then
     let '_ := (prerr " EXCEPTION ")  : unit in
     prerr_endline (string_of_exception ex)
   else tt.

Definition exceptionVectorOffset (ex : Exception) : M (mword 12) :=
   read_reg CP0Status_ref >>= fun w__0 : StatusReg =>
   returnm (if (bits_to_bool (_get_StatusReg_EXL w__0))  : bool then Ox"180"  : mword 12
            else if orb (generic_eq ex XTLBRefillL) (generic_eq ex XTLBRefillS) then
              Ox"080"
               : mword 12
            else if generic_eq ex C2Trap then Ox"280"  : mword 12
            else Ox"180"  : mword 12).

Definition exceptionVectorBase '(tt : unit) : M (mword 64) :=
   read_reg CP0Status_ref >>= fun w__0 : StatusReg =>
   returnm (if (bits_to_bool (_get_StatusReg_BEV w__0))  : bool then
              Ox"FFFFFFFFBFC00200"
               : mword 64
            else Ox"FFFFFFFF80000000"  : mword 64).

Definition updateBadInstr '(tt : unit) : M (unit) :=
   ((read_reg InBranchDelay_ref)  : M (mword 1)) >>= fun w__0 : mword 1 =>
   (if (bit_to_bool (access_vec_dec w__0 0))  : bool then
      ((read_reg LastInstrBits_ref)  : M (mword 32)) >>= fun w__1 : mword 32 =>
      write_reg CP0BadInstrP_ref w__1
       : M (unit)
    else returnm tt) >>
   ((read_reg CurrentInstrBits_ref)  : M (mword 32)) >>= fun w__2 : mword 32 =>
   write_reg CP0BadInstr_ref w__2
    : M (unit).

Definition set_CP0EPC (v : mword 64) : M (unit) := write_reg CP0EPC_ref v >> (skip tt)  : M (unit).

Definition SignalException {o : Type} (ex : Exception) : M (o) :=
   let '_ := (traceException ex)  : unit in
   read_reg CP0Status_ref >>= fun w__0 : StatusReg =>
   (if negb (bits_to_bool (_get_StatusReg_EXL w__0)) then
      ((read_reg InBranchDelay_ref)  : M (mword 1)) >>= fun w__1 : mword 1 =>
      (if (bit_to_bool (access_vec_dec w__1 0))  : bool then
         ((read_reg PC_ref)  : M (mword 64)) >>= fun w__2 : mword 64 =>
         (set_CP0EPC (sub_vec_int w__2 4)) >>
         (_set_CauseReg_BD CP0Cause_ref ('b"1"  : mword 1))
          : M (unit)
       else
         ((read_reg PC_ref)  : M (mword 64)) >>= fun w__3 : mword 64 =>
         (set_CP0EPC w__3) >> (_set_CauseReg_BD CP0Cause_ref ('b"0"  : mword 1))  : M (unit))
       : M (unit)
    else returnm tt) >>
   (updateBadInstr tt) >>
   (exceptionVectorOffset ex) >>= fun vectorOffset =>
   (exceptionVectorBase tt) >>= fun vectorBase =>
   write_reg NextPC_ref (add_vec vectorBase (mips_zero_extend 64 vectorOffset)) >>
   (_set_CauseReg_ExcCode CP0Cause_ref (ExceptionCode ex)) >>
   (_set_StatusReg_EXL CP0Status_ref ('b"1"  : mword 1)) >> throw (ISAException tt).

Definition SignalExceptionBadAddr {o : Type} (ex : Exception) (badAddr : mword 64) : M (o) :=
   write_reg CP0BadVAddr_ref badAddr >> (SignalException ex)  : M (o).

Definition SignalExceptionTLB {o : Type} (ex : Exception) (badAddr : mword 64) : M (o) :=
   write_reg CP0BadVAddr_ref badAddr >>
   (_set_ContextReg_BadVPN2 TLBContext_ref (subrange_vec_dec badAddr 31 13)) >>
   (_set_XContextReg_XBadVPN2 TLBXContext_ref (subrange_vec_dec badAddr 39 13)) >>
   (_set_XContextReg_XR TLBXContext_ref (subrange_vec_dec badAddr 63 62)) >>
   (_set_TLBEntryHiReg_R TLBEntryHi_ref (subrange_vec_dec badAddr 63 62)) >>
   (_set_TLBEntryHiReg_VPN2 TLBEntryHi_ref (subrange_vec_dec badAddr 39 13)) >>
   (SignalException ex)
    : M (o).

Definition MemAccessType_of_num (arg_ : Z) `{ArithFact ((0 <=? arg_) && (arg_ <=? 2))}
: MemAccessType :=
   let l__68 := arg_ in
   if sumbool_of_bool (Z.eqb l__68 0) then Instruction
   else if sumbool_of_bool (Z.eqb l__68 1) then LoadData
   else StoreData.

Definition num_of_MemAccessType (arg_ : MemAccessType)
: {e : Z & ArithFact ((0 <=? e) && (e <=? 2))} :=
   build_ex (match arg_ with | Instruction => 0 | LoadData => 1 | StoreData => 2 end).

Definition undefined_MemAccessType '(tt : unit) : M (MemAccessType) :=
   (internal_pick [Instruction; LoadData; StoreData])  : M (MemAccessType).

Definition MemAccessCapRestriction_of_num (arg_ : Z) `{ArithFact ((0 <=? arg_) && (arg_ <=? 2))}
: MemAccessCapRestriction :=
   let l__66 := arg_ in
   if sumbool_of_bool (Z.eqb l__66 0) then Unrestricted
   else if sumbool_of_bool (Z.eqb l__66 1) then Trap
   else Clear.

Definition num_of_MemAccessCapRestriction (arg_ : MemAccessCapRestriction)
: {e : Z & ArithFact ((0 <=? e) && (e <=? 2))} :=
   build_ex (match arg_ with | Unrestricted => 0 | Trap => 1 | Clear => 2 end).

Definition undefined_MemAccessCapRestriction '(tt : unit) : M (MemAccessCapRestriction) :=
   (internal_pick [Unrestricted; Trap; Clear])  : M (MemAccessCapRestriction).

Definition AccessLevel_of_num (arg_ : Z) `{ArithFact ((0 <=? arg_) && (arg_ <=? 2))} : AccessLevel :=
   let l__64 := arg_ in
   if sumbool_of_bool (Z.eqb l__64 0) then User
   else if sumbool_of_bool (Z.eqb l__64 1) then Supervisor
   else Kernel.

Definition num_of_AccessLevel (arg_ : AccessLevel) : {e : Z & ArithFact ((0 <=? e) && (e <=? 2))} :=
   build_ex (match arg_ with | User => 0 | Supervisor => 1 | Kernel => 2 end).

Definition undefined_AccessLevel '(tt : unit) : M (AccessLevel) :=
   (internal_pick [User; Supervisor; Kernel])  : M (AccessLevel).

Definition int_of_AccessLevel (level : AccessLevel)
: {n : Z & ArithFact (member_Z_list n [0; 1; 2])} :=
   build_ex (match level with | User => 0 | Supervisor => 1 | Kernel => 2 end).

Definition grantsAccess (currentLevel : AccessLevel) (requiredLevel : AccessLevel) : bool :=
   Z.geb (projT1 (int_of_AccessLevel currentLevel)) (projT1 (int_of_AccessLevel requiredLevel)).

Definition getAccessLevel '(tt : unit) : M (AccessLevel) :=
   (or_boolM
      (read_reg CP0Status_ref >>= fun w__0 : StatusReg =>
       returnm ((bits_to_bool (_get_StatusReg_EXL w__0))  : bool))
      (read_reg CP0Status_ref >>= fun w__1 : StatusReg =>
       returnm ((bits_to_bool (_get_StatusReg_ERL w__1))  : bool))) >>= fun w__2 : bool =>
   (if sumbool_of_bool w__2 then returnm Kernel
    else
      read_reg CP0Status_ref >>= fun w__3 : StatusReg =>
      let p__88 := _get_StatusReg_KSU w__3 in
      let b__0 := p__88 in
      returnm (if eq_vec b__0 ('b"00"  : mword 2) then Kernel
               else if eq_vec b__0 ('b"01"  : mword 2) then Supervisor
               else if eq_vec b__0 ('b"10"  : mword 2) then User
               else User))
    : M (AccessLevel).

Definition checkCP0AccessHook '(tt : unit) : M (unit) := returnm tt.

Definition checkCP0Access '(tt : unit) : M (unit) :=
   (getAccessLevel tt) >>= fun accessLevel =>
   (and_boolM (returnm ((generic_neq accessLevel Kernel)  : bool))
      (read_reg CP0Status_ref >>= fun w__0 : StatusReg =>
       returnm ((negb (bit_to_bool (access_vec_dec (_get_StatusReg_CU w__0) 0)))  : bool))) >>= fun w__1 : bool =>
   (if sumbool_of_bool w__1 then
      (_set_CauseReg_CE CP0Cause_ref ('b"00"  : mword 2)) >> (SignalException CpU)  : M (unit)
    else returnm tt) >>
   (checkCP0AccessHook tt)
    : M (unit).

Definition incrementCP0Count '(tt : unit) : M (unit) :=
   ((read_reg TLBRandom_ref)  : M (mword 6)) >>= fun w__0 : mword 6 =>
   ((read_reg TLBWired_ref)  : M (mword 6)) >>= fun w__1 : mword 6 =>
   (if eq_vec w__0 w__1 then returnm TLBIndexMax
    else
      ((read_reg TLBRandom_ref)  : M (mword 6)) >>= fun w__2 : mword 6 =>
      returnm (sub_vec_int w__2 1)) >>= fun w__3 : mword 6 =>
   write_reg TLBRandom_ref w__3 >>
   ((read_reg CP0Count_ref)  : M (mword 32)) >>= fun w__4 : mword 32 =>
   write_reg CP0Count_ref (add_vec_int w__4 1) >>
   ((read_reg CP0Count_ref)  : M (mword 32)) >>= fun w__5 : mword 32 =>
   ((read_reg CP0Compare_ref)  : M (mword 32)) >>= fun w__6 : mword 32 =>
   (if eq_vec w__5 w__6 then
      read_reg CP0Cause_ref >>= fun w__7 : CauseReg =>
      (_set_CauseReg_IP CP0Cause_ref (or_vec (_get_CauseReg_IP w__7) (Ox"80"  : mword 8)))
       : M (unit)
    else returnm tt) >>
   read_reg CP0Status_ref >>= fun w__8 : StatusReg =>
   let ims := _get_StatusReg_IM w__8 in
   read_reg CP0Cause_ref >>= fun w__9 : CauseReg =>
   let ips := _get_CauseReg_IP w__9 in
   read_reg CP0Status_ref >>= fun w__10 : StatusReg =>
   let ie := _get_StatusReg_IE w__10 in
   read_reg CP0Status_ref >>= fun w__11 : StatusReg =>
   let exl := _get_StatusReg_EXL w__11 in
   read_reg CP0Status_ref >>= fun w__12 : StatusReg =>
   let erl := _get_StatusReg_ERL w__12 in
   (if andb (negb (bits_to_bool exl))
         (andb (negb (bits_to_bool erl))
            (andb (bits_to_bool ie) (neq_vec (and_vec ips ims) (Ox"00"  : mword 8)))) then
      (SignalException Interrupt)
       : M (unit)
    else returnm tt)
    : M (unit).

Definition strReg (r : mword 5) : string := concat_str_dec "$" (projT1 (uint r)).

Definition strRRRArgs (r2 : mword 5) (r1 : mword 5) (rd : mword 5) : string :=
   String.append (strReg rd)
     (String.append ", " (String.append (strReg r1) (String.append ", " (strReg r2)))).

Definition strRRIArgs {n : Z} (rs : mword 5) (rd : mword 5) (imm : mword n) `{ArithFact (n >? 0)}
: string :=
   String.append (strReg rd)
     (String.append ", "
        (String.append (strReg rs) (String.append ", " (dec_str (projT1 (sint imm)))))).

Definition strRRIUArgs {n : Z} (rs : mword 5) (rd : mword 5) (imm : mword n) `{ArithFact (n >? 0)}
: string :=
   String.append (strReg rd)
     (String.append ", "
        (String.append (strReg rs) (String.append ", " (hex_str (projT1 (uint imm)))))).

Definition strRIArgs {n : Z} (rd : mword 5) (imm : mword n) `{ArithFact (n >? 0)} : string :=
   String.append (strReg rd) (String.append ", " (hex_str (projT1 (uint imm)))).

Definition strMemArgs {n : Z} (base : mword 5) (rt : mword 5) (offset : mword n)
`{ArithFact (n >? 0)}
: string :=
   String.append (strReg rt)
     (String.append ", "
        (String.append (dec_str (projT1 (sint offset)))
           (String.append "(" (String.append (strReg base) ")")))).

Definition decode_failure_of_num (arg_ : Z) `{ArithFact ((0 <=? arg_) && (arg_ <=? 3))}
: decode_failure :=
   let l__61 := arg_ in
   if sumbool_of_bool (Z.eqb l__61 0) then no_matching_pattern
   else if sumbool_of_bool (Z.eqb l__61 1) then unsupported_instruction
   else if sumbool_of_bool (Z.eqb l__61 2) then illegal_instruction
   else internal_error.

Definition num_of_decode_failure (arg_ : decode_failure)
: {e : Z & ArithFact ((0 <=? e) && (e <=? 3))} :=
   build_ex (
      match arg_ with
      | no_matching_pattern => 0
      | unsupported_instruction => 1
      | illegal_instruction => 2
      | internal_error => 3
      end
   ).

Definition undefined_decode_failure '(tt : unit) : M (decode_failure) :=
   (internal_pick
      [no_matching_pattern;
      unsupported_instruction;
      illegal_instruction;
      internal_error])
    : M (decode_failure).

Definition Comparison_of_num (arg_ : Z) `{ArithFact ((0 <=? arg_) && (arg_ <=? 7))} : Comparison :=
   let l__54 := arg_ in
   if sumbool_of_bool (Z.eqb l__54 0) then EQ'
   else if sumbool_of_bool (Z.eqb l__54 1) then NE
   else if sumbool_of_bool (Z.eqb l__54 2) then GE
   else if sumbool_of_bool (Z.eqb l__54 3) then GEU
   else if sumbool_of_bool (Z.eqb l__54 4) then GT'
   else if sumbool_of_bool (Z.eqb l__54 5) then LE
   else if sumbool_of_bool (Z.eqb l__54 6) then LT'
   else LTU.

Definition num_of_Comparison (arg_ : Comparison) : {e : Z & ArithFact ((0 <=? e) && (e <=? 7))} :=
   build_ex (
      match arg_ with
      | EQ' => 0
      | NE => 1
      | GE => 2
      | GEU => 3
      | GT' => 4
      | LE => 5
      | LT' => 6
      | LTU => 7
      end
   ).

Definition undefined_Comparison '(tt : unit) : M (Comparison) :=
   (internal_pick [EQ'; NE; GE; GEU; GT'; LE; LT'; LTU])  : M (Comparison).

Definition strCmp (cmp : Comparison) : string :=
   match cmp with
   | EQ' => "eq"
   | NE => "ne"
   | GE => "ge"
   | GEU => "geu"
   | GT' => "gt"
   | LE => "le"
   | LT' => "lt"
   | LTU => "ltu"
   end.

Definition compare (cmp : Comparison) (valA : mword 64) (valB : mword 64) : bool :=
   match cmp with
   | EQ' => eq_vec valA valB
   | NE => neq_vec valA valB
   | GE => zopz0zKzJ_s valA valB
   | GEU => zopz0zKzJ_u valA valB
   | GT' => zopz0zI_s valB valA
   | LE => zopz0zKzJ_s valB valA
   | LT' => zopz0zI_s valA valB
   | LTU => zopz0zI_u valA valB
   end.

Definition WordType_of_num (arg_ : Z) `{ArithFact ((0 <=? arg_) && (arg_ <=? 3))} : WordType :=
   let l__51 := arg_ in
   if sumbool_of_bool (Z.eqb l__51 0) then B
   else if sumbool_of_bool (Z.eqb l__51 1) then H
   else if sumbool_of_bool (Z.eqb l__51 2) then W
   else D.

Definition num_of_WordType (arg_ : WordType) : {e : Z & ArithFact ((0 <=? e) && (e <=? 3))} :=
   build_ex (match arg_ with | B => 0 | H => 1 | W => 2 | D => 3 end).

Definition undefined_WordType '(tt : unit) : M (WordType) :=
   (internal_pick [B; H; W; D])  : M (WordType).

Definition WordTypeUnaligned_of_num (arg_ : Z) `{ArithFact ((0 <=? arg_) && (arg_ <=? 3))}
: WordTypeUnaligned :=
   let l__48 := arg_ in
   if sumbool_of_bool (Z.eqb l__48 0) then WL
   else if sumbool_of_bool (Z.eqb l__48 1) then WR
   else if sumbool_of_bool (Z.eqb l__48 2) then DL
   else DR.

Definition num_of_WordTypeUnaligned (arg_ : WordTypeUnaligned)
: {e : Z & ArithFact ((0 <=? e) && (e <=? 3))} :=
   build_ex (match arg_ with | WL => 0 | WR => 1 | DL => 2 | DR => 3 end).

Definition undefined_WordTypeUnaligned '(tt : unit) : M (WordTypeUnaligned) :=
   (internal_pick [WL; WR; DL; DR])  : M (WordTypeUnaligned).

Definition strWordType (w : WordType) : string :=
   match w with | B => "b" | H => "h" | W => "w" | D => "d" end.

Definition unalignedBytesTouched (vAddr : Z) (width : WordTypeUnaligned) : (Z * Z) :=
   let woffset := projT1 (emod_with_eq vAddr 4) in
   let doffset := projT1 (emod_with_eq vAddr 8) in
   match width with
   | WL => (vAddr, Z.sub 4 woffset)
   | WR => (Z.sub vAddr woffset, Z.add woffset 1)
   | DL => (vAddr, Z.sub 8 doffset)
   | DR => (Z.sub vAddr doffset, Z.add doffset 1)
   end.

Definition wordWidthBytes (w : WordType)
: {rangevar : Z & ArithFact ((1 <=? rangevar) && (rangevar <=? 8))} :=
   build_ex (match w with | B => 1 | H => 2 | W => 4 | D => 8 end).

Definition alignment_width := 16.
Hint Unfold alignment_width : sail.
Definition isAddressAligned (addr : mword 64) (wordType : WordType) : bool :=
   let a := projT1 (uint addr) in
   Z.eqb (projT1 (ediv_with_eq a alignment_width))
     (projT1
      (ediv_with_eq (Z.sub (Z.add a (projT1 (wordWidthBytes wordType))) 1) alignment_width)).

Definition extendLoad {sz : Z} (memResult : mword sz) (sign : bool) `{ArithFact (sz <=? 64)}
: mword 64 :=
   if sumbool_of_bool sign then mips_sign_extend 64 memResult else mips_zero_extend 64 memResult.

Definition MEMr_wrapper (addr : mword 64) (size : Z) `{ArithFact ((1 <=? size) && (size <=? 8))}
: M (mword (8 * size)) :=
   (if eq_vec addr (Ox"000000007F000000"  : mword 64) then
      ((read_reg UART_RVALID_ref)  : M (mword 1)) >>= fun rvalid =>
      write_reg UART_RVALID_ref ('b"0"  : mword 1) >>
      ((read_reg UART_RDATA_ref)  : M (mword 8)) >>= fun w__0 : mword 8 =>
      returnm (mask (Z.mul 8 (projT1 (__id size)))
                 (concat_vec (Ox"00000000"  : mword 32)
                    (concat_vec w__0
                       (concat_vec rvalid
                          (concat_vec ('b"0000000"  : mword 7) (Ox"0000"  : mword 16))))))
    else if eq_vec addr (Ox"000000007F000004"  : mword 64) then
      returnm (mask (Z.mul 8 (projT1 (__id size))) (Ox"000000000004FFFF"  : mword 64))
    else (MEMr addr size) >>= fun w__1 : mword (8 * size) => returnm (reverse_endianness w__1))
    : M (mword (8 * size)).

Definition MEMr_reserve_wrapper (addr : mword 64) (size : Z)
`{ArithFact ((1 <=? size) && (size <=? 8))}
: M (mword (8 * size)) :=
   (MEMr_reserve addr size) >>= fun w__0 : mword (8 * size) => returnm (reverse_endianness w__0).

Definition init_cp0_state '(tt : unit) : M (unit) :=
   (_set_StatusReg_BEV CP0Status_ref ((cast_unit_vec B1)  : mword 1))  : M (unit).

Definition tlbEntryMatch (r : mword 2) (vpn2 : mword 27) (asid : mword 8) (entry : TLBEntry) : bool :=
   let entryValid := _get_TLBEntry_valid entry in
   let entryR := _get_TLBEntry_r entry in
   let entryMask := _get_TLBEntry_pagemask entry in
   let entryVPN := _get_TLBEntry_vpn2 entry in
   let entryASID := _get_TLBEntry_asid entry in
   let entryG := _get_TLBEntry_g entry in
   let vpnMask : bits 27 := not_vec (mips_zero_extend 27 entryMask) in
   andb (bits_to_bool entryValid)
     (andb (eq_vec r entryR)
        (andb (eq_vec (and_vec vpn2 vpnMask) (and_vec entryVPN vpnMask))
           (orb (eq_vec asid entryASID) (bits_to_bool entryG)))).

Definition tlbSearch (VAddr : mword 64) : M (option (mword 6)) :=
   catch_early_return
     (let r := subrange_vec_dec VAddr 63 62 in
     let vpn2 := subrange_vec_dec VAddr 39 13 in
     liftR (read_reg TLBEntryHi_ref) >>= fun w__0 : TLBEntryHiReg =>
     let asid := _get_TLBEntryHiReg_ASID w__0 in
     (let loop_idx_lower := 0 in
     let loop_idx_upper := 63 in
     (foreach_ZM_up loop_idx_lower loop_idx_upper 1 tt
       (fun idx _ _ =>
         liftR ((reg_deref (vec_access_dec TLBEntries idx))) >>= fun w__1 : TLBEntry =>
         (if tlbEntryMatch r vpn2 asid w__1 then
            (early_return ((Some (to_bits 6 idx))  : option (mword 6)) : MR unit (option (mword 6)))
             : MR (unit) _
          else returnm tt)
          : MR (unit) _))) >>
     returnm None).

Definition MIPSSegmentOf (vAddr : mword 64) : M ((AccessLevel * option (mword 64))) :=
   let compat32 :=
     eq_vec (subrange_vec_dec vAddr 61 31)
       ('b"1111111111111111111111111111111"
        : mword (61 - 31 + 1)) in
   let b__0 := subrange_vec_dec vAddr 63 62 in
   (if eq_vec b__0 ('b"11"  : mword (63 - 62 + 1)) then
      returnm (match (compat32, subrange_vec_dec vAddr 30 29) with
               | (true, b__1) =>
                  if eq_vec b__1 ('b"11"  : mword (30 - 29 + 1)) then
                    (Kernel, None
                     : option (bits 64))
                  else if eq_vec b__1 ('b"10"  : mword (30 - 29 + 1)) then
                    (Supervisor, None
                     : option (bits 64))
                  else if eq_vec b__1 ('b"01"  : mword (30 - 29 + 1)) then
                    (Kernel, Some
                               (concat_vec (Ox"00000000"  : mword 32)
                                  (concat_vec ('b"000"  : mword 3) (subrange_vec_dec vAddr 28 0))))
                  else if eq_vec b__1 ('b"00"  : mword (30 - 29 + 1)) then
                    (Kernel, Some
                               (concat_vec (Ox"00000000"  : mword 32)
                                  (concat_vec ('b"000"  : mword 3) (subrange_vec_dec vAddr 28 0))))
                  else match (true, b__1) with | (_, _) => (Kernel, None  : option (bits 64)) end
               | (_, _) => (Kernel, None  : option (bits 64))
               end)
    else if eq_vec b__0 ('b"10"  : mword (63 - 62 + 1)) then
      returnm (Kernel, Some (concat_vec ('b"00000"  : mword 5) (subrange_vec_dec vAddr 58 0)))
    else if eq_vec b__0 ('b"01"  : mword (63 - 62 + 1)) then
      returnm (Supervisor, None  : option (bits 64))
    else if eq_vec b__0 ('b"00"  : mword (63 - 62 + 1)) then
      returnm (User, None  : option (bits 64))
    else assert_exp' false "Pattern match failure at mips_tlb.sail 64:1 - 75:2" >>= fun _ => exit tt)
    : M ((AccessLevel * option (mword 64))).

Definition TLBTranslate2 (vAddr : mword 64) (accessType : MemAccessType) (accessLevel : AccessLevel)
: M ((mword 64 * MemAccessCapRestriction)) :=
   (tlbSearch vAddr) >>= fun idx =>
   (match idx with
    | Some idx =>
       let i := projT1 (uint idx) in
       (reg_deref (vec_access_dec TLBEntries i)) >>= fun entry =>
       let entryMask := _get_TLBEntry_pagemask entry in
       let b__0 := entryMask in
       (if eq_vec b__0 (Ox"0000"  : mword 16) then returnm (build_ex 12)
        else if eq_vec b__0 (Ox"0003"  : mword 16) then returnm (build_ex 14)
        else if eq_vec b__0 (Ox"000F"  : mword 16) then returnm (build_ex 16)
        else if eq_vec b__0 (Ox"003F"  : mword 16) then returnm (build_ex 18)
        else if eq_vec b__0 (Ox"00FF"  : mword 16) then returnm (build_ex 20)
        else if eq_vec b__0 (Ox"03FF"  : mword 16) then returnm (build_ex 22)
        else if eq_vec b__0 (Ox"0FFF"  : mword 16) then returnm (build_ex 24)
        else if eq_vec b__0 (Ox"3FFF"  : mword 16) then returnm (build_ex 26)
        else if eq_vec b__0 (Ox"FFFF"  : mword 16) then returnm (build_ex 28)
        else
          (undefined_range 12 28)
           : M ({rangevar : Z & ArithFact ((12 <=? rangevar) && (rangevar <=? 28))})) >>= fun '(existT _ evenOddBit _ : {rangevar : Z & ArithFact ((12 <=?
         rangevar) &&
         (rangevar <=? 28))}) =>
       let isOdd := access_vec_dec vAddr evenOddBit in
       let '(caps, caplg, capl, pfn, d, v) :=
         if (bit_to_bool isOdd)  : bool then
           (_get_TLBEntry_caps1 entry, _get_TLBEntry_caplg1 entry, _get_TLBEntry_capl1 entry, _get_TLBEntry_pfn1
                                                                                entry, _get_TLBEntry_d1
                                                                                entry, _get_TLBEntry_v1
                                                                                entry)
         else
           (_get_TLBEntry_caps0 entry, _get_TLBEntry_caplg0 entry, _get_TLBEntry_capl0 entry, _get_TLBEntry_pfn0
                                                                                entry, _get_TLBEntry_d0
                                                                                entry, _get_TLBEntry_v0
                                                                                entry) in
       (if negb (bits_to_bool v) then
          (SignalExceptionTLB (if generic_eq accessType StoreData then XTLBInvS else XTLBInvL) vAddr)
           : M ((mword 64 * MemAccessCapRestriction))
        else if andb (generic_eq accessType StoreData) (negb (bits_to_bool d)) then
          (SignalExceptionTLB TLBMod vAddr)
           : M ((mword 64 * MemAccessCapRestriction))
        else
          let res : bits 64 :=
            mips_zero_extend 64
              (concat_vec (subrange_vec_dec pfn 23 (Z.sub evenOddBit 12))
                 (subrange_vec_dec vAddr (Z.sub evenOddBit 1) 0)) in
          (if generic_eq accessType StoreData then
             returnm (if (bits_to_bool caps)  : bool then Trap else Unrestricted)
           else if (bits_to_bool capl)  : bool then returnm Clear
           else
             (match accessLevel with
              | User =>
                 read_reg TLBEntryHi_ref >>= fun w__11 : TLBEntryHiReg =>
                 returnm (_get_TLBEntryHiReg_CLGU w__11)
              | Supervisor =>
                 read_reg TLBEntryHi_ref >>= fun w__12 : TLBEntryHiReg =>
                 returnm (_get_TLBEntryHiReg_CLGS w__12)
              | Kernel =>
                 read_reg TLBEntryHi_ref >>= fun w__13 : TLBEntryHiReg =>
                 returnm (_get_TLBEntryHiReg_CLGK w__13)
              end) >>= fun gclg : bits 1 =>
             returnm (if neq_bool (bits_to_bool gclg) (bits_to_bool caplg) then Trap
                      else Unrestricted)) >>= fun macr =>
          returnm (res, macr))
        : M ((mword 64 * MemAccessCapRestriction))
    | None =>
       (SignalExceptionTLB (if generic_eq accessType StoreData then XTLBRefillS else XTLBRefillL)
          vAddr)
        : M ((mword 64 * MemAccessCapRestriction))
    end)
    : M ((mword 64 * MemAccessCapRestriction)).

Definition TLBTranslateC (vAddr : mword 64) (accessType : MemAccessType)
: M ((mword 64 * MemAccessCapRestriction)) :=
   (getAccessLevel tt) >>= fun currentAccessLevel =>
   let compat32 :=
     eq_vec (subrange_vec_dec vAddr 61 31)
       ('b"1111111111111111111111111111111"
        : mword (61 - 31 + 1)) in
   (MIPSSegmentOf vAddr) >>= fun '((requiredLevel, addr)
   : (AccessLevel * option (bits 64))) =>
   (if negb (grantsAccess currentAccessLevel requiredLevel) then
      (SignalExceptionBadAddr (if generic_eq accessType StoreData then AdES else AdEL) vAddr)
       : M ((mword 64 * MemAccessCapRestriction))
    else
      (match addr with
       | Some a => returnm (a, Unrestricted)
       | None =>
          (if sumbool_of_bool
             (andb (negb compat32)
                ((Z.gtb (projT1 (uint (subrange_vec_dec vAddr 61 0))) MAX_VA)
                 : bool)) then
             (SignalExceptionBadAddr (if generic_eq accessType StoreData then AdES else AdEL) vAddr)
              : M ((mword 64 * MemAccessCapRestriction))
           else
             (TLBTranslate2 vAddr accessType requiredLevel)
              : M ((mword 64 * MemAccessCapRestriction)))
           : M ((mword 64 * MemAccessCapRestriction))
       end) >>= fun '((pa, c)
      : (bits 64 * MemAccessCapRestriction)) =>
      (if sumbool_of_bool (Z.gtb (projT1 (uint pa)) MAX_PA) then
         (SignalExceptionBadAddr (if generic_eq accessType StoreData then AdES else AdEL) vAddr)
          : M ((mword 64 * MemAccessCapRestriction))
       else returnm (pa, c))
       : M ((mword 64 * MemAccessCapRestriction)))
    : M ((mword 64 * MemAccessCapRestriction)).

Definition TLBTranslate (vAddr : mword 64) (accessType : MemAccessType) : M (mword 64) :=
   (TLBTranslateC vAddr accessType) >>= fun '(addr, c) => returnm addr.

Definition get_CP0EPC '(tt : unit) : M (mword 64) :=
   ((read_reg CP0EPC_ref)  : M (mword 64))  : M (mword 64).

Definition get_CP0ErrorEPC '(tt : unit) : M (mword 64) :=
   ((read_reg CP0ErrorEPC_ref)  : M (mword 64))  : M (mword 64).

Definition set_CP0ErrorEPC (v : mword 64) : M (unit) :=
   write_reg CP0ErrorEPC_ref v >> (skip tt)  : M (unit).

Definition MEMw_wrapper (addr : mword 64) (size : Z) (data : mword (8 * size))
`{ArithFact ((1 <=? size) && (size <=? 8))}
: M (unit) :=
   let ledata := reverse_endianness data in
   (if eq_vec addr (Ox"000000007F000000"  : mword 64) then
      write_reg UART_WDATA_ref (subrange_vec_dec ledata 7 0) >>
      write_reg UART_WRITTEN_ref ((cast_unit_vec B1)  : bits 1)
       : M (unit)
    else (MEMea addr size) >> (MEMval addr size ledata)  : M (unit))
    : M (unit).

Definition MEMw_conditional_wrapper (addr : mword 64) (size : Z) (data : mword (8 * size))
`{ArithFact ((1 <=? size) && (size <=? 8))}
: M (bool) :=
   (MEMea_conditional addr size) >>
   (MEMval_conditional addr size (reverse_endianness data))
    : M (bool).

Definition addrWrapper (addr : mword 64) (accessType : MemAccessType) (width : WordType) : mword 64 :=
   addr.

Definition addrWrapperUnaligned
(addr : mword 64) (accessType : MemAccessType) (width : WordTypeUnaligned)
: (mword 64 * Z) :=
   let '(addr, size) := unalignedBytesTouched (projT1 (uint addr)) width in
   (to_bits 64 addr, size).

Definition TranslatePC (vAddr : mword 64) : M (mword 64) :=
   (incrementCP0Count tt) >>
   (if neq_vec (subrange_vec_dec vAddr 1 0) ('b"00"  : mword (1 - 0 + 1)) then
      (SignalExceptionBadAddr AdEL vAddr)
       : M (mword 64)
    else (TLBTranslate vAddr Instruction)  : M (mword 64))
    : M (mword 64).

Definition have_cp2 := false.
Hint Unfold have_cp2 : sail.
Definition ERETHook '(tt : unit) : unit := tt.

Definition init_cp2_state '(tt : unit) : M (unit) := (skip tt) >> (skip tt)  : M (unit).

Definition cp2_next_pc '(tt : unit) : M (unit) := (skip tt) >> (skip tt)  : M (unit).

Definition dump_cp2_state '(tt : unit) : M (unit) := (skip tt) >> (skip tt)  : M (unit).

Definition execute_branch (pc : mword 64) : M (unit) :=
   (skip tt) >> (skip tt) >> (execute_branch_mips pc)  : M (unit).

Definition TLBWriteEntry (idx : mword 6) : M (unit) :=
   ((read_reg TLBPageMask_ref)  : M (mword 16)) >>= fun pagemask =>
   let b__0 := pagemask in
   (if eq_vec b__0 (Ox"0000"  : mword 16) then returnm tt
    else if eq_vec b__0 (Ox"0003"  : mword 16) then returnm tt
    else if eq_vec b__0 (Ox"000F"  : mword 16) then returnm tt
    else if eq_vec b__0 (Ox"003F"  : mword 16) then returnm tt
    else if eq_vec b__0 (Ox"00FF"  : mword 16) then returnm tt
    else if eq_vec b__0 (Ox"03FF"  : mword 16) then returnm tt
    else if eq_vec b__0 (Ox"0FFF"  : mword 16) then returnm tt
    else if eq_vec b__0 (Ox"3FFF"  : mword 16) then returnm tt
    else if eq_vec b__0 (Ox"FFFF"  : mword 16) then returnm tt
    else (SignalException MCheck)  : M (unit)) >>
   let i := projT1 (uint idx) in
   let entry := vec_access_dec TLBEntries i in
   (_set_TLBEntry_pagemask entry pagemask) >>
   read_reg TLBEntryHi_ref >>= fun w__0 : TLBEntryHiReg =>
   (_set_TLBEntry_r entry (_get_TLBEntryHiReg_R w__0)) >>
   read_reg TLBEntryHi_ref >>= fun w__1 : TLBEntryHiReg =>
   (_set_TLBEntry_vpn2 entry (_get_TLBEntryHiReg_VPN2 w__1)) >>
   read_reg TLBEntryHi_ref >>= fun w__2 : TLBEntryHiReg =>
   (_set_TLBEntry_asid entry (_get_TLBEntryHiReg_ASID w__2)) >>
   (and_boolM
      (read_reg TLBEntryLo0_ref >>= fun w__3 : TLBEntryLoReg =>
       returnm ((bits_to_bool (_get_TLBEntryLoReg_G w__3))  : bool))
      (read_reg TLBEntryLo1_ref >>= fun w__4 : TLBEntryLoReg =>
       returnm ((bits_to_bool (_get_TLBEntryLoReg_G w__4))  : bool))) >>= fun w__5 : bool =>
   (_set_TLBEntry_g entry ((bool_to_bits w__5)  : mword 1)) >>
   (_set_TLBEntry_valid entry ((cast_unit_vec B1)  : mword 1)) >>
   read_reg TLBEntryLo0_ref >>= fun w__6 : TLBEntryLoReg =>
   (_set_TLBEntry_caps0 entry (_get_TLBEntryLoReg_CapS w__6)) >>
   read_reg TLBEntryLo0_ref >>= fun w__7 : TLBEntryLoReg =>
   (_set_TLBEntry_capl0 entry (_get_TLBEntryLoReg_CapL w__7)) >>
   read_reg TLBEntryLo0_ref >>= fun w__8 : TLBEntryLoReg =>
   (_set_TLBEntry_caplg0 entry (_get_TLBEntryLoReg_CapLG w__8)) >>
   read_reg TLBEntryLo0_ref >>= fun w__9 : TLBEntryLoReg =>
   (_set_TLBEntry_pfn0 entry (_get_TLBEntryLoReg_PFN w__9)) >>
   read_reg TLBEntryLo0_ref >>= fun w__10 : TLBEntryLoReg =>
   (_set_TLBEntry_c0 entry (_get_TLBEntryLoReg_C w__10)) >>
   read_reg TLBEntryLo0_ref >>= fun w__11 : TLBEntryLoReg =>
   (_set_TLBEntry_d0 entry (_get_TLBEntryLoReg_D w__11)) >>
   read_reg TLBEntryLo0_ref >>= fun w__12 : TLBEntryLoReg =>
   (_set_TLBEntry_v0 entry (_get_TLBEntryLoReg_V w__12)) >>
   read_reg TLBEntryLo1_ref >>= fun w__13 : TLBEntryLoReg =>
   (_set_TLBEntry_caps1 entry (_get_TLBEntryLoReg_CapS w__13)) >>
   read_reg TLBEntryLo1_ref >>= fun w__14 : TLBEntryLoReg =>
   (_set_TLBEntry_capl1 entry (_get_TLBEntryLoReg_CapL w__14)) >>
   read_reg TLBEntryLo1_ref >>= fun w__15 : TLBEntryLoReg =>
   (_set_TLBEntry_caplg1 entry (_get_TLBEntryLoReg_CapLG w__15)) >>
   read_reg TLBEntryLo1_ref >>= fun w__16 : TLBEntryLoReg =>
   (_set_TLBEntry_pfn1 entry (_get_TLBEntryLoReg_PFN w__16)) >>
   read_reg TLBEntryLo1_ref >>= fun w__17 : TLBEntryLoReg =>
   (_set_TLBEntry_c1 entry (_get_TLBEntryLoReg_C w__17)) >>
   read_reg TLBEntryLo1_ref >>= fun w__18 : TLBEntryLoReg =>
   (_set_TLBEntry_d1 entry (_get_TLBEntryLoReg_D w__18)) >>
   read_reg TLBEntryLo1_ref >>= fun w__19 : TLBEntryLoReg =>
   (_set_TLBEntry_v1 entry (_get_TLBEntryLoReg_V w__19))
    : M (unit).

Definition decode (v__0 : mword 32) : option ast :=
   if eq_vec (subrange_vec_dec v__0 31 26) ('b"011001"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (DADDIU (rs, rt, imm))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000101101"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DADDU (rs, rt, rd))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"011000"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (DADDI (rs, rt, imm))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000101100"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DADD (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000100000"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (ADD (rs, rt, rd))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"001000"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (ADDI (rs, rt, imm))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000100001"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (ADDU (rs, rt, rd))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"001001"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (ADDIU (rs, rt, imm))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000101111"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSUBU (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000101110"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSUB (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000100010"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SUB (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000100011"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SUBU (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000100100"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (AND (rs, rt, rd))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"001100"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (ANDI (rs, rt, imm))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000100101"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (OR (rs, rt, rd))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"001101"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (ORI (rs, rt, imm))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000100111"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (NOR (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000100110"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (XOR (rs, rt, rd))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"001110"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (XORI (rs, rt, imm))
   else if eq_vec (subrange_vec_dec v__0 31 21) ('b"00111100000"  : mword (31 - 21 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (LUI (rt, imm))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"00000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"111000"  : mword (5 - 0 + 1))) then
     let sa : bits 5 := subrange_vec_dec v__0 10 6 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSLL (rt, rd, sa))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"00000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"111100"  : mword (5 - 0 + 1))) then
     let sa : bits 5 := subrange_vec_dec v__0 10 6 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSLL32 (rt, rd, sa))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000010100"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSLLV (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"00000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"111011"  : mword (5 - 0 + 1))) then
     let sa : bits 5 := subrange_vec_dec v__0 10 6 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSRA (rt, rd, sa))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"00000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"111111"  : mword (5 - 0 + 1))) then
     let sa : bits 5 := subrange_vec_dec v__0 10 6 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSRA32 (rt, rd, sa))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000010111"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSRAV (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"00000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"111010"  : mword (5 - 0 + 1))) then
     let sa : bits 5 := subrange_vec_dec v__0 10 6 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSRL (rt, rd, sa))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"00000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"111110"  : mword (5 - 0 + 1))) then
     let sa : bits 5 := subrange_vec_dec v__0 10 6 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSRL32 (rt, rd, sa))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000010110"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (DSRLV (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"00000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"000000"  : mword (5 - 0 + 1))) then
     let sa : regno := subrange_vec_dec v__0 10 6 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SLL (rt, rd, sa))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000000100"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SLLV (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"00000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"000011"  : mword (5 - 0 + 1))) then
     let sa : regno := subrange_vec_dec v__0 10 6 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SRA (rt, rd, sa))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000000111"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SRAV (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"00000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"000010"  : mword (5 - 0 + 1))) then
     let sa : regno := subrange_vec_dec v__0 10 6 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SRL (rt, rd, sa))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000000110"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SRLV (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000101010"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SLT (rs, rt, rd))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"001010"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (SLTI (rs, rt, imm))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000101011"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (SLTU (rs, rt, rd))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"001011"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (SLTIU (rs, rt, imm))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000001011"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (MOVN (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000001010"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (MOVZ (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 16) (Ox"0000"  : mword (31 - 16 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000010000"  : mword (10 - 0 + 1))) then
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (MFHI rd)
   else if andb (eq_vec (subrange_vec_dec v__0 31 16) (Ox"0000"  : mword (31 - 16 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000010010"  : mword (10 - 0 + 1))) then
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (MFLO rd)
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 0) ('b"000000000000000010001"  : mword (20 - 0 + 1)))
   then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (MTHI rs)
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 0) ('b"000000000000000010011"  : mword (20 - 0 + 1)))
   then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (MTLO rs)
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"011100"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000000010"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (MUL (rs, rt, rd))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"0018"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (MULT (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"0019"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (MULTU (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"001C"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (DMULT (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"001D"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (DMULTU (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"011100"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"0000"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (MADD (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"011100"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"0001"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (MADDU (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"011100"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"0004"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (MSUB (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"011100"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"0005"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (MSUBU (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"001A"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (DIV (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"001B"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (DIVU (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"001E"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (DDIV (rs, rt))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"001F"  : mword (15 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (DDIVU (rs, rt))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"000010"  : mword (31 - 26 + 1)) then
     let offset : bits 26 := subrange_vec_dec v__0 25 0 in
     Some (J offset)
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"000011"  : mword (31 - 26 + 1)) then
     let offset : bits 26 := subrange_vec_dec v__0 25 0 in
     Some (JAL offset)
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (andb (eq_vec (subrange_vec_dec v__0 20 11) ('b"0000000000"  : mword (20 - 11 + 1)))
                (eq_vec (subrange_vec_dec v__0 5 0) ('b"001000"  : mword (5 - 0 + 1)))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (JR rs)
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (andb (eq_vec (subrange_vec_dec v__0 20 16) ('b"00000"  : mword (20 - 16 + 1)))
                (eq_vec (subrange_vec_dec v__0 5 0) ('b"001001"  : mword (5 - 0 + 1)))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (JALR (rs, rd))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"000100"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BEQ (rs, rt, imm, false, false))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"010100"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BEQ (rs, rt, imm, false, true))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"000101"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BEQ (rs, rt, imm, true, false))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"010101"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BEQ (rs, rt, imm, true, true))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"00000"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, LT', false, false))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"10000"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, LT', true, false))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"00010"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, LT', false, true))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"10010"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, LT', true, true))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"00001"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, GE, false, false))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"10001"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, GE, true, false))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"00011"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, GE, false, true))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"10011"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, GE, true, true))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000111"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"00000"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, GT', false, false))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"010111"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"00000"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, GT', false, true))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000110"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"00000"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, LE, false, false))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"010110"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"00000"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (BCMPZ (rs, imm, LE, false, true))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"001100"  : mword (5 - 0 + 1))) then
     Some (SYSCALL tt)
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"001101"  : mword (5 - 0 + 1))) then
     Some (BREAK tt)
   else if eq_vec v__0 (Ox"42000020"  : mword 32) then Some (WAIT tt)
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"110000"  : mword (5 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (TRAPREG (rs, rt, GE))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"110001"  : mword (5 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (TRAPREG (rs, rt, GEU))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"110010"  : mword (5 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (TRAPREG (rs, rt, LT'))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"110011"  : mword (5 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (TRAPREG (rs, rt, LTU))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"110100"  : mword (5 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (TRAPREG (rs, rt, EQ'))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000000"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"110110"  : mword (5 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rs : regno := subrange_vec_dec v__0 25 21 in
     Some (TRAPREG (rs, rt, NE))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"01100"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (TRAPIMM (rs, imm, EQ'))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"01110"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (TRAPIMM (rs, imm, NE))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"01000"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (TRAPIMM (rs, imm, GE))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"01001"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (TRAPIMM (rs, imm, GEU))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"01010"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (TRAPIMM (rs, imm, LT'))
   else if andb (eq_vec (subrange_vec_dec v__0 31 26) ('b"000001"  : mword (31 - 26 + 1)))
             (eq_vec (subrange_vec_dec v__0 20 16) ('b"01011"  : mword (20 - 16 + 1))) then
     let rs : regno := subrange_vec_dec v__0 25 21 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     Some (TRAPIMM (rs, imm, LTU))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"100000"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Load (B, true, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"100100"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Load (B, false, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"100001"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Load (H, true, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"100101"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Load (H, false, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"100011"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Load (W, true, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"100111"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Load (W, false, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"110111"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Load (D, false, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"110000"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Load (W, true, true, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"110100"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Load (D, false, true, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"101000"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Store (B, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"101001"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Store (H, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"101011"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Store (W, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"111111"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Store (D, false, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"111000"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Store (W, true, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"111100"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (Store (D, true, base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"100010"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (LWL (base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"100110"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (LWR (base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"101010"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (SWL (base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"101110"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (SWR (base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"011010"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (LDL (base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"011011"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (LDR (base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"101100"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (SDL (base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"101101"  : mword (31 - 26 + 1)) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let offset : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (SDR (base, rt, offset))
   else if eq_vec (subrange_vec_dec v__0 31 26) ('b"101111"  : mword (31 - 26 + 1)) then
     let op : regno := subrange_vec_dec v__0 20 16 in
     let imm : imm16 := subrange_vec_dec v__0 15 0 in
     let base : regno := subrange_vec_dec v__0 25 21 in
     Some (CACHE (base, op, imm))
   else if andb
             (eq_vec (subrange_vec_dec v__0 31 11)
                ('b"000000000000000000000"
                 : mword (31 - 11 + 1)))
             (eq_vec (subrange_vec_dec v__0 5 0) ('b"001111"  : mword (5 - 0 + 1))) then
     Some (SYNC tt)
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"01000000000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 3) (Ox"00"  : mword (10 - 3 + 1))) then
     let sel : bits 3 := subrange_vec_dec v__0 2 0 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (MFC0 (rt, rd, sel, false))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"01000000001"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 3) (Ox"00"  : mword (10 - 3 + 1))) then
     let sel : bits 3 := subrange_vec_dec v__0 2 0 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (MFC0 (rt, rd, sel, true))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"01000000100"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"B800"  : mword (15 - 0 + 1))) then
     Some (HCF tt)
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"01000000100"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 15 0) (Ox"D000"  : mword (15 - 0 + 1))) then
     Some (HCF tt)
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"01000000100"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 3) (Ox"00"  : mword (10 - 3 + 1))) then
     let sel : bits 3 := subrange_vec_dec v__0 2 0 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (MTC0 (rt, rd, sel, false))
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"01000000101"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 3) (Ox"00"  : mword (10 - 3 + 1))) then
     let sel : bits 3 := subrange_vec_dec v__0 2 0 in
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (MTC0 (rt, rd, sel, true))
   else if eq_vec v__0 (Ox"42000002"  : mword 32) then Some ((TLBWI tt)  : ast)
   else if eq_vec v__0 (Ox"42000006"  : mword 32) then Some ((TLBWR tt)  : ast)
   else if eq_vec v__0 (Ox"42000001"  : mword 32) then Some ((TLBR tt)  : ast)
   else if eq_vec v__0 (Ox"42000008"  : mword 32) then Some ((TLBP tt)  : ast)
   else if andb (eq_vec (subrange_vec_dec v__0 31 21) ('b"01111100000"  : mword (31 - 21 + 1)))
             (eq_vec (subrange_vec_dec v__0 10 0) ('b"00000111011"  : mword (10 - 0 + 1))) then
     let rt : regno := subrange_vec_dec v__0 20 16 in
     let rd : regno := subrange_vec_dec v__0 15 11 in
     Some (RDHWR (rt, rd))
   else if eq_vec v__0 (Ox"42000018"  : mword 32) then Some (ERET tt)
   else Some (RI tt).

Definition execute_XORI (rs : mword 5) (rt : mword 5) (imm : mword 16) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (wGPR rt (xor_vec w__0 (mips_zero_extend 64 imm)))
    : M (unit).

Definition execute_XOR (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 => (wGPR rd (xor_vec w__0 w__1))  : M (unit).

Definition execute_WAIT '(tt : unit) : M (unit) :=
   ((read_reg InBranchDelay_ref)  : M (mword 1)) >>= fun w__0 : mword 1 =>
   (if (bits_to_bool w__0)  : bool then (SignalException ResI)  : M (unit)
    else returnm tt) >>
   ((read_reg PC_ref)  : M (mword 64)) >>= fun w__1 : mword 64 =>
   write_reg NextPC_ref w__1
    : M (unit).

Definition execute_TRAPREG (rs : mword 5) (rt : mword 5) (cmp : Comparison) : M (unit) :=
   (rGPR rs) >>= fun rs_val =>
   (rGPR rt) >>= fun rt_val =>
   let condition := compare cmp rs_val rt_val in
   (if sumbool_of_bool condition then (SignalException Tr)  : M (unit)
    else returnm tt)
    : M (unit).

Definition execute_TRAPIMM (rs : mword 5) (imm : mword 16) (cmp : Comparison) : M (unit) :=
   (rGPR rs) >>= fun rs_val =>
   let imm_val : bits 64 := mips_sign_extend 64 imm in
   let condition := compare cmp rs_val imm_val in
   (if sumbool_of_bool condition then (SignalException Tr)  : M (unit)
    else returnm tt)
    : M (unit).

Definition execute_TLBWR '(tt : unit) : M (unit) :=
   (checkCP0Access tt) >>
   ((read_reg TLBRandom_ref)  : M (mword 6)) >>= fun w__0 : mword 6 =>
   (TLBWriteEntry w__0)
    : M (unit).

Definition execute_TLBWI '(tt : unit) : M (unit) :=
   (checkCP0Access tt) >>
   ((read_reg TLBIndex_ref)  : M (mword 6)) >>= fun w__0 : mword 6 =>
   (TLBWriteEntry w__0)
    : M (unit).

Definition execute_TLBR '(tt : unit) : M (unit) :=
   (checkCP0Access tt) >>
   ((read_reg TLBIndex_ref)  : M (mword 6)) >>= fun w__0 : mword 6 =>
   let i := projT1 (uint w__0) in
   (reg_deref (vec_access_dec TLBEntries i)) >>= fun entry =>
   write_reg TLBPageMask_ref (_get_TLBEntry_pagemask entry) >>
   (_set_TLBEntryHiReg_R TLBEntryHi_ref (_get_TLBEntry_r entry)) >>
   (_set_TLBEntryHiReg_CLGK TLBEntryHi_ref ((cast_unit_vec B0)  : mword 1)) >>
   (_set_TLBEntryHiReg_CLGS TLBEntryHi_ref ((cast_unit_vec B0)  : mword 1)) >>
   (_set_TLBEntryHiReg_CLGU TLBEntryHi_ref ((cast_unit_vec B0)  : mword 1)) >>
   (_set_TLBEntryHiReg_VPN2 TLBEntryHi_ref (_get_TLBEntry_vpn2 entry)) >>
   (_set_TLBEntryHiReg_ASID TLBEntryHi_ref (_get_TLBEntry_asid entry)) >>
   (_set_TLBEntryLoReg_CapS TLBEntryLo0_ref (_get_TLBEntry_caps0 entry)) >>
   (_set_TLBEntryLoReg_CapL TLBEntryLo0_ref (_get_TLBEntry_capl0 entry)) >>
   (_set_TLBEntryLoReg_CapLG TLBEntryLo0_ref (_get_TLBEntry_caplg0 entry)) >>
   (_set_TLBEntryLoReg_PFN TLBEntryLo0_ref (_get_TLBEntry_pfn0 entry)) >>
   (_set_TLBEntryLoReg_C TLBEntryLo0_ref (_get_TLBEntry_c0 entry)) >>
   (_set_TLBEntryLoReg_D TLBEntryLo0_ref (_get_TLBEntry_d0 entry)) >>
   (_set_TLBEntryLoReg_V TLBEntryLo0_ref (_get_TLBEntry_v0 entry)) >>
   (_set_TLBEntryLoReg_G TLBEntryLo0_ref (_get_TLBEntry_g entry)) >>
   (_set_TLBEntryLoReg_CapS TLBEntryLo1_ref (_get_TLBEntry_caps1 entry)) >>
   (_set_TLBEntryLoReg_CapL TLBEntryLo1_ref (_get_TLBEntry_capl1 entry)) >>
   (_set_TLBEntryLoReg_CapLG TLBEntryLo1_ref (_get_TLBEntry_caplg1 entry)) >>
   (_set_TLBEntryLoReg_PFN TLBEntryLo1_ref (_get_TLBEntry_pfn1 entry)) >>
   (_set_TLBEntryLoReg_C TLBEntryLo1_ref (_get_TLBEntry_c1 entry)) >>
   (_set_TLBEntryLoReg_D TLBEntryLo1_ref (_get_TLBEntry_d1 entry)) >>
   (_set_TLBEntryLoReg_V TLBEntryLo1_ref (_get_TLBEntry_v1 entry)) >>
   (_set_TLBEntryLoReg_G TLBEntryLo1_ref (_get_TLBEntry_g entry))
    : M (unit).

Definition execute_TLBP '(tt : unit) : M (unit) :=
   (checkCP0Access tt) >>
   read_reg TLBEntryHi_ref >>= fun w__0 : TLBEntryHiReg =>
   (tlbSearch (_get_TLBEntryHiReg_bits w__0)) >>= fun result =>
   (match result with
    | Some idx =>
       write_reg TLBProbe_ref ('b"0"  : mword 1) >> write_reg TLBIndex_ref idx  : M (unit)
    | None =>
       write_reg TLBProbe_ref ('b"1"  : mword 1) >>
       write_reg TLBIndex_ref ('b"000000"  : mword 6)
        : M (unit)
    end)
    : M (unit).

Definition execute_Store
(width : WordType) (conditional : bool) (base : mword 5) (rt : mword 5) (offset : mword 16)
: M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let vAddr : bits 64 := addrWrapper (add_vec (mips_sign_extend 64 offset) w__0) StoreData width in
   (rGPR rt) >>= fun rt_val =>
   (if negb (isAddressAligned vAddr width) then (SignalExceptionBadAddr AdES vAddr)  : M (unit)
    else
    (TLBTranslate vAddr StoreData) >>= fun pAddr =>
    if sumbool_of_bool conditional then
      (and_boolM
         (((read_reg CP0LLBit_ref)  : M (mword 1)) >>= fun w__1 : mword 1 =>
          returnm ((bit_to_bool (access_vec_dec w__1 0))  : bool))
         (((read_reg CP0LLAddr_ref)  : M (mword 64)) >>= fun w__2 : mword 64 =>
          returnm ((eq_vec w__2 pAddr)  : bool))) >>= fun w__3 : bool =>
      (if sumbool_of_bool w__3 then
         (match width with
          | W => (MEMw_conditional_wrapper pAddr 4 (subrange_vec_dec rt_val 31 0))  : M (bool)
          | D => (MEMw_conditional_wrapper pAddr 8 rt_val)  : M (bool)
          | _ => throw (Error_internal_error tt)
          end)
          : M (bool)
       else returnm false) >>= fun success : bool =>
      (wGPR rt (mips_zero_extend 64 (bool_to_bits success)))
       : M (unit)
    else
      (match width with
       | B => (MEMw_wrapper pAddr 1 (subrange_vec_dec rt_val 7 0))  : M (unit)
       | H => (MEMw_wrapper pAddr 2 (subrange_vec_dec rt_val 15 0))  : M (unit)
       | W => (MEMw_wrapper pAddr 4 (subrange_vec_dec rt_val 31 0))  : M (unit)
       | D => (MEMw_wrapper pAddr 8 rt_val)  : M (unit)
       end)
       : M (unit))
    : M (unit).

Definition execute_SYSCALL '(tt : unit) : M (unit) := (SignalException Sys)  : M (unit).

Definition execute_SYNC '(tt : unit) : M (unit) := (MEM_sync tt)  : M (unit).

Definition execute_SWR (base : mword 5) (rt : mword 5) (offset : mword 16) : M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let '(vAddr, size) :=
     addrWrapperUnaligned (add_vec (mips_sign_extend 64 offset) w__0) StoreData WR in
   (TLBTranslate vAddr StoreData) >>= fun pAddr =>
   (rGPR rt) >>= fun reg_val =>
   let l__12 := size in
   (if sumbool_of_bool (Z.eqb l__12 1) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 7 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__12 2) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 15 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__12 3) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 23 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__12 4) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 31 0))))
       : M (unit)
    else assert_exp' false "mips_insts.sail 1404:26 - 1404:27" >>= fun _ => exit tt)
    : M (unit).

Definition execute_SWL (base : mword 5) (rt : mword 5) (offset : mword 16) : M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let '(vAddr, size) :=
     addrWrapperUnaligned (add_vec (mips_sign_extend 64 offset) w__0) StoreData WL in
   (TLBTranslate vAddr StoreData) >>= fun pAddr =>
   (rGPR rt) >>= fun reg_val =>
   let l__8 := size in
   (if sumbool_of_bool (Z.eqb l__8 4) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 31 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__8 3) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 31 8))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__8 2) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 31 16))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__8 1) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 31 24))))
       : M (unit)
    else assert_exp' false "mips_insts.sail 1383:24 - 1383:25" >>= fun _ => exit tt)
    : M (unit).

Definition execute_SUBU (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun opA =>
   (rGPR rt) >>= fun opB =>
   (if orb (NotWordVal opA) (NotWordVal opB) then
      (undefined_bitvector 64) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit)
    else
      (wGPR rd
         (mips_sign_extend 64 (sub_vec (subrange_vec_dec opA 31 0) (subrange_vec_dec opB 31 0))))
       : M (unit))
    : M (unit).

Definition execute_SUB (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun opA =>
   (rGPR rt) >>= fun opB =>
   (if orb (NotWordVal opA) (NotWordVal opB) then
      (undefined_bitvector 64) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit)
    else
      let temp33 : bits 33 :=
        sub_vec (mips_sign_extend 33 (subrange_vec_dec opA 31 0))
          (mips_sign_extend 33 (subrange_vec_dec opB 31 0)) in
      (if neq_bool (bit_to_bool (access_vec_dec temp33 32)) (bit_to_bool (access_vec_dec temp33 31))
       then
         (SignalException Ov)
          : M (unit)
       else (wGPR rd (mips_sign_extend 64 (subrange_vec_dec temp33 31 0)))  : M (unit))
       : M (unit))
    : M (unit).

Definition execute_SRLV (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   (rGPR rs) >>= fun w__0 : mword 64 =>
   let sa := subrange_vec_dec w__0 4 0 in
   (if NotWordVal temp then
      (undefined_bitvector 64) >>= fun w__1 : mword 64 => (wGPR rd w__1)  : M (unit)
    else
      let rt32 := subrange_vec_dec temp 31 0 in
      (shift_bits_right rt32 sa) >>= fun w__2 : mword (31 - 0 + 1) =>
      (wGPR rd (mips_sign_extend 64 w__2))
       : M (unit))
    : M (unit).

Definition execute_SRL (rt : mword 5) (rd : mword 5) (sa : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   (if NotWordVal temp then
      (undefined_bitvector 64) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit)
    else
      let rt32 := subrange_vec_dec temp 31 0 in
      (shift_bits_right rt32 sa) >>= fun w__1 : mword (31 - 0 + 1) =>
      (wGPR rd (mips_sign_extend 64 w__1))
       : M (unit))
    : M (unit).

Definition execute_SRAV (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   (rGPR rs) >>= fun w__0 : mword 64 =>
   let sa := subrange_vec_dec w__0 4 0 in
   (if NotWordVal temp then
      (undefined_bitvector 64) >>= fun w__1 : mword 64 => (wGPR rd w__1)  : M (unit)
    else
      let rt32 := subrange_vec_dec temp 31 0 in
      (shift_bits_right_arith rt32 sa) >>= fun w__2 : mword (31 - 0 + 1) =>
      (wGPR rd (mips_sign_extend 64 w__2))
       : M (unit))
    : M (unit).

Definition execute_SRA (rt : mword 5) (rd : mword 5) (sa : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   (if NotWordVal temp then
      (undefined_bitvector 64) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit)
    else
      let rt32 := subrange_vec_dec temp 31 0 in
      (shift_bits_right_arith rt32 sa) >>= fun w__1 : mword (31 - 0 + 1) =>
      (wGPR rd (mips_sign_extend 64 w__1))
       : M (unit))
    : M (unit).

Definition execute_SLTU (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rs_val =>
   (rGPR rt) >>= fun rt_val =>
   (wGPR rd
      (mips_zero_extend 64 (if zopz0zI_u rs_val rt_val then 'b"1"  : mword 1 else 'b"0"  : mword 1)))
    : M (unit).

Definition execute_SLTIU (rs : mword 5) (rt : mword 5) (imm : mword 16) : M (unit) :=
   (rGPR rs) >>= fun rs_val =>
   let immext : bits 64 := mips_sign_extend 64 imm in
   (wGPR rt
      (mips_zero_extend 64 (if zopz0zI_u rs_val immext then 'b"1"  : mword 1 else 'b"0"  : mword 1)))
    : M (unit).

Definition execute_SLTI (rs : mword 5) (rt : mword 5) (imm : mword 16) : M (unit) :=
   let imm_val := projT1 (sint imm) in
   (rGPR rs) >>= fun w__0 : mword 64 =>
   let rs_val := projT1 (sint w__0) in
   (wGPR rt
      (mips_zero_extend 64
         (if sumbool_of_bool (Z.ltb rs_val imm_val) then 'b"1"  : mword 1
          else 'b"0"  : mword 1)))
    : M (unit).

Definition execute_SLT (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 =>
   (wGPR rd
      (mips_zero_extend 64 (if zopz0zI_s w__0 w__1 then 'b"1"  : mword 1 else 'b"0"  : mword 1)))
    : M (unit).

Definition execute_SLLV (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   let sa := subrange_vec_dec w__0 4 0 in
   (rGPR rt) >>= fun w__1 : mword 64 =>
   let rt32 := subrange_vec_dec w__1 31 0 in
   (shift_bits_left rt32 sa) >>= fun w__2 : mword (31 - 0 + 1) =>
   (wGPR rd (mips_sign_extend 64 w__2))
    : M (unit).

Definition execute_SLL (rt : mword 5) (rd : mword 5) (sa : mword 5) : M (unit) :=
   (rGPR rt) >>= fun w__0 : mword 64 =>
   let rt32 := subrange_vec_dec w__0 31 0 in
   (shift_bits_left rt32 sa) >>= fun w__1 : mword (31 - 0 + 1) =>
   (wGPR rd (mips_sign_extend 64 w__1))
    : M (unit).

Definition execute_SDR (base : mword 5) (rt : mword 5) (offset : mword 16) : M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let '(vAddr, size) :=
     addrWrapperUnaligned (add_vec (mips_sign_extend 64 offset) w__0) StoreData DR in
   (TLBTranslate vAddr StoreData) >>= fun pAddr =>
   (rGPR rt) >>= fun reg_val =>
   let l__40 := size in
   (if sumbool_of_bool (Z.eqb l__40 1) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 7 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__40 2) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 15 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__40 3) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 23 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__40 4) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 31 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__40 5) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 39 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__40 6) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 47 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__40 7) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 55 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__40 8) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 63 0))))
       : M (unit)
    else assert_exp' false "mips_insts.sail 1509:24 - 1509:25" >>= fun _ => exit tt)
    : M (unit).

Definition execute_SDL (base : mword 5) (rt : mword 5) (offset : mword 16) : M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let '(vAddr, size) :=
     addrWrapperUnaligned (add_vec (mips_sign_extend 64 offset) w__0) StoreData DL in
   (TLBTranslate vAddr StoreData) >>= fun pAddr =>
   (rGPR rt) >>= fun reg_val =>
   let l__32 := size in
   (if sumbool_of_bool (Z.eqb l__32 8) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 63 0))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__32 7) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 63 8))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__32 6) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 63 16))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__32 5) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 63 24))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__32 4) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 63 32))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__32 3) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 63 40))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__32 2) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 63 48))))
       : M (unit)
    else if sumbool_of_bool (Z.eqb l__32 1) then
      (MEMw_wrapper pAddr size (autocast (autocast (subrange_vec_dec reg_val 63 56))))
       : M (unit)
    else assert_exp' false "mips_insts.sail 1482:24 - 1482:25" >>= fun _ => exit tt)
    : M (unit).

Definition execute_RI '(tt : unit) : M (unit) := (skip tt) >> (SignalException ResI)  : M (unit).

Definition execute_RDHWR (rt : mword 5) (rd : mword 5) : M (unit) :=
   (getAccessLevel tt) >>= fun accessLevel =>
   let haveAccessLevel : bool := generic_eq accessLevel Kernel in
   read_reg CP0Status_ref >>= fun w__0 : StatusReg =>
   let haveCU0 : bool := eq_bit B1 (access_vec_dec (_get_StatusReg_CU w__0) 0) in
   let rdi := projT1 (uint rd) in
   ((read_reg CP0HWREna_ref)  : M (mword 32)) >>= fun w__1 : mword 32 =>
   let haveHWREna : bool := eq_bit B1 (access_vec_dec w__1 rdi) in
   (if sumbool_of_bool (negb (orb haveAccessLevel (orb haveCU0 haveHWREna))) then
      (SignalException ResI)
       : M (unit)
    else returnm tt) >>
   let b__102 := rd in
   (if eq_vec b__102 ('b"00000"  : mword 5) then returnm (mips_zero_extend 64 ('b"0"  : mword 1))
    else if eq_vec b__102 ('b"00001"  : mword 5) then
      returnm (mips_zero_extend 64 ('b"0"  : mword 1))
    else if eq_vec b__102 ('b"00010"  : mword 5) then
      ((read_reg CP0Count_ref)  : M (mword 32)) >>= fun w__2 : mword 32 =>
      returnm (mips_zero_extend 64 w__2)
    else if eq_vec b__102 ('b"00011"  : mword 5) then
      returnm (mips_zero_extend 64 ('b"1"  : mword 1))
    else if eq_vec b__102 ('b"11101"  : mword 5) then
      ((read_reg CP0UserLocal_ref)  : M (mword 64))
       : M (mword 64)
    else (SignalException ResI)  : M (mword 64)) >>= fun temp : bits 64 =>
   (wGPR rt temp)
    : M (unit).

Definition execute_ORI (rs : mword 5) (rt : mword 5) (imm : mword 16) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (wGPR rt (or_vec w__0 (mips_zero_extend 64 imm)))
    : M (unit).

Definition execute_OR (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 => (wGPR rd (or_vec w__0 w__1))  : M (unit).

Definition execute_NOR (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 => (wGPR rd (not_vec (or_vec w__0 w__1)))  : M (unit).

Definition execute_MULTU (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rsVal =>
   (rGPR rt) >>= fun rtVal =>
   (if orb (NotWordVal rsVal) (NotWordVal rtVal) then (undefined_bitvector 64)  : M (mword 64)
    else returnm (mult_vec (subrange_vec_dec rsVal 31 0) (subrange_vec_dec rtVal 31 0))) >>= fun result : bits 64 =>
   write_reg HI_ref (mips_sign_extend 64 (subrange_vec_dec result 63 32)) >>
   write_reg LO_ref (mips_sign_extend 64 (subrange_vec_dec result 31 0))
    : M (unit).

Definition execute_MULT (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rsVal =>
   (rGPR rt) >>= fun rtVal =>
   (if orb (NotWordVal rsVal) (NotWordVal rtVal) then (undefined_bitvector 64)  : M (mword 64)
    else returnm (mults_vec (subrange_vec_dec rsVal 31 0) (subrange_vec_dec rtVal 31 0))) >>= fun result : bits 64 =>
   write_reg HI_ref (mips_sign_extend 64 (subrange_vec_dec result 63 32)) >>
   write_reg LO_ref (mips_sign_extend 64 (subrange_vec_dec result 31 0))
    : M (unit).

Definition execute_MUL (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rsVal =>
   (rGPR rt) >>= fun rtVal =>
   let result : bits 64 :=
     mips_sign_extend 64 (mults_vec (subrange_vec_dec rsVal 31 0) (subrange_vec_dec rtVal 31 0)) in
   (if orb (NotWordVal rsVal) (NotWordVal rtVal) then (undefined_bitvector 64)  : M (mword 64)
    else returnm (mips_sign_extend 64 (subrange_vec_dec result 31 0))) >>= fun w__1 : mword 64 =>
   (wGPR rd w__1)
    : M (unit).

Definition execute_MTLO (rs : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 => write_reg LO_ref w__0  : M (unit).

Definition execute_MTHI (rs : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 => write_reg HI_ref w__0  : M (unit).

Definition execute_MTC0 (rt : mword 5) (rd : mword 5) (sel : mword 3) (double : bool) : M (unit) :=
   (checkCP0Access tt) >>
   (rGPR rt) >>= fun reg_val =>
   (match (rd, sel) with
    | (b__64, b__65) =>
       (if andb (eq_vec b__64 ('b"00000"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          write_reg TLBIndex_ref (mask 6 reg_val)
           : M (unit)
        else if andb (eq_vec b__64 ('b"00001"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          returnm tt
        else if andb (eq_vec b__64 ('b"00010"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          (_set_TLBEntryLoReg_bits TLBEntryLo0_ref reg_val)
           : M (unit)
        else if andb (eq_vec b__64 ('b"00011"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          (_set_TLBEntryLoReg_bits TLBEntryLo1_ref reg_val)
           : M (unit)
        else if andb (eq_vec b__64 ('b"00100"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          (_set_ContextReg_PTEBase TLBContext_ref (subrange_vec_dec reg_val 63 23))
           : M (unit)
        else if andb (eq_vec b__64 ('b"00100"  : mword 5)) (eq_vec b__65 ('b"010"  : mword 3)) then
          write_reg CP0UserLocal_ref reg_val
           : M (unit)
        else if andb (eq_vec b__64 ('b"00101"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          write_reg TLBPageMask_ref (subrange_vec_dec reg_val 28 13)
           : M (unit)
        else if andb (eq_vec b__64 ('b"00110"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          write_reg TLBWired_ref (mask 6 reg_val) >> write_reg TLBRandom_ref TLBIndexMax  : M (unit)
        else if andb (eq_vec b__64 ('b"00111"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          write_reg
            CP0HWREna_ref
            (concat_vec (subrange_vec_dec reg_val 31 29)
               (concat_vec ('b"0000000000000000000000000"  : mword 25)
                  (subrange_vec_dec reg_val 3 0)))
           : M (unit)
        else if andb (eq_vec b__64 ('b"01000"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          returnm tt
        else if andb (eq_vec b__64 ('b"01001"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          write_reg CP0Count_ref (subrange_vec_dec reg_val 31 0)
           : M (unit)
        else if andb (eq_vec b__64 ('b"01010"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          (_set_TLBEntryHiReg_R TLBEntryHi_ref (subrange_vec_dec reg_val 63 62)) >>
          (_set_TLBEntryHiReg_CLGK TLBEntryHi_ref
             ((cast_unit_vec (access_vec_dec reg_val 61))
              : mword 1)) >>
          (_set_TLBEntryHiReg_CLGS TLBEntryHi_ref
             ((cast_unit_vec (access_vec_dec reg_val 60))
              : mword 1)) >>
          (_set_TLBEntryHiReg_CLGU TLBEntryHi_ref
             ((cast_unit_vec (access_vec_dec reg_val 59))
              : mword 1)) >>
          (_set_TLBEntryHiReg_VPN2 TLBEntryHi_ref (subrange_vec_dec reg_val 39 13)) >>
          (_set_TLBEntryHiReg_ASID TLBEntryHi_ref (subrange_vec_dec reg_val 7 0))
           : M (unit)
        else if andb (eq_vec b__64 ('b"01011"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          write_reg CP0Compare_ref (subrange_vec_dec reg_val 31 0) >>
          read_reg CP0Cause_ref >>= fun w__0 : CauseReg =>
          (_set_CauseReg_IP CP0Cause_ref (and_vec (_get_CauseReg_IP w__0) (Ox"7F"  : mword 8)))
           : M (unit)
        else if andb (eq_vec b__64 ('b"01100"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          (_set_StatusReg_CU CP0Status_ref
             (and_vec (subrange_vec_dec reg_val 31 28)
                (concat_vec ('b"0"  : mword 1)
                   (concat_vec (bool_to_bits have_cp2) ('b"01"  : mword 2))))) >>
          (_set_StatusReg_BEV CP0Status_ref ((cast_unit_vec (access_vec_dec reg_val 22))  : mword 1)) >>
          (_set_StatusReg_IM CP0Status_ref (subrange_vec_dec reg_val 15 8)) >>
          (_set_StatusReg_KX CP0Status_ref ((cast_unit_vec (access_vec_dec reg_val 7))  : mword 1)) >>
          (_set_StatusReg_SX CP0Status_ref ((cast_unit_vec (access_vec_dec reg_val 6))  : mword 1)) >>
          (_set_StatusReg_UX CP0Status_ref ((cast_unit_vec (access_vec_dec reg_val 5))  : mword 1)) >>
          (_set_StatusReg_KSU CP0Status_ref (subrange_vec_dec reg_val 4 3)) >>
          (_set_StatusReg_ERL CP0Status_ref ((cast_unit_vec (access_vec_dec reg_val 2))  : mword 1)) >>
          (_set_StatusReg_EXL CP0Status_ref ((cast_unit_vec (access_vec_dec reg_val 1))  : mword 1)) >>
          (_set_StatusReg_IE CP0Status_ref ((cast_unit_vec (access_vec_dec reg_val 0))  : mword 1))
           : M (unit)
        else if andb (eq_vec b__64 ('b"01101"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          (_set_CauseReg_IV CP0Cause_ref ((cast_unit_vec (access_vec_dec reg_val 23))  : mword 1)) >>
          read_reg CP0Cause_ref >>= fun w__1 : CauseReg =>
          let ip := _get_CauseReg_IP w__1 in
          (_set_CauseReg_IP CP0Cause_ref
             (concat_vec (subrange_vec_dec ip 7 2) (subrange_vec_dec reg_val 9 8)))
           : M (unit)
        else if andb (eq_vec b__64 ('b"01110"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          (set_CP0EPC reg_val)
           : M (unit)
        else if andb (eq_vec b__64 ('b"10000"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          write_reg CP0ConfigK0_ref (subrange_vec_dec reg_val 2 0)
           : M (unit)
        else if andb (eq_vec b__64 ('b"10100"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          (_set_XContextReg_XPTEBase TLBXContext_ref (subrange_vec_dec reg_val 63 33))
           : M (unit)
        else if andb (eq_vec b__64 ('b"11110"  : mword 5)) (eq_vec b__65 ('b"000"  : mword 3)) then
          (set_CP0ErrorEPC reg_val)
           : M (unit)
        else (SignalException ResI)  : M (unit))
        : M (unit)
    end)
    : M (unit).

Definition execute_MSUBU (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rsVal =>
   (rGPR rt) >>= fun rtVal =>
   (if orb (NotWordVal rsVal) (NotWordVal rtVal) then (undefined_bitvector 64)  : M (mword 64)
    else returnm (mult_vec (subrange_vec_dec rsVal 31 0) (subrange_vec_dec rtVal 31 0))) >>= fun mul_result : bits 64 =>
   ((read_reg HI_ref)  : M (mword 64)) >>= fun w__1 : mword 64 =>
   ((read_reg LO_ref)  : M (mword 64)) >>= fun w__2 : mword 64 =>
   let result :=
     sub_vec (concat_vec (subrange_vec_dec w__1 31 0) (subrange_vec_dec w__2 31 0)) mul_result in
   write_reg HI_ref (mips_sign_extend 64 (subrange_vec_dec result 63 32)) >>
   write_reg LO_ref (mips_sign_extend 64 (subrange_vec_dec result 31 0))
    : M (unit).

Definition execute_MSUB (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rsVal =>
   (rGPR rt) >>= fun rtVal =>
   (if orb (NotWordVal rsVal) (NotWordVal rtVal) then (undefined_bitvector 64)  : M (mword 64)
    else returnm (mults_vec (subrange_vec_dec rsVal 31 0) (subrange_vec_dec rtVal 31 0))) >>= fun mul_result : bits 64 =>
   ((read_reg HI_ref)  : M (mword 64)) >>= fun w__1 : mword 64 =>
   ((read_reg LO_ref)  : M (mword 64)) >>= fun w__2 : mword 64 =>
   let result :=
     sub_vec (concat_vec (subrange_vec_dec w__1 31 0) (subrange_vec_dec w__2 31 0)) mul_result in
   write_reg HI_ref (mips_sign_extend 64 (subrange_vec_dec result 63 32)) >>
   write_reg LO_ref (mips_sign_extend 64 (subrange_vec_dec result 31 0))
    : M (unit).

Definition execute_MOVZ (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rt) >>= fun w__0 : mword 64 =>
   (if eq_vec w__0 (Ox"0000000000000000"  : mword 64) then
      (rGPR rs) >>= fun w__1 : mword 64 => (wGPR rd w__1)  : M (unit)
    else returnm tt)
    : M (unit).

Definition execute_MOVN (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rt) >>= fun w__0 : mword 64 =>
   (if neq_vec w__0 (Ox"0000000000000000"  : mword 64) then
      (rGPR rs) >>= fun w__1 : mword 64 => (wGPR rd w__1)  : M (unit)
    else returnm tt)
    : M (unit).

Definition execute_MFLO (rd : mword 5) : M (unit) :=
   ((read_reg LO_ref)  : M (mword 64)) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit).

Definition execute_MFHI (rd : mword 5) : M (unit) :=
   ((read_reg HI_ref)  : M (mword 64)) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit).

Definition execute_MFC0 (rt : mword 5) (rd : mword 5) (sel : mword 3) (double : bool) : M (unit) :=
   (checkCP0Access tt) >>
   (match (rd, sel) with
    | (b__0, b__1) =>
       (if andb (eq_vec b__0 ('b"00000"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg TLBIndex_ref)  : M (mword 6)) >>= fun w__0 : mword 6 =>
          let idx : bits 31 := mips_zero_extend 31 w__0 in
          ((read_reg TLBProbe_ref)  : M (mword 1)) >>= fun w__1 : mword 1 =>
          returnm (concat_vec (Ox"00000000"  : mword 32) (concat_vec w__1 idx))
        else if andb (eq_vec b__0 ('b"00001"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg TLBRandom_ref)  : M (mword 6)) >>= fun w__2 : mword 6 =>
          returnm (mips_zero_extend 64 w__2)
        else if andb (eq_vec b__0 ('b"00010"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          read_reg TLBEntryLo0_ref >>= fun w__3 : TLBEntryLoReg =>
          returnm (_get_TLBEntryLoReg_bits w__3)
        else if andb (eq_vec b__0 ('b"00011"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          read_reg TLBEntryLo1_ref >>= fun w__4 : TLBEntryLoReg =>
          returnm (_get_TLBEntryLoReg_bits w__4)
        else if andb (eq_vec b__0 ('b"00100"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          read_reg TLBContext_ref >>= fun w__5 : ContextReg => returnm (_get_ContextReg_bits w__5)
        else if andb (eq_vec b__0 ('b"00100"  : mword 5)) (eq_vec b__1 ('b"010"  : mword 3)) then
          ((read_reg CP0UserLocal_ref)  : M (mword 64))
           : M (mword 64)
        else if andb (eq_vec b__0 ('b"00101"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg TLBPageMask_ref)  : M (mword 16)) >>= fun w__7 : mword 16 =>
          returnm (mips_zero_extend 64 (concat_vec w__7 (Ox"000"  : mword 12)))
        else if andb (eq_vec b__0 ('b"00110"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg TLBWired_ref)  : M (mword 6)) >>= fun w__8 : mword 6 =>
          returnm (mips_zero_extend 64 w__8)
        else if andb (eq_vec b__0 ('b"00111"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg CP0HWREna_ref)  : M (mword 32)) >>= fun w__9 : mword 32 =>
          returnm (mips_zero_extend 64 w__9)
        else if andb (eq_vec b__0 ('b"01000"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg CP0BadVAddr_ref)  : M (mword 64))
           : M (mword 64)
        else if andb (eq_vec b__0 ('b"01000"  : mword 5)) (eq_vec b__1 ('b"001"  : mword 3)) then
          ((read_reg CP0BadInstr_ref)  : M (mword 32)) >>= fun w__11 : mword 32 =>
          returnm (mips_zero_extend 64 w__11)
        else if andb (eq_vec b__0 ('b"01000"  : mword 5)) (eq_vec b__1 ('b"010"  : mword 3)) then
          ((read_reg CP0BadInstrP_ref)  : M (mword 32)) >>= fun w__12 : mword 32 =>
          returnm (mips_zero_extend 64 w__12)
        else if andb (eq_vec b__0 ('b"01001"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg CP0Count_ref)  : M (mword 32)) >>= fun w__13 : mword 32 =>
          returnm (mips_zero_extend 64 w__13)
        else if andb (eq_vec b__0 ('b"01010"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          read_reg TLBEntryHi_ref >>= fun w__14 : TLBEntryHiReg =>
          returnm (_get_TLBEntryHiReg_bits w__14)
        else if andb (eq_vec b__0 ('b"01011"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg CP0Compare_ref)  : M (mword 32)) >>= fun w__15 : mword 32 =>
          returnm (mips_zero_extend 64 w__15)
        else if andb (eq_vec b__0 ('b"01100"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          read_reg CP0Status_ref >>= fun w__16 : StatusReg =>
          returnm (mips_zero_extend 64 (_get_StatusReg_bits w__16))
        else if andb (eq_vec b__0 ('b"01101"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          read_reg CP0Cause_ref >>= fun w__17 : CauseReg =>
          returnm (mips_zero_extend 64 (_get_CauseReg_bits w__17))
        else if andb (eq_vec b__0 ('b"01110"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          (get_CP0EPC tt)
           : M (mword 64)
        else if andb (eq_vec b__0 ('b"01111"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          returnm (mips_zero_extend 64 (Ox"00000405"  : mword 32))
        else if andb (eq_vec b__0 ('b"01111"  : mword 5)) (eq_vec b__1 ('b"110"  : mword 3)) then
          returnm (mips_zero_extend 64 ('b"0"  : mword 1))
        else if andb (eq_vec b__0 ('b"01111"  : mword 5)) (eq_vec b__1 ('b"111"  : mword 3)) then
          returnm (mips_zero_extend 64 ('b"0"  : mword 1))
        else if andb (eq_vec b__0 ('b"10000"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg CP0ConfigK0_ref)  : M (mword 3)) >>= fun w__19 : mword 3 =>
          returnm (mips_zero_extend 64
                     (concat_vec ('b"1"  : mword 1)
                        (concat_vec ('b"000000000000000"  : mword 15)
                           (concat_vec ('b"1"  : mword 1)
                              (concat_vec ('b"10"  : mword 2)
                                 (concat_vec ('b"000"  : mword 3)
                                    (concat_vec ('b"001"  : mword 3)
                                       (concat_vec (Ox"0"  : mword 4) w__19))))))))
        else if andb (eq_vec b__0 ('b"10000"  : mword 5)) (eq_vec b__1 ('b"001"  : mword 3)) then
          returnm (mips_zero_extend 64
                     (concat_vec ('b"1"  : mword 1)
                        (concat_vec TLBIndexMax
                           (concat_vec ('b"000"  : mword 3)
                              (concat_vec ('b"000"  : mword 3)
                                 (concat_vec ('b"000"  : mword 3)
                                    (concat_vec ('b"000"  : mword 3)
                                       (concat_vec ('b"000"  : mword 3)
                                          (concat_vec ('b"000"  : mword 3)
                                             (concat_vec (bool_to_bits have_cp2)
                                                (concat_vec ('b"0"  : mword 1)
                                                   (concat_vec ('b"0"  : mword 1)
                                                      (concat_vec ('b"0"  : mword 1)
                                                         (concat_vec ('b"0"  : mword 1)
                                                            (concat_vec ('b"0"  : mword 1)
                                                               ('b"0"
                                                                : mword 1))))))))))))))))
        else if andb (eq_vec b__0 ('b"10000"  : mword 5)) (eq_vec b__1 ('b"010"  : mword 3)) then
          returnm (mips_zero_extend 64
                     (concat_vec ('b"1"  : mword 1)
                        (concat_vec ('b"000"  : mword 3)
                           (concat_vec (Ox"0"  : mword 4)
                              (concat_vec (Ox"0"  : mword 4)
                                 (concat_vec (Ox"0"  : mword 4)
                                    (concat_vec (Ox"0"  : mword 4)
                                       (concat_vec (Ox"0"  : mword 4)
                                          (concat_vec (Ox"0"  : mword 4) (Ox"0"  : mword 4))))))))))
        else if andb (eq_vec b__0 ('b"10000"  : mword 5)) (eq_vec b__1 ('b"011"  : mword 3)) then
          returnm (Ox"000000000C002000"  : mword 64)
        else if andb (eq_vec b__0 ('b"10000"  : mword 5)) (eq_vec b__1 ('b"101"  : mword 3)) then
          returnm (Ox"0000000000000000"  : mword 64)
        else if andb (eq_vec b__0 ('b"10000"  : mword 5)) (eq_vec b__1 ('b"110"  : mword 3)) then
          returnm (Ox"0000000000000000"  : mword 64)
        else if andb (eq_vec b__0 ('b"10001"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          ((read_reg CP0LLAddr_ref)  : M (mword 64))
           : M (mword 64)
        else if andb (eq_vec b__0 ('b"10010"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          returnm (mips_zero_extend 64 ('b"0"  : mword 1))
        else if andb (eq_vec b__0 ('b"10011"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          returnm (mips_zero_extend 64 ('b"0"  : mword 1))
        else if andb (eq_vec b__0 ('b"10100"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          read_reg TLBXContext_ref >>= fun w__21 : XContextReg =>
          returnm (_get_XContextReg_bits w__21)
        else if andb (eq_vec b__0 ('b"11110"  : mword 5)) (eq_vec b__1 ('b"000"  : mword 3)) then
          (get_CP0ErrorEPC tt)
           : M (mword 64)
        else (SignalException ResI)  : M (mword 64))
        : M (mword 64)
    end) >>= fun result : bits 64 =>
   (wGPR rt
      (if sumbool_of_bool double then result
       else mips_sign_extend 64 (subrange_vec_dec result 31 0)))
    : M (unit).

Definition execute_MADDU (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rsVal =>
   (rGPR rt) >>= fun rtVal =>
   (if orb (NotWordVal rsVal) (NotWordVal rtVal) then (undefined_bitvector 64)  : M (mword 64)
    else returnm (mult_vec (subrange_vec_dec rsVal 31 0) (subrange_vec_dec rtVal 31 0))) >>= fun mul_result : bits 64 =>
   ((read_reg HI_ref)  : M (mword 64)) >>= fun w__1 : mword 64 =>
   ((read_reg LO_ref)  : M (mword 64)) >>= fun w__2 : mword 64 =>
   let result :=
     add_vec mul_result (concat_vec (subrange_vec_dec w__1 31 0) (subrange_vec_dec w__2 31 0)) in
   write_reg HI_ref (mips_sign_extend 64 (subrange_vec_dec result 63 32)) >>
   write_reg LO_ref (mips_sign_extend 64 (subrange_vec_dec result 31 0))
    : M (unit).

Definition execute_MADD (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rsVal =>
   (rGPR rt) >>= fun rtVal =>
   (if orb (NotWordVal rsVal) (NotWordVal rtVal) then (undefined_bitvector 64)  : M (mword 64)
    else returnm (mults_vec (subrange_vec_dec rsVal 31 0) (subrange_vec_dec rtVal 31 0))) >>= fun mul_result : bits 64 =>
   ((read_reg HI_ref)  : M (mword 64)) >>= fun w__1 : mword 64 =>
   ((read_reg LO_ref)  : M (mword 64)) >>= fun w__2 : mword 64 =>
   let result :=
     add_vec mul_result (concat_vec (subrange_vec_dec w__1 31 0) (subrange_vec_dec w__2 31 0)) in
   write_reg HI_ref (mips_sign_extend 64 (subrange_vec_dec result 63 32)) >>
   write_reg LO_ref (mips_sign_extend 64 (subrange_vec_dec result 31 0))
    : M (unit).

Definition execute_Load
(width : WordType) (sign : bool) (linked : bool) (base : mword 5) (rt : mword 5) (offset : mword 16)
: M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let vAddr : bits 64 := addrWrapper (add_vec (mips_sign_extend 64 offset) w__0) LoadData width in
   (if negb (isAddressAligned vAddr width) then (SignalExceptionBadAddr AdEL vAddr)  : M (unit)
    else
      (TLBTranslate vAddr LoadData) >>= fun pAddr =>
      (if sumbool_of_bool linked then
         write_reg CP0LLBit_ref ('b"1"  : mword 1) >>
         write_reg CP0LLAddr_ref pAddr >>
         (match width with
          | W =>
             (MEMr_reserve_wrapper pAddr 4) >>= fun w__1 : mword (8 * 4) =>
             returnm (extendLoad w__1 sign)
          | D =>
             (MEMr_reserve_wrapper pAddr 8) >>= fun w__2 : mword (8 * 8) =>
             returnm (extendLoad w__2 sign)
          | _ => throw (Error_internal_error tt)
          end)
          : M (mword 64)
       else
         (match width with
          | B =>
             (MEMr_wrapper pAddr 1) >>= fun w__5 : mword (8 * 1) => returnm (extendLoad w__5 sign)
          | H =>
             (MEMr_wrapper pAddr 2) >>= fun w__6 : mword (8 * 2) => returnm (extendLoad w__6 sign)
          | W =>
             (MEMr_wrapper pAddr 4) >>= fun w__7 : mword (8 * 4) => returnm (extendLoad w__7 sign)
          | D =>
             (MEMr_wrapper pAddr 8) >>= fun w__8 : mword (8 * 8) => returnm (extendLoad w__8 sign)
          end)
          : M (mword 64)) >>= fun memResult : bits 64 =>
      (wGPR rt memResult)
       : M (unit))
    : M (unit).

Definition execute_LWR (base : mword 5) (rt : mword 5) (offset : mword 16) : M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let '(vAddr, size) :=
     addrWrapperUnaligned (add_vec (mips_sign_extend 64 offset) w__0) LoadData WR in
   (TLBTranslate vAddr LoadData) >>= fun pAddr =>
   (rGPR rt) >>= fun reg_val =>
   let l__4 := size in
   (if sumbool_of_bool (Z.eqb l__4 1) then
      (MEMr_wrapper pAddr size) >>= fun w__1 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 31 8) w__1)))
    else if sumbool_of_bool (Z.eqb l__4 2) then
      (MEMr_wrapper pAddr size) >>= fun w__2 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 31 16) w__2)))
    else if sumbool_of_bool (Z.eqb l__4 3) then
      (MEMr_wrapper pAddr size) >>= fun w__3 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 31 24) w__3)))
    else if sumbool_of_bool (Z.eqb l__4 4) then (MEMr_wrapper pAddr _)  : M (mword (8 * 4))
    else assert_exp' false "mips_insts.sail 1360:21 - 1360:22" >>= fun _ => exit tt) >>= fun result : bits 32 =>
   (wGPR rt (mips_sign_extend 64 result))
    : M (unit).

Definition execute_LWL (base : mword 5) (rt : mword 5) (offset : mword 16) : M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let '(vAddr, size) :=
     addrWrapperUnaligned (add_vec (mips_sign_extend 64 offset) w__0) LoadData WL in
   (TLBTranslate vAddr LoadData) >>= fun pAddr =>
   (rGPR rt) >>= fun reg_val =>
   let l__0 := size in
   (if sumbool_of_bool (Z.eqb l__0 4) then (MEMr_wrapper pAddr _)  : M (mword (8 * 4))
    else if sumbool_of_bool (Z.eqb l__0 3) then
      (MEMr_wrapper pAddr size) >>= fun w__2 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__2 (subrange_vec_dec reg_val 7 0))))
    else if sumbool_of_bool (Z.eqb l__0 2) then
      (MEMr_wrapper pAddr size) >>= fun w__3 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__3 (subrange_vec_dec reg_val 15 0))))
    else if sumbool_of_bool (Z.eqb l__0 1) then
      (MEMr_wrapper pAddr size) >>= fun w__4 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__4 (subrange_vec_dec reg_val 23 0))))
    else assert_exp' false "mips_insts.sail 1339:21 - 1339:22" >>= fun _ => exit tt) >>= fun result : bits 32 =>
   (wGPR rt (mips_sign_extend 64 result))
    : M (unit).

Definition execute_LUI (rt : mword 5) (imm : mword 16) : M (unit) :=
   (wGPR rt (mips_sign_extend 64 (concat_vec imm (Ox"0000"  : mword 16))))  : M (unit).

Definition execute_LDR (base : mword 5) (rt : mword 5) (offset : mword 16) : M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let '(vAddr, size) :=
     addrWrapperUnaligned (add_vec (mips_sign_extend 64 offset) w__0) LoadData DR in
   (TLBTranslate vAddr LoadData) >>= fun pAddr =>
   (rGPR rt) >>= fun reg_val =>
   let l__24 := size in
   (if sumbool_of_bool (Z.eqb l__24 1) then
      (MEMr_wrapper pAddr size) >>= fun w__1 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 63 8) w__1)))
    else if sumbool_of_bool (Z.eqb l__24 2) then
      (MEMr_wrapper pAddr size) >>= fun w__2 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 63 16) w__2)))
    else if sumbool_of_bool (Z.eqb l__24 3) then
      (MEMr_wrapper pAddr size) >>= fun w__3 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 63 24) w__3)))
    else if sumbool_of_bool (Z.eqb l__24 4) then
      (MEMr_wrapper pAddr size) >>= fun w__4 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 63 32) w__4)))
    else if sumbool_of_bool (Z.eqb l__24 5) then
      (MEMr_wrapper pAddr size) >>= fun w__5 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 63 40) w__5)))
    else if sumbool_of_bool (Z.eqb l__24 6) then
      (MEMr_wrapper pAddr size) >>= fun w__6 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 63 48) w__6)))
    else if sumbool_of_bool (Z.eqb l__24 7) then
      (MEMr_wrapper pAddr size) >>= fun w__7 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec (subrange_vec_dec reg_val 63 56) w__7)))
    else if sumbool_of_bool (Z.eqb l__24 8) then (MEMr_wrapper pAddr _)  : M (mword (8 * 8))
    else assert_exp' false "mips_insts.sail 1456:21 - 1456:22" >>= fun _ => exit tt) >>= fun w__16 : mword 64 =>
   (wGPR rt w__16)
    : M (unit).

Definition execute_LDL (base : mword 5) (rt : mword 5) (offset : mword 16) : M (unit) :=
   (rGPR base) >>= fun w__0 : mword 64 =>
   let '(vAddr, size) :=
     addrWrapperUnaligned (add_vec (mips_sign_extend 64 offset) w__0) LoadData DL in
   (TLBTranslate vAddr LoadData) >>= fun pAddr =>
   (rGPR rt) >>= fun reg_val =>
   let l__16 := size in
   (if sumbool_of_bool (Z.eqb l__16 8) then (MEMr_wrapper pAddr _)  : M (mword (8 * 8))
    else if sumbool_of_bool (Z.eqb l__16 7) then
      (MEMr_wrapper pAddr size) >>= fun w__2 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__2 (subrange_vec_dec reg_val 7 0))))
    else if sumbool_of_bool (Z.eqb l__16 6) then
      (MEMr_wrapper pAddr size) >>= fun w__3 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__3 (subrange_vec_dec reg_val 15 0))))
    else if sumbool_of_bool (Z.eqb l__16 5) then
      (MEMr_wrapper pAddr size) >>= fun w__4 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__4 (subrange_vec_dec reg_val 23 0))))
    else if sumbool_of_bool (Z.eqb l__16 4) then
      (MEMr_wrapper pAddr size) >>= fun w__5 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__5 (subrange_vec_dec reg_val 31 0))))
    else if sumbool_of_bool (Z.eqb l__16 3) then
      (MEMr_wrapper pAddr size) >>= fun w__6 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__6 (subrange_vec_dec reg_val 39 0))))
    else if sumbool_of_bool (Z.eqb l__16 2) then
      (MEMr_wrapper pAddr size) >>= fun w__7 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__7 (subrange_vec_dec reg_val 47 0))))
    else if sumbool_of_bool (Z.eqb l__16 1) then
      (MEMr_wrapper pAddr size) >>= fun w__8 : mword (8 * size) =>
      returnm (autocast (autocast (concat_vec w__8 (subrange_vec_dec reg_val 55 0))))
    else assert_exp' false "mips_insts.sail 1430:21 - 1430:22" >>= fun _ => exit tt) >>= fun w__16 : mword 64 =>
   (wGPR rt w__16)
    : M (unit).

Definition execute_JR (rs : mword 5) : M (unit) :=
   ((read_reg InBranchDelay_ref)  : M (mword 1)) >>= fun w__0 : mword 1 =>
   (if (bits_to_bool w__0)  : bool then (SignalException ResI)  : M (unit)
    else returnm tt) >>
   (rGPR rs) >>= fun w__1 : mword 64 => (execute_branch w__1)  : M (unit).

Definition execute_JALR (rs : mword 5) (rd : mword 5) : M (unit) :=
   ((read_reg InBranchDelay_ref)  : M (mword 1)) >>= fun w__0 : mword 1 =>
   (if (bits_to_bool w__0)  : bool then (SignalException ResI)  : M (unit)
    else returnm tt) >>
   (rGPR rs) >>= fun w__1 : mword 64 =>
   (execute_branch w__1) >>
   ((read_reg PC_ref)  : M (mword 64)) >>= fun w__2 : mword 64 =>
   (wGPR rd (add_vec_int w__2 8))
    : M (unit).

Definition execute_JAL (offset : mword 26) : M (unit) :=
   ((read_reg InBranchDelay_ref)  : M (mword 1)) >>= fun w__0 : mword 1 =>
   (if (bits_to_bool w__0)  : bool then (SignalException ResI)  : M (unit)
    else returnm tt) >>
   ((read_reg PC_ref)  : M (mword 64)) >>= fun w__1 : mword 64 =>
   (execute_branch
      (concat_vec (subrange_vec_dec (add_vec_int w__1 4) 63 28)
         (concat_vec offset ('b"00"  : mword 2)))) >>
   ((read_reg PC_ref)  : M (mword 64)) >>= fun w__2 : mword 64 =>
   (wGPR ('b"11111"  : mword 5) (add_vec_int w__2 8))
    : M (unit).

Definition execute_J (offset : mword 26) : M (unit) :=
   ((read_reg InBranchDelay_ref)  : M (mword 1)) >>= fun w__0 : mword 1 =>
   (if (bits_to_bool w__0)  : bool then (SignalException ResI)  : M (unit)
    else returnm tt) >>
   ((read_reg PC_ref)  : M (mword 64)) >>= fun w__1 : mword 64 =>
   (execute_branch
      (concat_vec (subrange_vec_dec (add_vec_int w__1 4) 63 28)
         (concat_vec offset ('b"00"  : mword 2))))
    : M (unit).

Definition execute_HCF '(tt : unit) : unit := tt.

Definition execute_ERET '(tt : unit) : M (unit) :=
   (checkCP0Access tt) >>
   let '_ := (ERETHook tt)  : unit in
   write_reg CP0LLBit_ref ('b"0"  : mword 1) >>
   read_reg CP0Status_ref >>= fun w__0 : StatusReg =>
   (if Bool.eqb (bits_to_bool (_get_StatusReg_ERL w__0)) (bit_to_bool B1) then
      (get_CP0ErrorEPC tt) >>= fun w__1 : mword 64 =>
      write_reg NextPC_ref w__1 >> (_set_StatusReg_ERL CP0Status_ref ('b"0"  : mword 1))  : M (unit)
    else
      (get_CP0EPC tt) >>= fun w__2 : mword 64 =>
      write_reg NextPC_ref w__2 >> (_set_StatusReg_EXL CP0Status_ref ('b"0"  : mword 1))  : M (unit))
    : M (unit).

Definition execute_DSUBU (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 => (wGPR rd (sub_vec w__0 w__1))  : M (unit).

Definition execute_DSUB (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 =>
   let temp65 : bits 65 := sub_vec (mips_sign_extend 65 w__0) (mips_sign_extend 65 w__1) in
   (if neq_bool (bit_to_bool (access_vec_dec temp65 64)) (bit_to_bool (access_vec_dec temp65 63))
    then
      (SignalException Ov)
       : M (unit)
    else (wGPR rd (subrange_vec_dec temp65 63 0))  : M (unit))
    : M (unit).

Definition execute_DSRLV (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   (rGPR rs) >>= fun w__0 : mword 64 =>
   let sa := subrange_vec_dec w__0 5 0 in
   (shift_bits_right temp sa) >>= fun w__1 : mword 64 => (wGPR rd w__1)  : M (unit).

Definition execute_DSRL32 (rt : mword 5) (rd : mword 5) (sa : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   let sa32 := concat_vec ('b"1"  : mword 1) sa in
   (shift_bits_right temp sa32) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit).

Definition execute_DSRL (rt : mword 5) (rd : mword 5) (sa : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   (shift_bits_right temp sa) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit).

Definition execute_DSRAV (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   (rGPR rs) >>= fun w__0 : mword 64 =>
   let sa := subrange_vec_dec w__0 5 0 in
   (shift_bits_right_arith temp sa) >>= fun w__1 : mword 64 => (wGPR rd w__1)  : M (unit).

Definition execute_DSRA32 (rt : mword 5) (rd : mword 5) (sa : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   let sa32 := concat_vec ('b"1"  : mword 1) sa in
   (shift_bits_right_arith temp sa32) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit).

Definition execute_DSRA (rt : mword 5) (rd : mword 5) (sa : mword 5) : M (unit) :=
   (rGPR rt) >>= fun temp =>
   (shift_bits_right_arith temp sa) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit).

Definition execute_DSLLV (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rt) >>= fun w__0 : mword 64 =>
   (rGPR rs) >>= fun w__1 : mword 64 =>
   (shift_bits_left w__0 (subrange_vec_dec w__1 5 0)) >>= fun w__2 : mword 64 =>
   (wGPR rd w__2)
    : M (unit).

Definition execute_DSLL32 (rt : mword 5) (rd : mword 5) (sa : mword 5) : M (unit) :=
   (rGPR rt) >>= fun w__0 : mword 64 =>
   (shift_bits_left w__0 (concat_vec ('b"1"  : mword 1) sa)) >>= fun w__1 : mword 64 =>
   (wGPR rd w__1)
    : M (unit).

Definition execute_DSLL (rt : mword 5) (rd : mword 5) (sa : mword 5) : M (unit) :=
   (rGPR rt) >>= fun w__0 : mword 64 =>
   (shift_bits_left w__0 sa) >>= fun w__1 : mword 64 => (wGPR rd w__1)  : M (unit).

Definition execute_DMULTU (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 =>
   let result := mult_vec w__0 w__1 in
   write_reg HI_ref (subrange_vec_dec result 127 64) >>
   write_reg LO_ref (subrange_vec_dec result 63 0)
    : M (unit).

Definition execute_DMULT (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 =>
   let result := mults_vec w__0 w__1 in
   write_reg HI_ref (subrange_vec_dec result 127 64) >>
   write_reg LO_ref (subrange_vec_dec result 63 0)
    : M (unit).

Definition execute_DIVU (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rsVal =>
   (rGPR rt) >>= fun rtVal =>
   (if orb (NotWordVal rsVal)
         (orb (NotWordVal rtVal) (eq_vec rtVal (Ox"0000000000000000"  : mword 64))) then
      (undefined_bitvector 32) >>= fun w__0 : mword 32 =>
      (undefined_bitvector 32) >>= fun w__1 : mword 32 => returnm (w__0  : bits 32, w__1  : bits 32)
    else
      let si := projT1 (uint (subrange_vec_dec rsVal 31 0)) in
      let ti := projT1 (uint (subrange_vec_dec rtVal 31 0)) in
      let qi := Z.quot si ti in
      let ri := Z.rem si ti in
      returnm (to_bits 32 qi, to_bits 32 ri)) >>= fun '(q, r) =>
   write_reg HI_ref (mips_sign_extend 64 r) >> write_reg LO_ref (mips_sign_extend 64 q)  : M (unit).

Definition execute_DIV (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun rsVal =>
   (rGPR rt) >>= fun rtVal =>
   (if orb (NotWordVal rsVal)
         (orb (NotWordVal rtVal) (eq_vec rtVal (Ox"0000000000000000"  : mword 64))) then
      (undefined_bitvector 32) >>= fun w__0 : mword 32 =>
      (undefined_bitvector 32) >>= fun w__1 : mword 32 => returnm (w__0  : bits 32, w__1  : bits 32)
    else
      let si := projT1 (sint (subrange_vec_dec rsVal 31 0)) in
      let ti := projT1 (sint (subrange_vec_dec rtVal 31 0)) in
      let qi := Z.quot si ti in
      let ri := Z.sub si (Z.mul ti qi) in
      returnm (to_bits 32 qi, to_bits 32 ri)) >>= fun '(q, r) =>
   write_reg HI_ref (mips_sign_extend 64 r) >> write_reg LO_ref (mips_sign_extend 64 q)  : M (unit).

Definition execute_DDIVU (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   let rsVal := projT1 (uint w__0) in
   (rGPR rt) >>= fun w__1 : mword 64 =>
   let rtVal := projT1 (uint w__1) in
   (if sumbool_of_bool (Z.eqb rtVal 0) then
      (undefined_bitvector 64) >>= fun w__2 : mword 64 =>
      (undefined_bitvector 64) >>= fun w__3 : mword 64 => returnm (w__2  : bits 64, w__3  : bits 64)
    else
      let qi := Z.quot rsVal rtVal in
      let ri := Z.rem rsVal rtVal in
      returnm (to_bits 64 qi, to_bits 64 ri)) >>= fun '(q, r) =>
   write_reg LO_ref q >> write_reg HI_ref r  : M (unit).

Definition execute_DDIV (rs : mword 5) (rt : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   let rsVal := projT1 (sint w__0) in
   (rGPR rt) >>= fun w__1 : mword 64 =>
   let rtVal := projT1 (sint w__1) in
   (if sumbool_of_bool (Z.eqb rtVal 0) then
      (undefined_bitvector 64) >>= fun w__2 : mword 64 =>
      (undefined_bitvector 64) >>= fun w__3 : mword 64 => returnm (w__2  : bits 64, w__3  : bits 64)
    else
      let qi := Z.quot rsVal rtVal in
      let ri := Z.sub rsVal (Z.mul qi rtVal) in
      returnm (to_bits 64 qi, to_bits 64 ri)) >>= fun '(q, r) =>
   write_reg LO_ref q >> write_reg HI_ref r  : M (unit).

Definition execute_DADDU (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 => (wGPR rd (add_vec w__0 w__1))  : M (unit).

Definition execute_DADDIU (rs : mword 5) (rt : mword 5) (imm : mword 16) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (wGPR rt (add_vec w__0 (mips_sign_extend 64 imm)))
    : M (unit).

Definition execute_DADDI (rs : mword 5) (rt : mword 5) (imm : mword 16) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   let sum65 : bits 65 := add_vec (mips_sign_extend 65 w__0) (mips_sign_extend 65 imm) in
   (if neq_bool (bit_to_bool (access_vec_dec sum65 64)) (bit_to_bool (access_vec_dec sum65 63)) then
      (SignalException Ov)
       : M (unit)
    else (wGPR rt (subrange_vec_dec sum65 63 0))  : M (unit))
    : M (unit).

Definition execute_DADD (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 =>
   let sum65 : bits 65 := add_vec (mips_sign_extend 65 w__0) (mips_sign_extend 65 w__1) in
   (if neq_bool (bit_to_bool (access_vec_dec sum65 64)) (bit_to_bool (access_vec_dec sum65 63)) then
      (SignalException Ov)
       : M (unit)
    else (wGPR rd (subrange_vec_dec sum65 63 0))  : M (unit))
    : M (unit).

Definition execute_CACHE (base : mword 5) (op : mword 5) (imm : mword 16) : M (unit) :=
   (checkCP0Access tt)  : M (unit).

Definition execute_BREAK '(tt : unit) : M (unit) := (SignalException Bp)  : M (unit).

Definition execute_BEQ (rs : mword 5) (rd : mword 5) (imm : mword 16) (ne : bool) (likely : bool)
: M (unit) :=
   ((read_reg InBranchDelay_ref)  : M (mword 1)) >>= fun w__0 : mword 1 =>
   (if (bits_to_bool w__0)  : bool then (SignalException ResI)  : M (unit)
    else returnm tt) >>
   (rGPR rs) >>= fun w__1 : mword 64 =>
   (rGPR rd) >>= fun w__2 : mword 64 =>
   (if (bits_to_bool (xor_vec (bool_to_bits (eq_vec w__1 w__2)) ((bool_to_bits ne)  : mword 1)))
       : bool then
      let offset : bits 64 :=
        add_vec_int (mips_sign_extend 64 (concat_vec imm ('b"00"  : mword 2))) 4 in
      ((read_reg PC_ref)  : M (mword 64)) >>= fun w__3 : mword 64 =>
      (execute_branch (add_vec w__3 offset))
       : M (unit)
    else if sumbool_of_bool likely then
      ((read_reg PC_ref)  : M (mword 64)) >>= fun w__4 : mword 64 =>
      write_reg NextPC_ref (add_vec_int w__4 8)
       : M (unit)
    else write_reg NextInBranchDelay_ref ('b"1"  : mword 1)  : M (unit))
    : M (unit).

Definition execute_BCMPZ
(rs : mword 5) (imm : mword 16) (cmp : Comparison) (link : bool) (likely : bool)
: M (unit) :=
   ((read_reg InBranchDelay_ref)  : M (mword 1)) >>= fun w__0 : mword 1 =>
   (if (bits_to_bool w__0)  : bool then (SignalException ResI)  : M (unit)
    else returnm tt) >>
   ((read_reg PC_ref)  : M (mword 64)) >>= fun w__1 : mword 64 =>
   let linkVal := add_vec_int w__1 8 in
   (rGPR rs) >>= fun regVal =>
   let condition := compare cmp regVal (mips_zero_extend 64 ('b"0"  : mword 1)) in
   (if sumbool_of_bool condition then
      let offset : bits 64 :=
        add_vec_int (mips_sign_extend 64 (concat_vec imm ('b"00"  : mword 2))) 4 in
      ((read_reg PC_ref)  : M (mword 64)) >>= fun w__2 : mword 64 =>
      (execute_branch (add_vec w__2 offset))
       : M (unit)
    else if sumbool_of_bool likely then
      ((read_reg PC_ref)  : M (mword 64)) >>= fun w__3 : mword 64 =>
      write_reg NextPC_ref (add_vec_int w__3 8)
       : M (unit)
    else write_reg NextInBranchDelay_ref ('b"1"  : mword 1)  : M (unit)) >>
   (if sumbool_of_bool link then (wGPR ('b"11111"  : mword 5) linkVal)  : M (unit)
    else returnm tt)
    : M (unit).

Definition execute_ANDI (rs : mword 5) (rt : mword 5) (imm : mword 16) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (wGPR rt (and_vec w__0 (mips_zero_extend 64 imm)))
    : M (unit).

Definition execute_AND (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun w__0 : mword 64 =>
   (rGPR rt) >>= fun w__1 : mword 64 => (wGPR rd (and_vec w__0 w__1))  : M (unit).

Definition execute_ADDU (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun opA =>
   (rGPR rt) >>= fun opB =>
   (if orb (NotWordVal opA) (NotWordVal opB) then
      (undefined_bitvector 64) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit)
    else
      (wGPR rd
         (mips_sign_extend 64 (add_vec (subrange_vec_dec opA 31 0) (subrange_vec_dec opB 31 0))))
       : M (unit))
    : M (unit).

Definition execute_ADDIU (rs : mword 5) (rt : mword 5) (imm : mword 16) : M (unit) :=
   (rGPR rs) >>= fun opA =>
   (if NotWordVal opA then
      (undefined_bitvector 64) >>= fun w__0 : mword 64 => (wGPR rt w__0)  : M (unit)
    else
      (wGPR rt
         (mips_sign_extend 64
            (add_vec (subrange_vec_dec opA 31 0) (mips_sign_extend (Z.add (Z.sub 31 0) 1) imm))))
       : M (unit))
    : M (unit).

Definition execute_ADDI (rs : mword 5) (rt : mword 5) (imm : mword 16) : M (unit) :=
   (rGPR rs) >>= fun opA =>
   (if NotWordVal opA then
      (undefined_bitvector 64) >>= fun w__0 : mword 64 => (wGPR rt w__0)  : M (unit)
    else
      let sum33 : bits 33 :=
        add_vec (mips_sign_extend 33 (subrange_vec_dec opA 31 0)) (mips_sign_extend 33 imm) in
      (if neq_bool (bit_to_bool (access_vec_dec sum33 32)) (bit_to_bool (access_vec_dec sum33 31))
       then
         (SignalException Ov)
          : M (unit)
       else (wGPR rt (mips_sign_extend 64 (subrange_vec_dec sum33 31 0)))  : M (unit))
       : M (unit))
    : M (unit).

Definition execute_ADD (rs : mword 5) (rt : mword 5) (rd : mword 5) : M (unit) :=
   (rGPR rs) >>= fun opA : bits 64 =>
   (rGPR rt) >>= fun opB : bits 64 =>
   (if orb (NotWordVal opA) (NotWordVal opB) then
      (undefined_bitvector 64) >>= fun w__0 : mword 64 => (wGPR rd w__0)  : M (unit)
    else
      let sum33 : bits 33 :=
        add_vec (mips_sign_extend 33 (subrange_vec_dec opA 31 0))
          (mips_sign_extend 33 (subrange_vec_dec opB 31 0)) in
      (if neq_bool (bit_to_bool (access_vec_dec sum33 32)) (bit_to_bool (access_vec_dec sum33 31))
       then
         (SignalException Ov)
          : M (unit)
       else (wGPR rd (mips_sign_extend 64 (subrange_vec_dec sum33 31 0)))  : M (unit))
       : M (unit))
    : M (unit).

Definition execute (merge_var : ast) : M (unit) :=
   (match merge_var with
    | DADDIU (rs, rt, imm) => (execute_DADDIU rs rt imm)  : M (unit)
    | DADDU (rs, rt, rd) => (execute_DADDU rs rt rd)  : M (unit)
    | DADDI (rs, rt, imm) => (execute_DADDI rs rt imm)  : M (unit)
    | DADD (rs, rt, rd) => (execute_DADD rs rt rd)  : M (unit)
    | ADD (rs, rt, rd) => (execute_ADD rs rt rd)  : M (unit)
    | ADDI (rs, rt, imm) => (execute_ADDI rs rt imm)  : M (unit)
    | ADDU (rs, rt, rd) => (execute_ADDU rs rt rd)  : M (unit)
    | ADDIU (rs, rt, imm) => (execute_ADDIU rs rt imm)  : M (unit)
    | DSUBU (rs, rt, rd) => (execute_DSUBU rs rt rd)  : M (unit)
    | DSUB (rs, rt, rd) => (execute_DSUB rs rt rd)  : M (unit)
    | SUB (rs, rt, rd) => (execute_SUB rs rt rd)  : M (unit)
    | SUBU (rs, rt, rd) => (execute_SUBU rs rt rd)  : M (unit)
    | AND (rs, rt, rd) => (execute_AND rs rt rd)  : M (unit)
    | ANDI (rs, rt, imm) => (execute_ANDI rs rt imm)  : M (unit)
    | OR (rs, rt, rd) => (execute_OR rs rt rd)  : M (unit)
    | ORI (rs, rt, imm) => (execute_ORI rs rt imm)  : M (unit)
    | NOR (rs, rt, rd) => (execute_NOR rs rt rd)  : M (unit)
    | XOR (rs, rt, rd) => (execute_XOR rs rt rd)  : M (unit)
    | XORI (rs, rt, imm) => (execute_XORI rs rt imm)  : M (unit)
    | LUI (rt, imm) => (execute_LUI rt imm)  : M (unit)
    | DSLL (rt, rd, sa) => (execute_DSLL rt rd sa)  : M (unit)
    | DSLL32 (rt, rd, sa) => (execute_DSLL32 rt rd sa)  : M (unit)
    | DSLLV (rs, rt, rd) => (execute_DSLLV rs rt rd)  : M (unit)
    | DSRA (rt, rd, sa) => (execute_DSRA rt rd sa)  : M (unit)
    | DSRA32 (rt, rd, sa) => (execute_DSRA32 rt rd sa)  : M (unit)
    | DSRAV (rs, rt, rd) => (execute_DSRAV rs rt rd)  : M (unit)
    | DSRL (rt, rd, sa) => (execute_DSRL rt rd sa)  : M (unit)
    | DSRL32 (rt, rd, sa) => (execute_DSRL32 rt rd sa)  : M (unit)
    | DSRLV (rs, rt, rd) => (execute_DSRLV rs rt rd)  : M (unit)
    | SLL (rt, rd, sa) => (execute_SLL rt rd sa)  : M (unit)
    | SLLV (rs, rt, rd) => (execute_SLLV rs rt rd)  : M (unit)
    | SRA (rt, rd, sa) => (execute_SRA rt rd sa)  : M (unit)
    | SRAV (rs, rt, rd) => (execute_SRAV rs rt rd)  : M (unit)
    | SRL (rt, rd, sa) => (execute_SRL rt rd sa)  : M (unit)
    | SRLV (rs, rt, rd) => (execute_SRLV rs rt rd)  : M (unit)
    | SLT (rs, rt, rd) => (execute_SLT rs rt rd)  : M (unit)
    | SLTI (rs, rt, imm) => (execute_SLTI rs rt imm)  : M (unit)
    | SLTU (rs, rt, rd) => (execute_SLTU rs rt rd)  : M (unit)
    | SLTIU (rs, rt, imm) => (execute_SLTIU rs rt imm)  : M (unit)
    | MOVN (rs, rt, rd) => (execute_MOVN rs rt rd)  : M (unit)
    | MOVZ (rs, rt, rd) => (execute_MOVZ rs rt rd)  : M (unit)
    | MFHI rd => (execute_MFHI rd)  : M (unit)
    | MFLO rd => (execute_MFLO rd)  : M (unit)
    | MTHI rs => (execute_MTHI rs)  : M (unit)
    | MTLO rs => (execute_MTLO rs)  : M (unit)
    | MUL (rs, rt, rd) => (execute_MUL rs rt rd)  : M (unit)
    | MULT (rs, rt) => (execute_MULT rs rt)  : M (unit)
    | MULTU (rs, rt) => (execute_MULTU rs rt)  : M (unit)
    | DMULT (rs, rt) => (execute_DMULT rs rt)  : M (unit)
    | DMULTU (rs, rt) => (execute_DMULTU rs rt)  : M (unit)
    | MADD (rs, rt) => (execute_MADD rs rt)  : M (unit)
    | MADDU (rs, rt) => (execute_MADDU rs rt)  : M (unit)
    | MSUB (rs, rt) => (execute_MSUB rs rt)  : M (unit)
    | MSUBU (rs, rt) => (execute_MSUBU rs rt)  : M (unit)
    | DIV (rs, rt) => (execute_DIV rs rt)  : M (unit)
    | DIVU (rs, rt) => (execute_DIVU rs rt)  : M (unit)
    | DDIV (rs, rt) => (execute_DDIV rs rt)  : M (unit)
    | DDIVU (rs, rt) => (execute_DDIVU rs rt)  : M (unit)
    | J offset => (execute_J offset)  : M (unit)
    | JAL offset => (execute_JAL offset)  : M (unit)
    | JR rs => (execute_JR rs)  : M (unit)
    | JALR (rs, rd) => (execute_JALR rs rd)  : M (unit)
    | BEQ (rs, rd, imm, ne, likely) => (execute_BEQ rs rd imm ne likely)  : M (unit)
    | BCMPZ (rs, imm, cmp, link, likely) => (execute_BCMPZ rs imm cmp link likely)  : M (unit)
    | SYSCALL arg0 => (execute_SYSCALL arg0)  : M (unit)
    | BREAK arg0 => (execute_BREAK arg0)  : M (unit)
    | WAIT arg0 => (execute_WAIT arg0)  : M (unit)
    | TRAPREG (rs, rt, cmp) => (execute_TRAPREG rs rt cmp)  : M (unit)
    | TRAPIMM (rs, imm, cmp) => (execute_TRAPIMM rs imm cmp)  : M (unit)
    | Load (width, sign, linked, base, rt, offset) =>
       (execute_Load width sign linked base rt offset)  : M (unit)
    | Store (width, conditional, base, rt, offset) =>
       (execute_Store width conditional base rt offset)  : M (unit)
    | LWL (base, rt, offset) => (execute_LWL base rt offset)  : M (unit)
    | LWR (base, rt, offset) => (execute_LWR base rt offset)  : M (unit)
    | SWL (base, rt, offset) => (execute_SWL base rt offset)  : M (unit)
    | SWR (base, rt, offset) => (execute_SWR base rt offset)  : M (unit)
    | LDL (base, rt, offset) => (execute_LDL base rt offset)  : M (unit)
    | LDR (base, rt, offset) => (execute_LDR base rt offset)  : M (unit)
    | SDL (base, rt, offset) => (execute_SDL base rt offset)  : M (unit)
    | SDR (base, rt, offset) => (execute_SDR base rt offset)  : M (unit)
    | CACHE (base, op, imm) => (execute_CACHE base op imm)  : M (unit)
    | SYNC arg0 => (execute_SYNC arg0)  : M (unit)
    | MFC0 (rt, rd, sel, double) => (execute_MFC0 rt rd sel double)  : M (unit)
    | HCF arg0 => returnm (execute_HCF arg0)
    | MTC0 (rt, rd, sel, double) => (execute_MTC0 rt rd sel double)  : M (unit)
    | TLBWI arg0 => (execute_TLBWI arg0)  : M (unit)
    | TLBWR arg0 => (execute_TLBWR arg0)  : M (unit)
    | TLBR arg0 => (execute_TLBR arg0)  : M (unit)
    | TLBP arg0 => (execute_TLBP arg0)  : M (unit)
    | RDHWR (rt, rd) => (execute_RDHWR rt rd)  : M (unit)
    | ERET arg0 => (execute_ERET arg0)  : M (unit)
    | RI arg0 => (execute_RI arg0)  : M (unit)
    end)
    : M (unit).

Definition assembly (merge_var : ast) : string :=
   match merge_var with
   | DADDIU (rs, rt, imm) => String.append "daddiu " (strRRIArgs rs rt imm)
   | DADDU (rs, rt, rd) => String.append "daddu " (strRRRArgs rs rt rd)
   | DADDI (rs, rt, imm) => String.append "daddi " (strRRIArgs rs rt imm)
   | DADD (rs, rt, rd) => String.append "dadd " (strRRRArgs rs rt rd)
   | ADD (rs, rt, rd) => String.append "add " (strRRRArgs rs rt rd)
   | ADDI (rs, rt, imm) => String.append "addi " (strRRIArgs rs rt imm)
   | ADDU (rs, rt, rd) => String.append "addu " (strRRRArgs rs rt rd)
   | ADDIU (rs, rt, imm) => String.append "addiu " (strRRIArgs rs rt imm)
   | DSUBU (rs, rt, rd) => String.append "dsubu " (strRRRArgs rs rt rd)
   | DSUB (rs, rt, rd) => String.append "dsub " (strRRRArgs rs rt rd)
   | SUB (rs, rt, rd) => String.append "sub " (strRRRArgs rs rt rd)
   | SUBU (rs, rt, rd) => String.append "subu " (strRRRArgs rs rt rd)
   | AND (rs, rt, rd) => String.append "and " (strRRRArgs rs rt rd)
   | ANDI (rs, rt, imm) => String.append "andi " (strRRIUArgs rs rt imm)
   | OR (rs, rt, rd) => String.append "or " (strRRRArgs rs rt rd)
   | ORI (rs, rt, imm) => String.append "ori " (strRRIUArgs rs rt imm)
   | NOR (rs, rt, rd) => String.append "nor " (strRRRArgs rs rt rd)
   | XOR (rs, rt, rd) => String.append "xor " (strRRRArgs rs rt rd)
   | XORI (rs, rt, imm) => String.append "xori " (strRRIUArgs rs rt imm)
   | LUI (rt, imm) => String.append "lui " (strRIArgs rt imm)
   | DSLL (rs, rd, sa) => String.append "dsll " (strRRIUArgs rs rd sa)
   | DSLL32 (rs, rd, sa) => String.append "dsll32 " (strRRIUArgs rs rd sa)
   | DSLLV (rs, rt, rd) => String.append "dsllv " (strRRRArgs rs rt rd)
   | DSRA (rt, rd, sa) => String.append "dsra " (strRRIUArgs rt rd sa)
   | DSRA32 (rt, rd, sa) => String.append "dsra32 " (strRRIUArgs rt rd sa)
   | DSRAV (rs, rt, rd) => String.append "dsrav " (strRRRArgs rs rt rd)
   | DSRL (rt, rd, sa) => String.append "dsrl " (strRRIUArgs rt rd sa)
   | DSRL32 (rt, rd, sa) => String.append "dsrl32 " (strRRIUArgs rt rd sa)
   | DSRLV (rs, rt, rd) => String.append "dsrlv " (strRRRArgs rs rt rd)
   | SLL (rt, rd, sa) => String.append "sll " (strRRIUArgs rt rd sa)
   | SLLV (rs, rt, rd) => String.append "sllv " (strRRRArgs rs rt rd)
   | SRA (rt, rd, sa) => String.append "sra " (strRRIUArgs rt rd sa)
   | SRAV (rs, rt, rd) => String.append "srav " (strRRRArgs rs rt rd)
   | SRL (rt, rd, sa) => String.append "srl " (strRRIUArgs rt rd sa)
   | SRLV (rs, rt, rd) => String.append "srlv " (strRRRArgs rs rt rd)
   | SLT (rs, rt, rd) => String.append "slt " (strRRRArgs rs rt rd)
   | SLTI (rs, rd, imm) => String.append "slti " (strRRIArgs rs rd imm)
   | SLTU (rs, rt, rd) => String.append "sltu " (strRRRArgs rs rt rd)
   | SLTIU (rs, rd, imm) => String.append "sltiu " (strRRIUArgs rs rd imm)
   | MOVN (rs, rt, rd) => String.append "movn " (strRRRArgs rs rt rd)
   | MOVZ (rs, rt, rd) => String.append "movz " (strRRRArgs rs rt rd)
   | MFHI rd => String.append "mfhi " (strReg rd)
   | MFLO rd => String.append "mflo " (strReg rd)
   | MTHI rs => String.append "mthi " (strReg rs)
   | MTLO rs => String.append "mtlo " (strReg rs)
   | MUL (rs, rt, rd) => String.append "mul " (strRRRArgs rs rt rd)
   | MULT (rs, rt) =>
      String.append "mult " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | MULTU (rs, rt) =>
      String.append "multu " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | DMULT (rs, rt) =>
      String.append "dmult " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | DMULTU (rs, rt) =>
      String.append "dmultu " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | MADD (rs, rt) =>
      String.append "madd " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | MADDU (rs, rt) =>
      String.append "maddu " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | MSUB (rs, rt) =>
      String.append "msub " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | MSUBU (rs, rt) =>
      String.append "msubu " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | DIV (rs, rt) =>
      String.append "div " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | DIVU (rs, rt) =>
      String.append "divu " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | DDIV (rs, rt) =>
      String.append "ddiv " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | DDIVU (rs, rt) =>
      String.append "ddivu " (String.append (strReg rs) (String.append ", " (strReg rt)))
   | J offset => String.append "j " (hex_str (projT1 (uint offset)))
   | JAL offset => String.append "jal " (hex_str (projT1 (uint offset)))
   | JR rs => String.append "jr " (strReg rs)
   | JALR (rs, rd) =>
      String.append "jalr " (String.append (strReg rd) (String.append ", " (strReg rs)))
   | BEQ (rs, rt, imm, ne, likely) =>
      let op := if sumbool_of_bool ne then "bne" else "beq" in
      let l := if sumbool_of_bool likely then "l " else " " in
      String.append op
        (String.append l
           (String.append (strReg rs)
              (String.append ", "
                 (String.append (strReg rt) (String.append ", " (hex_str (projT1 (sint imm))))))))
   | BCMPZ (rs, imm, cmp, link, likely) =>
      let op := String.append "b" (String.append (strCmp cmp) "z") in
      let al := if sumbool_of_bool link then "al" else "" in
      let l := if sumbool_of_bool likely then "l " else " " in
      String.append op
        (String.append al
           (String.append l
              (String.append (strReg rs) (String.append ", " (hex_str (projT1 (sint imm)))))))
   | SYSCALL tt => "syscall"
   | BREAK tt => "break"
   | WAIT tt => "wait"
   | TRAPREG (rs, rt, cmp) =>
      let op := String.append "t" (String.append (strCmp cmp) " ") in
      String.append op (String.append (strReg rs) (String.append ", " (strReg rt)))
   | TRAPIMM (rs, imm, cmp) =>
      let op := String.append "t" (String.append (strCmp cmp) "i ") in
      String.append op
        (String.append (strReg rs) (String.append ", " (hex_str (projT1 (uint imm)))))
   | Load (width, sign, linked, base, rt, offset) =>
      let op : string :=
        match (width, sign, linked) with
        | (B, true, false) => "lb "
        | (B, false, false) => "lbu "
        | (H, true, false) => "lh "
        | (H, false, false) => "lhu "
        | (W, true, false) => "lw "
        | (W, false, false) => "lwu "
        | (D, false, false) => "ld "
        | (W, true, true) => "ll "
        | (D, false, true) => "lld "
        | _ => "invalid load"
        end in
      String.append op (strMemArgs base rt offset)
   | Store (width, conditional, base, rt, offset) =>
      let op : string :=
        if sumbool_of_bool conditional then
          match width with | W => "sc" | D => "scd" | _ => "invalid sc" end
        else String.append "s" (strWordType width) in
      String.append op (String.append " " (strMemArgs base rt offset))
   | LWL (base, rt, offset) => String.append "lwl " (strMemArgs base rt offset)
   | LWR (base, rt, offset) => String.append "lwr " (strMemArgs base rt offset)
   | SWL (base, rt, offset) => String.append "swl " (strMemArgs base rt offset)
   | SWR (base, rt, offset) => String.append "swr " (strMemArgs base rt offset)
   | LDL (base, rt, offset) => String.append "ldl " (strMemArgs base rt offset)
   | LDR (base, rt, offset) => String.append "ldr " (strMemArgs base rt offset)
   | SDL (base, rt, offset) => String.append "sdl " (strMemArgs base rt offset)
   | SDR (base, rt, offset) => String.append "sdr " (strMemArgs base rt offset)
   | CACHE (base, op, imm) => String.append "cache " (strMemArgs base op imm)
   | SYNC tt => "sync"
   | MFC0 (rt, rd, sel, double) =>
      let op := if sumbool_of_bool double then "dmfc0 " else "mfc0 " in
      String.append op
        (String.append (strReg rt)
           (String.append ", "
              (String.append (strReg rd) (String.append ", $" (dec_str (projT1 (uint sel)))))))
   | MTC0 (rt, rd, sel, double) =>
      let op := if sumbool_of_bool double then "dmtc0 " else "mtc0 " in
      String.append op
        (String.append (strReg rt)
           (String.append ", "
              (String.append (strReg rd) (String.append ", $" (dec_str (projT1 (uint sel)))))))
   | TLBWI tt => "tlbwi"
   | TLBWR tt => "tlbwr"
   | TLBR tt => "tlbr"
   | TLBP tt => "tlbp"
   | RDHWR (rt, rd) =>
      String.append "rdhwr" (String.append (strReg rt) (String.append ", " (strReg rd)))
   | ERET tt => "eret"
   | RI tt => "reserved instruction"
   | _ => "assembly unimplemented"
   end.

Definition supported_instructions (instr : ast) : option ast := Some instr.

Definition initialize_registers '(tt : unit) : M (unit) :=
   (undefined_bitvector 64) >>= fun w__0 : mword 64 =>
   write_reg PC_ref w__0 >>
   (undefined_bitvector 64) >>= fun w__1 : mword 64 =>
   write_reg NextPC_ref w__1 >>
   (undefined_bitvector 1) >>= fun w__2 : mword 1 =>
   write_reg TLBProbe_ref w__2 >>
   (undefined_bitvector 6) >>= fun w__3 : mword 6 =>
   write_reg TLBIndex_ref w__3 >>
   (undefined_bitvector 6) >>= fun w__4 : mword 6 =>
   write_reg TLBRandom_ref w__4 >>
   (undefined_TLBEntryLoReg tt) >>= fun w__5 : TLBEntryLoReg =>
   write_reg TLBEntryLo0_ref w__5 >>
   (undefined_TLBEntryLoReg tt) >>= fun w__6 : TLBEntryLoReg =>
   write_reg TLBEntryLo1_ref w__6 >>
   (undefined_ContextReg tt) >>= fun w__7 : ContextReg =>
   write_reg TLBContext_ref w__7 >>
   (undefined_bitvector 16) >>= fun w__8 : mword 16 =>
   write_reg TLBPageMask_ref w__8 >>
   (undefined_bitvector 6) >>= fun w__9 : mword 6 =>
   write_reg TLBWired_ref w__9 >>
   (undefined_TLBEntryHiReg tt) >>= fun w__10 : TLBEntryHiReg =>
   write_reg TLBEntryHi_ref w__10 >>
   (undefined_XContextReg tt) >>= fun w__11 : XContextReg =>
   write_reg TLBXContext_ref w__11 >>
   (undefined_TLBEntry tt) >>= fun w__12 : TLBEntry =>
   write_reg TLBEntry00_ref w__12 >>
   (undefined_TLBEntry tt) >>= fun w__13 : TLBEntry =>
   write_reg TLBEntry01_ref w__13 >>
   (undefined_TLBEntry tt) >>= fun w__14 : TLBEntry =>
   write_reg TLBEntry02_ref w__14 >>
   (undefined_TLBEntry tt) >>= fun w__15 : TLBEntry =>
   write_reg TLBEntry03_ref w__15 >>
   (undefined_TLBEntry tt) >>= fun w__16 : TLBEntry =>
   write_reg TLBEntry04_ref w__16 >>
   (undefined_TLBEntry tt) >>= fun w__17 : TLBEntry =>
   write_reg TLBEntry05_ref w__17 >>
   (undefined_TLBEntry tt) >>= fun w__18 : TLBEntry =>
   write_reg TLBEntry06_ref w__18 >>
   (undefined_TLBEntry tt) >>= fun w__19 : TLBEntry =>
   write_reg TLBEntry07_ref w__19 >>
   (undefined_TLBEntry tt) >>= fun w__20 : TLBEntry =>
   write_reg TLBEntry08_ref w__20 >>
   (undefined_TLBEntry tt) >>= fun w__21 : TLBEntry =>
   write_reg TLBEntry09_ref w__21 >>
   (undefined_TLBEntry tt) >>= fun w__22 : TLBEntry =>
   write_reg TLBEntry10_ref w__22 >>
   (undefined_TLBEntry tt) >>= fun w__23 : TLBEntry =>
   write_reg TLBEntry11_ref w__23 >>
   (undefined_TLBEntry tt) >>= fun w__24 : TLBEntry =>
   write_reg TLBEntry12_ref w__24 >>
   (undefined_TLBEntry tt) >>= fun w__25 : TLBEntry =>
   write_reg TLBEntry13_ref w__25 >>
   (undefined_TLBEntry tt) >>= fun w__26 : TLBEntry =>
   write_reg TLBEntry14_ref w__26 >>
   (undefined_TLBEntry tt) >>= fun w__27 : TLBEntry =>
   write_reg TLBEntry15_ref w__27 >>
   (undefined_TLBEntry tt) >>= fun w__28 : TLBEntry =>
   write_reg TLBEntry16_ref w__28 >>
   (undefined_TLBEntry tt) >>= fun w__29 : TLBEntry =>
   write_reg TLBEntry17_ref w__29 >>
   (undefined_TLBEntry tt) >>= fun w__30 : TLBEntry =>
   write_reg TLBEntry18_ref w__30 >>
   (undefined_TLBEntry tt) >>= fun w__31 : TLBEntry =>
   write_reg TLBEntry19_ref w__31 >>
   (undefined_TLBEntry tt) >>= fun w__32 : TLBEntry =>
   write_reg TLBEntry20_ref w__32 >>
   (undefined_TLBEntry tt) >>= fun w__33 : TLBEntry =>
   write_reg TLBEntry21_ref w__33 >>
   (undefined_TLBEntry tt) >>= fun w__34 : TLBEntry =>
   write_reg TLBEntry22_ref w__34 >>
   (undefined_TLBEntry tt) >>= fun w__35 : TLBEntry =>
   write_reg TLBEntry23_ref w__35 >>
   (undefined_TLBEntry tt) >>= fun w__36 : TLBEntry =>
   write_reg TLBEntry24_ref w__36 >>
   (undefined_TLBEntry tt) >>= fun w__37 : TLBEntry =>
   write_reg TLBEntry25_ref w__37 >>
   (undefined_TLBEntry tt) >>= fun w__38 : TLBEntry =>
   write_reg TLBEntry26_ref w__38 >>
   (undefined_TLBEntry tt) >>= fun w__39 : TLBEntry =>
   write_reg TLBEntry27_ref w__39 >>
   (undefined_TLBEntry tt) >>= fun w__40 : TLBEntry =>
   write_reg TLBEntry28_ref w__40 >>
   (undefined_TLBEntry tt) >>= fun w__41 : TLBEntry =>
   write_reg TLBEntry29_ref w__41 >>
   (undefined_TLBEntry tt) >>= fun w__42 : TLBEntry =>
   write_reg TLBEntry30_ref w__42 >>
   (undefined_TLBEntry tt) >>= fun w__43 : TLBEntry =>
   write_reg TLBEntry31_ref w__43 >>
   (undefined_TLBEntry tt) >>= fun w__44 : TLBEntry =>
   write_reg TLBEntry32_ref w__44 >>
   (undefined_TLBEntry tt) >>= fun w__45 : TLBEntry =>
   write_reg TLBEntry33_ref w__45 >>
   (undefined_TLBEntry tt) >>= fun w__46 : TLBEntry =>
   write_reg TLBEntry34_ref w__46 >>
   (undefined_TLBEntry tt) >>= fun w__47 : TLBEntry =>
   write_reg TLBEntry35_ref w__47 >>
   (undefined_TLBEntry tt) >>= fun w__48 : TLBEntry =>
   write_reg TLBEntry36_ref w__48 >>
   (undefined_TLBEntry tt) >>= fun w__49 : TLBEntry =>
   write_reg TLBEntry37_ref w__49 >>
   (undefined_TLBEntry tt) >>= fun w__50 : TLBEntry =>
   write_reg TLBEntry38_ref w__50 >>
   (undefined_TLBEntry tt) >>= fun w__51 : TLBEntry =>
   write_reg TLBEntry39_ref w__51 >>
   (undefined_TLBEntry tt) >>= fun w__52 : TLBEntry =>
   write_reg TLBEntry40_ref w__52 >>
   (undefined_TLBEntry tt) >>= fun w__53 : TLBEntry =>
   write_reg TLBEntry41_ref w__53 >>
   (undefined_TLBEntry tt) >>= fun w__54 : TLBEntry =>
   write_reg TLBEntry42_ref w__54 >>
   (undefined_TLBEntry tt) >>= fun w__55 : TLBEntry =>
   write_reg TLBEntry43_ref w__55 >>
   (undefined_TLBEntry tt) >>= fun w__56 : TLBEntry =>
   write_reg TLBEntry44_ref w__56 >>
   (undefined_TLBEntry tt) >>= fun w__57 : TLBEntry =>
   write_reg TLBEntry45_ref w__57 >>
   (undefined_TLBEntry tt) >>= fun w__58 : TLBEntry =>
   write_reg TLBEntry46_ref w__58 >>
   (undefined_TLBEntry tt) >>= fun w__59 : TLBEntry =>
   write_reg TLBEntry47_ref w__59 >>
   (undefined_TLBEntry tt) >>= fun w__60 : TLBEntry =>
   write_reg TLBEntry48_ref w__60 >>
   (undefined_TLBEntry tt) >>= fun w__61 : TLBEntry =>
   write_reg TLBEntry49_ref w__61 >>
   (undefined_TLBEntry tt) >>= fun w__62 : TLBEntry =>
   write_reg TLBEntry50_ref w__62 >>
   (undefined_TLBEntry tt) >>= fun w__63 : TLBEntry =>
   write_reg TLBEntry51_ref w__63 >>
   (undefined_TLBEntry tt) >>= fun w__64 : TLBEntry =>
   write_reg TLBEntry52_ref w__64 >>
   (undefined_TLBEntry tt) >>= fun w__65 : TLBEntry =>
   write_reg TLBEntry53_ref w__65 >>
   (undefined_TLBEntry tt) >>= fun w__66 : TLBEntry =>
   write_reg TLBEntry54_ref w__66 >>
   (undefined_TLBEntry tt) >>= fun w__67 : TLBEntry =>
   write_reg TLBEntry55_ref w__67 >>
   (undefined_TLBEntry tt) >>= fun w__68 : TLBEntry =>
   write_reg TLBEntry56_ref w__68 >>
   (undefined_TLBEntry tt) >>= fun w__69 : TLBEntry =>
   write_reg TLBEntry57_ref w__69 >>
   (undefined_TLBEntry tt) >>= fun w__70 : TLBEntry =>
   write_reg TLBEntry58_ref w__70 >>
   (undefined_TLBEntry tt) >>= fun w__71 : TLBEntry =>
   write_reg TLBEntry59_ref w__71 >>
   (undefined_TLBEntry tt) >>= fun w__72 : TLBEntry =>
   write_reg TLBEntry60_ref w__72 >>
   (undefined_TLBEntry tt) >>= fun w__73 : TLBEntry =>
   write_reg TLBEntry61_ref w__73 >>
   (undefined_TLBEntry tt) >>= fun w__74 : TLBEntry =>
   write_reg TLBEntry62_ref w__74 >>
   (undefined_TLBEntry tt) >>= fun w__75 : TLBEntry =>
   write_reg TLBEntry63_ref w__75 >>
   (undefined_bitvector 32) >>= fun w__76 : mword 32 =>
   write_reg CP0Compare_ref w__76 >>
   (undefined_CauseReg tt) >>= fun w__77 : CauseReg =>
   write_reg CP0Cause_ref w__77 >>
   (undefined_bitvector 1) >>= fun w__78 : mword 1 =>
   write_reg CP0LLBit_ref w__78 >>
   (undefined_bitvector 64) >>= fun w__79 : mword 64 =>
   write_reg CP0LLAddr_ref w__79 >>
   (undefined_bitvector 64) >>= fun w__80 : mword 64 =>
   write_reg CP0BadVAddr_ref w__80 >>
   (undefined_bitvector 32) >>= fun w__81 : mword 32 =>
   write_reg CurrentInstrBits_ref w__81 >>
   (undefined_bitvector 32) >>= fun w__82 : mword 32 =>
   write_reg LastInstrBits_ref w__82 >>
   (undefined_bitvector 32) >>= fun w__83 : mword 32 =>
   write_reg CP0BadInstr_ref w__83 >>
   (undefined_bitvector 32) >>= fun w__84 : mword 32 =>
   write_reg CP0BadInstrP_ref w__84 >>
   (undefined_bitvector 32) >>= fun w__85 : mword 32 =>
   write_reg CP0Count_ref w__85 >>
   (undefined_bitvector 32) >>= fun w__86 : mword 32 =>
   write_reg CP0HWREna_ref w__86 >>
   (undefined_bitvector 64) >>= fun w__87 : mword 64 =>
   write_reg CP0UserLocal_ref w__87 >>
   (undefined_bitvector 3) >>= fun w__88 : mword 3 =>
   write_reg CP0ConfigK0_ref w__88 >>
   (undefined_StatusReg tt) >>= fun w__89 : StatusReg =>
   write_reg CP0Status_ref w__89 >>
   (undefined_bitvector 1) >>= fun w__90 : mword 1 =>
   write_reg NextInBranchDelay_ref w__90 >>
   (undefined_bitvector 1) >>= fun w__91 : mword 1 =>
   write_reg InBranchDelay_ref w__91 >>
   (undefined_bitvector 1) >>= fun w__92 : mword 1 =>
   write_reg BranchPending_ref w__92 >>
   (undefined_bitvector 64) >>= fun w__93 : mword 64 =>
   write_reg DelayedPC_ref w__93 >>
   (undefined_bitvector 64) >>= fun w__94 : mword 64 =>
   write_reg HI_ref w__94 >>
   (undefined_bitvector 64) >>= fun w__95 : mword 64 =>
   write_reg LO_ref w__95 >>
   (undefined_bitvector 64) >>= fun w__96 : mword 64 =>
   (undefined_vector 32 w__96) >>= fun w__97 : vec (mword 64) 32 =>
   write_reg GPR_ref w__97 >>
   (undefined_bitvector 8) >>= fun w__98 : mword 8 =>
   write_reg UART_WDATA_ref w__98 >>
   (undefined_bitvector 1) >>= fun w__99 : mword 1 =>
   write_reg UART_WRITTEN_ref w__99 >>
   (undefined_bitvector 8) >>= fun w__100 : mword 8 =>
   write_reg UART_RDATA_ref w__100 >>
   (undefined_bitvector 1) >>= fun w__101 : mword 1 =>
   write_reg UART_RVALID_ref w__101 >>
   (undefined_bitvector 64) >>= fun w__102 : mword 64 =>
   write_reg CP0EPC_ref w__102 >>
   (undefined_bitvector 64) >>= fun w__103 : mword 64 =>
   write_reg CP0ErrorEPC_ref w__103
    : M (unit).

Definition initial_CauseReg : CauseReg :=
{| CauseReg_CauseReg_chunk_0 := (Ox"00000000"  : mword 32) |}.
Hint Unfold initial_CauseReg : sail.
Definition initial_TLBEntryLoReg : TLBEntryLoReg :=
{| TLBEntryLoReg_TLBEntryLoReg_chunk_0 := (Ox"0000000000000000"  : mword 64) |}.
Hint Unfold initial_TLBEntryLoReg : sail.
Definition initial_TLBEntryHiReg : TLBEntryHiReg :=
{| TLBEntryHiReg_TLBEntryHiReg_chunk_0 := (Ox"0000000000000000"  : mword 64) |}.
Hint Unfold initial_TLBEntryHiReg : sail.
Definition initial_ContextReg : ContextReg :=
{| ContextReg_ContextReg_chunk_0 := (Ox"0000000000000000"  : mword 64) |}.
Hint Unfold initial_ContextReg : sail.
Definition initial_XContextReg : XContextReg :=
{| XContextReg_XContextReg_chunk_0 := (Ox"0000000000000000"  : mword 64) |}.
Hint Unfold initial_XContextReg : sail.
Definition initial_TLBEntry : TLBEntry :=
{| TLBEntry_TLBEntry_chunk_1 :=
     ('b"0000000000000000000000000000000000000000000000000000000"
      : mword 55);
   TLBEntry_TLBEntry_chunk_0 := (Ox"0000000000000000"  : mword 64) |}.
Hint Unfold initial_TLBEntry : sail.
Definition initial_StatusReg : StatusReg :=
{| StatusReg_StatusReg_chunk_0 := (Ox"00000000"  : mword 32) |}.
Hint Unfold initial_StatusReg : sail.
Definition initial_regstate : regstate :=
{| CP0ErrorEPC := (Ox"0000000000000000"  : mword 64);
   CP0EPC := (Ox"0000000000000000"  : mword 64);
   UART_RVALID := ('b"0"  : mword 1);
   UART_RDATA := (Ox"00"  : mword 8);
   UART_WRITTEN := ('b"0"  : mword 1);
   UART_WDATA := (Ox"00"  : mword 8);
   GPR :=
     (vec_of_list_len [Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64;Ox"0000000000000000"  : mword 64;
                       Ox"0000000000000000"
                        : mword 64;Ox"0000000000000000"  : mword 64]);
   LO := (Ox"0000000000000000"  : mword 64);
   HI := (Ox"0000000000000000"  : mword 64);
   DelayedPC := (Ox"0000000000000000"  : mword 64);
   BranchPending := ('b"0"  : mword 1);
   InBranchDelay := ('b"0"  : mword 1);
   NextInBranchDelay := ('b"0"  : mword 1);
   CP0Status := initial_StatusReg;
   CP0ConfigK0 := ('b"000"  : mword 3);
   CP0UserLocal := (Ox"0000000000000000"  : mword 64);
   CP0HWREna := (Ox"00000000"  : mword 32);
   CP0Count := (Ox"00000000"  : mword 32);
   CP0BadInstrP := (Ox"00000000"  : mword 32);
   CP0BadInstr := (Ox"00000000"  : mword 32);
   LastInstrBits := (Ox"00000000"  : mword 32);
   CurrentInstrBits := (Ox"00000000"  : mword 32);
   CP0BadVAddr := (Ox"0000000000000000"  : mword 64);
   CP0LLAddr := (Ox"0000000000000000"  : mword 64);
   CP0LLBit := ('b"0"  : mword 1);
   CP0Cause := initial_CauseReg;
   CP0Compare := (Ox"00000000"  : mword 32);
   TLBEntry63 := initial_TLBEntry;
   TLBEntry62 := initial_TLBEntry;
   TLBEntry61 := initial_TLBEntry;
   TLBEntry60 := initial_TLBEntry;
   TLBEntry59 := initial_TLBEntry;
   TLBEntry58 := initial_TLBEntry;
   TLBEntry57 := initial_TLBEntry;
   TLBEntry56 := initial_TLBEntry;
   TLBEntry55 := initial_TLBEntry;
   TLBEntry54 := initial_TLBEntry;
   TLBEntry53 := initial_TLBEntry;
   TLBEntry52 := initial_TLBEntry;
   TLBEntry51 := initial_TLBEntry;
   TLBEntry50 := initial_TLBEntry;
   TLBEntry49 := initial_TLBEntry;
   TLBEntry48 := initial_TLBEntry;
   TLBEntry47 := initial_TLBEntry;
   TLBEntry46 := initial_TLBEntry;
   TLBEntry45 := initial_TLBEntry;
   TLBEntry44 := initial_TLBEntry;
   TLBEntry43 := initial_TLBEntry;
   TLBEntry42 := initial_TLBEntry;
   TLBEntry41 := initial_TLBEntry;
   TLBEntry40 := initial_TLBEntry;
   TLBEntry39 := initial_TLBEntry;
   TLBEntry38 := initial_TLBEntry;
   TLBEntry37 := initial_TLBEntry;
   TLBEntry36 := initial_TLBEntry;
   TLBEntry35 := initial_TLBEntry;
   TLBEntry34 := initial_TLBEntry;
   TLBEntry33 := initial_TLBEntry;
   TLBEntry32 := initial_TLBEntry;
   TLBEntry31 := initial_TLBEntry;
   TLBEntry30 := initial_TLBEntry;
   TLBEntry29 := initial_TLBEntry;
   TLBEntry28 := initial_TLBEntry;
   TLBEntry27 := initial_TLBEntry;
   TLBEntry26 := initial_TLBEntry;
   TLBEntry25 := initial_TLBEntry;
   TLBEntry24 := initial_TLBEntry;
   TLBEntry23 := initial_TLBEntry;
   TLBEntry22 := initial_TLBEntry;
   TLBEntry21 := initial_TLBEntry;
   TLBEntry20 := initial_TLBEntry;
   TLBEntry19 := initial_TLBEntry;
   TLBEntry18 := initial_TLBEntry;
   TLBEntry17 := initial_TLBEntry;
   TLBEntry16 := initial_TLBEntry;
   TLBEntry15 := initial_TLBEntry;
   TLBEntry14 := initial_TLBEntry;
   TLBEntry13 := initial_TLBEntry;
   TLBEntry12 := initial_TLBEntry;
   TLBEntry11 := initial_TLBEntry;
   TLBEntry10 := initial_TLBEntry;
   TLBEntry09 := initial_TLBEntry;
   TLBEntry08 := initial_TLBEntry;
   TLBEntry07 := initial_TLBEntry;
   TLBEntry06 := initial_TLBEntry;
   TLBEntry05 := initial_TLBEntry;
   TLBEntry04 := initial_TLBEntry;
   TLBEntry03 := initial_TLBEntry;
   TLBEntry02 := initial_TLBEntry;
   TLBEntry01 := initial_TLBEntry;
   TLBEntry00 := initial_TLBEntry;
   TLBXContext := initial_XContextReg;
   TLBEntryHi := initial_TLBEntryHiReg;
   TLBWired := ('b"000000"  : mword 6);
   TLBPageMask := (Ox"0000"  : mword 16);
   TLBContext := initial_ContextReg;
   TLBEntryLo1 := initial_TLBEntryLoReg;
   TLBEntryLo0 := initial_TLBEntryLoReg;
   TLBRandom := ('b"000000"  : mword 6);
   TLBIndex := ('b"000000"  : mword 6);
   TLBProbe := ('b"0"  : mword 1);
   NextPC := (Ox"0000000000000000"  : mword 64);
   PC := (Ox"0000000000000000"  : mword 64) |}.
Hint Unfold initial_regstate : sail.