123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364openUtilsopenVar0openProgincludeCoreConvmoduleW=WsizemoduleT=TypemoduleC=Exprletz_of_natn=z_of_cz(BinInt.Z.of_natn)letint_of_natn=Z.to_int(z_of_natn)letnat_of_inti=BinInt.Z.to_nat(cz_of_inti)letpos_of_inti=pos_of_z(Z.of_inti)letint_of_posp=Z.to_int(z_of_posp)letword_of_zszz=Word0.wreprsz(cz_of_zz)letint64_of_zz=word_of_zW.U64zletint32_of_zz=word_of_zW.U32zletz_of_int256z=z_of_cz(Word0.wsignedW.U256z)letz_of_int128z=z_of_cz(Word0.wsignedW.U128z)letz_of_int64z=z_of_cz(Word0.wsignedW.U64z)letz_of_int32z=z_of_cz(Word0.wsignedW.U32z)letz_of_int16z=z_of_cz(Word0.wsignedW.U16z)letz_of_int8z=z_of_cz(Word0.wsignedW.U8z)letz_of_wordszz=z_of_cz(Word0.wsignedszz)letz_unsigned_of_wordszz=z_of_cz(Word0.wunsignedszz)(* ------------------------------------------------------------------------ *)letcty_of_ty=function|BtyBool->T.Coq_sbool|BtyInt->T.Coq_sint|Bty(Usz)->T.Coq_sword(sz)|Arr(sz,len)->T.Coq_sarr(pos_of_int(size_of_wssz*len))letty_of_cty=function|T.Coq_sbool->BtyBool|T.Coq_sint->BtyInt|T.Coq_swordsz->Bty(Usz)|T.Coq_sarrp->Arr(U8,int_of_posp)(* ------------------------------------------------------------------------ *)letcvar_of_varv={Var.vtype=cty_of_tyv.v_ty;Var.vname=v}letvar_of_cvarcv=letv=cv.Var.vnameinassert(cty_of_tyv.v_ty=cv.Var.vtype);vletcsv_of_svs=letopenVar0.SvExtra.SvinSv.fold(funxcs->add(Obj.magic(cvar_of_varx))cs)semptyletsv_of_csvcs=letopenVar0.SvExtra.Svinfold(funxs->Sv.add(var_of_cvar(Obj.magicx))s)csSv.empty(* ------------------------------------------------------------------------ *)letcvari_of_variv=letp=L.locvinletcv=cvar_of_var(L.unlocv)in{C.v_var=cv;C.v_info=p}letvari_of_cvariv=L.mk_locv.C.v_info(var_of_cvarv.C.v_var)letcgvari_of_gvariv={C.gv=cvari_of_variv.gv;C.gs=v.gs}letgvari_of_cgvariv={gv=vari_of_cvariv.C.gv;gs=v.C.gs}(* ------------------------------------------------------------------------ *)letreccexpr_of_expr=function|Pconstz->C.Pconst(cz_of_zz)|Pboolb->C.Pboolb|Parr_initn->C.Parr_init(pos_of_intn)|Pvarx->C.Pvar(cgvari_of_gvarix)|Pget(al,aa,ws,x,e)->C.Pget(al,aa,ws,cgvari_of_gvarix,cexpr_of_expre)|Psub(aa,ws,len,x,e)->C.Psub(aa,ws,pos_of_intlen,cgvari_of_gvarix,cexpr_of_expre)|Pload(al,ws,e)->C.Pload(al,ws,cexpr_of_expre)|Papp1(o,e)->C.Papp1(o,cexpr_of_expre)|Papp2(o,e1,e2)->C.Papp2(o,cexpr_of_expre1,cexpr_of_expre2)|PappN(o,es)->C.PappN(o,List.map(cexpr_of_expr)es)|Pif(ty,e,e1,e2)->C.Pif(cty_of_tyty,cexpr_of_expre,cexpr_of_expre1,cexpr_of_expre2)letrecexpr_of_cexpr=function|C.Pconstz->Pconst(z_of_czz)|C.Pboolb->Pboolb|C.Parr_initn->Parr_init(int_of_posn)|C.Pvarx->Pvar(gvari_of_cgvarix)|C.Pget(al,aa,ws,x,e)->Pget(al,aa,ws,gvari_of_cgvarix,expr_of_cexpre)|C.Psub(aa,ws,len,x,e)->Psub(aa,ws,int_of_poslen,gvari_of_cgvarix,expr_of_cexpre)|C.Pload(al,ws,e)->Pload(al,ws,expr_of_cexpre)|C.Papp1(o,e)->Papp1(o,expr_of_cexpre)|C.Papp2(o,e1,e2)->Papp2(o,expr_of_cexpre1,expr_of_cexpre2)|C.PappN(o,es)->PappN(o,List.map(expr_of_cexpr)es)|C.Pif(ty,e,e1,e2)->Pif(ty_of_ctyty,expr_of_cexpre,expr_of_cexpre1,expr_of_cexpre2)(* ------------------------------------------------------------------------ *)letclval_of_lval=function|Lnone(loc,ty)->C.Lnone(loc,cty_of_tyty)|Lvarx->C.Lvar(cvari_of_varix)|Lmem(al,ws,loc,e)->C.Lmem(al,ws,loc,cexpr_of_expre)|Laset(al,aa,ws,x,e)->C.Laset(al,aa,ws,cvari_of_varix,cexpr_of_expre)|Lasub(aa,ws,len,x,e)->C.Lasub(aa,ws,pos_of_intlen,cvari_of_varix,cexpr_of_expre)letlval_of_clval=function|C.Lnone(loc,ty)->Lnone(loc,ty_of_ctyty)|C.Lvarx->Lvar(vari_of_cvarix)|C.Lmem(al,ws,loc,e)->Lmem(al,ws,loc,expr_of_cexpre)|C.Laset(al,aa,ws,x,e)->Laset(al,aa,ws,vari_of_cvarix,expr_of_cexpre)|C.Lasub(aa,ws,len,x,e)->Lasub(aa,ws,int_of_poslen,vari_of_cvarix,expr_of_cexpre)(* ------------------------------------------------------------------------ *)letclval_of_lvalsxs=List.map(clval_of_lval)xsletlval_of_clvalsxs=List.map(lval_of_clval)xsletcexpr_of_exprses=List.map(cexpr_of_expr)esletexpr_of_cexprses=List.map(expr_of_cexpr)es(* ------------------------------------------------------------------------ *)letreccinstr_of_instri=letn=i.i_loc,i.i_annotincinstr_r_of_instr_rni.i_descandcinstr_r_of_instr_rpi=matchiwith|Cassgn(x,t,ty,e)->letir=C.Cassgn(clval_of_lvalx,t,cty_of_tyty,cexpr_of_expre)inC.MkI(p,ir)|Copn(x,t,o,e)->letir=C.Copn(clval_of_lvalsx,t,o,cexpr_of_exprse)inC.MkI(p,ir)|Csyscall(x,o,e)->letir=C.Csyscall(clval_of_lvalsx,o,cexpr_of_exprse)inC.MkI(p,ir)|Cif(e,c1,c2)->letc1=cstmt_of_stmtc1inletc2=cstmt_of_stmtc2inletir=C.Cif(cexpr_of_expre,c1,c2)inC.MkI(p,ir)|Cfor(x,(d,e1,e2),c)->letd=((d,cexpr_of_expre1),cexpr_of_expre2)inletx=cvari_of_varixinletc=cstmt_of_stmtcinletir=C.Cfor(x,d,c)inC.MkI(p,ir)|Cwhile(a,c,e,(info,_),c')->letir=C.Cwhile(a,cstmt_of_stmtc,cexpr_of_expre,info,cstmt_of_stmtc')inC.MkI(p,ir)|Ccall(x,f,e)->letir=C.Ccall(clval_of_lvalsx,f,cexpr_of_exprse)inC.MkI(p,ir)andcstmt_of_stmtc=List.mapcinstr_of_instrcletrecinstr_of_cinstri=matchiwith|C.MkI(p,ir)->leti_loc,i_annot=pinleti_desc=instr_r_of_cinstr_ririn{i_desc;i_loc;i_info=();i_annot}andinstr_r_of_cinstr_r=function|C.Cassgn(x,t,ty,e)->Cassgn(lval_of_clvalx,t,ty_of_ctyty,expr_of_cexpre)|C.Copn(x,t,o,e)->Copn(lval_of_clvalsx,t,o,expr_of_cexprse)|C.Csyscall(x,o,e)->Csyscall(lval_of_clvalsx,o,expr_of_cexprse)|C.Cif(e,c1,c2)->letc1=stmt_of_cstmtc1inletc2=stmt_of_cstmtc2inCif(expr_of_cexpre,c1,c2)|Cfor(x,((d,e1),e2),c)->letd=(d,expr_of_cexpre1,expr_of_cexpre2)inletx=vari_of_cvarixinletc=stmt_of_cstmtcinCfor(x,d,c)|Cwhile(a,c,e,info,c')->Cwhile(a,stmt_of_cstmtc,expr_of_cexpre,(info,()),stmt_of_cstmtc')|Ccall(x,f,e)->Ccall(lval_of_clvalsx,f,expr_of_cexprse)andstmt_of_cstmtc=List.mapinstr_of_cinstrc(* ------------------------------------------------------------------------ *)letcufdef_of_fdeffd=letfn=fd.f_nameinletf_info=fd.f_loc,fd.f_annot,fd.f_cc,fd.f_ret_infoinletf_params=List.map(funx->cvari_of_vari(L.mk_locL._dummyx))fd.f_argsinletf_body=cstmt_of_stmtfd.f_bodyinletf_res=List.mapcvari_of_varifd.f_retinfn,{C.f_info=f_info;C.f_tyin=List.mapcty_of_tyfd.f_tyin;C.f_params=f_params;C.f_body=f_body;C.f_tyout=List.mapcty_of_tyfd.f_tyout;C.f_res=f_res;C.f_extra=();}letfdef_of_cufdef(fn,fd)=letf_loc,f_annot,f_cc,f_ret_info=fd.C.f_infoin{f_loc;f_annot;f_cc;f_info=();f_name=fn;f_tyin=List.mapty_of_ctyfd.C.f_tyin;f_args=List.map(funv->L.unloc(vari_of_cvariv))fd.C.f_params;f_body=stmt_of_cstmtfd.C.f_body;f_tyout=List.mapty_of_ctyfd.C.f_tyout;f_ret_info;f_ret=List.map(vari_of_cvari)fd.C.f_res;}letcgd_of_gd(x,gd)=(cvar_of_varx,gd)letgd_of_cgd(x,gd)=(var_of_cvarx,gd)letcuprog_of_progp=letfds=List.map(cufdef_of_fdef)(sndp)inletgd=List.map(cgd_of_gd)(fstp)in{C.p_globs=gd;C.p_funcs=fds;C.p_extra=()}letprog_of_cuprogp=List.map(gd_of_cgd)p.C.p_globs,List.map(fdef_of_cufdef)p.C.p_funcsletcsfdef_of_fdef((fe,fd):('info,'asm)sfundef)=letfn,fd=cufdef_of_fdeffdinfn,{fdwithC.f_extra=fe}letfdef_of_csfdef(fn,fd)=letfd'=fdef_of_cufdef(fn,fd)infd.C.f_extra,fd'letprog_of_csprogp=List.map(fdef_of_csfdef)p.C.p_funcs,p.C.p_extra(* ---------------------------------------------------------------------------- *)letto_arraytypt=letws,n=array_kindtyinletgeti=matchWarray_.WArray.getpAlignedWarray_.AAscalewst(cz_of_inti)with|Utils0.Okw->z_of_wordwsw|_->assertfalseinws,Array.initnget(* ---------------------------------------------------------------------------- *)(* This avoids printing dummy locations. Hope that it will not hide errors. *)letpatch_vi_loc(e:Compiler_util.pp_error_loc)=matche.Compiler_util.pel_viwith|None->e|Somevi->ifL.isdummyvithen{ewithCompiler_util.pel_vi=None}elsee(* do we want more complex logic, e.g. if both vi and ii are <> None,
we could check whether they point to the same line. If not, we could
decide to return both.
*)letiloc_of_loce=letopenUtilsinlete=patch_vi_loceinmatche.pel_viwith|Someloc->beginmatche.pel_iiwith|None->Loneloc|Some({L.stack_loc=locs;_},_)->(* if there are some locations coming from inlining, we print them *)Lmore(L.i_locloclocs)end|None->matche.pel_iiwith|Someii->leti_loc,_=iiinLmorei_loc|None->matche.pel_fiwith|Somefi->let(f_loc,_,_,_)=fiinLonef_loc|None->Lnone(* Converts a Coq error into an OCaml one.
We take as an argument the printer [pp_err] used to print the error message.
*)leterror_of_cerrorpp_erre=letopenUtilsinletmsg=Format.dprintf"%a"pp_erre.Compiler_util.pel_msginletiloc=iloc_of_loceinletfunname=Option.map(funfn->fn.fn_name)e.pel_fninletpass=e.pel_passin{err_msg=msg;err_loc=iloc;err_funname=funname;err_kind="compilation error";err_sub_kind=pass;err_internal=e.pel_internal;}(* -------------------------------------------------------------------------- *)letfresh_var_ident=letmemo=Hashtbl.create5infunr(i_loc,_)numnst->letk=(r,i_loc.L.uid_loc,num,n,st)inmatchHashtbl.findmemokwith|x->x|exceptionNot_found->letty=ty_of_ctystinletx=V.mknrtyi_loc.L.base_loc[]inHashtbl.addmemokx;x