1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156(****************************************************************************)(* Sail *)(* *)(* Sail and the Sail architecture models here, comprising all files and *)(* directories except the ASL-derived Sail code in the aarch64 directory, *)(* are subject to the BSD two-clause licence below. *)(* *)(* The ASL derived parts of the ARMv8.3 specification in *)(* aarch64/no_vector and aarch64/full are copyright ARM Ltd. *)(* *)(* Copyright (c) 2013-2021 *)(* Kathyrn Gray *)(* Shaked Flur *)(* Stephen Kell *)(* Gabriel Kerneis *)(* Robert Norton-Wright *)(* Christopher Pulte *)(* Peter Sewell *)(* Alasdair Armstrong *)(* Brian Campbell *)(* Thomas Bauereiss *)(* Anthony Fox *)(* Jon French *)(* Dominic Mulligan *)(* Stephen Kell *)(* Mark Wassell *)(* Alastair Reid (Arm Ltd) *)(* *)(* All rights reserved. *)(* *)(* This work was partially supported by EPSRC grant EP/K008528/1 <a *)(* href="http://www.cl.cam.ac.uk/users/pes20/rems">REMS: Rigorous *)(* Engineering for Mainstream Systems</a>, an ARM iCASE award, EPSRC IAA *)(* KTF funding, and donations from Arm. This project has received *)(* funding from the European Research Council (ERC) under the European *)(* Union’s Horizon 2020 research and innovation programme (grant *)(* agreement No 789108, ELVER). *)(* *)(* This software was developed by SRI International and the University of *)(* Cambridge Computer Laboratory (Department of Computer Science and *)(* Technology) under DARPA/AFRL contracts FA8650-18-C-7809 ("CIFV") *)(* and FA8750-10-C-0237 ("CTSRD"). *)(* *)(* Redistribution and use in source and binary forms, with or without *)(* modification, are permitted provided that the following conditions *)(* are met: *)(* 1. Redistributions of source code must retain the above copyright *)(* notice, this list of conditions and the following disclaimer. *)(* 2. Redistributions in binary form must reproduce the above copyright *)(* notice, this list of conditions and the following disclaimer in *)(* the documentation and/or other materials provided with the *)(* distribution. *)(* *)(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *)(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *)(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *)(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *)(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *)(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *)(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *)(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *)(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *)(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *)(* SUCH DAMAGE. *)(****************************************************************************)moduleBig_int=Nat_big_num(* for ToFromInterp_lib_foo *)moduletypeBitType=sigtypetvalb0:tvalb1:tendtype'areturn={return:'b.'a->'b}type'zazoption=ZNoneofunit|ZSomeof'zaletzint_forwardsi=string_of_int(Big_int.to_inti)letopt_trace=reffalselettrace_depth=ref0letrandom=reffalseletopt_cycle_limit=ref0letcycle_count_var=ref0letget_cycle_count()=Big_int.of_int!cycle_count_varletcycle_count()=incrcycle_count_varletcycle_limit_reached()=incrcycle_count_var;!opt_cycle_limit!=0&&!cycle_count_var>=!opt_cycle_limitletsail_call(typet)(f:_->t)=letmoduleM=structexceptionReturnoftendinletreturn={return=(funx->raise(M.Returnx))}intryfreturnwithM.Returnx->xlettracestr=if!opt_tracethenbeginif!trace_depth<0thentrace_depth:=0else();prerr_endline(String.make(!trace_depth*2)' '^str)endelse()lettrace_writenamestr=trace("Write: "^name^" "^str)lettrace_readnamestr=trace("Read: "^name^" "^str)letsail_trace_call(typet)(name:string)(in_string:string)(string_of_out:t->string)(f:_->t)=letmoduleM=structexceptionReturnoftendinletreturn={return=(funx->raise(M.Returnx))}intrace("Call: "^name^" "^in_string);incrtrace_depth;letresult=tryfreturnwithM.Returnx->xindecrtrace_depth;trace("Return: "^string_of_outresult);resultlettrace_callstr=tracestr;incrtrace_depthtypebit=B0|B1leteq_anything(a,b)=a=bleteq_bit(a,b)=a=bletand_bit=functionB1,B1->B1|_,_->B0letor_bit=functionB0,B0->B0|_,_->B1letxor_bit=functionB1,B0->B1|B0,B1->B1|_,_->B0letand_vec(xs,ys)=assert(List.lengthxs=List.lengthys);List.map2(funxy->and_bit(x,y))xsysletand_bool(b1,b2)=b1&&b2letor_vec(xs,ys)=assert(List.lengthxs=List.lengthys);List.map2(funxy->or_bit(x,y))xsysletor_bool(b1,b2)=b1||b2letxor_vec(xs,ys)=assert(List.lengthxs=List.lengthys);List.map2(funxy->xor_bit(x,y))xsysletxor_bool(b1,b2)=(b1||b2)&&b1!=b2letundefined_bit()=if!randomthenifRandom.bool()thenB0elseB1elseB0letundefined_bool()=if!randomthenRandom.bool()elsefalseletrecundefined_vector(len,item)=ifBig_int.equallenBig_int.zerothen[]elseitem::undefined_vector(Big_int.sublen(Big_int.of_int1),item)letundefined_list_=[]letundefined_bitvectorlen=ifBig_int.equallenBig_int.zerothen[]elseB0::undefined_vector(Big_int.sublen(Big_int.of_int1),B0)letundefined_string()=""letundefined_unit()=()letundefined_int()=if!randomthenBig_int.of_int(Random.int0xFFFF)elseBig_int.zeroletundefined_nat()=Big_int.zeroletundefined_range(lo,_)=loletinternal_picklist=if!randomthenList.nthlist(Random.int(List.lengthlist))elseList.nthlist0leteq_int(n,m)=Big_int.equalnmleteq_bool((x:bool),(y:bool)):bool=x=yletrecdropnxs=match(n,xs)with0,xs->xs|_,[]->[]|n,_::xs->drop(n-1)xsletrectakenxs=match(n,xs)with0,_->[]|n,x::xs->x::take(n-1)xs|_,[]->[]letcount_leading_zerosxs=letrecauxbsacc=matchbswithB0::bs'->auxbs'(acc+1)|_->accinBig_int.of_int(auxxs0)letsubrange(list,n,m)=letn=Big_int.to_intninletm=Big_int.to_intminList.rev(take(n-(m-1))(dropm(List.revlist)))letslice(list,n,m)=letn=Big_int.to_intninletm=Big_int.to_intminList.rev(takem(dropn(List.revlist)))leteq_list(xs,ys)=List.for_all2(funxy->x=y)xsysletaccess(xs,n)=List.nth(List.revxs)(Big_int.to_intn)letappend(xs,ys)=xs@ysletupdate(xs,n,x)=letn=List.lengthxs-Big_int.to_intn-1intakenxs@[x]@drop(n+1)xsletupdate_subrange(xs,n,_,ys)=letrecauxxso=function[]->xs|y::ys->aux(update(xs,o,y))(Big_int.subo(Big_int.of_int1))ysinauxxsnysletvector_truncate(xs,n)=List.rev(take(Big_int.to_intn)(List.revxs))letvector_truncateLSB(xs,n)=take(Big_int.to_intn)xsletlengthxs=Big_int.of_int(List.lengthxs)letbig_int_of_bit=functionB0->Big_int.zero|B1->Big_int.of_int1letuintxs=letuint_bitx(n,pos)=(Big_int.addn(Big_int.mul(Big_int.pow_int_positive2pos)(big_int_of_bitx)),pos+1)infst(List.fold_rightuint_bitxs(Big_int.zero,0))letsint=function|[]->Big_int.zero|[msb]->Big_int.negate(big_int_of_bitmsb)|msb::xs->letmsb_pos=List.lengthxsinletcomplement=Big_int.negate(Big_int.mul(Big_int.pow_int_positive2msb_pos)(big_int_of_bitmsb))inBig_int.addcomplement(uintxs)letadd_int(x,y)=Big_int.addxyletsub_int(x,y)=Big_int.subxyletsub_nat(x,y)=letz=Big_int.subxyinifBig_int.lesszBig_int.zerothenBig_int.zeroelsezletmult(x,y)=Big_int.mulxy(* This is euclidian division from lem *)letquotient(x,y)=Big_int.divxy(* This is the same as tdiv_int, kept for compatibility with old preludes *)letquot_round_zero(x,y)=Big_int.integerDiv_txy(* The corresponding remainder function for above just respects the sign of x *)letrem_round_zero(x,y)=Big_int.integerRem_txy(* Lem provides euclidian modulo by default *)letmodulus(x,y)=Big_int.modulusxyletnegatex=Big_int.negatexlettdiv_int(x,y)=Big_int.integerDiv_txylettmod_int(x,y)=Big_int.integerRem_txyletadd_bit_with_carry(x,y,carry)=match(x,y,carry)with|B0,B0,B0->(B0,B0)|B0,B1,B0->(B1,B0)|B1,B0,B0->(B1,B0)|B1,B1,B0->(B0,B1)|B0,B0,B1->(B1,B0)|B0,B1,B1->(B0,B1)|B1,B0,B1->(B0,B1)|B1,B1,B1->(B1,B1)letsub_bit_with_carry(x,y,carry)=match(x,y,carry)with|B0,B0,B0->(B0,B0)|B0,B1,B0->(B0,B1)|B1,B0,B0->(B1,B0)|B1,B1,B0->(B0,B0)|B0,B0,B1->(B1,B0)|B0,B1,B1->(B0,B0)|B1,B0,B1->(B1,B1)|B1,B1,B1->(B1,B0)letnot_bit=functionB0->B1|B1->B0letnot_vecxs=List.mapnot_bitxsletadd_vec_carry(xs,ys)=assert(List.lengthxs=List.lengthys);letcarry,result=List.fold_right2(funxy(c,result)->letz,c=add_bit_with_carry(x,y,c)in(c,z::result))xsys(B0,[])in(carry,result)letadd_vec(xs,ys)=snd(add_vec_carry(xs,ys))letrecreplicate_bits(bits,n)=ifBig_int.less_equalnBig_int.zerothen[]elsebits@replicate_bits(bits,Big_int.subn(Big_int.of_int1))letidentityx=x(*
Returns list of n bits of integer m starting from offset o >= 0 (bits numbered from least significant).
Uses twos-complement representation for m<0 and pads most significant bits in sign-extended way.
Most significant bit is head of returned list.
*)letrecget_slice_int'(n,m,o)=ifn<=0then[]else(letbit=ifBig_int.extract_numm(n+o-1)1==Big_int.zerothenB0elseB1inbit::get_slice_int'(n-1,m,o))(* as above but taking Big_int for all arguments *)letget_slice_int(n,m,o)=get_slice_int'(Big_int.to_intn,m,Big_int.to_into)(* as above but omitting offset, len is ocaml int *)letto_bits'(len,n)=get_slice_int'(len,n,0)(* as above but taking big_int for length *)letto_bits(len,n)=get_slice_int'(Big_int.to_intlen,n,0)(* unsigned multiplication of two n bit lists producing a list of 2n bits *)letmult_vec(x,y)=letxi=uintxinletyi=uintyinletlen=List.lengthxinletprod=Big_int.mulxiyiinto_bits'(2*len,prod)(* signed multiplication of two n bit lists producing a list of 2n bits. *)letmults_vec(x,y)=letxi=sintxinletyi=sintyinletlen=List.lengthxinletprod=Big_int.mulxiyiinto_bits'(2*len,prod)letadd_vec_int(v,n)=letn_bits=to_bits'(List.lengthv,n)inadd_vec(v,n_bits)letsub_vec(xs,ys)=add_vec(xs,add_vec_int(not_vecys,Big_int.of_int1))letsub_vec_int(v,n)=letn_bits=to_bits'(List.lengthv,n)insub_vec(v,n_bits)letbin_char=function'0'->B0|'1'->B1|_->failwith"Invalid binary character"lethex_char=function|'0'->[B0;B0;B0;B0]|'1'->[B0;B0;B0;B1]|'2'->[B0;B0;B1;B0]|'3'->[B0;B0;B1;B1]|'4'->[B0;B1;B0;B0]|'5'->[B0;B1;B0;B1]|'6'->[B0;B1;B1;B0]|'7'->[B0;B1;B1;B1]|'8'->[B1;B0;B0;B0]|'9'->[B1;B0;B0;B1]|'A'|'a'->[B1;B0;B1;B0]|'B'|'b'->[B1;B0;B1;B1]|'C'|'c'->[B1;B1;B0;B0]|'D'|'d'->[B1;B1;B0;B1]|'E'|'e'->[B1;B1;B1;B0]|'F'|'f'->[B1;B1;B1;B1]|_->failwith"Invalid hex character"letlist_of_strings=letrecauxiacc=ifi<0thenaccelseaux(i-1)(s.[i]::acc)inaux(String.lengths-1)[]letbits_of_stringstr=List.concat(List.maphex_char(list_of_stringstr))letconcat_str(str1,str2)=str1^str2letrecbreakn=function[]->[]|_::_asxs->[takenxs]@breakn(dropnxs)letstring_of_bit=functionB0->"0"|B1->"1"letchar_of_bit=functionB0->'0'|B1->'1'letint_of_bit=functionB0->0|B1->1letbool_of_bit=functionB0->false|B1->trueletbit_of_bool=functionfalse->B0|true->B1letbigint_of_bitb=Big_int.of_int(int_of_bitb)letstring_of_hex=function|[B0;B0;B0;B0]->"0"|[B0;B0;B0;B1]->"1"|[B0;B0;B1;B0]->"2"|[B0;B0;B1;B1]->"3"|[B0;B1;B0;B0]->"4"|[B0;B1;B0;B1]->"5"|[B0;B1;B1;B0]->"6"|[B0;B1;B1;B1]->"7"|[B1;B0;B0;B0]->"8"|[B1;B0;B0;B1]->"9"|[B1;B0;B1;B0]->"A"|[B1;B0;B1;B1]->"B"|[B1;B1;B0;B0]->"C"|[B1;B1;B0;B1]->"D"|[B1;B1;B1;B0]->"E"|[B1;B1;B1;B1]->"F"|_->failwith"Cannot convert binary sequence to hex"letstring_of_bitsbits=ifList.lengthbitsmod4==0then"0x"^String.concat""(List.mapstring_of_hex(break4bits))else"0b"^String.concat""(List.mapstring_of_bitbits)letdecimal_string_of_bitsbits=letplace_values=List.mapi(funib->Big_int.mul(bigint_of_bitb)(Big_int.pow_int_positive2i))(List.revbits)inletsum=List.fold_leftBig_int.addBig_int.zeroplace_valuesinBig_int.to_stringsumlethex_slice(str,n,m)=letbits=List.concat(List.maphex_char(list_of_string(String.substr2(String.lengthstr-2))))inletpadding=replicate_bits([B0],n)inletbits=padding@bitsinletslice=List.rev(take(Big_int.to_intn)(drop(Big_int.to_intm)(List.revbits)))insliceletputcharn=print_char(char_of_int(Big_int.to_intn));flushstdoutletrecbits_of_intbitn=ifbit<>0thenbeginifn/bit>0thenB1::bits_of_int(bit/2)(n-bit)elseB0::bits_of_int(bit/2)nendelse[]letrecbits_of_big_intpown=ifpow<1then[]elsebeginletbit=Big_int.pow_int_positive2(pow-1)inifBig_int.greater(Big_int.divnbit)Big_int.zerothenB1::bits_of_big_int(pow-1)(Big_int.subnbit)elseB0::bits_of_big_int(pow-1)nendletbyte_of_intn=bits_of_int128nmoduleMem=structincludeMap.Make(structtypet=Big_int.numletcompare=Big_int.compareend)endletmem_pages=(refMem.empty:Bytes.tMem.tref)letpage_shift_bits=20(* 1M page *)letpage_size_bytes=1lslpage_shift_bitsletpage_no_of_addra=Big_int.shift_rightapage_shift_bitsletbottom_addr_of_pagep=Big_int.shift_leftppage_shift_bitslettop_addr_of_pagep=Big_int.shift_left(Big_int.succp)page_shift_bitsletget_mem_pagep=tryMem.findp!mem_pageswithNot_found->letnew_page=Bytes.makepage_size_bytes'\000'inmem_pages:=Mem.addpnew_page!mem_pages;new_pageletrecadd_mem_bytesaddrbufofflen=letpage_no=page_no_of_addraddrinletpage_bot=bottom_addr_of_pagepage_noinletpage_top=top_addr_of_pagepage_noinletpage_off=Big_int.to_int(Big_int.subaddrpage_bot)inletpage=get_mem_pagepage_noinletbytes_left_in_page=Big_int.subpage_topaddrinletto_copy=min(Big_int.to_intbytes_left_in_page)leninBytes.blitbufoffpagepage_offto_copy;ifto_copy<lenthenadd_mem_bytespage_topbuf(off+to_copy)(len-to_copy)letrecread_mem_bytesaddrlen=letpage_no=page_no_of_addraddrinletpage_bot=bottom_addr_of_pagepage_noinletpage_top=top_addr_of_pagepage_noinletpage_off=Big_int.to_int(Big_int.subaddrpage_bot)inletpage=get_mem_pagepage_noinletbytes_left_in_page=Big_int.subpage_topaddrinletto_get=min(Big_int.to_intbytes_left_in_page)leninletbytes=Bytes.subpagepage_offto_getinifto_get>=lenthenbyteselseBytes.catbytes(read_mem_bytespage_top(len-to_get))letwrite_ram'(data_size,addr,data)=letlen=Big_int.to_intdata_sizeinletbytes=Bytes.createleninbeginList.iteri(funibyte->Bytes.setbytes(len-i-1)(char_of_int(Big_int.to_int(uintbyte))))(break8data);add_mem_bytesaddrbytes0lenendletwrite_ram(_addr_size,data_size,_hex_ram,addr,data)=write_ram'(data_size,uintaddr,data);trueletwramaddrbyte=letbytes=Bytes.make1(char_of_intbyte)inadd_mem_bytesaddrbytes01letread_ram(_addr_size,data_size,_hex_ram,addr)=letaddr=uintaddrinletbytes=read_mem_bytesaddr(Big_int.to_intdata_size)inletvector=ref[]inBytes.iter(funbyte->vector:=byte_of_int(int_of_charbyte)@!vector)bytes;!vectorletfast_read_ram(data_size,addr)=letaddr=uintaddrinletbytes=read_mem_bytesaddr(Big_int.to_intdata_size)inletvector=ref[]inBytes.iter(funbyte->vector:=byte_of_int(int_of_charbyte)@!vector)bytes;!vectorlettag_ram=(refMem.empty:boolMem.tref)letwrite_tag_bool(addr,tag)=letaddri=uintaddrintag_ram:=Mem.addaddritag!tag_ramletread_tag_booladdr=letaddri=uintaddrintryMem.findaddri!tag_ramwithNot_found->falseletrecreverse_endiannessbits=ifList.lengthbits<=8thenbitselsereverse_endianness(drop8bits)@take8bits(* FIXME: Casts can't be externed *)letzcast_unit_vecx=[x]letshl_int(n,m)=Big_int.shift_leftn(Big_int.to_intm)letshr_int(n,m)=Big_int.shift_rightn(Big_int.to_intm)letlor_int(n,m)=Big_int.bitwise_ornmletland_int(n,m)=Big_int.bitwise_andnmletlxor_int(n,m)=Big_int.bitwise_xornmletdebug(str1,n,str2,v)=prerr_endline(str1^Big_int.to_stringn^str2^string_of_bitsv)leteq_string(str1,str2)=String.comparestr1str2==0letstring_startswith(str1,str2)=String.lengthstr1>=String.lengthstr2&&String.compare(String.substr10(String.lengthstr2))str2==0letstring_drop(str,n)=ifBig_int.less_equal(Big_int.of_int(String.lengthstr))nthen""else(letn=Big_int.to_intninString.substrn(String.lengthstr-n))letstring_take(str,n)=letn=Big_int.to_intninifString.lengthstr<=nthenstrelseString.substr0nletstring_lengthstr=Big_int.of_int(String.lengthstr)letstring_append(s1,s2)=s1^s2letint_of_string_opts=trySome(Big_int.of_strings)withInvalid_argument_->None(* highly inefficient recursive implementation *)letrecmaybe_int_of_prefix=function|""->ZNone()|str->(letlen=String.lengthstrinmatchint_of_string_optstrwith|Somen->ZSome(n,Big_int.of_intlen)|None->maybe_int_of_prefix(String.substr0(len-1)))letmaybe_int_of_stringstr=matchint_of_string_optstrwithNone->ZNone()|Somen->ZSomenletlt_int(x,y)=Big_int.lessxyletset_slice(out_len,_slice_len,out,n,slice)=letout=update_subrange(out,Big_int.addn(Big_int.of_int(List.lengthslice-1)),n,slice)inassert(List.lengthout=Big_int.to_intout_len);out(* Set slice_len bits in the integer m, starting from index n *)letset_slice_int(slice_len,m,n,slice)=assert(Big_int.to_intslice_len==List.lengthslice);letshifted_slice=Big_int.shift_left(uintslice)(Big_int.to_intn)inletmask=uint(replicate_bits([B1],slice_len)@replicate_bits([B0],n))inBig_int.bitwise_or(Big_int.bitwise_xor(Big_int.bitwise_ormaskm)mask)shifted_sliceleteq_real(x,y)=Rational.equalxyletlt_real(x,y)=Rational.ltxyletgt_real(x,y)=Rational.gtxyletlteq_real(x,y)=Rational.leqxyletgteq_real(x,y)=Rational.geqxyletto_realx=Rational.of_int(Big_int.to_intx)(* FIXME *)letnegate_realx=Rational.negxletneg_realx=Rational.negxletstring_of_realx=ifBig_int.equal(Rational.denx)(Big_int.of_int1)thenBig_int.to_string(Rational.numx)elseBig_int.to_string(Rational.numx)^"/"^Big_int.to_string(Rational.denx)letprint_real(str,r)=print_endline(str^string_of_realr)letprerr_real(str,r)=prerr_endline(str^string_of_realr)letround_downx=Rational.floorxletround_upx=Rational.ceilingxletquotient_real(x,y)=Rational.divxyletdiv_real(x,y)=Rational.divxyletmult_real(x,y)=Rational.mulxyletreal_power(_,_)=failwith"real_power"letint_power(x,y)=Big_int.pow_intx(Big_int.to_inty)letadd_real(x,y)=Rational.addxyletsub_real(x,y)=Rational.subxyletabs_realx=Rational.absxletsqrt_realx=letprecision=30inlets=Big_int.sqrt(Rational.numx)inifBig_int.equal(Rational.denx)(Big_int.of_int1)&&Big_int.equal(Big_int.mulss)(Rational.numx)thento_realselse(letp=ref(to_real(Big_int.sqrt(Big_int.div(Rational.numx)(Rational.denx))))inletn=ref(Rational.of_int0)inletconvergence=ref(Rational.div(Rational.of_int1)(Rational.of_big_int(Big_int.pow_int_positive10precision)))inletquit_loop=reffalseinwhilenot!quit_loopdon:=Rational.div(Rational.add!p(Rational.divx!p))(Rational.of_int2);ifRational.lt(Rational.abs(Rational.sub!p!n))!convergencethenquit_loop:=trueelsep:=!ndone;!n)letrandom_real()=Rational.div(Rational.of_int(Random.bits()))(Rational.of_int(Random.bits()))letlt(x,y)=Big_int.lessxyletgt(x,y)=Big_int.greaterxyletlteq(x,y)=Big_int.less_equalxyletgteq(x,y)=Big_int.greater_equalxyletpow2x=Big_int.pow_int(Big_int.of_int2)(Big_int.to_intx)letmax_int(x,y)=Big_int.maxxyletmin_int(x,y)=Big_int.minxyletabs_intx=Big_int.absxletstring_of_intx=Big_int.to_stringxletundefined_real()=Rational.of_int0letrecpowx=function0->1|n->x*powx(n-1)letreal_of_stringstr=matchUtil.split_on_char'.'strwith|[whole;frac]->letwhole=Rational.of_int(int_of_stringwhole)inletfrac=Rational.div(Rational.of_int(int_of_stringfrac))(Rational.of_int(pow10(String.lengthfrac)))inRational.addwholefrac|[_]->Rational.of_int(int_of_stringstr)|_->failwith"invalid real literal"letprintstr=Stdlib.print_stringstrletprerrstr=Stdlib.prerr_stringstrletprint_int(str,x)=print_endline(str^Big_int.to_stringx)letprerr_int(str,x)=prerr_endline(str^Big_int.to_stringx)letprint_bits(str,xs)=print_endline(str^string_of_bitsxs)letprerr_bits(str,xs)=prerr_endline(str^string_of_bitsxs)letprint_string(str,msg)=print_endline(str^msg)letprerr_string(str,msg)=prerr_endline(str^msg)letreg_derefr=!rletstring_of_zbit=functionB0->"0"|B1->"1"letstring_of_znatn=Big_int.to_stringnletstring_of_zintn=Big_int.to_stringnletstring_of_zimplicitn=Big_int.to_stringnletstring_of_zunit()="()"letstring_of_zbool=functiontrue->"true"|false->"false"letstring_of_zreal_="REAL"letstring_of_zstringstr="\""^String.escapedstr^"\""letrecstring_of_listsepstring_of=function|[]->""|[x]->string_ofx|x::ls->string_ofx^sep^string_of_listsepstring_oflsletskip()=()letmemea(_,_)=()letzero_extend(vec,n)=letm=Big_int.to_intninifm<=List.lengthvecthentakemvecelsereplicate_bits([B0],Big_int.of_int(m-List.lengthvec))@vecletsign_extend(vec,n)=letm=Big_int.to_intninmatchvecwith|B0::_asvec->replicate_bits([B0],Big_int.of_int(m-List.lengthvec))@vec|[]->replicate_bits([B0],Big_int.of_int(m-List.lengthvec))@vec|B1::_asvec->replicate_bits([B1],Big_int.of_int(m-List.lengthvec))@vecletzerosn=replicate_bits([B0],n)letonesn=replicate_bits([B1],n)letshift_bits_right_arith(x,y)=letybi=uintyinletmsbs=replicate_bits(take1x,ybi)inletrbits=msbs@xintake(List.lengthx)rbitsletshiftr(x,y)=letzeros=zerosyinletrbits=zeros@xintake(List.lengthx)rbitsletarith_shiftr(x,y)=letmsbs=replicate_bits(take1x,y)inletrbits=msbs@xintake(List.lengthx)rbitsletshift_bits_right(x,y)=shiftr(x,uinty)letshiftl(x,y)=letyi=Big_int.to_intyinletzeros=zerosyinletrbits=x@zerosindropyirbitsletshift_bits_left(x,y)=shiftl(x,uinty)letspeculate_conditional_success()=true(* Return nanoseconds since epoch. Truncates to ocaml int but will be OK for next 100 years or so... *)letget_time_ns()=Big_int.of_int(int_of_float(1e9*.Unix.gettimeofday()))(* Python:
f = """let hex_bits_{0}_matches_prefix s =
match maybe_int_of_prefix s with
| ZNone () -> ZNone ()
| ZSome (n, len) ->
if Big_int.less_equal Big_int.zero n
&& Big_int.less n (Big_int.pow_int_positive 2 {0}) then
ZSome ((bits_of_big_int {0} n, len))
else
ZNone ()
"""
for i in list(range(1, 34)) + [48, 64]:
print(f.format(i))
*)lethex_bits_1_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive21)thenZSome(bits_of_big_int1n,len)elseZNone()lethex_bits_2_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive22)thenZSome(bits_of_big_int2n,len)elseZNone()lethex_bits_3_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive23)thenZSome(bits_of_big_int3n,len)elseZNone()lethex_bits_4_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive24)thenZSome(bits_of_big_int4n,len)elseZNone()lethex_bits_5_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive25)thenZSome(bits_of_big_int5n,len)elseZNone()lethex_bits_6_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive26)thenZSome(bits_of_big_int6n,len)elseZNone()lethex_bits_7_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive27)thenZSome(bits_of_big_int7n,len)elseZNone()lethex_bits_8_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive28)thenZSome(bits_of_big_int8n,len)elseZNone()lethex_bits_9_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive29)thenZSome(bits_of_big_int9n,len)elseZNone()lethex_bits_10_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive210)thenZSome(bits_of_big_int10n,len)elseZNone()lethex_bits_11_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive211)thenZSome(bits_of_big_int11n,len)elseZNone()lethex_bits_12_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive212)thenZSome(bits_of_big_int12n,len)elseZNone()lethex_bits_13_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive213)thenZSome(bits_of_big_int13n,len)elseZNone()lethex_bits_14_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive214)thenZSome(bits_of_big_int14n,len)elseZNone()lethex_bits_15_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive215)thenZSome(bits_of_big_int15n,len)elseZNone()lethex_bits_16_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive216)thenZSome(bits_of_big_int16n,len)elseZNone()lethex_bits_17_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive217)thenZSome(bits_of_big_int17n,len)elseZNone()lethex_bits_18_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive218)thenZSome(bits_of_big_int18n,len)elseZNone()lethex_bits_19_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive219)thenZSome(bits_of_big_int19n,len)elseZNone()lethex_bits_20_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive220)thenZSome(bits_of_big_int20n,len)elseZNone()lethex_bits_21_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive221)thenZSome(bits_of_big_int21n,len)elseZNone()lethex_bits_22_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive222)thenZSome(bits_of_big_int22n,len)elseZNone()lethex_bits_23_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive223)thenZSome(bits_of_big_int23n,len)elseZNone()lethex_bits_24_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive224)thenZSome(bits_of_big_int24n,len)elseZNone()lethex_bits_25_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive225)thenZSome(bits_of_big_int25n,len)elseZNone()lethex_bits_26_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive226)thenZSome(bits_of_big_int26n,len)elseZNone()lethex_bits_27_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive227)thenZSome(bits_of_big_int27n,len)elseZNone()lethex_bits_28_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive228)thenZSome(bits_of_big_int28n,len)elseZNone()lethex_bits_29_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive229)thenZSome(bits_of_big_int29n,len)elseZNone()lethex_bits_30_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive230)thenZSome(bits_of_big_int30n,len)elseZNone()lethex_bits_31_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive231)thenZSome(bits_of_big_int31n,len)elseZNone()lethex_bits_32_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive232)thenZSome(bits_of_big_int32n,len)elseZNone()lethex_bits_33_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive233)thenZSome(bits_of_big_int33n,len)elseZNone()lethex_bits_48_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive248)thenZSome(bits_of_big_int48n,len)elseZNone()lethex_bits_64_matches_prefixs=matchmaybe_int_of_prefixswith|ZNone()->ZNone()|ZSome(n,len)->ifBig_int.less_equalBig_int.zeron&&Big_int.lessn(Big_int.pow_int_positive264)thenZSome(bits_of_big_int64n,len)elseZNone()letstring_of_bool=functiontrue->"true"|false->"false"letdec_strx=Big_int.to_stringxletto_lower_hex_charn=if10<=n&&n<=15thenChar.chr(n+87)elseChar.chr(n+48)letto_upper_hex_charn=if10<=n&&n<=15thenChar.chr(n+55)elseChar.chr(n+48)lethex_str_helperto_charx=ifBig_int.equalxBig_int.zerothen"0x0"else(letx=refxinlets=ref""inwhilenot(Big_int.equal!xBig_int.zero)doletlower_4=Big_int.to_int(Big_int.bitwise_and!x(Big_int.of_int15))ins:=String.make1(to_charlower_4)^!s;x:=Big_int.shift_right!x4done;"0x"^!s)lethex_str=hex_str_helperto_lower_hex_charlethex_str_upper=hex_str_helperto_upper_hex_charletis_hex_charch=letc=Char.codechin(Char.code'0'<=c&&c<=Char.code'9')||(Char.code'a'<=c&&c<=Char.code'f')||(Char.code'A'<=c&&c<=Char.code'F')letvalid_hex_bits(n,s)=letlen=String.lengthsin(* We must have at least the 0x prefix, then one character *)iflen<3||String.subs02<>"0x"thenfalseelse(lethex=String.subs2(len-2)inletis_valid=reftrueinString.iter(func->is_valid:=!is_valid&&is_hex_charc)hex;!is_valid)letparse_hex_bits(n,s)=ifnot(valid_hex_bits(n,s))thenzerosnelsebits_of_string(String.subs2(String.lengths-2))|>List.rev|>Util.take(Big_int.to_intn)|>List.revlettrace_memory_write(_,_,_)=()lettrace_memory_read(_,_,_)=()letsleep_request()=()letwakeup_request()=()letreset_registers()=()letload_raw(paddr,file)=leti=ref0inletpaddr=uintpaddrinletin_chan=open_infileintrywhiletruedoletbyte=input_charin_chan|>Char.codeinwram(Big_int.addpaddr(Big_int.of_int!i))byte;incridonewithEnd_of_file->()(* TODO range, atom, register(?), int, nat, bool, real(!), list, string, itself(?) *)letrand_zvector(g:'generators)(size:int)(_order:bool)(elem_gen:'generators->'a):'alist=Util.list_initsize(fun_->elem_geng)letrand_zbit(_:'generators):bit=bit_of_bool(Random.bool())letrand_zbitvector(g:'generators)(size:int)(_order:bool):bitlist=Util.list_initsize(fun_->rand_zbitg)letrand_zbool(_:'generators):bool=Random.bool()letrand_zunit(_:'generators):unit=()letrand_choicel=letn=List.lengthlinList.nthl(Random.intn)letemulator_read_mem(_addrsize,addr,len)=fast_read_ram(len,addr)letemulator_read_mem_ifetch(_addrsize,addr,len)=fast_read_ram(len,addr)letemulator_read_mem_exclusive(_addrsize,addr,len)=fast_read_ram(len,addr)letemulator_write_mem(_addrsize,addr,len,value)=write_ram'(len,uintaddr,value);trueletemulator_write_mem_exclusive(_addrsize,addr,len,value)=write_ram'(len,uintaddr,value);trueletemulator_read_tag(_addrsize,addr)=read_tag_booladdrletemulator_write_tag(_addrsize,addr,tag)=write_tag_bool(addr,tag)