123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233(******************************************************************************)(* 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. *)(******************************************************************************)openASTopenASTUtilsmoduletypeRunTimeConf=sigmoduleScope:Backend.SCOPEtypevvalunroll:intendmoduletypeS=sigtypevmoduleScope:Backend.SCOPEtypeglobal={static:StaticEnv.global;storage:vStorage.t;stack_size:Z.tIMap.t;}typelocaltypeenv={global:global;local:local}valto_static:env->StaticEnv.envvallocal_empty_scoped:?storage:vStorage.t->Scope.t->localvalglobal_from_static:?storage:vStorage.t->StaticEnv.global->globaltype'aenv_result=Localof'a|Globalof'a|NotFoundvalfind:identifier->env->venv_resultvalmem:identifier->env->boolvaldeclare_local:identifier->v->env->envvalassign_local:identifier->v->env->envvaldeclare_global:identifier->v->env->envvalassign_global:identifier->v->env->envvalremove_local:identifier->env->envvalassign:identifier->v->env->envenv_resultvaltick_push:env->envvaltick_push_bis:env->envvaltick_pop:env->envvaltick_decr:env->bool*envvalget_scope:env->Scope.tvalpush_scope:env->envvalpop_scope:env->env->envvalget_stack_size:identifier->env->Z.tvalincr_stack_size:identifier->global->globalvaldecr_stack_size:identifier->global->globalendmoduleRunTime(C:RunTimeConf)=structmoduleScope=C.Scopetypev=C.vtypeglobal={static:StaticEnv.global;storage:C.vStorage.t;stack_size:Z.tIMap.t;}typeint_stack=intlisttypelocal={storage:C.vStorage.t;scope:Scope.t;unroll:int_stack;declared:identifierlist;}typeenv={global:global;local:local}letlocal_empty_scoped?(storage=Storage.empty)scope={scope;storage;unroll=[];declared=[]}letglobal_from_static?(storage=Storage.empty)static={static;storage;stack_size=IMap.empty}letget_scopeenv=env.local.scopeletto_staticenv=letglobal=env.global.staticinStaticEnv.{emptywithglobal}(* --------------------------------------------------------------------------*)(* Loop unrolling controls. *)letset_unrollenvunroll={envwithlocal={env.localwithunroll}}(** [tick_push env] is [env] with [C.unroll] pushed on its unrolling stack. *)lettick_pushenv=set_unrollenv(C.unroll::env.local.unroll)(** [tick_push_bis env] is [env] with [C.unroll -1] pushed on its unrolling
stack. *)lettick_push_bisenv=set_unrollenv((C.unroll-1)::env.local.unroll)(** [tick_pop env] is [env] with removed the unrolling stack first element. *)lettick_popenv=matchenv.local.unrollwith|[]->assertfalse|_::unroll->set_unrollenvunroll(** [tick_decr env] decrements the unrolling stack of env and returns
wheather it has poped something or not. *)lettick_decrenv=matchenv.local.unrollwith|[]->assertfalse|x::xs->letx=x-1inifx<=0then(true,set_unrollenvxs)else(false,set_unrollenv(x::xs))(* --------------------------------------------------------------------------*)(* Retrieval utils *)type'aenv_result=Localof'a|Globalof'a|NotFound(* Begin SemanticsRule.EnvFind *)letfindxenv=tryLocal(Storage.findxenv.local.storage)withNot_found->(tryGlobal(Storage.findxenv.global.storage)withNot_found->NotFound)(* End *)letmemxenv=Storage.memxenv.local.storage||Storage.memxenv.global.storage(* --------------------------------------------------------------------------*)(* Assignments utils *)letdeclare_localxvenv={envwithlocal={env.localwithstorage=Storage.addxvenv.local.storage;declared=x::env.local.declared;};}letassign_localxvenv={envwithlocal={env.localwithstorage=Storage.assignxvenv.local.storage};}letdeclare_globalxvenv={envwithglobal={env.globalwithstorage=Storage.addxvenv.global.storage};}letassign_globalxvenv={envwithglobal={env.globalwithstorage=Storage.assignxvenv.global.storage};}letremove_localxenv={envwithlocal={env.localwithstorage=Storage.removexenv.local.storage;declared=List.filter(funs->not(String.equalsx))env.local.declared;};}letassignxvenv=tryLocal(assign_localxvenv)withNot_found->(tryGlobal(assign_globalxvenv)withNot_found->NotFound)(* --------------------------------------------------------------------------*)(* Scope swapping utils *)letpush_scopeenv={envwithlocal={env.localwithdeclared=[]}}letpop_scopeparentchild=letlocal_storage=Storage.patch_mem~t_env:parent.local.storage~t_mem:child.local.storagechild.local.declaredin{childwithlocal={parent.localwithstorage=local_storage}}letget_stack_sizenameenv=tryIMap.findnameenv.global.stack_sizewithNot_found->Z.zeroletset_stack_sizenamevalueglobal=letstack_size=IMap.addnamevalueglobal.stack_sizein{globalwithstack_size}letincr_stack_sizenameglobal=letprev=tryIMap.findnameglobal.stack_sizewithNot_found->Z.zeroinset_stack_sizename(Z.succprev)globalletdecr_stack_sizenameglobal=letprev=tryIMap.findnameglobal.stack_sizewithNot_found->assertfalseinassert(Z.signprev>0);set_stack_sizename(Z.predprev)globalend