123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377(*Generated by Lem from sail2_prompt_monad.lem.*)openLem_pervasives_extra(*open import Sail_impl_base*)openSail2_instr_kindsopenSail2_valuestyperegister_name=stringtypeaddress=bitUlisttype('regval,'a,'e)monad=|Doneof'a(* Read a number of bytes from memory, returned in little endian order,
with or without a tag. The first nat specifies the address, the second
the number of bytes. *)|Read_memofread_kind*int*int*(memory_bytelist->('regval,'a,'e)monad)|Read_memtofread_kind*int*int*((memory_bytelist*bitU)->('regval,'a,'e)monad)(* Tell the system a write is imminent, at the given address and with the
given size. *)|Write_eaofwrite_kind*int*int*('regval,'a,'e)monad(* Request the result of store-exclusive *)|Excl_resof(bool->('regval,'a,'e)monad)(* Request to write a memory value of the given size at the given address,
with or without a tag. *)|Write_memofwrite_kind*int*int*memory_bytelist*(bool->('regval,'a,'e)monad)|Write_memtofwrite_kind*int*int*memory_bytelist*bitU*(bool->('regval,'a,'e)monad)(* Tell the system to dynamically recalculate dependency footprint *)|Footprintof('regval,'a,'e)monad(* Request a memory barrier *)|Barrierofbarrier_kind*('regval,'a,'e)monad(* Request to read register, will track dependency when mode.track_values *)|Read_regofregister_name*('regval->('regval,'a,'e)monad)(* Request to write register *)|Write_regofregister_name*'regval*('regval,'a,'e)monad(* Request to choose a (register) value, e.g. to resolve an undefined bit.
The string argument may be used to provide information to the system
about what the value is going to be used for. *)|Chooseofstring*('regval->('regval,'a,'e)monad)(* Print debugging or tracing information *)|Printofstring*('regval,'a,'e)monad(*Result of a failed assert with possible error message to report*)|Failofstring(* Exception of type 'e *)|Exceptionof'etype'regvalevent=|E_read_memofread_kind*int*int*memory_bytelist|E_read_memtofread_kind*int*int*(memory_bytelist*bitU)|E_write_memofwrite_kind*int*int*memory_bytelist*bool|E_write_memtofwrite_kind*int*int*memory_bytelist*bitU*bool|E_write_eaofwrite_kind*int*int|E_excl_resofbool|E_barrierofbarrier_kind|E_footprint|E_read_regofregister_name*'regval|E_write_regofregister_name*'regval|E_chooseofstring*'regval|E_printofstringtype'regvaltrace=('regvalevent)list(*val return : forall 'rv 'a 'e. 'a -> monad 'rv 'a 'e*)letreturna:('rv,'a,'e)monad=(Donea)(*val bind : forall 'rv 'a 'b 'e. monad 'rv 'a 'e -> ('a -> monad 'rv 'b 'e) -> monad 'rv 'b 'e*)letrecbindmf:('rv,'b,'e)monad=((matchmwith|Donea->fa|Read_mem(rk,a,sz,k)->Read_mem(rk,a,sz,(funv->bind(kv)f))|Read_memt(rk,a,sz,k)->Read_memt(rk,a,sz,(funv->bind(kv)f))|Write_mem(wk,a,sz,v,k)->Write_mem(wk,a,sz,v,(funv->bind(kv)f))|Write_memt(wk,a,sz,v,t,k)->Write_memt(wk,a,sz,v,t,(funv->bind(kv)f))|Read_reg(descr,k)->Read_reg(descr,(funv->bind(kv)f))|Excl_resk->Excl_res(funv->bind(kv)f)|Choose(descr,k)->Choose(descr,(funv->bind(kv)f))|Write_ea(wk,a,sz,k)->Write_ea(wk,a,sz,(bindkf))|Footprintk->Footprint(bindkf)|Barrier(bk,k)->Barrier(bk,(bindkf))|Write_reg(r,v,k)->Write_reg(r,v,(bindkf))|Print(msg,k)->Print(msg,(bindkf))|Faildescr->Faildescr|Exceptione->Exceptione))(*val exit : forall 'rv 'a 'e. unit -> monad 'rv 'a 'e*)letexit():('rv,'a,'e)monad=(Fail"exit")(*val assert_exp : forall 'rv 'e. bool -> string -> monad 'rv unit 'e*)letassert_expexpmsg:('rv,(unit),'e)monad=(ifexpthenDone()elseFailmsg)(*val throw : forall 'rv 'a 'e. 'e -> monad 'rv 'a 'e*)letthrowe:('rv,'a,'e)monad=(Exceptione)(*val try_catch : forall 'rv 'a 'e1 'e2. monad 'rv 'a 'e1 -> ('e1 -> monad 'rv 'a 'e2) -> monad 'rv 'a 'e2*)letrectry_catchmh:('rv,'a,'e2)monad=((matchmwith|Donea->Donea|Read_mem(rk,a,sz,k)->Read_mem(rk,a,sz,(funv->try_catch(kv)h))|Read_memt(rk,a,sz,k)->Read_memt(rk,a,sz,(funv->try_catch(kv)h))|Write_mem(wk,a,sz,v,k)->Write_mem(wk,a,sz,v,(funv->try_catch(kv)h))|Write_memt(wk,a,sz,v,t,k)->Write_memt(wk,a,sz,v,t,(funv->try_catch(kv)h))|Read_reg(descr,k)->Read_reg(descr,(funv->try_catch(kv)h))|Excl_resk->Excl_res(funv->try_catch(kv)h)|Choose(descr,k)->Choose(descr,(funv->try_catch(kv)h))|Write_ea(wk,a,sz,k)->Write_ea(wk,a,sz,(try_catchkh))|Footprintk->Footprint(try_catchkh)|Barrier(bk,k)->Barrier(bk,(try_catchkh))|Write_reg(r,v,k)->Write_reg(r,v,(try_catchkh))|Print(msg,k)->Print(msg,(try_catchkh))|Faildescr->Faildescr|Exceptione->he))(* For early return, we abuse exceptions by throwing and catching
the return value. The exception type is "either 'r 'e", where "Right e"
represents a proper exception and "Left r" an early return of value "r". *)type('rv,'a,'r,'e)monadR=('rv,'a,(('r,'e)Either.either))monad(*val early_return : forall 'rv 'a 'r 'e. 'r -> monadR 'rv 'a 'r 'e*)letearly_returnr:('rv,'a,(('r,'e)Either.either))monad=(throw(Either.Leftr))(*val catch_early_return : forall 'rv 'a 'e. monadR 'rv 'a 'a 'e -> monad 'rv 'a 'e*)letcatch_early_returnm:('rv,'a,'e)monad=(try_catchm((function|Either.Lefta->returna|Either.Righte->throwe)))(*val pure_early_return : forall 'a. either 'a 'a -> 'a*)letpure_early_return:('a,'a)Either.either->'a=((function|Either.Lefta->a|Either.Righta->a))(*val either_bind : forall 'e 'a 'b. either 'e 'a -> ('a -> either 'e 'b) -> either 'e 'b*)leteither_bindmf:('e,'b)Either.either=((matchmwith|Either.Lefte->Either.Lefte|Either.Rightx->fx))(* Lift to monad with early return by wrapping exceptions *)(*val liftR : forall 'rv 'a 'r 'e. monad 'rv 'a 'e -> monadR 'rv 'a 'r 'e*)letliftRm:('rv,'a,(('r,'e)Either.either))monad=(try_catchm(fune->throw(Either.Righte)))(* Catch exceptions in the presence of early returns *)(*val try_catchR : forall 'rv 'a 'r 'e1 'e2. monadR 'rv 'a 'r 'e1 -> ('e1 -> monadR 'rv 'a 'r 'e2) -> monadR 'rv 'a 'r 'e2*)lettry_catchRmh:('rv,'a,(('r,'e2)Either.either))monad=(try_catchm((function|Either.Leftr->throw(Either.Leftr)|Either.Righte->he)))(*val maybe_fail : forall 'rv 'a 'e. string -> maybe 'a -> monad 'rv 'a 'e*)letmaybe_failmsg:'aoption->('rv,'a,'e)monad=((function|Somea->returna|None->Failmsg))(*val choose_regval : forall 'rv 'e. string -> monad 'rv 'rv 'e*)letchoose_regvaldescr:('rv,'rv,'e)monad=(Choose(descr,return))(*val choose_convert : forall 'rv 'e 'a. ('rv -> maybe 'a) -> string -> monad 'rv 'a 'e*)letchoose_convertof_rvdescr:('rv,'a,'e)monad=(Choose(descr,(funrv->maybe_faildescr(of_rvrv))))(*val choose_convert_default : forall 'rv 'e 'a. ('rv -> maybe 'a) -> 'a -> string -> monad 'rv 'a 'e*)letchoose_convert_defaultof_rvxdescr:('rv,'a,'e)monad=(Choose(descr,(funrv->return((matchof_rvrvwith|Somea->a|None->x)))))(*val choose_bool : forall 'rv 'e. Register_Value 'rv => string -> monad 'rv bool 'e*)letchoose_booldict_Sail2_values_Register_Value_rvdescr:('rv,(bool),'e)monad=(choose_convert_defaultdict_Sail2_values_Register_Value_rv.bool_of_regval_methodfalsedescr)(*val choose_bit : forall 'rv 'e. Register_Value 'rv => string -> monad 'rv bitU 'e*)letchoose_bitdict_Sail2_values_Register_Value_rvdescr:('rv,(bitU),'e)monad=(bind(choose_booldict_Sail2_values_Register_Value_rvdescr)(funb->return(bitU_of_boolb)))(*val choose_int : forall 'rv 'e. Register_Value 'rv => string -> monad 'rv integer 'e*)letchoose_intdict_Sail2_values_Register_Value_rvdescr:('rv,(Nat_big_num.num),'e)monad=(choose_convert_defaultdict_Sail2_values_Register_Value_rv.int_of_regval_method((Nat_big_num.of_int0))descr)(*val choose_real : forall 'rv 'e. Register_Value 'rv => string -> monad 'rv real 'e*)letchoose_realdict_Sail2_values_Register_Value_rvdescr:('rv,(float),'e)monad=(choose_convert_defaultdict_Sail2_values_Register_Value_rv.real_of_regval_method((Nat_big_num.to_float(Nat_big_num.of_int0)))descr)(*val choose_string : forall 'rv 'e. Register_Value 'rv => string -> monad 'rv string 'e*)letchoose_stringdict_Sail2_values_Register_Value_rvdescr:('rv,(string),'e)monad=(choose_convert_defaultdict_Sail2_values_Register_Value_rv.string_of_regval_method"default"descr)(*val headM : forall 'rv 'a 'e. list 'a -> monad 'rv 'a 'e*)letheadM:'alist->('rv,'a,'e)monad=((function|x::_->returnx|[]->Fail"headM"))(*val tailM : forall 'rv 'a 'e. list 'a -> monad 'rv (list 'a) 'e*)lettailM:'alist->('rv,('alist),'e)monad=((function|_::xs->returnxs|[]->Fail"tailM"))(*val read_memt_bytes : forall 'rv 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monad 'rv (list memory_byte * bitU) 'e*)letread_memt_bytesdict_Sail2_values_Bitvector_adict_Sail2_values_Bitvector_brkaddrsz:('rv,((memory_byte)list*bitU),'e)monad=(bind(maybe_fail"nat_of_bv"(nat_of_bvdict_Sail2_values_Bitvector_aaddr))(funaddr->Read_memt(rk,addr,(nat_of_intsz),return)))(*val read_memt : forall 'rv 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monad 'rv ('b * bitU) 'e*)letread_memtdict_Sail2_values_Bitvector_adict_Sail2_values_Bitvector_brkaddrsz:('rv,('b*bitU),'e)monad=(bind(read_memt_bytesdict_Sail2_values_Bitvector_adict_Sail2_values_Bitvector_arkaddrsz)(fun(bytes,tag)->(matchdict_Sail2_values_Bitvector_b.of_bits_method(bits_of_mem_bytesbytes)with|Somev->return(v,tag)|None->Fail"bits_of_mem_bytes")))(*val read_mem_bytes : forall 'rv 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monad 'rv (list memory_byte) 'e*)letread_mem_bytesdict_Sail2_values_Bitvector_adict_Sail2_values_Bitvector_brkaddrsz:('rv,((memory_byte)list),'e)monad=(bind(maybe_fail"nat_of_bv"(nat_of_bvdict_Sail2_values_Bitvector_aaddr))(funaddr->Read_mem(rk,addr,(nat_of_intsz),return)))(*val read_mem : forall 'rv 'a 'b 'e 'addrsize. Bitvector 'a, Bitvector 'b => read_kind -> 'addrsize -> 'a -> integer -> monad 'rv 'b 'e*)letread_memdict_Sail2_values_Bitvector_adict_Sail2_values_Bitvector_brk_addr_szaddrsz:('rv,'b,'e)monad=(bind(read_mem_bytesdict_Sail2_values_Bitvector_adict_Sail2_values_Bitvector_arkaddrsz)(funbytes->(matchdict_Sail2_values_Bitvector_b.of_bits_method(bits_of_mem_bytesbytes)with|Somev->returnv|None->Fail"bits_of_mem_bytes")))(*val excl_result : forall 'rv 'e. unit -> monad 'rv bool 'e*)letexcl_result():('rv,(bool),'e)monad=(letksuccessful=(returnsuccessful)inExcl_resk)(*val write_mem_ea : forall 'rv 'a 'e 'addrsize. Bitvector 'a => write_kind -> 'addrsize -> 'a -> integer -> monad 'rv unit 'e*)letwrite_mem_eadict_Sail2_values_Bitvector_awk_addr_sizeaddrsz:('rv,(unit),'e)monad=(bind(maybe_fail"nat_of_bv"(nat_of_bvdict_Sail2_values_Bitvector_aaddr))(funaddr->Write_ea(wk,addr,(nat_of_intsz),(Done()))))(*val write_mem : forall 'rv 'a 'b 'e 'addrsize. Bitvector 'a, Bitvector 'b =>
write_kind -> 'addrsize -> 'a -> integer -> 'b -> monad 'rv bool 'e*)letwrite_memdict_Sail2_values_Bitvector_adict_Sail2_values_Bitvector_bwk_addr_sizeaddrszv:('rv,(bool),'e)monad=((match(mem_bytes_of_bitsdict_Sail2_values_Bitvector_bv,nat_of_bvdict_Sail2_values_Bitvector_aaddr)with|(Somev,Someaddr)->Write_mem(wk,addr,(nat_of_intsz),v,return)|_->Fail"write_mem"))(*val write_memt : forall 'rv 'a 'b 'e. Bitvector 'a, Bitvector 'b =>
write_kind -> 'a -> integer -> 'b -> bitU -> monad 'rv bool 'e*)letwrite_memtdict_Sail2_values_Bitvector_adict_Sail2_values_Bitvector_bwkaddrszvtag:('rv,(bool),'e)monad=((match(mem_bytes_of_bitsdict_Sail2_values_Bitvector_bv,nat_of_bvdict_Sail2_values_Bitvector_aaddr)with|(Somev,Someaddr)->Write_memt(wk,addr,(nat_of_intsz),v,tag,return)|_->Fail"write_mem"))(*val read_reg : forall 's 'rv 'a 'e. register_ref 's 'rv 'a -> monad 'rv 'a 'e*)letread_regreg:('rv,'a,'e)monad=(letkv=((matchreg.of_regvalvwith|Somev->Donev|None->Fail"read_reg: unrecognised value"))inRead_reg(reg.name,k))(*val write_reg : forall 's 'rv 'a 'e. register_ref 's 'rv 'a -> 'a -> monad 'rv unit 'e*)letwrite_regregv:('rv,(unit),'e)monad=(Write_reg(reg.name,(reg.regval_ofv),(Done())))(* TODO
let write_reg reg v =
write_reg_aux (external_reg_whole reg) v
let write_reg_range reg i j v =
write_reg_aux (external_reg_slice reg (nat_of_int i,nat_of_int j)) v
let write_reg_pos reg i v =
let iN = nat_of_int i in
write_reg_aux (external_reg_slice reg (iN,iN)) [v]
let write_reg_bit = write_reg_pos
let write_reg_field reg regfield v =
write_reg_aux (external_reg_field_whole reg regfield.field_name) v
let write_reg_field_bit reg regfield bit =
write_reg_aux (external_reg_field_whole reg regfield.field_name)
(Vector [bit] 0 (is_inc_of_reg reg))
let write_reg_field_range reg regfield i j v =
write_reg_aux (external_reg_field_slice reg regfield.field_name (nat_of_int i,nat_of_int j)) v
let write_reg_field_pos reg regfield i v =
write_reg_field_range reg regfield i i [v]
let write_reg_field_bit = write_reg_field_pos*)(*val barrier : forall 'rv 'e. barrier_kind -> monad 'rv unit 'e*)letbarrierbk:('rv,(unit),'e)monad=(Barrier(bk,(Done())))(*val footprint : forall 'rv 'e. unit -> monad 'rv unit 'e*)letfootprint_:('rv,(unit),'e)monad=(Footprint(Done()))(* Event traces *)(*val emitEvent : forall 'regval 'a 'e. Eq 'regval => monad 'regval 'a 'e -> event 'regval -> maybe (monad 'regval 'a 'e)*)letemitEventdict_Basic_classes_Eq_regvalme:(('regval,'a,'e)monad)option=((match(e,m)with|(E_read_mem(rk,a,sz,v),Read_mem(rk',a',sz',k))->if(rk'=rk)&&((a'=a)&&(sz'=sz))thenSome(kv)elseNone|(E_read_memt(rk,a,sz,vt),Read_memt(rk',a',sz',k))->if(rk'=rk)&&((a'=a)&&(sz'=sz))thenSome(kvt)elseNone|(E_write_mem(wk,a,sz,v,r),Write_mem(wk',a',sz',v',k))->if(wk'=wk)&&((a'=a)&&((sz'=sz)&&(listEqualBy(listEqualBy(=))v'v)))thenSome(kr)elseNone|(E_write_memt(wk,a,sz,v,tag,r),Write_memt(wk',a',sz',v',tag',k))->if(wk'=wk)&&((a'=a)&&((sz'=sz)&&((listEqualBy(listEqualBy(=))v'v)&&(tag'=tag))))thenSome(kr)elseNone|(E_read_reg(r,v),Read_reg(r',k))->ifr'=rthenSome(kv)elseNone|(E_write_reg(r,v),Write_reg(r',v',k))->if(r'=r)&&dict_Basic_classes_Eq_regval.isEqual_methodv'vthenSomekelseNone|(E_write_ea(wk,a,sz),Write_ea(wk',a',sz',k))->if(wk'=wk)&&((a'=a)&&(sz'=sz))thenSomekelseNone|(E_barrierbk,Barrier(bk',k))->ifbk'=bkthenSomekelseNone|(E_printm,Print(m',k))->ifm'=mthenSomekelseNone|(E_excl_resv,Excl_resk)->Some(kv)|(E_choose(descr,v),Choose(descr',k))->ifdescr'=descrthenSome(kv)elseNone|(E_footprint,Footprintk)->Somek|_->None))(*val runTrace : forall 'regval 'a 'e. Eq 'regval => trace 'regval -> monad 'regval 'a 'e -> maybe (monad 'regval 'a 'e)*)letrecrunTracedict_Basic_classes_Eq_regvaltm:(('regval,'a,'e)monad)option=((matchtwith|[]->Somem|e::t'->Lem.option_bind(emitEventdict_Basic_classes_Eq_regvalme)(runTracedict_Basic_classes_Eq_regvalt')))(*val final : forall 'regval 'a 'e. monad 'regval 'a 'e -> bool*)letfinal:('regval,'a,'e)monad->bool=((function|Done_->true|Fail_->true|Exception_->true|_->false))(*val hasTrace : forall 'regval 'a 'e. Eq 'regval => trace 'regval -> monad 'regval 'a 'e -> bool*)lethasTracedict_Basic_classes_Eq_regvaltm:bool=((matchrunTracedict_Basic_classes_Eq_regvaltmwith|Somem->finalm|None->false))(*val hasException : forall 'regval 'a 'e. Eq 'regval => trace 'regval -> monad 'regval 'a 'e -> bool*)lethasExceptiondict_Basic_classes_Eq_regvaltm:bool=((matchrunTracedict_Basic_classes_Eq_regvaltmwith|Some(Exception_)->true|_->false))(*val hasFailure : forall 'regval 'a 'e. Eq 'regval => trace 'regval -> monad 'regval 'a 'e -> bool*)lethasFailuredict_Basic_classes_Eq_regvaltm:bool=((matchrunTracedict_Basic_classes_Eq_regvaltmwith|Some(Fail_)->true|_->false))(* Define a type synonym that also takes the register state as a type parameter,
in order to make switching to the state monad without changing generated
definitions easier, see also lib/hol/prompt_monad.lem. *)type('regval,'regstate,'a,'e)base_monad=('regval,'a,'e)monadtype('regval,'regstate,'a,'r,'e)base_monadR=('regval,'a,'r,'e)monadR