123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124(******************************************************************************)(* ASLRef *)(******************************************************************************)(*
* SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
* SPDX-License-Identifier: BSD-3-Clause
*)(******************************************************************************)(* Disclaimer: *)(* This material covers both ASLv0 (viz, the existing ASL pseudocode language *)(* which appears in the Arm Architecture Reference Manual) and ASLv1, a new, *)(* experimental, and as yet unreleased version of ASL. *)(* This material is work in progress, more precisely at pre-Alpha quality as *)(* per Arm’s quality standards. *)(* In particular, this means that it would be premature to base any *)(* production tool development on this material. *)(* However, any feedback, question, query and feature request would be most *)(* welcome; those can be sent to Arm’s Architecture Formal Team Lead *)(* Jade Alglave <jade.alglave@arm.com>, or by raising issues or PRs to the *)(* herdtools7 github repository. *)(******************************************************************************)openASTUtilslet_runtime_assertions=truetypepointer=intmodulePMap=structmodulePM=Map.Make(Int)let[@warning"-32"]of_listli=List.fold_left(funacc(key,value)->PM.addkeyvalueacc)PM.emptyliincludePMendmodulePSet=Set.Make(Int)type'vt={env:pointerIMap.t;mem:'vPMap.t}letalloc=letnext=ref0infun()->letr=!nextinnext:=r+1;rletempty={env=IMap.empty;mem=PMap.empty}letmemxt=IMap.memxt.envletassignxvt=letp=IMap.findxt.envin{twithmem=PMap.addpvt.mem}letdeclarexvt=let()=if_runtime_assertions&&memxtthenlet()=Printf.eprintf"Storage element %s already declared in env.\n%!"xinassertfalseinletp=alloc()in{env=IMap.addxpt.env;mem=PMap.addpvt.mem}letof_v_mapmap=letmem_list=ref[]inletenv=IMap.map(funv->letp=alloc()inmem_list:=(p,v)::!mem_list;p)mapinletmem=PMap.of_list!mem_listin{env;mem}letaddxvt=tryassignxvtwithNot_found->declarexvtletfindxt=letp=IMap.findxt.envinPMap.findpt.memletfind_optxt=trySome(findxt)withNot_found->Noneletremovext=tryletp=IMap.findxt.envin{mem=PMap.removept.mem;env=IMap.removext.env}withNot_found->tletpatch_mem~t_env~t_memto_avoid=letenv=t_env.envandmem=tryList.fold_left(funmemx->letp=IMap.findxt_mem.envinPMap.removepmem)t_mem.memto_avoidwithNot_found->let()=Printf.eprintf"Bug in unsetting one of ";List.iter(funs->Printf.eprintf"%s, "s)to_avoid;Printf.eprintf"\n%!"inassertfalsein{env;mem}letto_seqt=IMap.to_seqt.env|>Seq.map(fun(name,pointer)->(name,PMap.findpointert.mem))letpp_printpp_elt=letopenFormatinletpp_sepf()=fprintff",@ "inletpp_onef(key,elt)=fprintff"@[<h 2>%s |-> @[%a@]@]"keypp_elteltinfunft->fprintff"@[<hv 2>{@ %a}@]"(PP.pp_print_seq~pp_seppp_one)(to_seqt)letmapft={twithmem=PMap.mapft.mem}