diff options
| author | Thomas Bauereiss | 2017-12-06 17:18:36 +0000 |
|---|---|---|
| committer | Thomas Bauereiss | 2017-12-06 17:18:36 +0000 |
| commit | 2bc281428a3a1d608d56f69e71b50056a25e3da0 (patch) | |
| tree | dfd8e8a13702696fd9daef64315952b9652f95e8 | |
| parent | c3c3c40a1d4f81448d8356317e88be2b04363df7 (diff) | |
| parent | 44e9396fa90ab68ee4c8d9674c6bbad6fc851c6d (diff) | |
Merge remote branch 'experiments' into experiments
199 files changed, 45208 insertions, 5606 deletions
diff --git a/arm/Makefile b/arm/Makefile index 18eba393..d7124df6 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -1,16 +1,5 @@ -BUILDDIR=./build - -SAIL=../sail -ifeq ("$(wildcard $(SAIL))","") - $(warning can not find Sail) -endif - -LEM=../../lem/lem -ifeq ("$(wildcard $(LEM))","") - $(warning can not find Lem) -endif - -LEMINTERPDIR=../src/lem_interp/ +SAIL:=../src/sail.native +LEM:=../../lem/lem # the order of the files is important SOURCES=armV8.h.sail\ @@ -23,39 +12,28 @@ SOURCES=armV8.h.sail\ armV8_A64_lib.sail\ armV8.sail -all: $(BUILDDIR)/armv8.ml - -clean: - rm -rf $(BUILDDIR) - -ocaml: $(BUILDDIR)/armv8_embed.ml +all: armV8.lem armV8.ml armV8_embed.lem -.PHONY: all clean ocaml +armV8.lem: $(SOURCES) + $(SAIL) -lem_ast -o armV8 $(SOURCES) -$(BUILDDIR): - mkdir -p $@ +armV8.ml: armV8.lem ../src/lem_interp/interp_ast.lem + $(LEM) -ocaml -lib ../src/lem_interp/ $< -$(BUILDDIR)/armv8.lem: $(SOURCES) | $(BUILDDIR) - $(SAIL) -lem_ast $(SOURCES) -o $(basename $@) -# sail generates the .lem file in pwd - mv $(notdir $@) $@ -$(BUILDDIR)/armv8.ml: $(BUILDDIR)/armv8.lem - $(LEM) -ocaml -lib $(LEMINTERPDIR) $< - -$(BUILDDIR)/armv8_embed.ml: $(SOURCES) | $(BUILDDIR) - $(SAIL) -ocaml $(SOURCES) -o $(basename $@) -# sail generates the .lem file in pwd - mv $(notdir $@) $@ +armV8_embed.lem: $(SOURCES) ../etc/regfp.sail aarch64_regfp.sail +# also generates armV8_embed_sequential.lem, armV8_embed_types.lem, armV8_toFromInterp.lem + $(SAIL) -lem -lem_lib ArmV8_extras_embed -o armV8 $^ +clean: + rm -f armV8.lem armV8.ml + rm -f armV8_embed*.lem armV8_toFromInterp.lem ###################################################################### ETCDIR=../etc apply_header: - -chmod u+w *.sail headache -c $(ETCDIR)/headache_config -h $(ETCDIR)/arm_header *.sail - chmod a-w *.sail .PHONY: apply_header @@ -63,10 +41,13 @@ apply_header: IDLARM=../../../rsem/idlarm pull_from_idlarm: - svn up $(IDLARM) - $(MAKE) -C $(IDLARM) - -chmod u+w *.sail + $(MAKE) -C $(IDLARM) clean + $(MAKE) -C $(IDLARM) san_sail rm -f *.sail cp -a $(IDLARM)/build/*.sail ./ - chmod a-w *.sail + cp -a $(IDLARM)/armV8_extras_embed.lem ./ + cp -a $(IDLARM)/armV8_extras_embed_sequential.lem ./ + cp -a $(IDLARM)/armV8_extras.lem ./ + mkdir -p gen + cp -a $(IDLARM)/*.hgen gen/ $(MAKE) apply_header diff --git a/arm/aarch64_regfp.sail b/arm/aarch64_regfp.sail new file mode 100644 index 00000000..148f9646 --- /dev/null +++ b/arm/aarch64_regfp.sail @@ -0,0 +1,598 @@ +(*========================================================================*) +(* *) +(* Copyright (c) 2015-2017 Shaked Flur *) +(* Copyright (c) 2015-2017 Kathyrn Gray *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(*========================================================================*) + +function instruction_kind rmem_kind ((AccType) acctype, (bool) exclusive) = + if exclusive then + switch acctype { + case AccType_ATOMIC -> IK_mem_read(Read_exclusive) + case AccType_ORDERED -> IK_mem_read(Read_exclusive_acquire) + case _ -> { not_implemented("unimplemented memory access"); + IK_mem_read(Read_exclusive); } + } + else + switch acctype { + case AccType_NORMAL -> IK_mem_read(Read_plain) + case AccType_ATOMIC -> IK_mem_read(Read_plain) + case AccType_STREAM -> IK_mem_read(Read_stream) + case AccType_UNPRIV -> IK_mem_read(Read_plain) + case AccType_ORDERED -> IK_mem_read(Read_acquire) + } + + +function instruction_kind wmem_kind ((AccType) acctype, (bool) exclusive) = + if exclusive then { + switch acctype { + case AccType_ATOMIC -> IK_mem_write(Write_exclusive) + case AccType_ORDERED -> IK_mem_write(Write_exclusive_release) + case _ -> { not_implemented("unimplemented memory access"); + IK_mem_write(Write_exclusive); } + } + } else { + switch acctype { + case AccType_NORMAL -> IK_mem_write(Write_plain) + case AccType_STREAM -> IK_mem_write(Write_plain) + case AccType_UNPRIV -> IK_mem_write(Write_plain) + case AccType_ORDERED -> IK_mem_write(Write_release) + case _ -> { not_implemented("unimplemented memory access"); + IK_mem_write(Write_plain) } + }; + } + + +let (vector<30,31,dec,string>) _Rs = + ["R30","R29","R28","R27","R26","R25","R24","R23","R22","R21", + "R20","R19","R18","R17","R16","R15","R14","R13","R12","R11", + "R10","R9" ,"R8" ,"R7" ,"R6" ,"R5" ,"R4" ,"R3" ,"R2" ,"R1" , + "R0"] + +let TxNestingLevelfp = RFull("TxNestingLevel") +let TXIDR_EL0_DEPTHfp = RField("TXIDR_EL0","DEPTH") + +let PSTATE_Nfp = RField("NZCV","N") +let PSTATE_Zfp = RField("NZCV","Z") +let PSTATE_Cfp = RField("NZCV","C") +let PSTATE_Vfp = RField("NZCV","V") +let PSTATE_Dfp = RField("DAIF","D") +let PSTATE_Afp = RField("DAIF","A") +let PSTATE_Ifp = RField("DAIF","I") +let PSTATE_Ffp = RField("DAIF","F") +let PSTATE_ELfp = RFull("CurrentEL") +let PSTATE_SPfp = RField("SPSel","SP") +let _PCfp = RFull("_PC") + +let NZCVfp = [|| PSTATE_Nfp, PSTATE_Zfp, PSTATE_Cfp, PSTATE_Vfp ||] + +function regfps xFP((reg_index) n) = + if n != 31 then [||RFull(_Rs[n])||] else [|| ||] + + +(* check if this is still what we want *) +function forall Nat 'N, 'N IN {32,64}. (regfps,regfps) BranchToFP (iR,oR) = + (if UsingAArch32() then iR else PSTATE_ELfp :: iR, _PCfp :: oR) + +function regfps ConditionHoldsIFP((bit[4]) _cond) = + switch _cond[3..1] { + case 0b000 -> [|| PSTATE_Zfp ||] + case 0b001 -> [|| PSTATE_Cfp ||] + case 0b010 -> [|| PSTATE_Nfp ||] + case 0b011 -> [|| PSTATE_Vfp ||] + case 0b100 -> [|| PSTATE_Cfp, PSTATE_Zfp ||] + case 0b101 -> [|| PSTATE_Nfp, PSTATE_Vfp ||] + case 0b110 -> [|| PSTATE_Nfp, PSTATE_Vfp, PSTATE_Zfp ||] + case 0b111 -> [|| ||] + } + +(* for iR if rSPFP, for oR if wSPFP *) +let rSPIFP = + (* TODO: actually this depends on runtime data: PSTATE_SP and PSTATE_EL *) + [|| PSTATE_SPfp, RFull("SP_EL0") ||] + +let wSPFP = + (* TODO: actually this depends on runtime data: PSTATE_SP and PSTATE_EL *) + ([|| PSTATE_SPfp ||], + [|| RFull("SP_EL0") ||]) + + +let CheckSPAlignmentIFP = PSTATE_ELfp :: rSPIFP + +let BigEndianIFP = + if UsingAArch32() then [|| RFull("PSTATE_E") ||] else [|| PSTATE_ELfp ||] + +let wMem'IFP = BigEndianIFP +let wMemIFP = wMem'IFP + +function (regfps,regfps,regfps,niafps,diafp,instruction_kind) effect pure initial_analysis (instr) = { + iR := [|| ||]; + oR := [|| ||]; + aR := [|| ||]; + Nias := [|| NIAFP_successor ||]; + Dia := DIAFP_none; + ik := IK_simple; + + switch instr { + case (TMStart(t)) -> { + iR := TxNestingLevelfp :: TXIDR_EL0_DEPTHfp :: iR; + (* TODO: whether the following applies depends on runtime data: + ~(TxNestingLevel >= TXIDR_EL0.DEPTH) *) + oR := TxNestingLevelfp :: append(oR,xFP(t)); + ik := IK_trans(Transaction_start); + } + case (TMCommit) -> { + iR := TxNestingLevelfp :: iR; + oR := TxNestingLevelfp :: oR; + ik := IK_trans(Transaction_commit); + } + case (TMAbort(retry,reason)) -> { + iR := TxNestingLevelfp :: iR; + ik := IK_trans(Transaction_abort); + } + case (TMTest) -> { + iR := TxNestingLevelfp :: iR; + oR := RFull("NZCV") :: oR; + } + case (CompareAndBranch(t,datasize,iszero,offset)) -> { + iR := append(iR,xFP(t)); + (* TODO: whether the following applies depends on runtime data: + IsZero(operand1) *) + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + (bit[64]) nia' := rPC() + offset; + Nias := [|| NIAFP_successor, NIAFP_concrete_address(nia') ||]; + ik := IK_cond_branch; + } + case (BranchConditional(offset,condition)) -> { + iR := append(iR,ConditionHoldsIFP(condition)); + (* TODO: whether the following applies depends on runtime data: + ConditionHolds(condition) *) + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + Nias := [|| NIAFP_successor, NIAFP_concrete_address(rPC() + offset) ||]; + ik := IK_cond_branch; + } + case (GenerateExceptionEL1(imm)) -> not_implemented("GenerateExceptionEL1") + case (GenerateExceptionEL2(imm)) -> not_implemented("GenerateExceptionEL2") + case (GenerateExceptionEL3(imm)) -> not_implemented("GenerateExceptionEL3") + case (DebugBreakpoint(comment)) -> not_implemented("DebugBreakpoint") + case (ExternalDebugBreakpoint) -> not_implemented("ExternalDebugBreakpoint") + case (DebugSwitchToExceptionLevel(target_level)) -> not_implemented("DebugSwitchToExceptionLevel") + case (MoveSystemImmediate(operand,field)) -> + switch field { + case PSTATEField_SP -> oR := PSTATE_SPfp :: oR + case PSTATEField_DAIFSet -> { + iR := append(iR, [|| PSTATE_Dfp, PSTATE_Afp, PSTATE_Ifp, PSTATE_Ffp ||]); + oR := append(oR, [|| PSTATE_Dfp, PSTATE_Afp, PSTATE_Ifp, PSTATE_Ffp ||]); + } + case PSTATEField_DAIFClr -> { + iR := append(iR, [|| PSTATE_Dfp, PSTATE_Afp, PSTATE_Ifp, PSTATE_Ffp ||]); + oR := append(oR, [|| PSTATE_Dfp, PSTATE_Afp, PSTATE_Ifp, PSTATE_Ffp ||]); + } + } + case (Hint(op)) -> + switch op { + case SystemHintOp_YIELD -> () + case SystemHintOp_WFE -> { + if EventRegistered() then () (* ClearEventRegister *) + else { + (* the execute code for this case always fails because of + WaitForEvent, declared as extern but not defined *) + not_implemented("Hint(SystemHintOp_WFE);") + } + } + case SystemHintOp_WFI -> { + (* the execute code for this case always fails because of + InterruptPending, declared as extern but not defined *) + not_implemented("Hint(SystemHintOp_WFI);") + } + case SystemHintOp_SEV -> () (*SendEvent*) + case SystemHintOp_SEVL -> + (* the execute code for this case always fails because of + EventRegisterSet, declared as extern but not defined *) + not_implemented("Hint(SystemHintOp_SEVL);") + case _ -> () (* do nothing *) + } + case (ClearExclusiveMonitor(imm)) -> () (*ClearExclusiveLocal*) + case (Barrier(op,domain,types)) -> { + ik := switch op { + case MemBarrierOp_DSB -> + switch types { + case MBReqTypes_Reads -> IK_barrier(Barrier_DSB_LD) + case MBReqTypes_Writes -> IK_barrier(Barrier_DSB_ST) + case MBReqTypes_All -> IK_barrier(Barrier_DSB) + } + case MemBarrierOp_DMB -> + switch types { + case MBReqTypes_Reads -> IK_barrier(Barrier_DMB_LD) + case MBReqTypes_Writes -> IK_barrier(Barrier_DMB_ST) + case MBReqTypes_All -> IK_barrier(Barrier_DMB) + } + case MemBarrierOp_ISB -> + IK_barrier(Barrier_ISB) + }; + } + case (System(t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,has_result)) -> { + oR := append(oR,xFP(t)); + not_implemented("System"); (* because SysOp_R and SysOp_W *) + } + case (MoveSystemRegister(t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read)) -> { + if read then { + oR := append(oR,xFP(t)); + switch (sys_op0,sys_op1,sys_crn,sys_crm,sys_op2) { (* System_Get *) + case (3,3,4,2,0) -> iR := RFull("NZCV") :: iR + case (3,3,4,2,1) -> iR := RFull("DAIF") :: iR + case (3, 3, 13, 0, 2) -> iR := RFull("TPIDR_EL0") :: iR + (* TODO FIXME: higher EL TPIDRs *) + } + } + else { + iR := append(iR,xFP(t)); + switch (sys_op0,sys_op1,sys_crn,sys_crm,sys_op2) { (* System_Put *) + case (3,3,4,2,0) -> oR := RFull("NZCV") :: oR + case (3,3,4,2,1) -> oR := RFull("DAIF") :: oR + case (3, 3, 13, 0, 2) -> oR := RFull("TPIDR_EL0") :: oR + (* TODO FIXME: higher EL TPIDRs *) + } + } + } + case (ImplementationDefinedTestBeginEnd(isEnd)) -> () + case (ImplementationDefinedStopFetching) -> () + case (ImplementationDefinedThreadStart) -> () + case (TestBitAndBranch(t,datasize,bit_pos,bit_val,offset)) -> { + iR := append(xFP(t),iR); + (* TODO: whether the following applies depends on runtime data: + operand[bit_pos] == bit_val *) + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + Nias := [|| NIAFP_successor, NIAFP_concrete_address(rPC() + offset) ||]; + ik := IK_cond_branch; + } + case (BranchImmediate(branch_type,offset)) -> { + if branch_type == BranchType_CALL + then {iR := _PCfp :: iR; oR := append(xFP(30),oR)}; + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + Nias := [|| NIAFP_concrete_address(rPC() + offset) ||]; + ik := IK_simple (* IK_uncond_branch *) + } + case (BranchRegister(n,branch_type)) -> { + iR := append(iR,xFP(n)); + if branch_type == BranchType_CALL + then {iR := _PCfp :: iR; oR := append(xFP(30),oR)}; + let (i,o) = BranchToFP(iR,oR) in {iR := i; oR := o}; + Nias := if n ==31 + then [|| NIAFP_concrete_address(0) ||] + else [|| NIAFP_register(RFull(_Rs[n]))||]; + ik := IK_simple (* IK_uncond_branch *) + } + case (ExceptionReturn) -> not_implemented("ExceptionReturn") + case (DebugRestorePState) -> not_implemented("DebugRestorePState") + case (LoadLiteral(t,memop,_signed,size,offset,datasize)) -> { + (* assuming rMem doesn't touch other registers *) + iR := _PCfp :: iR; + oR := append(xFP(t),oR); + aR := _PCfp :: aR; + switch memop { + case MemOp_LOAD -> ik := IK_mem_read(Read_plain) + case MemOp_PREFETCH -> {ik := IK_simple; aR := [|| ||]} + } + } + case (LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize)) -> { + (boolean) rt_unknown := false; + (boolean) rn_unknown := false; + if n==31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else if rn_unknown then () + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown then () + else if pair then iR := append(xFP(t),append(xFP(t2),iR)) + else iR := append(xFP(t),iR); + if excl then { + (* TODO: the command below depends on runtime data: + AArch64_ExclusiveMonitorsPass(address, dbytes) *) + iR := append(iR,wMemIFP); + oR := append(xFP(s),oR); + ik := wmem_kind(acctype,true); + } + else { + iR := append(iR,wMemIFP); + ik := wmem_kind(acctype,false); + } + } + case MemOp_LOAD -> { + if pair then { + if rt_unknown then + oR := append(xFP(t),oR) + else if elsize == 32 then { + iR := append(iR,BigEndianIFP); + oR := append(xFP(t),append(xFP(t2),oR)); + } + else { + oR := append(xFP(t),append(xFP(t2),oR)) + }; + ik := rmem_kind(acctype,true); + } + else { + oR := append(xFP(t),oR); + ik := rmem_kind(acctype,excl); + } + + } + case MemOp_PREFETCH -> aR := [|| ||] + } + } + case (LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,memop,scale,datasize,offset)) -> { + (boolean) rt_unknown := false; + if n == 31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + if wback then { + if n == 31 then + let (i,o) = wSPFP in { + iR := append(i,iR); + oR := append(o,oR); + } + else + oR := append(xFP(n),oR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown & t == n then () + else iR := append(xFP(t),iR); + if rt_unknown & t2 == n then () + else iR := append(xFP(t2),iR); + iR := append(wMemIFP,iR); + ik := wmem_kind(acctype,false); + } + case MemOp_LOAD -> { + oR := append(xFP(t),append(xFP(t2),oR)); + ik := rmem_kind(acctype,false); + } + } + } + case (LoadImmediate(n,t,acctype,memop,_signed,wback,postindex,offset,regsize,datasize)) -> { + (boolean) wb_unknown := false; + (boolean) rt_unknown := false; + if n == 31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + if wback then { + if n == 31 then + let (i,o) = wSPFP in {iR := append(i,iR); oR := append(o,oR)} + else oR := append(xFP(n),oR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown then () + else iR := append(xFP(t),iR); + iR := append(wMemIFP,iR); + ik := wmem_kind(acctype,false); + } + case MemOp_LOAD -> { + oR := append(xFP(t),oR); + ik := rmem_kind(acctype,false); + } + case MemOp_PREFETCH -> aR := [|| ||] + } + } + case (LoadRegister(n,t,m,acctype,memop,_signed,wback,postindex,extend_type,shift,regsize,datasize)) -> { + iR := append(xFP(m),iR); + aR := append(xFP(m),aR); + (boolean) wb_unknown := false; + (boolean) rt_unknown := false; + if n == 31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + if wback then { + if n == 31 then let (i,o) = wSPFP in {iR := append(i,iR); oR := append(o,oR)} + else oR := append(xFP(n),oR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown then () + else iR := append(xFP(t),iR); + iR := append(wMemIFP,iR); + ik := wmem_kind(acctype,false); + } + case MemOp_LOAD -> { + oR := append(xFP(t),oR); + ik := rmem_kind(acctype,false); + } + case MemOp_PREFETCH -> aR := [|| ||] + } + } + case (LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,datasize,offset)) -> { + (boolean) rt_unknown := false; + (boolean) wb_unknown := false; + if n == 31 then { + iR := append(CheckSPAlignmentIFP,iR); + iR := append(rSPIFP,iR); + aR := append(rSPIFP,aR); + } + else { + iR := append(xFP(n),iR); + aR := append(xFP(n),aR); + }; + if wback then { + if n == 31 then let (i,o) = wSPFP in {iR := append(i,iR); oR := append(o,oR)} + else oR := append(xFP(n),oR); + }; + switch memop { + case MemOp_STORE -> { + if rt_unknown & t == n then () + else iR := append(xFP(t),iR); + if rt_unknown & t2 == n then () + else iR := append(xFP(t2),iR); + iR := append(wMemIFP,iR); + ik := wmem_kind(acctype,false); + } + case MemOp_LOAD -> { + oR := append(xFP(t),oR); + oR := append(xFP(t2),oR); + ik := rmem_kind(acctype,false); + } + } + } + case (AddSubImmediate(d,n,datasize,sub_op,setflags,imm)) -> { + iR := append(if n == 31 then rSPIFP else xFP(n),iR); + if setflags then oR := append(NZCVfp,oR); + if d ==31 & ~(setflags) then + let (i,o) = wSPFP in + { iR := append(i,iR); + oR := append(o,oR) } + else oR := append(xFP(d),oR) + } + case (BitfieldMove(d,n,datasize,inzero,extend,R,S,wmask,tmask)) -> { + if inzero then () else iR:= append(xFP(d),iR); + iR := append(xFP(n),iR); + oR := append(xFP(d),oR); + } + case (ExtractRegister(d,n,m,datasize,lsb)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + oR := append(xFP(d),oR); + } + case (LogicalImmediate(d,n,datasize,setflags,op,imm)) -> { + iR := append(xFP(n),iR); + if setflags then oR := append(NZCVfp,oR); + if d ==31 & ~(setflags) then let (i,o) = wSPFP in + { iR := append(i,iR); oR := append(o,oR) } + else oR := append(xFP(d),oR) + } + case (MoveWide(d,datasize,imm,pos,opcode)) -> { + if opcode == MoveWideOp_K then iR := append(xFP(d),iR); + oR := append(xFP(d),oR); + } + case (Address(d,page,imm)) -> { + iR := _PCfp :: iR; + oR := append(xFP(d),oR); + } + case (AddSubExtendRegister(d,n,m,datasize,sub_op,setflags,extend_type,shift)) -> { + iR := append(if n == 31 then rSPIFP else xFP(n),iR); + iR := append(xFP(m),iR); + if setflags then oR := append(NZCVfp,oR); + if d ==31 & ~(setflags) then let (i,o) = wSPFP in + { iR := append(i,iR); oR := append(o,oR) } + else oR := append(xFP(d),oR) + } + case (AddSubShiftedRegister(d,n,m,datasize,sub_op,setflags,shift_type,shift_amount)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + if setflags then oR := append(NZCVfp,oR); + oR := append(xFP(d),oR); + } + case (AddSubCarry(d,n,m,datasize,sub_op,setflags)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + iR := PSTATE_Cfp :: iR; + if setflags then oR := append(NZCVfp,oR); + oR := append(xFP(d),oR); + } + case (ConditionalCompareImmediate(n,datasize,sub_op,condition,flags,imm)) -> { + iR := append(xFP(n),iR); + iR := append(ConditionHoldsIFP(condition),iR); + oR := append(NZCVfp,oR); + } + case (ConditionalCompareRegister(n,m,datasize,sub_op,condition,flags)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + iR := append(ConditionHoldsIFP(condition),iR); + oR := append(NZCVfp,oR); + } + case (ConditionalSelect(d,n,m,datasize,condition,else_inv,else_inc)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + iR := append(ConditionHoldsIFP(condition),iR); + oR := append(xFP(d),oR); + } + case (Reverse(d,n,datasize,op)) -> { + iR := append(xFP(n),iR); + oR := append(xFP(d),oR); + } + case (CountLeading(d,n,datasize,opcode)) -> { + iR := append(xFP(n),iR); + oR := append(xFP(d),oR); + } + case (Division(d,n,m,datasize,_unsigned)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + oR := append(xFP(d),oR); + } + case (Shift(d,n,m,datasize,shift_type)) -> { + iR := append(xFP(m),iR); + iR := append(xFP(n),iR); + oR := append(xFP(d),oR); + } + case (CRC(d,n,m,size,crc32c)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + oR := append(xFP(d),oR); + } + case (MultiplyAddSub(d,n,m,a,destsize,datasize,sub_op)) -> { + iR := append(xFP(n),iR); + iR := append(xFP(m),iR); + iR := append(xFP(a),iR); + oR := append(xFP(d),oR); + } + case (MultiplyAddSubLong(d,n,m,a,destsize,datasize,sub_op,_unsigned)) -> { + iR := append(xFP(n),iR); + iR := append(xFP(m),iR); + iR := append(xFP(a),iR); + oR := append(xFP(d),oR); + } + case (MultiplyHigh(d,n,m,a,destsize,datasize,_unsigned)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + oR := append(xFP(d),oR); + } + case (LogicalShiftedRegister(d,n,m,datasize,setflags,op,shift_type,shift_amount,invert)) -> { + iR := append(xFP(n),append(xFP(m),iR)); + if setflags then oR := append(NZCVfp,oR); + oR := append(xFP(d),oR); + } + }; + (iR,oR,aR,Nias,Dia,ik) +} diff --git a/arm/armV8.h.sail b/arm/armV8.h.sail index c788855a..9105f964 100644 --- a/arm/armV8.h.sail +++ b/arm/armV8.h.sail @@ -43,6 +43,27 @@ typedef SIMD_index = [|32|] register (bit[64]) _PC +(* transactional memory registers *) +register (bit[8]) TxNestingLevel (* same size as TXIDR_EL0.DEPTH *) + +typedef TMSTATUS_type = register bits [63:0] +{ + (*63..17 : RES0;*) + 16 : IMP; + 15 : DBG; + 14 : MEM; + 13 : ERR; + 12 : INV; + 11 : SIZE; + 10 : NEST; + 9 : ABRT; + 8 : RTRY; + (*7..5 : RES0*) + 4..0 : REASON; +} +register (TMSTATUS_type) TMAbortEffect (* we abuse the register write to pass out the status value *) +register (TMSTATUS_type) TMStartEffect (* we abuse the register read to pass in the status value *) + (* General purpose registers *) register (bit[64]) R30 @@ -170,3 +191,6 @@ let IMPLEMENTATION_DEFINED = (* FIXME: ask Kathy what should we do with this *) let UNKNOWN = 0 + + +val extern unit -> bool effect {exmem} speculate_exclusive_success diff --git a/arm/armV8.sail b/arm/armV8.sail index 10c57d1e..2614c7a5 100644 --- a/arm/armV8.sail +++ b/arm/armV8.sail @@ -40,6 +40,12 @@ typedef ast = const union forall Nat 'R, 'R IN {32, 64}, (* register size *) ImplementationDefinedStopFetching; ImplementationDefinedThreadStart; + (* transactional memory, from the pre-alpha document *) + (reg_index) TMStart; + TMCommit; + (boolean,bit[5]) TMAbort; + TMTest; + (reg_index,[:'R:],boolean,bit[64]) CompareAndBranch; (bit[64],bit[4]) BranchConditional; (bit[16]) GenerateExceptionEL1; (* TODO: add to .hgen *) @@ -64,7 +70,7 @@ typedef ast = const union forall Nat 'R, 'R IN {32, 64}, (* register size *) (boolean,boolean,reg_index,reg_index,reg_index,AccType,MemOp,uinteger,[:'D:],bit[64]) LoadStorePairNonTemp; (reg_index,reg_index,AccType,MemOp,boolean,boolean,boolean,bit[64],[:'R:],[:'D:]) LoadImmediate; (reg_index,reg_index,reg_index,AccType,MemOp,boolean,boolean,boolean,ExtendType,uinteger,[:'R:],[:'D:]) LoadRegister; - (boolean,boolean,reg_index,reg_index,reg_index,AccType,MemOp,boolean,uinteger,[:'D:],bit[64]) LoadStorePair; + (boolean,boolean,reg_index,reg_index,reg_index,AccType,MemOp,boolean,[:'D:],bit[64]) LoadStorePair; (reg_index,reg_index,[:'R:],boolean,boolean,bit['R]) AddSubImmediate; (reg_index,reg_index,[:'R:],boolean,boolean,uinteger,uinteger,bit['R],bit['R]) BitfieldMove; (reg_index,reg_index,reg_index,[:'R:],uinteger) ExtractRegister; @@ -86,12 +92,91 @@ typedef ast = const union forall Nat 'R, 'R IN {32, 64}, (* register size *) (reg_index,reg_index,reg_index,reg_index,[:'R:],[:'D:],boolean,boolean) MultiplyAddSubLong; (reg_index,reg_index,reg_index,reg_index,[:'R:],[:'D:],boolean) MultiplyHigh; (reg_index,reg_index,reg_index,[:'R:],boolean,LogicalOp,ShiftType,[|63|],boolean) LogicalShiftedRegister; - } -val forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. ast<'R,'D> -> unit effect {rreg,wreg,rmem,barr,eamem,wmv,escape} execute +val forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. ast<'R,'D> -> unit effect {rreg,wreg,rmem,barr,eamem,wmv,exmem,escape} execute scattered function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. unit execute +(* TSTART - dummy decoding *) +function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. + option<(ast<'R,'D>)> effect pure decodeTMStart ((bit[5]) Rt) = +{ + (reg_index) t := UInt_reg(Rt); + + Some(TMStart(t)); +} + +(* transactional memory, from the pre-alpha document *) +function clause execute (TMStart(t)) = { + (bit[8]) nesting := TxNestingLevel; + + if nesting <_u TXIDR_EL0.DEPTH then { + TxNestingLevel := nesting + 1; + (bit[64]) status := 0; + if nesting == 0 then + status := TMStartEffect; (* fake effect *) + wX(t) := status; + } else { + (bit[64]) status := 0; + status[10] := 1; (* set the NEST bit *) + TMAbortEffect := status; (* fake effect *) + } +} + +val extern unit -> unit effect {barr} TMCommitEffect + +(* TCOMMIT - dummy decoding *) +function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. + option<(ast<'R,'D>)> effect pure decodeTMCommit () = +{ + Some(TMCommit); +} + +(* transactional memory, from the pre-alpha document *) +function clause execute (TMCommit) = { + (bit[8]) nesting := TxNestingLevel; + + if nesting == 1 then + TMCommitEffect() (* fake effect *) + else if nesting == 0 then + AArch64_UndefinedFault(); + + TxNestingLevel := nesting - 1; +} + +(* TTEST - dummy decoding *) +function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. + option<(ast<'R,'D>)> effect pure decodeTMTest () = +{ + Some(TMTest); +} + +(* transactional memory, from the pre-alpha document *) +function clause execute (TMTest) = { + if TxNestingLevel > 0 then + wPSTATE_NZCV() := 0b0000 + else + wPSTATE_NZCV() := 0b0100 +} + +(* TABORT - dummy decoding *) +function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. + option<(ast<'R,'D>)> effect pure decodeTMAbort ([R]:(bit[5]) imm5) = +{ + Some(TMAbort(R,imm5)); +} + +(* transactional memory, from the pre-alpha document *) +function clause execute (TMAbort(retry,reason)) = { + if TxNestingLevel > 0 then { + (bit[64]) status := 0; + status[4..0] := reason; (* REASON *) + status[8] := retry; (* RTRY *) + status[9] := 1; (* ABRT *) + TMAbortEffect := status; (* fake effect *) + }; +} + (* CBNZ *) (* CBZ *) function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. @@ -517,16 +602,16 @@ function clause execute ( TestBitAndBranch(t,datasize,bit_pos,bit_val,offset) ) (* BL *) function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. option<(ast<'R,'D>)> effect {escape} decodeUnconditionalBranchImmediate ([op]:0b00101:(bit[26]) imm26) = { - (BranchType) _branch_type := if op == 1 then BranchType_CALL else BranchType_JMP; + (BranchType) branch_type := if op == 1 then BranchType_CALL else BranchType_JMP; (bit[64]) offset := SignExtend(imm26:0b00); - Some(BranchImmediate(_branch_type,offset)); + Some(BranchImmediate(branch_type,offset)); } -function clause execute (BranchImmediate(_branch_type,offset)) = { - if _branch_type == BranchType_CALL then wX(30) := rPC() + 4; +function clause execute (BranchImmediate(branch_type,offset)) = { + if branch_type == BranchType_CALL then wX(30) := rPC() + 4; - BranchTo(rPC() + offset, _branch_type); + BranchTo(rPC() + offset, branch_type); } @@ -540,24 +625,24 @@ scattered function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. (* RET *) function clause decodeUnconditionalBranchRegister (0b1101011:0b00:op:0b11111:0b000000:Rn:0b00000) = { (reg_index) n := UInt_reg(Rn); - (BranchType) _branch_type := 0; (* ARM: uninitialized *) + (BranchType) branch_type := 0; (* ARM: uninitialized *) switch op { - case 0b00 -> _branch_type := BranchType_JMP - case 0b01 -> _branch_type := BranchType_CALL - case 0b10 -> _branch_type := BranchType_RET + case 0b00 -> branch_type := BranchType_JMP + case 0b01 -> branch_type := BranchType_CALL + case 0b10 -> branch_type := BranchType_RET case _ -> UnallocatedEncoding() }; - Some(BranchRegister(n,_branch_type)); + Some(BranchRegister(n,branch_type)); } -function clause execute (BranchRegister(n,_branch_type)) = +function clause execute (BranchRegister(n,branch_type)) = { (bit[64]) target := rX(n); - if _branch_type == BranchType_CALL then wX(30) := rPC() + 4; - BranchTo(target, _branch_type); + if branch_type == BranchType_CALL then wX(30) := rPC() + 4; + BranchTo(target, branch_type); } (* ERET *) @@ -717,7 +802,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. Some(LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize)); } -function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) ) = { +function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,([:'D:]) datasize) ) = { (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data := 0; (* ARM: uninitialized *) (*constant*) (uinteger) dbytes := datasize quot 8; @@ -760,6 +845,19 @@ function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsiz }; }; + (* this is a hack to allow the result of store-exclusive to be observed + before anything else *) + (bit) status := 0; + if memop == MemOp_STORE & excl then { + (*(bit)*) status := if speculate_exclusive_success() then 0 else 1; + wX(s) := (bit[32]) (ZeroExtend([status])); + + (* should be: + if status == 1 then return (); + *) + }; + if status == 1 then () else { + if n == 31 then { CheckSPAlignment(); address := rSP(); @@ -781,7 +879,7 @@ function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsiz (bit['R]) el2 := rX(t2); (* ARM: bit[datasize / 2] see lemma in the decoding *) data := if BigEndian() then el1:el2 else el2:el1; } else - data := rX(t); + (bit['D]) data := rX(t); if excl then { (* store {release} exclusive register|pair (atomic) *) @@ -798,7 +896,9 @@ function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsiz wMem_exclusive(empty_write_buffer, address, dbytes, acctype, data) ); }; + (* ARM: the following code was moved up, see note there wX(s) := (bit[32]) (ZeroExtend([status])); + *) } else { (* store release register (atomic) *) flush_write_buffer( @@ -860,6 +960,7 @@ function clause execute ( LoadStoreAcqExc(n,t,t2,s,acctype,excl,pair,memop,elsiz }; } }; + }; } (* LDNP *) @@ -885,7 +986,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. Some(LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,memop,scale,datasize,offset)); } -function clause execute ( LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,memop,scale,datasize,offset) ) = { +function clause execute ( LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,memop,scale,([:'D:]) datasize,offset) ) = { (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data1 := 0; (* ARM: uninitialized *) (bit['D]) data2 := 0; (* ARM: uninitialized *) @@ -930,11 +1031,11 @@ function clause execute ( LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,me switch memop { case MemOp_STORE -> { if rt_unknown & t == n then - date1 := (bit['D]) UNKNOWN + data1 := (bit['D]) UNKNOWN else data1 := rX(t); if rt_unknown & t2 == n then - date2 := (bit['D]) UNKNOWN + data2 := (bit['D]) UNKNOWN else data2 := rX(t2); @@ -951,7 +1052,7 @@ function clause execute ( LoadStorePairNonTemp(wback,postindex,n,t,t2,acctype,me data2 := read_data[((datasize * 2) - 1)..datasize]; if rt_unknown then { - date1 := (bit['D]) UNKNOWN; + data1 := (bit['D]) UNKNOWN; data2 := (bit['D]) UNKNOWN; }; wX(t) := data1; @@ -1028,7 +1129,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. sharedDecodeLoadImmediate(opc,size,Rn,Rt,wback,postindex,scale,offset,AccType_NORMAL,false); } -function clause execute ( LoadImmediate(n,t,acctype,memop,_signed,wback,postindex,offset,regsize,datasize) ) = { +function clause execute ( LoadImmediate(n,t,acctype,memop,_signed,wback,postindex,offset,regsize,([:'D:]) datasize) ) = { (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data := 0; (* ARM: uninitialized *) (boolean) wb_unknown := false; @@ -1191,7 +1292,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. sharedDecodeLoadRegister(Rn,Rt,Rm,opc,size,wback,postindex,scale,extend_type,shift); } -function clause execute ( LoadRegister(n,t,m,acctype,memop,_signed,wback,postindex,extend_type,shift,regsize,datasize) ) = { +function clause execute ( LoadRegister(n,t,m,acctype,memop,_signed,wback,postindex,extend_type,shift,regsize,([:'D:]) datasize) ) = { (bit[64]) offset := ExtendReg(m, extend_type, shift); (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data := 0; (* ARM: uninitialized *) @@ -1352,7 +1453,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. ([:'D:]) datasize := lsl(8, scale); (bit[64]) offset := LSL(SignExtend(imm7), scale); - Some(LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,scale,datasize,offset)); + Some(LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,datasize,offset)); } (* LDP signed offset *) @@ -1367,7 +1468,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. sharedDecodeLoadStorePair(L,opc,imm7,Rn,Rt,Rt2,wback,postindex); } -function clause execute ( LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,scale,datasize,offset) ) = { +function clause execute ( LoadStorePair(wback,postindex,n,t,t2,acctype,memop,_signed,([:'D:])datasize,offset) ) = { (bit[64]) address := 0; (* ARM: uninitialized *) (bit['D]) data1 := 0; (* ARM: uninitialized *) (bit['D]) data2 := 0; (* ARM: uninitialized *) @@ -1616,7 +1717,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. Some(ExtractRegister(d,n,m,datasize,lsb)); } -function clause execute ( ExtractRegister(d,n,m,datasize,lsb) ) = { +function clause execute ( ExtractRegister(d,n,m,([:'R:]) datasize,lsb) ) = { (bit['R]) result := 0; (* ARM: uninitialized *) (bit['R]) operand1 := rX(n); (bit['R]) operand2 := rX(m); @@ -1650,7 +1751,7 @@ function forall Nat 'R, 'R IN {32,64}, Nat 'D, 'D IN {8,16,32,64}. Some(LogicalImmediate(d,n,datasize,setflags,op,imm)); }} -function clause execute (LogicalImmediate(d,n,datasize,setflags,op,imm)) = { +function clause execute (LogicalImmediate(d,n,([:'R:]) datasize,setflags,op,imm)) = { (bit['R]) result := 0; (* ARM: uninitialized *) (bit['R]) operand1 := rX(n); (bit['R]) operand2 := imm; diff --git a/arm/armV8_A64_lib.sail b/arm/armV8_A64_lib.sail index 5a1b6ec3..2aa31d4f 100644 --- a/arm/armV8_A64_lib.sail +++ b/arm/armV8_A64_lib.sail @@ -730,6 +730,8 @@ function bit[64] System_Get((uinteger) op0, (uinteger) op1, (uinteger) crn, (uin switch (op0,op1,crn,crm,op2) { case (3,3,4,2,0) -> ZeroExtend(NZCV) case (3,3,4,2,1) -> ZeroExtend(DAIF) + case (3, 3, 13, 0, 2) -> TPIDR_EL0 + (* TODO FIXME: higher EL TPIDRs *) (* case (3,0,1,0,1) -> ZeroExtend(ACTLR_EL1) *) } @@ -741,6 +743,8 @@ function unit effect {wreg} System_Put((uinteger) op0, (uinteger) op1, (uinteger switch (op0,op1,crn,crm,op2) { case (3,3,4,2,0) -> NZCV := _val[31..0] case (3,3,4,2,1) -> DAIF := _val[31..0] + case (3, 3, 13, 0, 2) -> TPIDR_EL0 := _val[63..0] + (* TODO FIXME: higher EL TPIDRs *) (* case (3,0,1,0,1) -> ACTLR_EL1 := _val[31..0] *) } @@ -756,7 +760,19 @@ function unit AArch64_ExceptionReturn((bit[64]) new_pc, (bit[32]) spsr) = (** ENUMERATE:aarch64/instrs/countop/CountOp *) (** FUNCTION:ExtendType DecodeRegExtend(bits(3) op) *) -function ExtendType DecodeRegExtend ((bit[3]) op) = ([|8|]) op +function ExtendType DecodeRegExtend ((bit[3]) op) = +{ + switch op { + case 0b000 -> ExtendType_UXTB + case 0b001 -> ExtendType_UXTH + case 0b010 -> ExtendType_UXTW + case 0b011 -> ExtendType_UXTX + case 0b100 -> ExtendType_SXTB + case 0b101 -> ExtendType_SXTH + case 0b110 -> ExtendType_SXTW + case 0b111 -> ExtendType_SXTX + } +} (** FUNCTION:aarch64/instrs/extendreg/ExtendReg *) diff --git a/arm/armV8_A64_sys_regs.sail b/arm/armV8_A64_sys_regs.sail index 50c150c6..95b5c710 100644 --- a/arm/armV8_A64_sys_regs.sail +++ b/arm/armV8_A64_sys_regs.sail @@ -35,162 +35,6 @@ (*************************************************************************) (* General system control registers *) -register (bit[32]) ACTLR_EL1 (* Auxiliary Control Register (EL1) *) (* UNUSED *) -register (bit[32]) ACTLR_EL2 (* Auxiliary Control Register (EL2) *) (* UNUSED *) -register (bit[32]) ACTLR_EL3 (* Auxiliary Control Register (EL3) *) (* UNUSED *) -register (bit[32]) AFSR0_EL1 (* Auxiliary Fault Status Register 0 (EL1) *) (* UNUSED *) -register (bit[32]) AFSR0_EL2 (* Auxiliary Fault Status Register 0 (EL2) *) (* UNUSED *) -register (bit[32]) AFSR0_EL3 (* Auxiliary Fault Status Register 0 (EL3) *) (* UNUSED *) -register (bit[32]) AFSR1_EL1 (* Auxiliary Fault Status Register 1 (EL1) *) (* UNUSED *) -register (bit[32]) AFSR1_EL2 (* Auxiliary Fault Status Register 1 (EL2) *) (* UNUSED *) -register (bit[32]) AFSR1_EL3 (* Auxiliary Fault Status Register 1 (EL3) *) (* UNUSED *) -register (bit[32]) AIDR_EL1 (* Auxiliary ID Register *) (* UNUSED *) -register (bit[64]) AMAIR_EL1 (* Auxiliary Memory Attribute Indirection Register (EL1) *) (* UNUSED *) -register (bit[64]) AMAIR_EL2 (* Auxiliary Memory Attribute Indirection Register (EL2) *) (* UNUSED *) -register (bit[64]) AMAIR_EL3 (* Auxiliary Memory Attribute Indirection Register (EL3) *) (* UNUSED *) - -typedef CCSIDR_type = register bits [31:0] -{ - 31 : WT; - 30 : WB; - 29 : RA; - 28 : WA; - 27..13 : NumSets; - 12..3 : Associativity; - 2..0 : LineSize; -} -register (CCSIDR_type) CCSIDR_EL1 (* Current Cache Size ID Register *) (* UNUSED *) - -typedef CLIDR_type = register bits [63:0] -{ - (*63..33 : RES0*) - 32..30 : ICB; - 29..27 : LoUU; - 26..24 : LoC; - 23..21 : LoUIS; - 20..18 : Ctype7; - 17..15 : Ctype6; - 14..12 : Ctype5; - 11..9 : Ctype4; - 8..6 : Ctype3; - 5..3 : Ctype2; - 2..0 : Ctype1; -} -register (CLIDR_type) CLIDR_EL1 (* Cache Level ID Register *) (* UNUSED *) - -typedef CONTEXTIDR_type = register bits [31:0] { 31..0 : PROCID } -register (CONTEXTIDR_type) CONTEXTIDR_EL1 (* Context ID Register *) (* UNUSED *) - -typedef CPACR_type = register bits [31:0] -{ - (*31..29 : RES0;*) - 28 : TTA; - (*27..22 : RES0;*) - 21..20 : FPEN; - (*19..0 : RES0;*) -} -register (CPACR_type) CPACR_EL1 (* Architectural Feature Access Control Register *) (* UNUSED *) - -typedef CPTR_type = register bits [31:0] -{ - (* in EL3 all the RES are RES0 *) - 31 : TCPAC; - (*30..21 : RES0;*) - 20 : TTA; - (*19..14 : RES0;*) - (*13..12 : RES1;*) - (*11 : RES0;*) - 10 : TFP; - (*9..0 : RES1;*) -} -register (CPTR_type) CPTR_EL2 (* Architectural Feature Trap Register (EL2) *) (* UNUSED *) -register (CPTR_type) CPTR_EL3 (* Architectural Feature Trap Register (EL3) *) (* UNUSED *) - -typedef CSSELR_type = register bits [31:0] -{ - (*31..4 : RES0;*) - 3..1 : Level; - 0 : InD; -} -register (CSSELR_type) CSSELR_EL1 (* Cache Size Selection Register *) (* UNUSED *) - -typedef CTR_type = register bits [31:0] -{ - (*31 : RES1;*) - (*30..28 : RES0;*) - 27..24 : CWG; - 23..20 : ERG; - 19..16 : DminLine; - 15..14 : L1Ip; - (*13..4 : RES0;*) - 3..0 : IminLine; -} -register (CTR_type) CTR_EL0 (* Cache Type Register *) (* UNUSED *) - -typedef DACR32_type = register bits [31:0] -{ - 31..30 : D15; - 29..28 : D14; - 27..26 : D13; - 25..24 : D12; - 23..22 : D11; - 21..20 : D10; - 29..18 : D9; - 17..16 : D8; - 15..14 : D7; - 13..12 : D6; - 11..10 : D5; - 9..8 : D4; - 7..6 : D3; - 5..4 : D2; - 3..2 : D1; - 1..0 : D0; -} -register (DACR32_type) DACR32_EL2 (* Domain Access Control Register *) (* UNUSED *) - -typedef DCZID_type = register bits [31:0] -{ - (*31..5 : RES0;*) - 4 : DZP; - 3..0 : BS; -} -register (DCZID_type) DCZID_EL0 (* Data Cache Zero ID register *) (* UNUSED *) - -typedef ESR_type = register bits [31:0] -{ - 31..26 : EC; - 25 : IL; - 24..0 : ISS; -} -register (ESR_type) ESR_EL1 (* Exception Syndrome Register (EL1) *) (* UNUSED *) -register (ESR_type) ESR_EL2 (* Exception Syndrome Register (EL2) *) (* UNUSED *) -register (ESR_type) ESR_EL3 (* Exception Syndrome Register (EL3) *) (* UNUSED *) - -register (bit[64]) FAR_EL1 (* Fault Address Register (EL1) *) (* UNUSED *) -register (bit[64]) FAR_EL2 (* Fault Address Register (EL2) *) (* UNUSED *) -register (bit[64]) FAR_EL3 (* Fault Address Register (EL3) *) (* UNUSED *) - -typedef FPEXC32_type = register bits [31:0] -{ - 31 : EX; - 30 : EN; - 29 : DEX; - 28 : FP2V; - 27 : VV; - 26 : TFV; - (*25..21 : RES0;*) - (*20..11 : IMPLEMENTATION DEFINED*) - 10..8 : VECITR; - 7 : IDF; - (*6..5 : IMPLEMENTATION DEFINED*) - 4 : IXF; - 3 : UFF; - 2 : OFF; - 1 : DZF; - 0 : IOF; -} -register (FPEXC32_type) FPEXC32_EL2 (* Floating-point Exception Control register *) (* UNUSED *) -register (bit[32]) HACR_EL2 (* Hypervisor Auxiliary Control Register *) (* UNUSED *) typedef HCR_type = register bits [63:0] { @@ -231,35 +75,6 @@ typedef HCR_type = register bits [63:0] } register (HCR_type) HCR_EL2 (* Hypervisor Configuration Register *) -typedef HPFAR_type = register bits [63:0] -{ - (*63..40 : RES0;*) - 39..4 : FIPA; (* bits [47:12] of FIPA *) - (*3..0 : RES0;*) -} -register (HPFAR_type) HPFAR_EL2 (* Hypervisor IPA Fault Address Register *) (* UNUSED *) - -typedef HSTR_type = register bits [31:0] -{ - (*31..16 : RES0;*) - 15 : T15; - 14 : T14; - 13 : T13; - 12 : T12; - 11 : T11; - 10 : T10; - 9 : T9; - 8 : T8; - 7 : T7; - 6 : T6; - 5 : T5; - 4 : T4; - 3 : T3; - 2 : T2; - 1 : T1; - 0 : T0; -} -register (HSTR_type) HSTR_EL2 (* Hypervisor System Trap Register *) (* UNUSED *) typedef ID_AA64MMFR0_type = register bits [63:0] { @@ -402,6 +217,11 @@ typedef TCR_type = register bits [31:0] register (TCR_type) TCR_EL2 (* Translation Control Register (EL2) *) register (TCR_type) TCR_EL3 (* Translation Control Register (EL3) *) +register (bit[64]) TPIDR_EL0 (* EL0 Read/Write Software Thread ID Register *) +register (bit[64]) TPIDR_EL1 (* EL1 Read/Write Software Thread ID Register *) +register (bit[64]) TPIDR_EL2 (* EL2 Read/Write Software Thread ID Register *) +register (bit[64]) TPIDR_EL3 (* EL3 Read/Write Software Thread ID Register *) + (*************************************************************************) (* Debug registers *) @@ -458,9 +278,17 @@ typedef EDSCR_type = register bits [31:0] } register (EDSCR_type) EDSCR (* External Debug Status and Control Register *) +(* transactional memory, from the pre-alpha document *) +typedef TXIDR_EL0_type = register bits [63:0] +{ + (*63..8 : RES0;*) + 7..0 : DEPTH; +} +register (TXIDR_EL0_type) TXIDR_EL0 (* Transaction ID Register *) + + function unit effect pure AArch64_ResetControlRegisters((boolean) cold_reset) = { () } - diff --git a/arm/armV8_common_lib.sail b/arm/armV8_common_lib.sail index 3bae8070..9bea1cd1 100644 --- a/arm/armV8_common_lib.sail +++ b/arm/armV8_common_lib.sail @@ -513,8 +513,8 @@ val extern unit -> unit effect {barr} DataMemoryBarrier_All function unit effect {barr} DataMemoryBarrier((MBReqDomain) domain, (MBReqTypes) types) = { - if domain != MBReqDomain_FullSystem then - not_implemented("DataMemoryBarrier: not MBReqDomain_FullSystem"); + if domain != MBReqDomain_FullSystem & domain != MBReqDomain_InnerShareable then + not_implemented("DataMemoryBarrier: not MBReqDomain_FullSystem or _InnerShareable"); switch types { case MBReqTypes_Reads -> DataMemoryBarrier_Reads() @@ -725,10 +725,10 @@ function bool effect {wmv} flush_write_buffer_exclusive((write_buffer_type) writ (** FUNCTION:BranchTo(bits(N) target, BranchType branch_type) *) -function forall Nat 'N, 'N IN {32,64}. unit effect {rreg,wreg} BranchTo((bit['N]) target, (BranchType) _branch_type) = { +function forall Nat 'N, 'N IN {32,64}. unit effect {rreg,wreg} BranchTo((bit['N]) target, (BranchType) branch_type) = { (bit['N]) target' := target; (* Sail does not let you change parameter vector *) - Hint_Branch(_branch_type); + Hint_Branch(branch_type); if length(target) == 32 then { assert( UsingAArch32(), None ); _PC := ZeroExtend(target); @@ -831,7 +831,7 @@ function boolean effect {rreg} ConditionHolds((bit[4]) _cond) = case 0b111 -> result := true (* AL *) }; - (* Condition flag valuesin the set '111x' indicate always true *) + (* Condition flag values in the set '111x' indicate always true *) (* Otherwise, invert condition if necessary. *) if _cond[0] == 1 & _cond != 0b1111 then result := ~(result); diff --git a/arm/armV8_extras.lem b/arm/armV8_extras.lem new file mode 100644 index 00000000..9a187ecb --- /dev/null +++ b/arm/armV8_extras.lem @@ -0,0 +1,77 @@ +open import Pervasives +open import Interp_ast +open import Interp_interface +open import Sail_impl_base +open import Interp_inter_imp +import Set_extra + +let memory_parameter_transformer mode v = + match v with + | Interp_ast.V_tuple [location;length] -> + let (v,loc_regs) = extern_with_track mode extern_vector_value location in + + match length with + | Interp_ast.V_lit (L_aux (L_num len) _) -> + (v,(natFromInteger len),loc_regs) + + | Interp_ast.V_track (Interp_ast.V_lit (L_aux (L_num len) _)) size_regs -> + match loc_regs with + | Nothing -> (v,(natFromInteger len),Just (List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs))) + | Just loc_regs -> (v,(natFromInteger len),Just (loc_regs++(List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs)))) + end + + | _ -> Assert_extra.failwith "expected 'V_lit (L_aux (L_num _) _)' or 'V_track (V_lit (L_aux (L_num len) _)) _'" + end + | _ -> Assert_extra.failwith "expected 'V_tuple [_;_]'" + end + +let aArch64_read_memory_functions : memory_reads = + [ ("rMem_NORMAL", (MR Read_plain memory_parameter_transformer)); + ("rMem_STREAM", (MR Read_stream memory_parameter_transformer)); + ("rMem_ORDERED", (MR Read_acquire memory_parameter_transformer)); + ("rMem_ATOMIC", (MR Read_exclusive memory_parameter_transformer)); + ("rMem_ATOMIC_ORDERED", (MR Read_exclusive_acquire memory_parameter_transformer)); + ] + +let aArch64_memory_writes : memory_writes = [] + (* [ ("wMem_NORMAL", (MW Write_plain memory_parameter_transformer Nothing)); + ("wMem_ORDERED", (MW Write_release memory_parameter_transformer Nothing)); + ("wMem_ATOMIC", (MW Write_exclusive memory_parameter_transformer Nothing)); + ("wMem_ATOMIC_ORDERED", (MW Write_exclusive_release memory_parameter_transformer Nothing)); + ] *) + +let aArch64_memory_eas : memory_write_eas = + [ ("wMem_Addr_NORMAL", (MEA Write_plain memory_parameter_transformer)); + ("wMem_Addr_ORDERED", (MEA Write_release memory_parameter_transformer)); + ("wMem_Addr_ATOMIC", (MEA Write_exclusive memory_parameter_transformer)); + ("wMem_Addr_ATOMIC_ORDERED", (MEA Write_exclusive_release memory_parameter_transformer)); + ] + +let aArch64_memory_vals : memory_write_vals = + [ ("wMem_Val_NORMAL", (MV (fun mode v -> Nothing) Nothing)); + ("wMem_Val_ATOMIC", (MV (fun mode v -> Nothing) + (Just + (fun (IState interp context) b -> + (*ppcmem2 provides true for success and false for failure; but the status for ARM is reversed*) + let bit = Interp_ast.V_lit (L_aux (if b then L_zero else L_one) Interp_ast.Unknown)in + (IState (Interp.add_answer_to_stack interp bit) context))))); + ] + +let aArch64_excl_res : excl_res = + let f = fun (IState interp context) b -> + let bool_res = Interp_ast.V_lit (L_aux (if b then L_one else L_zero) Interp_ast.Unknown) in + IState (Interp.add_answer_to_stack interp bool_res) context + in + Just ("speculate_exclusive_success", (ER (Just f))) + +let aArch64_barrier_functions = + [ ("DataMemoryBarrier_Reads", Barrier_DMB_LD); + ("DataMemoryBarrier_Writes", Barrier_DMB_ST); + ("DataMemoryBarrier_All", Barrier_DMB); + ("DataSynchronizationBarrier_Reads", Barrier_DSB_LD); + ("DataSynchronizationBarrier_Writes", Barrier_DSB_ST); + ("DataSynchronizationBarrier_All", Barrier_DSB); + ("InstructionSynchronizationBarrier", Barrier_ISB); + + ("TMCommitEffect", Barrier_TM_COMMIT); + ] diff --git a/arm/armV8_extras_embed.lem b/arm/armV8_extras_embed.lem new file mode 100644 index 00000000..86570fc4 --- /dev/null +++ b/arm/armV8_extras_embed.lem @@ -0,0 +1,59 @@ +open import Pervasives +open import Sail_impl_base +open import Sail_values +open import Prompt + +val rMem_NORMAL : (vector bitU * integer) -> M (vector bitU) +val rMem_STREAM : (vector bitU * integer) -> M (vector bitU) +val rMem_ORDERED : (vector bitU * integer) -> M (vector bitU) +val rMem_ATOMICL : (vector bitU * integer) -> M (vector bitU) +val rMem_ATOMIC_ORDERED : (vector bitU * integer) -> M (vector bitU) + +let rMem_NORMAL (addr,size) = read_mem false Read_plain addr size +let rMem_STREAM (addr,size) = read_mem false Read_stream addr size +let rMem_ORDERED (addr,size) = read_mem false Read_acquire addr size +let rMem_ATOMIC (addr,size) = read_mem false Read_exclusive addr size +let rMem_ATOMIC_ORDERED (addr,size) = read_mem false Read_exclusive_acquire addr size + +val wMem_Addr_NORMAL : (vector bitU * integer) -> M unit +val wMem_Addr_ORDERED : (vector bitU * integer) -> M unit +val wMem_Addr_ATOMIC : (vector bitU * integer) -> M unit +val wMem_Addr_ATOMIC_ORDERED : (vector bitU * integer) -> M unit + +let wMem_Addr_NORMAL (addr,size) = write_mem_ea Write_plain addr size +let wMem_Addr_ORDERED (addr,size) = write_mem_ea Write_release addr size +let wMem_Addr_ATOMIC (addr,size) = write_mem_ea Write_exclusive addr size +let wMem_Addr_ATOMIC_ORDERED (addr,size) = write_mem_ea Write_exclusive_release addr size + + +val wMem_Val_NORMAL : (integer * vector bitU) -> M unit +val wMem_Val_ATOMIC : (integer * vector bitU) -> M bitU + +let wMem_Val_NORMAL (_,v) = write_mem_val v >>= fun _ -> return () +(* in ARM the status returned is inversed *) +let wMem_Val_ATOMIC (_,v) = write_mem_val v >>= fun b -> return (if b then B0 else B1) + +let speculate_exclusive_success () = excl_result () >>= fun b -> return (if b then B1 else B0) + +val DataMemoryBarrier_Reads : unit -> M unit +val DataMemoryBarrier_Writes : unit -> M unit +val DataMemoryBarrier_All : unit -> M unit +val DataSynchronizationBarrier_Reads : unit -> M unit +val DataSynchronizationBarrier_Writes : unit -> M unit +val DataSynchronizationBarrier_All : unit -> M unit +val InstructionSynchronizationBarrier : unit -> M unit + +let DataMemoryBarrier_Reads () = barrier Barrier_DMB_LD +let DataMemoryBarrier_Writes () = barrier Barrier_DMB_ST +let DataMemoryBarrier_All () = barrier Barrier_DMB +let DataSynchronizationBarrier_Reads () = barrier Barrier_DSB_LD +let DataSynchronizationBarrier_Writes () = barrier Barrier_DSB_ST +let DataSynchronizationBarrier_All () = barrier Barrier_DSB +let InstructionSynchronizationBarrier () = barrier Barrier_ISB + +val TMCommitEffect : unit -> M unit +let TMCommitEffect () = barrier Barrier_TM_COMMIT + +let duplicate_bits (Vector bits start direction,len) = + let bits' = repeat bits len in + Vector bits' start direction diff --git a/arm/armV8_extras_embed_sequential.lem b/arm/armV8_extras_embed_sequential.lem new file mode 100644 index 00000000..d2bb8330 --- /dev/null +++ b/arm/armV8_extras_embed_sequential.lem @@ -0,0 +1,59 @@ +open import Pervasives +open import Sail_impl_base +open import Sail_values +open import State + +val rMem_NORMAL : (vector bitU * integer) -> M (vector bitU) +val rMem_STREAM : (vector bitU * integer) -> M (vector bitU) +val rMem_ORDERED : (vector bitU * integer) -> M (vector bitU) +val rMem_ATOMICL : (vector bitU * integer) -> M (vector bitU) +val rMem_ATOMIC_ORDERED : (vector bitU * integer) -> M (vector bitU) + +let rMem_NORMAL (addr,size) = read_mem false Read_plain addr size +let rMem_STREAM (addr,size) = read_mem false Read_stream addr size +let rMem_ORDERED (addr,size) = read_mem false Read_acquire addr size +let rMem_ATOMIC (addr,size) = read_mem false Read_exclusive addr size +let rMem_ATOMIC_ORDERED (addr,size) = read_mem false Read_exclusive_acquire addr size + +val wMem_Addr_NORMAL : (vector bitU * integer) -> M unit +val wMem_Addr_ORDERED : (vector bitU * integer) -> M unit +val wMem_Addr_ATOMIC : (vector bitU * integer) -> M unit +val wMem_Addr_ATOMIC_ORDERED : (vector bitU * integer) -> M unit + +let wMem_Addr_NORMAL (addr,size) = write_mem_ea Write_plain addr size +let wMem_Addr_ORDERED (addr,size) = write_mem_ea Write_release addr size +let wMem_Addr_ATOMIC (addr,size) = write_mem_ea Write_exclusive addr size +let wMem_Addr_ATOMIC_ORDERED (addr,size) = write_mem_ea Write_exclusive_release addr size + + +val wMem_Val_NORMAL : (integer * vector bitU) -> M unit +val wMem_Val_ATOMIC : (integer * vector bitU) -> M bitU + +let wMem_Val_NORMAL (_,v) = write_mem_val v >>= fun _ -> return () +(* in ARM the status returned is inversed *) +let wMem_Val_ATOMIC (_,v) = write_mem_val v >>= fun b -> return (if b then B0 else B1) + +let speculate_exclusive_success () = excl_result () >>= fun b -> return (if b then B1 else B0) + +val DataMemoryBarrier_Reads : unit -> M unit +val DataMemoryBarrier_Writes : unit -> M unit +val DataMemoryBarrier_All : unit -> M unit +val DataSynchronizationBarrier_Reads : unit -> M unit +val DataSynchronizationBarrier_Writes : unit -> M unit +val DataSynchronizationBarrier_All : unit -> M unit +val InstructionSynchronizationBarrier : unit -> M unit + +let DataMemoryBarrier_Reads () = barrier Barrier_DMB_LD +let DataMemoryBarrier_Writes () = barrier Barrier_DMB_ST +let DataMemoryBarrier_All () = barrier Barrier_DMB +let DataSynchronizationBarrier_Reads () = barrier Barrier_DSB_LD +let DataSynchronizationBarrier_Writes () = barrier Barrier_DSB_ST +let DataSynchronizationBarrier_All () = barrier Barrier_DSB +let InstructionSynchronizationBarrier () = barrier Barrier_ISB + +val TMCommitEffect : unit -> M unit +let TMCommitEffect () = barrier Barrier_TM_COMMIT + +let duplicate_bits (Vector bits start direction,len) = + let bits' = repeat bits len in + Vector bits' start direction diff --git a/arm/armV8_lib.h.sail b/arm/armV8_lib.h.sail index 849472e1..d52cc5d5 100644 --- a/arm/armV8_lib.h.sail +++ b/arm/armV8_lib.h.sail @@ -187,9 +187,8 @@ typedef CountOp = enumerate {CountOp_CLZ; CountOp_CLS; CountOp_CNT} typedef ExtendType = - (* the oreder is important for decoding *) - enumerate { ExtendType_UXTB; ExtendType_UXTH; ExtendType_UXTW; ExtendType_UXTX; - ExtendType_SXTB; ExtendType_SXTH; ExtendType_SXTW; ExtendType_SXTX } + enumerate { ExtendType_SXTB; ExtendType_SXTH; ExtendType_SXTW; ExtendType_SXTX; + ExtendType_UXTB; ExtendType_UXTH; ExtendType_UXTW; ExtendType_UXTX } typedef RevOp = enumerate {RevOp_RBIT; RevOp_REV16; RevOp_REV32; RevOp_REV64} diff --git a/arm/gen/ast.hgen b/arm/gen/ast.hgen new file mode 100644 index 00000000..60f130d7 --- /dev/null +++ b/arm/gen/ast.hgen @@ -0,0 +1,44 @@ + | `AArch64TMStart of inst_reg (* t *) + | `AArch64TMCommit + | `AArch64TMAbort of boolean*bit5 (* retry,reason *) + | `AArch64TMTest + + | `AArch64ImplementationDefinedTestBeginEnd of boolean (* isEnd *) + | `AArch64ImplementationDefinedStopFetching + | `AArch64ImplementationDefinedThreadStart + | `AArch64AddSubCarry of inst_reg*inst_reg*inst_reg*reg_size*boolean*boolean (* d,n,m,datasize,sub_op,setflags *) + | `AArch64AddSubExtendRegister of inst_reg*inst_reg*inst_reg*reg_size*boolean*boolean*extendType*range0_7 (* d,n,m,datasize,sub_op,setflags,extend_type,shift *) + | `AArch64AddSubShiftedRegister of inst_reg*inst_reg*inst_reg*reg_size*boolean*boolean*shiftType*range0_63 (* d,n,m,datasize,sub_op,setflags,shift_type,shift_amount *) + | `AArch64AddSubImmediate of inst_reg*inst_reg*reg_size*boolean*boolean*reg_size_bits (* d,n,datasize,sub_op,setflags,imm *) + | `AArch64Address of inst_reg*boolean*bit64 (* d,page,imm *) + | `AArch64LogicalImmediate of inst_reg*inst_reg*reg_size*boolean*logicalOp*reg_size_bits (* d,n,datasize,setflags,op,imm *) + | `AArch64LogicalShiftedRegister of inst_reg*inst_reg*inst_reg*reg_size*boolean*logicalOp*shiftType*range0_63*boolean (* d,n,m,datasize,setflags,op,shift_type,shift_amount,invert *) + | `AArch64Shift of inst_reg*inst_reg*inst_reg*reg_size*shiftType (* d,n,m,datasize,shift_type *) + | `AArch64BranchConditional of bit64*bit4 (* offset,condition *) + | `AArch64BranchImmediate of branchType*bit64 (* branch_type,offset *) + | `AArch64BitfieldMove of inst_reg*inst_reg*reg_size*boolean*boolean*uinteger*uinteger*reg_size_bits*reg_size_bits (* d,n,datasize,inzero,extend,R,S,wmask,tmask *) + | `AArch64BranchRegister of inst_reg*branchType (* n,branch_type *) + | `AArch64CompareAndBranch of inst_reg*reg_size*boolean*bit64 (* t,datasize,iszero,offset *) + | `AArch64ConditionalCompareImmediate of inst_reg*reg_size*boolean*bit4*bit4*reg_size_bits (* n,datasize,sub_op,condition,flags,imm *) + | `AArch64ConditionalCompareRegister of inst_reg*inst_reg*reg_size*boolean*bit4*bit4 (* n,m,datasize,sub_op,condition,flags *) + | `AArch64ClearExclusiveMonitor of uinteger (* imm *) + | `AArch64CountLeading of inst_reg*inst_reg*reg_size*countOp (* d,n,datasize,opcode *) + | `AArch64CRC of inst_reg*inst_reg*inst_reg*data_size*boolean (* d,n,m,size,crc32c *) + | `AArch64ConditionalSelect of inst_reg*inst_reg*inst_reg*reg_size*bit4*boolean*boolean (* d,n,m,datasize,condition,else_inv,else_inc *) + | `AArch64Barrier of memBarrierOp*mBReqDomain*mBReqTypes (* op,domain,types *) + | `AArch64ExtractRegister of inst_reg*inst_reg*inst_reg*reg_size*uinteger (* d,n,m,datasize,lsb *) + | `AArch64Hint of systemHintOp (* op *) + | `AArch64LoadStoreAcqExc of inst_reg*inst_reg*inst_reg*inst_reg*accType*boolean*boolean*memOp*uinteger*reg_size*data_size (* n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize *) + | `AArch64LoadStorePair of boolean*boolean*inst_reg*inst_reg*inst_reg*accType*memOp*boolean*data_size*bit64 (* wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset *) + | `AArch64LoadImmediate of inst_reg*inst_reg*accType*memOp*boolean*boolean*boolean*bit64*reg_size*data_size (* n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize *) + | `AArch64LoadLiteral of inst_reg*memOp*boolean*uinteger*bit64*data_size (* t,memop,signed,size,offset,datasize *) + | `AArch64LoadRegister of inst_reg*inst_reg*inst_reg*accType*memOp*boolean*boolean*boolean*extendType*uinteger*reg_size*data_size (* n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize *) + | `AArch64MultiplyAddSub of inst_reg*inst_reg*inst_reg*inst_reg*reg_size*data_size*boolean (* d,n,m,a,destsize,datasize,sub_op *) + | `AArch64MoveWide of inst_reg*reg_size*bit16*uinteger*moveWideOp (* d,datasize,imm,pos,opcode *) + | `AArch64Reverse of inst_reg*inst_reg*reg_size*revOp (* d,n,datasize,op *) + | `AArch64Division of inst_reg*inst_reg*inst_reg*reg_size*boolean (* d,n,m,datasize,unsigned *) + | `AArch64MultiplyAddSubLong of inst_reg*inst_reg*inst_reg*inst_reg*reg_size*data_size*boolean*boolean (* d,n,m,a,destsize,datasize,sub_op,unsigned *) + | `AArch64MultiplyHigh of inst_reg*inst_reg*inst_reg*inst_reg*reg_size*data_size*boolean (* d,n,m,a,destsize,datasize,unsigned *) + | `AArch64TestBitAndBranch of inst_reg*reg_size*uinteger*bit*bit64 (* t,datasize,bit_pos,bit_val,offset *) + | `AArch64MoveSystemRegister of inst_reg*uinteger*uinteger*uinteger*uinteger*uinteger*boolean (* t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read *) + | `AArch64MoveSystemImmediate of bit4*pSTATEField (* operand,field *) diff --git a/arm/gen/fold.hgen b/arm/gen/fold.hgen new file mode 100644 index 00000000..4062d8e6 --- /dev/null +++ b/arm/gen/fold.hgen @@ -0,0 +1,44 @@ +| `AArch64TMStart t -> fold_reg t (y_reg, y_sreg) +| `AArch64TMCommit -> (y_reg, y_sreg) +| `AArch64TMAbort (retry,reason) -> (y_reg, y_sreg) +| `AArch64TMTest -> (y_reg, y_sreg) + +| `AArch64ImplementationDefinedStopFetching -> (y_reg, y_sreg) +| `AArch64ImplementationDefinedThreadStart -> (y_reg, y_sreg) +| `AArch64ImplementationDefinedTestBeginEnd (isEnd) -> (y_reg, y_sreg) +| `AArch64AddSubCarry (d,n,m,datasize,sub_op,setflags) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64AddSubExtendRegister (d,n,m,datasize,sub_op,setflags,extend_type,shift) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64AddSubShiftedRegister (d,n,m,datasize,sub_op,setflags,shift_type,shift_amount) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64AddSubImmediate (d,n,datasize,sub_op,setflags,imm) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64Address (d,page,imm) -> fold_reg d (y_reg, y_sreg) +| `AArch64LogicalImmediate (d,n,datasize,setflags,op,imm) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64LogicalShiftedRegister (d,n,m,datasize,setflags,op,shift_type,shift_amount,invert) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64Shift (d,n,m,datasize,shift_type) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64BranchConditional (offset,condition) -> (y_reg, y_sreg) +| `AArch64BranchImmediate (branch_type,offset) -> (y_reg, y_sreg) +| `AArch64BitfieldMove (d,n,datasize,inzero,extend,_R,_S,wmask,tmask) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64BranchRegister (n,branch_type) -> fold_reg n (y_reg, y_sreg) +| `AArch64CompareAndBranch (t,datasize,iszero,offset) -> fold_reg t (y_reg, y_sreg) +| `AArch64ConditionalCompareImmediate (n,datasize,sub_op,condition,flags,imm) -> fold_reg n (y_reg, y_sreg) +| `AArch64ConditionalCompareRegister (n,m,datasize,sub_op,condition,flags) -> fold_reg m (fold_reg n (y_reg, y_sreg)) +| `AArch64ClearExclusiveMonitor (imm) -> (y_reg, y_sreg) +| `AArch64CountLeading (d,n,datasize,opcode) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64CRC (d,n,m,size,crc32c) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64ConditionalSelect (d,n,m,datasize,condition,else_inv,else_inc) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64Barrier (op,domain,types) -> (y_reg, y_sreg) +| `AArch64ExtractRegister (d,n,m,datasize,lsb) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64Hint (op) -> (y_reg, y_sreg) +| `AArch64LoadStoreAcqExc (n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) -> fold_reg s (fold_reg t2 (fold_reg t (fold_reg n (y_reg, y_sreg)))) +| `AArch64LoadStorePair (wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset) -> fold_reg t2 (fold_reg t (fold_reg n (y_reg, y_sreg))) +| `AArch64LoadImmediate (n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) -> fold_reg t (fold_reg n (y_reg, y_sreg)) +| `AArch64LoadLiteral (t,memop,signed,size,offset,datasize) -> fold_reg t (y_reg, y_sreg) +| `AArch64LoadRegister (n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) -> fold_reg m (fold_reg t (fold_reg n (y_reg, y_sreg))) +| `AArch64MultiplyAddSub (d,n,m,a,destsize,datasize,sub_op) -> fold_reg a (fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg)))) +| `AArch64MoveWide (d,datasize,imm,pos,opcode) -> fold_reg d (y_reg, y_sreg) +| `AArch64Reverse (d,n,datasize,op) -> fold_reg n (fold_reg d (y_reg, y_sreg)) +| `AArch64Division (d,n,m,datasize,unsigned) -> fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg))) +| `AArch64MultiplyAddSubLong (d,n,m,a,destsize,datasize,sub_op,unsigned) -> fold_reg a (fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg)))) +| `AArch64MultiplyHigh (d,n,m,a,destsize,datasize,unsigned) -> fold_reg a (fold_reg m (fold_reg n (fold_reg d (y_reg, y_sreg)))) +| `AArch64TestBitAndBranch (t,datasize,bit_pos,bit_val,offset) -> fold_reg t (y_reg, y_sreg) +| `AArch64MoveSystemRegister (t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) -> fold_reg t (y_reg, y_sreg) +| `AArch64MoveSystemImmediate (operand,field) -> (y_reg, y_sreg) diff --git a/arm/gen/herdtools_ast_to_shallow_ast.hgen b/arm/gen/herdtools_ast_to_shallow_ast.hgen new file mode 100644 index 00000000..5a19e483 --- /dev/null +++ b/arm/gen/herdtools_ast_to_shallow_ast.hgen @@ -0,0 +1,335 @@ +| `AArch64TMStart t -> TMStart (translate_reg "t" t) + +| `AArch64TMCommit -> TMCommit + +| `AArch64TMAbort (retry,reason) -> + TMAbort + (translate_boolean "retry" retry, + translate_bit5 "reason" reason) + +| `AArch64TMTest -> TMTest + +| `AArch64ImplementationDefinedStopFetching -> + ImplementationDefinedStopFetching + +| `AArch64ImplementationDefinedThreadStart -> + ImplementationDefinedThreadStart + +| `AArch64ImplementationDefinedTestBeginEnd(isEnd) -> + ImplementationDefinedTestBeginEnd + (translate_boolean "isEnd" isEnd) + +| `AArch64AddSubCarry(d,n,m,datasize,sub_op,setflags) -> + AddSubCarry + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "setflags" setflags) + +| `AArch64AddSubExtendRegister (d,n,m,datasize,sub_op,setflags,extend_type,shift) -> + AddSubExtendRegister + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "setflags" setflags, + translate_extendType "extend_type" extend_type, + translate_range0_7 "shift" shift) + +| `AArch64AddSubShiftedRegister (d,n,m,datasize,sub_op,setflags,shift_type,shift_amount) -> + AddSubShiftedRegister + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "setflags" setflags, + translate_shiftType "shift_type" shift_type, + translate_range0_63 "shift_amount" shift_amount) + +| `AArch64AddSubImmediate (d,n,datasize,sub_op,setflags,imm) -> + AddSubImmediate + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "setflags" setflags, + translate_reg_size_bits "imm" imm) + +| `AArch64Address (d,page,imm) -> + Address0 + (translate_reg "d" d, + translate_boolean "page" page, + translate_bit64 "imm" imm) + +| `AArch64LogicalImmediate (d,n,datasize,setflags,op,imm) -> + LogicalImmediate + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_boolean "setflags" setflags, + translate_logicalOp "op" op, + translate_reg_size_bits "imm" imm) + +| `AArch64LogicalShiftedRegister (d,n,m,datasize,setflags,op,shift_type,shift_amount,invert) -> + LogicalShiftedRegister + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "setflags" setflags, + translate_logicalOp "op" op, + translate_shiftType "shift_type" shift_type, + translate_range0_63 "shift_amount" shift_amount, + translate_boolean "invert" invert) + +| `AArch64Shift (d,n,m,datasize,shift_type) -> + Shift + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_shiftType "shift_type" shift_type) + +| `AArch64BranchConditional (offset,condition) -> + BranchConditional + (translate_bit64 "offset" offset, + translate_bit4 "condition" condition) + +| `AArch64BranchImmediate (branch_type,offset) -> + BranchImmediate + (translate_branchType "branch_type" branch_type, + translate_bit64 "offset" offset) + +| `AArch64BitfieldMove (d,n,datasize,inzero,extend,_R,_S,wmask,tmask) -> + BitfieldMove + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_boolean "inzero" inzero, + translate_boolean "extend" extend, + translate_uinteger "_R" _R, + translate_uinteger "_S" _S, + translate_reg_size_bits "wmask" wmask, + translate_reg_size_bits "tmask" tmask) + +| `AArch64BranchRegister (n,branch_type) -> + BranchRegister + (translate_reg "n" n, + translate_branchType "branch_type" branch_type) + +| `AArch64CompareAndBranch (t,datasize,iszero,offset) -> + CompareAndBranch + (translate_reg "t" t, + translate_reg_size "datasize" datasize, + translate_boolean "iszero" iszero, + translate_bit64 "offset" offset) + +| `AArch64ConditionalCompareImmediate (n,datasize,sub_op,condition,flags,imm) -> + ConditionalCompareImmediate + (translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_bit4 "condition" condition, + translate_bit4 "flags" flags, + translate_reg_size_bits "imm" imm) + +| `AArch64ConditionalCompareRegister (n,m,datasize,sub_op,condition,flags) -> + ConditionalCompareRegister + (translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_bit4 "condition" condition, + translate_bit4 "flags" flags) + +| `AArch64ClearExclusiveMonitor (imm) -> + ClearExclusiveMonitor + (translate_uinteger "imm" imm) + +| `AArch64CountLeading (d,n,datasize,opcode) -> + CountLeading + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_countOp "opcode" opcode) + +| `AArch64CRC (d,n,m,size,crc32c) -> + CRC + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_data_size "size" size, + translate_boolean "crc32c" crc32c) + +| `AArch64ConditionalSelect (d,n,m,datasize,condition,else_inv,else_inc) -> + ConditionalSelect + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_bit4 "condition" condition, + translate_boolean "else_inv" else_inv, + translate_boolean "else_inc" else_inc) + +| `AArch64Barrier (op,domain,types) -> + Barrier2 + (translate_memBarrierOp "op" op, + translate_mBReqDomain "domain" domain, + translate_mBReqTypes "types" types) + +| `AArch64ExtractRegister (d,n,m,datasize,lsb) -> + ExtractRegister + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_uinteger "lsb" lsb) + +| `AArch64Hint (op) -> + Hint + (translate_systemHintOp "op" op) + +| `AArch64LoadStoreAcqExc (n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) -> + LoadStoreAcqExc + (translate_reg "n" n, + translate_reg "t" t, + translate_reg "t2" t2, + translate_reg "s" s, + translate_accType "acctype" acctype, + translate_boolean "excl" excl, + translate_boolean "pair" pair, + translate_memOp "memop" memop, + translate_uinteger "elsize" elsize, + translate_reg_size "regsize" regsize, + translate_data_size "datasize" datasize) + +| `AArch64LoadStorePair (wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset) -> + LoadStorePair + (translate_boolean "wback" wback, + translate_boolean "postindex" postindex, + translate_reg "n" n, + translate_reg "t" t, + translate_reg "t2" t2, + translate_accType "acctype" acctype, + translate_memOp "memop" memop, + translate_boolean "signed" signed, + translate_data_size "datasize" datasize, + translate_bit64 "offset" offset) + +| `AArch64LoadImmediate (n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) -> + LoadImmediate + (translate_reg "n" n, + translate_reg "t" t, + translate_accType "acctype" acctype, + translate_memOp "memop" memop, + translate_boolean "signed" signed, + translate_boolean "wback" wback, + translate_boolean "postindex" postindex, + translate_bit64 "offset" offset, + translate_reg_size "regsize" regsize, + translate_data_size "datasize" datasize) + +| `AArch64LoadLiteral (t,memop,signed,size,offset,datasize) -> + LoadLiteral + (translate_reg "t" t, + translate_memOp "memop" memop, + translate_boolean "signed" signed, + translate_uinteger "size" size, + translate_bit64 "offset" offset, + translate_data_size "datasize" datasize) + +| `AArch64LoadRegister (n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) -> + LoadRegister + (translate_reg "n" n, + translate_reg "t" t, + translate_reg "m" m, + translate_accType "acctype" acctype, + translate_memOp "memop" memop, + translate_boolean "signed" signed, + translate_boolean "wback" wback, + translate_boolean "postindex" postindex, + translate_extendType "extend_type" extend_type, + translate_uinteger "shift" shift, + translate_reg_size "regsize" regsize, + translate_data_size "datasize" datasize) + +| `AArch64MultiplyAddSub (d,n,m,a,destsize,datasize,sub_op) -> + MultiplyAddSub + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg "a" a, + translate_reg_size "destsize" destsize, + translate_data_size "datasize" datasize, + translate_boolean "sub_op" sub_op) + +| `AArch64MoveWide (d,datasize,imm,pos,opcode) -> + MoveWide + (translate_reg "d" d, + translate_reg_size "datasize" datasize, + translate_bit16 "imm" imm, + translate_uinteger "pos" pos, + translate_moveWideOp "opcode" opcode) + +| `AArch64Reverse (d,n,datasize,op) -> + Reverse + (translate_reg "d" d, + translate_reg "n" n, + translate_reg_size "datasize" datasize, + translate_revOp "op" op) + +| `AArch64Division (d,n,m,datasize,unsigned) -> + Division + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg_size "datasize" datasize, + translate_boolean "unsigned" unsigned) + +| `AArch64MultiplyAddSubLong (d,n,m,a,destsize,datasize,sub_op,unsigned) -> + MultiplyAddSubLong + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg "a" a, + translate_reg_size "destsize" destsize, + translate_data_size "datasize" datasize, + translate_boolean "sub_op" sub_op, + translate_boolean "unsigned" unsigned) + +| `AArch64MultiplyHigh (d,n,m,a,destsize,datasize,unsigned) -> + MultiplyHigh + (translate_reg "d" d, + translate_reg "n" n, + translate_reg "m" m, + translate_reg "a" a, + translate_reg_size "destsize" destsize, + translate_data_size "datasize" datasize, + translate_boolean "unsigned" unsigned) + +| `AArch64TestBitAndBranch (t,datasize,bit_pos,bit_val,offset) -> + TestBitAndBranch + (translate_reg "t" t, + translate_reg_size "datasize" datasize, + translate_uinteger "bit_pos" bit_pos, + translate_bit "bit_val" bit_val, + translate_bit64 "offset" offset) + +| `AArch64MoveSystemRegister (t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) -> + MoveSystemRegister + (translate_reg "t" t, + translate_uinteger "sys_op0" sys_op0, + translate_uinteger "sys_op1" sys_op1, + translate_uinteger "sys_op2" sys_op2, + translate_uinteger "sys_crn" sys_crn, + translate_uinteger "sys_crm" sys_crm, + translate_boolean "read" read) + +| `AArch64MoveSystemImmediate (operand,field) -> + MoveSystemImmediate + (translate_bit4 "operand" operand, + translate_pSTATEField "field" field) diff --git a/arm/gen/herdtools_types_to_shallow_types.hgen b/arm/gen/herdtools_types_to_shallow_types.hgen new file mode 100644 index 00000000..e14a37e3 --- /dev/null +++ b/arm/gen/herdtools_types_to_shallow_types.hgen @@ -0,0 +1,153 @@ +open Sail_values + +let is_inc = false + +let translate_big_int bits (name : string) value = + (name, Range0 (Some bits), IInt.bit_list_of_integer bits value) + +let translate_big_bit bits (name:string) value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int bits,value) + +let translate_int (size : int) (name:string) value = (Nat_big_num.of_int value) + +let translate_bits bits (name:string) value = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int bits,Nat_big_num.of_int value) + +let translate_bool _ = function + | true -> B1 + | false -> B0 + +let translate_reg_size name value = + match value with + | Set32 -> (Nat_big_num.of_int 32) + | Set64 -> (Nat_big_num.of_int 64) + +let translate_reg name value = + (Nat_big_num.of_int (inst_reg_to_int value)) + + +let translate_reg_size_bits name value = + match value with + | R32Bits value -> translate_bits 32 name value + | R64Bits value -> translate_big_bit 64 name value + +let translate_data_size name value = + match value with + | DataSize8 -> (Nat_big_num.of_int 8) + | DataSize16 -> (Nat_big_num.of_int 16) + | DataSize32 -> (Nat_big_num.of_int 32) + | DataSize64 -> (Nat_big_num.of_int 64) + +let translate_reg_index = translate_int 5 + +let translate_boolean = translate_bool + +let translate_range0_7 = translate_int 3 + +let translate_range0_63 = translate_int 6 + +let translate_bit64 = translate_big_bit 64 + +let translate_bit4 = translate_bits 4 +let translate_bit5 = translate_bits 5 +let translate_bit16 = translate_bits 16 + +let translate_bit = translate_bool + +let translate_range8_64 = translate_int 7 + +let translate_uinteger = translate_int 63 + +let translate_extendType _ = function + | ExtendType_UXTB -> ArmV8_embed_types.ExtendType_UXTB + | ExtendType_UXTH -> ArmV8_embed_types.ExtendType_UXTH + | ExtendType_UXTW -> ArmV8_embed_types.ExtendType_UXTW + | ExtendType_UXTX -> ArmV8_embed_types.ExtendType_UXTX + | ExtendType_SXTB -> ArmV8_embed_types.ExtendType_SXTB + | ExtendType_SXTH -> ArmV8_embed_types.ExtendType_SXTH + | ExtendType_SXTW -> ArmV8_embed_types.ExtendType_SXTW + | ExtendType_SXTX -> ArmV8_embed_types.ExtendType_SXTX + +let translate_shiftType _ = function + | ShiftType_LSL -> ArmV8_embed_types.ShiftType_LSL + | ShiftType_LSR -> ArmV8_embed_types.ShiftType_LSR + | ShiftType_ASR -> ArmV8_embed_types.ShiftType_ASR + | ShiftType_ROR -> ArmV8_embed_types.ShiftType_ROR + +let translate_logicalOp _ = function + | LogicalOp_AND -> ArmV8_embed_types.LogicalOp_AND + | LogicalOp_EOR -> ArmV8_embed_types.LogicalOp_EOR + | LogicalOp_ORR -> ArmV8_embed_types.LogicalOp_ORR + +let translate_branchType _ = function + | BranchType_CALL -> ArmV8_embed_types.BranchType_CALL + | BranchType_ERET -> ArmV8_embed_types.BranchType_ERET + | BranchType_DBGEXIT -> ArmV8_embed_types.BranchType_DBGEXIT + | BranchType_RET -> ArmV8_embed_types.BranchType_RET + | BranchType_JMP -> ArmV8_embed_types.BranchType_JMP + | BranchType_EXCEPTION -> ArmV8_embed_types.BranchType_EXCEPTION + | BranchType_UNKNOWN -> ArmV8_embed_types.BranchType_UNKNOWN + +let translate_countOp _ = function + | CountOp_CLZ -> ArmV8_embed_types.CountOp_CLZ + | CountOp_CLS -> ArmV8_embed_types.CountOp_CLS + | CountOp_CNT -> ArmV8_embed_types.CountOp_CNT + +let translate_memBarrierOp _ = function + | MemBarrierOp_DSB -> ArmV8_embed_types.MemBarrierOp_DSB + | MemBarrierOp_DMB -> ArmV8_embed_types.MemBarrierOp_DMB + | MemBarrierOp_ISB -> ArmV8_embed_types.MemBarrierOp_ISB + +let translate_mBReqDomain _ = function + | MBReqDomain_Nonshareable -> ArmV8_embed_types.MBReqDomain_Nonshareable + | MBReqDomain_InnerShareable -> ArmV8_embed_types.MBReqDomain_InnerShareable + | MBReqDomain_OuterShareable -> ArmV8_embed_types.MBReqDomain_OuterShareable + | MBReqDomain_FullSystem -> ArmV8_embed_types.MBReqDomain_FullSystem + +let translate_mBReqTypes _ = function + | MBReqTypes_Reads -> ArmV8_embed_types.MBReqTypes_Reads + | MBReqTypes_Writes -> ArmV8_embed_types.MBReqTypes_Writes + | MBReqTypes_All -> ArmV8_embed_types.MBReqTypes_All + +let translate_systemHintOp _ = function + | SystemHintOp_NOP -> ArmV8_embed_types.SystemHintOp_NOP + | SystemHintOp_YIELD -> ArmV8_embed_types.SystemHintOp_YIELD + | SystemHintOp_WFE -> ArmV8_embed_types.SystemHintOp_WFE + | SystemHintOp_WFI -> ArmV8_embed_types.SystemHintOp_WFI + | SystemHintOp_SEV -> ArmV8_embed_types.SystemHintOp_SEV + | SystemHintOp_SEVL -> ArmV8_embed_types.SystemHintOp_SEVL + +let translate_accType _ = function + | AccType_NORMAL -> ArmV8_embed_types.AccType_NORMAL + | AccType_VEC -> ArmV8_embed_types.AccType_VEC + | AccType_STREAM -> ArmV8_embed_types.AccType_STREAM + | AccType_VECSTREAM -> ArmV8_embed_types.AccType_VECSTREAM + | AccType_ATOMIC -> ArmV8_embed_types.AccType_ATOMIC + | AccType_ORDERED -> ArmV8_embed_types.AccType_ORDERED + | AccType_UNPRIV -> ArmV8_embed_types.AccType_UNPRIV + | AccType_IFETCH -> ArmV8_embed_types.AccType_IFETCH + | AccType_PTW -> ArmV8_embed_types.AccType_PTW + | AccType_DC -> ArmV8_embed_types.AccType_DC + | AccType_IC -> ArmV8_embed_types.AccType_IC + | AccType_AT -> ArmV8_embed_types.AccType_AT + +let translate_memOp _ = function + | MemOp_LOAD -> ArmV8_embed_types.MemOp_LOAD + | MemOp_STORE -> ArmV8_embed_types.MemOp_STORE + | MemOp_PREFETCH -> ArmV8_embed_types.MemOp_PREFETCH + +let translate_moveWideOp _ = function + | MoveWideOp_N -> ArmV8_embed_types.MoveWideOp_N + | MoveWideOp_Z -> ArmV8_embed_types.MoveWideOp_Z + | MoveWideOp_K -> ArmV8_embed_types.MoveWideOp_K + +let translate_revOp _ = function + | RevOp_RBIT -> ArmV8_embed_types.RevOp_RBIT + | RevOp_REV16 -> ArmV8_embed_types.RevOp_REV16 + | RevOp_REV32 -> ArmV8_embed_types.RevOp_REV32 + | RevOp_REV64 -> ArmV8_embed_types.RevOp_REV64 + +let translate_pSTATEField _ = function + | PSTATEField_DAIFSet -> ArmV8_embed_types.PSTATEField_DAIFSet + | PSTATEField_DAIFClr -> ArmV8_embed_types.PSTATEField_DAIFClr + | PSTATEField_SP -> ArmV8_embed_types.PSTATEField_SP diff --git a/arm/gen/lexer.hgen b/arm/gen/lexer.hgen new file mode 100644 index 00000000..6ff24317 --- /dev/null +++ b/arm/gen/lexer.hgen @@ -0,0 +1,309 @@ +(* instructions: *) + + "TSTART" , TSTART {txt="TSTART"} ; + "TCOMMIT", TCOMMIT {txt="TCOMMIT"} ; + "TABORT" , TABORT {txt="TABORT"} ; + "TTEST" , TTEST {txt="TTEST"} ; + + "ADC" , ADCSBC {txt="ADC"; sub_op = false; setflags = false} ; + "SBC" , ADCSBC {txt="SBC"; sub_op = true; setflags = false} ; + "ADCS" , ADCSBC {txt="ADCS"; sub_op = false; setflags = true} ; + "SBCS" , ADCSBC {txt="SBCS"; sub_op = true; setflags = true} ; + + "ADD" , ADDSUB {txt="ADD"; sub_op=false; setflags=false} ; + "SUB" , ADDSUB {txt="SUB"; sub_op=true; setflags=false} ; + "ADDS" , ADDSUB {txt="ADDS"; sub_op=false; setflags=true} ; + "SUBS" , ADDSUB {txt="SUBS"; sub_op=true; setflags=true} ; + + "ADR" , ADR {txt="ADR"; page=false} ; + "ADRP" , ADR {txt="ADRP"; page=true} ; + + "AND" , LOGOP {txt="AND"; op = LogicalOp_AND; setflags = false; invert = false} ; + "ANDS" , LOGOP {txt="ANDS"; op = LogicalOp_AND; setflags = true; invert = false} ; + "EOR" , LOGOP {txt="EOR"; op = LogicalOp_EOR; setflags = false; invert = false} ; + "ORR" , LOGOP {txt="ORR"; op = LogicalOp_ORR; setflags = false; invert = false} ; + "BIC" , LOGOP {txt="BIC"; op = LogicalOp_AND; setflags = false; invert = true} ; + "BICS" , LOGOP {txt="BICS"; op = LogicalOp_AND; setflags = true; invert = true} ; + "EON" , LOGOP {txt="EON"; op = LogicalOp_EOR; setflags = false; invert = true} ; + "ORN" , LOGOP {txt="ORN"; op = LogicalOp_ORR; setflags = false; invert = true} ; + + "ASRV" , SHIFTOP {txt="ASRV"; shift_type=ShiftType_ASR} ; + "LSLV" , SHIFTOP {txt="LSLV"; shift_type=ShiftType_LSL} ; + "LSRV" , SHIFTOP {txt="LSRV"; shift_type=ShiftType_LSR} ; + "RORV" , SHIFTOP {txt="RORV"; shift_type=ShiftType_ROR} ; + + "B.EQ" , BCOND {txt="B.EQ"; condition=0b0000} ; + "B.NE" , BCOND {txt="B.NE"; condition=0b0001} ; + "B.CS" , BCOND {txt="B.CS"; condition=0b0010} ; + "B.HS" , BCOND {txt="B.CS"; condition=0b0010} ; + "B.CC" , BCOND {txt="B.CC"; condition=0b0011} ; + "B.LO" , BCOND {txt="B.CC"; condition=0b0011} ; + "B.MI" , BCOND {txt="B.MI"; condition=0b0100} ; + "B.PL" , BCOND {txt="B.PL"; condition=0b0101} ; + "B.VS" , BCOND {txt="B.VS"; condition=0b0110} ; + "B.VC" , BCOND {txt="B.VC"; condition=0b0111} ; + "B.HI" , BCOND {txt="B.HI"; condition=0b1000} ; + "B.LS" , BCOND {txt="B.LS"; condition=0b1001} ; + "B.GE" , BCOND {txt="B.GE"; condition=0b1010} ; + "B.LT" , BCOND {txt="B.LT"; condition=0b1011} ; + "B.GT" , BCOND {txt="B.GT"; condition=0b1100} ; + "B.LE" , BCOND {txt="B.LE"; condition=0b1101} ; + "B.AL" , BCOND {txt="B.AL"; condition=0b1110} ; + "B.NV" , BCOND {txt="B.NV"; condition=0b1111} ; (* ARM: exists only to provide a valid disassembly + of the 0b1111 encoding, otherwise its + behavior is identical to AL *) + + "B" , B {txt="B"; branch_type=BranchType_JMP} ; + "BL" , B {txt="BL"; branch_type=BranchType_CALL} ; + + "BR" , BR {txt="BR"; branch_type=BranchType_JMP} ; + "BLR" , BR {txt="BLR"; branch_type=BranchType_CALL} ; + + "CBZ" , CBZ {txt="CBZ"; iszero=true} ; + "CBNZ" , CBZ {txt="CBNZ"; iszero=false} ; + + "BFM" , BFM {txt="BFM"; inzero=false; extend=false} ; + "SBFM" , BFM {txt="SBFM"; inzero=true; extend=true} ; + "UBFM" , BFM {txt="UBFM"; inzero=true; extend=false} ; + + "CCMN" , CCM {txt="CCMN"; sub_op=false} ; + "CCMP" , CCM {txt="CCMP"; sub_op=true} ; + + "CMN" , CM {txt="CMN"; sub_op=false} ; + "CMP" , CM {txt="CMP"; sub_op=true} ; + + "CLS" , CL {txt="CLS"; opcode=CountOp_CLS} ; + "CLZ" , CL {txt="CLZ"; opcode=CountOp_CLZ} ; + + "CRC32B" , CRC {txt="CRC32B"; size = DataSize8; crc32c = false} ; + "CRC32H" , CRC {txt="CRC32H"; size = DataSize16; crc32c = false} ; + "CRC32W" , CRC {txt="CRC32W"; size = DataSize32; crc32c = false} ; + "CRC32CB" , CRC {txt="CRC32CB"; size = DataSize8; crc32c = true} ; + "CRC32CH" , CRC {txt="CRC32CH"; size = DataSize16; crc32c = true} ; + "CRC32CW" , CRC {txt="CRC32CW"; size = DataSize32; crc32c = true} ; + + "CRC32X" , CRC32X {txt="CRC32X"; crc32c=false} ; + "CRC32CX" , CRC32X {txt="CRC32CX"; crc32c=true} ; + + "CSEL" , CSEL {txt="CSEL"; else_inv = false; else_inc = false} ; + "CSINC" , CSEL {txt="CSINC"; else_inv = false; else_inc = true} ; + "CSINV" , CSEL {txt="CSINV"; else_inv = true; else_inc = false} ; + "CSNEG" , CSEL {txt="CSNEG"; else_inv = true; else_inc = true} ; + + "CSET" , CSET {txt="CSET"; else_inv = false; else_inc = true} ; + "CSETM" , CSETM {txt="CSETM"; else_inv = true; else_inc = false} ; + + "CINC" , CON {txt="CINC"; else_inv = false; else_inc = true} ; + "CINV" , CON {txt="CINV"; else_inv = true; else_inc = false} ; + "CNEG" , CON {txt="CNEG"; else_inv = true; else_inc = true} ; + + "DMB" , MEMBARR {txt="DMB"; op=MemBarrierOp_DMB} ; + "DSB" , MEMBARR {txt="DSB"; op=MemBarrierOp_DSB} ; + + "LDAR" , LDAXR {txt="LDAR"; acctype=AccType_ORDERED; excl=false; memop=MemOp_LOAD; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "LDARB" , LDAXR {txt="LDARB"; acctype=AccType_ORDERED; excl=false; memop=MemOp_LOAD; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "LDARH" , LDAXR {txt="LDARH"; acctype=AccType_ORDERED; excl=false; memop=MemOp_LOAD; var32={elsize=16; datasize=DataSize16}; var64=false} ; + "LDAXR" , LDAXR {txt="LDAXR"; acctype=AccType_ORDERED; excl=true; memop=MemOp_LOAD; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "LDAXRB" , LDAXR {txt="LDAXRB"; acctype=AccType_ORDERED; excl=true; memop=MemOp_LOAD; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "LDAXRH" , LDAXR {txt="LDAXRH"; acctype=AccType_ORDERED; excl=true; memop=MemOp_LOAD; var32={elsize=16; datasize=DataSize16}; var64=false} ; + "LDXR" , LDAXR {txt="LDXR"; acctype=AccType_ATOMIC; excl=true; memop=MemOp_LOAD; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "LDXRB" , LDAXR {txt="LDXRB"; acctype=AccType_ATOMIC; excl=true; memop=MemOp_LOAD; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "LDXRH" , LDAXR {txt="LDXRH"; acctype=AccType_ATOMIC; excl=true; memop=MemOp_LOAD; var32={elsize=16; datasize=DataSize16}; var64=false} ; + "STLR" , LDAXR {txt="STLR"; acctype=AccType_ORDERED; excl=false; memop=MemOp_STORE; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "STLRB" , LDAXR {txt="STLRB"; acctype=AccType_ORDERED; excl=false; memop=MemOp_STORE; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "STLRH" , LDAXR {txt="STLRH"; acctype=AccType_ORDERED; excl=false; memop=MemOp_STORE; var32={elsize=16; datasize=DataSize16}; var64=false} ; + + "STLXR" , STLXR {txt="STLXR"; acctype=AccType_ORDERED; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "STLXRB" , STLXR {txt="STLXRB"; acctype=AccType_ORDERED; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "STLXRH" , STLXR {txt="STLXRH"; acctype=AccType_ORDERED; var32={elsize=16; datasize=DataSize16}; var64=false} ; + "STXR" , STLXR {txt="STXR"; acctype=AccType_ATOMIC; var32={elsize=32; datasize=DataSize32}; var64=true} ; + "STXRB" , STLXR {txt="STXRB"; acctype=AccType_ATOMIC; var32={elsize=8; datasize=DataSize8}; var64=false} ; + "STXRH" , STLXR {txt="STXRH"; acctype=AccType_ATOMIC; var32={elsize=16; datasize=DataSize16}; var64=false} ; + + + "LDAXP" , LDXP {txt="LDAXP"; acctype=AccType_ORDERED} ; + "LDXP" , LDXP {txt="LDXP"; acctype=AccType_ATOMIC} ; + + "STLXP" , STXP {txt="STLXP"; acctype=AccType_ORDERED} ; + "STXP" , STXP {txt="STXP"; acctype=AccType_ATOMIC} ; + + "LDR" , LDSTR {txt="LDR"; memop=MemOp_LOAD; signed=false; lit32=true; var32=Some {datasize=DataSize32}; var64=Some {datasize=DataSize64}; lit64=Some {datasize=DataSize64; size=8}} ; + "LDRB" , LDSTR {txt="LDRB"; memop=MemOp_LOAD; signed=false; lit32=false; var32=Some {datasize=DataSize8}; var64=None; lit64=None} ; + "LDRH" , LDSTR {txt="LDRH"; memop=MemOp_LOAD; signed=false; lit32=false; var32=Some {datasize=DataSize16}; var64=None; lit64=None} ; + "LDRSB" , LDSTR {txt="LDRSB"; memop=MemOp_LOAD; signed=true; lit32=false; var32=Some {datasize=DataSize8}; var64=Some {datasize=DataSize8}; lit64=None} ; + "LDRSH" , LDSTR {txt="LDRSH"; memop=MemOp_LOAD; signed=true; lit32=false; var32=Some {datasize=DataSize16}; var64=Some {datasize=DataSize16}; lit64=None} ; + "LDRSW" , LDSTR {txt="LDRSW"; memop=MemOp_LOAD; signed=true; lit32=false; var32=None; var64=Some {datasize=DataSize32}; lit64=Some {datasize=DataSize32; size=4}} ; + "STR" , LDSTR {txt="STR"; memop=MemOp_STORE; signed=false; lit32=false; var32=Some {datasize=DataSize32}; var64=Some {datasize=DataSize64}; lit64=None} ; + "STRB" , LDSTR {txt="STRB"; memop=MemOp_STORE; signed=false; lit32=false; var32=Some {datasize=DataSize8}; var64=None; lit64=None} ; + "STRH" , LDSTR {txt="STRH"; memop=MemOp_STORE; signed=false; lit32=false; var32=Some {datasize=DataSize16}; var64=None; lit64=None} ; + + "LDTR" , LDSTTUR {txt="LDTR"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize32}; off64=Some {datasize=DataSize64}} ; + "LDTRB" , LDSTTUR {txt="LDTRB"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize8}; off64=None} ; + "LDTRH" , LDSTTUR {txt="LDTRH"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize16}; off64=None} ; + "LDTRSB" , LDSTTUR {txt="LDTRSB"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=true; off32=Some {datasize=DataSize8}; off64=Some {datasize=DataSize8}} ; + "LDTRSH" , LDSTTUR {txt="LDTRSH"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=true; off32=Some {datasize=DataSize16}; off64=Some {datasize=DataSize16}} ; + "LDTRSW" , LDSTTUR {txt="LDTRSW"; memop=MemOp_LOAD; acctype=AccType_UNPRIV; signed=true; off32=None; off64=Some {datasize=DataSize32}} ; + "LDUR" , LDSTTUR {txt="LDUR"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize32}; off64=Some {datasize=DataSize64}} ; + "LDURB" , LDSTTUR {txt="LDURB"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize8}; off64=None} ; + "LDURH" , LDSTTUR {txt="LDURH"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize16}; off64=None} ; + "LDURSB" , LDSTTUR {txt="LDURSB"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=true; off32=Some {datasize=DataSize8}; off64=Some {datasize=DataSize8}} ; + "LDURSH" , LDSTTUR {txt="LDURSH"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=true; off32=Some {datasize=DataSize16}; off64=Some {datasize=DataSize16}} ; + "LDURSW" , LDSTTUR {txt="LDURSW"; memop=MemOp_LOAD; acctype=AccType_NORMAL; signed=true; off32=None; off64=Some {datasize=DataSize32}} ; + "STTR" , LDSTTUR {txt="STTR"; memop=MemOp_STORE; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize32}; off64=Some {datasize=DataSize64}} ; + "STTRB" , LDSTTUR {txt="STTRB"; memop=MemOp_STORE; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize8}; off64=None} ; + "STTRH" , LDSTTUR {txt="STTRH"; memop=MemOp_STORE; acctype=AccType_UNPRIV; signed=false; off32=Some {datasize=DataSize16}; off64=None} ; + "STUR" , LDSTTUR {txt="STUR"; memop=MemOp_STORE; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize32}; off64=Some {datasize=DataSize64}} ; + "STURB" , LDSTTUR {txt="STURB"; memop=MemOp_STORE; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize8}; off64=None} ; + "STURH" , LDSTTUR {txt="STURH"; memop=MemOp_STORE; acctype=AccType_NORMAL; signed=false; off32=Some {datasize=DataSize16}; off64=None} ; + + "MADD" , MADDSUB {txt="MADD"; sub_op=false} ; + "MSUB" , MADDSUB {txt="MSUB"; sub_op=true} ; + + "MUL" , MUL {txt="MUL"; sub_op=false} ; + "MNEG" , MUL {txt="MNEG"; sub_op=true} ; + + "MOVK" , MOVWIDE {txt="MOVK"; opcode=MoveWideOp_K} ; + "MOVN" , MOVWIDE {txt="MOVN"; opcode=MoveWideOp_N} ; + "MOVZ" , MOVWIDE {txt="MOVZ"; opcode=MoveWideOp_Z} ; + + "NEG" , NEG {txt="NEG"; setflags=false} ; + "NEGS" , NEG {txt="NEGS"; setflags=true} ; + + "NGC" , NGC {txt="NGC"; setflags=false} ; + "NGCS" , NGC {txt="NGCS"; setflags=true} ; + + "RBIT" , REV {txt="RBIT"; op32=Some RevOp_RBIT; op64=RevOp_RBIT} ; + "REV" , REV {txt="REV"; op32=Some RevOp_REV32; op64=RevOp_REV64} ; + "REV16" , REV {txt="REV16"; op32=Some RevOp_REV16; op64=RevOp_REV16} ; + "REV32" , REV {txt="REV32"; op32=None; op64=RevOp_REV32} ; + + "SDIV" , DIV {txt="SDIV"; unsigned=false} ; + "UDIV" , DIV {txt="UDIV"; unsigned=true} ; + + "SMADDL" , MADDSUBL {txt="SMADDL"; sub_op=false; unsigned=false} ; + "SMSUBL" , MADDSUBL {txt="SMSUBL"; sub_op=true; unsigned=false} ; + "UMADDL" , MADDSUBL {txt="UMADDL"; sub_op=false; unsigned=true} ; + "UMSUBL" , MADDSUBL {txt="UMSUBL"; sub_op=true; unsigned=true} ; + + "SMULH" , MULH {txt="SMULH"; unsigned=false} ; + "UMULH" , MULH {txt="UMULH"; unsigned=true} ; + + "SMULL" , MULL {txt="SMULL"; unsigned=false} ; + "UMULL" , MULL {txt="UMULL"; unsigned=true} ; + + "LDP" , LDSTP {txt="LDP"; memop=MemOp_LOAD} ; + "STP" , LDSTP {txt="STP"; memop=MemOp_STORE} ; + + "TBZ" , TBZ {txt="TBZ"; bit_val=false} ; + "TBNZ" , TBZ {txt="TBNZ"; bit_val=true} ; + + "SBFIZ" , BFIZ {txt="SBFIZ"; extend=true} ; + "UBFIZ" , BFIZ {txt="UBFIZ"; extend=false} ; + + "SBFX" , BFX {txt="SBFX"; extend=true} ; + "UBFX" , BFX {txt="UBFX"; extend=false} ; + + "SMNEGL" , MNEGL {txt="SMNEGL"; unsigned=false} ; + "UMNEGL" , MNEGL {txt="UMNEGL"; unsigned=true} ; + + "BFI" , BFI {txt="BFI"} ; + "BFXIL" , BFXIL {txt="BFXIL"} ; + "CLREX" , CLREX {txt="CLREX"} ; + "EXTR" , EXTR {txt="EXTR"} ; + "HINT" , HINT {txt="HINT"} ; + "ISB" , ISB {txt="ISB"} ; + "LDPSW" , LDPSW {txt="LDPSW"} ; + "MOV" , MOV {txt="MOV"} ; + "MVN" , MVN {txt="MVN"} ; + "NOP" , NOP {txt="NOP"} ; + "PRFM" , PRFM {txt="PRFM"} ; + "PRFUM" , PRFUM {txt="PRFUM"} ; + "RET" , RET {txt="RET"} ; + "TST" , TST {txt="TST"} ; + "MRS" , MRS {txt="MRS"} ; + "MSR" , MSR {txt="MSR"} ; + + +(*** instructions/operands ***) + + "LSL" , SHIFT {txt="LSL"; shift_type=ShiftType_LSL} ; + "LSR" , SHIFT {txt="LSR"; shift_type=ShiftType_LSR} ; + "ASR" , SHIFT {txt="ASR"; shift_type=ShiftType_ASR} ; + "ROR" , SHIFT {txt="ROR"; shift_type=ShiftType_ROR} ; + + "UXTB" , EXTEND {txt="UXTB"; _type=ExtendType_UXTB; inst=Some {extend=false; imms=7}} ; + "UXTH" , EXTEND {txt="UXTH"; _type=ExtendType_UXTH; inst=Some {extend=false; imms=15}} ; + "UXTW" , EXTEND {txt="UXTW"; _type=ExtendType_UXTW; inst=None} ; + "UXTX" , EXTEND {txt="UXTX"; _type=ExtendType_UXTX; inst=None} ; + "SXTB" , EXTEND {txt="SXTB"; _type=ExtendType_SXTB; inst=Some {extend=true; imms=7}} ; + "SXTH" , EXTEND {txt="SXTH"; _type=ExtendType_SXTH; inst=Some {extend=true; imms=15}} ; + "SXTW" , EXTEND {txt="SXTW"; _type=ExtendType_SXTW; inst=Some {extend=true; imms=31}} ; + "SXTX" , EXTEND {txt="SXTX"; _type=ExtendType_SXTX; inst=None} ; + +(*** operands: ***) + + "EQ" , COND 0b0000 ; + "NE" , COND 0b0001 ; + "CS" , COND 0b0010 ; + "HS" , COND 0b0010 ; + "CC" , COND 0b0011 ; + "LO" , COND 0b0011 ; + "MI" , COND 0b0100 ; + "PL" , COND 0b0101 ; + "VS" , COND 0b0110 ; + "VC" , COND 0b0111 ; + "HI" , COND 0b1000 ; + "LS" , COND 0b1001 ; + "GE" , COND 0b1010 ; + "LT" , COND 0b1011 ; + "GT" , COND 0b1100 ; + "LE" , COND 0b1101 ; + "AL" , COND 0b1110 ; + "NV" , COND 0b1111 ; (* ARM: exists only to provide a valid disassembly + of the 0b1111 encoding, otherwise its + behavior is identical to AL *) + + "OSHLD" , BARROP {domain=MBReqDomain_OuterShareable; types=MBReqTypes_Reads} ; + "OSHST" , BARROP {domain=MBReqDomain_OuterShareable; types=MBReqTypes_Writes} ; + "OSH" , BARROP {domain=MBReqDomain_OuterShareable; types=MBReqTypes_All} ; + "NSHLD" , BARROP {domain=MBReqDomain_Nonshareable; types=MBReqTypes_Reads} ; + "NSHST" , BARROP {domain=MBReqDomain_Nonshareable; types=MBReqTypes_Writes} ; + "NSH" , BARROP {domain=MBReqDomain_Nonshareable; types=MBReqTypes_All} ; + "ISHLD" , BARROP {domain=MBReqDomain_InnerShareable; types=MBReqTypes_Reads} ; + "ISHST" , BARROP {domain=MBReqDomain_InnerShareable; types=MBReqTypes_Writes} ; + "ISH" , BARROP {domain=MBReqDomain_InnerShareable; types=MBReqTypes_All} ; + "LD" , BARROP {domain=MBReqDomain_FullSystem; types=MBReqTypes_Reads} ; + "ST" , BARROP {domain=MBReqDomain_FullSystem; types=MBReqTypes_Writes} ; + "SY" , BARROP {domain=MBReqDomain_FullSystem; types=MBReqTypes_All} ; + + "PLDL1KEEP" , PRFOP (X (Ireg R0)) ; + "PLDL1STRM" , PRFOP (X (Ireg R1)) ; + "PLDL2KEEP" , PRFOP (X (Ireg R2)) ; + "PLDL2STRM" , PRFOP (X (Ireg R3)) ; + "PLDL3KEEP" , PRFOP (X (Ireg R4)) ; + "PLDL3STRM" , PRFOP (X (Ireg R5)) ; + + "PLIL1KEEP" , PRFOP (X (Ireg R8)) ; + "PLIL1STRM" , PRFOP (X (Ireg R9)) ; + "PLIL2KEEP" , PRFOP (X (Ireg R10)) ; + "PLIL2STRM" , PRFOP (X (Ireg R11)) ; + "PLIL3KEEP" , PRFOP (X (Ireg R12)) ; + "PLIL3STRM" , PRFOP (X (Ireg R13)) ; + + "PSTL1KEEP" , PRFOP (X (Ireg R16)) ; + "PSTL1STRM" , PRFOP (X (Ireg R17)) ; + "PSTL2KEEP" , PRFOP (X (Ireg R18)) ; + "PSTL2STRM" , PRFOP (X (Ireg R19)) ; + "PSTL3KEEP" , PRFOP (X (Ireg R20)) ; + "PSTL3STRM" , PRFOP (X (Ireg R21)) ; + + "NZCV" , SYSREG {sys_op0=0b11; sys_op1=0b011; sys_op2=0b000; sys_crn=0b0100; sys_crm=0b0010} ; + "DAIF" , SYSREG {sys_op0=0b11; sys_op1=0b011; sys_op2=0b001; sys_crn=0b0100; sys_crm=0b0010} ; + "TPIDR_EL0" , SYSREG {sys_op0=0b11; sys_op1=0b011; sys_op2=0b010; sys_crn=0b1101; sys_crm=0b0000} ; + "TPIDR_EL1" , SYSREG {sys_op0=0b11; sys_op1=0b000; sys_op2=0b100; sys_crn=0b1101; sys_crm=0b0000} ; + "TPIDR_EL2" , SYSREG {sys_op0=0b11; sys_op1=0b100; sys_op2=0b010; sys_crn=0b1101; sys_crm=0b0000} ; + "TPIDR_EL3" , SYSREG {sys_op0=0b11; sys_op1=0b011; sys_op2=0b011; sys_crn=0b1101; sys_crm=0b0000} ; + + "SPSel" , PSTATEFIELD (PSTATEField_SP) ; + "DAIFSet" , PSTATEFIELD (PSTATEField_DAIFSet) ; + "DAIFClr" , PSTATEFIELD (PSTATEField_DAIFClr) ; diff --git a/arm/gen/map.hgen b/arm/gen/map.hgen new file mode 100644 index 00000000..62899c91 --- /dev/null +++ b/arm/gen/map.hgen @@ -0,0 +1,44 @@ +| `AArch64TMStart t -> `AArch64TMStart (map_reg t) +| `AArch64TMCommit -> `AArch64TMCommit +| `AArch64TMAbort (retry,reason) -> `AArch64TMAbort (retry,reason) +| `AArch64TMTest -> `AArch64TMTest + +| `AArch64ImplementationDefinedStopFetching -> `AArch64ImplementationDefinedStopFetching +| `AArch64ImplementationDefinedThreadStart -> `AArch64ImplementationDefinedThreadStart +| `AArch64ImplementationDefinedTestBeginEnd (isEnd) -> `AArch64ImplementationDefinedTestBeginEnd (isEnd) +| `AArch64AddSubCarry (d,n,m,datasize,sub_op,setflags) -> `AArch64AddSubCarry (map_reg d,map_reg n,map_reg m,datasize,sub_op,setflags) +| `AArch64AddSubExtendRegister (d,n,m,datasize,sub_op,setflags,extend_type,shift) -> `AArch64AddSubExtendRegister (map_reg d,map_reg n,map_reg m,datasize,sub_op,setflags,extend_type,shift) +| `AArch64AddSubShiftedRegister (d,n,m,datasize,sub_op,setflags,shift_type,shift_amount) -> `AArch64AddSubShiftedRegister (map_reg d,map_reg n,map_reg m,datasize,sub_op,setflags,shift_type,shift_amount) +| `AArch64AddSubImmediate (d,n,datasize,sub_op,setflags,imm) -> `AArch64AddSubImmediate (map_reg d,map_reg n,datasize,sub_op,setflags,imm) +| `AArch64Address (d,page,imm) -> `AArch64Address (map_reg d,page,imm) +| `AArch64LogicalImmediate (d,n,datasize,setflags,op,imm) -> `AArch64LogicalImmediate (map_reg d,map_reg n,datasize,setflags,op,imm) +| `AArch64LogicalShiftedRegister (d,n,m,datasize,setflags,op,shift_type,shift_amount,invert) -> `AArch64LogicalShiftedRegister (map_reg d,map_reg n,map_reg m,datasize,setflags,op,shift_type,shift_amount,invert) +| `AArch64Shift (d,n,m,datasize,shift_type) -> `AArch64Shift (map_reg d,map_reg n,map_reg m,datasize,shift_type) +| `AArch64BranchConditional (offset,condition) -> `AArch64BranchConditional (offset,condition) +| `AArch64BranchImmediate (branch_type,offset) -> `AArch64BranchImmediate (branch_type,offset) +| `AArch64BitfieldMove (d,n,datasize,inzero,extend,_R,_S,wmask,tmask) -> `AArch64BitfieldMove (map_reg d,map_reg n,datasize,inzero,extend,_R,_S,wmask,tmask) +| `AArch64BranchRegister (n,branch_type) -> `AArch64BranchRegister (map_reg n,branch_type) +| `AArch64CompareAndBranch (t,datasize,iszero,offset) -> `AArch64CompareAndBranch (map_reg t,datasize,iszero,offset) +| `AArch64ConditionalCompareImmediate (n,datasize,sub_op,condition,flags,imm) -> `AArch64ConditionalCompareImmediate (map_reg n,datasize,sub_op,condition,flags,imm) +| `AArch64ConditionalCompareRegister (n,m,datasize,sub_op,condition,flags) -> `AArch64ConditionalCompareRegister (map_reg n,map_reg m,datasize,sub_op,condition,flags) +| `AArch64ClearExclusiveMonitor (imm) -> `AArch64ClearExclusiveMonitor (imm) +| `AArch64CountLeading (d,n,datasize,opcode) -> `AArch64CountLeading (map_reg d,map_reg n,datasize,opcode) +| `AArch64CRC (d,n,m,size,crc32c) -> `AArch64CRC (map_reg d,map_reg n,map_reg m,size,crc32c) +| `AArch64ConditionalSelect (d,n,m,datasize,condition,else_inv,else_inc) -> `AArch64ConditionalSelect (map_reg d,map_reg n,map_reg m,datasize,condition,else_inv,else_inc) +| `AArch64Barrier (op,domain,types) -> `AArch64Barrier (op,domain,types) +| `AArch64ExtractRegister (d,n,m,datasize,lsb) -> `AArch64ExtractRegister (map_reg d,map_reg n,map_reg m,datasize,lsb) +| `AArch64Hint (op) -> `AArch64Hint (op) +| `AArch64LoadStoreAcqExc (n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) -> `AArch64LoadStoreAcqExc (map_reg n,map_reg t,map_reg t2,map_reg s,acctype,excl,pair,memop,elsize,regsize,datasize) +| `AArch64LoadStorePair (wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset) -> `AArch64LoadStorePair (wback,postindex,map_reg n,map_reg t,map_reg t2,acctype,memop,signed,datasize,offset) +| `AArch64LoadImmediate (n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) -> `AArch64LoadImmediate (map_reg n,map_reg t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) +| `AArch64LoadLiteral (t,memop,signed,size,offset,datasize) -> `AArch64LoadLiteral (map_reg t,memop,signed,size,offset,datasize) +| `AArch64LoadRegister (n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) -> `AArch64LoadRegister (map_reg n,map_reg t,map_reg m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) +| `AArch64MultiplyAddSub (d,n,m,a,destsize,datasize,sub_op) -> `AArch64MultiplyAddSub (map_reg d,map_reg n,map_reg m,map_reg a,destsize,datasize,sub_op) +| `AArch64MoveWide (d,datasize,imm,pos,opcode) -> `AArch64MoveWide (map_reg d,datasize,imm,pos,opcode) +| `AArch64Reverse (d,n,datasize,op) -> `AArch64Reverse (map_reg d,map_reg n,datasize,op) +| `AArch64Division (d,n,m,datasize,unsigned) -> `AArch64Division (map_reg d,map_reg n,map_reg m,datasize,unsigned) +| `AArch64MultiplyAddSubLong (d,n,m,a,destsize,datasize,sub_op,unsigned) -> `AArch64MultiplyAddSubLong (map_reg d,map_reg n,map_reg m,map_reg a,destsize,datasize,sub_op,unsigned) +| `AArch64MultiplyHigh (d,n,m,a,destsize,datasize,unsigned) -> `AArch64MultiplyHigh (map_reg d,map_reg n,map_reg m,map_reg a,destsize,datasize,unsigned) +| `AArch64TestBitAndBranch (t,datasize,bit_pos,bit_val,offset) -> `AArch64TestBitAndBranch (map_reg t,datasize,bit_pos,bit_val,offset) +| `AArch64MoveSystemRegister (t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) -> `AArch64MoveSystemRegister (map_reg t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) +| `AArch64MoveSystemImmediate (operand,field) -> `AArch64MoveSystemImmediate (operand,field) diff --git a/arm/gen/parser.hgen b/arm/gen/parser.hgen new file mode 100644 index 00000000..94ce6fcf --- /dev/null +++ b/arm/gen/parser.hgen @@ -0,0 +1,1396 @@ + /* TSTART */ + | TSTART xreg + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xt>") + else `AArch64TMStart $2 } + + /* TCOMMIT */ + | TCOMMIT + { `AArch64TMCommit } + + /* TABORT */ + | TABORT imm + { if not (iskbituimm 6 $2) then error_arg "<imm> must be in the range 0 to 63" + else `AArch64TMAbort (($2 lsr 5) <> 0, $2 mod 32) } + + /* TTEST */ + | TTEST + {`AArch64TMTest} + + | ADCSBC wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>") + else `AArch64AddSubCarry ($2,$4,$6,Set32,$1.sub_op,$1.setflags) } + | ADCSBC xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>") + else `AArch64AddSubCarry ($2,$4,$6,Set64,$1.sub_op,$1.setflags) } + + /* ADC/ADCS/SBC/SBCS */ + + | ADCSBC wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>") + else `AArch64AddSubCarry ($2,$4,$6,Set32,$1.sub_op,$1.setflags) } + | ADCSBC xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>") + else `AArch64AddSubCarry ($2,$4,$6,Set64,$1.sub_op,$1.setflags) } + + /* ADD/SUB/ADDS/SUBS (extended register), and when noted (shifted register) */ + + | ADDSUB wreg COMMA wreg COMMA wreg + { (* ambiguous with (shifted register) *) + if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then + error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then + error_registers ("expected " ^ $1.txt ^ " <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,ExtendType_UXTW,0) } + | ADDSUB wreg COMMA wreg COMMA wreg COMMA EXTEND + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then + error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then + error_registers ("expected " ^ $1.txt ^ " <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,$8._type,0) } + | ADDSUB wreg COMMA wreg COMMA wreg COMMA SHIFT + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if (not $1.setflags) && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,ExtendType_UXTW,0) } + | ADDSUB wreg COMMA wreg COMMA wreg COMMA EXTEND imm + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not (0 <= $9 && $9 <= 4) then error_arg "<amount> must be in the range 0 to 4" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,$8._type,$9) } + | ADDSUB wreg COMMA wreg COMMA wreg COMMA SHIFT imm + { if (issp $2 || issp $4) then + begin + (* (extended register) *) + if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else if not (0 <= $9 && $9 <= 4) then error_arg "<amount> must be in the range 0 to 4" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,ExtendType_UXTW,$9) + end + else + begin + (* (shifted register) *) + if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>{, <shift> #<amount>}") + else if $8.shift_type = ShiftType_ROR then error_arg "<shift> must be one of LSL,LSR,ASR" + else if not (0 <= $9 && $9 <= 31) then error_arg "<amount> must be in the range 0 to 31" + else `AArch64AddSubShiftedRegister ($2,$4,$6,Set32,$1.sub_op,$1.setflags,$8.shift_type,$9) + end } + + | ADDSUB xreg COMMA xreg COMMA xreg + { (* ambiguous with (shifted register) *) + if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,0) } + | ADDSUB xreg COMMA xreg COMMA wreg COMMA EXTEND + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if $8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX then error_arg "<R> doesn't match <extend>" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,0) } + | ADDSUB xreg COMMA xreg COMMA wreg COMMA SHIFT + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,0) } + | ADDSUB xreg COMMA xreg COMMA wreg COMMA EXTEND imm + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not (0 <= $9 && $9 <= 4) then error_arg "<amount> must be in the range 0 to 4." + else if $8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX then error_arg "<R> doesn't match <extend>" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,$9) } + | ADDSUB xreg COMMA xreg COMMA wreg COMMA SHIFT imm + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else if not (0 <= $9 && $9 <= 4) then error_arg "<amount> must be in the range 0 to 4." + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,$9) } + | ADDSUB xreg COMMA xreg COMMA xreg COMMA EXTEND + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not ($8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX) then error_arg "<R> doesn't match <extend>" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,0) } + | ADDSUB xreg COMMA xreg COMMA xreg COMMA SHIFT + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,0) } + | ADDSUB xreg COMMA xreg COMMA xreg COMMA EXTEND imm + { if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not (0 <= $9 && $9 <= 4) then error_arg "<amount> must be in the range 0 to 4." + else if not ($8._type = ExtendType_UXTX || $8._type = ExtendType_SXTX) then error_arg "<R> doesn't match <extend>" + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8._type,$9) } + | ADDSUB xreg COMMA xreg COMMA xreg COMMA SHIFT imm + { if (issp $2 || issp $4) then + begin + (* (extended register) *) + if $1.setflags && not (isregzr $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not $1.setflags && not (isregsp $2 && isregsp $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not ($8.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else if not (0 <= $9 && $9 <= 4) then error_arg "<amount> must be in the range 0 to 4." + else `AArch64AddSubExtendRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,ExtendType_UXTX,$9) + end + else + begin + (* (shifted register) *) + if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>{, <shift> #<amount>}") + else if $8.shift_type = ShiftType_ROR then error_arg "<shift> must be one of LSL,LSR,ASR" + else if not (0 <= $9 && $9 <= 63) then error_arg "<amount> must be in the range 0 to 63" + else `AArch64AddSubShiftedRegister ($2,$4,$6,Set64,$1.sub_op,$1.setflags,$8.shift_type,$9) + end } + + /* ADD/SUB/ADDS/SUBS (immediate) */ + + | ADDSUB wreg COMMA wreg COMMA imm + { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn|WSP>, #<imm>{, <shift>}") + else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}") + else if not (0 <= $6 && $6 <= 4095) then error_arg "<imm> must be in the range 0 to 4095" + else `AArch64AddSubImmediate ($2,$4,Set32,$1.sub_op,$1.setflags,reg_size_bits_R32_of_int $6) } + | ADDSUB wreg COMMA wreg COMMA imm COMMA SHIFT imm + { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn|WSP>, #<imm>{, <shift>}") + else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}") + else if not (0 <= $6 && $6 <= 4095) then error_arg "<imm> must be in the range 0 to 4095" + else if not ($8.shift_type = ShiftType_LSL && ($9 = 0 || $9 = 12)) then error_arg "<shift> must be 'LSL #0' or 'LSL #12'" + else `AArch64AddSubImmediate ($2,$4,Set32,$1.sub_op,$1.setflags,reg_size_bits_R32_of_int ($6 lsl $9)) } + | ADDSUB xreg COMMA xreg COMMA imm + { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, #<imm>{, <shift>}") + else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}") + else if not (0 <= $6 && $6 <= 4095) then error_arg "<imm> must be in the range 0 to 4095" + else `AArch64AddSubImmediate ($2,$4,Set64,$1.sub_op,$1.setflags,reg_size_bits_R64_of_int $6) } + | ADDSUB xreg COMMA xreg COMMA imm COMMA SHIFT imm + { if $1.setflags && not (isregzr $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn|SP>, #<imm>{, <shift>}") + else if not $1.setflags && not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}") + else if not (0 <= $6 && $6 <= 4095) then error_arg "<imm> must be in the range 0 to 4095" + else if not ($8.shift_type = ShiftType_LSL && ($9 = 0 || $9 = 12)) then error_arg "<shift> must be 'LSL #0' or 'LSL #12'" + else `AArch64AddSubImmediate ($2,$4,Set64,$1.sub_op,$1.setflags,reg_size_bits_R64_of_int ($6 lsl $9)) } + + /* ADR/ADRP */ +/* + | ADR xreg COMMA NAME + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <label>") + else `AArch64Address ($2,$1.page,(* FIXME: label *)) } +*/ + + /* AND/ANDS/EOR/ORR (immediate) */ + + | LOGOP wreg COMMA wreg COMMA big_imm + { if $1.invert then error_arg "bad logical operator" + else if not $1.setflags && not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd|WSP>, <Wn>, #<imm>") + else if $1.setflags && not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, #<imm>") + else + match encodeBitMasks 32 $6 with + | None -> error_arg "<imm> can not be encoded as bitmask" + | _ -> `AArch64LogicalImmediate($2,$4,Set32,$1.setflags,$1.op,reg_size_bits_R32_of_big_int $6) } + | LOGOP xreg COMMA xreg COMMA big_imm + { if $1.invert then error_arg "bad logical operator" + else if not $1.setflags && not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn>, #<imm>") + else if $1.setflags && not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, #<imm>") + else + match encodeBitMasks 64 $6 with + | None -> error_arg "<imm> can not be encoded as bitmask" + | _ -> `AArch64LogicalImmediate($2,$4,Set64,$1.setflags,$1.op,reg_size_bits_R64_of_big_int $6) } + + /* AND/ANDS/EOR/ORR/BIC/BICS/EON/ORN (shifted register) */ + + | LOGOP wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>{, <shift> #<amount>}") + else `AArch64LogicalShiftedRegister($2,$4,$6,Set32,$1.setflags,$1.op,ShiftType_LSL,0,$1.invert) } + | LOGOP wreg COMMA wreg COMMA wreg COMMA SHIFT imm + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>{, <shift> #<amount>}") + else if not (0 <= $9 && $9 <= 31) then error_arg "<amount> must be in the range 0 to 31" + else `AArch64LogicalShiftedRegister($2,$4,$6,Set32,$1.setflags,$1.op,$8.shift_type,$9,$1.invert) } + + | LOGOP xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>{, <shift> #<amount>}") + else `AArch64LogicalShiftedRegister($2,$4,$6,Set64,$1.setflags,$1.op,ShiftType_LSL,0,$1.invert) } + | LOGOP xreg COMMA xreg COMMA xreg COMMA SHIFT imm + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>{, <shift> #<amount>}") + else if not (0 <= $9 && $9 <= 63) then error_arg "<amount> must be in the range 0 to 63" + else `AArch64LogicalShiftedRegister($2,$4,$6,Set64,$1.setflags,$1.op,$8.shift_type,$9,$1.invert) } + + + /* LSL/LSR/ASR/ROR (register) alias of LSLV/LSRV/ASRV/RORV */ + + | SHIFT wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>") + else `AArch64Shift($2,$4,$6,Set32,$1.shift_type) } + | SHIFT xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>") + else `AArch64Shift($2,$4,$6,Set64,$1.shift_type) } + + /* LSL/LSR/ASR/ROR (immediate) alias of UBFM/UBFM/SBFM/EXTR */ + + | SHIFT wreg COMMA wreg COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, #<shift>") + else if not (0 <= $6 && $6 <= 31) then error_arg "<shift> must be in the range 0 to 31" + else match $1.shift_type with + | ShiftType_ASR -> + let (wmask,tmask) = decodeBitMasks 32 0 31 $6 false in + `AArch64BitfieldMove($2,$4,Set32,true,true,$6,31,reg_size_bits_R32_of_big_int wmask,reg_size_bits_R32_of_big_int tmask) + | ShiftType_LSL -> + let (wmask,tmask) = decodeBitMasks 32 0 (31-$6) (-$6 mod 32) false in + `AArch64BitfieldMove($2,$4,Set32,true,false,-$6 mod 32,31-$6,reg_size_bits_R32_of_big_int wmask,reg_size_bits_R32_of_big_int tmask) + | ShiftType_LSR -> + let (wmask,tmask) = decodeBitMasks 32 0 31 $6 false in + `AArch64BitfieldMove($2,$4,Set32,true,false,$6,31,reg_size_bits_R32_of_big_int wmask,reg_size_bits_R32_of_big_int tmask) + | ShiftType_ROR -> + `AArch64ExtractRegister($2,$4,$4,Set32,$6) } + | SHIFT xreg COMMA xreg COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, #<shift>") + else if not (0 <= $6 && $6 <= 63) then error_arg "<shift> must be in the range 0 to 64" + else match $1.shift_type with + | ShiftType_ASR -> + let (wmask,tmask) = decodeBitMasks 64 1 63 $6 false in + `AArch64BitfieldMove($2,$4,Set64,true,true,$6,63,reg_size_bits_R64_of_big_int wmask,reg_size_bits_R64_of_big_int tmask) + | ShiftType_LSL -> + let (wmask,tmask) = decodeBitMasks 64 1 (63-$6) ((64-$6) mod 64) false in + `AArch64BitfieldMove($2,$4,Set64,true,false,(64-$6) mod 64,63-$6,reg_size_bits_R64_of_big_int wmask,reg_size_bits_R64_of_big_int tmask) + | ShiftType_LSR -> + let (wmask,tmask) = decodeBitMasks 64 1 63 $6 false in + `AArch64BitfieldMove($2,$4,Set64,true,false,$6,63,reg_size_bits_R64_of_big_int wmask,reg_size_bits_R64_of_big_int tmask) + | ShiftType_ROR -> + `AArch64ExtractRegister($2,$4,$4,Set64,$6) } + + /* ASRV/LSLV/LSRV/RORV */ + + | SHIFTOP wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>") + else `AArch64Shift($2,$4,$6,Set32,$1.shift_type) } + | SHIFTOP xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>") + else `AArch64Shift($2,$4,$6,Set64,$1.shift_type) } + + /* B.cond */ +/* + | BCOND NAME + { `AArch64BranchConditional((* FIXME: label *),$1.condition) } +*/ + /* B/BL */ +/* + | B NAME + { `AArch64BranchImmediate($1.branch_type,(* FIXME: label *)) } +*/ + /* BFI alias of BFM */ + + | BFI wreg COMMA wreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, #<lsb>, #<width>") + else if not (0 <= $6 && $6 <= 31) then error_arg "<lsb> must be in the range 0 to 31" + else if not (1 <= $8 && $8 <= 32-$6) then error_arg "<width> must be in the range 1 to 32-<lsb>" + else + let (wmask,tmask) = decodeBitMasks 32 0 ($8 - 1) (-$6 mod 32) false in + `AArch64BitfieldMove($2,$4,Set32,false,false,(-$6 mod 32),($8 - 1),reg_size_bits_R32_of_big_int wmask,reg_size_bits_R32_of_big_int tmask) } + | BFI xreg COMMA xreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, #<lsb>, #<width>") + else if not (0 <= $6 && $6 <= 63) then error_arg "<lsb> must be in the range 0 to 63" + else if not (1 <= $8 && $8 <= 64-$6) then error_arg "<width> must be in the range 1 to 64-<lsb>" + else + let (wmask,tmask) = decodeBitMasks 64 1 ($8 - 1) (-$6 mod 64) false in + `AArch64BitfieldMove($2,$4,Set64,false,false,(-$6 mod 64),($8 - 1),reg_size_bits_R64_of_big_int wmask,reg_size_bits_R64_of_big_int tmask) } + + /* BFM/SBFM/UBFM */ + + | BFM wreg COMMA wreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, #<immr>, #<imms>") + else if not (0 <= $6 && $6 <= 31) then error_arg "<immr> must be in the range 0 to 31" + else if not (0 <= $8 && $8 <= 31) then error_arg "<imms> must be in the range 0 to 31" + else + let (wmask,tmask) = decodeBitMasks 32 0 $8 $6 false in + `AArch64BitfieldMove($2,$4,Set32,$1.inzero,$1.extend,$6,$8,reg_size_bits_R32_of_big_int wmask,reg_size_bits_R32_of_big_int tmask) } + | BFM xreg COMMA xreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, #<immr>, #<imms>") + else if not (0 <= $6 && $6 <= 63) then error_arg "<immr> must be in the range 0 to 63" + else if not (0 <= $8 && $8 <= 63) then error_arg "<imms> must be in the range 0 to 63" + else + let (wmask,tmask) = decodeBitMasks 64 1 $8 $6 false in + `AArch64BitfieldMove($2,$4,Set64,$1.inzero,$1.extend,$6,$8,reg_size_bits_R64_of_big_int wmask,reg_size_bits_R64_of_big_int tmask) } + + /* BFXIL alias of BFM */ + + | BFXIL wreg COMMA wreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, #<lsb>, #<width>") + else if not (0 <= $6 && $6 <= 31) then error_arg "<immr> must be in the range 0 to 31" + else if not (1 <= $8 && $8 <= 32-$6) then error_arg "<imms> must be in the range 1 to 32-<lsb>" + else + let (wmask,tmask) = decodeBitMasks 32 0 ($6+$8-1) $6 false in + `AArch64BitfieldMove($2,$4,Set32,false,false,$6,$6+$8-1,reg_size_bits_R32_of_big_int wmask,reg_size_bits_R32_of_big_int tmask) } + | BFXIL xreg COMMA xreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, #<lsb>, #<width>") + else if not (0 <= $6 && $6 <= 63) then error_arg "<immr> must be in the range 0 to 63" + else if not (1 <= $8 && $8 <= 64-$6) then error_arg "<imms> must be in the range 1 to 64-<lsb>" + else + let (wmask,tmask) = decodeBitMasks 64 1 ($6+$8-1) $6 false in + `AArch64BitfieldMove($2,$4,Set64,false,false,$6,$6+$8-1,reg_size_bits_R64_of_big_int wmask,reg_size_bits_R64_of_big_int tmask) } + + /* BR/BLR */ + + | BR xreg + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xn>") + else `AArch64BranchRegister($2,$1.branch_type) } + + /* CBZ/CBNZ */ +/* + | CBZ wreg COMMA NAME + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Wt>, <label>") + else `AArch64CompareAndBranch($2,Set32,$1.iszero,(* FIXME: label *)) } + | CBZ xreg COMMA NAME + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xt>, <label>") + else `AArch64CompareAndBranch($2,Set64,$1.iszero,(* FIXME: label *)) } +*/ + + /* CCMN/CCMP (immediate) */ + + | CCM wreg COMMA imm COMMA imm COMMA COND + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Wn>, #<imm>, #<nzcv>, <cond>") + else if not (iskbituimm 5 $4) then error_arg "<imm> must be in the range 0 to 31" + else if not (0 <= $6 && $6 <= 15) then error_arg "<nzcv> must be in the range 0 to 15" + else `AArch64ConditionalCompareImmediate($2,Set32,$1.sub_op,$8,$6,reg_size_bits_R32_of_int $4) } + | CCM xreg COMMA imm COMMA imm COMMA COND + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xn>, #<imm>, #<nzcv>, <cond>") + else if not (iskbituimm 5 $4) then error_arg "<imm> must be in the range 0 to 31" + else if not (0 <= $6 && $6 <= 15) then error_arg "<nzcv> must be in the range 0 to 15" + else `AArch64ConditionalCompareImmediate($2,Set64,$1.sub_op,$8,$6,reg_size_bits_R64_of_int $4) } + + /* CCMN/CCMP (register) */ + + | CCM wreg COMMA wreg COMMA imm COMMA COND + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wn>, <Wm>, #<nzcv>, <cond>") + else if not (0 <= $6 && $6 <= 15) then error_arg "<nzcv> must be in the range 0 to 15" + else `AArch64ConditionalCompareRegister($2,$4,Set32,$1.sub_op,$8,$6) } + | CCM xreg COMMA xreg COMMA imm COMMA COND + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn>, <Xm>, #<nzcv>, <cond>") + else if not (0 <= $6 && $6 <= 15) then error_arg "<nzcv> must be in the range 0 to 15" + else `AArch64ConditionalCompareRegister($2,$4,Set64,$1.sub_op,$8,$6) } + + /* CINC/CINV/CNEG alias of CSINC/CSINV/CSNEG */ + + | CON wreg COMMA wreg COMMA COND + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <cond>") + else if ($6 = 0b1110 || $6 = 0b1111) then error_arg "<cond> must not be AL or NV" + else `AArch64ConditionalSelect($2,$4,$4,Set32,invert $6,$1.else_inv,$1.else_inc) } + | CON xreg COMMA xreg COMMA COND + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <cond>") + else if ($6 = 0b1110 || $6 = 0b1111) then error_arg "<cond> must not be AL or NV" + else `AArch64ConditionalSelect($2,$4,$4,Set64,invert $6,$1.else_inv,$1.else_inc) } + + /* CLREX */ + + | CLREX + { `AArch64ClearExclusiveMonitor(15) } + | CLREX imm + { if not (iskbituimm 4 $2) then error_arg "<imm> must be in the range 0 to 15" + else `AArch64ClearExclusiveMonitor($2) } + + /* CLS/CLZ */ + + | CL wreg COMMA wreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>") + else `AArch64CountLeading($2,$4,Set32,$1.opcode) } + | CL xreg COMMA xreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>") + else `AArch64CountLeading($2,$4,Set64,$1.opcode) } + + /* CMN/CMP (extended register) alias of ADDS/SUBS (extended register) */ + + | CM wreg COMMA wreg + { (* ambiguous with (shifted register) *) + if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else `AArch64AddSubExtendRegister (W ZR,$2,$4,Set32,$1.sub_op,true,ExtendType_UXTW,0) } + | CM wreg COMMA wreg COMMA EXTEND + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else `AArch64AddSubExtendRegister (W ZR,$2,$4,Set32,$1.sub_op,true,$6._type,0) } + | CM wreg COMMA wreg COMMA SHIFT + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not ($6.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else `AArch64AddSubExtendRegister (W ZR,$2,$4,Set32,$1.sub_op,true,ExtendType_UXTW,0) } + | CM wreg COMMA wreg COMMA EXTEND imm + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not (0 <= $7 && $7 <= 4) then error_arg "<amount> must be in the range 0 to 4" + else `AArch64AddSubExtendRegister (W ZR,$2,$4,Set32,$1.sub_op,true,$6._type,$7) } + | CM wreg COMMA wreg COMMA SHIFT imm + { if issp $2 then + begin + (* (extended register) *) + if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wn|WSP>, <Wm>{, <extend> {#<amount>}}") + else if not ($6.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else if not (0 <= $7 && $7 <= 4) then error_arg "<amount> must be in the range 0 to 4" + else `AArch64AddSubExtendRegister (W ZR,$2,$4,Set32,$1.sub_op,true,ExtendType_UXTW,$7) + end + else + begin + (* (shifted register) *) + if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wn>, <Wm>{, <shift> #<amount>}") + else if $6.shift_type = ShiftType_ROR then error_arg "<shift> must be one of LSL,LSR,ASR" + else if not (0 <= $7 && $7 <= 31) then error_arg "<amount> must be in the range 0 to 31" + else `AArch64AddSubShiftedRegister (W ZR,$2,$4,Set32,$1.sub_op,true,$6.shift_type,$7) + end } + + | CM xreg COMMA xreg + { (* ambiguous with (shifted register) *) + if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else `AArch64AddSubExtendRegister (X ZR,$2,$4,Set64,$1.sub_op,true,ExtendType_UXTX,0) } + | CM xreg COMMA wreg COMMA EXTEND + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if $6._type = ExtendType_UXTX || $6._type = ExtendType_SXTX then error_arg "<R> doesn't match <extend>" + else `AArch64AddSubExtendRegister (X ZR,$2,$4,Set64,$1.sub_op,true,$6._type,0) } + | CM xreg COMMA wreg COMMA SHIFT + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not ($6.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else `AArch64AddSubExtendRegister (X ZR,$2,$4,Set64,$1.sub_op,true,ExtendType_UXTX,0) } + | CM xreg COMMA wreg COMMA EXTEND imm + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not (0 <= $7 && $7 <= 4) then error_arg "<amount> must be in the range 0 to 4." + else if $6._type = ExtendType_UXTX || $6._type = ExtendType_SXTX then error_arg "<R> doesn't match <extend>" + else `AArch64AddSubExtendRegister (X ZR,$2,$4,Set64,$1.sub_op,true,$6._type,$7) } + | CM xreg COMMA wreg COMMA SHIFT imm + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not ($6.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else if not (0 <= $7 && $7 <= 4) then error_arg "<amount> must be in the range 0 to 4." + else `AArch64AddSubExtendRegister (X ZR,$2,$4,Set64,$1.sub_op,true,ExtendType_UXTX,$7) } + | CM xreg COMMA xreg COMMA EXTEND + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not ($6._type = ExtendType_UXTX || $6._type = ExtendType_SXTX) then error_arg "<R> doesn't match <extend>" + else `AArch64AddSubExtendRegister (X ZR,$2,$4,Set64,$1.sub_op,true,$6._type,0) } + | CM xreg COMMA xreg COMMA SHIFT + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not ($6.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else `AArch64AddSubExtendRegister (X ZR,$2,$4,Set64,$1.sub_op,true,ExtendType_UXTX,0) } + | CM xreg COMMA xreg COMMA EXTEND imm + { if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, <R><m>{, <extend> {#<amount>}}") + else if not (0 <= $7 && $7 <= 4) then error_arg "<amount> must be in the range 0 to 4." + else if not ($6._type = ExtendType_UXTX || $6._type = ExtendType_SXTX) then error_arg "<R> doesn't match <extend>" + else `AArch64AddSubExtendRegister (X ZR,$2,$4,Set64,$1.sub_op,true,$6._type,$7) } + | CM xreg COMMA xreg COMMA SHIFT imm + { if issp $2 then + begin + (* (extended register) *) + if not (isregsp $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, <X ZR>") + else if not ($6.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of UXTB,UXTH,UXTW,UXTX,SXTB,SXTH,SXTW,SXTX,LSL" + else if not (0 <= $7 && $7 <= 4) then error_arg "<amount> must be in the range 0 to 4." + else `AArch64AddSubExtendRegister (X ZR,$2,$4,Set64,$1.sub_op,true,ExtendType_UXTX,$7) + end + else + begin + (* (shifted register) *) + if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn>, <Xm>{, <shift> #<amount>}") + else if $6.shift_type = ShiftType_ROR then error_arg "<shift> must be one of LSL,LSR,ASR" + else if not (0 <= $7 && $7 <= 63) then error_arg "<amount> must be in the range 0 to 63" + else `AArch64AddSubShiftedRegister (X ZR,$2,$4,Set64,$1.sub_op,true,$6.shift_type,$7) + end } + + /* CMN/CMP (immediate) alias of ADDS/SUBS (immediate) */ + + | CM wreg COMMA imm + { if not (isregsp $2) then error_registers ("expected " ^ $1.txt ^ " <Wn|WSP>, #<imm>{, <shift>}") + else if not (0 <= $4 && $4 <= 4095) then error_arg "<imm> must be in the range 0 to 4095" + else `AArch64AddSubImmediate (W ZR,$2,Set32,$1.sub_op,true,reg_size_bits_R32_of_int $4) } + | CM wreg COMMA imm COMMA SHIFT imm + { if not (isregsp $2) then error_registers ("expected " ^ $1.txt ^ " <Wn|WSP>, #<imm>{, <shift>}") + else if not (0 <= $4 && $4 <= 4095) then error_arg "<imm> must be in the range 0 to 4095" + else if not ($6.shift_type = ShiftType_LSL && ($7 = 0 || $7 = 12)) then error_arg "<shift> must be 'LSL #0' or 'LSL #12'" + else `AArch64AddSubImmediate (W ZR,$2,Set32,$1.sub_op,true,reg_size_bits_R32_of_int ($4 lsl $7)) } + | CM xreg COMMA imm + { if not (isregsp $2) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, #<imm>{, <shift>}") + else if not (0 <= $4 && $4 <= 4095) then error_arg "<imm> must be in the range 0 to 4095" + else `AArch64AddSubImmediate (X ZR,$2,Set64,$1.sub_op,true,reg_size_bits_R64_of_int $4) } + | CM xreg COMMA imm COMMA SHIFT imm + { if not (isregsp $2) then error_registers ("expected " ^ $1.txt ^ " <Xn|SP>, #<imm>{, <shift>}") + else if not (0 <= $4 && $4 <= 4095) then error_arg "<imm> must be in the range 0 to 4095" + else if not ($6.shift_type = ShiftType_LSL && ($7 = 0 || $7 = 12)) then error_arg "<shift> must be 'LSL #0' or 'LSL #12'" + else `AArch64AddSubImmediate (X ZR,$2,Set64,$1.sub_op,true,reg_size_bits_R64_of_int ($4 lsl $7)) } + + /* CRC32B/CRC32H/CRC32W */ + /* CRC32CB/CRC32CH/CRC32CW */ + + | CRC wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>") + else `AArch64CRC($2,$4,$6,$1.size,$1.crc32c) } + + /* CRC32X/CRC32CX */ + + | CRC32X wreg COMMA wreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Xm>") + else `AArch64CRC($2,$4,$6,DataSize64,$1.crc32c) } + + /* CSEL/CSINV/CSINC/CSNEG */ + + | CSEL wreg COMMA wreg COMMA wreg COMMA COND + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>, <cond>") + else `AArch64ConditionalSelect($2,$4,$6,Set32,$8,$1.else_inv,$1.else_inc) } + | CSEL xreg COMMA xreg COMMA xreg COMMA COND + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>, <cond>") + else `AArch64ConditionalSelect($2,$4,$6,Set64,$8,$1.else_inv,$1.else_inc) } + + /* CSET/CSETM alias of CSINC/CSINV */ + + | CSET wreg COMMA COND + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <cond>") + else if ($4 = 0b1110 || $4 = 0b1111) then error_arg "<cond> must not be AL or NV" + else `AArch64ConditionalSelect($2,W ZR,W ZR,Set32,$4,$1.else_inv,$1.else_inc) } + | CSET xreg COMMA COND + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <cond>") + else if ($4 = 0b1110 || $4 = 0b1111) then error_arg "<cond> must not be AL or NV" + else `AArch64ConditionalSelect($2,X ZR,X ZR,Set64,$4,$1.else_inv,$1.else_inc) } + + /* DMB/DSB */ + + | MEMBARR BARROP + { `AArch64Barrier($1.op,$2.domain,$2.types) } + | MEMBARR imm + { if not (0 <= $2 && $2 <= 15) then error_arg "<imm> must be in the range 0 to 15" + else + let domain = + match $2 / 4 with + | 0b00 -> MBReqDomain_OuterShareable + | 0b01 -> MBReqDomain_Nonshareable + | 0b10 -> MBReqDomain_InnerShareable + | 0b11 -> MBReqDomain_FullSystem + | _ -> assert false + in + let (domain,types) = + match $2 mod 4 with + | 0b01 -> (domain,MBReqTypes_Reads) + | 0b10 -> (domain,MBReqTypes_Writes) + | 0b11 -> (domain,MBReqTypes_All) + | _ -> (MBReqDomain_FullSystem,MBReqTypes_All) + in + `AArch64Barrier($1.op,domain,types) } + + /* EXTR */ + + | EXTR wreg COMMA wreg COMMA wreg COMMA imm + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>, #<lsb>") + else if not (0 <= $8 && $8 <= 31) then error_arg "<lsb> must be in the range 0 to 31" + else `AArch64ExtractRegister($2,$4,$6,Set32,$8) } + | EXTR xreg COMMA xreg COMMA xreg COMMA imm + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>, #<lsb>") + else if not (0 <= $8 && $8 <= 63) then error_arg "<lsb> must be in the range 0 to 63" + else `AArch64ExtractRegister($2,$4,$6,Set64,$8) } + + /* HINT */ + + | HINT imm + { if not (0 <= $2 && $2 <= 127) then error_arg "<imm> must be in the range 0 to 127" + else + match $2 with + | 0 -> `AArch64Hint(SystemHintOp_NOP) + | 1 -> `AArch64Hint(SystemHintOp_YIELD) + | 2 -> `AArch64Hint(SystemHintOp_WFE) + | 3 -> `AArch64Hint(SystemHintOp_WFI) + | 4 -> `AArch64Hint(SystemHintOp_SEV) + | 5 -> `AArch64Hint(SystemHintOp_SEVL) + | _ -> `AArch64Hint(SystemHintOp_NOP) } + + /* ISB */ + + | ISB + { `AArch64Barrier(MemBarrierOp_ISB,MBReqDomain_FullSystem,MBReqTypes_All) } + | ISB BARROP + { if not ($2 = {domain=MBReqDomain_FullSystem; types=MBReqTypes_All}) then error_arg "<option> must be SY" + else `AArch64Barrier(MemBarrierOp_ISB,MBReqDomain_FullSystem,MBReqTypes_All) } + | ISB imm + { (* FIXME: this seems like an ARM bug, why do we let this be anything other then 15 *) + if not (0 <= $2 && $2 <= 15) then error_arg "<imm> must be in the range 0 to 15" + else + let domain = + match $2 / 4 with + | 0b00 -> MBReqDomain_OuterShareable + | 0b01 -> MBReqDomain_Nonshareable + | 0b10 -> MBReqDomain_InnerShareable + | 0b11 -> MBReqDomain_FullSystem + | _ -> assert false + in + let (domain,types) = + match $2 mod 4 with + | 0b01 -> (domain,MBReqTypes_Reads) + | 0b10 -> (domain,MBReqTypes_Writes) + | 0b11 -> (domain,MBReqTypes_All) + | _ -> (MBReqDomain_FullSystem,MBReqTypes_All) + in + `AArch64Barrier(MemBarrierOp_ISB,domain,types) } + + /* LDAR/LDARB/LDARH + LDAXR/LDAXRB/LDAXRH + LDXR/LDXRB/LDXRH + STLR/STLRB/STLRH */ + + | LDAXR wreg COMMA LBRK xreg RBRK + { if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($5,$2,W ZR (* ARM: 0b11111 *),W ZR (* ARM: 0b11111 *),$1.acctype,$1.excl,false,$1.memop,$1.var32.elsize,Set32,$1.var32.datasize) } + | LDAXR wreg COMMA LBRK xreg COMMA imm RBRK + { if not (isregzr $2 && isregsp $5 && $7 = 0) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($5,$2,W ZR (* ARM: 0b11111 *),W ZR (* ARM: 0b11111 *),$1.acctype,$1.excl,false,$1.memop,$1.var32.elsize,Set32,$1.var32.datasize) } + | LDAXR xreg COMMA LBRK xreg RBRK + { if not $1.var64 then error_arg "unrecognised instruction" + else if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($5,$2,X ZR (* ARM: 0b11111 *),W ZR (* ARM: 0b11111 *),$1.acctype,$1.excl,false,$1.memop,64,Set64,DataSize64) } + | LDAXR xreg COMMA LBRK xreg COMMA imm RBRK + { if not $1.var64 then error_arg "unrecognised instruction" + else if not (isregzr $2 && isregsp $5 && $7 = 0) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($5,$2,X ZR (* ARM: 0b11111 *),W ZR (* ARM: 0b11111 *),$1.acctype,$1.excl,false,$1.memop,64,Set64,DataSize64) } + + /* STXR/STXRB/STXRH */ + /* STLXR/STLXRB/STLXRH */ + + | STLXR wreg COMMA wreg COMMA LBRK xreg RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Ws>, <Wt>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($7,$4,W ZR (* ARM: 0b11111 *),$2,$1.acctype,true,false,MemOp_STORE,$1.var32.elsize,Set32,$1.var32.datasize) } + | STLXR wreg COMMA wreg COMMA LBRK xreg COMMA imm RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7 && $9 = 0) then error_registers ("expected " ^ $1.txt ^ " <Ws>, <Wt>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($7,$4,W ZR (* ARM: 0b11111 *),$2,$1.acctype,true,false,MemOp_STORE,$1.var32.elsize,Set32,$1.var32.datasize) } + | STLXR wreg COMMA xreg COMMA LBRK xreg RBRK + { if not $1.var64 then error_arg "unrecognised instruction" + else if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Ws>, <Xt>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($7,$4,X ZR (* ARM: 0b11111 *),$2,$1.acctype,true,false,MemOp_STORE,64,Set64,DataSize64) } + | STLXR wreg COMMA xreg COMMA LBRK xreg COMMA imm RBRK + { if not $1.var64 then error_arg "unrecognised instruction" + else if not (isregzr $2 && isregzr $4 && isregsp $7 && $9 = 0) then error_registers ("expected " ^ $1.txt ^ " <Ws>, <Xt>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($7,$4,X ZR (* ARM: 0b11111 *),$2,$1.acctype,true,false,MemOp_STORE,64,Set64,DataSize64) } + + /* LDAXP/LDXP */ + + | LDXP wreg COMMA wreg COMMA LBRK xreg RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Wt1>, <Wt2>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($7,$2,$4,W ZR (* ARM: 0b11111 *),$1.acctype,true,true,MemOp_LOAD,32,Set32,DataSize32) } + | LDXP wreg COMMA wreg COMMA LBRK xreg COMMA imm RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7 && $9 = 0) then error_registers ("expected " ^ $1.txt ^ " <Wt1>, <Wt2>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($7,$2,$4,W ZR (* ARM: 0b11111 *),$1.acctype,true,true,MemOp_LOAD,32,Set32,DataSize32) } + | LDXP xreg COMMA xreg COMMA LBRK xreg RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($7,$2,$4,W ZR (* ARM: 0b11111 *),$1.acctype,true,true,MemOp_LOAD,64,Set64,DataSize64) } + | LDXP xreg COMMA xreg COMMA LBRK xreg COMMA imm RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7 && $9 = 0) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($7,$2,$4,W ZR (* ARM: 0b11111 *),$1.acctype,true,true,MemOp_LOAD,64,Set64,DataSize64) } + + /* STLXP/STXP */ + + | STXP wreg COMMA wreg COMMA wreg COMMA LBRK xreg RBRK + { if not (isregzr $2 && isregzr $4 && isregzr $6 && isregsp $9) then error_registers ("expected " ^ $1.txt ^ " <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($9,$4,$6,$2,$1.acctype,true,true,MemOp_STORE,32,Set32,DataSize32) } + | STXP wreg COMMA wreg COMMA wreg COMMA LBRK xreg COMMA imm RBRK + { if not (isregzr $2 && isregzr $4 && isregzr $6 && isregsp $9 && $11 = 0) then error_registers ("expected " ^ $1.txt ^ " <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($9,$4,$6,$2,$1.acctype,true,true,MemOp_STORE,32,Set32,DataSize32) } + | STXP wreg COMMA xreg COMMA xreg COMMA LBRK xreg RBRK + { if not (isregzr $2 && isregzr $4 && isregzr $6 && isregsp $9) then error_registers ("expected " ^ $1.txt ^ " <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($9,$4,$6,$2,$1.acctype,true,true,MemOp_STORE,64,Set64,DataSize64) } + | STXP wreg COMMA xreg COMMA xreg COMMA LBRK xreg COMMA imm RBRK + { if not (isregzr $2 && isregzr $4 && isregzr $6 && isregsp $9 && $11 = 0) then error_registers ("expected " ^ $1.txt ^ " <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]") + else `AArch64LoadStoreAcqExc($9,$4,$6,$2,$1.acctype,true,true,MemOp_STORE,64,Set64,DataSize64) } + + /* LDP/STP (post-index) */ + + | LDSTP wreg COMMA wreg COMMA LBRK xreg RBRK COMMA imm + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Wt1>, <Wt2>, [<Xn|SP>], #<imm>") + else if not (-256 <= $10 && $10 <= 252) then error_arg "<imm> must be in the range -256 to 252" + else if not ($10 mod 4 = 0) then error_arg "<imm> must be a multiple of 4" + else `AArch64LoadStorePair (true,true,$7,$2,$4,AccType_NORMAL,$1.memop,false,DataSize32,bit64_of_int $10) } + | LDSTP xreg COMMA xreg COMMA LBRK xreg RBRK COMMA imm + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>], #<imm>") + else if not (-512 <= $10 && $10 <= 504) then error_arg "<imm> must be in the range -512 to 504" + else if not ($10 mod 8 = 0) then error_arg "<imm> must be a multiple of 8" + else `AArch64LoadStorePair (true,true,$7,$2,$4,AccType_NORMAL,$1.memop,false,DataSize64,bit64_of_int $10) } + + /* LDP/STP (pre-index) */ + + | LDSTP wreg COMMA wreg COMMA LBRK xreg COMMA imm RBRK EXCL + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!") + else if not (-256 <= $9 && $9 <= 252) then error_arg "<imm> must be in the range -256 to 252" + else if not ($9 mod 4 = 0) then error_arg "<imm> must be a multiple of 4" + else `AArch64LoadStorePair (true,false,$7,$2,$4,AccType_NORMAL,$1.memop,false,DataSize32,bit64_of_int $9) } + | LDSTP xreg COMMA xreg COMMA LBRK xreg COMMA imm RBRK EXCL + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!") + else if not (-512 <= $9 && $9 <= 504) then error_arg "<imm> must be in the range -512 to 504" + else if not ($9 mod 8 = 0) then error_arg "<imm> must be a multiple of 8" + else `AArch64LoadStorePair (true,false,$7,$2,$4,AccType_NORMAL,$1.memop,false,DataSize64,bit64_of_int $9) } + + /* LDP/STP (signed offset) */ + + | LDSTP wreg COMMA wreg COMMA LBRK xreg RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]") + else `AArch64LoadStorePair (false,false,$7,$2,$4,AccType_NORMAL,$1.memop,false,DataSize32,bit64_of_int 0) } + | LDSTP wreg COMMA wreg COMMA LBRK xreg COMMA imm RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]") + else if not (-256 <= $9 && $9 <= 252) then error_arg "<imm> must be in the range -256 to 252" + else if not ($9 mod 4 = 0) then error_arg "<imm> must be a multiple of 4" + else `AArch64LoadStorePair (false,false,$7,$2,$4,AccType_NORMAL,$1.memop,false,DataSize32,bit64_of_int $9) } + | LDSTP xreg COMMA xreg COMMA LBRK xreg RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]") + else `AArch64LoadStorePair (false,false,$7,$2,$4,AccType_NORMAL,$1.memop,false,DataSize64,bit64_of_int 0) } + | LDSTP xreg COMMA xreg COMMA LBRK xreg COMMA imm RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]") + else if not (-512 <= $9 && $9 <= 504) then error_arg "<imm> must be in the range -512 to 504" + else if not ($9 mod 8 = 0) then error_arg "<imm> must be a multiple of 8" + else `AArch64LoadStorePair (false,false,$7,$2,$4,AccType_NORMAL,$1.memop,false,DataSize64,bit64_of_int $9) } + + /* LDPSW (post-index) */ + + | LDPSW xreg COMMA xreg COMMA LBRK xreg RBRK COMMA imm + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>], #<imm>") + else if not (-256 <= $10 && $10 <= 252) then error_arg "<imm> must be in the range -256 to 252" + else if not ($10 mod 4 = 0) then error_arg "<imm> must be a multiple of 4" + else `AArch64LoadStorePair (true,true,$7,$2,$4,AccType_NORMAL,MemOp_LOAD,true,DataSize32,bit64_of_int $10) } + + /* LDPSW (pre-index) */ + + | LDPSW xreg COMMA xreg COMMA LBRK xreg COMMA imm RBRK EXCL + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!") + else if not (-256 <= $9 && $9 <= 252) then error_arg "<imm> must be in the range -256 to 252" + else if not ($9 mod 4 = 0) then error_arg "<imm> must be a multiple of 4" + else `AArch64LoadStorePair (true,false,$7,$2,$4,AccType_NORMAL,MemOp_LOAD,true,DataSize32,bit64_of_int $9) } + + /* LDPSW (signed offset) */ + + | LDPSW xreg COMMA xreg COMMA LBRK xreg RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]") + else `AArch64LoadStorePair (false,false,$7,$2,$4,AccType_NORMAL,MemOp_LOAD,true,DataSize32,bit64_of_int 0) } + | LDPSW xreg COMMA xreg COMMA LBRK xreg COMMA imm RBRK + { if not (isregzr $2 && isregzr $4 && isregsp $7) then error_registers ("expected " ^ $1.txt ^ " <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]") + else if not (-256 <= $9 && $9 <= 252) then error_arg "<imm> must be in the range -256 to 252" + else if not ($9 mod 4 = 0) then error_arg "<imm> must be a multiple of 4" + else `AArch64LoadStorePair (false,false,$7,$2,$4,AccType_NORMAL,MemOp_LOAD,true,DataSize32,bit64_of_int $9) } + + /* LDR/LDRB/LDRH/LDRSB/LDRSH/LDRSW/STR/STRB/STRH (immediate) (post-index) */ + + | LDSTR wreg COMMA LBRK xreg RBRK COMMA imm + { match $1.var32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>], #<simm>") + | Some var32 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>]") + else if not (-256 <= $8 && $8 <= 255) then error_arg "<simm> must be in the range -256 to 255" + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,$1.memop,$1.signed,true,true,bit64_of_int $8,Set32,var32.datasize) } + | LDSTR xreg COMMA LBRK xreg RBRK COMMA imm + { match $1.var64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>], #<simm>") + | Some var64 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>]") + else if not (-256 <= $8 && $8 <= 255) then error_arg "<simm> must be in the range -256 to 255" + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,$1.memop,$1.signed,true,true,bit64_of_int $8,Set64,var64.datasize) } + + /* LDR/LDRB/LDRH/LDRSB/LDRSH/LDRSW/STR/STRB/STRH (immediate) (pre-index) */ + + | LDSTR wreg COMMA LBRK xreg COMMA imm RBRK EXCL + { match $1.var32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, #<simm>]!") + | Some var32 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, #<simm>]!") + else if not (-256 <= $7 && $7 <= 255) then error_arg "<simm> must be in the range -256 to 255" + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,$1.memop,$1.signed,true,false,bit64_of_int $7,Set32,var32.datasize) } + | LDSTR xreg COMMA LBRK xreg COMMA imm RBRK EXCL + { match $1.var64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, #<simm>]!") + | Some var64 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, #<simm>]!") + else if not (-256 <= $7 && $7 <= 255) then error_arg "<simm> must be in the range -256 to 255" + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,$1.memop,$1.signed,true,false,bit64_of_int $7,Set64,var64.datasize) } + + /* LDR/LDRB/LDRH/LDRSB/LDRSH/LDRSW/STR/STRB/STRH (immediate) (unsigned offset) */ + + | LDSTR wreg COMMA LBRK xreg RBRK + { match $1.var32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{, #<pimm>}]") + | Some var32 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{, #<pimm>}]") + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,$1.memop,$1.signed,false,false,bit64_of_int 0,Set32,var32.datasize) } + | LDSTR wreg COMMA LBRK xreg COMMA imm RBRK + { match $1.var32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{, #<pimm>}]") + | Some var32 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{, #<pimm>}]") + else if var32.datasize = DataSize8 && not (0 <= $7 && $7 <= 4095) then error_arg "<pimm> must be in the range 0 to 4095" + else if var32.datasize = DataSize16 && not (0 <= $7 && $7 <= 8190) then error_arg "<pimm> must be in the range 0 to 8190" + else if var32.datasize = DataSize16 && not ($7 mod 2 = 0) then error_arg "<pimm> must be a multiple of 2" + else if var32.datasize = DataSize32 && not (0 <= $7 && $7 <= 16380) then error_arg "<pimm> must be in the range 0 to 16380" + else if var32.datasize = DataSize32 && not ($7 mod 4 = 0) then error_arg "<pimm> must be a multiple of 4" + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,$1.memop,$1.signed,false,false,bit64_of_int $7,Set32,var32.datasize) } + | LDSTR xreg COMMA LBRK xreg RBRK + { match $1.var64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{, #<pimm>}]") + | Some var64 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{, #<pimm>}]") + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,$1.memop,$1.signed,false,false,bit64_of_int 0,Set64,var64.datasize) } + | LDSTR xreg COMMA LBRK xreg COMMA imm RBRK + { match $1.var64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{, #<pimm>}]") + | Some var64 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{, #<pimm>}]") + else if var64.datasize = DataSize8 && not (0 <= $7 && $7 <= 4095) then error_arg "<pimm> must be in the range 0 to 4095" + else if var64.datasize = DataSize16 && not (0 <= $7 && $7 <= 8190) then error_arg "<pimm> must be in the range 0 to 8190" + else if var64.datasize = DataSize16 && not ($7 mod 2 = 0) then error_arg "<pimm> must be a multiple of 2" + else if var64.datasize = DataSize32 && not (0 <= $7 && $7 <= 16380) then error_arg "<pimm> must be in the range 0 to 16380" + else if var64.datasize = DataSize32 && not ($7 mod 4 = 0) then error_arg "<pimm> must be a multiple of 4" + else if var64.datasize = DataSize64 && not (0 <= $7 && $7 <= 32760) then error_arg "<pimm> must be in the range 0 to 32760" + else if var64.datasize = DataSize64 && not ($7 mod 8 = 0) then error_arg "<pimm> must be a multiple of 8" + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,$1.memop,$1.signed,false,false,bit64_of_int $7,Set64,var64.datasize) } + + /* LDR/LDRSW (literal) */ +/* + | LDSTR wreg COMMA NAME + { if not $1.lit32 then error_arg "unrecognised instruction" + else if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Wt>, <label>") + else `AArch64LoadLiteral($2,MemOp_LOAD,$1.signed,4,(* FIXME: label *),DataSize32) } + | LDSTR xreg COMMA NAME + { match $1.lit64 with + | None -> error_arg "unrecognised instruction" + | Some lit64 -> + if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xt>, <label>") + else `AArch64LoadLiteral($2,MemOp_LOAD,$1.signed,lit64.size,(* FIXME: label *),lit64.datasize) } +*/ + + /* LDR/LDRB/LDRH/LDRSB/LDRSH/LDRSW/STR/STRB/STRH (register) */ /* FIXME: the combination of extend and amount is not clear in ARM */ + + | LDSTR wreg COMMA LBRK xreg COMMA wreg COMMA EXTEND RBRK + { match $1.var32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + | Some var32 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9._type = ExtendType_UXTW || $9._type = ExtendType_SXTW) then error_arg "<extend> must be one of UXTW,SXTW" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,$9._type,0,Set32,var32.datasize) } + | LDSTR wreg COMMA LBRK xreg COMMA xreg RBRK + { match $1.var32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + | Some var32 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>]") + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,ExtendType_UXTX,0,Set32,var32.datasize) } + | LDSTR wreg COMMA LBRK xreg COMMA xreg COMMA EXTEND RBRK + { match $1.var32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + | Some var32 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9._type = ExtendType_SXTX) then error_arg "<extend> must be one of LSL,SXTX" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,$9._type,0,Set32,var32.datasize) } + | LDSTR wreg COMMA LBRK xreg COMMA xreg COMMA SHIFT RBRK + { match $1.var32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + | Some var32 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of LSL,SXTX" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,ExtendType_UXTX,0,Set32,var32.datasize) } + | LDSTR wreg COMMA LBRK xreg COMMA xreg COMMA SHIFT imm RBRK + { match $1.var32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + | Some var32 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of LSL,SXTX" + else if var32.datasize = DataSize8 && not ($10 = 0) then error_arg "<amount> must be 0" + else if var32.datasize = DataSize16 && not ($10 = 0 || $10 = 1) then error_arg "<amount> must be one of 0,1" + else if var32.datasize = DataSize32 && not ($10 = 0 || $10 = 2) then error_arg "<amount> must be one of 0,2" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,ExtendType_UXTX,$10,Set32,var32.datasize) } + + | LDSTR xreg COMMA LBRK xreg COMMA wreg COMMA EXTEND RBRK + { match $1.var64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + | Some var64 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9._type = ExtendType_UXTW || $9._type = ExtendType_SXTW) then error_arg "<extend> must be one of UXTW,SXTW" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,$9._type,0,Set64,var64.datasize) } + | LDSTR xreg COMMA LBRK xreg COMMA xreg RBRK + { match $1.var64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>]") + | Some var64 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>]") + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,ExtendType_UXTX,0,Set64,var64.datasize) } + | LDSTR xreg COMMA LBRK xreg COMMA xreg COMMA EXTEND RBRK + { match $1.var64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + | Some var64 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9._type = ExtendType_SXTX) then error_arg "<extend> must be one of LSL,SXTX" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,$9._type,0,Set64,var64.datasize) } + | LDSTR xreg COMMA LBRK xreg COMMA xreg COMMA SHIFT RBRK + { match $1.var64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + | Some var64 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of LSL,SXTX" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,ExtendType_UXTX,0,Set64,var64.datasize) } + | LDSTR xreg COMMA LBRK xreg COMMA xreg COMMA SHIFT imm RBRK + { match $1.var64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + | Some var64 -> + if not (isregzr $2 && isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of LSL,SXTX" + else if var64.datasize = DataSize8 && not ($10 = 0) then error_arg "<amount> must be 0" + else if var64.datasize = DataSize16 && not ($10 = 0 || $10 = 1) then error_arg "<amount> must be one of 0,1" + else if var64.datasize = DataSize32 && not ($10 = 0 || $10 = 2) then error_arg "<amount> must be one of 0,2" + else if var64.datasize = DataSize64 && not ($10 = 0 || $10 = 3) then error_arg "<amount> must be one of 0,3" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,$1.memop,$1.signed,false,false,ExtendType_UXTX,$10,Set64,var64.datasize) } + + /* LDTR/LDTRB/LDTRH/LDTRSB/LDTRSH/LDTRSW + LDUR/LDURB/LDURH/LDURSB/LDURSH/LDURSW + STTR/STTRB/STTRH + STUR/STURB/STURH */ + + | LDSTTUR wreg COMMA LBRK xreg RBRK + { match $1.off32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{, #<simm>}]") + | Some off32 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{, #<simm>}]") + else `AArch64LoadImmediate($5,$2,$1.acctype,$1.memop,$1.signed,false,false,bit64_of_int 0,Set32,off32.datasize) } + | LDSTTUR wreg COMMA LBRK xreg COMMA imm RBRK + { match $1.off32 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{, #<simm>}]") + | Some off32 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{, #<simm>}]") + else if not (-256 <= $7 && $7 <= 255) then error_arg "<simm> must be in the range -256 to 255" + else `AArch64LoadImmediate($5,$2,$1.acctype,$1.memop,$1.signed,false,false,bit64_of_int $7,Set32,off32.datasize) } + | LDSTTUR xreg COMMA LBRK xreg RBRK + { match $1.off64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{, #<simm>}]") + | Some off64 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{, #<simm>}]") + else `AArch64LoadImmediate($5,$2,$1.acctype,$1.memop,$1.signed,false,false,bit64_of_int 0,Set64,off64.datasize) } + | LDSTTUR xreg COMMA LBRK xreg COMMA imm RBRK + { match $1.off64 with + | None -> error_registers ("expected " ^ $1.txt ^ " <Wt>, [<Xn|SP>{, #<simm>}]") + | Some off64 -> + if not (isregzr $2 && isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <Xt>, [<Xn|SP>{, #<simm>}]") + else if not (-256 <= $7 && $7 <= 255) then error_arg "<simm> must be in the range -256 to 255" + else `AArch64LoadImmediate($5,$2,$1.acctype,$1.memop,$1.signed,false,false,bit64_of_int $7,Set64,off64.datasize) } + + /* MADD/MSUB */ + + | MADDSUB wreg COMMA wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6 && isregzr $8) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>, <Wa>") + else `AArch64MultiplyAddSub($2,$4,$6,$8,Set32,DataSize32,$1.sub_op) } + | MADDSUB xreg COMMA xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6 && isregzr $8) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>, <Xa>") + else `AArch64MultiplyAddSub($2,$4,$6,$8,Set64,DataSize64,$1.sub_op) } + + /* MUL/MNEG alias of MADD/MSUB */ + + | MUL wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>") + else `AArch64MultiplyAddSub($2,$4,$6,W ZR,Set32,DataSize32,$1.sub_op) } + | MUL xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>") + else `AArch64MultiplyAddSub($2,$4,$6,X ZR,Set64,DataSize64,$1.sub_op) } + + /* MOV (to/from SP) alias of ADD (immediate) */ + + | MOV wreg COMMA wreg + { if not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Wd|WSP>, <Wn|WSP>") + else `AArch64AddSubImmediate($2,$4,Set32,false,false,reg_size_bits_R32_of_int 0) } + | MOV xreg COMMA xreg + { if not (isregsp $2 && isregsp $4) then error_registers ("expected " ^ $1.txt ^ " <Xd|SP>, <Xn|SP>") + else `AArch64AddSubImmediate($2,$4,Set64,false,false,reg_size_bits_R64_of_int 0) } + + /* MOV (... immediate) alias of MOVZ/MOVN/ORR */ + + | MOV wreg COMMA imm + { if issp $2 then + begin + (* bitmask immediate *) + match encodeBitMasks 32 (Nat_big_num.of_int $4) with + | Some _ -> `AArch64LogicalImmediate($2,W ZR,Set32,false,LogicalOp_ORR,reg_size_bits_R32_of_int $4) + | None -> error_arg "<imm> can not be encoded" + end + else if not (iskbituimm 32 $4) then error_arg "<imm> must be a 32-bit unsigned immediate" + else if $4 land 0xffff0000 = 0 then + (* wide immediate *) + `AArch64MoveWide($2,Set32,$4,0,MoveWideOp_Z) + else if $4 land 0x0000ffff = 0 then + (* wide immediate *) + `AArch64MoveWide($2,Set32,$4 lsr 16,16,MoveWideOp_Z) + else if (lnot $4) land 0xffff0000 = 0 then + (* inverted wide immediate *) + `AArch64MoveWide($2,Set32,lnot $4,0,MoveWideOp_N) + else if (lnot $4) land 0x0000ffff = 0 then + (* inverted wide immediate *) + `AArch64MoveWide($2,Set32,(lnot $4) lsr 16,16,MoveWideOp_N) + else + (* bitmask immediate *) + match encodeBitMasks 32 (Nat_big_num.of_int $4) with + | Some _ -> `AArch64LogicalImmediate($2,W ZR,Set32,false,LogicalOp_ORR,reg_size_bits_R32_of_int $4) + | None -> error_arg "<imm> can not be encoded" } + | MOV xreg COMMA big_imm + { if issp $2 then + begin + (* bitmask immediate *) + match encodeBitMasks 64 $4 with + | Some _ -> `AArch64LogicalImmediate($2,X ZR,Set64,false,LogicalOp_ORR,reg_size_bits_R64_of_big_int $4) + | None -> error_arg "<imm> can not be encoded" + end + else if not (big_iskbituimm 64 $4) then error_arg "<imm> must be a 64-bit unsigned immediate" + else if check_bits $4 0 16 then + (* wide immediate *) + `AArch64MoveWide($2,Set64,Nat_big_num.to_int $4,0,MoveWideOp_Z) + else if check_bits $4 16 16 then + (* wide immediate *) + `AArch64MoveWide($2,Set64,Nat_big_num.to_int (Nat_big_num.extract_num $4 16 16),16,MoveWideOp_Z) + else if check_bits $4 32 16 then + (* wide immediate *) + `AArch64MoveWide($2,Set64,Nat_big_num.to_int (Nat_big_num.extract_num $4 32 16),32,MoveWideOp_Z) + else if check_bits $4 48 16 then + (* wide immediate *) + `AArch64MoveWide($2,Set64,Nat_big_num.to_int (Nat_big_num.extract_num $4 48 16),48,MoveWideOp_Z) + else + begin + let not_imm = (* the following should negate the first 64 bits of $4 + by doing 0xffffffffffffffff - $4 *) + Nat_big_num.sub + (Nat_big_num.pred (Nat_big_num.shift_left (Nat_big_num.of_int 1) 64)) + $4 in + if check_bits not_imm 0 16 then + (* inverted wide immediate *) + `AArch64MoveWide($2,Set64,Nat_big_num.to_int not_imm,0,MoveWideOp_N) + else if check_bits not_imm 16 16 then + (* inverted wide immediate *) + `AArch64MoveWide($2,Set64,Nat_big_num.to_int (Nat_big_num.extract_num not_imm 16 16),16,MoveWideOp_N) + else if check_bits not_imm 32 16 then + (* inverted wide immediate *) + `AArch64MoveWide($2,Set64,Nat_big_num.to_int (Nat_big_num.extract_num not_imm 32 16),32,MoveWideOp_N) + else if check_bits not_imm 48 16 then + (* inverted wide immediate *) + `AArch64MoveWide($2,Set64,Nat_big_num.to_int (Nat_big_num.extract_num not_imm 48 16),48,MoveWideOp_N) + else + (* bitmask immediate *) + match encodeBitMasks 64 $4 with + | Some _ -> `AArch64LogicalImmediate($2,X ZR,Set64,false,LogicalOp_ORR,reg_size_bits_R64_of_big_int $4) + | None -> error_arg "<imm> can not be encoded" + end} + + /* MOV (register) alias of ORR (shifted register) */ + + | MOV wreg COMMA wreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wm>") + else `AArch64LogicalShiftedRegister($2,W ZR,$4,Set32,false,LogicalOp_ORR,ShiftType_LSL,0,false) } + | MOV xreg COMMA xreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xm>") + else `AArch64LogicalShiftedRegister($2,X ZR,$4,Set64,false,LogicalOp_ORR,ShiftType_LSL,0,false) } + + /* MOVK/MOVN/MOVZ */ + + | MOVWIDE wreg COMMA imm + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Wd>, #<imm>{, LSL #<shift>}") + else if not (0 <= $4 && $4 <= 65535) then error_arg "<imm> must be in the range 0 to 65535" + else `AArch64MoveWide($2,Set32,$4,0,$1.opcode) } + | MOVWIDE wreg COMMA imm COMMA SHIFT imm + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Wd>, #<imm>{, LSL #<shift>}") + else if not (0 <= $4 && $4 <= 65535) then error_arg "<imm> must be in the range 0 to 65535" + else if not ($6.shift_type = ShiftType_LSL) then error_arg "must be LSL" + else if not ($7 = 0 || $7 = 16) then error_arg "<shift> must be one of 0,16" + else `AArch64MoveWide($2,Set32,$4,$7,$1.opcode) } + | MOVWIDE xreg COMMA imm + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xd>, #<imm>{, LSL #<shift>}") + else if not (0 <= $4 && $4 <= 65535) then error_arg "<imm> must be in the range 0 to 65535" + else `AArch64MoveWide($2,Set64,$4,0,$1.opcode) } + | MOVWIDE xreg COMMA imm COMMA SHIFT imm + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xd>, #<imm>{, LSL #<shift>}") + else if not (0 <= $4 && $4 <= 65535) then error_arg "<imm> must be in the range 0 to 65535" + else if not ($6.shift_type = ShiftType_LSL) then error_arg "must be LSL" + else if not ($7 = 0 || $7 = 16 || $7 = 32 || $7 = 48) then error_arg "<shift> must be one of 0,16,32,48" + else `AArch64MoveWide($2,Set64,$4,$7,$1.opcode) } + + /* MVN alias of ORN (shifted register) */ + + | MVN wreg COMMA wreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wm>{, <shift> #<amount>}") + else `AArch64LogicalShiftedRegister($2,W ZR,$4,Set32,false,LogicalOp_ORR,ShiftType_LSL,0,true) } + | MVN wreg COMMA wreg COMMA SHIFT imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wm>{, <shift> #<amount>}") + else if not (0 <= $7 && $7 <= 31) then error_arg "<amount> must be in the range 0 to 31" + else `AArch64LogicalShiftedRegister($2,W ZR,$4,Set32,false,LogicalOp_ORR,$6.shift_type,$7,true) } + | MVN xreg COMMA xreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xm>{, <shift> #<amount>}") + else `AArch64LogicalShiftedRegister($2,X ZR,$4,Set64,false,LogicalOp_ORR,ShiftType_LSL,0,true) } + | MVN xreg COMMA xreg COMMA SHIFT imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xm>{, <shift> #<amount>}") + else if not (0 <= $7 && $7 <= 63) then error_arg "<amount> must be in the range 0 to 63" + else `AArch64LogicalShiftedRegister($2,X ZR,$4,Set64,false,LogicalOp_ORR,$6.shift_type,$7,true) } + + /* NEG/NEGS (shifted register) alias of SUB/SUBS (shifted register) */ + + | NEG wreg COMMA wreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wm>{, <shift> #<amount>}") + else `AArch64AddSubShiftedRegister($2,W ZR,$4,Set32,true,$1.setflags,ShiftType_LSL,0) } + | NEG wreg COMMA wreg COMMA SHIFT imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wm>{, <shift> #<amount>}") + else if $6.shift_type = ShiftType_ROR then error_arg "<shift> must be one of LSL,LSR,ASR" + else if not (0 <= $7 && $7 <= 31) then error_arg "<amount> must be in the range 0 to 31" + else `AArch64AddSubShiftedRegister($2,W ZR,$4,Set32,true,$1.setflags,$6.shift_type,0) } + | NEG xreg COMMA xreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xm>{, <shift> #<amount>}") + else `AArch64AddSubShiftedRegister($2,X ZR,$4,Set64,true,$1.setflags,ShiftType_LSL,0) } + | NEG xreg COMMA xreg COMMA SHIFT imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xm>{, <shift> #<amount>}") + else if $6.shift_type = ShiftType_ROR then error_arg "<shift> must be one of LSL,LSR,ASR" + else if not (0 <= $7 && $7 <= 63) then error_arg "<amount> must be in the range 0 to 63" + else `AArch64AddSubShiftedRegister($2,X ZR,$4,Set64,true,$1.setflags,$6.shift_type,$7) } + + /* NGC/NGCS alias of SBC/SBCS */ + + | NGC wreg COMMA wreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wm>") + else `AArch64AddSubCarry ($2,W ZR,$4,Set32,true,$1.setflags) } + | NGC xreg COMMA xreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xm>") + else `AArch64AddSubCarry ($2,X ZR,$4,Set64,true,$1.setflags) } + + /* NOP alias of HINT */ + + | NOP + { `AArch64Hint(SystemHintOp_NOP) } + + /* PRFM (immediate) */ + + | PRFM PRFOP COMMA LBRK xreg RBRK + { if not (isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>{, #<pimm>}]") + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,MemOp_PREFETCH,false,false,false,bit64_of_int 0,Set64,DataSize64) } + | PRFM PRFOP COMMA LBRK xreg COMMA imm RBRK + { if not (isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>{, #<pimm>}]") + else if not (0 <= $7 && $7 <= 32760) then error_arg "<pimm> must be in the range 0 to 32760" + else if not ($7 mod 8 = 0) then error_arg "<pimm> must be a multiple of 8" + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,MemOp_PREFETCH,false,false,false,bit64_of_int $7,Set64,DataSize64) } + | PRFM imm COMMA LBRK xreg RBRK + { if not (isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>{, #<pimm>}]") + else if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else `AArch64LoadImmediate($5,X (Ireg (ireg_of_int $2)),AccType_NORMAL,MemOp_PREFETCH,false,false,false,bit64_of_int 0,Set64,DataSize64) } + | PRFM imm COMMA LBRK xreg COMMA imm RBRK + { if not (isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>{, #<pimm>}]") + else if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else if not (0 <= $7 && $7 <= 32760) then error_arg "<pimm> must be in the range 0 to 32760" + else if not ($7 mod 8 = 0) then error_arg "<pimm> must be a multiple of 8" + else `AArch64LoadImmediate($5,X (Ireg (ireg_of_int $2)),AccType_NORMAL,MemOp_PREFETCH,false,false,false,bit64_of_int $7,Set64,DataSize64) } + + /* PRFM (literal) */ +/* + | PRFM PRFOP COMMA NAME + { `AArch64LoadLiteral($2,MemOp_PREFETCH,false,0,(* FIXME: label *),DataSize32) } + | PRFM imm COMMA NAME + { if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else `AArch64LoadLiteral(X (Ireg (ireg_of_int $2)),MemOp_PREFETCH,false,0,(* FIXME: label *),DataSize32) } +*/ + + /* PRFM (register) */ + + | PRFM PRFOP COMMA LBRK xreg COMMA wreg COMMA EXTEND RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9._type = ExtendType_UXTW || $9._type = ExtendType_SXTW) then error_arg "<extend> must be one of UXTW,SXTW" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,$9._type,0,Set32,DataSize64) } + | PRFM PRFOP COMMA LBRK xreg COMMA xreg RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,ExtendType_UXTX,0,Set32,DataSize64) } + | PRFM PRFOP COMMA LBRK xreg COMMA xreg COMMA EXTEND RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9._type = ExtendType_SXTX) then error_arg "<extend> must be one of LSL,SXTX" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,$9._type,0,Set32,DataSize64) } + | PRFM PRFOP COMMA LBRK xreg COMMA xreg COMMA SHIFT RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of LSL,SXTX" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,ExtendType_UXTX,0,Set32,DataSize64) } + | PRFM PRFOP COMMA LBRK xreg COMMA xreg COMMA SHIFT imm RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($9.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of LSL,SXTX" + else if not ($10 = 0 || $10 = 3) then error_arg "<amount> must be one of 0,3" + else `AArch64LoadRegister($5,$2,$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,ExtendType_UXTX,$10,Set32,DataSize64) } + + | PRFM imm COMMA LBRK xreg COMMA wreg COMMA EXTEND RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else if not ($9._type = ExtendType_UXTW || $9._type = ExtendType_SXTW) then error_arg "<extend> must be one of UXTW,SXTW" + else `AArch64LoadRegister($5,X (Ireg (ireg_of_int $2)),$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,$9._type,0,Set32,DataSize64) } + | PRFM imm COMMA LBRK xreg COMMA xreg RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else `AArch64LoadRegister($5,X (Ireg (ireg_of_int $2)),$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,ExtendType_UXTX,0,Set32,DataSize64) } + | PRFM imm COMMA LBRK xreg COMMA xreg COMMA EXTEND RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else if not ($9._type = ExtendType_SXTX) then error_arg "<extend> must be one of LSL,SXTX" + else `AArch64LoadRegister($5,X (Ireg (ireg_of_int $2)),$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,$9._type,0,Set32,DataSize64) } + | PRFM imm COMMA LBRK xreg COMMA xreg COMMA SHIFT RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else if not ($9.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of LSL,SXTX" + else `AArch64LoadRegister($5,X (Ireg (ireg_of_int $2)),$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,ExtendType_UXTX,0,Set32,DataSize64) } + | PRFM imm COMMA LBRK xreg COMMA xreg COMMA SHIFT imm RBRK + { if not (isregsp $5 && isregzr $7) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]") + else if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else if not ($9.shift_type = ShiftType_LSL) then error_arg "<extend> must be one of LSL,SXTX" + else if not ($10 = 0 || $10 = 3) then error_arg "<amount> must be one of 0,3" + else `AArch64LoadRegister($5,X (Ireg (ireg_of_int $2)),$7,AccType_NORMAL,MemOp_PREFETCH,false,false,false,ExtendType_UXTX,$10,Set32,DataSize64) } + + /* PRFUM */ + + | PRFUM PRFOP COMMA LBRK xreg RBRK + { if not (isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>{, #<simm>}]") + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,MemOp_PREFETCH,false,false,false,bit64_of_int 0,Set64,DataSize64) } + | PRFUM PRFOP COMMA LBRK xreg COMMA imm RBRK + { if not (isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>{, #<simm>}]") + else if not (-256 <= $7 && $7 <= 255) then error_arg "<simm> must be in the range -256 to 255" + else `AArch64LoadImmediate($5,$2,AccType_NORMAL,MemOp_PREFETCH,false,false,false,bit64_of_int $7,Set64,DataSize64) } + | PRFUM imm COMMA LBRK xreg RBRK + { if not (isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>{, #<simm>}]") + else if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else `AArch64LoadImmediate($5,X (Ireg (ireg_of_int $2)),AccType_NORMAL,MemOp_PREFETCH,false,false,false,bit64_of_int 0,Set64,DataSize64) } + | PRFUM imm COMMA LBRK xreg COMMA imm RBRK + { if not (isregsp $5) then error_registers ("expected " ^ $1.txt ^ " <prfop>, [<Xn|SP>{, #<simm>}]") + else if not ($2 = 6 || $2 = 7 || $2 = 14 || $2 = 15 || (22 <= $2 && $2 <= 31)) then error_arg "<prfop> must be one of 6,7,14,15,22-31" + else if not (-256 <= $7 && $7 <= 255) then error_arg "<simm> must be in the range -256 to 255" + else `AArch64LoadImmediate($5,X (Ireg (ireg_of_int $2)),AccType_NORMAL,MemOp_PREFETCH,false,false,false,bit64_of_int $7,Set64,DataSize64) } + + /* RET */ + + | RET + { `AArch64BranchRegister(X (Ireg R30),BranchType_RET) } + | RET xreg + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " {<Xn>}") + else `AArch64BranchRegister($2,BranchType_RET) } + + /* RBIT/REV/REV16/REV32 */ + + | REV wreg COMMA wreg + { match $1.op32 with + | None -> error_arg "unrecognised instruction" + | Some op -> + if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>") + else `AArch64Reverse($2,$4,Set32,op) } + | REV xreg COMMA xreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>") + else `AArch64Reverse($2,$4,Set64,$1.op64) } + + /* SBFIZ/UBFIZ alias of SBFM/UBFM */ + + | BFIZ wreg COMMA wreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, #<lsb>, #<width>") + else if not (0 <= $6 && $6 <= 31) then error_arg "<lsb> must be in the range 0 to 31" + else if not (1 <= $8 && $8 <= (32 - $6)) then error_arg "<width> must be in the range 1 to 32-<lsb>" + else + let (wmask,tmask) = decodeBitMasks 32 0 ($8 - 1) (-$6 mod 32) false in + `AArch64BitfieldMove($2,$4,Set32,true,$1.extend,-$6 mod 32,$8 - 1,reg_size_bits_R32_of_big_int wmask,reg_size_bits_R32_of_big_int tmask) } + | BFIZ xreg COMMA xreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, #<lsb>, #<width>") + else if not (0 <= $6 && $6 <= 63) then error_arg "<lsb> must be in the range 0 to 63" + else if not (1 <= $8 && $8 <= (64 - $6)) then error_arg "<width> must be in the range 1 to 64-<lsb>" + else + let (wmask,tmask) = decodeBitMasks 64 1 ($8 - 1) (-$6 mod 64) false in + `AArch64BitfieldMove($2,$4,Set64,true,$1.extend,-$6 mod 64,$8 - 1,reg_size_bits_R64_of_big_int wmask,reg_size_bits_R64_of_big_int tmask) } + + /* SBFX/UBFX alias of SBFM/UBFM */ + + | BFX wreg COMMA wreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, #<lsb>, #<width>") + else if not (0 <= $6 && $6 <= 31) then error_arg "<lsb> must be in the range 0 to 31" + else if not (1 <= $8 && $8 <= (32 - $6)) then error_arg "<width> must be in the range 1 to 32-<lsb>" + else + let (wmask,tmask) = decodeBitMasks 32 0 ($6 + $8 - 1) $6 false in + `AArch64BitfieldMove($2,$4,Set32,true,$1.extend,$6,$6 + $8 - 1,reg_size_bits_R32_of_big_int wmask,reg_size_bits_R32_of_big_int tmask) } + | BFX xreg COMMA xreg COMMA imm COMMA imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, #<lsb>, #<width>") + else if not (0 <= $6 && $6 <= 63) then error_arg "<lsb> must be in the range 0 to 63" + else if not (1 <= $8 && $8 <= (64 - $6)) then error_arg "<width> must be in the range 1 to 64-<lsb>" + else + let (wmask,tmask) = decodeBitMasks 64 1 ($6 + $8 - 1) $6 false in + `AArch64BitfieldMove($2,$4,Set64,true,$1.extend,$6,$6 + $8 - 1,reg_size_bits_R64_of_big_int wmask,reg_size_bits_R64_of_big_int tmask) } + + /* SDIV/UDIV */ + + | DIV wreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>, <Wm>") + else `AArch64Division($2,$4,$6,Set32,$1.unsigned) } + | DIV xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>") + else `AArch64Division($2,$4,$6,Set64,$1.unsigned) } + + /* SMADDL/SMSUBL/UMADDL/UMSUBL */ + + | MADDSUBL xreg COMMA wreg COMMA wreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6 && isregzr $8) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Wn>, <Wm>, <Xa>") + else `AArch64MultiplyAddSubLong($2,$4,$6,$8,Set64,DataSize32,$1.sub_op,$1.unsigned) } + + /* SMNEGL/UMNEGL alias of SMSUBL/UMSUBL */ + + | MNEGL xreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Wn>, <Wm>") + else `AArch64MultiplyAddSubLong($2,$4,$6,X ZR,Set64,DataSize32,true,$1.unsigned) } + + /* SMULH/UMULH */ + + | MULH xreg COMMA xreg COMMA xreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Xn>, <Xm>") + else `AArch64MultiplyHigh($2,$4,$6,X ZR,Set64,DataSize64,$1.unsigned) } + + /* SMULL/UMULL alias of SMADDL/UMADDL */ + + | MULL xreg COMMA wreg COMMA wreg + { if not (isregzr $2 && isregzr $4 && isregzr $6) then error_registers ("expected " ^ $1.txt ^ " <Xd>, <Wn>, <Wm>") + else `AArch64MultiplyAddSubLong($2,$4,$6,X ZR,Set64,DataSize32,false,$1.unsigned) } + + /* SXTB/SXTH/SXTW alias of SBFM + UXTB/UXTH alias of UBFM */ + + | EXTEND wreg COMMA wreg + { match $1.inst with + | None -> error_not_instruction $1.txt + | Some inst -> + if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>") + else + let (wmask,tmask) = decodeBitMasks 32 0 7 0 false in + `AArch64BitfieldMove($2,$4,Set32,true,inst.extend,0,7,reg_size_bits_R32_of_big_int wmask,reg_size_bits_R32_of_big_int tmask) } + | EXTEND xreg COMMA wreg + { match $1.inst with + | None -> error_not_instruction $1.txt + | Some inst -> + if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wd>, <Wn>") + else + let (wmask,tmask) = decodeBitMasks 64 1 7 0 false in + `AArch64BitfieldMove($2,$4,Set64,true,inst.extend,0,7,reg_size_bits_R64_of_big_int wmask,reg_size_bits_R64_of_big_int tmask) } + + /* TBZ/TBNZ */ +/* + | TBZ wreg COMMA imm COMMA NAME + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <R><t>, #<imm>, <label>") + else if not (0 <= $4 && $4 <= 31) then error_arg "<imm> must be in the range 0 to 31" + else `AArch64TestBitAndBranch($2,Set32,$4,$1.bit_val,(* FIXME: label *)) } + | TBZ xreg COMMA imm COMMA NAME + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <R><t>, #<imm>, <label>") + else if not (0 <= $4 && $4 <= 63) then error_arg "<imm> must be in the range 0 to 63" + else `AArch64TestBitAndBranch($2,Set64,$4,$1.bit_val,(* FIXME: label *)) } +*/ + + /* TST (immediate) alias of ANDS (immediate) */ + + | TST wreg COMMA big_imm + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Wd>, #<imm>") + else match encodeBitMasks 32 $4 with + | None -> error_arg "<imm> can not be encoded as bitmask" + | _ -> `AArch64LogicalImmediate(W ZR,$2,Set32,true,LogicalOp_AND,reg_size_bits_R32_of_big_int $4) } + | TST xreg COMMA big_imm + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xd>, #<imm>") + else match encodeBitMasks 64 $4 with + | None -> error_arg "<imm> can not be encoded as bitmask" + | _ -> `AArch64LogicalImmediate(X ZR,$2,Set64,true,LogicalOp_AND,reg_size_bits_R64_of_big_int $4) } + + /* TST (shifted register) alias of ANDS (shifted register) */ + + | TST wreg COMMA wreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wn>, <Wm>{, <shift> #<amount>}") + else `AArch64LogicalShiftedRegister(W ZR,$2,$4,Set32,true,LogicalOp_AND,ShiftType_LSL,0,false) } + | TST wreg COMMA wreg COMMA SHIFT imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Wn>, <Wm>{, <shift> #<amount>}") + else if not (0 <= $7 && $7 <= 31) then error_arg "<amount> must be in the range 0 to 31" + else `AArch64LogicalShiftedRegister(W ZR,$2,$4,Set32,true,LogicalOp_AND,$6.shift_type,$7,false) } + + | TST xreg COMMA xreg + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn>, <Xm>{, <shift> #<amount>}") + else `AArch64LogicalShiftedRegister(X ZR,$2,$4,Set64,true,LogicalOp_AND,ShiftType_LSL,0,false) } + | TST xreg COMMA xreg COMMA SHIFT imm + { if not (isregzr $2 && isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <Xn>, <Xm>{, <shift> #<amount>}") + else if not (0 <= $7 && $7 <= 63) then error_arg "<amount> must be in the range 0 to 63" + else `AArch64LogicalShiftedRegister(X ZR,$2,$4,Set64,true,LogicalOp_AND,$6.shift_type,$7,false) } + + /* MRS */ + + | MRS xreg COMMA SYSREG + { if not (isregzr $2) then error_registers ("expected " ^ $1.txt ^ " <Xt>, <systemreg>") + else `AArch64MoveSystemRegister($2,$4.sys_op0,$4.sys_op1,$4.sys_op2,$4.sys_crn,$4.sys_crm,true) } + + /* MSR (immediate) */ + + | MSR PSTATEFIELD COMMA imm + { if not (0 <= $4 && $4 <= 15) then error_arg "<imm> must be in the range 0 to 15" + else `AArch64MoveSystemImmediate($4,$2) } + + /* MSR (register) */ + + | MSR SYSREG COMMA xreg + { if not (isregzr $4) then error_registers ("expected " ^ $1.txt ^ " <systemreg>, <Xt>") + else `AArch64MoveSystemRegister($4,$2.sys_op0,$2.sys_op1,$2.sys_op2,$2.sys_crn,$2.sys_crm,false) } diff --git a/arm/gen/pretty.hgen b/arm/gen/pretty.hgen new file mode 100644 index 00000000..2bbf7af7 --- /dev/null +++ b/arm/gen/pretty.hgen @@ -0,0 +1,393 @@ +| `AArch64TMStart t -> + sprintf "TSTART %s" (pp_regzr Set64 t) + +| `AArch64TMCommit -> "TCOMMIT" + +| `AArch64TMAbort (retry,reason) -> + sprintf "TABORT %s" (pp_imm (if retry then 32 + reason else reason)) + +| `AArch64TMTest -> "TTEST" + +| `AArch64ImplementationDefinedStopFetching -> + "_STOP_FETCHING" + +| `AArch64ImplementationDefinedThreadStart -> + "_THREAD_START" + +| `AArch64ImplementationDefinedTestBeginEnd (isEnd) -> + if isEnd then + "_TEST_ENDS" + else + "_TEST_BEGINS" + +| `AArch64AddSubCarry (d,n,m,datasize,sub_op,setflags) -> + if sub_op && is_zero_reg n then + sprintf "%s %s,%s" (pp_withflags "NGC" setflags) (pp_regzr datasize d) (pp_regzr datasize m) + else if sub_op then + sprintf "%s %s,%s,%s" (pp_withflags "SBC" setflags) (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) + else + sprintf "%s %s,%s,%s" (pp_withflags "ADC" setflags) (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) + +| `AArch64AddSubExtendRegister (d,n,m,datasize,sub_op,setflags,extend_type,shift) -> + if setflags && is_zero_reg d then + begin + if (is_sp_reg n) && ((datasize = Set32 && extend_type = ExtendType_UXTW) || (datasize = Set64 && extend_type = ExtendType_UXTX)) then + sprintf "%s %s,%s%s" (if sub_op then "CMP" else "CMN") (pp_regsp datasize n) (pp_regzrbyext datasize extend_type m) + (if shift = 0 then "" else (",LSL " ^ (pp_imm shift))) + else + sprintf "%s %s,%s%s" (if sub_op then "CMP" else "CMN") (pp_regsp datasize n) (pp_regzrbyext datasize extend_type m) (pp_addsub_regext datasize extend_type shift) + end + else if (is_sp_reg d || is_sp_reg n) && ((datasize = Set32 && extend_type = ExtendType_UXTW) || (datasize = Set64 && extend_type = ExtendType_UXTX)) then + sprintf "%s %s,%s,%s%s" (pp_addsub sub_op setflags) (if setflags then pp_regzr datasize d else pp_regsp datasize d) (pp_regsp datasize n) (pp_regzrbyext datasize extend_type m) + (if shift = 0 then "" else (",LSL " ^ (pp_imm shift))) + else + sprintf "%s %s,%s,%s%s" (pp_addsub sub_op setflags) (if setflags then pp_regzr datasize d else pp_regsp datasize d) (pp_regsp datasize n) (pp_regzrbyext datasize extend_type m) (pp_addsub_regext datasize extend_type shift) + +| `AArch64AddSubImmediate (d,n,datasize,sub_op,setflags,imm) -> + let (imm12,shift) = + if reg_size_bits_iskbituimm 12 imm then (reg_size_bits_to_int imm, 0) + else (reg_size_bits_to_int (reg_size_bits_shift_right imm 12), 12) + in + if (sub_op,setflags) = (false,false) && (is_sp_reg d || is_sp_reg n) && (shift = 0 && imm12 = 0) then + sprintf "MOV %s,%s" (pp_regsp datasize d) (pp_regsp datasize n) + else if setflags && is_zero_reg d then + sprintf "%s %s,%s%s" (if sub_op then "CMP" else "CMN") (pp_regsp datasize n) (pp_imm imm12) (if shift = 0 then "" else ",LSL #12") + else + sprintf "%s %s,%s,%s%s" (pp_addsub sub_op setflags) (if setflags then pp_regzr datasize d else pp_regsp datasize d) (pp_regsp datasize n) (pp_imm imm12) (if shift = 0 then "" else ",LSL #12") + +| `AArch64AddSubShiftedRegister (d,n,m,datasize,sub_op,setflags,shift_type,shift_amount) -> + if setflags && is_zero_reg d then + begin + if shift_type = ShiftType_LSL && shift_amount = 0 then + sprintf "%s %s,%s" (if sub_op then "CMP" else "CMN") (pp_regzr datasize n) (pp_regzr datasize m) + else + sprintf "%s %s,%s,%s %s" (if sub_op then "CMP" else "CMN") (pp_regzr datasize n) (pp_regzr datasize m) (pp_shift shift_type) (pp_imm shift_amount) + end + else if sub_op && is_zero_reg n then + begin + if shift_type = ShiftType_LSL && shift_amount = 0 then + sprintf "%s %s,%s" (pp_withflags "NEG" setflags) (pp_regzr datasize d) (pp_regzr datasize m) + else + sprintf "%s %s,%s,%s %s" (pp_withflags "NEG" setflags) (pp_regzr datasize d) (pp_regzr datasize m) (pp_shift shift_type) (pp_imm shift_amount) + end + else if shift_type = ShiftType_LSL && shift_amount = 0 then + sprintf "%s %s,%s,%s" (pp_addsub sub_op setflags) (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) + else + sprintf "%s %s,%s,%s,%s %s" (pp_addsub sub_op setflags) (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) (pp_shift shift_type) (pp_imm shift_amount) + +| `AArch64Address (d,page,imm) -> + sprintf "%s %s,%s" (if page then "ADRP" else "ADR") (pp_regzr Set64 d) (pp_offset page imm) + +| `AArch64LogicalImmediate (d,n,datasize,setflags,op,imm) -> + if op = LogicalOp_AND && setflags && is_zero_reg d then + sprintf "TST %s,%s" (pp_regzr datasize n) (pp_reg_size_imm imm) + else if op = LogicalOp_ORR && not setflags && is_zero_reg n && not (moveWidePreferred datasize imm) then (* ARM: missing the check of n=ZR *) + sprintf "MOV %s,%s" (pp_regsp datasize d) (pp_reg_size_imm imm) + else sprintf "%s %s,%s,%s" (pp_logop op setflags false) (if setflags then pp_regzr datasize d else pp_regsp datasize d) (pp_regzr datasize n) (pp_reg_size_imm imm) + +| `AArch64LogicalShiftedRegister (d,n,m,datasize,setflags,op,shift_type,shift_amount,invert) -> + if op = LogicalOp_AND && setflags && not invert && is_zero_reg d then + begin + if shift_type = ShiftType_LSL && shift_amount = 0 then + sprintf "TST %s,%s" (pp_regzr datasize n) (pp_regzr datasize m) + else + sprintf "TST %s,%s,%s %s" (pp_regzr datasize n) (pp_regzr datasize m) (pp_shift shift_type) (pp_imm shift_amount) + end + else if op = LogicalOp_ORR && not setflags && invert && is_zero_reg n then + begin + if shift_type = ShiftType_LSL && shift_amount = 0 then + sprintf "MVN %s,%s" (pp_regzr datasize d) (pp_regzr datasize m) + else + sprintf "MVN %s,%s,%s %s" (pp_regzr datasize d) (pp_regzr datasize m) (pp_shift shift_type) (pp_imm shift_amount) + end + else if op = LogicalOp_ORR && not setflags && not invert && is_zero_reg n && shift_type = ShiftType_LSL && shift_amount = 0 then + sprintf "MOV %s,%s" (pp_regzr datasize d) (pp_regzr datasize m) + else + begin + if shift_type = ShiftType_LSL && shift_amount = 0 then + sprintf "%s %s,%s,%s" (pp_logop op setflags invert) (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) + else + sprintf "%s %s,%s,%s,%s %s" (pp_logop op setflags invert) (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) (pp_shift shift_type) (pp_imm shift_amount) + end + +| `AArch64Shift (d,n,m,datasize,shift_type) -> + sprintf "%s %s,%s,%s" (pp_shiftop shift_type) (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) + +| `AArch64BranchConditional (offset,condition) -> + sprintf "B.%s %s" (pp_cond condition) (pp_offset false offset) + +| `AArch64BranchImmediate (branch_type,offset) -> + sprintf "%s %s" (pp_branchimmediate branch_type) (pp_offset false offset) + +| `AArch64BitfieldMove (d,n,datasize,inzero,extend,_R,_S,wmask,tmask) -> + if (inzero,extend) = (false,false) && _S < _R then + sprintf "BFI %s,%s,%s,%s" (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm _R) (pp_imm (_S+1)) (* FIXME: I'm not sure this is the right translation of imms and immr *) + else if (inzero,extend) = (false,false) && _S >= _R then + sprintf "BFXIL %s,%s,%s,%s" (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm _R) (pp_imm (_S-_R+1)) + else if (inzero,extend) = (true,false) && datasize = Set32 && _S <> 0b011111 && _S+1 = _R then + sprintf "LSL %s,%s,%s" (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm (31-_S)) + else if (inzero,extend) = (true,false) && datasize = Set64 && _S <> 0b111111 && _S+1 = _R then + sprintf "LSL %s,%s,%s" (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm (63-_S)) + else if inzero && datasize = Set32 && _S = 0b011111 then + sprintf "%s %s,%s,%s" (if extend then "ASR" else "LSR") (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm _R) + else if inzero && datasize = Set64 && _S = 0b111111 then + sprintf "%s %s,%s,%s" (if extend then "ASR" else "LSR") (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm _R) + else if inzero && _S < _R then + sprintf "%s %s,%s,%s,%s" (if extend then "SBFIZ" else "UBFIZ") (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm _R) (pp_imm (_S+1)) (* FIXME: -<lsb> MOD 32/64 *) + else if inzero && bFXPreferred datasize (if extend then 0 else 1) _S _R then + sprintf "%s %s,%s,%s,%s" (if extend then "SBFX" else "UBFX") (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm _R) (pp_imm (_S - _R + 1)) + else if inzero && _R = 0 && _S = 0b000111 then + sprintf "%s %s,%s" (if extend then "SXTB" else "UXTB") (pp_regzr datasize d) (pp_regzr Set32 n) + else if inzero && _R = 0 && _S = 0b001111 then + sprintf "%s %s,%s" (if extend then "SXTH" else "UXTH") (pp_regzr datasize d) (pp_regzr Set32 n) + else if (inzero,extend) = (true,true) && _R = 0 && _S = 0b011111 then (* implicitly datasize = Set64 *) + sprintf "SXTW %s,%s" (pp_regzr datasize d) (pp_regzr Set32 n) + else + sprintf "%s %s,%s,%s,%s" (pp_bfm inzero extend) (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm _R) (pp_imm _S) + +| `AArch64BranchRegister (n,branch_type) -> + if branch_type = BranchType_RET && n = X (Ireg R30) then + "RET" + else + sprintf "%s %s" (pp_branchregister branch_type) (pp_regzr Set64 n) + +| `AArch64CompareAndBranch (t,datasize,iszero,offset) -> + sprintf "%s %s,%s" (if iszero then "CBZ" else "CBNZ") (pp_regzr datasize t) (pp_offset false offset) + +| `AArch64ConditionalCompareImmediate (n,datasize,sub_op,condition,flags,imm) -> + sprintf "%s %s,%s,%s,%s" (if sub_op then "CCMP" else "CCMN") (pp_regzr datasize n) (pp_reg_size_imm imm) (pp_imm flags) (pp_cond condition) + +| `AArch64ConditionalCompareRegister (n,m,datasize,sub_op,condition,flags) -> + sprintf "%s %s,%s,%s,%s" (if sub_op then "CCMP" else "CCMN") (pp_regzr datasize n) (pp_regzr datasize m) (pp_imm flags) (pp_cond condition) + +| `AArch64ClearExclusiveMonitor (imm) -> + if imm = 15 then + sprintf "CLREX" + else + sprintf "CLREX %s" (pp_imm imm) + +| `AArch64CountLeading (d,n,datasize,opcode) -> + sprintf "%s %s,%s" (pp_countop opcode) (pp_regzr datasize d) (pp_regzr datasize n) + +| `AArch64CRC (d,n,m,size,crc32c) -> + sprintf "%s %s,%s,%s" (pp_crc size crc32c) (pp_regzr Set32 d) (pp_regzr Set32 n) (pp_regzr (if size = DataSize64 then Set64 else Set32) m) + +| `AArch64ConditionalSelect (d,n,m,datasize,condition,else_inv,else_inc) -> + if not else_inv && else_inc && n = m && not (is_zero_reg n) && not (condition = 0b1110 || condition = 0b1111) then + sprintf "CINC %s,%s,%s" (pp_regzr datasize d) (pp_regzr datasize n) (pp_cond condition) + else if not else_inv && else_inc && n = m && is_zero_reg n && not (condition = 0b1110 || condition = 0b1111) then + sprintf "CSET %s,%s" (pp_regzr datasize d) (pp_cond condition) + else if else_inv && not else_inc && n = m && not (is_zero_reg n) && not (condition = 0b1110 || condition = 0b1111) then + sprintf "CINV %s,%s,%s" (pp_regzr datasize d) (pp_regzr datasize n) (pp_cond condition) + else if else_inv && not else_inc && n = m && is_zero_reg n && not (condition = 0b1110 || condition = 0b1111) then + sprintf "CSETM %s,%s" (pp_regzr datasize d) (pp_cond condition) + else if else_inv && else_inc && n = m && not (condition = 0b1110 || condition = 0b1111) then + sprintf "CNEG %s,%s,%s" (pp_regzr datasize d) (pp_regzr datasize n) (pp_cond condition) + else + sprintf "%s %s,%s,%s,%s" (pp_csel else_inv else_inc) (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) (pp_cond condition) + +| `AArch64Barrier (op,domain,types) -> + if op = MemBarrierOp_ISB && domain = MBReqDomain_FullSystem && types = MBReqTypes_All then + pp_barr op + else + sprintf "%s %s" (pp_barr op) (pp_barroption domain types) + +| `AArch64ExtractRegister (d,n,m,datasize,lsb) -> + if n = m then + sprintf "ROR %s,%s,%s" (pp_regzr datasize d) (pp_regzr datasize n) (pp_imm lsb) + else + sprintf "EXTR %s,%s,%s,%s" (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) (pp_imm lsb) + +| `AArch64Hint (op) -> + begin + match op with + | SystemHintOp_NOP -> "NOP" + | SystemHintOp_YIELD -> "YIELD" + | SystemHintOp_WFE -> "WFE" + | SystemHintOp_WFI -> "WFI" + | SystemHintOp_SEV -> "SEV" + | SystemHintOp_SEVL -> "SEVL" + end + +| `AArch64LoadStoreAcqExc (n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) -> + if pair && memop = MemOp_LOAD then + sprintf "%s %s,%s,[%s]" (pp_ldaxstlxp memop acctype excl pair datasize) (pp_regzr regsize t) (pp_regzr regsize t2) (pp_regsp Set64 n) + else if pair && memop = MemOp_STORE then + sprintf "%s %s,%s,%s,[%s]" (pp_ldaxstlxp memop acctype excl pair datasize) (pp_regzr Set32 s) (pp_regzr regsize t) (pp_regzr regsize t2) (pp_regsp Set64 n) + else if not pair && memop = MemOp_STORE && excl then + sprintf "%s %s,%s,[%s]" (pp_ldaxstlxp memop acctype excl pair datasize) (pp_regzr Set32 s) (pp_regzr regsize t) (pp_regsp Set64 n) + else + sprintf "%s %s,[%s]" (pp_ldaxstlxp memop acctype excl pair datasize) (pp_regzr regsize t) (pp_regsp Set64 n) + +| `AArch64LoadStorePair (wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset) -> + begin + let inst = if signed then "LDPSW" else if memop = MemOp_LOAD then "LDP" else "STP" in + let regsize = if signed then Set64 else (match datasize with DataSize32 -> Set32 | DataSize64 -> Set64 | DataSize16 | DataSize8 -> failwith "unexpected value") in + match (wback,postindex) with + | (true,true) -> + sprintf "%s %s,%s,[%s],%s" inst (pp_regzr regsize t) (pp_regzr regsize t2) (pp_regsp Set64 n) (pp_big_imm offset) + | (true,false) -> + sprintf "%s %s,%s,[%s,%s]!" inst (pp_regzr regsize t) (pp_regzr regsize t2) (pp_regsp Set64 n) (pp_big_imm offset) + | (false,false) -> + if eq_bit64 offset (bit64_of_int 0) then + sprintf "%s %s,%s,[%s]" inst (pp_regzr regsize t) (pp_regzr regsize t2) (pp_regsp Set64 n) + else + sprintf "%s %s,%s,[%s,%s]" inst (pp_regzr regsize t) (pp_regzr regsize t2) (pp_regsp Set64 n) (pp_big_imm offset) + | (false,true) -> failwith "unexpected value" + end + +| `AArch64LoadImmediate (n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) -> + begin + if memop = MemOp_PREFETCH then + begin + (* the ast does not hold enough information to distinguish PRFM and PRFUM in some cases. + PRFM: <pimm> is a multiple of 8 in the range 0 to 32760 + PRFUM: <simm> is in the range -256 to 255 *) + if eq_bit64 offset (bit64_of_int 0) then + sprintf "PRFM %s,[%s]" (pp_prfop (inst_reg_to_int t)) (pp_regsp Set64 n) + else if big_in_range offset (-256) 255 then + sprintf "PRFUM %s,[%s,%s]" (pp_prfop (inst_reg_to_int t)) (pp_regsp Set64 n) (pp_big_imm offset) + else + sprintf "PRFM %s,[%s,%s]" (pp_prfop (inst_reg_to_int t)) (pp_regsp Set64 n) (pp_big_imm offset) + end + else + let inst = + (if memop = MemOp_LOAD then "LD" else "ST") ^ + (if not wback && not postindex && + not begin match datasize with + | DataSize8 -> + Nat_big_num.less_equal Nat_big_num.zero offset && + Nat_big_num.less_equal offset (Nat_big_num.of_int 4095) + | DataSize16 -> + Nat_big_num.less_equal Nat_big_num.zero offset && + Nat_big_num.less_equal offset (Nat_big_num.of_int 8190) && + Nat_big_num.equal + (Nat_big_num.modulus offset (Nat_big_num.of_int 2)) + Nat_big_num.zero + | DataSize32 -> + Nat_big_num.less_equal Nat_big_num.zero offset && + Nat_big_num.less_equal offset (Nat_big_num.of_int 16380) && + Nat_big_num.equal + (Nat_big_num.modulus offset (Nat_big_num.of_int 4)) + Nat_big_num.zero + | DataSize64 -> + Nat_big_num.less_equal Nat_big_num.zero offset && + Nat_big_num.less_equal offset (Nat_big_num.of_int 32760) && + Nat_big_num.equal + (Nat_big_num.modulus offset (Nat_big_num.of_int 8)) + Nat_big_num.zero + end + then + begin + if acctype=AccType_UNPRIV then "TR" + else "UR" + end + else "R") ^ + (if signed then "S" else "") ^ + (match datasize with + | DataSize8 -> "B" + | DataSize16 -> "H" + | DataSize32 -> if regsize = Set32 then "" else "W" + | DataSize64 -> "") in + match (wback,postindex) with + | (true,true) -> + sprintf "%s %s,[%s],%s" inst (pp_regzr regsize t) (pp_regsp Set64 n) (pp_big_imm offset) + | (true,false) -> + sprintf "%s %s,[%s,%s]!" inst (pp_regzr regsize t) (pp_regsp Set64 n) (pp_big_imm offset) + | (false,false) -> + if eq_bit64 offset (bit64_of_int 0) then + sprintf "%s %s,[%s]" inst (pp_regzr regsize t) (pp_regsp Set64 n) + else + sprintf "%s %s,[%s,%s]" inst (pp_regzr regsize t) (pp_regsp Set64 n) (pp_big_imm offset) + | (false,true) -> failwith "unexpected value" + end + +| `AArch64LoadLiteral (t,memop,signed,size,offset,datasize) -> + if memop = MemOp_PREFETCH then + sprintf "PRFM %s,%s" (pp_prfop (inst_reg_to_int t)) (pp_offset false offset) + else + let datasize = + if signed then Set64 + else + begin match datasize with + | DataSize64 -> Set64 + | DataSize32 -> Set32 + | DataSize16 | DataSize8 -> failwith "unexpected value" + end + in + sprintf "%s %s,%s" (if signed then "LDRSW" else "LDR") (pp_regzr datasize t) (pp_offset false offset) + +| `AArch64LoadRegister (n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) -> + begin + if memop = MemOp_PREFETCH then + begin + if extend_type = ExtendType_UXTX && shift = 0 then + sprintf "PRFM %s,[%s,%s]" (pp_prfop (inst_reg_to_int t)) (pp_regsp Set64 n) (pp_regzrbyext Set64 extend_type m) + else if extend_type = ExtendType_UXTX (* && shift <> 0 *) then + sprintf "PRFM %s,[%s,%s,LSL %s]" (pp_prfop (inst_reg_to_int t)) (pp_regsp Set64 n) (pp_regzrbyext Set64 extend_type m) (pp_imm shift) + else + sprintf "PRFM %s,[%s,%s%s]" (pp_prfop (inst_reg_to_int t)) (pp_regsp Set64 n) (pp_regzrbyext Set64 extend_type m) (pp_ldrstr_regext extend_type shift) + end + else + let inst = + (if memop = MemOp_LOAD then "LDR" else "STR") ^ + (if signed then "S" else "") ^ + (match datasize with + | DataSize8 -> "B" + | DataSize16 -> "H" + | DataSize32 -> if regsize = Set32 then "" else "W" + | DataSize64 -> "") in + if extend_type = ExtendType_UXTX && shift = 0 then + sprintf "%s %s,[%s,%s]" inst (pp_regzr regsize t) (pp_regsp Set64 n) (pp_regzrbyext Set64 extend_type m) + else if extend_type = ExtendType_UXTX (* && shift <> 0 *) then + sprintf "%s %s,[%s,%s,LSL %s]" inst (pp_regzr regsize t) (pp_regsp Set64 n) (pp_regzrbyext Set64 extend_type m) (pp_imm shift) + else + sprintf "%s %s,[%s,%s%s]" inst (pp_regzr regsize t) (pp_regsp Set64 n) (pp_regzrbyext Set64 extend_type m) (pp_ldrstr_regext extend_type shift) + end + +| `AArch64MultiplyAddSub (d,n,m,a,destsize,datasize,sub_op) -> + if is_zero_reg a then + sprintf "%s %s,%s,%s" (if sub_op then "MNEG" else "MUL") (pp_regzr destsize d) (pp_regzr destsize n) (pp_regzr destsize m) + else + sprintf "%s %s,%s,%s,%s" (if sub_op then "MSUB" else "MADD") (pp_regzr destsize d) (pp_regzr destsize n) (pp_regzr destsize m) (pp_regzr destsize a) + +| `AArch64MoveWide (d,datasize,imm,pos,opcode) -> + if opcode = MoveWideOp_N && datasize = Set32 && (not (imm = 0 && pos <> 0)) && not (imm = 0xffff) then + sprintf "MOV %s,%s" (pp_regzr datasize d) (pp_imm (lnot (imm lsl (pos*16)))) + else if opcode = MoveWideOp_N && datasize = Set64 && (not (imm = 0 && pos <> 0)) then + sprintf "MOV %s,%s" (pp_regzr datasize d) (pp_imm (lnot (imm lsl (pos*16)))) + else if opcode = MoveWideOp_Z && (not (imm = 0 && pos <> 0)) then + sprintf "MOV %s,%s" (pp_regzr datasize d) (pp_imm (imm lsl (pos*16))) + else if pos = 0 then + sprintf "%s %s,%s" (pp_movwide opcode) (pp_regzr datasize d) (pp_imm imm) + else + sprintf "%s %s,%s,LSL %s" (pp_movwide opcode) (pp_regzr datasize d) (pp_imm imm) (pp_imm pos) + +| `AArch64Reverse (d,n,datasize,op) -> + sprintf "%s %s,%s" (pp_reverse datasize op) (pp_regzr datasize d) (pp_regzr datasize n) + +| `AArch64Division (d,n,m,datasize,unsigned) -> + sprintf "%s %s,%s,%s" (if unsigned then "UDIV" else "SDIV") (pp_regzr datasize d) (pp_regzr datasize n) (pp_regzr datasize m) + +| `AArch64MultiplyAddSubLong (d,n,m,a,destsize,datasize,sub_op,unsigned) -> + if sub_op && is_zero_reg a then + sprintf "%s %s,%s,%s" (if unsigned then "UMNEGL" else "SMNEGL") (pp_regzr Set64 d) (pp_regzr Set32 n) (pp_regzr Set32 m) + else if not sub_op && is_zero_reg a then + sprintf "%s %s,%s,%s" (if unsigned then "UMULL" else "SMULL") (pp_regzr Set64 d) (pp_regzr Set32 n) (pp_regzr Set32 m) + else + sprintf "%s %s,%s,%s,%s" (pp_maddsubl sub_op unsigned) (pp_regzr Set64 d) (pp_regzr Set32 n) (pp_regzr Set32 m) (pp_regzr Set64 a) + +| `AArch64MultiplyHigh (d,n,m,a,destsize,datasize,unsigned) -> + sprintf "%s %s,%s,%s" (if unsigned then "UMULH" else "SMULH") (pp_regzr Set64 d) (pp_regzr Set64 n) (pp_regzr Set64 m) + +| `AArch64TestBitAndBranch (t,datasize,bit_pos,bit_val,offset) -> + sprintf "%s %s,%s,%s" (if bit_pos = 1 then "TBNZ" else "TBZ") (pp_regzr datasize t) (pp_imm bit_pos) (pp_offset false offset) + +| `AArch64MoveSystemRegister (t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) -> + if read then + sprintf "MRS %s,%s" (pp_regzr Set64 t) (pp_sysreg (sys_op0,sys_op1,sys_op2,sys_crn,sys_crm)) + else + sprintf "MSR %s,%s" (pp_sysreg (sys_op0,sys_op1,sys_op2,sys_crn,sys_crm)) (pp_regzr Set64 t) + +| `AArch64MoveSystemImmediate (operand,field) -> + sprintf "MSR %s,%s" (pp_pstatefield field) (pp_imm operand) diff --git a/arm/gen/regs_out_in.hgen b/arm/gen/regs_out_in.hgen new file mode 100644 index 00000000..724a574b --- /dev/null +++ b/arm/gen/regs_out_in.hgen @@ -0,0 +1,155 @@ +(* for each instruction instance, identify the role of the registers + and possible branching: (outputs, inputs, voidstars, branch) *) + +| `AArch64TMStart t -> failwith "TSTART is not implemented" +| `AArch64TMCommit -> failwith "TCOMMIT is not implemented" +| `AArch64TMAbort (retry,reason) -> failwith "TABORT is not implemented" +| `AArch64TMTest -> failwith "TTEST is not implemented" + +| `AArch64AddSubCarry (d,n,m,_datasize,_sub_op,_setflags) -> + ([d], [n; m], [], [Next]) + +| `AArch64AddSubExtendRegister (d,n,m,_datasize,_sub_op,_setflags,_extend_type,_shift) -> + ([d], [n; m], [], [Next]) + +| `AArch64AddSubShiftedRegister (d,n,m,_datasize,_sub_op,_setflags,_shift_type,_shift_amount) -> + ([d], [n; m], [], [Next]) + +| `AArch64AddSubImmediate (d,n,_datasize,_sub_op,_setflags,_imm) -> + ([d], [n], [], [Next]) + +| `AArch64Address (d,_page,_imm) -> + ([d], [], [], [Next]) + +| `AArch64LogicalImmediate (d,n,_datasize,_setflags,_op,_imm) -> + ([d], [n], [], [Next]) + +| `AArch64LogicalShiftedRegister (d,n,m,_datasize,_setflags,_op,_shift_type,_shift_amount,_invert) -> + ([d], [n; m], [], [Next]) + +| `AArch64Shift (d,n,m,_datasize,_shift_type) -> + ([d], [n; m], [], [Next]) + +| `AArch64BranchConditional (__offset,_condition) -> + ([], [], [], [Next]) + +| `AArch64BranchImmediate (branch_type,__offset) -> + ([], [], [], [Next]) + +| `AArch64BitfieldMove (d,n,_datasize,_inzero,_extend,_R,_S,_wmask,_tmask) -> + ([d], [n], [], [Next]) + +| `AArch64BranchRegister (n,branch_type) -> + ([], [n], [], [Next]) + +| `AArch64CompareAndBranch (t,_datasize,_iszero,__offset) -> + ([], [t], [], [Next]) + +| `AArch64ConditionalCompareImmediate (n,_datasize,_sub_op,_condition,_flags,_imm) -> + ([], [n], [], [Next]) + +| `AArch64ConditionalCompareRegister (n,m,_datasize,_sub_op,_condition,_flags) -> + ([], [n; m], [], [Next]) + +| `AArch64ClearExclusiveMonitor (_imm) -> + ([], [], [], [Next]) + +| `AArch64CountLeading (d,n,_datasize,__opcode) -> + ([d], [n], [], [Next]) + +| `AArch64CRC (d,n,m,_size,_crc32c) -> + ([d], [n; m], [], [Next]) + +| `AArch64ConditionalSelect (d,n,m,_datasize,_condition,_else_inv,_else_inc) -> + ([d], [n; m], [], [Next]) + +| `AArch64Barrier (_op,_domain,_types) -> + ([], [], [], [Next]) + +| `AArch64ExtractRegister (d,n,m,_datasize,_lsb) -> + ([d], [n; m], [], [Next]) + +| `AArch64Hint (_op) -> + ([], [], [], [Next]) + +| `AArch64LoadStoreAcqExc (n,t,t2,s,_acctype,false,false,MemOp_STORE,_elsize,_regsize,_datasize) -> + ([], [t; n], [n], [Next]) +| `AArch64LoadStoreAcqExc (n,t,t2,s,_acctype,true,false,MemOp_STORE,_elsize,_regsize,_datasize) -> + ([s], [t; n], [n], [Next]) +| `AArch64LoadStoreAcqExc (n,t,t2,s,_acctype,true,true,MemOp_STORE,_elsize,_regsize,_datasize) -> + ([s], [t; t2; n], [n], [Next]) + +| `AArch64LoadStoreAcqExc (n,t,t2,s,_acctype,false,false,MemOp_LOAD,_elsize,_regsize,_datasize) -> + ([t], [n], [n], [Next]) +| `AArch64LoadStoreAcqExc (n,t,t2,s,_acctype,true,false,MemOp_LOAD,_elsize,_regsize,_datasize) -> + ([t], [n], [n], [Next]) +| `AArch64LoadStoreAcqExc (n,t,t2,s,_acctype,true,true,MemOp_LOAD,_elsize,_regsize,_datasize) -> + ([t; t2], [n], [n], [Next]) + +| `AArch64LoadStorePair (false,_postindex,n,t,t2,_acctype,MemOp_STORE,_signed,_datasize,_offset) -> + ([], [n; t; t2], [n], [Next]) +| `AArch64LoadStorePair (true,_postindex,n,t,t2,_acctype,MemOp_STORE,_signed,_datasize,_offset) -> + ([n], [n; t; t2], [n], [Next]) + +| `AArch64LoadStorePair (false,_postindex,n,t,t2,_acctype,MemOp_LOAD,_signed,_datasize,_offset) -> + ([t; t2], [n], [n], [Next]) +| `AArch64LoadStorePair (true,_postindex,n,t,t2,_acctype,MemOp_LOAD,_signed,_datasize,_offset) -> + ([t; t2; n], [n], [n], [Next]) + +| `AArch64LoadImmediate (n,t,_acctype,MemOp_STORE,_signed,false,_postindex,_offset,_regsize,_datasize) -> + ([], [n; t], [n], [Next]) +| `AArch64LoadImmediate (n,t,_acctype,MemOp_STORE,_signed,true,_postindex,_offset,_regsize,_datasize) -> + ([n], [n; t], [n], [Next]) + +| `AArch64LoadImmediate (n,t,_acctype,MemOp_LOAD,_signed,false,_postindex,_offset,_regsize,_datasize) -> + ([t], [n], [n], [Next]) +| `AArch64LoadImmediate (n,t,_acctype,MemOp_LOAD,_signed,true,_postindex,_offset,_regsize,_datasize) -> + ([t; n], [n], [n], [Next]) + +| `AArch64LoadLiteral (t,MemOp_STORE,_signed,_size,_offset,_datasize) -> + ([], [t], [], [Next]) + +| `AArch64LoadLiteral (t,MemOp_LOAD,_signed,_size,_offset,_datasize) -> + ([t], [], [], [Next]) + +| `AArch64LoadRegister (n,t,m,_acctype,MemOp_STORE,_signed,false,_postindex,_extend_type,_shift,_regsize,_datasize) -> + ([], [n; t; m], [n], [Next]) +| `AArch64LoadRegister (n,t,m,_acctype,MemOp_STORE,_signed,true,_postindex,_extend_type,_shift,_regsize,_datasize) -> + ([n], [n; t; m], [n], [Next]) + +| `AArch64LoadRegister (n,t,m,_acctype,MemOp_LOAD,_signed,false,_postindex,_extend_type,_shift,_regsize,_datasize) -> + ([t], [n; m], [n], [Next]) +| `AArch64LoadRegister (n,t,m,_acctype,MemOp_LOAD,_signed,true,_postindex,_extend_type,_shift,_regsize,_datasize) -> + ([t; n], [n; m], [n], [Next]) + +| `AArch64LoadRegister (n,t,m,_acctype,MemOp_PREFETCH,_signed,_wback,_postindex,_extend_type,_shift,_regsize,_datasize) -> + ([], [n; m], [n], [Next]) + +| `AArch64MultiplyAddSub (d,n,m,a,_destsize,_datasize,_sub_op) -> + ([d], [n; m; a], [], [Next]) + +| `AArch64MoveWide (d,_datasize,_imm,_pos,_opcode) -> + ([d], [], [], [Next]) + +| `AArch64Reverse (d,n,_datasize,_op) -> + ([d], [n], [], [Next]) + +| `AArch64Division (d,n,m,_datasize,_unsigned) -> + ([d], [n; m], [], [Next]) + +| `AArch64MultiplyAddSubLong (d,n,m,a,_destsize,_datasize,_sub_op,_unsigned) -> + ([d], [n; m; a], [], [Next]) + +| `AArch64MultiplyHigh (d,n,m,a,_destsize,_datasize,_unsigned) -> + ([d], [n; m; a], [], [Next]) + +| `AArch64TestBitAndBranch (t,_datasize,_bit_pos,_bit_val,_offset) -> + ([], [t], [], [Next]) + +| `AArch64MoveSystemRegister (t,_sys_op0,_sys_op1,_sys_op2,_sys_crn,_sys_crm,true) -> + ([t], [], [], [Next]) +| `AArch64MoveSystemRegister (t,_sys_op0,_sys_op1,_sys_op2,_sys_crn,_sys_crm,false) -> + ([], [t], [], [Next]) + +| `AArch64MoveSystemImmediate (_operand,_field) -> + ([], [], [], [Next]) diff --git a/arm/gen/sail_trans_out.hgen b/arm/gen/sail_trans_out.hgen new file mode 100644 index 00000000..9595f00c --- /dev/null +++ b/arm/gen/sail_trans_out.hgen @@ -0,0 +1,326 @@ +| ("TMStart", [t]) -> + `AArch64TMStart (translate_out_regzr Set64 t) + +| ("TMCommit", []) -> `AArch64TMCommit + +| ("TMAbort", [retry; reason]) -> + `AArch64TMAbort ( translate_out_bool retry, + translate_out_bits reason) + +| ("TMTest", []) -> `AArch64TMTest + +| ("ImplementationDefinedStopFetching",[]) -> + `AArch64ImplementationDefinedStopFetching + +| ("ImplementationDefinedThreadStart",[]) -> + `AArch64ImplementationDefinedThreadStart + +| ("ImplementationDefinedTestBeginEnd" , [isEnd]) -> + `AArch64ImplementationDefinedTestBeginEnd (translate_out_bool isEnd) + +| ("AddSubCarry", [d; n; m; datasize; sub_op; setflags]) -> + let datasize' = translate_out_reg_size datasize in + `AArch64AddSubCarry ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool sub_op, + translate_out_bool setflags) + +| "AddSubExtendRegister", [d; n; m; datasize; sub_op; setflags; extend_type; shift] -> + let setflags' = translate_out_bool setflags in + let datasize' = translate_out_reg_size datasize in + let extend_type' = translate_out_extendType extend_type in + `AArch64AddSubExtendRegister ((if setflags' then translate_out_regzr datasize' d else translate_out_regsp datasize' d), + translate_out_regsp datasize' n, + translate_out_regzrbyext datasize' extend_type' m, + datasize', + translate_out_bool sub_op, + setflags', + extend_type', + translate_out_int shift) + +| "AddSubShiftedRegister", [d; n; m; datasize; sub_op; setflags; shift_type; shift_amount] -> + let datasize' = translate_out_reg_size datasize in + `AArch64AddSubShiftedRegister ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool sub_op, + translate_out_bool setflags, + translate_out_shiftType shift_type, + translate_out_int shift_amount) + +| "AddSubImmediate", [d; n; datasize; sub_op; setflags; imm] -> + let setflags' = translate_out_bool setflags in + let datasize' = translate_out_reg_size datasize in + `AArch64AddSubImmediate ( (if setflags' then translate_out_regzr datasize' d else translate_out_regsp datasize' d), + translate_out_regsp datasize' n, + datasize', + translate_out_bool sub_op, + setflags', + translate_out_reg_size_bits imm) + +| "Address", [d; page; imm] -> + `AArch64Address ( translate_out_regzr Set64 d, + translate_out_bool page, + translate_out_big_bit imm) + +| "LogicalImmediate", [d; n; datasize; setflags; op; imm] -> + let setflags' = translate_out_bool setflags in + let datasize' = translate_out_reg_size datasize in + `AArch64LogicalImmediate ((if setflags' then translate_out_regzr datasize' d else translate_out_regsp datasize' d), + translate_out_regzr datasize' n, + datasize', + setflags', + translate_out_logicalOp op, + translate_out_reg_size_bits imm) + +| "LogicalShiftedRegister", [d; n; m; datasize; setflags; op; shift_type; shift_amount; invert] -> + let datasize' = translate_out_reg_size datasize in + `AArch64LogicalShiftedRegister (translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool setflags, + translate_out_logicalOp op, + translate_out_shiftType shift_type, + translate_out_int shift_amount, + translate_out_bool invert) + +| "Shift", [d; n; m; datasize; shift_type] -> + let datasize' = translate_out_reg_size datasize in + `AArch64Shift ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_shiftType shift_type) + +| "BranchConditional", [offset; condition] -> + `AArch64BranchConditional ( translate_out_signed_big_bit offset, + translate_out_bits condition) + +| "BranchImmediate", [branch_type; offset] -> + `AArch64BranchImmediate ( translate_out_branchType branch_type, + translate_out_signed_big_bit offset) + +| "BitfieldMove", [d; n; datasize; inzero; extend; _R; _S; wmask; tmask] -> + let datasize' = translate_out_reg_size datasize in + `AArch64BitfieldMove (translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + datasize', + translate_out_bool inzero, + translate_out_bool extend, + translate_out_int _R, + translate_out_int _S, + translate_out_reg_size_bits wmask, + translate_out_reg_size_bits wmask) + +| "BranchRegister", [n; branch_type] -> + `AArch64BranchRegister (translate_out_regzr Set64 n, + translate_out_branchType branch_type) + +| "CompareAndBranch", [t; datasize; iszero; offset] -> + let datasize' = translate_out_reg_size datasize in + `AArch64CompareAndBranch (translate_out_regzr datasize' t, + datasize', + translate_out_bool iszero, + translate_out_signed_big_bit offset) + +| "ConditionalCompareImmediate", [n; datasize; sub_op; condition; flags; imm] -> + let datasize' = translate_out_reg_size datasize in + `AArch64ConditionalCompareImmediate ( translate_out_regzr datasize' n, + datasize', + translate_out_bool sub_op, + translate_out_bits condition, + translate_out_bits flags, + translate_out_reg_size_bits imm) + +| "ConditionalCompareRegister", [n; m; datasize; sub_op; condition; flags] -> + let datasize' = translate_out_reg_size datasize in + `AArch64ConditionalCompareRegister (translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool sub_op, + translate_out_bits condition, + translate_out_bits flags) + +| "ClearExclusiveMonitor", [imm] -> `AArch64ClearExclusiveMonitor (translate_out_int imm) + +| "CountLeading", [d; n; datasize; opcode] -> + let datasize' = translate_out_reg_size datasize in + `AArch64CountLeading (translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + datasize', + translate_out_countOp opcode) + +| "CRC", [d; n; m; size; crc32c] -> + let size' = translate_out_data_size size in + `AArch64CRC ( translate_out_regzr Set32 d, + translate_out_regzr Set32 n, + translate_out_regzr (if size' = DataSize64 then Set64 else Set32) m, + size', + translate_out_bool crc32c) + +| "ConditionalSelect", [d; n; m; datasize; condition; else_inf; else_inc] -> + let datasize' = translate_out_reg_size datasize in + `AArch64ConditionalSelect ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bits condition, + translate_out_bool else_inf, + translate_out_bool else_inc) + +| "Barrier", [op; domain; types] -> + `AArch64Barrier ( translate_out_memBarrierOp op, + translate_out_mBReqDomain domain, + translate_out_mBReqTypes types) + +| "ExtractRegister", [d; n; m; datasize; lsb] -> + let datasize' = translate_out_reg_size datasize in + `AArch64ExtractRegister ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_int lsb) + +| "Hint", [op] -> `AArch64Hint (translate_out_systemHintOp op) + +| "LoadStoreAcqExc", [n; t; t2; s; acctype; excl; pair; memop; elsize; regsize; datasize] -> + let regsize' = translate_out_reg_size regsize in + `AArch64LoadStoreAcqExc ( translate_out_regsp Set64 n, + translate_out_regzr regsize' t, + translate_out_regzr regsize' t2, + translate_out_regzr Set32 s, + translate_out_accType acctype, + translate_out_bool excl, + translate_out_bool pair, + translate_out_memOp memop, + translate_out_int elsize, + regsize', + translate_out_data_size datasize) + +| "LoadStorePair",[wback; postindex; n; t; t2; acctype; memop; signed; datasize; offset] -> + let signed' = translate_out_bool signed in + let regsize = if signed' then Set64 else translate_out_reg_size datasize in + `AArch64LoadStorePair ( translate_out_bool wback, + translate_out_bool postindex, + translate_out_regsp Set64 n, + translate_out_regzr regsize t, + translate_out_regzr regsize t2, + translate_out_accType acctype, + translate_out_memOp memop, + signed', + translate_out_data_size datasize, + translate_out_signed_big_bit offset) + +| "LoadImmediate",[n; t; acctype; memop; signed; wback; postindex; offset; regsize; datasize] -> + let regsize' = translate_out_reg_size regsize in + `AArch64LoadImmediate ( translate_out_regsp Set64 n, + translate_out_regzr regsize' t, + translate_out_accType acctype, + translate_out_memOp memop, + translate_out_bool signed, + translate_out_bool wback, + translate_out_bool postindex, + translate_out_signed_big_bit offset, + translate_out_reg_size regsize, + translate_out_data_size datasize) + +| "LoadLiteral",[t; memop; signed; size; offset; datasize] -> + `AArch64LoadLiteral ( translate_out_regzr (translate_out_reg_size datasize) t, + translate_out_memOp memop, + translate_out_bool signed, + translate_out_int size, + translate_out_signed_big_bit offset, + translate_out_data_size datasize) + +| "LoadRegister",[n; t; m; acctype; memop; signed; wback; postindex; extend_type; shift; regsize; datasize] -> + let regsize' = translate_out_reg_size regsize in + let extend_type' = translate_out_extendType extend_type in + `AArch64LoadRegister (translate_out_regsp Set64 n, + translate_out_regzr regsize' t, + translate_out_regzrbyext Set64 extend_type' m, + translate_out_accType acctype, + translate_out_memOp memop, + translate_out_bool signed, + translate_out_bool wback, + translate_out_bool postindex, + extend_type', + translate_out_int shift, + translate_out_reg_size regsize , + translate_out_data_size datasize) + +| "MultiplyAddSub", [d; n; m; a; destsize; datasize; sub_op] -> + let destsize' = translate_out_reg_size destsize in + `AArch64MultiplyAddSub (translate_out_regzr destsize' d, + translate_out_regzr destsize' n, + translate_out_regzr destsize' m, + translate_out_regzr destsize' a, + destsize', + translate_out_data_size datasize, + translate_out_bool sub_op) + +| "MoveWide", [d; datasize; imm; pos; opcode] -> + let datasize' = translate_out_reg_size datasize in + `AArch64MoveWide (translate_out_regzr datasize' d, + datasize', + translate_out_bits imm, + translate_out_int pos, + translate_out_moveWideOp opcode) + +| "Reverse", [d; n; datasize; op] -> + let datasize' = translate_out_reg_size datasize in + `AArch64Reverse ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + datasize', + translate_out_revOp op) + +| "Division", [d; n; m; datasize; unsigned] -> + let datasize' = translate_out_reg_size datasize in + `AArch64Division (translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool unsigned) + +| "MultiplyAddSubLong", [d; n; m; a; destsize; datasize; sub_op; unsigned] -> + `AArch64MultiplyAddSubLong (translate_out_regzr Set64 d, + translate_out_regzr Set32 n, + translate_out_regzr Set32 m, + translate_out_regzr Set64 a, + translate_out_reg_size destsize, + translate_out_data_size datasize, + translate_out_bool sub_op, + translate_out_bool unsigned) + +| "MultiplyHigh", [d; n; m; a; destsize; datasize; unsigned] -> + `AArch64MultiplyHigh (translate_out_regzr Set64 d, + translate_out_regzr Set64 n, + translate_out_regzr Set64 m, + translate_out_regzr Set64 a, + translate_out_reg_size destsize, + translate_out_data_size datasize, + translate_out_bool unsigned) + +| "TestBitAndBranch", [t; datasize; bit_pos; bit_val; offset] -> + let datasize' = translate_out_reg_size datasize in + `AArch64TestBitAndBranch (translate_out_regzr datasize' t, + datasize', + translate_out_int bit_pos, + translate_out_bool bit_val, + translate_out_signed_big_bit offset) + +| "MoveSystemRegister", [t; sys_op0; sys_op1; sys_op2; sys_crn; sys_crm; read] -> + `AArch64MoveSystemRegister (translate_out_regzr Set64 t, + translate_out_int sys_op0, + translate_out_int sys_op1, + translate_out_int sys_op2, + translate_out_int sys_crn, + translate_out_int sys_crm, + translate_out_bool read) + +| "MoveSystemImmediate", [operand; field] -> + `AArch64MoveSystemImmediate ( translate_out_int operand, + translate_out_pSTATEField field) diff --git a/arm/gen/shallow_ast_to_herdtools_ast.hgen b/arm/gen/shallow_ast_to_herdtools_ast.hgen new file mode 100644 index 00000000..aa989e95 --- /dev/null +++ b/arm/gen/shallow_ast_to_herdtools_ast.hgen @@ -0,0 +1,326 @@ +| TMStart t -> + `AArch64TMStart (translate_out_regzr Set64 t) + +| TMCommit -> `AArch64TMCommit + +| TMAbort (retry, reason) -> + `AArch64TMAbort ( translate_out_bool retry, + translate_out_bits reason) + +| TMTest -> `AArch64TMTest + +| ImplementationDefinedStopFetching -> + `AArch64ImplementationDefinedStopFetching + +| ImplementationDefinedThreadStart -> + `AArch64ImplementationDefinedThreadStart + +| ImplementationDefinedTestBeginEnd (isEnd) -> + `AArch64ImplementationDefinedTestBeginEnd (translate_out_bool isEnd) + +| AddSubCarry (d, n, m, datasize, sub_op, setflags) -> + let datasize' = translate_out_reg_size datasize in + `AArch64AddSubCarry ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool sub_op, + translate_out_bool setflags) + +| AddSubExtendRegister (d, n, m, datasize, sub_op, setflags, extend_type, shift) -> + let setflags' = translate_out_bool setflags in + let datasize' = translate_out_reg_size datasize in + let extend_type' = translate_out_extendType extend_type in + `AArch64AddSubExtendRegister ((if setflags' then translate_out_regzr datasize' d else translate_out_regsp datasize' d), + translate_out_regsp datasize' n, + translate_out_regzrbyext datasize' extend_type' m, + datasize', + translate_out_bool sub_op, + setflags', + extend_type', + translate_out_int shift) + +| AddSubShiftedRegister (d, n, m, datasize, sub_op, setflags, shift_type, shift_amount) -> + let datasize' = translate_out_reg_size datasize in + `AArch64AddSubShiftedRegister ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool sub_op, + translate_out_bool setflags, + translate_out_shiftType shift_type, + translate_out_int shift_amount) + +| AddSubImmediate (d, n, datasize, sub_op, setflags, imm) -> + let setflags' = translate_out_bool setflags in + let datasize' = translate_out_reg_size datasize in + `AArch64AddSubImmediate ( (if setflags' then translate_out_regzr datasize' d else translate_out_regsp datasize' d), + translate_out_regsp datasize' n, + datasize', + translate_out_bool sub_op, + setflags', + translate_out_reg_size_bits imm) + +| Address0 (d, page, imm) -> + `AArch64Address ( translate_out_regzr Set64 d, + translate_out_bool page, + translate_out_big_bit imm) + +| LogicalImmediate (d, n, datasize, setflags, op, imm) -> + let setflags' = translate_out_bool setflags in + let datasize' = translate_out_reg_size datasize in + `AArch64LogicalImmediate ((if setflags' then translate_out_regzr datasize' d else translate_out_regsp datasize' d), + translate_out_regzr datasize' n, + datasize', + setflags', + translate_out_logicalOp op, + translate_out_reg_size_bits imm) + +| LogicalShiftedRegister (d, n, m, datasize, setflags, op, shift_type, shift_amount, invert) -> + let datasize' = translate_out_reg_size datasize in + `AArch64LogicalShiftedRegister (translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool setflags, + translate_out_logicalOp op, + translate_out_shiftType shift_type, + translate_out_int shift_amount, + translate_out_bool invert) + +| Shift (d, n, m, datasize, shift_type) -> + let datasize' = translate_out_reg_size datasize in + `AArch64Shift ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_shiftType shift_type) + +| BranchConditional (offset, condition) -> + `AArch64BranchConditional ( translate_out_signed_big_bit offset, + translate_out_bits condition) + +| BranchImmediate (branch_type, offset) -> + `AArch64BranchImmediate ( translate_out_branchType branch_type, + translate_out_signed_big_bit offset) + +| BitfieldMove (d, n, datasize, inzero, extend, _R, _S, wmask, tmask) -> + let datasize' = translate_out_reg_size datasize in + `AArch64BitfieldMove (translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + datasize', + translate_out_bool inzero, + translate_out_bool extend, + translate_out_int _R, + translate_out_int _S, + translate_out_reg_size_bits wmask, + translate_out_reg_size_bits wmask) + +| BranchRegister (n, branch_type) -> + `AArch64BranchRegister (translate_out_regzr Set64 n, + translate_out_branchType branch_type) + +| CompareAndBranch (t, datasize, iszero, offset) -> + let datasize' = translate_out_reg_size datasize in + `AArch64CompareAndBranch (translate_out_regzr datasize' t, + datasize', + translate_out_bool iszero, + translate_out_signed_big_bit offset) + +| ConditionalCompareImmediate (n, datasize, sub_op, condition, flags, imm) -> + let datasize' = translate_out_reg_size datasize in + `AArch64ConditionalCompareImmediate ( translate_out_regzr datasize' n, + datasize', + translate_out_bool sub_op, + translate_out_bits condition, + translate_out_bits flags, + translate_out_reg_size_bits imm) + +| ConditionalCompareRegister (n, m, datasize, sub_op, condition, flags) -> + let datasize' = translate_out_reg_size datasize in + `AArch64ConditionalCompareRegister (translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool sub_op, + translate_out_bits condition, + translate_out_bits flags) + +| ClearExclusiveMonitor (imm) -> `AArch64ClearExclusiveMonitor (translate_out_int imm) + +| CountLeading (d, n, datasize, opcode) -> + let datasize' = translate_out_reg_size datasize in + `AArch64CountLeading (translate_out_regzr datasize' d, + translate_out_regzr datasize' d, + datasize', + translate_out_countOp opcode) + +| CRC (d, n, m, size, crc32c) -> + let size' = translate_out_data_size size in + `AArch64CRC ( translate_out_regzr Set32 d, + translate_out_regzr Set32 n, + translate_out_regzr (if size' = DataSize64 then Set64 else Set32) m, + size', + translate_out_bool crc32c) + +| ConditionalSelect (d, n, m, datasize, condition, else_inf, else_inc) -> + let datasize' = translate_out_reg_size datasize in + `AArch64ConditionalSelect ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bits condition, + translate_out_bool else_inf, + translate_out_bool else_inc) + +| Barrier2 (op, domain, types) -> + `AArch64Barrier ( translate_out_memBarrierOp op, + translate_out_mBReqDomain domain, + translate_out_mBReqTypes types) + +| ExtractRegister (d, n, m, datasize, lsb) -> + let datasize' = translate_out_reg_size datasize in + `AArch64ExtractRegister ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_int lsb) + +| Hint (op) -> `AArch64Hint (translate_out_systemHintOp op) + +| LoadStoreAcqExc (n, t, t2, s, acctype, excl, pair, memop, elsize, regsize, datasize) -> + let regsize' = translate_out_reg_size regsize in + `AArch64LoadStoreAcqExc ( translate_out_regsp Set64 n, + translate_out_regzr regsize' t, + translate_out_regzr regsize' t2, + translate_out_regzr Set32 s, + translate_out_accType acctype, + translate_out_bool excl, + translate_out_bool pair, + translate_out_memOp memop, + translate_out_int elsize, + regsize', + translate_out_data_size datasize) + +| LoadStorePair(wback, postindex, n, t, t2, acctype, memop, signed, datasize, offset) -> + let signed' = translate_out_bool signed in + let regsize = if signed' then Set64 else translate_out_reg_size datasize in + `AArch64LoadStorePair ( translate_out_bool wback, + translate_out_bool postindex, + translate_out_regsp Set64 n, + translate_out_regzr regsize t, + translate_out_regzr regsize t2, + translate_out_accType acctype, + translate_out_memOp memop, + signed', + translate_out_data_size datasize, + translate_out_signed_big_bit offset) + +| LoadImmediate(n, t, acctype, memop, signed, wback, postindex, offset, regsize, datasize) -> + let regsize' = translate_out_reg_size regsize in + `AArch64LoadImmediate ( translate_out_regsp Set64 n, + translate_out_regzr regsize' t, + translate_out_accType acctype, + translate_out_memOp memop, + translate_out_bool signed, + translate_out_bool wback, + translate_out_bool postindex, + translate_out_signed_big_bit offset, + translate_out_reg_size regsize, + translate_out_data_size datasize) + +| LoadLiteral(t, memop, signed, size, offset, datasize) -> + `AArch64LoadLiteral ( translate_out_regzr (translate_out_reg_size datasize) t, + translate_out_memOp memop, + translate_out_bool signed, + translate_out_int size, + translate_out_signed_big_bit offset, + translate_out_data_size datasize) + +| LoadRegister(n, t, m, acctype, memop, signed, wback, postindex, extend_type, shift, regsize, datasize) -> + let regsize' = translate_out_reg_size regsize in + let extend_type' = translate_out_extendType extend_type in + `AArch64LoadRegister (translate_out_regsp Set64 n, + translate_out_regzr regsize' t, + translate_out_regzrbyext Set64 extend_type' m, + translate_out_accType acctype, + translate_out_memOp memop, + translate_out_bool signed, + translate_out_bool wback, + translate_out_bool postindex, + extend_type', + translate_out_int shift, + translate_out_reg_size regsize , + translate_out_data_size datasize) + +| MultiplyAddSub (d, n, m, a, destsize, datasize, sub_op) -> + let destsize' = translate_out_reg_size destsize in + `AArch64MultiplyAddSub (translate_out_regzr destsize' d, + translate_out_regzr destsize' n, + translate_out_regzr destsize' m, + translate_out_regzr destsize' a, + destsize', + translate_out_data_size datasize, + translate_out_bool sub_op) + +| MoveWide (d, datasize, imm, pos, opcode) -> + let datasize' = translate_out_reg_size datasize in + `AArch64MoveWide (translate_out_regzr datasize' d, + datasize', + translate_out_bits imm, + translate_out_int pos, + translate_out_moveWideOp opcode) + +| Reverse (d, n, datasize, op) -> + let datasize' = translate_out_reg_size datasize in + `AArch64Reverse ( translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + datasize', + translate_out_revOp op) + +| Division (d, n, m, datasize, unsigned) -> + let datasize' = translate_out_reg_size datasize in + `AArch64Division (translate_out_regzr datasize' d, + translate_out_regzr datasize' n, + translate_out_regzr datasize' m, + datasize', + translate_out_bool unsigned) + +| MultiplyAddSubLong (d, n, m, a, destsize, datasize, sub_op, unsigned) -> + `AArch64MultiplyAddSubLong (translate_out_regzr Set64 d, + translate_out_regzr Set32 n, + translate_out_regzr Set32 m, + translate_out_regzr Set64 a, + translate_out_reg_size destsize, + translate_out_data_size datasize, + translate_out_bool sub_op, + translate_out_bool unsigned) + +| MultiplyHigh (d, n, m, a, destsize, datasize, unsigned) -> + `AArch64MultiplyHigh (translate_out_regzr Set64 d, + translate_out_regzr Set64 n, + translate_out_regzr Set64 m, + translate_out_regzr Set64 a, + translate_out_reg_size destsize, + translate_out_data_size datasize, + translate_out_bool unsigned) + +| TestBitAndBranch (t, datasize, bit_pos, bit_val, offset) -> + let datasize' = translate_out_reg_size datasize in + `AArch64TestBitAndBranch (translate_out_regzr datasize' t, + datasize', + translate_out_int bit_pos, + translate_out_bool bit_val, + translate_out_signed_big_bit offset) + +| MoveSystemRegister (t, sys_op0, sys_op1, sys_op2, sys_crn, sys_crm, read) -> + `AArch64MoveSystemRegister (translate_out_regzr Set64 t, + translate_out_int sys_op0, + translate_out_int sys_op1, + translate_out_int sys_op2, + translate_out_int sys_crn, + translate_out_int sys_crm, + translate_out_bool read) + +| MoveSystemImmediate (operand, field) -> + `AArch64MoveSystemImmediate ( translate_out_bits operand, + translate_out_pSTATEField field) diff --git a/arm/gen/shallow_types_to_herdtools_types.hgen b/arm/gen/shallow_types_to_herdtools_types.hgen new file mode 100644 index 00000000..771f52ac --- /dev/null +++ b/arm/gen/shallow_types_to_herdtools_types.hgen @@ -0,0 +1,154 @@ +let translate_out_big_int_bits x = Sail_values.unsigned x + +let translate_out_big_bit = Sail_values.unsigned + +let translate_out_signed_big_bit = Sail_values.signed + +let translate_out_int inst = (Nat_big_num.to_int inst) + +let translate_out_bits bits = Nat_big_num.to_int (Sail_values.unsigned bits) + +let translate_out_bool = function + | Sail_values.B1 -> true + | Sail_values.B0 -> false + | Sail_values.BU -> failwith "translate_out_bool Undef" + +let translate_out_enum (name,_,bits) = + Nat_big_num.to_int (IInt.integer_of_bit_list bits) + +let translate_out_reg_size inst = + match translate_out_int inst with + | 32 -> Set32 + | 64 -> Set64 + | _ -> assert false + +let translate_out_regzr regsize reg = + begin match (regsize, translate_out_int reg) with + | (Set32, 31) -> W ZR + | (Set32, reg) -> W (Ireg (ireg_of_int reg)) + | (Set64, 31) -> X ZR + | (Set64, reg) -> X (Ireg (ireg_of_int reg)) + end + +let translate_out_regsp regsize reg = + begin match (regsize, translate_out_int reg) with + | (Set32, 31) -> W SP + | (Set32, reg) -> W (Ireg (ireg_of_int reg)) + | (Set64, 31) -> X SP + | (Set64, reg) -> X (Ireg (ireg_of_int reg)) + end + +let translate_out_regzrbyext regsize extend_type reg = begin match extend_type with + | ExtendType_UXTX | ExtendType_SXTX -> translate_out_regzr regsize reg + | _ -> translate_out_regzr Set32 reg + end + +let translate_out_reg_size_bits bits = + match Nat_big_num.to_int (Sail_values.length bits) with + | 32 -> R32Bits (translate_out_bits bits) + | 64 -> R64Bits (translate_out_big_bit bits) + | _ -> assert false + +let translate_out_data_size inst = + match (translate_out_int inst) with + | 8 -> DataSize8 + | 16 -> DataSize16 + | 32 -> DataSize32 + | 64 -> DataSize64 + | _ -> assert false + +let translate_out_extendType = function + | ArmV8_embed_types.ExtendType_UXTB -> ExtendType_UXTB + | ArmV8_embed_types.ExtendType_UXTH -> ExtendType_UXTH + | ArmV8_embed_types.ExtendType_UXTW -> ExtendType_UXTW + | ArmV8_embed_types.ExtendType_UXTX -> ExtendType_UXTX + | ArmV8_embed_types.ExtendType_SXTB -> ExtendType_SXTB + | ArmV8_embed_types.ExtendType_SXTH -> ExtendType_SXTH + | ArmV8_embed_types.ExtendType_SXTW -> ExtendType_SXTW + | ArmV8_embed_types.ExtendType_SXTX -> ExtendType_SXTX + +let translate_out_shiftType = function + | ArmV8_embed_types.ShiftType_LSL -> ShiftType_LSL + | ArmV8_embed_types.ShiftType_LSR -> ShiftType_LSR + | ArmV8_embed_types.ShiftType_ASR -> ShiftType_ASR + | ArmV8_embed_types.ShiftType_ROR -> ShiftType_ROR + +let translate_out_logicalOp = function + | ArmV8_embed_types.LogicalOp_AND -> LogicalOp_AND + | ArmV8_embed_types.LogicalOp_EOR -> LogicalOp_EOR + | ArmV8_embed_types.LogicalOp_ORR -> LogicalOp_ORR + +let translate_out_branchType = function + | ArmV8_embed_types.BranchType_CALL -> BranchType_CALL + | ArmV8_embed_types.BranchType_ERET -> BranchType_ERET + | ArmV8_embed_types.BranchType_DBGEXIT -> BranchType_DBGEXIT + | ArmV8_embed_types.BranchType_RET -> BranchType_RET + | ArmV8_embed_types.BranchType_JMP -> BranchType_JMP + | ArmV8_embed_types.BranchType_EXCEPTION -> BranchType_EXCEPTION + | ArmV8_embed_types.BranchType_UNKNOWN -> BranchType_UNKNOWN + +let translate_out_countOp = function + | ArmV8_embed_types.CountOp_CLZ -> CountOp_CLZ + | ArmV8_embed_types.CountOp_CLS -> CountOp_CLS + | ArmV8_embed_types.CountOp_CNT -> CountOp_CNT + +let translate_out_memBarrierOp = function + | ArmV8_embed_types.MemBarrierOp_DSB -> MemBarrierOp_DSB + | ArmV8_embed_types.MemBarrierOp_DMB -> MemBarrierOp_DMB + | ArmV8_embed_types.MemBarrierOp_ISB -> MemBarrierOp_ISB + +let translate_out_mBReqDomain = function + | ArmV8_embed_types.MBReqDomain_Nonshareable -> MBReqDomain_Nonshareable + | ArmV8_embed_types.MBReqDomain_InnerShareable -> MBReqDomain_InnerShareable + | ArmV8_embed_types.MBReqDomain_OuterShareable -> MBReqDomain_OuterShareable + | ArmV8_embed_types.MBReqDomain_FullSystem -> MBReqDomain_FullSystem + +let translate_out_mBReqTypes = function + | ArmV8_embed_types.MBReqTypes_Reads -> MBReqTypes_Reads + | ArmV8_embed_types.MBReqTypes_Writes -> MBReqTypes_Writes + | ArmV8_embed_types.MBReqTypes_All -> MBReqTypes_All + +let translate_out_systemHintOp = function + | ArmV8_embed_types.SystemHintOp_NOP -> SystemHintOp_NOP + | ArmV8_embed_types.SystemHintOp_YIELD -> SystemHintOp_YIELD + | ArmV8_embed_types.SystemHintOp_WFE -> SystemHintOp_WFE + | ArmV8_embed_types.SystemHintOp_WFI -> SystemHintOp_WFI + | ArmV8_embed_types.SystemHintOp_SEV -> SystemHintOp_SEV + | ArmV8_embed_types.SystemHintOp_SEVL -> SystemHintOp_SEVL + +let translate_out_accType = function + | ArmV8_embed_types.AccType_NORMAL -> AccType_NORMAL + | ArmV8_embed_types.AccType_VEC -> AccType_VEC + | ArmV8_embed_types.AccType_STREAM -> AccType_STREAM + | ArmV8_embed_types.AccType_VECSTREAM -> AccType_VECSTREAM + | ArmV8_embed_types.AccType_ATOMIC -> AccType_ATOMIC + | ArmV8_embed_types.AccType_ORDERED -> AccType_ORDERED + | ArmV8_embed_types.AccType_UNPRIV -> AccType_UNPRIV + | ArmV8_embed_types.AccType_IFETCH -> AccType_IFETCH + | ArmV8_embed_types.AccType_PTW -> AccType_PTW + | ArmV8_embed_types.AccType_DC -> AccType_DC + | ArmV8_embed_types.AccType_IC -> AccType_IC + | ArmV8_embed_types.AccType_AT -> AccType_AT + +let translate_out_memOp = function + | ArmV8_embed_types.MemOp_LOAD -> MemOp_LOAD + | ArmV8_embed_types.MemOp_STORE -> MemOp_STORE + | ArmV8_embed_types.MemOp_PREFETCH -> MemOp_PREFETCH + + +let translate_out_moveWideOp = function + | ArmV8_embed_types.MoveWideOp_N -> MoveWideOp_N + | ArmV8_embed_types.MoveWideOp_Z -> MoveWideOp_Z + | ArmV8_embed_types.MoveWideOp_K -> MoveWideOp_K + +let translate_out_revOp = function + | ArmV8_embed_types.RevOp_RBIT -> RevOp_RBIT + | ArmV8_embed_types.RevOp_REV16 -> RevOp_REV16 + | ArmV8_embed_types.RevOp_REV32 -> RevOp_REV32 + | ArmV8_embed_types.RevOp_REV64 -> RevOp_REV64 + +let translate_out_pSTATEField = function + | ArmV8_embed_types.PSTATEField_DAIFSet -> PSTATEField_DAIFSet + | ArmV8_embed_types.PSTATEField_DAIFClr -> PSTATEField_DAIFClr + | ArmV8_embed_types.PSTATEField_SP -> PSTATEField_SP + diff --git a/arm/gen/token_types.hgen b/arm/gen/token_types.hgen new file mode 100644 index 00000000..411dddf9 --- /dev/null +++ b/arm/gen/token_types.hgen @@ -0,0 +1,85 @@ +(*** instructions ***) + +type token_TSTART = {txt : string} +type token_TCOMMIT = {txt : string} +type token_TABORT = {txt : string} +type token_TTEST = {txt : string} + +type token_ADCSBC = {txt : string; sub_op : boolean; setflags : boolean} +type token_ADDSUB = {txt : string; sub_op : boolean; setflags : boolean} +type token_ADR = {txt : string; page : boolean} +type token_LOGOP = {txt : string; op : logicalOp; setflags : boolean; invert : boolean} +type token_SHIFTOP = {txt : string; shift_type : shiftType} +type token_BCOND = {txt : string; condition : int} +type token_B = {txt : string; branch_type : branchType} +type token_BR = {txt : string; branch_type : branchType} +type token_CBZ = {txt : string; iszero : boolean} +type token_BFM = {txt : string; inzero : boolean; extend : boolean} +type token_CCM = {txt : string; sub_op : boolean} +type token_CM = {txt : string; sub_op : boolean} +type token_CL = {txt : string; opcode : countOp} +type token_CRC = {txt : string; size : data_size; crc32c : boolean} +type token_CRC32X = {txt : string; crc32c : boolean} +type token_CSEL = {txt : string; else_inv : boolean; else_inc : boolean} +type token_CSET = {txt : string; else_inv : boolean; else_inc : boolean} +type token_CSETM = {txt : string; else_inv : boolean; else_inc : boolean} +type token_CON = {txt : string; else_inv : boolean; else_inc : boolean} +type token_MEMBARR = {txt : string; op : memBarrierOp} +type token_LDAXR_var32 = {elsize : int; datasize : data_size} +type token_LDAXR = {txt : string; acctype : accType; excl : boolean; memop : memOp; var32 : token_LDAXR_var32; var64 : boolean} +type token_STLXR_var32 = {elsize : int; datasize : data_size} +type token_STLXR = {txt : string; acctype : accType; var32 : token_STLXR_var32; var64 : boolean} +type token_LDXP = {txt : string; acctype : accType} +type token_STXP = {txt : string; acctype : accType} +type token_LDSTR_var32 = {datasize : data_size} +type token_LDSTR_var64 = {datasize : data_size} +type token_LDSTR_lit64 = {datasize : data_size; size : int} +type token_LDSTR = {txt : string; memop : memOp; signed : boolean; lit32 : boolean; var32 : token_LDSTR_var32 option; var64 : token_LDSTR_var64 option; lit64 : token_LDSTR_lit64 option} +type token_LDSTTUR_off32 = {datasize : data_size} +type token_LDSTTUR_off64 = {datasize : data_size} +type token_LDSTTUR = {txt : string; memop : memOp; acctype : accType; signed : boolean; off32 : token_LDSTTUR_off32 option; off64 : token_LDSTTUR_off64 option} +type token_MADDSUB = {txt : string; sub_op : boolean} +type token_MUL = {txt : string; sub_op : boolean} +type token_MOVWIDE = {txt : string; opcode : moveWideOp} +type token_NEG = {txt : string; setflags : boolean} +type token_NGC = {txt : string; setflags : boolean} +type token_REV = {txt : string; op32 : revOp option; op64 : revOp} +type token_DIV = {txt : string; unsigned : boolean} +type token_MADDSUBL = {txt : string; sub_op : boolean; unsigned : boolean} +type token_MULH = {txt : string; unsigned : boolean} +type token_MULL = {txt : string; unsigned : boolean} +type token_LDSTP = {txt : string; memop : memOp} +type token_TBZ = {txt : string; bit_val : bit} +type token_BFIZ = {txt : string; extend : boolean} +type token_BFX = {txt : string; extend : boolean} +type token_MNEGL = {txt : string; unsigned : boolean} +type token_BFI = {txt : string} +type token_BFXIL = {txt : string} +type token_CLREX = {txt : string} +type token_EXTR = {txt : string} +type token_HINT = {txt : string} +type token_ISB = {txt : string} +type token_LDPSW = {txt : string} +type token_MOV = {txt : string} +type token_MVN = {txt : string} +type token_NOP = {txt : string} +type token_PRFM = {txt : string} +type token_PRFUM = {txt : string} +type token_RET = {txt : string} +type token_TST = {txt : string} +type token_MRS = {txt : string} +type token_MSR = {txt : string} + +(*** instructions/operands ***) + +type token_SHIFT = {txt : string; shift_type : shiftType} +type token_EXTEND_inst = {extend : boolean; imms : int} +type token_EXTEND = {txt : string; _type : extendType; inst : token_EXTEND_inst option} + +(*** operands: ***) + +type token_COND = int +type token_BARROP = {domain : mBReqDomain; types : mBReqTypes} +type token_PRFOP = inst_reg (* this is an int that is encoded in a reg field *) +type token_SYSREG = {sys_op0 : uinteger; sys_op1 : uinteger; sys_op2 : uinteger; sys_crn : uinteger; sys_crm : uinteger} +type token_PSTATEFIELD = pSTATEField diff --git a/arm/gen/tokens.hgen b/arm/gen/tokens.hgen new file mode 100644 index 00000000..bf49e463 --- /dev/null +++ b/arm/gen/tokens.hgen @@ -0,0 +1,78 @@ +/*** instructions ***/ + +%token <AArch64HGenBase.token_TSTART> TSTART +%token <AArch64HGenBase.token_TCOMMIT> TCOMMIT +%token <AArch64HGenBase.token_TABORT> TABORT +%token <AArch64HGenBase.token_TTEST> TTEST + +%token <AArch64HGenBase.token_ADCSBC> ADCSBC +%token <AArch64HGenBase.token_ADDSUB> ADDSUB +%token <AArch64HGenBase.token_ADR> ADR +%token <AArch64HGenBase.token_LOGOP> LOGOP +%token <AArch64HGenBase.token_SHIFTOP> SHIFTOP +%token <AArch64HGenBase.token_BCOND> BCOND +%token <AArch64HGenBase.token_B> B +%token <AArch64HGenBase.token_BR> BR +%token <AArch64HGenBase.token_CBZ> CBZ +%token <AArch64HGenBase.token_BFM> BFM +%token <AArch64HGenBase.token_CCM> CCM +%token <AArch64HGenBase.token_CM> CM +%token <AArch64HGenBase.token_CL> CL +%token <AArch64HGenBase.token_CRC> CRC +%token <AArch64HGenBase.token_CRC32X> CRC32X +%token <AArch64HGenBase.token_CSEL> CSEL +%token <AArch64HGenBase.token_CSET> CSET +%token <AArch64HGenBase.token_CSETM> CSETM +%token <AArch64HGenBase.token_CON> CON +%token <AArch64HGenBase.token_MEMBARR> MEMBARR +%token <AArch64HGenBase.token_LDAXR> LDAXR +%token <AArch64HGenBase.token_STLXR> STLXR +%token <AArch64HGenBase.token_LDXP> LDXP +%token <AArch64HGenBase.token_STXP> STXP +%token <AArch64HGenBase.token_LDSTR> LDSTR +%token <AArch64HGenBase.token_LDSTTUR> LDSTTUR +%token <AArch64HGenBase.token_MADDSUB> MADDSUB +%token <AArch64HGenBase.token_MUL> MUL +%token <AArch64HGenBase.token_MOVWIDE> MOVWIDE +%token <AArch64HGenBase.token_NEG> NEG +%token <AArch64HGenBase.token_NGC> NGC +%token <AArch64HGenBase.token_REV> REV +%token <AArch64HGenBase.token_DIV> DIV +%token <AArch64HGenBase.token_MADDSUBL> MADDSUBL +%token <AArch64HGenBase.token_MULH> MULH +%token <AArch64HGenBase.token_MULL> MULL +%token <AArch64HGenBase.token_LDSTP> LDSTP +%token <AArch64HGenBase.token_TBZ> TBZ +%token <AArch64HGenBase.token_BFIZ> BFIZ +%token <AArch64HGenBase.token_BFX> BFX +%token <AArch64HGenBase.token_MNEGL> MNEGL +%token <AArch64HGenBase.token_BFI> BFI +%token <AArch64HGenBase.token_BFXIL> BFXIL +%token <AArch64HGenBase.token_CLREX> CLREX +%token <AArch64HGenBase.token_EXTR> EXTR +%token <AArch64HGenBase.token_HINT> HINT +%token <AArch64HGenBase.token_ISB> ISB +%token <AArch64HGenBase.token_LDPSW> LDPSW +%token <AArch64HGenBase.token_MOV> MOV +%token <AArch64HGenBase.token_MVN> MVN +%token <AArch64HGenBase.token_NOP> NOP +%token <AArch64HGenBase.token_PRFM> PRFM +%token <AArch64HGenBase.token_PRFUM> PRFUM +%token <AArch64HGenBase.token_RET> RET +%token <AArch64HGenBase.token_TST> TST +%token <AArch64HGenBase.token_MRS> MRS +%token <AArch64HGenBase.token_MSR> MSR + +/*** instructions/operands ***/ + +%token <AArch64HGenBase.token_SHIFT> SHIFT +%token <AArch64HGenBase.token_EXTEND> EXTEND + +/*** operands: ***/ + +%token <AArch64HGenBase.token_COND> COND +%token <AArch64HGenBase.token_BARROP> BARROP +%token <AArch64HGenBase.token_PRFOP> PRFOP +%token <AArch64HGenBase.token_SYSREG> SYSREG +%token <AArch64HGenBase.token_PSTATEFIELD> PSTATEFIELD + diff --git a/arm/gen/trans_sail.hgen b/arm/gen/trans_sail.hgen new file mode 100644 index 00000000..2b176308 --- /dev/null +++ b/arm/gen/trans_sail.hgen @@ -0,0 +1,379 @@ +| `AArch64TMStart t -> + ("TMStart", [translate_reg "t" t], []) + +| `AArch64TMCommit -> ("TMCommit", [], []) + +| `AArch64TMAbort (retry,reason) -> + ("TMAbort", + [ translate_boolean "retry" retry; + translate_bit5 "reason" reason], + []) + +| `AArch64TMTest -> ("TMTest", [], []) + + +| `AArch64ImplementationDefinedStopFetching -> + ("ImplementationDefinedStopFetching", + [], + []) + +| `AArch64ImplementationDefinedThreadStart -> + ("ImplementationDefinedThreadStart", + [], + []) + +| `AArch64ImplementationDefinedTestBeginEnd(isEnd) -> + ("ImplementationDefinedTestBeginEnd", + [translate_boolean "isEnd" isEnd], + []) + +| `AArch64AddSubCarry(d,n,m,datasize,sub_op,setflags) -> + ("AddSubCarry", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg_size "datasize" datasize; + translate_boolean "sub_op" sub_op; + translate_boolean "setflags" setflags], + []) + +| `AArch64AddSubExtendRegister (d,n,m,datasize,sub_op,setflags,extend_type,shift) -> + ("AddSubExtendRegister", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg_size "datasize" datasize; + translate_boolean "sub_op" sub_op; + translate_boolean "setflags" setflags; + translate_extendType "extend_type" extend_type; + translate_range0_7 "shift" shift], + []) + +| `AArch64AddSubShiftedRegister (d,n,m,datasize,sub_op,setflags,shift_type,shift_amount) -> + ("AddSubShiftedRegister", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg_size "datasize" datasize; + translate_boolean "sub_op" sub_op; + translate_boolean "setflags" setflags; + translate_shiftType "shift_type" shift_type; + translate_range0_63 "shift_amount" shift_amount], + []) + +| `AArch64AddSubImmediate (d,n,datasize,sub_op,setflags,imm) -> + ("AddSubImmediate", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg_size "datasize" datasize; + translate_boolean "sub_op" sub_op; + translate_boolean "setflags" setflags; + translate_reg_size_bits "imm" imm], + []) + +| `AArch64Address (d,page,imm) -> + ("Address", + [translate_reg "d" d; + translate_boolean "page" page; + translate_bit64 "imm" imm], + []) + +| `AArch64LogicalImmediate (d,n,datasize,setflags,op,imm) -> + ("LogicalImmediate", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg_size "datasize" datasize; + translate_boolean "setflags" setflags; + translate_logicalOp "op" op; + translate_reg_size_bits "imm" imm], + []) + +| `AArch64LogicalShiftedRegister (d,n,m,datasize,setflags,op,shift_type,shift_amount,invert) -> + ("LogicalShiftedRegister", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg_size "datasize" datasize; + translate_boolean "setflags" setflags; + translate_logicalOp "op" op; + translate_shiftType "shift_type" shift_type; + translate_range0_63 "shift_amount" shift_amount; + translate_boolean "invert" invert], + []) + +| `AArch64Shift (d,n,m,datasize,shift_type) -> + ("Shift", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg_size "datasize" datasize; + translate_shiftType "shift_type" shift_type], + []) + +| `AArch64BranchConditional (offset,condition) -> + ("BranchConditional", + [translate_bit64 "offset" offset; + translate_bit4 "condition" condition], + []) + +| `AArch64BranchImmediate (branch_type,offset) -> + ("BranchImmediate", + [translate_branchType "branch_type" branch_type; + translate_bit64 "offset" offset], + []) + +| `AArch64BitfieldMove (d,n,datasize,inzero,extend,_R,_S,wmask,tmask) -> + ("BitfieldMove", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg_size "datasize" datasize; + translate_boolean "inzero" inzero; + translate_boolean "extend" extend; + translate_uinteger "_R" _R; + translate_uinteger "_S" _S; + translate_reg_size_bits "wmask" wmask; + translate_reg_size_bits "tmask" tmask], + []) + +| `AArch64BranchRegister (n,branch_type) -> + ("BranchRegister", + [translate_reg "n" n; + translate_branchType "branch_type" branch_type], + []) + +| `AArch64CompareAndBranch (t,datasize,iszero,offset) -> + ("CompareAndBranch", + [translate_reg "t" t; + translate_reg_size "datasize" datasize; + translate_boolean "iszero" iszero; + translate_bit64 "offset" offset], + []) + +| `AArch64ConditionalCompareImmediate (n,datasize,sub_op,condition,flags,imm) -> + ("ConditionalCompareImmediate", + [translate_reg "n" n; + translate_reg_size "datasize" datasize; + translate_boolean "sub_op" sub_op; + translate_bit4 "condition" condition; + translate_bit4 "flags" flags; + translate_reg_size_bits "imm" imm], + []) + +| `AArch64ConditionalCompareRegister (n,m,datasize,sub_op,condition,flags) -> + ("ConditionalCompareRegister", + [translate_reg "n" n; + translate_reg "m" m; + translate_reg_size "datasize" datasize; + translate_boolean "sub_op" sub_op; + translate_bit4 "condition" condition; + translate_bit4 "flags" flags], + []) + +| `AArch64ClearExclusiveMonitor (imm) -> + ("ClearExclusiveMonitor", + [translate_uinteger "imm" imm], + []) + +| `AArch64CountLeading (d,n,datasize,opcode) -> + ("CountLeading", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg_size "datasize" datasize; + translate_countOp "opcode" opcode], + []) + +| `AArch64CRC (d,n,m,size,crc32c) -> + ("CRC", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_data_size "size" size; + translate_boolean "crc32c" crc32c], + []) + +| `AArch64ConditionalSelect (d,n,m,datasize,condition,else_inv,else_inc) -> + ("ConditionalSelect", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg_size "datasize" datasize; + translate_bit4 "condition" condition; + translate_boolean "else_inv" else_inv; + translate_boolean "else_inc" else_inc], + []) + +| `AArch64Barrier (op,domain,types) -> + ("Barrier", + [translate_memBarrierOp "op" op; + translate_mBReqDomain "domain" domain; + translate_mBReqTypes "types" types], + []) + +| `AArch64ExtractRegister (d,n,m,datasize,lsb) -> + ("ExtractRegister", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg_size "datasize" datasize; + translate_uinteger "lsb" lsb], + []) + +| `AArch64Hint (op) -> + ("Hint", + [translate_systemHintOp "op" op], + []) + +| `AArch64LoadStoreAcqExc (n,t,t2,s,acctype,excl,pair,memop,elsize,regsize,datasize) -> + ("LoadStoreAcqExc", + [translate_reg "n" n; + translate_reg "t" t; + translate_reg "t2" t2; + translate_reg "s" s; + translate_accType "acctype" acctype; + translate_boolean "excl" excl; + translate_boolean "pair" pair; + translate_memOp "memop" memop; + translate_uinteger "elsize" elsize; + translate_reg_size "regsize" regsize; + translate_data_size "datasize" datasize], + []) + +| `AArch64LoadStorePair (wback,postindex,n,t,t2,acctype,memop,signed,datasize,offset) -> + ("LoadStorePair", + [translate_boolean "wback" wback; + translate_boolean "postindex" postindex; + translate_reg "n" n; + translate_reg "t" t; + translate_reg "t2" t2; + translate_accType "acctype" acctype; + translate_memOp "memop" memop; + translate_boolean "signed" signed; + translate_data_size "datasize" datasize; + translate_bit64 "offset" offset], + []) + +| `AArch64LoadImmediate (n,t,acctype,memop,signed,wback,postindex,offset,regsize,datasize) -> + ("LoadImmediate", + [translate_reg "n" n; + translate_reg "t" t; + translate_accType "acctype" acctype; + translate_memOp "memop" memop; + translate_boolean "signed" signed; + translate_boolean "wback" wback; + translate_boolean "postindex" postindex; + translate_bit64 "offset" offset; + translate_reg_size "regsize" regsize; + translate_data_size "datasize" datasize], + []) + +| `AArch64LoadLiteral (t,memop,signed,size,offset,datasize) -> + ("LoadLiteral", + [translate_reg "t" t; + translate_memOp "memop" memop; + translate_boolean "signed" signed; + translate_uinteger "size" size; + translate_bit64 "offset" offset; + translate_data_size "datasize" datasize;], + []) + +| `AArch64LoadRegister (n,t,m,acctype,memop,signed,wback,postindex,extend_type,shift,regsize,datasize) -> + ("LoadRegister", + [translate_reg "n" n; + translate_reg "t" t; + translate_reg "m" m; + translate_accType "acctype" acctype; + translate_memOp "memop" memop; + translate_boolean "signed" signed; + translate_boolean "wback" wback; + translate_boolean "postindex" postindex; + translate_extendType "extend_type" extend_type; + translate_uinteger "shift" shift; + translate_reg_size "regsize" regsize; + translate_data_size "datasize" datasize], + []) + +| `AArch64MultiplyAddSub (d,n,m,a,destsize,datasize,sub_op) -> + ("MultiplyAddSub", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg "a" a; + translate_reg_size "destsize" destsize; + translate_data_size "datasize" datasize; + translate_boolean "sub_op" sub_op], + []) + +| `AArch64MoveWide (d,datasize,imm,pos,opcode) -> + ("MoveWide", + [translate_reg "d" d; + translate_reg_size "datasize" datasize; + translate_bit16 "imm" imm; + translate_uinteger "pos" pos; + translate_moveWideOp "opcode" opcode], + []) + +| `AArch64Reverse (d,n,datasize,op) -> + ("Reverse", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg_size "datasize" datasize; + translate_revOp "op" op], + []) + +| `AArch64Division (d,n,m,datasize,unsigned) -> + ("Division", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg_size "datasize" datasize; + translate_boolean "unsigned" unsigned], + []) + +| `AArch64MultiplyAddSubLong (d,n,m,a,destsize,datasize,sub_op,unsigned) -> + ("MultiplyAddSubLong", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg "a" a; + translate_reg_size "destsize" destsize; + translate_data_size "datasize" datasize; + translate_boolean "sub_op" sub_op; + translate_boolean "unsigned" unsigned], + []) + +| `AArch64MultiplyHigh (d,n,m,a,destsize,datasize,unsigned) -> + ("MultiplyHigh", + [translate_reg "d" d; + translate_reg "n" n; + translate_reg "m" m; + translate_reg "a" a; + translate_reg_size "destsize" destsize; + translate_data_size "datasize" datasize; + translate_boolean "unsigned" unsigned], + []) + +| `AArch64TestBitAndBranch (t,datasize,bit_pos,bit_val,offset) -> + ("TestBitAndBranch", + [translate_reg "t" t; + translate_reg_size "datasize" datasize; + translate_uinteger "bit_pos" bit_pos; + translate_bit "bit_val" bit_val; + translate_bit64 "offset" offset], + []) + +| `AArch64MoveSystemRegister (t,sys_op0,sys_op1,sys_op2,sys_crn,sys_crm,read) -> + ("MoveSystemRegister", + [translate_reg "t" t; + translate_uinteger "sys_op0" sys_op0; + translate_uinteger "sys_op1" sys_op1; + translate_uinteger "sys_op2" sys_op2; + translate_uinteger "sys_crn" sys_crn; + translate_uinteger "sys_crm" sys_crm; + translate_boolean "read" read], + []) + +| `AArch64MoveSystemImmediate (operand,field) -> + ("MoveSystemImmediate", + [translate_bit4 "operand" operand; + translate_pSTATEField "field" field], + []) diff --git a/arm/gen/types.hgen b/arm/gen/types.hgen new file mode 100644 index 00000000..d581a233 --- /dev/null +++ b/arm/gen/types.hgen @@ -0,0 +1,90 @@ +type reg_size = Set64 | Set32 + +type reg_size_bits = R32Bits of int | R64Bits of Nat_big_num.num +let reg_size_bits_R32_of_int value = R32Bits value +let reg_size_bits_R64_of_int value = R64Bits (Nat_big_num.of_int value) +let reg_size_bits_R32_of_big_int value = R32Bits (Nat_big_num.to_int value) +let reg_size_bits_R64_of_big_int value = R64Bits value +let eq_reg_size_bits = function + | (R32Bits lhs, R32Bits rhs) -> lhs = rhs + | (R64Bits lhs, R64Bits rhs) -> Nat_big_num.equal lhs rhs + | (R32Bits _, R64Bits _) -> false + | (R64Bits _, R32Bits _) -> false +let reg_size_bits_iskbituimm k value = + match value with + | R32Bits value -> iskbituimm k value + | R64Bits value -> big_iskbituimm k value +let reg_size_bits_shift_right value n = + match value with + | R32Bits value -> R32Bits (value lsr n) + | R64Bits value -> R64Bits (Nat_big_num.shift_right value n) +let reg_size_bits_to_int value = + match value with + | R32Bits value -> value + | R64Bits value -> Nat_big_num.to_int value + +type data_size = DataSize64 | DataSize32 | DataSize16 | DataSize8 + +type reg_index = int + +type boolean = bool + +type range0_7 = int + +type range0_63 = int + +type bit64 = Nat_big_num.num +let bit64_of_int = Nat_big_num.of_int +let bit64_to_int = Nat_big_num.to_int +let eq_bit64 = Nat_big_num.equal + +type bit4 = int + +type bit5 = int + +type bit16 = int + +type bit = bool + +type range8_64 = int + +type uinteger = int + +type extendType = ExtendType_SXTB | ExtendType_SXTH | ExtendType_SXTW | ExtendType_SXTX | + ExtendType_UXTB | ExtendType_UXTH | ExtendType_UXTW | ExtendType_UXTX + + +type shiftType = ShiftType_LSL | ShiftType_LSR | ShiftType_ASR | ShiftType_ROR + +type logicalOp = LogicalOp_AND | LogicalOp_EOR | LogicalOp_ORR + +type branchType = BranchType_CALL | BranchType_ERET | BranchType_DBGEXIT | + BranchType_RET | BranchType_JMP | BranchType_EXCEPTION | + BranchType_UNKNOWN + +type countOp = CountOp_CLZ | CountOp_CLS | CountOp_CNT + +type memBarrierOp = MemBarrierOp_DSB | MemBarrierOp_DMB | MemBarrierOp_ISB + +type mBReqDomain = MBReqDomain_Nonshareable | MBReqDomain_InnerShareable | + MBReqDomain_OuterShareable | MBReqDomain_FullSystem + +type mBReqTypes = MBReqTypes_Reads | MBReqTypes_Writes | MBReqTypes_All + +type systemHintOp = SystemHintOp_NOP | SystemHintOp_YIELD | + SystemHintOp_WFE | SystemHintOp_WFI | + SystemHintOp_SEV | SystemHintOp_SEVL + +type accType = AccType_NORMAL | AccType_VEC | AccType_STREAM | + AccType_VECSTREAM | AccType_ATOMIC | AccType_ORDERED | + AccType_UNPRIV | AccType_IFETCH | AccType_PTW | + AccType_DC | AccType_IC | AccType_AT + +type memOp = MemOp_LOAD | MemOp_STORE | MemOp_PREFETCH + +type moveWideOp = MoveWideOp_N | MoveWideOp_Z | MoveWideOp_K + +type revOp = RevOp_RBIT | RevOp_REV16 | RevOp_REV32 | RevOp_REV64 + +type pSTATEField = PSTATEField_DAIFSet | PSTATEField_DAIFClr | + PSTATEField_SP diff --git a/arm/gen/types_sail_trans_out.hgen b/arm/gen/types_sail_trans_out.hgen new file mode 100644 index 00000000..082a5464 --- /dev/null +++ b/arm/gen/types_sail_trans_out.hgen @@ -0,0 +1,189 @@ +let translate_out_big_int_bits = function + | (name, Range0 _, bits) -> IInt.integer_of_bit_list bits + | _ -> assert false + +let translate_out_big_bit = function + | (name, Bvector _, bits) -> IInt.integer_of_bit_list bits + | _ -> assert false + +let translate_out_signed_big_bit = function + | (name, Bvector _, bits) -> IInt.signed_integer_of_bit_list bits + | _ -> assert false + +let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_int_bits inst)) + +let translate_out_bits = function + | (name, Bvector _, bits) -> Nat_big_num.to_int (IInt.integer_of_bit_list bits) + | _ -> assert false + +let translate_out_bool = function + | (name, Bit, [Bitc_one]) -> true + | (name, Bit, [Bitc_zero]) -> false + | _ -> assert false + +let translate_out_enum (name,_,bits) = + Nat_big_num.to_int (IInt.integer_of_bit_list bits) + +let translate_out_reg_size inst = + match translate_out_int inst with + | 32 -> Set32 + | 64 -> Set64 + | _ -> assert false + +let translate_out_regzr regsize reg = + begin match (regsize, translate_out_int reg) with + | (Set32, 31) -> W ZR + | (Set32, reg) -> W (Ireg (ireg_of_int reg)) + | (Set64, 31) -> X ZR + | (Set64, reg) -> X (Ireg (ireg_of_int reg)) + end + +let translate_out_regsp regsize reg = + begin match (regsize, translate_out_int reg) with + | (Set32, 31) -> W SP + | (Set32, reg) -> W (Ireg (ireg_of_int reg)) + | (Set64, 31) -> X SP + | (Set64, reg) -> X (Ireg (ireg_of_int reg)) + end + +let translate_out_regzrbyext regsize extend_type reg = + begin match extend_type with + | ExtendType_UXTX | ExtendType_SXTX -> translate_out_regzr regsize reg + | _ -> translate_out_regzr Set32 reg + end + +let translate_out_reg_size_bits ((name,_,bits) as inst) = + match List.length bits with + | 32 -> R32Bits (translate_out_bits inst) + | 64 -> R64Bits (translate_out_big_bit inst) + | _ -> assert false + +let translate_out_data_size inst = + match (translate_out_int inst) with + | 8 -> DataSize8 + | 16 -> DataSize16 + | 32 -> DataSize32 + | 64 -> DataSize64 + | _ -> assert false + +let translate_out_extendType inst = + match translate_out_enum inst with + | 0 -> ExtendType_SXTB + | 1 -> ExtendType_SXTH + | 2 -> ExtendType_SXTW + | 3 -> ExtendType_SXTX + | 4 -> ExtendType_UXTB + | 5 -> ExtendType_UXTH + | 6 -> ExtendType_UXTW + | 7 -> ExtendType_UXTX + | _ -> assert false + +let translate_out_shiftType inst = + match translate_out_enum inst with + | 0 -> ShiftType_LSL + | 1 -> ShiftType_LSR + | 2 -> ShiftType_ASR + | 3 -> ShiftType_ROR + | _ -> assert false + +let translate_out_logicalOp inst = + match translate_out_enum inst with + | 0 -> LogicalOp_AND + | 1 -> LogicalOp_EOR + | 2 -> LogicalOp_ORR + | _ -> assert false + +let translate_out_branchType inst = + match translate_out_enum inst with + | 0 -> BranchType_CALL + | 1 -> BranchType_ERET + | 2 -> BranchType_DBGEXIT + | 3 -> BranchType_RET + | 4 -> BranchType_JMP + | 5 -> BranchType_EXCEPTION + | 6 -> BranchType_UNKNOWN + | _ -> assert false + +let translate_out_countOp inst = + match translate_out_enum inst with + | 0 -> CountOp_CLZ + | 1 -> CountOp_CLS + | 2 -> CountOp_CNT + | _ -> assert false + +let translate_out_memBarrierOp inst = + match translate_out_enum inst with + | 0 -> MemBarrierOp_DSB + | 1 -> MemBarrierOp_DMB + | 2 -> MemBarrierOp_ISB + | _ -> assert false + +let translate_out_mBReqDomain inst = + match translate_out_enum inst with + | 0 -> MBReqDomain_Nonshareable + | 1 -> MBReqDomain_InnerShareable + | 2 -> MBReqDomain_OuterShareable + | 3 -> MBReqDomain_FullSystem + | _ -> assert false + +let translate_out_mBReqTypes inst = + match translate_out_enum inst with + | 0 -> MBReqTypes_Reads + | 1 -> MBReqTypes_Writes + | 2 -> MBReqTypes_All + | _ -> assert false + +let translate_out_systemHintOp inst = + match translate_out_enum inst with + | 0 -> SystemHintOp_NOP + | 1 -> SystemHintOp_YIELD + | 2 -> SystemHintOp_WFE + | 3 -> SystemHintOp_WFI + | 4 -> SystemHintOp_SEV + | 5 -> SystemHintOp_SEVL + | _ -> assert false + +let translate_out_accType inst = + match translate_out_enum inst with + | 0 -> AccType_NORMAL + | 1 -> AccType_VEC + | 2 -> AccType_STREAM + | 3 -> AccType_VECSTREAM + | 4 -> AccType_ATOMIC + | 5 -> AccType_ORDERED + | 6 -> AccType_UNPRIV + | 7 -> AccType_IFETCH + | 8 -> AccType_PTW + | 9 -> AccType_DC + | 10 -> AccType_IC + | 11 -> AccType_AT + | _ -> assert false + +let translate_out_memOp inst = + match translate_out_enum inst with + | 0 -> MemOp_LOAD + | 1 -> MemOp_STORE + | 2 -> MemOp_PREFETCH + | _ -> assert false + +let translate_out_moveWideOp inst = + match translate_out_enum inst with + | 0 -> MoveWideOp_N + | 1 -> MoveWideOp_Z + | 2 -> MoveWideOp_K + | _ -> assert false + +let translate_out_revOp inst = + match translate_out_enum inst with + | 0 -> RevOp_RBIT + | 1 -> RevOp_REV16 + | 2 -> RevOp_REV32 + | 3 -> RevOp_REV64 + | _ -> assert false + +let translate_out_pSTATEField inst = + match translate_out_enum inst with + | 0 -> PSTATEField_DAIFSet + | 1 -> PSTATEField_DAIFClr + | 2 -> PSTATEField_SP + | _ -> assert false diff --git a/arm/gen/types_trans_sail.hgen b/arm/gen/types_trans_sail.hgen new file mode 100644 index 00000000..7f2d5fe7 --- /dev/null +++ b/arm/gen/types_trans_sail.hgen @@ -0,0 +1,119 @@ +let translate_big_int bits (name : string) value = + (name, Range0 (Some bits), IInt.bit_list_of_integer bits value) + +let translate_big_bit bits (name:string) value = + (name, Bvector (Some bits), IInt.bit_list_of_integer bits value) + +let translate_int bits name value = + translate_big_int bits name (Nat_big_num.of_int value) + +let translate_bits bits (name:string) value = + (name, Bvector (Some bits), IInt.bit_list_of_integer bits (Nat_big_num.of_int value)) + +let translate_bool name value = + (name, Bit, [if value then Bitc_one else Bitc_zero]) + +let translate_enum enum_values (name: string) value = + let rec bit_count n = + if n = 0 then 0 + else 1 + (bit_count (n lsr 1)) in + let rec find_index element = function + | h::tail -> if h = element then 0 else 1 + (find_index element tail) + | _ -> failwith "translate_enum could not find value" + in + let size = bit_count (List.length enum_values) in + let index = find_index value enum_values in + (name, Range0 (Some size), IInt.bit_list_of_integer size (Nat_big_num.of_int index)) + +(* the following are tightly coupled with types.hgen. As it is not relevant + to herdtools I put it here and not in types.hgen *) + +let translate_reg_size name value = + match value with + | Set32 -> (name, Range0 (Some 7), IInt.bit_list_of_integer 7 (Nat_big_num.of_int 32)) + | Set64 -> (name, Range0 (Some 7), IInt.bit_list_of_integer 7 (Nat_big_num.of_int 64)) + +let translate_reg name value = + (name, Range0 (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int (inst_reg_to_int value))) + +let translate_reg_size_bits name value = + match value with + | R32Bits value -> translate_bits 32 name value + | R64Bits value -> translate_big_bit 64 name value + +let translate_data_size name value = + match value with + | DataSize8 -> (name, Range0 (Some 7), IInt.bit_list_of_integer 7 (Nat_big_num.of_int 8)) + | DataSize16 -> (name, Range0 (Some 7), IInt.bit_list_of_integer 7 (Nat_big_num.of_int 16)) + | DataSize32 -> (name, Range0 (Some 7), IInt.bit_list_of_integer 7 (Nat_big_num.of_int 32)) + | DataSize64 -> (name, Range0 (Some 7), IInt.bit_list_of_integer 7 (Nat_big_num.of_int 64)) + +let translate_reg_index = translate_int 5 + +let translate_boolean = translate_bool + +let translate_range0_7 = translate_int 3 + +let translate_range0_63 = translate_int 6 + +let translate_bit64 = translate_big_bit 64 + +let translate_bit4 = translate_bits 4 +let translate_bit5 = translate_bits 5 +let translate_bit16 = translate_bits 16 + +let translate_bit = translate_bool + +let translate_range8_64 = translate_int 7 + +let translate_uinteger = translate_int 63 + +let translate_extendType = + translate_enum [ExtendType_SXTB; ExtendType_SXTH; ExtendType_SXTW; ExtendType_SXTX; + ExtendType_UXTB; ExtendType_UXTH; ExtendType_UXTW; ExtendType_UXTX] + +let translate_shiftType = + translate_enum [ShiftType_LSL; ShiftType_LSR; ShiftType_ASR; ShiftType_ROR] + +let translate_logicalOp = + translate_enum [LogicalOp_AND; LogicalOp_EOR; LogicalOp_ORR] + +let translate_branchType = + translate_enum [BranchType_CALL; BranchType_ERET; BranchType_DBGEXIT; + BranchType_RET; BranchType_JMP; BranchType_EXCEPTION; + BranchType_UNKNOWN] + +let translate_countOp = + translate_enum [CountOp_CLZ;CountOp_CLS;CountOp_CNT] + +let translate_memBarrierOp= + translate_enum [MemBarrierOp_DSB; MemBarrierOp_DMB; MemBarrierOp_ISB] + +let translate_mBReqDomain = + translate_enum [MBReqDomain_Nonshareable; MBReqDomain_InnerShareable; + MBReqDomain_OuterShareable; MBReqDomain_FullSystem] + +let translate_mBReqTypes = + translate_enum [MBReqTypes_Reads; MBReqTypes_Writes; MBReqTypes_All] + +let translate_systemHintOp = + translate_enum [SystemHintOp_NOP; SystemHintOp_YIELD; SystemHintOp_WFE; + SystemHintOp_WFI; SystemHintOp_SEV; SystemHintOp_SEVL] + +let translate_accType = + translate_enum [AccType_NORMAL; AccType_VEC; AccType_STREAM; + AccType_VECSTREAM; AccType_ATOMIC; AccType_ORDERED; + AccType_UNPRIV; AccType_IFETCH; AccType_PTW; + AccType_DC; AccType_IC; AccType_AT] + +let translate_memOp = + translate_enum [MemOp_LOAD; MemOp_STORE; MemOp_PREFETCH] + +let translate_moveWideOp = + translate_enum [MoveWideOp_N; MoveWideOp_Z; MoveWideOp_K] + +let translate_revOp = + translate_enum [RevOp_RBIT; RevOp_REV16; RevOp_REV32; RevOp_REV64] + +let translate_pSTATEField = + translate_enum [PSTATEField_DAIFSet; PSTATEField_DAIFClr; PSTATEField_SP] diff --git a/cheri/cheri_insts.sail b/cheri/cheri_insts.sail index 101414f8..3c1e34bb 100644 --- a/cheri/cheri_insts.sail +++ b/cheri/cheri_insts.sail @@ -32,6 +32,159 @@ (* SUCH DAMAGE. *) (*========================================================================*) +(* Old encodings *) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b000) = Some(CGetPerm(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b001) = Some(CGetType(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b010) = Some(CGetBase(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b011) = Some(CGetLen(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b101) = Some(CGetTag(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b110) = Some(CGetSealed(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : 0b00000 : 0b00000000 : 0b100) = Some(CGetCause(rd)) + +function clause decode (0b010010 : 0b00110 : 0b000000000000000000000) = Some(CReturn) + +function clause decode (0b010010 : 0b01101 : (regno) rd : (regno) cb : 0b00000000 : 0b010) = Some(CGetOffset(rd, cb)) (* NB encoding does not follow pattern *) +function clause decode (0b010010 : 0b00100 : 0b00000 : 0b00000 : (regno) rt : 0b000 : 0b100) = Some(CSetCause(rt)) +function clause decode (0b010010 : 0b00100 : (regno) cd : (regno) cb : (regno) rt : 0b000 : 0b000) = Some(CAndPerm(cd, cb, rt)) +function clause decode (0b010010 : 0b01100 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b000) = Some(CToPtr(rd, cb, ct)) + +function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b000) = Some(CPtrCmp(rd, cb, ct, CEQ)) +function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b001) = Some(CPtrCmp(rd, cb, ct, CNE)) +function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b010) = Some(CPtrCmp(rd, cb, ct, CLT)) +function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b011) = Some(CPtrCmp(rd, cb, ct, CLE)) +function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b100) = Some(CPtrCmp(rd, cb, ct, CLTU)) +function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b101) = Some(CPtrCmp(rd, cb, ct, CLEU)) +function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b110) = Some(CPtrCmp(rd, cb, ct, CEXEQ)) +function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b111) = Some(CPtrCmp(rd, cb, ct, CNEXEQ)) +function clause decode (0b010010 : 0b01101 : (regno) cd : (regno) cb : (regno) rt : 0b000 : 0b000) = Some(CIncOffset(cd, cb, rt)) +function clause decode (0b010010 : 0b01101 : (regno) cd : (regno) cb : (regno) rt : 0b000 : 0b001) = Some(CSetOffset(cd, cb, rt)) +function clause decode (0b010010 : 0b00001 : (regno) cd : (regno) cb : (regno) rt : 0b000000) = Some(CSetBounds(cd, cb, rt)) + +function clause decode (0b010010 : 0b00100 : (regno) cd : (regno) cb : 0b00000 : 0b000: 0b101) = Some(CClearTag(cd, cb)) +function clause decode (0b010010 : 0b00100 : (regno) cd : (regno) cb : (regno) rt : 0b000: 0b111) = Some(CFromPtr(cd, cb, rt)) +function clause decode (0b010010 : 0b01011 : (regno) cs : 0b00000 : (regno) rt : 0b000: 0b000) = Some(CCheckPerm(cs, rt)) +function clause decode (0b010010 : 0b01011 : (regno) cs : (regno) cb : 0b00000 : 0b000: 0b001) = Some(CCheckType(cs, cb)) +function clause decode (0b010010 : 0b00010 : (regno) cd : (regno) cs : (regno) ct : 0b000: 0b000) = Some(CSeal(cd, cs, ct)) +function clause decode (0b010010 : 0b00011 : (regno) cd : (regno) cs : (regno) ct : 0b000: 0b000) = Some(CUnseal(cd, cs, ct)) +function clause decode (0b010010 : 0b00111 : (regno) cd : (regno) cb : 0b00000 : 0b000000) = Some(CJALR(cd, cb, true)) (* CJALR *) +function clause decode (0b010010 : 0b01000 : 0b00000 : (regno) cb : 0b00000 : 0b000000) = Some(CJALR(0b00000, cb, false)) (* CJR *) + + +(* +New encodings as per CHERI ISA Appendix B.2. + +NB: Must be careful about order of matching because unused register +fields are re-used as additional function codes. +*) + +(* One arg *) +function clause decode (0b010010 : 0b00000 : (regno) rd : 0b00001 : 0b11111 : 0b111111) = Some(CGetCause(rd)) +function clause decode (0b010010 : 0b00000 : (regno) rs : 0b00010 : 0b11111 : 0b111111) = Some(CSetCause(rs)) +function clause decode (0b010010 : 0b00000 : (regno) cd : 0b00000 : 0b11111 : 0b111111) = Some(CGetPCC(cd)) +function clause decode (0b010010 : 0b00000 : (regno) cb : 0b00011 : 0b11111 : 0b111111) = Some(CJALR(0b00000, cb, false)) (* CJR *) + +(* Two arg *) +function clause decode (0b010010 : 0b00000 : (regno) cs : (regno) rt : 0b01000 : 0b111111) = Some(CCheckPerm(cs, rt)) +function clause decode (0b010010 : 0b00000 : (regno) cs : (regno) cb : 0b01001 : 0b111111) = Some(CCheckType(cs, cb)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : 0b01011 : 0b111111) = Some(CClearTag(cd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : 0b01010 : 0b111111) = Some(CMOVX(cd, cs, 0b00000, false)) (* CMOVE *) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : 0b01100 : 0b111111) = Some(CJALR(cd, cb, true)) (* CJALR *) + +(* Capability Inspection *) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000 : 0b111111) = Some(CGetPerm(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00001 : 0b111111) = Some(CGetType(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00010 : 0b111111) = Some(CGetBase(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00011 : 0b111111) = Some(CGetLen(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00100 : 0b111111) = Some(CGetTag(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00101 : 0b111111) = Some(CGetSealed(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00110 : 0b111111) = Some(CGetOffset(rd, cb)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) rs : 0b00111 : 0b111111) = Some(CGetPCCSetOffset(cd, rs)) + +(* Three operand *) + +(* Capability Modification *) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) ct : 0b001011) = Some(CSeal(cd, cs, ct)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) ct : 0b001100) = Some(CUnseal(cd, cs, ct)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) rt : 0b001101) = Some(CAndPerm(cd, cs, rt)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) rt : 0b001111) = Some(CSetOffset(cd, cs, rt)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) rt : 0b001000) = Some(CSetBounds(cd, cs, rt)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) rt : 0b001001) = Some(CSetBoundsExact(cd, cs, rt)) + + +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : (regno) rt : 0b010001) = Some(CIncOffset(cd, cb, rt)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : (regno) ct : 0b011101) = Some(CBuildCap(cd, cb, ct)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : (regno) ct : 0b011110) = Some(CCopyType(cd, cb, ct)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) ct : 0b011111) = Some(CCSeal(cd, cs, ct)) + +(* Pointer Arithmetic *) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) ct : 0b010010) = Some(CToPtr(rd, cb, ct)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : (regno) rs : 0b010011) = Some(CFromPtr(cd, cb, rs)) +function clause decode (0b010010 : 0b00000 : (regno) rt : (regno) cb : (regno) cs : 0b001010) = Some(CSub(rt, cb, cs)) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) rs : 0b011011) = Some(CMOVX(cd, cs, rs, false)) (* CMOVZ *) +function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) rs : 0b011100) = Some(CMOVX(cd, cs, rs, true)) (* CMOVN *) + +(* Pointer Comparison *) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) cs : 0b010100) = Some(CPtrCmp(rd, cb, cs, CEQ)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) cs : 0b010101) = Some(CPtrCmp(rd, cb, cs, CNE)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) cs : 0b010110) = Some(CPtrCmp(rd, cb, cs, CLT)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) cs : 0b010111) = Some(CPtrCmp(rd, cb, cs, CLE)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) cs : 0b011000) = Some(CPtrCmp(rd, cb, cs, CLTU)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) cs : 0b011001) = Some(CPtrCmp(rd, cb, cs, CLEU)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) cs : 0b011010) = Some(CPtrCmp(rd, cb, cs, CEXEQ)) +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) cs : 0b100001) = Some(CPtrCmp(rd, cb, cs, CNEXEQ)) + +function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) ct : 0b100000) = Some(CTestSubset(rd, cb, ct)) + +function clause decode (0b010010 : 0b01001 : (regno) cd : (bit[16]) imm) = Some(CBX(cd, imm, true)) (* CBTU *) +function clause decode (0b010010 : 0b01010 : (regno) cd : (bit[16]) imm) = Some(CBX(cd, imm, false)) (* CBTS *) +function clause decode (0b010010 : 0b10001 : (regno) cd : (bit[16]) imm) = Some(CBZ(cd, imm, false)) (* CBEZ *) +function clause decode (0b010010 : 0b10010 : (regno) cd : (bit[16]) imm) = Some(CBZ(cd, imm, true)) (* CBNZ *) + +function clause decode (0b010010 : 0b00101 : 0b00000 : 0b00000 : 0b11111111111) = Some(CReturn) +function clause decode (0b010010 : 0b00101 : (regno) cs : (regno) cb : (bit[11]) selector) = Some(CCall(cs, cb, selector)) + +function clause decode (0b010010 : 0b01111 : 0b00000 : (bit[16]) imm) = Some(ClearRegs(GPLo, imm)) +function clause decode (0b010010 : 0b01111 : 0b00001 : (bit[16]) imm) = Some(ClearRegs(GPHi, imm)) +function clause decode (0b010010 : 0b01111 : 0b00010 : (bit[16]) imm) = Some(ClearRegs(CLo, imm)) +function clause decode (0b010010 : 0b01111 : 0b00011 : (bit[16]) imm) = Some(ClearRegs(CHi, imm)) + +function clause decode (0b010010 : 0b10011 : (regno) cd : (regno) cb : (bit[11]) imm) = Some(CIncOffsetImmediate(cd, cb, imm)) +function clause decode (0b010010 : 0b10100 : (regno) cd : (regno) cb : (bit[11]) imm) = Some(CSetBoundsImmediate(cd, cb, imm)) + +function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b00) = Some(CLoad(rd, cb, rt, offset, false, B, false)) (* CLBU *) +function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b1 : 0b00) = Some(CLoad(rd, cb, rt, offset, true, B, false)) (* CLB *) +function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b01) = Some(CLoad(rd, cb, rt, offset, false, H, false)) (* CLHU *) +function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b1 : 0b01) = Some(CLoad(rd, cb, rt, offset, true, H, false)) (* CLH *) +function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b10) = Some(CLoad(rd, cb, rt, offset, false, W, false)) (* CLWU *) +function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b1 : 0b10) = Some(CLoad(rd, cb, rt, offset, true, W, false)) (* CLW *) +function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b11) = Some(CLoad(rd, cb, rt, offset, false, D, false)) (* CLD *) + +function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b0 : 0b00) = Some(CLoad(rd, cb, 0b00000, 0b00000000, false, B, true)) (* CLLBU *) +function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b1 : 0b00) = Some(CLoad(rd, cb, 0b00000, 0b00000000, true, B, true)) (* CLLB *) +function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b0 : 0b01) = Some(CLoad(rd, cb, 0b00000, 0b00000000, false, H, true)) (* CLLHU *) +function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b1 : 0b01) = Some(CLoad(rd, cb, 0b00000, 0b00000000, true, H, true)) (* CLLH *) +function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b0 : 0b10) = Some(CLoad(rd, cb, 0b00000, 0b00000000, false, W, true)) (* CLLWU *) +function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b1 : 0b10) = Some(CLoad(rd, cb, 0b00000, 0b00000000, true, W, true)) (* CLLW *) +function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b0 : 0b11) = Some(CLoad(rd, cb, 0b00000, 0b00000000, false, D, true)) (* CLLD *) + +function clause decode (0b111010 : (regno) rs : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b00) = Some(CStore(rs, cb, rt, 0b00000, offset, B, false)) (* CSB *) +function clause decode (0b111010 : (regno) rs : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b01) = Some(CStore(rs, cb, rt, 0b00000, offset, H, false)) (* CSH *) +function clause decode (0b111010 : (regno) rs : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b10) = Some(CStore(rs, cb, rt, 0b00000, offset, W, false)) (* CSW *) +function clause decode (0b111010 : (regno) rs : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b11) = Some(CStore(rs, cb, rt, 0b00000, offset, D, false)) (* CSD *) + +function clause decode (0b010010 : 0b10000 : (regno) rs : (regno) cb : (regno) rd : 0b0000 : 0b00) = Some(CStore(rs, cb, 0b00000, rd, 0b00000000, B, true)) (* CSCB *) +function clause decode (0b010010 : 0b10000 : (regno) rs : (regno) cb : (regno) rd : 0b0000 : 0b01) = Some(CStore(rs, cb, 0b00000, rd, 0b00000000, H, true)) (* CSCH *) +function clause decode (0b010010 : 0b10000 : (regno) rs : (regno) cb : (regno) rd : 0b0000 : 0b10) = Some(CStore(rs, cb, 0b00000, rd, 0b00000000, W, true)) (* CSCW *) +function clause decode (0b010010 : 0b10000 : (regno) rs : (regno) cb : (regno) rd : 0b0000 : 0b11) = Some(CStore(rs, cb, 0b00000, rd, 0b00000000, D, true)) (* CSCD *) + +function clause decode (0b111110 : (regno) cs : (regno) cb: (regno) rt : (bit[11]) offset) = Some(CSC(cs, cb, rt, 0b00000, offset, false)) +function clause decode (0b010010 : 0b10000 : (regno) cs : (regno) cb: (regno) rd : 0b00 : 0b0111) = Some(CSC(cs, cb, 0b00000, rd, 0b00000000000, true)) + +function clause decode (0b110110 : (regno) cd : (regno) cb: (regno) rt : (bit[11]) offset) = Some(CLC(cd, cb, rt, offset, false)) +function clause decode (0b010010 : 0b10000 : (regno) cd : (regno) cb: 0b0000000 : 0b1111) = Some(CLC(cd, cb, 0b00000, 0b00000000000, true)) + +function clause decode (0b010010 : 0b00100 : (regno) rt : 0x0006) = Some(C2Dump(rt)) + (* Operations that extract parts of a capability into GPR *) union ast member (regno, regno) CGetPerm @@ -42,15 +195,6 @@ union ast member (regno, regno) CGetTag union ast member (regno, regno) CGetSealed union ast member (regno, regno) CGetOffset -function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b000) = Some(CGetPerm(rd, cb)) -function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b001) = Some(CGetType(rd, cb)) -function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b010) = Some(CGetBase(rd, cb)) -function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b011) = Some(CGetLen(rd, cb)) -(* NB CGetCause Handled separately *) -function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b101) = Some(CGetTag(rd, cb)) -function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : 0b00000000 : 0b110) = Some(CGetSealed(rd, cb)) -function clause decode (0b010010 : 0b01101 : (regno) rd : (regno) cb : 0b00000000 : 0b010) = Some(CGetOffset(rd, cb)) (* NB encoding does not follow pattern *) - function clause execute (CGetPerm(rd, cb)) = { (* START_CGetPerms *) @@ -141,7 +285,6 @@ function clause execute (CGetSealed(rd, cb)) = } union ast member regno CGetPCC -function clause decode (0b010010 : 0b00000 : (regno) cd : 0b00000 : 0b11111 : 0b111111) = Some(CGetPCC(cd)) function clause execute (CGetPCC(cd)) = { (* START_CGetPCC *) @@ -158,7 +301,6 @@ function clause execute (CGetPCC(cd)) = union ast member (regno, regno) CGetPCCSetOffset -function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) rs : 0b00111 : 0b111111) = Some(CGetPCCSetOffset(cd, rs)) function clause execute (CGetPCCSetOffset(cd, rs)) = { (* START_CGetPCCSetOffset *) @@ -178,7 +320,6 @@ function clause execute (CGetPCCSetOffset(cd, rs)) = (* Get and Set CP2 cause register *) union ast member regno CGetCause -function clause decode (0b010010 : 0b00000 : (regno) rd : 0b00000 : 0b00000000 : 0b100) = Some(CGetCause(rd)) function clause execute (CGetCause(rd)) = { (* START_CGetCause *) @@ -191,7 +332,6 @@ function clause execute (CGetCause(rd)) = } union ast member (regno) CSetCause -function clause decode (0b010010 : 0b00100 : 0b00000 : 0b00000 : (regno) rt : 0b000 : 0b100) = Some(CSetCause(rt)) function clause execute (CSetCause((regno) rt)) = { (* START_CSetCause *) @@ -208,7 +348,6 @@ function clause execute (CSetCause((regno) rt)) = } union ast member regregreg CAndPerm -function clause decode (0b010010 : 0b00100 : (regno) cd : (regno) cb : (regno) rt : 0b000 : 0b000) = Some(CAndPerm(cd, cb, rt)) function clause execute(CAndPerm(cd, cb, rt)) = { (* START_CAndPerm *) @@ -233,7 +372,6 @@ function clause execute(CAndPerm(cd, cb, rt)) = union ast member regregreg CToPtr -function clause decode (0b010010 : 0b01100 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b000) = Some(CToPtr(rd, cb, ct)) function clause execute(CToPtr(rd, cb, ct)) = { (* START_CToPtr *) @@ -267,7 +405,6 @@ function clause execute(CToPtr(rd, cb, ct)) = union ast member regregreg CSub -function clause decode (0b010010 : 0b00000 : (regno) rd : (regno) cb : (regno) ct : 0b001010) = Some(CSub(rd, cb, ct)) function clause execute(CSub(rd, cb, ct)) = { (* START_CSub *) @@ -286,15 +423,6 @@ function clause execute(CSub(rd, cb, ct)) = } union ast member (regno, regno, regno, CPtrCmpOp) CPtrCmp -function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b000) = Some(CPtrCmp(rd, cb, ct, CEQ)) -function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b001) = Some(CPtrCmp(rd, cb, ct, CNE)) -function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b010) = Some(CPtrCmp(rd, cb, ct, CLT)) -function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b011) = Some(CPtrCmp(rd, cb, ct, CLE)) -function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b100) = Some(CPtrCmp(rd, cb, ct, CLTU)) -function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b101) = Some(CPtrCmp(rd, cb, ct, CLEU)) -function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b110) = Some(CPtrCmp(rd, cb, ct, CEXEQ)) -function clause decode (0b010010 : 0b01110 : (regno) rd : (regno) cb : (regno) ct : 0b000 : 0b111) = Some(CPtrCmp(rd, cb, ct, CNEXEQ)) - function clause execute(CPtrCmp(rd, cb, ct, op)) = { (* START_CPtrCmp *) @@ -341,7 +469,6 @@ function clause execute(CPtrCmp(rd, cb, ct, op)) = } union ast member regregreg CIncOffset -function clause decode (0b010010 : 0b01101 : (regno) cd : (regno) cb : (regno) rt : 0b000 : 0b000) = Some(CIncOffset(cd, cb, rt)) function clause execute (CIncOffset(cd, cb, rt)) = { (* START_CIncOffset *) @@ -363,8 +490,29 @@ function clause execute (CIncOffset(cd, cb, rt)) = (* END_CIncOffset *) } +union ast member (regno, regno, bit[11]) CIncOffsetImmediate +function clause execute (CIncOffsetImmediate(cd, cb, imm)) = +{ + (* START_CIncOffsetImmediate *) + checkCP2usable(); + cb_val := readCapReg(cb); + let (bit[64]) imm64 = EXTZ(imm) in + if (register_inaccessible(cd)) then + raise_c2_exception(CapEx_AccessSystemRegsViolation, cd) + else if (register_inaccessible(cb)) then + raise_c2_exception(CapEx_AccessSystemRegsViolation, cb) + else if ((cb_val.tag) & (cb_val.sealed)) then + raise_c2_exception(CapEx_SealViolation, cb) + else + let (success, newCap) = incCapOffset(cb_val, imm64) in + if (success) then + writeCapReg(cd, newCap) + else + writeCapReg(cd, int_to_cap(getCapBase(cb_val) + imm64)) + (* END_CIncOffsetImmediate *) +} + union ast member regregreg CSetOffset -function clause decode (0b010010 : 0b01101 : (regno) cd : (regno) cb : (regno) rt : 0b000 : 0b001) = Some(CSetOffset(cd, cb, rt)) function clause execute (CSetOffset(cd, cb, rt)) = { (* START_CSetOffset *) @@ -387,7 +535,6 @@ function clause execute (CSetOffset(cd, cb, rt)) = } union ast member regregreg CSetBounds -function clause decode (0b010010 : 0b00001 : (regno) cd : (regno) cb : (regno) rt : 0b000000) = Some(CSetBounds(cd, cb, rt)) function clause execute (CSetBounds(cd, cb, rt)) = { (* START_CSetBounds *) @@ -416,9 +563,36 @@ function clause execute (CSetBounds(cd, cb, rt)) = (* END_CSetBounds *) } +union ast member (regno, regno, bit[11]) CSetBoundsImmediate +function clause execute (CSetBoundsImmediate(cd, cb, imm)) = +{ + (* START_CSetBoundsImmedate *) + checkCP2usable(); + cb_val := readCapReg(cb); + immU := unsigned(imm); + cursor := getCapCursor(cb_val); + base := getCapBase(cb_val); + top := getCapTop(cb_val); + newTop := cursor + immU; + if (register_inaccessible(cd)) then + raise_c2_exception(CapEx_AccessSystemRegsViolation, cd) + else if (register_inaccessible(cb)) then + raise_c2_exception(CapEx_AccessSystemRegsViolation, cb) + else if not (cb_val.tag) then + raise_c2_exception(CapEx_TagViolation, cb) + else if (cb_val.sealed) then + raise_c2_exception(CapEx_SealViolation, cb) + else if (cursor < base) then + raise_c2_exception(CapEx_LengthViolation, cb) + else if (newTop > top) then + raise_c2_exception(CapEx_LengthViolation, cb) + else + let (_, newCap) = setCapBounds(cb_val, (bit[64]) cursor, (bit[65]) newTop) in + writeCapReg(cd, newCap) (* ignore exact *) + (* END_CSetBoundsImmediate *) +} union ast member regregreg CSetBoundsExact -function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : (regno) rt : 0b001001) = Some(CSetBoundsExact(cd, cb, rt)) function clause execute (CSetBoundsExact(cd, cb, rt)) = { (* START_CSetBoundsExact *) @@ -451,7 +625,6 @@ function clause execute (CSetBoundsExact(cd, cb, rt)) = } union ast member (regno, regno) CClearTag -function clause decode (0b010010 : 0b00100 : (regno) cd : (regno) cb : 0b00000 : 0b000: 0b101) = Some(CClearTag(cd, cb)) function clause execute (CClearTag(cd, cb)) = { (* START_CClearTag *) @@ -469,9 +642,7 @@ function clause execute (CClearTag(cd, cb)) = } union ast member (regno,regno,regno,bool) CMOVX -function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : (regno) rt : 0b011100) = Some(CMOVX(cd, cb, rt, false)) (* CMOVN *) -function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : (regno) rt : 0b011011) = Some(CMOVX(cd, cb, rt, true)) (* CMOVZ *) -function clause execute (CMOVX(cd, cb, rt, ismovz)) = +function clause execute (CMOVX(cd, cb, rt, ismovn)) = { (* START_CMOVX *) checkCP2usable(); @@ -479,16 +650,12 @@ function clause execute (CMOVX(cd, cb, rt, ismovz)) = raise_c2_exception(CapEx_AccessSystemRegsViolation, cd) else if (register_inaccessible(cb)) then raise_c2_exception(CapEx_AccessSystemRegsViolation, cb) - else if ((rGPR(rt) == 0) ^ ismovz) then + else if ((rGPR(rt) == 0) ^ ismovn) then writeCapReg(cd) := readCapReg(cb); (* END_CMOVX *) } union ast member (ClearRegSet, bit[16]) ClearRegs -function clause decode (0b010010 : 0b01111 : 0b00000 : (bit[16]) imm) = Some(ClearRegs(GPLo, imm)) (* ClearLo *) -function clause decode (0b010010 : 0b01111 : 0b00001 : (bit[16]) imm) = Some(ClearRegs(GPHi, imm)) (* ClearHi *) -function clause decode (0b010010 : 0b01111 : 0b00010 : (bit[16]) imm) = Some(ClearRegs(CLo, imm)) (* CClearLo *) -function clause decode (0b010010 : 0b01111 : 0b00011 : (bit[16]) imm) = Some(ClearRegs(CHi, imm)) (* CClearHi *) function clause execute (ClearRegs(regset, mask)) = { (* START_ClearRegs *) @@ -511,7 +678,6 @@ function clause execute (ClearRegs(regset, mask)) = } union ast member regregreg CFromPtr -function clause decode (0b010010 : 0b00100 : (regno) cd : (regno) cb : (regno) rt : 0b000: 0b111) = Some(CFromPtr(cd, cb, rt)) function clause execute (CFromPtr(cd, cb, rt)) = { (* START_CFromPtr *) @@ -538,7 +704,6 @@ function clause execute (CFromPtr(cd, cb, rt)) = } union ast member regregreg CBuildCap -function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : (regno) ct : 0b011101) = Some(CBuildCap(cd, cb, ct)) function clause execute (CBuildCap(cd, cb, ct)) = { (* START_CBuildCap *) @@ -583,7 +748,6 @@ function clause execute (CBuildCap(cd, cb, ct)) = } union ast member regregreg CCopyType -function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cb : (regno) ct : 0b011110) = Some(CCopyType(cd, cb, ct)) function clause execute (CCopyType(cd, cb, ct)) = { (* START_CCopyType *) @@ -619,7 +783,6 @@ function clause execute (CCopyType(cd, cb, ct)) = } union ast member (regno, regno) CCheckPerm -function clause decode (0b010010 : 0b01011 : (regno) cs : 0b00000 : (regno) rt : 0b000: 0b000) = Some(CCheckPerm(cs, rt)) function clause execute (CCheckPerm(cs, rt)) = { (* START_CCheckPerm *) @@ -639,7 +802,6 @@ function clause execute (CCheckPerm(cs, rt)) = } union ast member (regno, regno) CCheckType -function clause decode (0b010010 : 0b01011 : (regno) cs : (regno) cb : 0b00000 : 0b000: 0b001) = Some(CCheckType(cs, cb)) function clause execute (CCheckType(cs, cb)) = { (* START_CCheckType *) @@ -665,8 +827,42 @@ function clause execute (CCheckType(cs, cb)) = (* END_CCheckType *) } +union ast member regregreg CTestSubset +function clause execute (CTestSubset(rd, cb, ct)) = +{ + (* START_CTestSubset *) + checkCP2usable(); + cb_val := readCapReg(cb); + ct_val := readCapReg(ct); + ct_top := getCapTop(ct_val); + ct_base := getCapBase(ct_val); + ct_perms := getCapPerms(ct_val); + cb_top := getCapTop(cb_val); + cb_base := getCapBase(cb_val); + cb_perms := getCapPerms(cb_val); + if (register_inaccessible(cb)) then + raise_c2_exception(CapEx_AccessSystemRegsViolation, cb) + else if (register_inaccessible(ct)) then + raise_c2_exception(CapEx_AccessSystemRegsViolation, ct) + else { + (bit[64]) result := EXTZ(if (cb_val.tag != ct_val.tag) then + 0x0 + else if (cb_val.sealed != ct_val.sealed) then + 0x0 + else if (ct_base < cb_base) then + 0x0 + else if (ct_top > cb_top) then + 0x0 + else if ((ct_perms & cb_perms) != cb_perms) then + 0x0 + else + 0x1); + wGPR(rd) := result; + } + (* END_CTestSubset *) +} + union ast member regregreg CSeal -function clause decode (0b010010 : 0b00010 : (regno) cd : (regno) cs : (regno) ct : 0b000: 0b000) = Some(CSeal(cd, cs, ct)) function clause execute (CSeal(cd, cs, ct)) = { (* START_CSeal *) @@ -708,7 +904,6 @@ function clause execute (CSeal(cd, cs, ct)) = } union ast member regregreg CCSeal -function clause decode (0b010010 : 0b00000 : (regno) cd : (regno) cs : (regno) ct : 0b011111) = Some(CCSeal(cd, cs, ct)) function clause execute (CCSeal(cd, cs, ct)) = { (* START_CCSeal *) @@ -750,7 +945,6 @@ function clause execute (CCSeal(cd, cs, ct)) = } union ast member regregreg CUnseal -function clause decode (0b010010 : 0b00011 : (regno) cd : (regno) cs : (regno) ct : 0b000: 0b000) = Some(CUnseal(cd, cs, ct)) function clause execute (CUnseal(cd, cs, ct)) = { (* START_CUnseal *) @@ -790,7 +984,6 @@ function clause execute (CUnseal(cd, cs, ct)) = } union ast member (regno, regno, bit[11]) CCall -function clause decode (0b010010 : 0b00101 : (regno) cs : (regno) cb : (bit[11]) selector) = Some(CCall(cs, cb, selector)) function clause execute (CCall(cs, cb, 0b00000000000)) = (* selector=0 *) { (* Partial implementation of CCall with checks in hardware, but raising a trap to perform trusted stack manipulation *) @@ -865,9 +1058,10 @@ function clause execute (CCall(cs, cb, 0b00000000001)) = (* selector=1 *) sealed=false; otype=0; }) in { - nextPC := (bit[64]) (getCapOffset(cs_val)); - nextPCC := csUnsealed; + delayedPC := (bit[64]) (getCapOffset(cs_val)); delayedPCC := csUnsealed; + branchPending := true; + inCCallDelay := true; C26 := capStructToCapReg({cb_val with sealed=false; otype=0; @@ -877,7 +1071,6 @@ function clause execute (CCall(cs, cb, 0b00000000001)) = (* selector=1 *) } union ast member unit CReturn -function clause decode (0b010010 : 0b00110 : 0b000000000000000000000) = Some(CReturn) function clause execute (CReturn) = { (* START_CReturn *) @@ -887,9 +1080,6 @@ function clause execute (CReturn) = } union ast member (regno, bit[16], bool) CBX -function clause decode (0b010010 : 0b01001 : (regno) cb : (bit[16]) imm) = Some(CBX(cb, imm, true)) (* CBTU *) -function clause decode (0b010010 : 0b01010 : (regno) cb : (bit[16]) imm) = Some(CBX(cb, imm, false)) (* CBTS *) - function clause execute (CBX(cb, imm, invert)) = { (* START_CBx *) @@ -905,9 +1095,23 @@ function clause execute (CBX(cb, imm, invert)) = (* END_CBx *) } +union ast member (regno, bit[16], bool) CBZ +function clause execute (CBZ(cb, imm, invert)) = +{ + (* START_CBz *) + checkCP2usable(); + if (register_inaccessible(cb)) then + raise_c2_exception(CapEx_AccessSystemRegsViolation, cb) + else if (((readCapReg(cb)) == null_cap) ^ invert) then + { + let (bit[64]) offset = (EXTS(imm : 0b00) + 4) in + delayedPC := PC + offset; + branchPending := 1; + } + (* END_CBz *) +} + union ast member (regno, regno, bool) CJALR -function clause decode (0b010010 : 0b00111 : (regno) cd : (regno) cb : 0b00000 : 0b000000) = Some(CJALR(cd, cb, true)) (* CJALR *) -function clause decode (0b010010 : 0b01000 : 0b00000 : (regno) cb : 0b00000 : 0b000000) = Some(CJALR(0b00000, cb, false)) (* CJR *) function clause execute(CJALR(cd, cb, link)) = { (* START_CJALR *) @@ -949,22 +1153,6 @@ function clause execute(CJALR(cd, cb, link)) = } union ast member (regno, regno, regno, bit[8], bool, WordType, bool) CLoad -function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b00) = Some(CLoad(rd, cb, rt, offset, false, B, false)) (* CLBU *) -function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b1 : 0b00) = Some(CLoad(rd, cb, rt, offset, true, B, false)) (* CLB *) -function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b01) = Some(CLoad(rd, cb, rt, offset, false, H, false)) (* CLHU *) -function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b1 : 0b01) = Some(CLoad(rd, cb, rt, offset, true, H, false)) (* CLH *) -function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b10) = Some(CLoad(rd, cb, rt, offset, false, W, false)) (* CLWU *) -function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b1 : 0b10) = Some(CLoad(rd, cb, rt, offset, true, W, false)) (* CLW *) -function clause decode (0b110010 : (regno) rd : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b11) = Some(CLoad(rd, cb, rt, offset, false, D, false)) (* CLD *) - -function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b0 : 0b00) = Some(CLoad(rd, cb, 0b00000, 0b00000000, false, B, true)) (* CLLBU *) -function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b1 : 0b00) = Some(CLoad(rd, cb, 0b00000, 0b00000000, true, B, true)) (* CLLB *) -function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b0 : 0b01) = Some(CLoad(rd, cb, 0b00000, 0b00000000, false, H, true)) (* CLLHU *) -function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b1 : 0b01) = Some(CLoad(rd, cb, 0b00000, 0b00000000, true, H, true)) (* CLLH *) -function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b0 : 0b10) = Some(CLoad(rd, cb, 0b00000, 0b00000000, false, W, true)) (* CLLWU *) -function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b1 : 0b10) = Some(CLoad(rd, cb, 0b00000, 0b00000000, true, W, true)) (* CLLW *) -function clause decode (0b010010 : 0b10000 : (regno) rd : (regno) cb : 0b00000001 : 0b0 : 0b11) = Some(CLoad(rd, cb, 0b00000, 0b00000000, false, D, true)) (* CLLD *) - function clause execute (CLoad(rd, cb, rt, offset, signext, width, linked)) = { (* START_CLoad *) @@ -1017,15 +1205,6 @@ function clause execute (CLoad(rd, cb, rt, offset, signext, width, linked)) = } union ast member (regno, regno, regno, regno, bit[8], WordType, bool) CStore -function clause decode (0b111010 : (regno) rs : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b00) = Some(CStore(rs, cb, rt, 0b00000, offset, B, false)) (* CSB *) -function clause decode (0b111010 : (regno) rs : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b01) = Some(CStore(rs, cb, rt, 0b00000, offset, H, false)) (* CSH *) -function clause decode (0b111010 : (regno) rs : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b10) = Some(CStore(rs, cb, rt, 0b00000, offset, W, false)) (* CSW *) -function clause decode (0b111010 : (regno) rs : (regno) cb: (regno) rt : (bit[8]) offset : 0b0 : 0b11) = Some(CStore(rs, cb, rt, 0b00000, offset, D, false)) (* CSD *) - -function clause decode (0b010010 : 0b10000 : (regno) rs : (regno) cb : (regno) rd : 0b0000 : 0b00) = Some(CStore(rs, cb, 0b00000, rd, 0b00000000, B, true)) (* CSCB *) -function clause decode (0b010010 : 0b10000 : (regno) rs : (regno) cb : (regno) rd : 0b0000 : 0b01) = Some(CStore(rs, cb, 0b00000, rd, 0b00000000, H, true)) (* CSCH *) -function clause decode (0b010010 : 0b10000 : (regno) rs : (regno) cb : (regno) rd : 0b0000 : 0b10) = Some(CStore(rs, cb, 0b00000, rd, 0b00000000, W, true)) (* CSCW *) -function clause decode (0b010010 : 0b10000 : (regno) rs : (regno) cb : (regno) rd : 0b0000 : 0b11) = Some(CStore(rs, cb, 0b00000, rd, 0b00000000, D, true)) (* CSCD *) function clause execute (CStore(rs, cb, rt, rd, offset, width, conditional)) = { @@ -1084,8 +1263,6 @@ function clause execute (CStore(rs, cb, rt, rd, offset, width, conditional)) = } union ast member (regno, regno, regno, regno, bit[11], bool) CSC -function clause decode (0b111110 : (regno) cs : (regno) cb: (regno) rt : (bit[11]) offset) = Some(CSC(cs, cb, rt, 0b00000, offset, false)) -function clause decode (0b010010 : 0b10000 : (regno) cs : (regno) cb: (regno) rd : 0b00 : 0b0111) = Some(CSC(cs, cb, 0b00000, rd, 0b00000000000, true)) function clause execute (CSC(cs, cb, rt, rd, offset, conditional)) = { (* START_CSC *) @@ -1136,8 +1313,6 @@ function clause execute (CSC(cs, cb, rt, rd, offset, conditional)) = } union ast member (regno, regno, regno, bit[11], bool) CLC -function clause decode (0b110110 : (regno) cd : (regno) cb: (regno) rt : (bit[11]) offset) = Some(CLC(cd, cb, rt, offset, false)) -function clause decode (0b010010 : 0b10000 : (regno) cd : (regno) cb: 0b0000000 : 0b1111) = Some(CLC(cd, cb, 0b00000, 0b00000000000, true)) function clause execute (CLC(cd, cb, rt, offset, linked)) = { (* START_CLC *) @@ -1183,6 +1358,5 @@ function clause execute (CLC(cd, cb, rt, offset, linked)) = } union ast member (regno) C2Dump -function clause decode (0b010010 : 0b00100 : (regno) rt : 0x0006) = Some(C2Dump(rt)) function clause execute (C2Dump (rt)) = () (* Currently a NOP *) diff --git a/cheri/cheri_prelude_128.sail b/cheri/cheri_prelude_128.sail index 5e63221e..cc939f59 100644 --- a/cheri/cheri_prelude_128.sail +++ b/cheri/cheri_prelude_128.sail @@ -84,7 +84,7 @@ let (CapStruct) null_cap = { E = 48; (* encoded as 0 in memory due to xor *) sealed = false; B = 0; - T = 0; + T = 0x10000; otype = 0; address = 0; } @@ -133,7 +133,7 @@ function (bit[11]) getCapHardPerms((CapStruct) cap) = : [cap.permit_execute] : [cap.global]) -function (bit[128]) capStructToMemBits((CapStruct) cap) = +function (bit[128]) capStructToMemBits128((CapStruct) cap) = let (bit[20]) b = if cap.sealed then (cap.B)[19..12] : (cap.otype)[23..12] else cap.B in let (bit[20]) t = if cap.sealed then (cap.T)[19..12] : (cap.otype)[11..0] else cap.T in ( cap.uperms @@ -147,12 +147,24 @@ function (bit[128]) capStructToMemBits((CapStruct) cap) = ) function (CapReg) capStructToCapReg((CapStruct) cap) = - ([cap.tag] : capStructToMemBits(cap)) + ([cap.tag] : capStructToMemBits128(cap)) (* Reverse of above used when reading from memory *) -function (CapReg) memBitsToCapBits((bool) tag, (bit[128]) b) = +function (CapReg) memBitsToCapBits128((bool) tag, (bit[128]) b) = ([tag] : b) +(* When saving/restoring capabilities xor them with bits of null_cap -- + this ensures that canonical null_cap is always all-zeros in memory + even though it may have bits set logically (e.g. length or exponent *) + +let (bit[128]) null_cap_bits = capStructToMemBits128(null_cap) + +function (bit[128]) capStructToMemBits((CapStruct) cap) = + capStructToMemBits128(cap) ^ null_cap_bits + +function (bit[129]) memBitsToCapBits((bool) tag, (bit[128]) b) = + memBitsToCapBits128(tag, b ^ null_cap_bits) + function (bit[31]) getCapPerms((CapStruct) cap) = let (bit[15]) perms = EXTS(getCapHardPerms(cap)) in (* NB access_system copied into 14-11 *) (0x000 (* uperms 30-19 *) @@ -191,23 +203,23 @@ function [|-1:1|] a_top_correction((bit[20]) a_mid, (bit[20]) R, (bit[20]) bound } function uint64 getCapBase((CapStruct) c) = - let ([|45|]) E = min(unsigned(c.E), 45) in + let ([|48|]) E = min(unsigned(c.E), 48) in let (bit[20]) Bc = c.B in let (bit[65]) a = EXTZ(c.address) in let (bit[20]) R = Bc - 0x01000 in (* wraps *) - let (bit[20]) a_mid = a[(E + 19)..E] in + let (bit[20]) a_mid = mask(a >> E) in let correction = a_top_correction(a_mid, R, Bc) in let a_top = a >> (E+20) in let (bit[64]) base = EXTZ((a_top + correction) : Bc) << E in unsigned(base) function CapLen getCapTop ((CapStruct) c) = - let ([|45|]) E = min(unsigned(c.E), 45) in + let ([|45|]) E = min(unsigned(c.E), 48) in let (bit[20]) Bc = c.B in let (bit[20]) T = c.T in let (bit[65]) a = EXTZ(c.address) in let (bit[20]) R = Bc - 0x01000 in (* wraps *) - let (bit[20]) a_mid = a[(E + 19)..E] in + let (bit[20]) a_mid = mask(a >> E) in let correction = a_top_correction(a_mid, R, T) in let a_top = a >> (E+20) in let (bit[65]) top1 = EXTZ((a_top + correction) : T) in diff --git a/cheri/cheri_prelude_256.sail b/cheri/cheri_prelude_256.sail index 7b42020d..988cfe49 100644 --- a/cheri/cheri_prelude_256.sail +++ b/cheri/cheri_prelude_256.sail @@ -86,7 +86,7 @@ let (CapStruct) null_cap = { sealed = false; offset = 0; base = 0; - length = 0; + length = 0xffffffffffffffff; } def Nat cap_size_t = 32 (* cap size in bytes *) @@ -138,7 +138,7 @@ function (bit[31]) getCapPerms((CapStruct) cap) = - this is the same as register format except for the offset, field which is stored as an absolute cursor on CHERI due to uarch optimisation *) -function (bit[256]) capStructToMemBits((CapStruct) cap) = +function (bit[256]) capStructToMemBits256((CapStruct) cap) = ( cap.padding : cap.otype @@ -152,13 +152,25 @@ function (bit[256]) capStructToMemBits((CapStruct) cap) = (* Reverse of above used when reading from memory *) -function (bit[257]) memBitsToCapBits((bool) tag, (bit[256]) b) = +function (bit[257]) memBitsToCapBits256((bool) tag, (bit[256]) b) = ([tag] : b[255..192] : ((bit[64])(b[191..128] - b[127..64])) : b[127..0] ) +(* When saving/restoring capabilities xor them with bits of null_cap -- + this ensures that canonical null_cap is always all-zeros in memory + even though it may have bits set logically (e.g. length or exponent *) + +function (bit[256]) capStructToMemBits((CapStruct) cap) = + let (bit[256]) null_cap_bits = capStructToMemBits256(null_cap) in + capStructToMemBits256(cap) ^ null_cap_bits + +function (bit[257]) memBitsToCapBits((bool) tag, (bit[256]) b) = + let (bit[256]) null_cap_bits = capStructToMemBits256(null_cap) in + memBitsToCapBits256(tag, b ^ null_cap_bits) + function (CapReg) capStructToCapReg((CapStruct) cap) = ( [cap.tag] diff --git a/cheri/cheri_prelude_common.sail b/cheri/cheri_prelude_common.sail index f5fcd095..a2d3b441 100644 --- a/cheri/cheri_prelude_common.sail +++ b/cheri/cheri_prelude_common.sail @@ -45,6 +45,7 @@ scattered function option<ast> decode register CapReg PCC register CapReg nextPCC register CapReg delayedPCC +register (bit[1]) inCCallDelay register CapReg C00 (* aka default data capability, DDC *) register CapReg C01 register CapReg C02 @@ -115,6 +116,7 @@ typedef CapEx = enumerate { CapEx_PermitSealViolation; CapEx_AccessSystemRegsViolation; CapEx_PermitCCallViolation; + CapEx_AccessCCallIDCViolation; } typedef CPtrCmpOp = enumerate { @@ -158,6 +160,7 @@ function (bit[8]) CapExCode((CapEx) ex) = case CapEx_PermitSealViolation -> 0x17 case CapEx_AccessSystemRegsViolation -> 0x18 case CapEx_PermitCCallViolation -> 0x19 + case CapEx_AccessCCallIDCViolation -> 0x1a } typedef CapCauseReg = register bits [15:0] { @@ -204,7 +207,11 @@ function forall Type 'o . 'o raise_c2_exception8((CapEx) capEx, (bit[8]) regnum) } function forall Type 'o . 'o raise_c2_exception((CapEx) capEx, (regno) regnum) = - raise_c2_exception8(capEx, 0b000 : regnum) + let reg8 = 0b000 : regnum in + if ((capEx == CapEx_AccessSystemRegsViolation) & (regnum == 26 (* IDC *))) then + raise_c2_exception8(CapEx_AccessCCallIDCViolation, reg8) + else + raise_c2_exception8(capEx, reg8) function forall Type 'o . 'o raise_c2_exception_noreg((CapEx) capEx) = raise_c2_exception8(capEx, 0xff) @@ -213,7 +220,8 @@ function bool pcc_access_system_regs () = let pcc = capRegToCapStruct(PCC) in (pcc.access_system_regs) -function bool register_inaccessible((regno) r) = +function bool register_inaccessible((regno) r) = + if ((r == 26 (* IDC *)) & ((bool)inCCallDelay)) then true else (* XXX interpreter crash without cast *) let (bool) is_sys_reg = switch(r) { case 0b11011 -> true case 0b11100 -> true diff --git a/editors/sail2-mode.el b/editors/sail2-mode.el index b93542b5..8dde96df 100644 --- a/editors/sail2-mode.el +++ b/editors/sail2-mode.el @@ -8,7 +8,7 @@ "else" "match" "in" "return" "register" "forall" "operator" "effect" "overload" "cast" "sizeof" "constraint" "default" "assert" "pure" "infixl" "infixr" "infix" "scattered" "end" "try" "catch" "and" - "throw" "clause" "as" "repeat" "until" "while" "do")) + "throw" "clause" "as" "repeat" "until" "while" "do" "foreach")) (defconst sail2-kinds '("Int" "Type" "Order" "inc" "dec" diff --git a/etc/power_header b/etc/power_header new file mode 100644 index 00000000..eb01510e --- /dev/null +++ b/etc/power_header @@ -0,0 +1,31 @@ + +Copyright (c) 2015-2017 Gabriel Kerneis, Susmit Sarkar, Kathyrn Gray +Copyright (c) 2015-2017 Peter Sewell +All rights reserved. + +This software was developed by the University of Cambridge Computer +Laboratory as part of the Rigorous Engineering of Mainstream Systems +(REMS) project, funded by EPSRC grant EP/K008528/1. + +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. diff --git a/etc/regfp.sail b/etc/regfp.sail index fb15310a..cc057f2e 100644 --- a/etc/regfp.sail +++ b/etc/regfp.sail @@ -32,21 +32,31 @@ typedef diafp = const union { typedef read_kind = enumerate { Read_plain; - Read_tag; Read_reserve; Read_acquire; Read_exclusive; Read_exclusive_acquire; - Read_stream + Read_stream; + Read_RISCV_acquire; + Read_RISCV_strong_acquire; + Read_RISCV_reserved; + Read_RISCV_reserved_acquire; + Read_RISCV_reserved_strong_acquire; + Read_X86_locked; } typedef write_kind = enumerate { Write_plain; - Write_tag; Write_conditional; Write_release; Write_exclusive; Write_exclusive_release; + Write_RISCV_release; + Write_RISCV_strong_release; + Write_RISCV_conditional; + Write_RISCV_conditional_release; + Write_RISCV_conditional_strong_release; + Write_X86_locked; } typedef barrier_kind = enumerate { @@ -62,6 +72,13 @@ typedef barrier_kind = enumerate { Barrier_DSB_LD; Barrier_ISB; Barrier_MIPS_SYNC; + Barrier_RISCV_rw_rw; + Barrier_RISCV_r_rw; + Barrier_RISCV_r_r; + Barrier_RISCV_rw_w; + Barrier_RISCV_w_w; + Barrier_RISCV_i; + Barrier_x86_MFENCE; } typedef trans_kind = enumerate { @@ -72,6 +89,7 @@ typedef instruction_kind = const union { (barrier_kind) IK_barrier; (read_kind) IK_mem_read; (write_kind) IK_mem_write; + (read_kind, write_kind) IK_mem_rmw; IK_cond_branch; (trans_kind) IK_trans; IK_simple diff --git a/lib/ocaml_rts/sail_lib.ml b/lib/ocaml_rts/sail_lib.ml index 3cf4505d..dfdd1db9 100644 --- a/lib/ocaml_rts/sail_lib.ml +++ b/lib/ocaml_rts/sail_lib.ml @@ -413,6 +413,8 @@ let real_power (x, y) = Num.power_num x (Num.num_of_big_int y) let add_real (x, y) = Num.add_num x y let sub_real (x, y) = Num.sub_num x y +let abs_real x = Num.abs_num x + let lt (x, y) = lt_big_int x y let gt (x, y) = gt_big_int x y let lteq (x, y) = le_big_int x y @@ -422,6 +424,7 @@ let pow2 x = power_big_int_positive_int x 2 let max_int (x, y) = max_big_int x y let min_int (x, y) = min_big_int x y +let abs_int x = abs_big_int x let undefined_real () = Num.num_of_int 0 diff --git a/mips/Makefile b/mips/Makefile new file mode 100644 index 00000000..03d7ae15 --- /dev/null +++ b/mips/Makefile @@ -0,0 +1,23 @@ +SAIL:=../src/sail.native +LEM:=../../lem/lem + +# SOURCES:=mips_prelude.sail mips_tlb.sail mips_wrappers.sail mips_insts.sail mips_ri.sail mips_epilogue.sail ../etc/regfp.sail mips_regfp.sail +SOURCES:=mips_prelude.sail mips_tlb_stub.sail mips_wrappers.sail mips_insts.sail mips_epilogue.sail ../etc/regfp.sail mips_regfp.sail + + +all: mips.lem mips.ml mips_embed.lem + +mips.lem: $(SOURCES) + $(SAIL) -lem_ast -o $(BUILD)/mips $(SOURCES) + +mips.ml: mips.lem ../src/lem_interp/interp_ast.lem + $(LEM) -ocaml -lib ../src/lem_interp/ $< + + +mips_embed.lem: $(SOURCES) +# also generates mips_embed_sequential.lem, mips_embed_types.lem, mips_toFromInterp.lem + $(SAIL) -lem -lem_lib Mips_extras_embed -o mips $(SOURCES) + +clean: + rm -f mips.lem mips.ml + rm -f mips_embed*.lem mips_toFromInterp.lem diff --git a/mips/hgen/ast.hgen b/mips/gen/ast.hgen index a251adff..a251adff 100644 --- a/mips/hgen/ast.hgen +++ b/mips/gen/ast.hgen diff --git a/mips/hgen/fold.hgen b/mips/gen/fold.hgen index 05b9c808..05b9c808 100644 --- a/mips/hgen/fold.hgen +++ b/mips/gen/fold.hgen diff --git a/mips/hgen/herdtools_ast_to_shallow_ast.hgen b/mips/gen/herdtools_ast_to_shallow_ast.hgen index 7b1a58d9..7b1a58d9 100644 --- a/mips/hgen/herdtools_ast_to_shallow_ast.hgen +++ b/mips/gen/herdtools_ast_to_shallow_ast.hgen diff --git a/mips/hgen/herdtools_types_to_shallow_types.hgen b/mips/gen/herdtools_types_to_shallow_types.hgen index 5a0e3bfc..5a0e3bfc 100644 --- a/mips/hgen/herdtools_types_to_shallow_types.hgen +++ b/mips/gen/herdtools_types_to_shallow_types.hgen diff --git a/mips/hgen/lexer.hgen b/mips/gen/lexer.hgen index c01b14cc..c01b14cc 100644 --- a/mips/hgen/lexer.hgen +++ b/mips/gen/lexer.hgen diff --git a/mips/hgen/map.hgen b/mips/gen/map.hgen index f5116bae..f5116bae 100644 --- a/mips/hgen/map.hgen +++ b/mips/gen/map.hgen diff --git a/mips/hgen/parser.hgen b/mips/gen/parser.hgen index 8f573aa5..8f573aa5 100644 --- a/mips/hgen/parser.hgen +++ b/mips/gen/parser.hgen diff --git a/mips/hgen/pretty.hgen b/mips/gen/pretty.hgen index 98f56f2e..98f56f2e 100644 --- a/mips/hgen/pretty.hgen +++ b/mips/gen/pretty.hgen diff --git a/mips/hgen/sail_trans_out.hgen b/mips/gen/sail_trans_out.hgen index f2d006e8..f2d006e8 100644 --- a/mips/hgen/sail_trans_out.hgen +++ b/mips/gen/sail_trans_out.hgen diff --git a/mips/hgen/shallow_ast_to_herdtools_ast.hgen b/mips/gen/shallow_ast_to_herdtools_ast.hgen index efe2c77e..efe2c77e 100644 --- a/mips/hgen/shallow_ast_to_herdtools_ast.hgen +++ b/mips/gen/shallow_ast_to_herdtools_ast.hgen diff --git a/mips/hgen/shallow_types_to_herdtools_types.hgen b/mips/gen/shallow_types_to_herdtools_types.hgen index a02d83b7..a02d83b7 100644 --- a/mips/hgen/shallow_types_to_herdtools_types.hgen +++ b/mips/gen/shallow_types_to_herdtools_types.hgen diff --git a/mips/hgen/token_types.hgen b/mips/gen/token_types.hgen index 170b42d3..170b42d3 100644 --- a/mips/hgen/token_types.hgen +++ b/mips/gen/token_types.hgen diff --git a/mips/hgen/tokens.hgen b/mips/gen/tokens.hgen index 937c6354..937c6354 100644 --- a/mips/hgen/tokens.hgen +++ b/mips/gen/tokens.hgen diff --git a/mips/hgen/trans_sail.hgen b/mips/gen/trans_sail.hgen index e42d1b19..e42d1b19 100644 --- a/mips/hgen/trans_sail.hgen +++ b/mips/gen/trans_sail.hgen diff --git a/mips/hgen/types.hgen b/mips/gen/types.hgen index a1c61f4b..a1c61f4b 100644 --- a/mips/hgen/types.hgen +++ b/mips/gen/types.hgen diff --git a/mips/hgen/types_sail_trans_out.hgen b/mips/gen/types_sail_trans_out.hgen index ebd31fcb..ebd31fcb 100644 --- a/mips/hgen/types_sail_trans_out.hgen +++ b/mips/gen/types_sail_trans_out.hgen diff --git a/mips/hgen/types_trans_sail.hgen b/mips/gen/types_trans_sail.hgen index 63880ae9..63880ae9 100644 --- a/mips/hgen/types_trans_sail.hgen +++ b/mips/gen/types_trans_sail.hgen diff --git a/mips/mips_extras.lem b/mips/mips_extras.lem index 1fbba038..be576fb2 100644 --- a/mips/mips_extras.lem +++ b/mips/mips_extras.lem @@ -31,25 +31,25 @@ let memory_parameter_transformer_option_address _mode v = end -let read_memory_functions : memory_reads = +let mips_read_memory_functions : memory_reads = [ ("MEMr", (MR Read_plain memory_parameter_transformer)); ("MEMr_reserve", (MR Read_reserve memory_parameter_transformer)); ] -let read_memory_tagged_functions : memory_read_taggeds = +let mips_read_memory_tagged_functions : memory_read_taggeds = [ ("MEMr_tag", (MRT Read_plain memory_parameter_transformer)); ("MEMr_tag_reserve", (MRT Read_reserve memory_parameter_transformer)); ] -let memory_writes : memory_writes = +let mips_memory_writes : memory_writes = [] -let memory_eas : memory_write_eas = +let mips_memory_eas : memory_write_eas = [ ("MEMea", (MEA Write_plain memory_parameter_transformer)); ("MEMea_conditional", (MEA Write_conditional memory_parameter_transformer)); ] -let memory_vals : memory_write_vals = +let mips_memory_vals : memory_write_vals = [ ("MEMval", (MV memory_parameter_transformer_option_address Nothing)); ("MEMval_conditional", (MV memory_parameter_transformer_option_address (Just @@ -58,7 +58,7 @@ let memory_vals : memory_write_vals = (IState (Interp.add_answer_to_stack interp bit) context))))); ] -let memory_vals_tagged : memory_write_vals_tagged = +let mips_memory_vals_tagged : memory_write_vals_tagged = [ ("MEMval_tag", (MVT memory_parameter_transformer_option_address Nothing)); ("MEMval_tag_conditional", (MVT memory_parameter_transformer_option_address @@ -68,6 +68,6 @@ let memory_vals_tagged : memory_write_vals_tagged = (IState (Interp.add_answer_to_stack interp bit) context))))); ] -let barrier_functions = [ +let mips_barrier_functions = [ ("MEM_sync", Barrier_MIPS_SYNC); ] diff --git a/mips/mips_prelude.sail b/mips/mips_prelude.sail index a4098486..382e4d7f 100644 --- a/mips/mips_prelude.sail +++ b/mips/mips_prelude.sail @@ -472,6 +472,13 @@ function AccessLevel getAccessLevel() = case _ -> User (* behaviour undefined, assume user *) } +function ([|2|]) int_of_accessLevel((AccessLevel)x) = + switch (x) { + case User -> 0 + case Supervisor -> 1 + case Kernel -> 2 + } + function unit checkCP0Access () = { let accessLevel = getAccessLevel() in diff --git a/mips/mips_tlb.sail b/mips/mips_tlb.sail index 2e40deed..d72e0e75 100644 --- a/mips/mips_tlb.sail +++ b/mips/mips_tlb.sail @@ -108,7 +108,7 @@ function (bit[64], bool) TLBTranslateC ((bit[64]) vAddr, (MemAccessType) accessT case 0b01 -> (Supervisor, None) (* xsseg - supervisor mapped *) case 0b00 -> (User, None) (* xuseg - user mapped *) } in - if (((nat)currentAccessLevel) < ((nat)requiredLevel)) then + if ((int_of_accessLevel(currentAccessLevel)) < (int_of_accessLevel(requiredLevel))) then (SignalExceptionBadAddr(if (accessType == StoreData) then AdES else AdEL, vAddr)) else let (pa, c) = switch(addr) { diff --git a/mips/run_embed.ml b/mips/run_embed.ml index 463caffd..1bb6d5f6 100644 --- a/mips/run_embed.ml +++ b/mips/run_embed.ml @@ -219,7 +219,10 @@ module CHERI_model : ISA_model = struct let pc_vaddr = unsigned_big(Cheri_embed._PC) in let npc_addr = add_int_big_int 4 pc_vaddr in let npc_vec = to_vec_dec_big (bi64, npc_addr) in - set_register Cheri_embed._nextPC npc_vec + begin + set_register Cheri_embed._nextPC npc_vec; + set_register Cheri_embed._inCCallDelay (to_vec_dec_int (1, 0)) + end let get_pc () = unsigned_big (Cheri_embed._PC) @@ -250,7 +253,7 @@ module CHERI128_model : ISA_model = struct let start_addr = (to_vec_dec_big (bi64, big_int_of_string "0x9000000040000000")) in set_register Cheri128_embed._nextPC start_addr; set_register_field_bit Cheri128_embed._CP0Status "BEV" Vone; - let initial_cap_val_int = big_int_of_string "0x1fffe0000000800000000000000000000" in (* hex((0x80000 << 64) + (0x7fff << 113) + (1 << 128)) *) + let initial_cap_val_int = big_int_of_string "0x1fffe6000000100000000000000000000" in (* hex((0x10000 << 64) + (48 << 105) + (0x7fff << 113) + (1 << 128)) T=0x10000 E=48 perms=0x7fff tag=1 *) let initial_cap_vec = to_vec_dec ((bi129), initial_cap_val_int) in set_register Cheri128_embed._PCC initial_cap_vec; set_register Cheri128_embed._nextPCC initial_cap_vec; @@ -277,7 +280,10 @@ module CHERI128_model : ISA_model = struct let pc_vaddr = unsigned_big(Cheri128_embed._PC) in let npc_addr = add_int_big_int 4 pc_vaddr in let npc_vec = to_vec_dec_big (bi64, npc_addr) in - set_register Cheri128_embed._nextPC npc_vec + begin + set_register Cheri128_embed._nextPC npc_vec; + set_register Cheri128_embed._inCCallDelay (to_vec_dec_int (1, 0)) + end let get_pc () = unsigned_big (Cheri128_embed._PC) diff --git a/power/Makefile b/power/Makefile new file mode 100644 index 00000000..9559646c --- /dev/null +++ b/power/Makefile @@ -0,0 +1,49 @@ +SAIL:=../src/sail.native +LEM:=../../lem/lem + +SOURCES:=power.sail ../etc/regfp.sail power_regfp.sail + + +all: power.lem power.ml power_embed.lem + +power.lem: $(SOURCES) + $(SAIL) -lem_ast -o power $(SOURCES) + +power.ml: power.lem ../src/lem_interp/interp_ast.lem + $(LEM) -ocaml -lib ../src/lem_interp/ $< + + +power_embed.lem: $(SOURCES) +# also generates power_embed_sequential.lem, power_embed_types.lem, power_toFromInterp.lem + $(SAIL) -lem -lem_lib Power_extras_embed -o power $(SOURCES) + # patch: + rm -f power_embed.lem power_embed_sequential.lem + cp power_embed.lem.fixed power_embed.lem + cp power_embed_sequential.lem.fixed power_embed_sequential.lem + +clean: + rm -f power.lem power.ml + rm -f power_embed*.lem power_toFromInterp.lem + +###################################################################### +ETCDIR=../etc + +apply_header: + headache -c $(ETCDIR)/headache_config -h $(ETCDIR)/power_header *.sail +.PHONY: apply_header + +###################################################################### +IDLPOWER=../../../rsem/idl/power + +pull_from_idl: + cp -a $(IDLPOWER)/generated/power.sail ./ +# cp -a $(IDLPOWER)/generated/*.lem ./ +# cp -a $(IDLPOWER)/generated/power.ml ./ +# cp -a $(IDLPOWER)/generated/*.txt ./ + cp -a $(IDLPOWER)/extras/*.sail ./ + cp -a $(IDLPOWER)/extras/*.lem ./ + mkdir -p gen + cp -a $(IDLPOWER)/generated/*.gen gen/ + cp -a $(IDLPOWER)/*.hgen gen/ + $(MAKE) apply_header +.PHONY: pull_from_idl diff --git a/power/gen/ast.gen b/power/gen/ast.gen new file mode 100644 index 00000000..fdc12609 --- /dev/null +++ b/power/gen/ast.gen @@ -0,0 +1,202 @@ + | `Pb of setaa*setlk*k + | `Pbc of setaa*setlk*k*k*k + | `Pbclr of setlk*k*k*k + | `Pbcctr of setlk*k*k*k + | `Pcrand of k*k*k + | `Pcrnand of k*k*k + | `Pcror of k*k*k + | `Pcrxor of k*k*k + | `Pcrnor of k*k*k + | `Pcreqv of k*k*k + | `Pcrandc of k*k*k + | `Pcrorc of k*k*k + | `Pmcrf of crindex*k + | `Psc of k + | `Pscv of k + | `Plbz of reg*k*reg + | `Plbzx of reg*reg*reg + | `Plbzu of reg*k*reg + | `Plbzux of reg*reg*reg + | `Plhz of reg*k*reg + | `Plhzx of reg*reg*reg + | `Plhzu of reg*k*reg + | `Plhzux of reg*reg*reg + | `Plha of reg*k*reg + | `Plhax of reg*reg*reg + | `Plhau of reg*k*reg + | `Plhaux of reg*reg*reg + | `Plwz of reg*k*reg + | `Plwzx of reg*reg*reg + | `Plwzu of reg*k*reg + | `Plwzux of reg*reg*reg + | `Plwa of reg*ds*reg + | `Plwax of reg*reg*reg + | `Plwaux of reg*reg*reg + | `Pld of reg*ds*reg + | `Pldx of reg*reg*reg + | `Pldu of reg*ds*reg + | `Pldux of reg*reg*reg + | `Pstb of reg*k*reg + | `Pstbx of reg*reg*reg + | `Pstbu of reg*k*reg + | `Pstbux of reg*reg*reg + | `Psth of reg*k*reg + | `Psthx of reg*reg*reg + | `Psthu of reg*k*reg + | `Psthux of reg*reg*reg + | `Pstw of reg*k*reg + | `Pstwx of reg*reg*reg + | `Pstwu of reg*k*reg + | `Pstwux of reg*reg*reg + | `Pstd of reg*ds*reg + | `Pstdx of reg*reg*reg + | `Pstdu of reg*ds*reg + | `Pstdux of reg*reg*reg + | `Plq of k*k*reg*k + | `Pstq of k*ds*reg + | `Plhbrx of reg*reg*reg + | `Psthbrx of reg*reg*reg + | `Plwbrx of reg*reg*reg + | `Pstwbrx of reg*reg*reg + | `Pldbrx of reg*reg*reg + | `Pstdbrx of reg*reg*reg + | `Plmw of reg*k*reg + | `Pstmw of reg*k*reg + | `Plswi of k*reg*k + | `Plswx of reg*reg*reg + | `Pstswi of k*reg*k + | `Pstswx of k*reg*reg + | `Paddi of reg*reg*k + | `Paddis of reg*reg*k + | `Padd of setsoov*setcr0*reg*reg*reg + | `Psubf of setsoov*setcr0*reg*reg*reg + | `Paddic of reg*reg*k + | `Paddicdot of reg*reg*k + | `Psubfic of reg*reg*k + | `Paddc of setsoov*setcr0*reg*reg*reg + | `Psubfc of setsoov*setcr0*reg*reg*reg + | `Padde of setsoov*setcr0*reg*reg*reg + | `Psubfe of setsoov*setcr0*reg*reg*reg + | `Paddme of setsoov*setcr0*reg*reg + | `Psubfme of setsoov*setcr0*reg*reg + | `Paddze of setsoov*setcr0*reg*reg + | `Psubfze of setsoov*setcr0*reg*reg + | `Pneg of setsoov*setcr0*reg*reg + | `Pmulli of reg*reg*k + | `Pmullw of setsoov*setcr0*reg*reg*reg + | `Pmulhw of setcr0*reg*reg*reg + | `Pmulhwu of setcr0*reg*reg*reg + | `Pdivw of setsoov*setcr0*reg*reg*reg + | `Pdivwu of setsoov*setcr0*reg*reg*reg + | `Pdivwe of setsoov*setcr0*reg*reg*reg + | `Pdivweu of setsoov*setcr0*reg*reg*reg + | `Pmulld of setsoov*setcr0*reg*reg*reg + | `Pmulhd of setcr0*reg*reg*reg + | `Pmulhdu of setcr0*reg*reg*reg + | `Pdivd of setsoov*setcr0*reg*reg*reg + | `Pdivdu of setsoov*setcr0*reg*reg*reg + | `Pdivde of setsoov*setcr0*reg*reg*reg + | `Pdivdeu of setsoov*setcr0*reg*reg*reg + | `Pcmpi of crindex*k*reg*k + | `Pcmp of crindex*k*reg*reg + | `Pcmpli of crindex*k*reg*k + | `Pcmpl of crindex*k*reg*reg + | `Pisel of reg*reg*reg*k + | `Pandi of reg*reg*k + | `Pandis of reg*reg*k + | `Pori of reg*reg*k + | `Poris of reg*reg*k + | `Pxori of reg*reg*k + | `Pxoris of reg*reg*k + | `Pand of setcr0*reg*reg*reg + | `Pxor of setcr0*reg*reg*reg + | `Pnand of setcr0*reg*reg*reg + | `Por of setcr0*reg*reg*reg + | `Pnor of setcr0*reg*reg*reg + | `Peqv of setcr0*reg*reg*reg + | `Pandc of setcr0*reg*reg*reg + | `Porc of setcr0*reg*reg*reg + | `Pextsb of setcr0*reg*reg + | `Pextsh of setcr0*reg*reg + | `Pcntlzw of setcr0*reg*reg + | `Pcmpb of reg*k*reg + | `Ppopcntb of reg*reg + | `Ppopcntw of reg*reg + | `Pprtyd of reg*reg + | `Pprtyw of reg*reg + | `Pextsw of setcr0*reg*reg + | `Pcntlzd of setcr0*reg*reg + | `Ppopcntd of reg*reg + | `Pbpermd of reg*reg*reg + | `Prlwinm of setcr0*reg*reg*k*k*k + | `Prlwnm of setcr0*reg*reg*reg*k*k + | `Prlwimi of setcr0*reg*reg*k*k*k + | `Prldicl of setcr0*reg*reg*k*k + | `Prldicr of setcr0*reg*reg*k*k + | `Prldic of setcr0*reg*reg*k*k + | `Prldcl of setcr0*reg*reg*reg*k + | `Prldcr of setcr0*reg*reg*reg*k + | `Prldimi of setcr0*reg*reg*k*k + | `Pslw of setcr0*reg*reg*reg + | `Psrw of setcr0*reg*reg*reg + | `Psrawi of setcr0*reg*reg*k + | `Psraw of setcr0*reg*reg*reg + | `Psld of setcr0*reg*reg*reg + | `Psrd of setcr0*reg*reg*reg + | `Psradi of setcr0*reg*reg*k + | `Psrad of setcr0*reg*reg*reg + | `Pcdtbcd of reg*reg + | `Pcbcdtd of reg*reg + | `Paddg6s of reg*reg*reg + | `Pmtspr of k*reg + | `Pmfspr of reg*k + | `Pmtcrf of crmask*reg + | `Pmfcr of reg + | `Pmtocrf of crmask*reg + | `Pmfocrf of reg*crmask + | `Pmcrxr of crindex + | `Pdlmzb of setcr0*reg*reg*reg + | `Pmacchw of setsoov*setcr0*reg*reg*reg + | `Pmacchws of setsoov*setcr0*reg*reg*reg + | `Pmacchwu of setsoov*setcr0*reg*reg*reg + | `Pmacchwsu of setsoov*setcr0*reg*reg*reg + | `Pmachhw of setsoov*setcr0*reg*reg*reg + | `Pmachhws of setsoov*setcr0*reg*reg*reg + | `Pmachhwu of setsoov*setcr0*reg*reg*reg + | `Pmachhwsu of setsoov*setcr0*reg*reg*reg + | `Pmaclhw of setsoov*setcr0*reg*reg*reg + | `Pmaclhws of setsoov*setcr0*reg*reg*reg + | `Pmaclhwu of setsoov*setcr0*reg*reg*reg + | `Pmaclhwsu of setsoov*setcr0*reg*reg*reg + | `Pmulchw of setcr0*reg*reg*reg + | `Pmulchwu of setcr0*reg*reg*reg + | `Pmulhhw of setcr0*reg*reg*reg + | `Pmulhhwu of setcr0*reg*reg*reg + | `Pmullhw of setcr0*reg*reg*reg + | `Pmullhwu of setcr0*reg*reg*reg + | `Pnmacchw of setsoov*setcr0*reg*reg*reg + | `Pnmacchws of setsoov*setcr0*reg*reg*reg + | `Pnmachhw of setsoov*setcr0*reg*reg*reg + | `Pnmachhws of setsoov*setcr0*reg*reg*reg + | `Pnmaclhw of setsoov*setcr0*reg*reg*reg + | `Pnmaclhws of setsoov*setcr0*reg*reg*reg + | `Picbi of reg*reg + | `Picbt of k*reg*reg + | `Pdcba of reg*reg + | `Pdcbt of reg*reg*k + | `Pdcbtst of reg*reg*k + | `Pdcbz of reg*reg + | `Pdcbst of reg*reg + | `Pdcbf of reg*reg*k + | `Pisync + | `Plbarx of reg*reg*reg*k + | `Plharx of reg*reg*reg*k + | `Plwarx of reg*reg*reg*k + | `Pstbcx of reg*reg*reg + | `Psthcx of reg*reg*reg + | `Pstwcx of reg*reg*reg + | `Pldarx of reg*reg*reg*k + | `Pstdcx of reg*reg*reg + | `Psync of k + | `Peieio + | `Pwait of k diff --git a/power/gen/compile.gen b/power/gen/compile.gen new file mode 100644 index 00000000..d0af6e38 --- /dev/null +++ b/power/gen/compile.gen @@ -0,0 +1,2257 @@ +| `Pb (DontSetAA,DontSetLK,target_addr) -> + { empty_ins with + memo=sprintf "b %i" target_addr; + inputs=[]; + outputs=[]; }::k +| `Pb (SetAA,DontSetLK,target_addr) -> + { empty_ins with + memo=sprintf "ba %i" target_addr; + inputs=[]; + outputs=[]; }::k +| `Pb (DontSetAA,SetLK,target_addr) -> + { empty_ins with + memo=sprintf "bl %i" target_addr; + inputs=[]; + outputs=[]; }::k +| `Pb (SetAA,SetLK,target_addr) -> + { empty_ins with + memo=sprintf "bla %i" target_addr; + inputs=[]; + outputs=[]; }::k +| `Pbc (DontSetAA,DontSetLK,bO,bI,target_addr) -> + { empty_ins with + memo=sprintf "bc %i,%i,%i" bO bI target_addr; + inputs=[]; + outputs=[]; }::k +| `Pbc (SetAA,DontSetLK,bO,bI,target_addr) -> + { empty_ins with + memo=sprintf "bca %i,%i,%i" bO bI target_addr; + inputs=[]; + outputs=[]; }::k +| `Pbc (DontSetAA,SetLK,bO,bI,target_addr) -> + { empty_ins with + memo=sprintf "bcl %i,%i,%i" bO bI target_addr; + inputs=[]; + outputs=[]; }::k +| `Pbc (SetAA,SetLK,bO,bI,target_addr) -> + { empty_ins with + memo=sprintf "bcla %i,%i,%i" bO bI target_addr; + inputs=[]; + outputs=[]; }::k +| `Pbclr (DontSetLK,bO,bI,bH) -> + { empty_ins with + memo=sprintf "bclr %i,%i,%i" bO bI bH; + inputs=[]; + outputs=[]; }::k +| `Pbclr (SetLK,bO,bI,bH) -> + { empty_ins with + memo=sprintf "bclrl %i,%i,%i" bO bI bH; + inputs=[]; + outputs=[]; }::k +| `Pbcctr (DontSetLK,bO,bI,bH) -> + { empty_ins with + memo=sprintf "bcctr %i,%i,%i" bO bI bH; + inputs=[]; + outputs=[]; }::k +| `Pbcctr (SetLK,bO,bI,bH) -> + { empty_ins with + memo=sprintf "bcctrl %i,%i,%i" bO bI bH; + inputs=[]; + outputs=[]; }::k +| `Pcrand (bT,bA,bB) -> + { empty_ins with + memo=sprintf "crand %i,%i,%i" bT bA bB; + inputs=[]; + outputs=[]; }::k +| `Pcrnand (bT,bA,bB) -> + { empty_ins with + memo=sprintf "crnand %i,%i,%i" bT bA bB; + inputs=[]; + outputs=[]; }::k +| `Pcror (bT,bA,bB) -> + { empty_ins with + memo=sprintf "cror %i,%i,%i" bT bA bB; + inputs=[]; + outputs=[]; }::k +| `Pcrxor (bT,bA,bB) -> + { empty_ins with + memo=sprintf "crxor %i,%i,%i" bT bA bB; + inputs=[]; + outputs=[]; }::k +| `Pcrnor (bT,bA,bB) -> + { empty_ins with + memo=sprintf "crnor %i,%i,%i" bT bA bB; + inputs=[]; + outputs=[]; }::k +| `Pcreqv (bT,bA,bB) -> + { empty_ins with + memo=sprintf "creqv %i,%i,%i" bT bA bB; + inputs=[]; + outputs=[]; }::k +| `Pcrandc (bT,bA,bB) -> + { empty_ins with + memo=sprintf "crandc %i,%i,%i" bT bA bB; + inputs=[]; + outputs=[]; }::k +| `Pcrorc (bT,bA,bB) -> + { empty_ins with + memo=sprintf "crorc %i,%i,%i" bT bA bB; + inputs=[]; + outputs=[]; }::k +| `Pmcrf (bF,bFA) -> + { empty_ins with + memo=sprintf "mcrf %i,%i" bF bFA; + inputs=[]; + outputs=[]; }::k +| `Psc (lEV) -> + { empty_ins with + memo=sprintf "sc %i" lEV; + inputs=[]; + outputs=[]; }::k +| `Pscv (lEV) -> + { empty_ins with + memo=sprintf "scv %i" lEV; + inputs=[]; + outputs=[]; }::k +| `Plbz (rT,d,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lbz ^o0,%i(0)" d + else sprintf "lbz ^o0,%i(^i0)" d; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[rT]; }::k +| `Plbzx (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lbzx ^o0,0,^i0" + else sprintf "lbzx ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Plbzu (rT,d,rA) -> + { empty_ins with + memo=sprintf "lbzu ^o0,%i(^i0)" d; + inputs=[rA]; + outputs=[rT; rA]; }::k +| `Plbzux (rT,rA,rB) -> + { empty_ins with + memo=sprintf "lbzux ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT; rA]; }::k +| `Plhz (rT,d,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lhz ^o0,%i(0)" d + else sprintf "lhz ^o0,%i(^i0)" d; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[rT]; }::k +| `Plhzx (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lhzx ^o0,0,^i0" + else sprintf "lhzx ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Plhzu (rT,d,rA) -> + { empty_ins with + memo=sprintf "lhzu ^o0,%i(^i0)" d; + inputs=[rA]; + outputs=[rT; rA]; }::k +| `Plhzux (rT,rA,rB) -> + { empty_ins with + memo=sprintf "lhzux ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT; rA]; }::k +| `Plha (rT,d,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lha ^o0,%i(0)" d + else sprintf "lha ^o0,%i(^i0)" d; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[rT]; }::k +| `Plhax (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lhax ^o0,0,^i0" + else sprintf "lhax ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Plhau (rT,d,rA) -> + { empty_ins with + memo=sprintf "lhau ^o0,%i(^i0)" d; + inputs=[rA]; + outputs=[rT; rA]; }::k +| `Plhaux (rT,rA,rB) -> + { empty_ins with + memo=sprintf "lhaux ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT; rA]; }::k +| `Plwz (rT,d,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lwz ^o0,%i(0)" d + else sprintf "lwz ^o0,%i(^i0)" d; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[rT]; }::k +| `Plwzx (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lwzx ^o0,0,^i0" + else sprintf "lwzx ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Plwzu (rT,d,rA) -> + { empty_ins with + memo=sprintf "lwzu ^o0,%i(^i0)" d; + inputs=[rA]; + outputs=[rT; rA]; }::k +| `Plwzux (rT,rA,rB) -> + { empty_ins with + memo=sprintf "lwzux ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT; rA]; }::k +| `Plwa (rT,dS,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lwa ^o0,%i(0)" (dS lsr 2) + else sprintf "lwa ^o0,%i(^i0)" (dS lsr 2); + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[rT]; }::k +| `Plwax (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lwax ^o0,0,^i0" + else sprintf "lwax ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Plwaux (rT,rA,rB) -> + { empty_ins with + memo=sprintf "lwaux ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT; rA]; }::k +| `Pld (rT,dS,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "ld ^o0,%i(0)" (dS lsr 2) + else sprintf "ld ^o0,%i(^i0)" (dS lsr 2); + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[rT]; }::k +| `Pldx (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "ldx ^o0,0,^i0" + else sprintf "ldx ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Pldu (rT,dS,rA) -> + { empty_ins with + memo=sprintf "ldu ^o0,%i(^i0)" (dS lsr 2); + inputs=[rA]; + outputs=[rT; rA]; }::k +| `Pldux (rT,rA,rB) -> + { empty_ins with + memo=sprintf "ldux ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT; rA]; }::k +| `Pstb (rS,d,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stb ^i0,%i(0)" d + else sprintf "stb ^i0,%i(^i1)" d; + inputs= + (if rA = A.Ireg A.GPR0 then [rS] else [rS; rA]); + outputs=[]; }::k +| `Pstbx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stbx ^i0,0,^i1" + else sprintf "stbx ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rS; rB] else [rS; rA; rB]); + outputs=[]; }::k +| `Pstbu (rS,d,rA) -> + { empty_ins with + memo=sprintf "stbu ^i0,%i(^i1)" d; + inputs=[rS; rA]; + outputs=[rA]; }::k +| `Pstbux (rS,rA,rB) -> + { empty_ins with + memo=sprintf "stbux ^i0,^i1,^i2" ; + inputs=[rS; rA; rB]; + outputs=[rA]; }::k +| `Psth (rS,d,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "sth ^i0,%i(0)" d + else sprintf "sth ^i0,%i(^i1)" d; + inputs= + (if rA = A.Ireg A.GPR0 then [rS] else [rS; rA]); + outputs=[]; }::k +| `Psthx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "sthx ^i0,0,^i1" + else sprintf "sthx ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rS; rB] else [rS; rA; rB]); + outputs=[]; }::k +| `Psthu (rS,d,rA) -> + { empty_ins with + memo=sprintf "sthu ^i0,%i(^i1)" d; + inputs=[rS; rA]; + outputs=[rA]; }::k +| `Psthux (rS,rA,rB) -> + { empty_ins with + memo=sprintf "sthux ^i0,^i1,^i2" ; + inputs=[rS; rA; rB]; + outputs=[rA]; }::k +| `Pstw (rS,d,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stw ^i0,%i(0)" d + else sprintf "stw ^i0,%i(^i1)" d; + inputs= + (if rA = A.Ireg A.GPR0 then [rS] else [rS; rA]); + outputs=[]; }::k +| `Pstwx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stwx ^i0,0,^i1" + else sprintf "stwx ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rS; rB] else [rS; rA; rB]); + outputs=[]; }::k +| `Pstwu (rS,d,rA) -> + { empty_ins with + memo=sprintf "stwu ^i0,%i(^i1)" d; + inputs=[rS; rA]; + outputs=[rA]; }::k +| `Pstwux (rS,rA,rB) -> + { empty_ins with + memo=sprintf "stwux ^i0,^i1,^i2" ; + inputs=[rS; rA; rB]; + outputs=[rA]; }::k +| `Pstd (rS,dS,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "std ^i0,%i(0)" (dS lsr 2) + else sprintf "std ^i0,%i(^i1)" (dS lsr 2); + inputs= + (if rA = A.Ireg A.GPR0 then [rS] else [rS; rA]); + outputs=[]; }::k +| `Pstdx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stdx ^i0,0,^i1" + else sprintf "stdx ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rS; rB] else [rS; rA; rB]); + outputs=[]; }::k +| `Pstdu (rS,dS,rA) -> + { empty_ins with + memo=sprintf "stdu ^i0,%i(^i1)" (dS lsr 2); + inputs=[rS; rA]; + outputs=[rA]; }::k +| `Pstdux (rS,rA,rB) -> + { empty_ins with + memo=sprintf "stdux ^i0,^i1,^i2" ; + inputs=[rS; rA; rB]; + outputs=[rA]; }::k +| `Plq (rTp,dQ,rA,pT) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lq %i,%i(0),%i" rTp dQ pT + else sprintf "lq %i,%i(^i0),%i" rTp dQ pT; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[rA]; }::k +| `Pstq (rSp,dS,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stq %i,%i(0)" rSp (dS lsr 2) + else sprintf "stq %i,%i(^i0)" rSp (dS lsr 2); + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[]; }::k +| `Plhbrx (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lhbrx ^o0,0,^i0" + else sprintf "lhbrx ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Psthbrx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "sthbrx ^i0,0,^i1" + else sprintf "sthbrx ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rS; rB] else [rS; rA; rB]); + outputs=[]; }::k +| `Plwbrx (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lwbrx ^o0,0,^i0" + else sprintf "lwbrx ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Pstwbrx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stwbrx ^i0,0,^i1" + else sprintf "stwbrx ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rS; rB] else [rS; rA; rB]); + outputs=[]; }::k +| `Pldbrx (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "ldbrx ^o0,0,^i0" + else sprintf "ldbrx ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Pstdbrx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stdbrx ^i0,0,^i1" + else sprintf "stdbrx ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rS; rB] else [rS; rA; rB]); + outputs=[]; }::k +| `Plmw (rT,d,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lmw ^o0,%i(0)" d + else sprintf "lmw ^o0,%i(^i0)" d; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[] @ (A.regs_interval rT); }::k +| `Pstmw (rS,d,rA) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stmw ^i0,%i(0)" d + else sprintf "stmw ^i1,%i(^i0)" d; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]) @ (A.regs_interval rS); + outputs=[]; }::k +| `Plswi (rT,rA,nB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lswi %i,0,%i" rT nB + else sprintf "lswi %i,^i0,%i" rT nB; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[]; }::k +| `Plswx (rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lswx ^o0,0,^i0" + else sprintf "lswx ^o0,^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Pstswi (rS,rA,nB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stswi %i,0,%i" rS nB + else sprintf "stswi %i,^i0,%i" rS nB; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[]; }::k +| `Pstswx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stswx %i,0,^i0" rS + else sprintf "stswx %i,^i0,^i1" rS; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[]; }::k +| `Paddi (rT,rA,sI) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "addi ^o0,0,%i" sI + else sprintf "addi ^o0,^i0,%i" sI; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[rT]; }::k +| `Paddis (rT,rA,sI) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "addis ^o0,0,%i" sI + else sprintf "addis ^o0,^i0,%i" sI; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA]); + outputs=[rT]; }::k +| `Padd (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "add ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Padd (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "add. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Padd (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "addo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Padd (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "addo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubf (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subf ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubf (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subf. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubf (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubf (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Paddic (rT,rA,sI) -> + { empty_ins with + memo=sprintf "addic ^o0,^i0,%i" sI; + inputs=[rA]; + outputs=[rT]; }::k +| `Paddicdot (rT,rA,sI) -> + { empty_ins with + memo=sprintf "addic. ^o0,^i0,%i" sI; + inputs=[rA]; + outputs=[rT]; }::k +| `Psubfic (rT,rA,sI) -> + { empty_ins with + memo=sprintf "subfic ^o0,^i0,%i" sI; + inputs=[rA]; + outputs=[rT]; }::k +| `Paddc (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "addc ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Paddc (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "addc. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Paddc (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "addco ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Paddc (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "addco. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubfc (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfc ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubfc (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfc. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubfc (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfco ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubfc (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfco. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Padde (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "adde ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Padde (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "adde. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Padde (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "addeo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Padde (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "addeo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubfe (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfe ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubfe (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfe. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubfe (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfeo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Psubfe (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "subfeo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Paddme (DontSetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "addme ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Paddme (DontSetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "addme. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Paddme (SetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "addmeo ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Paddme (SetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "addmeo. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Psubfme (DontSetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "subfme ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Psubfme (DontSetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "subfme. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Psubfme (SetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "subfmeo ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Psubfme (SetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "subfmeo. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Paddze (DontSetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "addze ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Paddze (DontSetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "addze. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Paddze (SetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "addzeo ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Paddze (SetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "addzeo. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Psubfze (DontSetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "subfze ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Psubfze (DontSetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "subfze. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Psubfze (SetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "subfzeo ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Psubfze (SetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "subfzeo. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Pneg (DontSetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "neg ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Pneg (DontSetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "neg. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Pneg (SetSOOV,DontSetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "nego ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Pneg (SetSOOV,SetCR0,rT,rA) -> + { empty_ins with + memo=sprintf "nego. ^o0,^i0" ; + inputs=[rA]; + outputs=[rT]; }::k +| `Pmulli (rT,rA,sI) -> + { empty_ins with + memo=sprintf "mulli ^o0,^i0,%i" sI; + inputs=[rA]; + outputs=[rT]; }::k +| `Pmullw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mullw ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmullw (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mullw. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmullw (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mullwo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmullw (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mullwo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulhw (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulhw ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulhw (SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulhw. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulhwu (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulhwu ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulhwu (SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulhwu. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divw ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivw (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divw. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivw (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divwo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivw (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divwo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divwu ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivwu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divwu. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivwu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divwuo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivwu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divwuo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivwe (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divwe ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivwe (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divwe. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivwe (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divweo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivwe (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divweo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivweu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divweu ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivweu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divweu. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivweu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divweuo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivweu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divweuo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulld (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulld ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulld (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulld. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulld (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulldo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulld (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulldo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulhd (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulhd ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulhd (SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulhd. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulhdu (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulhdu ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmulhdu (SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "mulhdu. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivd (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divd ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivd (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divd. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivd (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivd (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivdu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdu ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivdu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdu. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivdu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divduo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivdu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divduo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivde (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divde ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivde (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divde. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivde (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdeo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivde (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdeo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivdeu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdeu ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivdeu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdeu. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivdeu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdeuo ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pdivdeu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo=sprintf "divdeuo. ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pcmpi (bF,l,rA,sI) -> + { empty_ins with + memo=sprintf "cmpi %i,%i,^i0,%i" bF l sI; + inputs=[rA]; + outputs=[]; }::k +| `Pcmp (bF,l,rA,rB) -> + { empty_ins with + memo=sprintf "cmp %i,%i,^i0,^i1" bF l; + inputs=[rA; rB]; + outputs=[]; }::k +| `Pcmpli (bF,l,rA,uI) -> + { empty_ins with + memo=sprintf "cmpli %i,%i,^i0,%i" bF l uI; + inputs=[rA]; + outputs=[]; }::k +| `Pcmpl (bF,l,rA,rB) -> + { empty_ins with + memo=sprintf "cmpl %i,%i,^i0,^i1" bF l; + inputs=[rA; rB]; + outputs=[]; }::k +| `Pisel (rT,rA,rB,bC) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "isel ^o0,0,^i0,%i" bC + else sprintf "isel ^o0,^i0,^i1,%i" bC; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Pandi (rA,rS,uI) -> + { empty_ins with + memo=sprintf "andi. ^o0,^i0,%i" uI; + inputs=[rS]; + outputs=[rA]; }::k +| `Pandis (rA,rS,uI) -> + { empty_ins with + memo=sprintf "andis. ^o0,^i0,%i" uI; + inputs=[rS]; + outputs=[rA]; }::k +| `Pori (rA,rS,uI) -> + { empty_ins with + memo=sprintf "ori ^o0,^i0,%i" uI; + inputs=[rS]; + outputs=[rA]; }::k +| `Poris (rA,rS,uI) -> + { empty_ins with + memo=sprintf "oris ^o0,^i0,%i" uI; + inputs=[rS]; + outputs=[rA]; }::k +| `Pxori (rA,rS,uI) -> + { empty_ins with + memo=sprintf "xori ^o0,^i0,%i" uI; + inputs=[rS]; + outputs=[rA]; }::k +| `Pxoris (rA,rS,uI) -> + { empty_ins with + memo=sprintf "xoris ^o0,^i0,%i" uI; + inputs=[rS]; + outputs=[rA]; }::k +| `Pand (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "and ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pand (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "and. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pxor (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "xor ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pxor (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "xor. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pnand (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "nand ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pnand (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "nand. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Por (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "or ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Por (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "or. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pnor (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "nor ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pnor (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "nor. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Peqv (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "eqv ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Peqv (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "eqv. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pandc (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "andc ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pandc (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "andc. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Porc (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "orc ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Porc (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "orc. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pextsb (DontSetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "extsb ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pextsb (SetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "extsb. ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pextsh (DontSetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "extsh ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pextsh (SetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "extsh. ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pcntlzw (DontSetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "cntlzw ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pcntlzw (SetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "cntlzw. ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pcmpb (rA,rS,rB) -> + { empty_ins with + memo=sprintf "cmpb ^o0,%i,^i0" rS; + inputs=[rB]; + outputs=[rA]; }::k +| `Ppopcntb (rA,rS) -> + { empty_ins with + memo=sprintf "popcntb ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Ppopcntw (rA,rS) -> + { empty_ins with + memo=sprintf "popcntw ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pprtyd (rA,rS) -> + { empty_ins with + memo=sprintf "prtyd ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pprtyw (rA,rS) -> + { empty_ins with + memo=sprintf "prtyw ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pextsw (DontSetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "extsw ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pextsw (SetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "extsw. ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pcntlzd (DontSetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "cntlzd ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pcntlzd (SetCR0,rA,rS) -> + { empty_ins with + memo=sprintf "cntlzd. ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Ppopcntd (rA,rS) -> + { empty_ins with + memo=sprintf "popcntd ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pbpermd (rA,rS,rB) -> + { empty_ins with + memo=sprintf "bpermd ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Prlwinm (DontSetCR0,rA,rS,sH,mB,mE) -> + { empty_ins with + memo=sprintf "rlwinm ^o0,^i0,%i,%i,%i" sH mB mE; + inputs=[rS]; + outputs=[rA]; }::k +| `Prlwinm (SetCR0,rA,rS,sH,mB,mE) -> + { empty_ins with + memo=sprintf "rlwinm. ^o0,^i0,%i,%i,%i" sH mB mE; + inputs=[rS]; + outputs=[rA]; }::k +| `Prlwnm (DontSetCR0,rA,rS,rB,mB,mE) -> + { empty_ins with + memo=sprintf "rlwnm ^o0,^i0,^i1,%i,%i" mB mE; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Prlwnm (SetCR0,rA,rS,rB,mB,mE) -> + { empty_ins with + memo=sprintf "rlwnm. ^o0,^i0,^i1,%i,%i" mB mE; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Prlwimi (DontSetCR0,rA,rS,sH,mB,mE) -> + { empty_ins with + memo=sprintf "rlwimi ^i0,^i1,%i,%i,%i" sH mB mE; + inputs=[rA; rS]; + outputs=[rA]; }::k +| `Prlwimi (SetCR0,rA,rS,sH,mB,mE) -> + { empty_ins with + memo=sprintf "rlwimi. ^i0,^i1,%i,%i,%i" sH mB mE; + inputs=[rA; rS]; + outputs=[rA]; }::k +| `Prldicl (DontSetCR0,rA,rS,sH,mB) -> + { empty_ins with + memo=sprintf "rldicl ^o0,^i0,%i,%i" sH mB; + inputs=[rS]; + outputs=[rA]; }::k +| `Prldicl (SetCR0,rA,rS,sH,mB) -> + { empty_ins with + memo=sprintf "rldicl. ^o0,^i0,%i,%i" sH mB; + inputs=[rS]; + outputs=[rA]; }::k +| `Prldicr (DontSetCR0,rA,rS,sH,mE) -> + { empty_ins with + memo=sprintf "rldicr ^o0,^i0,%i,%i" sH mE; + inputs=[rS]; + outputs=[rA]; }::k +| `Prldicr (SetCR0,rA,rS,sH,mE) -> + { empty_ins with + memo=sprintf "rldicr. ^o0,^i0,%i,%i" sH mE; + inputs=[rS]; + outputs=[rA]; }::k +| `Prldic (DontSetCR0,rA,rS,sH,mB) -> + { empty_ins with + memo=sprintf "rldic ^o0,^i0,%i,%i" sH mB; + inputs=[rS]; + outputs=[rA]; }::k +| `Prldic (SetCR0,rA,rS,sH,mB) -> + { empty_ins with + memo=sprintf "rldic. ^o0,^i0,%i,%i" sH mB; + inputs=[rS]; + outputs=[rA]; }::k +| `Prldcl (DontSetCR0,rA,rS,rB,mB) -> + { empty_ins with + memo=sprintf "rldcl ^o0,^i0,^i1,%i" mB; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Prldcl (SetCR0,rA,rS,rB,mB) -> + { empty_ins with + memo=sprintf "rldcl. ^o0,^i0,^i1,%i" mB; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Prldcr (DontSetCR0,rA,rS,rB,mE) -> + { empty_ins with + memo=sprintf "rldcr ^o0,^i0,^i1,%i" mE; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Prldcr (SetCR0,rA,rS,rB,mE) -> + { empty_ins with + memo=sprintf "rldcr. ^o0,^i0,^i1,%i" mE; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Prldimi (DontSetCR0,rA,rS,sH,mB) -> + { empty_ins with + memo=sprintf "rldimi ^i0,^i1,%i,%i" sH mB; + inputs=[rA; rS]; + outputs=[rA]; }::k +| `Prldimi (SetCR0,rA,rS,sH,mB) -> + { empty_ins with + memo=sprintf "rldimi. ^i0,^i1,%i,%i" sH mB; + inputs=[rA; rS]; + outputs=[rA]; }::k +| `Pslw (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "slw ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pslw (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "slw. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psrw (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "srw ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psrw (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "srw. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psrawi (DontSetCR0,rA,rS,sH) -> + { empty_ins with + memo=sprintf "srawi ^o0,^i0,%i" sH; + inputs=[rS]; + outputs=[rA]; }::k +| `Psrawi (SetCR0,rA,rS,sH) -> + { empty_ins with + memo=sprintf "srawi. ^o0,^i0,%i" sH; + inputs=[rS]; + outputs=[rA]; }::k +| `Psraw (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "sraw ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psraw (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "sraw. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psld (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "sld ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psld (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "sld. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psrd (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "srd ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psrd (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "srd. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psradi (DontSetCR0,rA,rS,sH) -> + { empty_ins with + memo=sprintf "sradi ^o0,^i0,%i" sH; + inputs=[rS]; + outputs=[rA]; }::k +| `Psradi (SetCR0,rA,rS,sH) -> + { empty_ins with + memo=sprintf "sradi. ^o0,^i0,%i" sH; + inputs=[rS]; + outputs=[rA]; }::k +| `Psrad (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "srad ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Psrad (SetCR0,rA,rS,rB) -> + { empty_ins with + memo=sprintf "srad. ^o0,^i0,^i1" ; + inputs=[rS; rB]; + outputs=[rA]; }::k +| `Pcdtbcd (rA,rS) -> + { empty_ins with + memo=sprintf "cdtbcd ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Pcbcdtd (rA,rS) -> + { empty_ins with + memo=sprintf "cbcdtd ^o0,^i0" ; + inputs=[rS]; + outputs=[rA]; }::k +| `Paddg6s (rT,rA,rB) -> + { empty_ins with + memo=sprintf "addg6s ^o0,^i0,^i1" ; + inputs=[rA; rB]; + outputs=[rT]; }::k +| `Pmtspr (sPR,rS) -> + { empty_ins with + memo=sprintf "mtspr %i,^i0" sPR; + inputs=[rS]; + outputs=[]; }::k +| `Pmfspr (rT,sPR) -> + { empty_ins with + memo=sprintf "mfspr ^o0,%i" sPR; + inputs=[]; + outputs=[rT]; }::k +| `Pmtcrf (fXM,rS) -> + { empty_ins with + memo=sprintf "mtcrf %i,^i0" fXM; + inputs=[rS]; + outputs=[]; }::k +| `Pmfcr (rT) -> + { empty_ins with + memo=sprintf "mfcr ^o0" ; + inputs=[]; + outputs=[rT]; }::k +| `Pmtocrf (fXM,rS) -> + { empty_ins with + memo=sprintf "mtocrf %i,^i0" fXM; + inputs=[rS]; + outputs=[]; }::k +| `Pmfocrf (rT,fXM) -> + { empty_ins with + memo=sprintf "mfocrf ^o0,%i" fXM; + inputs=[]; + outputs=[rT]; }::k +| `Pmcrxr (bF) -> + { empty_ins with + memo=sprintf "mcrxr %i" bF; + inputs=[]; + outputs=[]; }::k +| `Pdlmzb (DontSetCR0,rA,rS,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "dlmzb 0,^o1,^o2" + else sprintf "dlmzb ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rS; rB]); + outputs=[rA; rS; rB]; }::k +| `Pdlmzb (SetCR0,rA,rS,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "dlmzb. 0,^o1,^o2" + else sprintf "dlmzb. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rS; rB]); + outputs=[rA; rS; rB]; }::k +| `Pmacchw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchw ^o0,0,^o2" + else sprintf "macchw ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchw (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchw. ^o0,0,^o2" + else sprintf "macchw. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchw (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwo ^o0,0,^o2" + else sprintf "macchwo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchw (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwo. ^o0,0,^o2" + else sprintf "macchwo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchws ^o0,0,^o2" + else sprintf "macchws ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchws (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchws. ^o0,0,^o2" + else sprintf "macchws. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchws (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwso ^o0,0,^o2" + else sprintf "macchwso ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchws (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwso. ^o0,0,^o2" + else sprintf "macchwso. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwu ^o0,0,^o2" + else sprintf "macchwu ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchwu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwu. ^o0,0,^o2" + else sprintf "macchwu. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchwu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwuo ^o0,0,^o2" + else sprintf "macchwuo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchwu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwuo. ^o0,0,^o2" + else sprintf "macchwuo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwsu ^o0,0,^o2" + else sprintf "macchwsu ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwsu. ^o0,0,^o2" + else sprintf "macchwsu. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwsuo ^o0,0,^o2" + else sprintf "macchwsuo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmacchwsu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "macchwsuo. ^o0,0,^o2" + else sprintf "macchwsuo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhw ^o0,0,^o2" + else sprintf "machhw ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhw (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhw. ^o0,0,^o2" + else sprintf "machhw. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhw (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwo ^o0,0,^o2" + else sprintf "machhwo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhw (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwo. ^o0,0,^o2" + else sprintf "machhwo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhws ^o0,0,^o2" + else sprintf "machhws ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhws (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhws. ^o0,0,^o2" + else sprintf "machhws. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhws (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwso ^o0,0,^o2" + else sprintf "machhwso ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhws (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwso. ^o0,0,^o2" + else sprintf "machhwso. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwu ^o0,0,^o2" + else sprintf "machhwu ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhwu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwu. ^o0,0,^o2" + else sprintf "machhwu. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhwu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwuo ^o0,0,^o2" + else sprintf "machhwuo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhwu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwuo. ^o0,0,^o2" + else sprintf "machhwuo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwsu ^o0,0,^o2" + else sprintf "machhwsu ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwsu. ^o0,0,^o2" + else sprintf "machhwsu. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwsuo ^o0,0,^o2" + else sprintf "machhwsuo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmachhwsu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "machhwsuo. ^o0,0,^o2" + else sprintf "machhwsuo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhw ^o0,0,^o2" + else sprintf "maclhw ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhw (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhw. ^o0,0,^o2" + else sprintf "maclhw. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhw (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwo ^o0,0,^o2" + else sprintf "maclhwo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhw (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwo. ^o0,0,^o2" + else sprintf "maclhwo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhws ^o0,0,^o2" + else sprintf "maclhws ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhws (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhws. ^o0,0,^o2" + else sprintf "maclhws. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhws (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwso ^o0,0,^o2" + else sprintf "maclhwso ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhws (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwso. ^o0,0,^o2" + else sprintf "maclhwso. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwu ^o0,0,^o2" + else sprintf "maclhwu ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhwu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwu. ^o0,0,^o2" + else sprintf "maclhwu. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhwu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwuo ^o0,0,^o2" + else sprintf "maclhwuo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhwu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwuo. ^o0,0,^o2" + else sprintf "maclhwuo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwsu ^o0,0,^o2" + else sprintf "maclhwsu ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwsu. ^o0,0,^o2" + else sprintf "maclhwsu. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwsuo ^o0,0,^o2" + else sprintf "maclhwsuo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmaclhwsu (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "maclhwsuo. ^o0,0,^o2" + else sprintf "maclhwsuo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmulchw (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mulchw ^o0,0,^o2" + else sprintf "mulchw ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmulchw (SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mulchw. ^o0,0,^o2" + else sprintf "mulchw. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmulchwu (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mulchwu ^o0,0,^o2" + else sprintf "mulchwu ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmulchwu (SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mulchwu. ^o0,0,^o2" + else sprintf "mulchwu. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmulhhw (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mulhhw ^o0,0,^o2" + else sprintf "mulhhw ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmulhhw (SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mulhhw. ^o0,0,^o2" + else sprintf "mulhhw. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmulhhwu (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mulhhwu ^o0,0,^o2" + else sprintf "mulhhwu ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmulhhwu (SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mulhhwu. ^o0,0,^o2" + else sprintf "mulhhwu. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmullhw (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mullhw ^o0,0,^o2" + else sprintf "mullhw ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmullhw (SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mullhw. ^o0,0,^o2" + else sprintf "mullhw. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmullhwu (DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mullhwu ^o0,0,^o2" + else sprintf "mullhwu ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pmullhwu (SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "mullhwu. ^o0,0,^o2" + else sprintf "mullhwu. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmacchw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmacchw ^o0,0,^o2" + else sprintf "nmacchw ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmacchw (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmacchw. ^o0,0,^o2" + else sprintf "nmacchw. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmacchw (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmacchwo ^o0,0,^o2" + else sprintf "nmacchwo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmacchw (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmacchwo. ^o0,0,^o2" + else sprintf "nmacchwo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmacchws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmacchws ^o0,0,^o2" + else sprintf "nmacchws ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmacchws (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmacchws. ^o0,0,^o2" + else sprintf "nmacchws. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmacchws (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmacchwso ^o0,0,^o2" + else sprintf "nmacchwso ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmacchws (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmacchwso. ^o0,0,^o2" + else sprintf "nmacchwso. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmachhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmachhw ^o0,0,^o2" + else sprintf "nmachhw ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmachhw (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmachhw. ^o0,0,^o2" + else sprintf "nmachhw. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmachhw (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmachhwo ^o0,0,^o2" + else sprintf "nmachhwo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmachhw (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmachhwo. ^o0,0,^o2" + else sprintf "nmachhwo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmachhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmachhws ^o0,0,^o2" + else sprintf "nmachhws ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmachhws (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmachhws. ^o0,0,^o2" + else sprintf "nmachhws. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmachhws (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmachhwso ^o0,0,^o2" + else sprintf "nmachhwso ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmachhws (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmachhwso. ^o0,0,^o2" + else sprintf "nmachhwso. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmaclhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmaclhw ^o0,0,^o2" + else sprintf "nmaclhw ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmaclhw (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmaclhw. ^o0,0,^o2" + else sprintf "nmaclhw. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmaclhw (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmaclhwo ^o0,0,^o2" + else sprintf "nmaclhwo ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmaclhw (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmaclhwo. ^o0,0,^o2" + else sprintf "nmaclhwo. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmaclhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmaclhws ^o0,0,^o2" + else sprintf "nmaclhws ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmaclhws (DontSetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmaclhws. ^o0,0,^o2" + else sprintf "nmaclhws. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmaclhws (SetSOOV,DontSetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmaclhwso ^o0,0,^o2" + else sprintf "nmaclhwso ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Pnmaclhws (SetSOOV,SetCR0,rT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "nmaclhwso. ^o0,0,^o2" + else sprintf "nmaclhwso. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rT; rA; rB]); + outputs=[rT; rA; rB]; }::k +| `Picbi (rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "icbi 0,^o1" + else sprintf "icbi ^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rB]); + outputs=[rA; rB]; }::k +| `Picbt (cT,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "icbt %i,0,^o1" cT + else sprintf "icbt %i,^i0,^i1" cT; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rB]); + outputs=[rA; rB]; }::k +| `Pdcba (rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "dcba 0,^o1" + else sprintf "dcba ^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rB]); + outputs=[rA; rB]; }::k +| `Pdcbt (rA,rB,tH) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "dcbt 0,^o1,%i" tH + else sprintf "dcbt ^i0,^i1,%i" tH; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rB]); + outputs=[rA; rB]; }::k +| `Pdcbtst (rA,rB,tH) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "dcbtst 0,^o1,%i" tH + else sprintf "dcbtst ^i0,^i1,%i" tH; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rB]); + outputs=[rA; rB]; }::k +| `Pdcbz (rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "dcbz 0,^o1" + else sprintf "dcbz ^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rB]); + outputs=[rA; rB]; }::k +| `Pdcbst (rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "dcbst 0,^o1" + else sprintf "dcbst ^i0,^i1" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rB]); + outputs=[rA; rB]; }::k +| `Pdcbf (rA,rB,l) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "dcbf 0,^o1,%i" l + else sprintf "dcbf ^i0,^i1,%i" l; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rA; rB]); + outputs=[rA; rB]; }::k +| `Pisync -> + { empty_ins with + memo=sprintf "isync " ; + inputs=[]; + outputs=[]; }::k +| `Plbarx (rT,rA,rB,eH) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lbarx ^o0,0,^i0,%i" eH + else sprintf "lbarx ^o0,^i0,^i1,%i" eH; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Plharx (rT,rA,rB,eH) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lharx ^o0,0,^i0,%i" eH + else sprintf "lharx ^o0,^i0,^i1,%i" eH; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Plwarx (rT,rA,rB,eH) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "lwarx ^o0,0,^i0,%i" eH + else sprintf "lwarx ^o0,^i0,^i1,%i" eH; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Pstbcx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stbcx. ^o0,0,^o2" + else sprintf "stbcx. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rS; rA; rB]); + outputs=[rS; rA; rB]; }::k +| `Psthcx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "sthcx. ^o0,0,^o2" + else sprintf "sthcx. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rS; rA; rB]); + outputs=[rS; rA; rB]; }::k +| `Pstwcx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stwcx. ^o0,0,^o2" + else sprintf "stwcx. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rS; rA; rB]); + outputs=[rS; rA; rB]; }::k +| `Pldarx (rT,rA,rB,eH) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "ldarx ^o0,0,^i0,%i" eH + else sprintf "ldarx ^o0,^i0,^i1,%i" eH; + inputs= + (if rA = A.Ireg A.GPR0 then [rB] else [rA; rB]); + outputs=[rT]; }::k +| `Pstdcx (rS,rA,rB) -> + { empty_ins with + memo= if rA = A.Ireg A.GPR0 + then sprintf "stdcx. ^o0,0,^o2" + else sprintf "stdcx. ^i0,^i1,^i2" ; + inputs= + (if rA = A.Ireg A.GPR0 then [] else [rS; rA; rB]); + outputs=[rS; rA; rB]; }::k +| `Psync (l) -> + { empty_ins with + memo=sprintf "sync %i" l; + inputs=[]; + outputs=[]; }::k +| `Peieio -> + { empty_ins with + memo=sprintf "eieio " ; + inputs=[]; + outputs=[]; }::k +| `Pwait (wC) -> + { empty_ins with + memo=sprintf "wait %i" wC; + inputs=[]; + outputs=[]; }::k diff --git a/power/gen/fold.gen b/power/gen/fold.gen new file mode 100644 index 00000000..acec75ac --- /dev/null +++ b/power/gen/fold.gen @@ -0,0 +1,368 @@ +| `Pb (DontSetAA,DontSetLK,target_addr) -> y_reg, y_sreg +| `Pb (SetAA,DontSetLK,target_addr) -> y_reg, y_sreg +| `Pb (DontSetAA,SetLK,target_addr) -> y_reg, y_sreg +| `Pb (SetAA,SetLK,target_addr) -> y_reg, y_sreg +| `Pbc (DontSetAA,DontSetLK,bO,bI,target_addr) -> y_reg, y_sreg +| `Pbc (SetAA,DontSetLK,bO,bI,target_addr) -> y_reg, y_sreg +| `Pbc (DontSetAA,SetLK,bO,bI,target_addr) -> y_reg, y_sreg +| `Pbc (SetAA,SetLK,bO,bI,target_addr) -> y_reg, y_sreg +| `Pbclr (DontSetLK,bO,bI,bH) -> y_reg, y_sreg +| `Pbclr (SetLK,bO,bI,bH) -> y_reg, y_sreg +| `Pbcctr (DontSetLK,bO,bI,bH) -> y_reg, y_sreg +| `Pbcctr (SetLK,bO,bI,bH) -> y_reg, y_sreg +| `Pcrand (bT,bA,bB) -> y_reg, y_sreg +| `Pcrnand (bT,bA,bB) -> y_reg, y_sreg +| `Pcror (bT,bA,bB) -> y_reg, y_sreg +| `Pcrxor (bT,bA,bB) -> y_reg, y_sreg +| `Pcrnor (bT,bA,bB) -> y_reg, y_sreg +| `Pcreqv (bT,bA,bB) -> y_reg, y_sreg +| `Pcrandc (bT,bA,bB) -> y_reg, y_sreg +| `Pcrorc (bT,bA,bB) -> y_reg, y_sreg +| `Pmcrf (bF,bFA) -> y_reg, y_sreg +| `Psc (lEV) -> y_reg, y_sreg +| `Pscv (lEV) -> y_reg, y_sreg +| `Plbz (rT,d,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Plbzx (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plbzu (rT,d,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Plbzux (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plhz (rT,d,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Plhzx (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plhzu (rT,d,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Plhzux (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plha (rT,d,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Plhax (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plhau (rT,d,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Plhaux (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plwz (rT,d,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Plwzx (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plwzu (rT,d,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Plwzux (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plwa (rT,dS,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Plwax (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plwaux (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pld (rT,dS,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Pldx (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pldu (rT,dS,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Pldux (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pstb (rS,d,rA) -> fold_reg rA (fold_reg rS (y_reg, y_sreg)) +| `Pstbx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Pstbu (rS,d,rA) -> fold_reg rA (fold_reg rS (y_reg, y_sreg)) +| `Pstbux (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Psth (rS,d,rA) -> fold_reg rA (fold_reg rS (y_reg, y_sreg)) +| `Psthx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Psthu (rS,d,rA) -> fold_reg rA (fold_reg rS (y_reg, y_sreg)) +| `Psthux (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Pstw (rS,d,rA) -> fold_reg rA (fold_reg rS (y_reg, y_sreg)) +| `Pstwx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Pstwu (rS,d,rA) -> fold_reg rA (fold_reg rS (y_reg, y_sreg)) +| `Pstwux (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Pstd (rS,dS,rA) -> fold_reg rA (fold_reg rS (y_reg, y_sreg)) +| `Pstdx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Pstdu (rS,dS,rA) -> fold_reg rA (fold_reg rS (y_reg, y_sreg)) +| `Pstdux (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Plq (rTp,dQ,rA,pT) -> fold_reg rA (y_reg, y_sreg) +| `Pstq (rSp,dS,rA) -> fold_reg rA (y_reg, y_sreg) +| `Plhbrx (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psthbrx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Plwbrx (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pstwbrx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Pldbrx (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pstdbrx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Plmw (rT,d,rA) -> fold_reg rA (List.fold_right fold_reg (regs_interval rT) (y_reg, y_sreg)) +| `Pstmw (rS,d,rA) -> fold_reg rA (List.fold_right fold_reg (regs_interval rS) (y_reg, y_sreg)) +| `Plswi (rT,rA,nB) -> fold_reg rA (y_reg, y_sreg) +| `Plswx (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pstswi (rS,rA,nB) -> fold_reg rA (y_reg, y_sreg) +| `Pstswx (rS,rA,rB) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Paddi (rT,rA,sI) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddis (rT,rA,sI) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Padd (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Padd (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Padd (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Padd (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubf (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubf (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubf (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubf (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Paddic (rT,rA,sI) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddicdot (rT,rA,sI) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Psubfic (rT,rA,sI) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddc (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Paddc (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Paddc (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Paddc (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubfc (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubfc (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubfc (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubfc (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Padde (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Padde (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Padde (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Padde (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubfe (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubfe (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubfe (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Psubfe (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Paddme (DontSetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddme (DontSetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddme (SetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddme (SetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Psubfme (DontSetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Psubfme (DontSetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Psubfme (SetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Psubfme (SetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddze (DontSetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddze (DontSetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddze (SetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Paddze (SetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Psubfze (DontSetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Psubfze (DontSetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Psubfze (SetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Psubfze (SetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Pneg (DontSetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Pneg (DontSetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Pneg (SetSOOV,DontSetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Pneg (SetSOOV,SetCR0,rT,rA) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Pmulli (rT,rA,sI) -> fold_reg rA (fold_reg rT (y_reg, y_sreg)) +| `Pmullw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmullw (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmullw (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmullw (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhw (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhw (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhwu (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhwu (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivw (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivw (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivw (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivwu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivwu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivwu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivwe (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivwe (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivwe (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivwe (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivweu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivweu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivweu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivweu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulld (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulld (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulld (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulld (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhd (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhd (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhdu (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhdu (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivd (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivd (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivd (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivd (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivdu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivdu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivdu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivdu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivde (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivde (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivde (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivde (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivdeu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivdeu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivdeu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pdivdeu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pcmpi (bF,l,rA,sI) -> fold_reg rA (y_reg, y_sreg) +| `Pcmp (bF,l,rA,rB) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Pcmpli (bF,l,rA,uI) -> fold_reg rA (y_reg, y_sreg) +| `Pcmpl (bF,l,rA,rB) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Pisel (rT,rA,rB,bC) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pandi (rA,rS,uI) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pandis (rA,rS,uI) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pori (rA,rS,uI) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Poris (rA,rS,uI) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pxori (rA,rS,uI) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pxoris (rA,rS,uI) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pand (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pand (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pxor (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pxor (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pnand (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pnand (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Por (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Por (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pnor (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pnor (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Peqv (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Peqv (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pandc (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pandc (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Porc (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Porc (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pextsb (DontSetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pextsb (SetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pextsh (DontSetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pextsh (SetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pcntlzw (DontSetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pcntlzw (SetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pcmpb (rA,rS,rB) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Ppopcntb (rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Ppopcntw (rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pprtyd (rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pprtyw (rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pextsw (DontSetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pextsw (SetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pcntlzd (DontSetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pcntlzd (SetCR0,rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Ppopcntd (rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pbpermd (rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Prlwinm (DontSetCR0,rA,rS,sH,mB,mE) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prlwinm (SetCR0,rA,rS,sH,mB,mE) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prlwnm (DontSetCR0,rA,rS,rB,mB,mE) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Prlwnm (SetCR0,rA,rS,rB,mB,mE) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Prlwimi (DontSetCR0,rA,rS,sH,mB,mE) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prlwimi (SetCR0,rA,rS,sH,mB,mE) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prldicl (DontSetCR0,rA,rS,sH,mB) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prldicl (SetCR0,rA,rS,sH,mB) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prldicr (DontSetCR0,rA,rS,sH,mE) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prldicr (SetCR0,rA,rS,sH,mE) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prldic (DontSetCR0,rA,rS,sH,mB) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prldic (SetCR0,rA,rS,sH,mB) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prldcl (DontSetCR0,rA,rS,rB,mB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Prldcl (SetCR0,rA,rS,rB,mB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Prldcr (DontSetCR0,rA,rS,rB,mE) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Prldcr (SetCR0,rA,rS,rB,mE) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Prldimi (DontSetCR0,rA,rS,sH,mB) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Prldimi (SetCR0,rA,rS,sH,mB) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pslw (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pslw (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psrw (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psrw (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psrawi (DontSetCR0,rA,rS,sH) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Psrawi (SetCR0,rA,rS,sH) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Psraw (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psraw (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psld (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psld (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psrd (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psrd (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psradi (DontSetCR0,rA,rS,sH) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Psradi (SetCR0,rA,rS,sH) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Psrad (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Psrad (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pcdtbcd (rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Pcbcdtd (rA,rS) -> fold_reg rS (fold_reg rA (y_reg, y_sreg)) +| `Paddg6s (rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmtspr (sPR,rS) -> fold_reg rS (y_reg, y_sreg) +| `Pmfspr (rT,sPR) -> fold_reg rT (y_reg, y_sreg) +| `Pmtcrf (fXM,rS) -> fold_reg rS (y_reg, y_sreg) +| `Pmfcr (rT) -> fold_reg rT (y_reg, y_sreg) +| `Pmtocrf (fXM,rS) -> fold_reg rS (y_reg, y_sreg) +| `Pmfocrf (rT,fXM) -> fold_reg rT (y_reg, y_sreg) +| `Pmcrxr (bF) -> y_reg, y_sreg +| `Pdlmzb (DontSetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pdlmzb (SetCR0,rA,rS,rB) -> fold_reg rB (fold_reg rS (fold_reg rA (y_reg, y_sreg))) +| `Pmacchw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchw (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchw (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchw (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchws (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchws (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchws (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchwu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchwu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchwu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmacchwsu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhw (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhw (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhw (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhws (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhws (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhws (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhwu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhwu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhwu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmachhwsu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhw (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhw (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhw (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhws (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhws (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhws (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhwu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhwu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhwu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmaclhwsu (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulchw (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulchw (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulchwu (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulchwu (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhhw (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhhw (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhhwu (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmulhhwu (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmullhw (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmullhw (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmullhwu (DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pmullhwu (SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmacchw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmacchw (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmacchw (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmacchw (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmacchws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmacchws (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmacchws (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmacchws (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmachhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmachhw (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmachhw (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmachhw (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmachhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmachhws (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmachhws (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmachhws (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmaclhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmaclhw (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmaclhw (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmaclhw (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmaclhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmaclhws (DontSetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmaclhws (SetSOOV,DontSetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pnmaclhws (SetSOOV,SetCR0,rT,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Picbi (rA,rB) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Picbt (cT,rA,rB) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Pdcba (rA,rB) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Pdcbt (rA,rB,tH) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Pdcbtst (rA,rB,tH) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Pdcbz (rA,rB) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Pdcbst (rA,rB) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Pdcbf (rA,rB,l) -> fold_reg rB (fold_reg rA (y_reg, y_sreg)) +| `Pisync -> y_reg, y_sreg +| `Plbarx (rT,rA,rB,eH) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plharx (rT,rA,rB,eH) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Plwarx (rT,rA,rB,eH) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pstbcx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Psthcx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Pstwcx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Pldarx (rT,rA,rB,eH) -> fold_reg rB (fold_reg rA (fold_reg rT (y_reg, y_sreg))) +| `Pstdcx (rS,rA,rB) -> fold_reg rB (fold_reg rA (fold_reg rS (y_reg, y_sreg))) +| `Psync (l) -> y_reg, y_sreg +| `Peieio -> y_reg, y_sreg +| `Pwait (wC) -> y_reg, y_sreg diff --git a/power/gen/herdtools_ast_to_shallow_ast.gen b/power/gen/herdtools_ast_to_shallow_ast.gen new file mode 100644 index 00000000..e1de51f7 --- /dev/null +++ b/power/gen/herdtools_ast_to_shallow_ast.gen @@ -0,0 +1,1312 @@ + | `Pb(setaa0, setlk1, k2) -> + B + (Sail_values.to_vec0 true (Nat_big_num.of_int 24,Nat_big_num.of_int (trans_li_setaa_setlk_k setaa0 setlk1 k2)), + int_to_bit (trans_aa setaa0), + int_to_bit (trans_lk setlk1)) + + | `Pbc(setaa0, setlk1, k2, k3, k4) -> + Bc + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k3), + Sail_values.to_vec0 true (Nat_big_num.of_int 14,Nat_big_num.of_int (trans_bd_setaa_setlk_k_k_k setaa0 setlk1 k2 k3 k4)), + int_to_bit (trans_aa setaa0), + int_to_bit (trans_lk setlk1)) + + | `Pbclr(setlk0, k1, k2, k3) -> + Bclr + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2), + Sail_values.to_vec0 true (Nat_big_num.of_int 2,Nat_big_num.of_int k3), + int_to_bit (trans_lk setlk0)) + + | `Pbcctr(setlk0, k1, k2, k3) -> + Bcctr + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2), + Sail_values.to_vec0 true (Nat_big_num.of_int 2,Nat_big_num.of_int k3), + int_to_bit (trans_lk setlk0)) + + | `Pcrand(k0, k1, k2) -> + Crand + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Pcrnand(k0, k1, k2) -> + Crnand + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Pcror(k0, k1, k2) -> + Cror + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Pcrxor(k0, k1, k2) -> + Crxor + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Pcrnor(k0, k1, k2) -> + Crnor + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Pcreqv(k0, k1, k2) -> + Creqv + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Pcrandc(k0, k1, k2) -> + Crandc + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Pcrorc(k0, k1, k2) -> + Crorc + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Pmcrf(crindex0, k1) -> + Mcrf + (Sail_values.to_vec0 true (Nat_big_num.of_int 3,Nat_big_num.of_int crindex0), + Sail_values.to_vec0 true (Nat_big_num.of_int 3,Nat_big_num.of_int k1)) + + | `Psc(k0) -> + Sc + (Sail_values.to_vec0 true (Nat_big_num.of_int 7,Nat_big_num.of_int k0)) + + | `Pscv(k0) -> + Scv + (Sail_values.to_vec0 true (Nat_big_num.of_int 7,Nat_big_num.of_int k0)) + + | `Plbz(reg0, k1, reg2) -> + Lbz + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Plbzx(reg0, reg1, reg2) -> + Lbzx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plbzu(reg0, k1, reg2) -> + Lbzu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Plbzux(reg0, reg1, reg2) -> + Lbzux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plhz(reg0, k1, reg2) -> + Lhz + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Plhzx(reg0, reg1, reg2) -> + Lhzx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plhzu(reg0, k1, reg2) -> + Lhzu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Plhzux(reg0, reg1, reg2) -> + Lhzux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plha(reg0, k1, reg2) -> + Lha + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Plhax(reg0, reg1, reg2) -> + Lhax + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plhau(reg0, k1, reg2) -> + Lhau + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Plhaux(reg0, reg1, reg2) -> + Lhaux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plwz(reg0, k1, reg2) -> + Lwz + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Plwzx(reg0, reg1, reg2) -> + Lwzx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plwzu(reg0, k1, reg2) -> + Lwzu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Plwzux(reg0, reg1, reg2) -> + Lwzux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plwa(reg0, ds1, reg2) -> + Lwa + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 14,Nat_big_num.of_int ds1)) + + | `Plwax(reg0, reg1, reg2) -> + Lwax + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plwaux(reg0, reg1, reg2) -> + Lwaux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pld(reg0, ds1, reg2) -> + Ld + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 14,Nat_big_num.of_int ds1)) + + | `Pldx(reg0, reg1, reg2) -> + Ldx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pldu(reg0, ds1, reg2) -> + Ldu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 14,Nat_big_num.of_int ds1)) + + | `Pldux(reg0, reg1, reg2) -> + Ldux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstb(reg0, k1, reg2) -> + Stb + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Pstbx(reg0, reg1, reg2) -> + Stbx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstbu(reg0, k1, reg2) -> + Stbu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Pstbux(reg0, reg1, reg2) -> + Stbux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Psth(reg0, k1, reg2) -> + Sth + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Psthx(reg0, reg1, reg2) -> + Sthx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Psthu(reg0, k1, reg2) -> + Sthu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Psthux(reg0, reg1, reg2) -> + Sthux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstw(reg0, k1, reg2) -> + Stw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Pstwx(reg0, reg1, reg2) -> + Stwx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstwu(reg0, k1, reg2) -> + Stwu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Pstwux(reg0, reg1, reg2) -> + Stwux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstd(reg0, ds1, reg2) -> + Std + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 14,Nat_big_num.of_int ds1)) + + | `Pstdx(reg0, reg1, reg2) -> + Stdx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstdu(reg0, ds1, reg2) -> + Stdu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 14,Nat_big_num.of_int ds1)) + + | `Pstdux(reg0, reg1, reg2) -> + Stdux + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plq(k0, k1, reg2, k3) -> + Lq + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 12,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 4,Nat_big_num.of_int k3)) + + | `Pstq(k0, ds1, reg2) -> + Stq + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 14,Nat_big_num.of_int ds1)) + + | `Plhbrx(reg0, reg1, reg2) -> + Lhbrx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Psthbrx(reg0, reg1, reg2) -> + Sthbrx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plwbrx(reg0, reg1, reg2) -> + Lwbrx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstwbrx(reg0, reg1, reg2) -> + Stwbrx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pldbrx(reg0, reg1, reg2) -> + Ldbrx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstdbrx(reg0, reg1, reg2) -> + Stdbrx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Plmw(reg0, k1, reg2) -> + Lmw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Pstmw(reg0, k1, reg2) -> + Stmw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k1)) + + | `Plswi(k0, reg1, k2) -> + Lswi + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Plswx(reg0, reg1, reg2) -> + Lswx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstswi(k0, reg1, k2) -> + Stswi + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2)) + + | `Pstswx(k0, reg1, reg2) -> + Stswx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Paddi(reg0, reg1, k2) -> + Addi + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Paddis(reg0, reg1, k2) -> + Addis + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Padd(setsoov0, setcr01, reg2, reg3, reg4) -> + Add + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Psubf(setsoov0, setcr01, reg2, reg3, reg4) -> + Subf + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Paddic(reg0, reg1, k2) -> + Addic + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Paddicdot(reg0, reg1, k2) -> + AddicDot + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Psubfic(reg0, reg1, k2) -> + Subfic + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Paddc(setsoov0, setcr01, reg2, reg3, reg4) -> + Addc + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Psubfc(setsoov0, setcr01, reg2, reg3, reg4) -> + Subfc + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Padde(setsoov0, setcr01, reg2, reg3, reg4) -> + Adde + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Psubfe(setsoov0, setcr01, reg2, reg3, reg4) -> + Subfe + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Paddme(setsoov0, setcr01, reg2, reg3) -> + Addme + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Psubfme(setsoov0, setcr01, reg2, reg3) -> + Subfme + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Paddze(setsoov0, setcr01, reg2, reg3) -> + Addze + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Psubfze(setsoov0, setcr01, reg2, reg3) -> + Subfze + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pneg(setsoov0, setcr01, reg2, reg3) -> + Neg + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmulli(reg0, reg1, k2) -> + Mulli + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Pmullw(setsoov0, setcr01, reg2, reg3, reg4) -> + Mullw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmulhw(setcr00, reg1, reg2, reg3) -> + Mulhw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pmulhwu(setcr00, reg1, reg2, reg3) -> + Mulhwu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pdivw(setsoov0, setcr01, reg2, reg3, reg4) -> + Divw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pdivwu(setsoov0, setcr01, reg2, reg3, reg4) -> + Divwu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pdivwe(setsoov0, setcr01, reg2, reg3, reg4) -> + Divwe + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pdivweu(setsoov0, setcr01, reg2, reg3, reg4) -> + Divweu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmulld(setsoov0, setcr01, reg2, reg3, reg4) -> + Mulld + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmulhd(setcr00, reg1, reg2, reg3) -> + Mulhd + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pmulhdu(setcr00, reg1, reg2, reg3) -> + Mulhdu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pdivd(setsoov0, setcr01, reg2, reg3, reg4) -> + Divd + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pdivdu(setsoov0, setcr01, reg2, reg3, reg4) -> + Divdu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pdivde(setsoov0, setcr01, reg2, reg3, reg4) -> + Divde + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pdivdeu(setsoov0, setcr01, reg2, reg3, reg4) -> + Divdeu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pcmpi(crindex0, k1, reg2, k3) -> + Cmpi + (Sail_values.to_vec0 true (Nat_big_num.of_int 3,Nat_big_num.of_int crindex0), + int_to_bit k1, + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k3)) + + | `Pcmp(crindex0, k1, reg2, reg3) -> + Cmp + (Sail_values.to_vec0 true (Nat_big_num.of_int 3,Nat_big_num.of_int crindex0), + int_to_bit k1, + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3))) + + | `Pcmpli(crindex0, k1, reg2, k3) -> + Cmpli + (Sail_values.to_vec0 true (Nat_big_num.of_int 3,Nat_big_num.of_int crindex0), + int_to_bit k1, + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k3)) + + | `Pcmpl(crindex0, k1, reg2, reg3) -> + Cmpl + (Sail_values.to_vec0 true (Nat_big_num.of_int 3,Nat_big_num.of_int crindex0), + int_to_bit k1, + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3))) + + | `Pisel(reg0, reg1, reg2, k3) -> + Isel + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k3)) + + | `Pandi(reg0, reg1, k2) -> + Andi + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Pandis(reg0, reg1, k2) -> + Andis + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Pori(reg0, reg1, k2) -> + Ori + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Poris(reg0, reg1, k2) -> + Oris + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Pxori(reg0, reg1, k2) -> + Xori + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Pxoris(reg0, reg1, k2) -> + Xoris + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 16,Nat_big_num.of_int k2)) + + | `Pand(setcr00, reg1, reg2, reg3) -> + And + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pxor(setcr00, reg1, reg2, reg3) -> + Xor + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pnand(setcr00, reg1, reg2, reg3) -> + Nand + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Por(setcr00, reg1, reg2, reg3) -> + Or + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pnor(setcr00, reg1, reg2, reg3) -> + Nor + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Peqv(setcr00, reg1, reg2, reg3) -> + Eqv + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pandc(setcr00, reg1, reg2, reg3) -> + Andc + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Porc(setcr00, reg1, reg2, reg3) -> + Orc + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pextsb(setcr00, reg1, reg2) -> + Extsb + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + int_to_bit (trans_cr0 setcr00)) + + | `Pextsh(setcr00, reg1, reg2) -> + Extsh + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + int_to_bit (trans_cr0 setcr00)) + + | `Pcntlzw(setcr00, reg1, reg2) -> + Cntlzw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + int_to_bit (trans_cr0 setcr00)) + + | `Pcmpb(reg0, k1, reg2) -> + Cmpb + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k1), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Ppopcntb(reg0, reg1) -> + Popcntb + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0))) + + | `Ppopcntw(reg0, reg1) -> + Popcntw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0))) + + | `Pprtyd(reg0, reg1) -> + Prtyd + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0))) + + | `Pprtyw(reg0, reg1) -> + Prtyw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0))) + + | `Pextsw(setcr00, reg1, reg2) -> + Extsw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + int_to_bit (trans_cr0 setcr00)) + + | `Pcntlzd(setcr00, reg1, reg2) -> + Cntlzd + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + int_to_bit (trans_cr0 setcr00)) + + | `Ppopcntd(reg0, reg1) -> + Popcntd + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0))) + + | `Pbpermd(reg0, reg1, reg2) -> + Bpermd + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Prlwinm(setcr00, reg1, reg2, k3, k4, k5) -> + Rlwinm + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k3), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k4), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k5), + int_to_bit (trans_cr0 setcr00)) + + | `Prlwnm(setcr00, reg1, reg2, reg3, k4, k5) -> + Rlwnm + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k4), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k5), + int_to_bit (trans_cr0 setcr00)) + + | `Prlwimi(setcr00, reg1, reg2, k3, k4, k5) -> + Rlwimi + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k3), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k4), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k5), + int_to_bit (trans_cr0 setcr00)) + + | `Prldicl(setcr00, reg1, reg2, k3, k4) -> + Rldicl + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k3), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k4), + int_to_bit (trans_cr0 setcr00)) + + | `Prldicr(setcr00, reg1, reg2, k3, k4) -> + Rldicr + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k3), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k4), + int_to_bit (trans_cr0 setcr00)) + + | `Prldic(setcr00, reg1, reg2, k3, k4) -> + Rldic + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k3), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k4), + int_to_bit (trans_cr0 setcr00)) + + | `Prldcl(setcr00, reg1, reg2, reg3, k4) -> + Rldcl + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k4), + int_to_bit (trans_cr0 setcr00)) + + | `Prldcr(setcr00, reg1, reg2, reg3, k4) -> + Rldcr + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k4), + int_to_bit (trans_cr0 setcr00)) + + | `Prldimi(setcr00, reg1, reg2, k3, k4) -> + Rldimi + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k3), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k4), + int_to_bit (trans_cr0 setcr00)) + + | `Pslw(setcr00, reg1, reg2, reg3) -> + Slw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Psrw(setcr00, reg1, reg2, reg3) -> + Srw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Psrawi(setcr00, reg1, reg2, k3) -> + Srawi + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k3), + int_to_bit (trans_cr0 setcr00)) + + | `Psraw(setcr00, reg1, reg2, reg3) -> + Sraw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Psld(setcr00, reg1, reg2, reg3) -> + Sld + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Psrd(setcr00, reg1, reg2, reg3) -> + Srd + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Psradi(setcr00, reg1, reg2, k3) -> + Sradi + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 6,Nat_big_num.of_int k3), + int_to_bit (trans_cr0 setcr00)) + + | `Psrad(setcr00, reg1, reg2, reg3) -> + Srad + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pcdtbcd(reg0, reg1) -> + Cdtbcd + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0))) + + | `Pcbcdtd(reg0, reg1) -> + Cbcdtd + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0))) + + | `Paddg6s(reg0, reg1, reg2) -> + Addg6s + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pmtspr(k0, reg1) -> + Mtspr + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 10,Nat_big_num.of_int k0)) + + | `Pmfspr(reg0, k1) -> + Mfspr + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 10,Nat_big_num.of_int k1)) + + | `Pmtcrf(crmask0, reg1) -> + Mtcrf + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 8,Nat_big_num.of_int crmask0)) + + | `Pmfcr(reg0) -> + Mfcr + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0))) + + | `Pmtocrf(crmask0, reg1) -> + Mtocrf + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 8,Nat_big_num.of_int crmask0)) + + | `Pmfocrf(reg0, crmask1) -> + Mfocrf + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 8,Nat_big_num.of_int crmask1)) + + | `Pmcrxr(crindex0) -> + Mcrxr + (Sail_values.to_vec0 true (Nat_big_num.of_int 3,Nat_big_num.of_int crindex0)) + + | `Pdlmzb(setcr00, reg1, reg2, reg3) -> + Dlmzb + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pmacchw(setsoov0, setcr01, reg2, reg3, reg4) -> + Macchw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmacchws(setsoov0, setcr01, reg2, reg3, reg4) -> + Macchws + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmacchwu(setsoov0, setcr01, reg2, reg3, reg4) -> + Macchwu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmacchwsu(setsoov0, setcr01, reg2, reg3, reg4) -> + Macchwsu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmachhw(setsoov0, setcr01, reg2, reg3, reg4) -> + Machhw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmachhws(setsoov0, setcr01, reg2, reg3, reg4) -> + Machhws + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmachhwu(setsoov0, setcr01, reg2, reg3, reg4) -> + Machhwu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmachhwsu(setsoov0, setcr01, reg2, reg3, reg4) -> + Machhwsu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmaclhw(setsoov0, setcr01, reg2, reg3, reg4) -> + Maclhw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmaclhws(setsoov0, setcr01, reg2, reg3, reg4) -> + Maclhws + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmaclhwu(setsoov0, setcr01, reg2, reg3, reg4) -> + Maclhwu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmaclhwsu(setsoov0, setcr01, reg2, reg3, reg4) -> + Maclhwsu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pmulchw(setcr00, reg1, reg2, reg3) -> + Mulchw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pmulchwu(setcr00, reg1, reg2, reg3) -> + Mulchwu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pmulhhw(setcr00, reg1, reg2, reg3) -> + Mulhhw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pmulhhwu(setcr00, reg1, reg2, reg3) -> + Mulhhwu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pmullhw(setcr00, reg1, reg2, reg3) -> + Mullhw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pmullhwu(setcr00, reg1, reg2, reg3) -> + Mullhwu + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + int_to_bit (trans_cr0 setcr00)) + + | `Pnmacchw(setsoov0, setcr01, reg2, reg3, reg4) -> + Nmacchw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pnmacchws(setsoov0, setcr01, reg2, reg3, reg4) -> + Nmacchws + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pnmachhw(setsoov0, setcr01, reg2, reg3, reg4) -> + Nmachhw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pnmachhws(setsoov0, setcr01, reg2, reg3, reg4) -> + Nmachhws + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pnmaclhw(setsoov0, setcr01, reg2, reg3, reg4) -> + Nmaclhw + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Pnmaclhws(setsoov0, setcr01, reg2, reg3, reg4) -> + Nmaclhws + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg3)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg4)), + int_to_bit (trans_soov setsoov0), + int_to_bit (trans_cr0 setcr01)) + + | `Picbi(reg0, reg1) -> + Icbi + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1))) + + | `Picbt(k0, reg1, reg2) -> + Icbt + (Sail_values.to_vec0 true (Nat_big_num.of_int 4,Nat_big_num.of_int k0), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pdcba(reg0, reg1) -> + Dcba + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1))) + + | `Pdcbt(reg0, reg1, k2) -> + Dcbt + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1))) + + | `Pdcbtst(reg0, reg1, k2) -> + Dcbtst + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int k2), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1))) + + | `Pdcbz(reg0, reg1) -> + Dcbz + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1))) + + | `Pdcbst(reg0, reg1) -> + Dcbst + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1))) + + | `Pdcbf(reg0, reg1, k2) -> + Dcbf + (Sail_values.to_vec0 true (Nat_big_num.of_int 2,Nat_big_num.of_int k2), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1))) + + | `Pisync -> + Isync + + | `Plbarx(reg0, reg1, reg2, k3) -> + Lbarx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + int_to_bit k3) + + | `Plharx(reg0, reg1, reg2, k3) -> + Lharx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + int_to_bit k3) + + | `Plwarx(reg0, reg1, reg2, k3) -> + Lwarx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + int_to_bit k3) + + | `Pstbcx(reg0, reg1, reg2) -> + Stbcx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Psthcx(reg0, reg1, reg2) -> + Sthcx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pstwcx(reg0, reg1, reg2) -> + Stwcx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Pldarx(reg0, reg1, reg2, k3) -> + Ldarx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2)), + int_to_bit k3) + + | `Pstdcx(reg0, reg1, reg2) -> + Stdcx + (Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg0)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg1)), + Sail_values.to_vec0 true (Nat_big_num.of_int 5,Nat_big_num.of_int (int_of_reg reg2))) + + | `Psync(k0) -> + Sync + (Sail_values.to_vec0 true (Nat_big_num.of_int 2,Nat_big_num.of_int k0)) + + | `Peieio -> + Eieio + + | `Pwait(k0) -> + Wait + (Sail_values.to_vec0 true (Nat_big_num.of_int 2,Nat_big_num.of_int k0)) + diff --git a/power/gen/lexer.gen b/power/gen/lexer.gen new file mode 100644 index 00000000..a2100883 --- /dev/null +++ b/power/gen/lexer.gen @@ -0,0 +1,368 @@ + "b", B; + "ba", BA; + "bl", BL; + "bla", BLA; + "bc", BC; + "bca", BCA; + "bcl", BCL; + "bcla", BCLA; + "bclr", BCLR; + "bclrl", BCLRL; + "bcctr", BCCTR; + "bcctrl", BCCTRL; + "crand", CRAND; + "crnand", CRNAND; + "cror", CROR; + "crxor", CRXOR; + "crnor", CRNOR; + "creqv", CREQV; + "crandc", CRANDC; + "crorc", CRORC; + "mcrf", MCRF; + "sc", SC; + "scv", SCV; + "lbz", LBZ; + "lbzx", LBZX; + "lbzu", LBZU; + "lbzux", LBZUX; + "lhz", LHZ; + "lhzx", LHZX; + "lhzu", LHZU; + "lhzux", LHZUX; + "lha", LHA; + "lhax", LHAX; + "lhau", LHAU; + "lhaux", LHAUX; + "lwz", LWZ; + "lwzx", LWZX; + "lwzu", LWZU; + "lwzux", LWZUX; + "lwa", LWA; + "lwax", LWAX; + "lwaux", LWAUX; + "ld", LD; + "ldx", LDX; + "ldu", LDU; + "ldux", LDUX; + "stb", STB; + "stbx", STBX; + "stbu", STBU; + "stbux", STBUX; + "sth", STH; + "sthx", STHX; + "sthu", STHU; + "sthux", STHUX; + "stw", STW; + "stwx", STWX; + "stwu", STWU; + "stwux", STWUX; + "std", STD; + "stdx", STDX; + "stdu", STDU; + "stdux", STDUX; + "lq", LQ; + "stq", STQ; + "lhbrx", LHBRX; + "sthbrx", STHBRX; + "lwbrx", LWBRX; + "stwbrx", STWBRX; + "ldbrx", LDBRX; + "stdbrx", STDBRX; + "lmw", LMW; + "stmw", STMW; + "lswi", LSWI; + "lswx", LSWX; + "stswi", STSWI; + "stswx", STSWX; + "addi", ADDI; + "addis", ADDIS; + "add", ADD; + "add.", ADDDOT; + "addo", ADDO; + "addo.", ADDODOT; + "subf", SUBF; + "subf.", SUBFDOT; + "subfo", SUBFO; + "subfo.", SUBFODOT; + "addic", ADDIC; + "addic.", ADDICDOT; + "subfic", SUBFIC; + "addc", ADDC; + "addc.", ADDCDOT; + "addco", ADDCO; + "addco.", ADDCODOT; + "subfc", SUBFC; + "subfc.", SUBFCDOT; + "subfco", SUBFCO; + "subfco.", SUBFCODOT; + "adde", ADDE; + "adde.", ADDEDOT; + "addeo", ADDEO; + "addeo.", ADDEODOT; + "subfe", SUBFE; + "subfe.", SUBFEDOT; + "subfeo", SUBFEO; + "subfeo.", SUBFEODOT; + "addme", ADDME; + "addme.", ADDMEDOT; + "addmeo", ADDMEO; + "addmeo.", ADDMEODOT; + "subfme", SUBFME; + "subfme.", SUBFMEDOT; + "subfmeo", SUBFMEO; + "subfmeo.", SUBFMEODOT; + "addze", ADDZE; + "addze.", ADDZEDOT; + "addzeo", ADDZEO; + "addzeo.", ADDZEODOT; + "subfze", SUBFZE; + "subfze.", SUBFZEDOT; + "subfzeo", SUBFZEO; + "subfzeo.", SUBFZEODOT; + "neg", NEG; + "neg.", NEGDOT; + "nego", NEGO; + "nego.", NEGODOT; + "mulli", MULLI; + "mullw", MULLW; + "mullw.", MULLWDOT; + "mullwo", MULLWO; + "mullwo.", MULLWODOT; + "mulhw", MULHW; + "mulhw.", MULHWDOT; + "mulhwu", MULHWU; + "mulhwu.", MULHWUDOT; + "divw", DIVW; + "divw.", DIVWDOT; + "divwo", DIVWO; + "divwo.", DIVWODOT; + "divwu", DIVWU; + "divwu.", DIVWUDOT; + "divwuo", DIVWUO; + "divwuo.", DIVWUODOT; + "divwe", DIVWE; + "divwe.", DIVWEDOT; + "divweo", DIVWEO; + "divweo.", DIVWEODOT; + "divweu", DIVWEU; + "divweu.", DIVWEUDOT; + "divweuo", DIVWEUO; + "divweuo.", DIVWEUODOT; + "mulld", MULLD; + "mulld.", MULLDDOT; + "mulldo", MULLDO; + "mulldo.", MULLDODOT; + "mulhd", MULHD; + "mulhd.", MULHDDOT; + "mulhdu", MULHDU; + "mulhdu.", MULHDUDOT; + "divd", DIVD; + "divd.", DIVDDOT; + "divdo", DIVDO; + "divdo.", DIVDODOT; + "divdu", DIVDU; + "divdu.", DIVDUDOT; + "divduo", DIVDUO; + "divduo.", DIVDUODOT; + "divde", DIVDE; + "divde.", DIVDEDOT; + "divdeo", DIVDEO; + "divdeo.", DIVDEODOT; + "divdeu", DIVDEU; + "divdeu.", DIVDEUDOT; + "divdeuo", DIVDEUO; + "divdeuo.", DIVDEUODOT; + "cmpi", CMPI; + "cmp", CMP; + "cmpli", CMPLI; + "cmpl", CMPL; + "isel", ISEL; + "andi.", ANDIDOT; + "andis.", ANDISDOT; + "ori", ORI; + "oris", ORIS; + "xori", XORI; + "xoris", XORIS; + "and", AND; + "and.", ANDDOT; + "xor", XOR; + "xor.", XORDOT; + "nand", NAND; + "nand.", NANDDOT; + "or", OR; + "or.", ORDOT; + "nor", NOR; + "nor.", NORDOT; + "eqv", EQV; + "eqv.", EQVDOT; + "andc", ANDC; + "andc.", ANDCDOT; + "orc", ORC; + "orc.", ORCDOT; + "extsb", EXTSB; + "extsb.", EXTSBDOT; + "extsh", EXTSH; + "extsh.", EXTSHDOT; + "cntlzw", CNTLZW; + "cntlzw.", CNTLZWDOT; + "cmpb", CMPB; + "popcntb", POPCNTB; + "popcntw", POPCNTW; + "prtyd", PRTYD; + "prtyw", PRTYW; + "extsw", EXTSW; + "extsw.", EXTSWDOT; + "cntlzd", CNTLZD; + "cntlzd.", CNTLZDDOT; + "popcntd", POPCNTD; + "bpermd", BPERMD; + "rlwinm", RLWINM; + "rlwinm.", RLWINMDOT; + "rlwnm", RLWNM; + "rlwnm.", RLWNMDOT; + "rlwimi", RLWIMI; + "rlwimi.", RLWIMIDOT; + "rldicl", RLDICL; + "rldicl.", RLDICLDOT; + "rldicr", RLDICR; + "rldicr.", RLDICRDOT; + "rldic", RLDIC; + "rldic.", RLDICDOT; + "rldcl", RLDCL; + "rldcl.", RLDCLDOT; + "rldcr", RLDCR; + "rldcr.", RLDCRDOT; + "rldimi", RLDIMI; + "rldimi.", RLDIMIDOT; + "slw", SLW; + "slw.", SLWDOT; + "srw", SRW; + "srw.", SRWDOT; + "srawi", SRAWI; + "srawi.", SRAWIDOT; + "sraw", SRAW; + "sraw.", SRAWDOT; + "sld", SLD; + "sld.", SLDDOT; + "srd", SRD; + "srd.", SRDDOT; + "sradi", SRADI; + "sradi.", SRADIDOT; + "srad", SRAD; + "srad.", SRADDOT; + "cdtbcd", CDTBCD; + "cbcdtd", CBCDTD; + "addg6s", ADDG6S; + "mtspr", MTSPR; + "mfspr", MFSPR; + "mtcrf", MTCRF; + "mfcr", MFCR; + "mtocrf", MTOCRF; + "mfocrf", MFOCRF; + "mcrxr", MCRXR; + "dlmzb", DLMZB; + "dlmzb.", DLMZBDOT; + "macchw", MACCHW; + "macchw.", MACCHWDOT; + "macchwo", MACCHWO; + "macchwo.", MACCHWODOT; + "macchws", MACCHWS; + "macchws.", MACCHWSDOT; + "macchwso", MACCHWSO; + "macchwso.", MACCHWSODOT; + "macchwu", MACCHWU; + "macchwu.", MACCHWUDOT; + "macchwuo", MACCHWUO; + "macchwuo.", MACCHWUODOT; + "macchwsu", MACCHWSU; + "macchwsu.", MACCHWSUDOT; + "macchwsuo", MACCHWSUO; + "macchwsuo.", MACCHWSUODOT; + "machhw", MACHHW; + "machhw.", MACHHWDOT; + "machhwo", MACHHWO; + "machhwo.", MACHHWODOT; + "machhws", MACHHWS; + "machhws.", MACHHWSDOT; + "machhwso", MACHHWSO; + "machhwso.", MACHHWSODOT; + "machhwu", MACHHWU; + "machhwu.", MACHHWUDOT; + "machhwuo", MACHHWUO; + "machhwuo.", MACHHWUODOT; + "machhwsu", MACHHWSU; + "machhwsu.", MACHHWSUDOT; + "machhwsuo", MACHHWSUO; + "machhwsuo.", MACHHWSUODOT; + "maclhw", MACLHW; + "maclhw.", MACLHWDOT; + "maclhwo", MACLHWO; + "maclhwo.", MACLHWODOT; + "maclhws", MACLHWS; + "maclhws.", MACLHWSDOT; + "maclhwso", MACLHWSO; + "maclhwso.", MACLHWSODOT; + "maclhwu", MACLHWU; + "maclhwu.", MACLHWUDOT; + "maclhwuo", MACLHWUO; + "maclhwuo.", MACLHWUODOT; + "maclhwsu", MACLHWSU; + "maclhwsu.", MACLHWSUDOT; + "maclhwsuo", MACLHWSUO; + "maclhwsuo.", MACLHWSUODOT; + "mulchw", MULCHW; + "mulchw.", MULCHWDOT; + "mulchwu", MULCHWU; + "mulchwu.", MULCHWUDOT; + "mulhhw", MULHHW; + "mulhhw.", MULHHWDOT; + "mulhhwu", MULHHWU; + "mulhhwu.", MULHHWUDOT; + "mullhw", MULLHW; + "mullhw.", MULLHWDOT; + "mullhwu", MULLHWU; + "mullhwu.", MULLHWUDOT; + "nmacchw", NMACCHW; + "nmacchw.", NMACCHWDOT; + "nmacchwo", NMACCHWO; + "nmacchwo.", NMACCHWODOT; + "nmacchws", NMACCHWS; + "nmacchws.", NMACCHWSDOT; + "nmacchwso", NMACCHWSO; + "nmacchwso.", NMACCHWSODOT; + "nmachhw", NMACHHW; + "nmachhw.", NMACHHWDOT; + "nmachhwo", NMACHHWO; + "nmachhwo.", NMACHHWODOT; + "nmachhws", NMACHHWS; + "nmachhws.", NMACHHWSDOT; + "nmachhwso", NMACHHWSO; + "nmachhwso.", NMACHHWSODOT; + "nmaclhw", NMACLHW; + "nmaclhw.", NMACLHWDOT; + "nmaclhwo", NMACLHWO; + "nmaclhwo.", NMACLHWODOT; + "nmaclhws", NMACLHWS; + "nmaclhws.", NMACLHWSDOT; + "nmaclhwso", NMACLHWSO; + "nmaclhwso.", NMACLHWSODOT; + "icbi", ICBI; + "icbt", ICBT; + "dcba", DCBA; + "dcbt", DCBT; + "dcbtst", DCBTST; + "dcbz", DCBZ; + "dcbst", DCBST; + "dcbf", DCBF; + "isync", ISYNC; + "lbarx", LBARX; + "lharx", LHARX; + "lwarx", LWARX; + "stbcx.", STBCXDOT; + "sthcx.", STHCXDOT; + "stwcx.", STWCXDOT; + "ldarx", LDARX; + "stdcx.", STDCXDOT; + "sync", SYNC; + "eieio", EIEIO; + "wait", WAIT; diff --git a/power/gen/map.gen b/power/gen/map.gen new file mode 100644 index 00000000..27833b80 --- /dev/null +++ b/power/gen/map.gen @@ -0,0 +1,368 @@ +| `Pb (DontSetAA,DontSetLK,target_addr) -> `Pb(DontSetAA,DontSetLK,target_addr) +| `Pb (SetAA,DontSetLK,target_addr) -> `Pb(SetAA,DontSetLK,target_addr) +| `Pb (DontSetAA,SetLK,target_addr) -> `Pb(DontSetAA,SetLK,target_addr) +| `Pb (SetAA,SetLK,target_addr) -> `Pb(SetAA,SetLK,target_addr) +| `Pbc (DontSetAA,DontSetLK,bO,bI,target_addr) -> `Pbc(DontSetAA,DontSetLK,bO,bI,target_addr) +| `Pbc (SetAA,DontSetLK,bO,bI,target_addr) -> `Pbc(SetAA,DontSetLK,bO,bI,target_addr) +| `Pbc (DontSetAA,SetLK,bO,bI,target_addr) -> `Pbc(DontSetAA,SetLK,bO,bI,target_addr) +| `Pbc (SetAA,SetLK,bO,bI,target_addr) -> `Pbc(SetAA,SetLK,bO,bI,target_addr) +| `Pbclr (DontSetLK,bO,bI,bH) -> `Pbclr(DontSetLK,bO,bI,bH) +| `Pbclr (SetLK,bO,bI,bH) -> `Pbclr(SetLK,bO,bI,bH) +| `Pbcctr (DontSetLK,bO,bI,bH) -> `Pbcctr(DontSetLK,bO,bI,bH) +| `Pbcctr (SetLK,bO,bI,bH) -> `Pbcctr(SetLK,bO,bI,bH) +| `Pcrand (bT,bA,bB) -> `Pcrand(bT,bA,bB) +| `Pcrnand (bT,bA,bB) -> `Pcrnand(bT,bA,bB) +| `Pcror (bT,bA,bB) -> `Pcror(bT,bA,bB) +| `Pcrxor (bT,bA,bB) -> `Pcrxor(bT,bA,bB) +| `Pcrnor (bT,bA,bB) -> `Pcrnor(bT,bA,bB) +| `Pcreqv (bT,bA,bB) -> `Pcreqv(bT,bA,bB) +| `Pcrandc (bT,bA,bB) -> `Pcrandc(bT,bA,bB) +| `Pcrorc (bT,bA,bB) -> `Pcrorc(bT,bA,bB) +| `Pmcrf (bF,bFA) -> `Pmcrf(bF,bFA) +| `Psc (lEV) -> `Psc(lEV) +| `Pscv (lEV) -> `Pscv(lEV) +| `Plbz (rT,d,rA) -> `Plbz(map_reg rT,d,map_reg rA) +| `Plbzx (rT,rA,rB) -> `Plbzx(map_reg rT,map_reg rA,map_reg rB) +| `Plbzu (rT,d,rA) -> `Plbzu(map_reg rT,d,map_reg rA) +| `Plbzux (rT,rA,rB) -> `Plbzux(map_reg rT,map_reg rA,map_reg rB) +| `Plhz (rT,d,rA) -> `Plhz(map_reg rT,d,map_reg rA) +| `Plhzx (rT,rA,rB) -> `Plhzx(map_reg rT,map_reg rA,map_reg rB) +| `Plhzu (rT,d,rA) -> `Plhzu(map_reg rT,d,map_reg rA) +| `Plhzux (rT,rA,rB) -> `Plhzux(map_reg rT,map_reg rA,map_reg rB) +| `Plha (rT,d,rA) -> `Plha(map_reg rT,d,map_reg rA) +| `Plhax (rT,rA,rB) -> `Plhax(map_reg rT,map_reg rA,map_reg rB) +| `Plhau (rT,d,rA) -> `Plhau(map_reg rT,d,map_reg rA) +| `Plhaux (rT,rA,rB) -> `Plhaux(map_reg rT,map_reg rA,map_reg rB) +| `Plwz (rT,d,rA) -> `Plwz(map_reg rT,d,map_reg rA) +| `Plwzx (rT,rA,rB) -> `Plwzx(map_reg rT,map_reg rA,map_reg rB) +| `Plwzu (rT,d,rA) -> `Plwzu(map_reg rT,d,map_reg rA) +| `Plwzux (rT,rA,rB) -> `Plwzux(map_reg rT,map_reg rA,map_reg rB) +| `Plwa (rT,dS,rA) -> `Plwa(map_reg rT,dS,map_reg rA) +| `Plwax (rT,rA,rB) -> `Plwax(map_reg rT,map_reg rA,map_reg rB) +| `Plwaux (rT,rA,rB) -> `Plwaux(map_reg rT,map_reg rA,map_reg rB) +| `Pld (rT,dS,rA) -> `Pld(map_reg rT,dS,map_reg rA) +| `Pldx (rT,rA,rB) -> `Pldx(map_reg rT,map_reg rA,map_reg rB) +| `Pldu (rT,dS,rA) -> `Pldu(map_reg rT,dS,map_reg rA) +| `Pldux (rT,rA,rB) -> `Pldux(map_reg rT,map_reg rA,map_reg rB) +| `Pstb (rS,d,rA) -> `Pstb(map_reg rS,d,map_reg rA) +| `Pstbx (rS,rA,rB) -> `Pstbx(map_reg rS,map_reg rA,map_reg rB) +| `Pstbu (rS,d,rA) -> `Pstbu(map_reg rS,d,map_reg rA) +| `Pstbux (rS,rA,rB) -> `Pstbux(map_reg rS,map_reg rA,map_reg rB) +| `Psth (rS,d,rA) -> `Psth(map_reg rS,d,map_reg rA) +| `Psthx (rS,rA,rB) -> `Psthx(map_reg rS,map_reg rA,map_reg rB) +| `Psthu (rS,d,rA) -> `Psthu(map_reg rS,d,map_reg rA) +| `Psthux (rS,rA,rB) -> `Psthux(map_reg rS,map_reg rA,map_reg rB) +| `Pstw (rS,d,rA) -> `Pstw(map_reg rS,d,map_reg rA) +| `Pstwx (rS,rA,rB) -> `Pstwx(map_reg rS,map_reg rA,map_reg rB) +| `Pstwu (rS,d,rA) -> `Pstwu(map_reg rS,d,map_reg rA) +| `Pstwux (rS,rA,rB) -> `Pstwux(map_reg rS,map_reg rA,map_reg rB) +| `Pstd (rS,dS,rA) -> `Pstd(map_reg rS,dS,map_reg rA) +| `Pstdx (rS,rA,rB) -> `Pstdx(map_reg rS,map_reg rA,map_reg rB) +| `Pstdu (rS,dS,rA) -> `Pstdu(map_reg rS,dS,map_reg rA) +| `Pstdux (rS,rA,rB) -> `Pstdux(map_reg rS,map_reg rA,map_reg rB) +| `Plq (rTp,dQ,rA,pT) -> `Plq(rTp,dQ,map_reg rA,pT) +| `Pstq (rSp,dS,rA) -> `Pstq(rSp,dS,map_reg rA) +| `Plhbrx (rT,rA,rB) -> `Plhbrx(map_reg rT,map_reg rA,map_reg rB) +| `Psthbrx (rS,rA,rB) -> `Psthbrx(map_reg rS,map_reg rA,map_reg rB) +| `Plwbrx (rT,rA,rB) -> `Plwbrx(map_reg rT,map_reg rA,map_reg rB) +| `Pstwbrx (rS,rA,rB) -> `Pstwbrx(map_reg rS,map_reg rA,map_reg rB) +| `Pldbrx (rT,rA,rB) -> `Pldbrx(map_reg rT,map_reg rA,map_reg rB) +| `Pstdbrx (rS,rA,rB) -> `Pstdbrx(map_reg rS,map_reg rA,map_reg rB) +| `Plmw (rT,d,rA) -> `Plmw(rT,d,map_reg rA) +| `Pstmw (rS,d,rA) -> `Pstmw(rS,d,map_reg rA) +| `Plswi (rT,rA,nB) -> `Plswi(rT,map_reg rA,nB) +| `Plswx (rT,rA,rB) -> `Plswx(map_reg rT,map_reg rA,map_reg rB) +| `Pstswi (rS,rA,nB) -> `Pstswi(rS,map_reg rA,nB) +| `Pstswx (rS,rA,rB) -> `Pstswx(rS,map_reg rA,map_reg rB) +| `Paddi (rT,rA,sI) -> `Paddi(map_reg rT,map_reg rA,sI) +| `Paddis (rT,rA,sI) -> `Paddis(map_reg rT,map_reg rA,sI) +| `Padd (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Padd(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Padd (DontSetSOOV,SetCR0,rT,rA,rB) -> `Padd(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Padd (SetSOOV,DontSetCR0,rT,rA,rB) -> `Padd(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Padd (SetSOOV,SetCR0,rT,rA,rB) -> `Padd(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubf (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Psubf(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubf (DontSetSOOV,SetCR0,rT,rA,rB) -> `Psubf(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubf (SetSOOV,DontSetCR0,rT,rA,rB) -> `Psubf(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubf (SetSOOV,SetCR0,rT,rA,rB) -> `Psubf(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Paddic (rT,rA,sI) -> `Paddic(map_reg rT,map_reg rA,sI) +| `Paddicdot (rT,rA,sI) -> `Paddicdot(map_reg rT,map_reg rA,sI) +| `Psubfic (rT,rA,sI) -> `Psubfic(map_reg rT,map_reg rA,sI) +| `Paddc (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Paddc(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Paddc (DontSetSOOV,SetCR0,rT,rA,rB) -> `Paddc(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Paddc (SetSOOV,DontSetCR0,rT,rA,rB) -> `Paddc(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Paddc (SetSOOV,SetCR0,rT,rA,rB) -> `Paddc(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubfc (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Psubfc(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubfc (DontSetSOOV,SetCR0,rT,rA,rB) -> `Psubfc(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubfc (SetSOOV,DontSetCR0,rT,rA,rB) -> `Psubfc(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubfc (SetSOOV,SetCR0,rT,rA,rB) -> `Psubfc(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Padde (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Padde(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Padde (DontSetSOOV,SetCR0,rT,rA,rB) -> `Padde(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Padde (SetSOOV,DontSetCR0,rT,rA,rB) -> `Padde(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Padde (SetSOOV,SetCR0,rT,rA,rB) -> `Padde(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubfe (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Psubfe(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubfe (DontSetSOOV,SetCR0,rT,rA,rB) -> `Psubfe(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubfe (SetSOOV,DontSetCR0,rT,rA,rB) -> `Psubfe(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Psubfe (SetSOOV,SetCR0,rT,rA,rB) -> `Psubfe(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Paddme (DontSetSOOV,DontSetCR0,rT,rA) -> `Paddme(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Paddme (DontSetSOOV,SetCR0,rT,rA) -> `Paddme(DontSetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Paddme (SetSOOV,DontSetCR0,rT,rA) -> `Paddme(SetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Paddme (SetSOOV,SetCR0,rT,rA) -> `Paddme(SetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Psubfme (DontSetSOOV,DontSetCR0,rT,rA) -> `Psubfme(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Psubfme (DontSetSOOV,SetCR0,rT,rA) -> `Psubfme(DontSetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Psubfme (SetSOOV,DontSetCR0,rT,rA) -> `Psubfme(SetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Psubfme (SetSOOV,SetCR0,rT,rA) -> `Psubfme(SetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Paddze (DontSetSOOV,DontSetCR0,rT,rA) -> `Paddze(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Paddze (DontSetSOOV,SetCR0,rT,rA) -> `Paddze(DontSetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Paddze (SetSOOV,DontSetCR0,rT,rA) -> `Paddze(SetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Paddze (SetSOOV,SetCR0,rT,rA) -> `Paddze(SetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Psubfze (DontSetSOOV,DontSetCR0,rT,rA) -> `Psubfze(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Psubfze (DontSetSOOV,SetCR0,rT,rA) -> `Psubfze(DontSetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Psubfze (SetSOOV,DontSetCR0,rT,rA) -> `Psubfze(SetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Psubfze (SetSOOV,SetCR0,rT,rA) -> `Psubfze(SetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Pneg (DontSetSOOV,DontSetCR0,rT,rA) -> `Pneg(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Pneg (DontSetSOOV,SetCR0,rT,rA) -> `Pneg(DontSetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Pneg (SetSOOV,DontSetCR0,rT,rA) -> `Pneg(SetSOOV,DontSetCR0,map_reg rT,map_reg rA) +| `Pneg (SetSOOV,SetCR0,rT,rA) -> `Pneg(SetSOOV,SetCR0,map_reg rT,map_reg rA) +| `Pmulli (rT,rA,sI) -> `Pmulli(map_reg rT,map_reg rA,sI) +| `Pmullw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmullw(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmullw (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmullw(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmullw (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmullw(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmullw (SetSOOV,SetCR0,rT,rA,rB) -> `Pmullw(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhw (DontSetCR0,rT,rA,rB) -> `Pmulhw(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhw (SetCR0,rT,rA,rB) -> `Pmulhw(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhwu (DontSetCR0,rT,rA,rB) -> `Pmulhwu(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhwu (SetCR0,rT,rA,rB) -> `Pmulhwu(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivw(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivw (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pdivw(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivw (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivw(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivw (SetSOOV,SetCR0,rT,rA,rB) -> `Pdivw(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivwu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivwu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pdivwu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivwu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivwu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivwu (SetSOOV,SetCR0,rT,rA,rB) -> `Pdivwu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivwe (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivwe(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivwe (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pdivwe(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivwe (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivwe(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivwe (SetSOOV,SetCR0,rT,rA,rB) -> `Pdivwe(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivweu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivweu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivweu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pdivweu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivweu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivweu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivweu (SetSOOV,SetCR0,rT,rA,rB) -> `Pdivweu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulld (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmulld(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulld (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmulld(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulld (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmulld(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulld (SetSOOV,SetCR0,rT,rA,rB) -> `Pmulld(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhd (DontSetCR0,rT,rA,rB) -> `Pmulhd(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhd (SetCR0,rT,rA,rB) -> `Pmulhd(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhdu (DontSetCR0,rT,rA,rB) -> `Pmulhdu(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhdu (SetCR0,rT,rA,rB) -> `Pmulhdu(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivd (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivd(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivd (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pdivd(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivd (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivd(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivd (SetSOOV,SetCR0,rT,rA,rB) -> `Pdivd(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivdu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivdu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivdu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pdivdu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivdu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivdu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivdu (SetSOOV,SetCR0,rT,rA,rB) -> `Pdivdu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivde (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivde(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivde (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pdivde(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivde (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivde(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivde (SetSOOV,SetCR0,rT,rA,rB) -> `Pdivde(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivdeu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivdeu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivdeu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pdivdeu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivdeu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pdivdeu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pdivdeu (SetSOOV,SetCR0,rT,rA,rB) -> `Pdivdeu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pcmpi (bF,l,rA,sI) -> `Pcmpi(bF,l,map_reg rA,sI) +| `Pcmp (bF,l,rA,rB) -> `Pcmp(bF,l,map_reg rA,map_reg rB) +| `Pcmpli (bF,l,rA,uI) -> `Pcmpli(bF,l,map_reg rA,uI) +| `Pcmpl (bF,l,rA,rB) -> `Pcmpl(bF,l,map_reg rA,map_reg rB) +| `Pisel (rT,rA,rB,bC) -> `Pisel(map_reg rT,map_reg rA,map_reg rB,bC) +| `Pandi (rA,rS,uI) -> `Pandi(map_reg rA,map_reg rS,uI) +| `Pandis (rA,rS,uI) -> `Pandis(map_reg rA,map_reg rS,uI) +| `Pori (rA,rS,uI) -> `Pori(map_reg rA,map_reg rS,uI) +| `Poris (rA,rS,uI) -> `Poris(map_reg rA,map_reg rS,uI) +| `Pxori (rA,rS,uI) -> `Pxori(map_reg rA,map_reg rS,uI) +| `Pxoris (rA,rS,uI) -> `Pxoris(map_reg rA,map_reg rS,uI) +| `Pand (DontSetCR0,rA,rS,rB) -> `Pand(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pand (SetCR0,rA,rS,rB) -> `Pand(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pxor (DontSetCR0,rA,rS,rB) -> `Pxor(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pxor (SetCR0,rA,rS,rB) -> `Pxor(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pnand (DontSetCR0,rA,rS,rB) -> `Pnand(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pnand (SetCR0,rA,rS,rB) -> `Pnand(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Por (DontSetCR0,rA,rS,rB) -> `Por(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Por (SetCR0,rA,rS,rB) -> `Por(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pnor (DontSetCR0,rA,rS,rB) -> `Pnor(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pnor (SetCR0,rA,rS,rB) -> `Pnor(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Peqv (DontSetCR0,rA,rS,rB) -> `Peqv(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Peqv (SetCR0,rA,rS,rB) -> `Peqv(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pandc (DontSetCR0,rA,rS,rB) -> `Pandc(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pandc (SetCR0,rA,rS,rB) -> `Pandc(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Porc (DontSetCR0,rA,rS,rB) -> `Porc(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Porc (SetCR0,rA,rS,rB) -> `Porc(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pextsb (DontSetCR0,rA,rS) -> `Pextsb(DontSetCR0,map_reg rA,map_reg rS) +| `Pextsb (SetCR0,rA,rS) -> `Pextsb(SetCR0,map_reg rA,map_reg rS) +| `Pextsh (DontSetCR0,rA,rS) -> `Pextsh(DontSetCR0,map_reg rA,map_reg rS) +| `Pextsh (SetCR0,rA,rS) -> `Pextsh(SetCR0,map_reg rA,map_reg rS) +| `Pcntlzw (DontSetCR0,rA,rS) -> `Pcntlzw(DontSetCR0,map_reg rA,map_reg rS) +| `Pcntlzw (SetCR0,rA,rS) -> `Pcntlzw(SetCR0,map_reg rA,map_reg rS) +| `Pcmpb (rA,rS,rB) -> `Pcmpb(map_reg rA,rS,map_reg rB) +| `Ppopcntb (rA,rS) -> `Ppopcntb(map_reg rA,map_reg rS) +| `Ppopcntw (rA,rS) -> `Ppopcntw(map_reg rA,map_reg rS) +| `Pprtyd (rA,rS) -> `Pprtyd(map_reg rA,map_reg rS) +| `Pprtyw (rA,rS) -> `Pprtyw(map_reg rA,map_reg rS) +| `Pextsw (DontSetCR0,rA,rS) -> `Pextsw(DontSetCR0,map_reg rA,map_reg rS) +| `Pextsw (SetCR0,rA,rS) -> `Pextsw(SetCR0,map_reg rA,map_reg rS) +| `Pcntlzd (DontSetCR0,rA,rS) -> `Pcntlzd(DontSetCR0,map_reg rA,map_reg rS) +| `Pcntlzd (SetCR0,rA,rS) -> `Pcntlzd(SetCR0,map_reg rA,map_reg rS) +| `Ppopcntd (rA,rS) -> `Ppopcntd(map_reg rA,map_reg rS) +| `Pbpermd (rA,rS,rB) -> `Pbpermd(map_reg rA,map_reg rS,map_reg rB) +| `Prlwinm (DontSetCR0,rA,rS,sH,mB,mE) -> `Prlwinm(DontSetCR0,map_reg rA,map_reg rS,sH,mB,mE) +| `Prlwinm (SetCR0,rA,rS,sH,mB,mE) -> `Prlwinm(SetCR0,map_reg rA,map_reg rS,sH,mB,mE) +| `Prlwnm (DontSetCR0,rA,rS,rB,mB,mE) -> `Prlwnm(DontSetCR0,map_reg rA,map_reg rS,map_reg rB,mB,mE) +| `Prlwnm (SetCR0,rA,rS,rB,mB,mE) -> `Prlwnm(SetCR0,map_reg rA,map_reg rS,map_reg rB,mB,mE) +| `Prlwimi (DontSetCR0,rA,rS,sH,mB,mE) -> `Prlwimi(DontSetCR0,map_reg rA,map_reg rS,sH,mB,mE) +| `Prlwimi (SetCR0,rA,rS,sH,mB,mE) -> `Prlwimi(SetCR0,map_reg rA,map_reg rS,sH,mB,mE) +| `Prldicl (DontSetCR0,rA,rS,sH,mB) -> `Prldicl(DontSetCR0,map_reg rA,map_reg rS,sH,mB) +| `Prldicl (SetCR0,rA,rS,sH,mB) -> `Prldicl(SetCR0,map_reg rA,map_reg rS,sH,mB) +| `Prldicr (DontSetCR0,rA,rS,sH,mE) -> `Prldicr(DontSetCR0,map_reg rA,map_reg rS,sH,mE) +| `Prldicr (SetCR0,rA,rS,sH,mE) -> `Prldicr(SetCR0,map_reg rA,map_reg rS,sH,mE) +| `Prldic (DontSetCR0,rA,rS,sH,mB) -> `Prldic(DontSetCR0,map_reg rA,map_reg rS,sH,mB) +| `Prldic (SetCR0,rA,rS,sH,mB) -> `Prldic(SetCR0,map_reg rA,map_reg rS,sH,mB) +| `Prldcl (DontSetCR0,rA,rS,rB,mB) -> `Prldcl(DontSetCR0,map_reg rA,map_reg rS,map_reg rB,mB) +| `Prldcl (SetCR0,rA,rS,rB,mB) -> `Prldcl(SetCR0,map_reg rA,map_reg rS,map_reg rB,mB) +| `Prldcr (DontSetCR0,rA,rS,rB,mE) -> `Prldcr(DontSetCR0,map_reg rA,map_reg rS,map_reg rB,mE) +| `Prldcr (SetCR0,rA,rS,rB,mE) -> `Prldcr(SetCR0,map_reg rA,map_reg rS,map_reg rB,mE) +| `Prldimi (DontSetCR0,rA,rS,sH,mB) -> `Prldimi(DontSetCR0,map_reg rA,map_reg rS,sH,mB) +| `Prldimi (SetCR0,rA,rS,sH,mB) -> `Prldimi(SetCR0,map_reg rA,map_reg rS,sH,mB) +| `Pslw (DontSetCR0,rA,rS,rB) -> `Pslw(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pslw (SetCR0,rA,rS,rB) -> `Pslw(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psrw (DontSetCR0,rA,rS,rB) -> `Psrw(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psrw (SetCR0,rA,rS,rB) -> `Psrw(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psrawi (DontSetCR0,rA,rS,sH) -> `Psrawi(DontSetCR0,map_reg rA,map_reg rS,sH) +| `Psrawi (SetCR0,rA,rS,sH) -> `Psrawi(SetCR0,map_reg rA,map_reg rS,sH) +| `Psraw (DontSetCR0,rA,rS,rB) -> `Psraw(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psraw (SetCR0,rA,rS,rB) -> `Psraw(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psld (DontSetCR0,rA,rS,rB) -> `Psld(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psld (SetCR0,rA,rS,rB) -> `Psld(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psrd (DontSetCR0,rA,rS,rB) -> `Psrd(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psrd (SetCR0,rA,rS,rB) -> `Psrd(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psradi (DontSetCR0,rA,rS,sH) -> `Psradi(DontSetCR0,map_reg rA,map_reg rS,sH) +| `Psradi (SetCR0,rA,rS,sH) -> `Psradi(SetCR0,map_reg rA,map_reg rS,sH) +| `Psrad (DontSetCR0,rA,rS,rB) -> `Psrad(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Psrad (SetCR0,rA,rS,rB) -> `Psrad(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pcdtbcd (rA,rS) -> `Pcdtbcd(map_reg rA,map_reg rS) +| `Pcbcdtd (rA,rS) -> `Pcbcdtd(map_reg rA,map_reg rS) +| `Paddg6s (rT,rA,rB) -> `Paddg6s(map_reg rT,map_reg rA,map_reg rB) +| `Pmtspr (sPR,rS) -> `Pmtspr(sPR,map_reg rS) +| `Pmfspr (rT,sPR) -> `Pmfspr(map_reg rT,sPR) +| `Pmtcrf (fXM,rS) -> `Pmtcrf(fXM,map_reg rS) +| `Pmfcr (rT) -> `Pmfcr(map_reg rT) +| `Pmtocrf (fXM,rS) -> `Pmtocrf(fXM,map_reg rS) +| `Pmfocrf (rT,fXM) -> `Pmfocrf(map_reg rT,fXM) +| `Pmcrxr (bF) -> `Pmcrxr(bF) +| `Pdlmzb (DontSetCR0,rA,rS,rB) -> `Pdlmzb(DontSetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pdlmzb (SetCR0,rA,rS,rB) -> `Pdlmzb(SetCR0,map_reg rA,map_reg rS,map_reg rB) +| `Pmacchw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmacchw(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchw (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmacchw(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchw (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmacchw(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchw (SetSOOV,SetCR0,rT,rA,rB) -> `Pmacchw(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmacchws(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchws (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmacchws(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchws (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmacchws(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchws (SetSOOV,SetCR0,rT,rA,rB) -> `Pmacchws(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmacchwu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchwu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmacchwu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchwu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmacchwu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchwu (SetSOOV,SetCR0,rT,rA,rB) -> `Pmacchwu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmacchwsu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmacchwsu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmacchwsu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmacchwsu (SetSOOV,SetCR0,rT,rA,rB) -> `Pmacchwsu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmachhw(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhw (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmachhw(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhw (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmachhw(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhw (SetSOOV,SetCR0,rT,rA,rB) -> `Pmachhw(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmachhws(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhws (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmachhws(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhws (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmachhws(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhws (SetSOOV,SetCR0,rT,rA,rB) -> `Pmachhws(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmachhwu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhwu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmachhwu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhwu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmachhwu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhwu (SetSOOV,SetCR0,rT,rA,rB) -> `Pmachhwu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmachhwsu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmachhwsu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmachhwsu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmachhwsu (SetSOOV,SetCR0,rT,rA,rB) -> `Pmachhwsu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmaclhw(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhw (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmaclhw(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhw (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmaclhw(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhw (SetSOOV,SetCR0,rT,rA,rB) -> `Pmaclhw(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmaclhws(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhws (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmaclhws(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhws (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmaclhws(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhws (SetSOOV,SetCR0,rT,rA,rB) -> `Pmaclhws(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmaclhwu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhwu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmaclhwu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhwu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmaclhwu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhwu (SetSOOV,SetCR0,rT,rA,rB) -> `Pmaclhwu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pmaclhwsu(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pmaclhwsu(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pmaclhwsu(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmaclhwsu (SetSOOV,SetCR0,rT,rA,rB) -> `Pmaclhwsu(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulchw (DontSetCR0,rT,rA,rB) -> `Pmulchw(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulchw (SetCR0,rT,rA,rB) -> `Pmulchw(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulchwu (DontSetCR0,rT,rA,rB) -> `Pmulchwu(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulchwu (SetCR0,rT,rA,rB) -> `Pmulchwu(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhhw (DontSetCR0,rT,rA,rB) -> `Pmulhhw(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhhw (SetCR0,rT,rA,rB) -> `Pmulhhw(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhhwu (DontSetCR0,rT,rA,rB) -> `Pmulhhwu(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmulhhwu (SetCR0,rT,rA,rB) -> `Pmulhhwu(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmullhw (DontSetCR0,rT,rA,rB) -> `Pmullhw(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmullhw (SetCR0,rT,rA,rB) -> `Pmullhw(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmullhwu (DontSetCR0,rT,rA,rB) -> `Pmullhwu(DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pmullhwu (SetCR0,rT,rA,rB) -> `Pmullhwu(SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmacchw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmacchw(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmacchw (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pnmacchw(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmacchw (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmacchw(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmacchw (SetSOOV,SetCR0,rT,rA,rB) -> `Pnmacchw(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmacchws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmacchws(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmacchws (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pnmacchws(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmacchws (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmacchws(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmacchws (SetSOOV,SetCR0,rT,rA,rB) -> `Pnmacchws(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmachhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmachhw(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmachhw (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pnmachhw(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmachhw (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmachhw(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmachhw (SetSOOV,SetCR0,rT,rA,rB) -> `Pnmachhw(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmachhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmachhws(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmachhws (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pnmachhws(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmachhws (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmachhws(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmachhws (SetSOOV,SetCR0,rT,rA,rB) -> `Pnmachhws(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmaclhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmaclhw(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmaclhw (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pnmaclhw(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmaclhw (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmaclhw(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmaclhw (SetSOOV,SetCR0,rT,rA,rB) -> `Pnmaclhw(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmaclhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmaclhws(DontSetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmaclhws (DontSetSOOV,SetCR0,rT,rA,rB) -> `Pnmaclhws(DontSetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmaclhws (SetSOOV,DontSetCR0,rT,rA,rB) -> `Pnmaclhws(SetSOOV,DontSetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Pnmaclhws (SetSOOV,SetCR0,rT,rA,rB) -> `Pnmaclhws(SetSOOV,SetCR0,map_reg rT,map_reg rA,map_reg rB) +| `Picbi (rA,rB) -> `Picbi(map_reg rA,map_reg rB) +| `Picbt (cT,rA,rB) -> `Picbt(cT,map_reg rA,map_reg rB) +| `Pdcba (rA,rB) -> `Pdcba(map_reg rA,map_reg rB) +| `Pdcbt (rA,rB,tH) -> `Pdcbt(map_reg rA,map_reg rB,tH) +| `Pdcbtst (rA,rB,tH) -> `Pdcbtst(map_reg rA,map_reg rB,tH) +| `Pdcbz (rA,rB) -> `Pdcbz(map_reg rA,map_reg rB) +| `Pdcbst (rA,rB) -> `Pdcbst(map_reg rA,map_reg rB) +| `Pdcbf (rA,rB,l) -> `Pdcbf(map_reg rA,map_reg rB,l) +| `Pisync -> `Pisync +| `Plbarx (rT,rA,rB,eH) -> `Plbarx(map_reg rT,map_reg rA,map_reg rB,eH) +| `Plharx (rT,rA,rB,eH) -> `Plharx(map_reg rT,map_reg rA,map_reg rB,eH) +| `Plwarx (rT,rA,rB,eH) -> `Plwarx(map_reg rT,map_reg rA,map_reg rB,eH) +| `Pstbcx (rS,rA,rB) -> `Pstbcx(map_reg rS,map_reg rA,map_reg rB) +| `Psthcx (rS,rA,rB) -> `Psthcx(map_reg rS,map_reg rA,map_reg rB) +| `Pstwcx (rS,rA,rB) -> `Pstwcx(map_reg rS,map_reg rA,map_reg rB) +| `Pldarx (rT,rA,rB,eH) -> `Pldarx(map_reg rT,map_reg rA,map_reg rB,eH) +| `Pstdcx (rS,rA,rB) -> `Pstdcx(map_reg rS,map_reg rA,map_reg rB) +| `Psync (l) -> `Psync(l) +| `Peieio -> `Peieio +| `Pwait (wC) -> `Pwait(wC) diff --git a/power/gen/parser.gen b/power/gen/parser.gen new file mode 100644 index 00000000..298cd50f --- /dev/null +++ b/power/gen/parser.gen @@ -0,0 +1,736 @@ + | B k + { `Pb (DontSetAA,DontSetLK,$2) } + | BA k + { `Pb (SetAA,DontSetLK,$2) } + | BL k + { `Pb (DontSetAA,SetLK,$2) } + | BLA k + { `Pb (SetAA,SetLK,$2) } + | BC k COMMA k COMMA k + { `Pbc (DontSetAA,DontSetLK,$2,$4,$6) } + | BCA k COMMA k COMMA k + { `Pbc (SetAA,DontSetLK,$2,$4,$6) } + | BCL k COMMA k COMMA k + { `Pbc (DontSetAA,SetLK,$2,$4,$6) } + | BCLA k COMMA k COMMA k + { `Pbc (SetAA,SetLK,$2,$4,$6) } + | BCLR k COMMA k COMMA k + { `Pbclr (DontSetLK,$2,$4,$6) } + | BCLRL k COMMA k COMMA k + { `Pbclr (SetLK,$2,$4,$6) } + | BCCTR k COMMA k COMMA k + { `Pbcctr (DontSetLK,$2,$4,$6) } + | BCCTRL k COMMA k COMMA k + { `Pbcctr (SetLK,$2,$4,$6) } + | CRAND k COMMA k COMMA k + { `Pcrand ($2,$4,$6) } + | CRNAND k COMMA k COMMA k + { `Pcrnand ($2,$4,$6) } + | CROR k COMMA k COMMA k + { `Pcror ($2,$4,$6) } + | CRXOR k COMMA k COMMA k + { `Pcrxor ($2,$4,$6) } + | CRNOR k COMMA k COMMA k + { `Pcrnor ($2,$4,$6) } + | CREQV k COMMA k COMMA k + { `Pcreqv ($2,$4,$6) } + | CRANDC k COMMA k COMMA k + { `Pcrandc ($2,$4,$6) } + | CRORC k COMMA k COMMA k + { `Pcrorc ($2,$4,$6) } + | MCRF crindex COMMA k + { `Pmcrf ($2,$4) } + | SC k + { `Psc ($2) } + | SCV k + { `Pscv ($2) } + | LBZ reg COMMA k LPAR reg RPAR + { `Plbz ($2,$4,$6) } + | LBZX reg COMMA reg COMMA reg + { `Plbzx ($2,$4,$6) } + | LBZU reg COMMA k LPAR reg RPAR + { `Plbzu ($2,$4,$6) } + | LBZUX reg COMMA reg COMMA reg + { `Plbzux ($2,$4,$6) } + | LHZ reg COMMA k LPAR reg RPAR + { `Plhz ($2,$4,$6) } + | LHZX reg COMMA reg COMMA reg + { `Plhzx ($2,$4,$6) } + | LHZU reg COMMA k LPAR reg RPAR + { `Plhzu ($2,$4,$6) } + | LHZUX reg COMMA reg COMMA reg + { `Plhzux ($2,$4,$6) } + | LHA reg COMMA k LPAR reg RPAR + { `Plha ($2,$4,$6) } + | LHAX reg COMMA reg COMMA reg + { `Plhax ($2,$4,$6) } + | LHAU reg COMMA k LPAR reg RPAR + { `Plhau ($2,$4,$6) } + | LHAUX reg COMMA reg COMMA reg + { `Plhaux ($2,$4,$6) } + | LWZ reg COMMA k LPAR reg RPAR + { `Plwz ($2,$4,$6) } + | LWZX reg COMMA reg COMMA reg + { `Plwzx ($2,$4,$6) } + | LWZU reg COMMA k LPAR reg RPAR + { `Plwzu ($2,$4,$6) } + | LWZUX reg COMMA reg COMMA reg + { `Plwzux ($2,$4,$6) } + | LWA reg COMMA ds LPAR reg RPAR + { `Plwa ($2,$4,$6) } + | LWAX reg COMMA reg COMMA reg + { `Plwax ($2,$4,$6) } + | LWAUX reg COMMA reg COMMA reg + { `Plwaux ($2,$4,$6) } + | LD reg COMMA ds LPAR reg RPAR + { `Pld ($2,$4,$6) } + | LDX reg COMMA reg COMMA reg + { `Pldx ($2,$4,$6) } + | LDU reg COMMA ds LPAR reg RPAR + { `Pldu ($2,$4,$6) } + | LDUX reg COMMA reg COMMA reg + { `Pldux ($2,$4,$6) } + | STB reg COMMA k LPAR reg RPAR + { `Pstb ($2,$4,$6) } + | STBX reg COMMA reg COMMA reg + { `Pstbx ($2,$4,$6) } + | STBU reg COMMA k LPAR reg RPAR + { `Pstbu ($2,$4,$6) } + | STBUX reg COMMA reg COMMA reg + { `Pstbux ($2,$4,$6) } + | STH reg COMMA k LPAR reg RPAR + { `Psth ($2,$4,$6) } + | STHX reg COMMA reg COMMA reg + { `Psthx ($2,$4,$6) } + | STHU reg COMMA k LPAR reg RPAR + { `Psthu ($2,$4,$6) } + | STHUX reg COMMA reg COMMA reg + { `Psthux ($2,$4,$6) } + | STW reg COMMA k LPAR reg RPAR + { `Pstw ($2,$4,$6) } + | STWX reg COMMA reg COMMA reg + { `Pstwx ($2,$4,$6) } + | STWU reg COMMA k LPAR reg RPAR + { `Pstwu ($2,$4,$6) } + | STWUX reg COMMA reg COMMA reg + { `Pstwux ($2,$4,$6) } + | STD reg COMMA ds LPAR reg RPAR + { `Pstd ($2,$4,$6) } + | STDX reg COMMA reg COMMA reg + { `Pstdx ($2,$4,$6) } + | STDU reg COMMA ds LPAR reg RPAR + { `Pstdu ($2,$4,$6) } + | STDUX reg COMMA reg COMMA reg + { `Pstdux ($2,$4,$6) } + | LQ k COMMA k LPAR reg RPAR COMMA k + { `Plq ($2,$4,$6,$9) } + | STQ k COMMA ds LPAR reg RPAR + { `Pstq ($2,$4,$6) } + | LHBRX reg COMMA reg COMMA reg + { `Plhbrx ($2,$4,$6) } + | STHBRX reg COMMA reg COMMA reg + { `Psthbrx ($2,$4,$6) } + | LWBRX reg COMMA reg COMMA reg + { `Plwbrx ($2,$4,$6) } + | STWBRX reg COMMA reg COMMA reg + { `Pstwbrx ($2,$4,$6) } + | LDBRX reg COMMA reg COMMA reg + { `Pldbrx ($2,$4,$6) } + | STDBRX reg COMMA reg COMMA reg + { `Pstdbrx ($2,$4,$6) } + | LMW reg COMMA k LPAR reg RPAR + { `Plmw ($2,$4,$6) } + | STMW reg COMMA k LPAR reg RPAR + { `Pstmw ($2,$4,$6) } + | LSWI k COMMA reg COMMA k + { `Plswi ($2,$4,$6) } + | LSWX reg COMMA reg COMMA reg + { `Plswx ($2,$4,$6) } + | STSWI k COMMA reg COMMA k + { `Pstswi ($2,$4,$6) } + | STSWX k COMMA reg COMMA reg + { `Pstswx ($2,$4,$6) } + | ADDI reg COMMA reg COMMA k + { `Paddi ($2,$4,$6) } + | ADDIS reg COMMA reg COMMA k + { `Paddis ($2,$4,$6) } + | ADD reg COMMA reg COMMA reg + { `Padd (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | ADDDOT reg COMMA reg COMMA reg + { `Padd (DontSetSOOV,SetCR0,$2,$4,$6) } + | ADDO reg COMMA reg COMMA reg + { `Padd (SetSOOV,DontSetCR0,$2,$4,$6) } + | ADDODOT reg COMMA reg COMMA reg + { `Padd (SetSOOV,SetCR0,$2,$4,$6) } + | SUBF reg COMMA reg COMMA reg + { `Psubf (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | SUBFDOT reg COMMA reg COMMA reg + { `Psubf (DontSetSOOV,SetCR0,$2,$4,$6) } + | SUBFO reg COMMA reg COMMA reg + { `Psubf (SetSOOV,DontSetCR0,$2,$4,$6) } + | SUBFODOT reg COMMA reg COMMA reg + { `Psubf (SetSOOV,SetCR0,$2,$4,$6) } + | ADDIC reg COMMA reg COMMA k + { `Paddic ($2,$4,$6) } + | ADDICDOT reg COMMA reg COMMA k + { `Paddicdot ($2,$4,$6) } + | SUBFIC reg COMMA reg COMMA k + { `Psubfic ($2,$4,$6) } + | ADDC reg COMMA reg COMMA reg + { `Paddc (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | ADDCDOT reg COMMA reg COMMA reg + { `Paddc (DontSetSOOV,SetCR0,$2,$4,$6) } + | ADDCO reg COMMA reg COMMA reg + { `Paddc (SetSOOV,DontSetCR0,$2,$4,$6) } + | ADDCODOT reg COMMA reg COMMA reg + { `Paddc (SetSOOV,SetCR0,$2,$4,$6) } + | SUBFC reg COMMA reg COMMA reg + { `Psubfc (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | SUBFCDOT reg COMMA reg COMMA reg + { `Psubfc (DontSetSOOV,SetCR0,$2,$4,$6) } + | SUBFCO reg COMMA reg COMMA reg + { `Psubfc (SetSOOV,DontSetCR0,$2,$4,$6) } + | SUBFCODOT reg COMMA reg COMMA reg + { `Psubfc (SetSOOV,SetCR0,$2,$4,$6) } + | ADDE reg COMMA reg COMMA reg + { `Padde (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | ADDEDOT reg COMMA reg COMMA reg + { `Padde (DontSetSOOV,SetCR0,$2,$4,$6) } + | ADDEO reg COMMA reg COMMA reg + { `Padde (SetSOOV,DontSetCR0,$2,$4,$6) } + | ADDEODOT reg COMMA reg COMMA reg + { `Padde (SetSOOV,SetCR0,$2,$4,$6) } + | SUBFE reg COMMA reg COMMA reg + { `Psubfe (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | SUBFEDOT reg COMMA reg COMMA reg + { `Psubfe (DontSetSOOV,SetCR0,$2,$4,$6) } + | SUBFEO reg COMMA reg COMMA reg + { `Psubfe (SetSOOV,DontSetCR0,$2,$4,$6) } + | SUBFEODOT reg COMMA reg COMMA reg + { `Psubfe (SetSOOV,SetCR0,$2,$4,$6) } + | ADDME reg COMMA reg + { `Paddme (DontSetSOOV,DontSetCR0,$2,$4) } + | ADDMEDOT reg COMMA reg + { `Paddme (DontSetSOOV,SetCR0,$2,$4) } + | ADDMEO reg COMMA reg + { `Paddme (SetSOOV,DontSetCR0,$2,$4) } + | ADDMEODOT reg COMMA reg + { `Paddme (SetSOOV,SetCR0,$2,$4) } + | SUBFME reg COMMA reg + { `Psubfme (DontSetSOOV,DontSetCR0,$2,$4) } + | SUBFMEDOT reg COMMA reg + { `Psubfme (DontSetSOOV,SetCR0,$2,$4) } + | SUBFMEO reg COMMA reg + { `Psubfme (SetSOOV,DontSetCR0,$2,$4) } + | SUBFMEODOT reg COMMA reg + { `Psubfme (SetSOOV,SetCR0,$2,$4) } + | ADDZE reg COMMA reg + { `Paddze (DontSetSOOV,DontSetCR0,$2,$4) } + | ADDZEDOT reg COMMA reg + { `Paddze (DontSetSOOV,SetCR0,$2,$4) } + | ADDZEO reg COMMA reg + { `Paddze (SetSOOV,DontSetCR0,$2,$4) } + | ADDZEODOT reg COMMA reg + { `Paddze (SetSOOV,SetCR0,$2,$4) } + | SUBFZE reg COMMA reg + { `Psubfze (DontSetSOOV,DontSetCR0,$2,$4) } + | SUBFZEDOT reg COMMA reg + { `Psubfze (DontSetSOOV,SetCR0,$2,$4) } + | SUBFZEO reg COMMA reg + { `Psubfze (SetSOOV,DontSetCR0,$2,$4) } + | SUBFZEODOT reg COMMA reg + { `Psubfze (SetSOOV,SetCR0,$2,$4) } + | NEG reg COMMA reg + { `Pneg (DontSetSOOV,DontSetCR0,$2,$4) } + | NEGDOT reg COMMA reg + { `Pneg (DontSetSOOV,SetCR0,$2,$4) } + | NEGO reg COMMA reg + { `Pneg (SetSOOV,DontSetCR0,$2,$4) } + | NEGODOT reg COMMA reg + { `Pneg (SetSOOV,SetCR0,$2,$4) } + | MULLI reg COMMA reg COMMA k + { `Pmulli ($2,$4,$6) } + | MULLW reg COMMA reg COMMA reg + { `Pmullw (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MULLWDOT reg COMMA reg COMMA reg + { `Pmullw (DontSetSOOV,SetCR0,$2,$4,$6) } + | MULLWO reg COMMA reg COMMA reg + { `Pmullw (SetSOOV,DontSetCR0,$2,$4,$6) } + | MULLWODOT reg COMMA reg COMMA reg + { `Pmullw (SetSOOV,SetCR0,$2,$4,$6) } + | MULHW reg COMMA reg COMMA reg + { `Pmulhw (DontSetCR0,$2,$4,$6) } + | MULHWDOT reg COMMA reg COMMA reg + { `Pmulhw (SetCR0,$2,$4,$6) } + | MULHWU reg COMMA reg COMMA reg + { `Pmulhwu (DontSetCR0,$2,$4,$6) } + | MULHWUDOT reg COMMA reg COMMA reg + { `Pmulhwu (SetCR0,$2,$4,$6) } + | DIVW reg COMMA reg COMMA reg + { `Pdivw (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | DIVWDOT reg COMMA reg COMMA reg + { `Pdivw (DontSetSOOV,SetCR0,$2,$4,$6) } + | DIVWO reg COMMA reg COMMA reg + { `Pdivw (SetSOOV,DontSetCR0,$2,$4,$6) } + | DIVWODOT reg COMMA reg COMMA reg + { `Pdivw (SetSOOV,SetCR0,$2,$4,$6) } + | DIVWU reg COMMA reg COMMA reg + { `Pdivwu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | DIVWUDOT reg COMMA reg COMMA reg + { `Pdivwu (DontSetSOOV,SetCR0,$2,$4,$6) } + | DIVWUO reg COMMA reg COMMA reg + { `Pdivwu (SetSOOV,DontSetCR0,$2,$4,$6) } + | DIVWUODOT reg COMMA reg COMMA reg + { `Pdivwu (SetSOOV,SetCR0,$2,$4,$6) } + | DIVWE reg COMMA reg COMMA reg + { `Pdivwe (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | DIVWEDOT reg COMMA reg COMMA reg + { `Pdivwe (DontSetSOOV,SetCR0,$2,$4,$6) } + | DIVWEO reg COMMA reg COMMA reg + { `Pdivwe (SetSOOV,DontSetCR0,$2,$4,$6) } + | DIVWEODOT reg COMMA reg COMMA reg + { `Pdivwe (SetSOOV,SetCR0,$2,$4,$6) } + | DIVWEU reg COMMA reg COMMA reg + { `Pdivweu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | DIVWEUDOT reg COMMA reg COMMA reg + { `Pdivweu (DontSetSOOV,SetCR0,$2,$4,$6) } + | DIVWEUO reg COMMA reg COMMA reg + { `Pdivweu (SetSOOV,DontSetCR0,$2,$4,$6) } + | DIVWEUODOT reg COMMA reg COMMA reg + { `Pdivweu (SetSOOV,SetCR0,$2,$4,$6) } + | MULLD reg COMMA reg COMMA reg + { `Pmulld (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MULLDDOT reg COMMA reg COMMA reg + { `Pmulld (DontSetSOOV,SetCR0,$2,$4,$6) } + | MULLDO reg COMMA reg COMMA reg + { `Pmulld (SetSOOV,DontSetCR0,$2,$4,$6) } + | MULLDODOT reg COMMA reg COMMA reg + { `Pmulld (SetSOOV,SetCR0,$2,$4,$6) } + | MULHD reg COMMA reg COMMA reg + { `Pmulhd (DontSetCR0,$2,$4,$6) } + | MULHDDOT reg COMMA reg COMMA reg + { `Pmulhd (SetCR0,$2,$4,$6) } + | MULHDU reg COMMA reg COMMA reg + { `Pmulhdu (DontSetCR0,$2,$4,$6) } + | MULHDUDOT reg COMMA reg COMMA reg + { `Pmulhdu (SetCR0,$2,$4,$6) } + | DIVD reg COMMA reg COMMA reg + { `Pdivd (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | DIVDDOT reg COMMA reg COMMA reg + { `Pdivd (DontSetSOOV,SetCR0,$2,$4,$6) } + | DIVDO reg COMMA reg COMMA reg + { `Pdivd (SetSOOV,DontSetCR0,$2,$4,$6) } + | DIVDODOT reg COMMA reg COMMA reg + { `Pdivd (SetSOOV,SetCR0,$2,$4,$6) } + | DIVDU reg COMMA reg COMMA reg + { `Pdivdu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | DIVDUDOT reg COMMA reg COMMA reg + { `Pdivdu (DontSetSOOV,SetCR0,$2,$4,$6) } + | DIVDUO reg COMMA reg COMMA reg + { `Pdivdu (SetSOOV,DontSetCR0,$2,$4,$6) } + | DIVDUODOT reg COMMA reg COMMA reg + { `Pdivdu (SetSOOV,SetCR0,$2,$4,$6) } + | DIVDE reg COMMA reg COMMA reg + { `Pdivde (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | DIVDEDOT reg COMMA reg COMMA reg + { `Pdivde (DontSetSOOV,SetCR0,$2,$4,$6) } + | DIVDEO reg COMMA reg COMMA reg + { `Pdivde (SetSOOV,DontSetCR0,$2,$4,$6) } + | DIVDEODOT reg COMMA reg COMMA reg + { `Pdivde (SetSOOV,SetCR0,$2,$4,$6) } + | DIVDEU reg COMMA reg COMMA reg + { `Pdivdeu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | DIVDEUDOT reg COMMA reg COMMA reg + { `Pdivdeu (DontSetSOOV,SetCR0,$2,$4,$6) } + | DIVDEUO reg COMMA reg COMMA reg + { `Pdivdeu (SetSOOV,DontSetCR0,$2,$4,$6) } + | DIVDEUODOT reg COMMA reg COMMA reg + { `Pdivdeu (SetSOOV,SetCR0,$2,$4,$6) } + | CMPI crindex COMMA k COMMA reg COMMA k + { `Pcmpi ($2,$4,$6,$8) } + | CMP crindex COMMA k COMMA reg COMMA reg + { `Pcmp ($2,$4,$6,$8) } + | CMPLI crindex COMMA k COMMA reg COMMA k + { `Pcmpli ($2,$4,$6,$8) } + | CMPL crindex COMMA k COMMA reg COMMA reg + { `Pcmpl ($2,$4,$6,$8) } + | ISEL reg COMMA reg COMMA reg COMMA k + { `Pisel ($2,$4,$6,$8) } + | ANDIDOT reg COMMA reg COMMA k + { `Pandi ($2,$4,$6) } + | ANDISDOT reg COMMA reg COMMA k + { `Pandis ($2,$4,$6) } + | ORI reg COMMA reg COMMA k + { `Pori ($2,$4,$6) } + | ORIS reg COMMA reg COMMA k + { `Poris ($2,$4,$6) } + | XORI reg COMMA reg COMMA k + { `Pxori ($2,$4,$6) } + | XORIS reg COMMA reg COMMA k + { `Pxoris ($2,$4,$6) } + | AND reg COMMA reg COMMA reg + { `Pand (DontSetCR0,$2,$4,$6) } + | ANDDOT reg COMMA reg COMMA reg + { `Pand (SetCR0,$2,$4,$6) } + | XOR reg COMMA reg COMMA reg + { `Pxor (DontSetCR0,$2,$4,$6) } + | XORDOT reg COMMA reg COMMA reg + { `Pxor (SetCR0,$2,$4,$6) } + | NAND reg COMMA reg COMMA reg + { `Pnand (DontSetCR0,$2,$4,$6) } + | NANDDOT reg COMMA reg COMMA reg + { `Pnand (SetCR0,$2,$4,$6) } + | OR reg COMMA reg COMMA reg + { `Por (DontSetCR0,$2,$4,$6) } + | ORDOT reg COMMA reg COMMA reg + { `Por (SetCR0,$2,$4,$6) } + | NOR reg COMMA reg COMMA reg + { `Pnor (DontSetCR0,$2,$4,$6) } + | NORDOT reg COMMA reg COMMA reg + { `Pnor (SetCR0,$2,$4,$6) } + | EQV reg COMMA reg COMMA reg + { `Peqv (DontSetCR0,$2,$4,$6) } + | EQVDOT reg COMMA reg COMMA reg + { `Peqv (SetCR0,$2,$4,$6) } + | ANDC reg COMMA reg COMMA reg + { `Pandc (DontSetCR0,$2,$4,$6) } + | ANDCDOT reg COMMA reg COMMA reg + { `Pandc (SetCR0,$2,$4,$6) } + | ORC reg COMMA reg COMMA reg + { `Porc (DontSetCR0,$2,$4,$6) } + | ORCDOT reg COMMA reg COMMA reg + { `Porc (SetCR0,$2,$4,$6) } + | EXTSB reg COMMA reg + { `Pextsb (DontSetCR0,$2,$4) } + | EXTSBDOT reg COMMA reg + { `Pextsb (SetCR0,$2,$4) } + | EXTSH reg COMMA reg + { `Pextsh (DontSetCR0,$2,$4) } + | EXTSHDOT reg COMMA reg + { `Pextsh (SetCR0,$2,$4) } + | CNTLZW reg COMMA reg + { `Pcntlzw (DontSetCR0,$2,$4) } + | CNTLZWDOT reg COMMA reg + { `Pcntlzw (SetCR0,$2,$4) } + | CMPB reg COMMA k COMMA reg + { `Pcmpb ($2,$4,$6) } + | POPCNTB reg COMMA reg + { `Ppopcntb ($2,$4) } + | POPCNTW reg COMMA reg + { `Ppopcntw ($2,$4) } + | PRTYD reg COMMA reg + { `Pprtyd ($2,$4) } + | PRTYW reg COMMA reg + { `Pprtyw ($2,$4) } + | EXTSW reg COMMA reg + { `Pextsw (DontSetCR0,$2,$4) } + | EXTSWDOT reg COMMA reg + { `Pextsw (SetCR0,$2,$4) } + | CNTLZD reg COMMA reg + { `Pcntlzd (DontSetCR0,$2,$4) } + | CNTLZDDOT reg COMMA reg + { `Pcntlzd (SetCR0,$2,$4) } + | POPCNTD reg COMMA reg + { `Ppopcntd ($2,$4) } + | BPERMD reg COMMA reg COMMA reg + { `Pbpermd ($2,$4,$6) } + | RLWINM reg COMMA reg COMMA k COMMA k COMMA k + { `Prlwinm (DontSetCR0,$2,$4,$6,$8,$10) } + | RLWINMDOT reg COMMA reg COMMA k COMMA k COMMA k + { `Prlwinm (SetCR0,$2,$4,$6,$8,$10) } + | RLWNM reg COMMA reg COMMA reg COMMA k COMMA k + { `Prlwnm (DontSetCR0,$2,$4,$6,$8,$10) } + | RLWNMDOT reg COMMA reg COMMA reg COMMA k COMMA k + { `Prlwnm (SetCR0,$2,$4,$6,$8,$10) } + | RLWIMI reg COMMA reg COMMA k COMMA k COMMA k + { `Prlwimi (DontSetCR0,$2,$4,$6,$8,$10) } + | RLWIMIDOT reg COMMA reg COMMA k COMMA k COMMA k + { `Prlwimi (SetCR0,$2,$4,$6,$8,$10) } + | RLDICL reg COMMA reg COMMA k COMMA k + { `Prldicl (DontSetCR0,$2,$4,$6,$8) } + | RLDICLDOT reg COMMA reg COMMA k COMMA k + { `Prldicl (SetCR0,$2,$4,$6,$8) } + | RLDICR reg COMMA reg COMMA k COMMA k + { `Prldicr (DontSetCR0,$2,$4,$6,$8) } + | RLDICRDOT reg COMMA reg COMMA k COMMA k + { `Prldicr (SetCR0,$2,$4,$6,$8) } + | RLDIC reg COMMA reg COMMA k COMMA k + { `Prldic (DontSetCR0,$2,$4,$6,$8) } + | RLDICDOT reg COMMA reg COMMA k COMMA k + { `Prldic (SetCR0,$2,$4,$6,$8) } + | RLDCL reg COMMA reg COMMA reg COMMA k + { `Prldcl (DontSetCR0,$2,$4,$6,$8) } + | RLDCLDOT reg COMMA reg COMMA reg COMMA k + { `Prldcl (SetCR0,$2,$4,$6,$8) } + | RLDCR reg COMMA reg COMMA reg COMMA k + { `Prldcr (DontSetCR0,$2,$4,$6,$8) } + | RLDCRDOT reg COMMA reg COMMA reg COMMA k + { `Prldcr (SetCR0,$2,$4,$6,$8) } + | RLDIMI reg COMMA reg COMMA k COMMA k + { `Prldimi (DontSetCR0,$2,$4,$6,$8) } + | RLDIMIDOT reg COMMA reg COMMA k COMMA k + { `Prldimi (SetCR0,$2,$4,$6,$8) } + | SLW reg COMMA reg COMMA reg + { `Pslw (DontSetCR0,$2,$4,$6) } + | SLWDOT reg COMMA reg COMMA reg + { `Pslw (SetCR0,$2,$4,$6) } + | SRW reg COMMA reg COMMA reg + { `Psrw (DontSetCR0,$2,$4,$6) } + | SRWDOT reg COMMA reg COMMA reg + { `Psrw (SetCR0,$2,$4,$6) } + | SRAWI reg COMMA reg COMMA k + { `Psrawi (DontSetCR0,$2,$4,$6) } + | SRAWIDOT reg COMMA reg COMMA k + { `Psrawi (SetCR0,$2,$4,$6) } + | SRAW reg COMMA reg COMMA reg + { `Psraw (DontSetCR0,$2,$4,$6) } + | SRAWDOT reg COMMA reg COMMA reg + { `Psraw (SetCR0,$2,$4,$6) } + | SLD reg COMMA reg COMMA reg + { `Psld (DontSetCR0,$2,$4,$6) } + | SLDDOT reg COMMA reg COMMA reg + { `Psld (SetCR0,$2,$4,$6) } + | SRD reg COMMA reg COMMA reg + { `Psrd (DontSetCR0,$2,$4,$6) } + | SRDDOT reg COMMA reg COMMA reg + { `Psrd (SetCR0,$2,$4,$6) } + | SRADI reg COMMA reg COMMA k + { `Psradi (DontSetCR0,$2,$4,$6) } + | SRADIDOT reg COMMA reg COMMA k + { `Psradi (SetCR0,$2,$4,$6) } + | SRAD reg COMMA reg COMMA reg + { `Psrad (DontSetCR0,$2,$4,$6) } + | SRADDOT reg COMMA reg COMMA reg + { `Psrad (SetCR0,$2,$4,$6) } + | CDTBCD reg COMMA reg + { `Pcdtbcd ($2,$4) } + | CBCDTD reg COMMA reg + { `Pcbcdtd ($2,$4) } + | ADDG6S reg COMMA reg COMMA reg + { `Paddg6s ($2,$4,$6) } + | MTSPR k COMMA reg + { `Pmtspr ($2,$4) } + | MFSPR reg COMMA k + { `Pmfspr ($2,$4) } + | MTCRF crmask COMMA reg + { `Pmtcrf ($2,$4) } + | MFCR reg + { `Pmfcr ($2) } + | MTOCRF crmask COMMA reg + { `Pmtocrf ($2,$4) } + | MFOCRF reg COMMA crmask + { `Pmfocrf ($2,$4) } + | MCRXR crindex + { `Pmcrxr ($2) } + | DLMZB reg COMMA reg COMMA reg + { `Pdlmzb (DontSetCR0,$2,$4,$6) } + | DLMZBDOT reg COMMA reg COMMA reg + { `Pdlmzb (SetCR0,$2,$4,$6) } + | MACCHW reg COMMA reg COMMA reg + { `Pmacchw (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACCHWDOT reg COMMA reg COMMA reg + { `Pmacchw (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACCHWO reg COMMA reg COMMA reg + { `Pmacchw (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACCHWODOT reg COMMA reg COMMA reg + { `Pmacchw (SetSOOV,SetCR0,$2,$4,$6) } + | MACCHWS reg COMMA reg COMMA reg + { `Pmacchws (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACCHWSDOT reg COMMA reg COMMA reg + { `Pmacchws (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACCHWSO reg COMMA reg COMMA reg + { `Pmacchws (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACCHWSODOT reg COMMA reg COMMA reg + { `Pmacchws (SetSOOV,SetCR0,$2,$4,$6) } + | MACCHWU reg COMMA reg COMMA reg + { `Pmacchwu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACCHWUDOT reg COMMA reg COMMA reg + { `Pmacchwu (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACCHWUO reg COMMA reg COMMA reg + { `Pmacchwu (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACCHWUODOT reg COMMA reg COMMA reg + { `Pmacchwu (SetSOOV,SetCR0,$2,$4,$6) } + | MACCHWSU reg COMMA reg COMMA reg + { `Pmacchwsu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACCHWSUDOT reg COMMA reg COMMA reg + { `Pmacchwsu (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACCHWSUO reg COMMA reg COMMA reg + { `Pmacchwsu (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACCHWSUODOT reg COMMA reg COMMA reg + { `Pmacchwsu (SetSOOV,SetCR0,$2,$4,$6) } + | MACHHW reg COMMA reg COMMA reg + { `Pmachhw (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACHHWDOT reg COMMA reg COMMA reg + { `Pmachhw (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACHHWO reg COMMA reg COMMA reg + { `Pmachhw (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACHHWODOT reg COMMA reg COMMA reg + { `Pmachhw (SetSOOV,SetCR0,$2,$4,$6) } + | MACHHWS reg COMMA reg COMMA reg + { `Pmachhws (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACHHWSDOT reg COMMA reg COMMA reg + { `Pmachhws (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACHHWSO reg COMMA reg COMMA reg + { `Pmachhws (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACHHWSODOT reg COMMA reg COMMA reg + { `Pmachhws (SetSOOV,SetCR0,$2,$4,$6) } + | MACHHWU reg COMMA reg COMMA reg + { `Pmachhwu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACHHWUDOT reg COMMA reg COMMA reg + { `Pmachhwu (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACHHWUO reg COMMA reg COMMA reg + { `Pmachhwu (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACHHWUODOT reg COMMA reg COMMA reg + { `Pmachhwu (SetSOOV,SetCR0,$2,$4,$6) } + | MACHHWSU reg COMMA reg COMMA reg + { `Pmachhwsu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACHHWSUDOT reg COMMA reg COMMA reg + { `Pmachhwsu (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACHHWSUO reg COMMA reg COMMA reg + { `Pmachhwsu (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACHHWSUODOT reg COMMA reg COMMA reg + { `Pmachhwsu (SetSOOV,SetCR0,$2,$4,$6) } + | MACLHW reg COMMA reg COMMA reg + { `Pmaclhw (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACLHWDOT reg COMMA reg COMMA reg + { `Pmaclhw (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACLHWO reg COMMA reg COMMA reg + { `Pmaclhw (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACLHWODOT reg COMMA reg COMMA reg + { `Pmaclhw (SetSOOV,SetCR0,$2,$4,$6) } + | MACLHWS reg COMMA reg COMMA reg + { `Pmaclhws (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACLHWSDOT reg COMMA reg COMMA reg + { `Pmaclhws (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACLHWSO reg COMMA reg COMMA reg + { `Pmaclhws (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACLHWSODOT reg COMMA reg COMMA reg + { `Pmaclhws (SetSOOV,SetCR0,$2,$4,$6) } + | MACLHWU reg COMMA reg COMMA reg + { `Pmaclhwu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACLHWUDOT reg COMMA reg COMMA reg + { `Pmaclhwu (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACLHWUO reg COMMA reg COMMA reg + { `Pmaclhwu (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACLHWUODOT reg COMMA reg COMMA reg + { `Pmaclhwu (SetSOOV,SetCR0,$2,$4,$6) } + | MACLHWSU reg COMMA reg COMMA reg + { `Pmaclhwsu (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | MACLHWSUDOT reg COMMA reg COMMA reg + { `Pmaclhwsu (DontSetSOOV,SetCR0,$2,$4,$6) } + | MACLHWSUO reg COMMA reg COMMA reg + { `Pmaclhwsu (SetSOOV,DontSetCR0,$2,$4,$6) } + | MACLHWSUODOT reg COMMA reg COMMA reg + { `Pmaclhwsu (SetSOOV,SetCR0,$2,$4,$6) } + | MULCHW reg COMMA reg COMMA reg + { `Pmulchw (DontSetCR0,$2,$4,$6) } + | MULCHWDOT reg COMMA reg COMMA reg + { `Pmulchw (SetCR0,$2,$4,$6) } + | MULCHWU reg COMMA reg COMMA reg + { `Pmulchwu (DontSetCR0,$2,$4,$6) } + | MULCHWUDOT reg COMMA reg COMMA reg + { `Pmulchwu (SetCR0,$2,$4,$6) } + | MULHHW reg COMMA reg COMMA reg + { `Pmulhhw (DontSetCR0,$2,$4,$6) } + | MULHHWDOT reg COMMA reg COMMA reg + { `Pmulhhw (SetCR0,$2,$4,$6) } + | MULHHWU reg COMMA reg COMMA reg + { `Pmulhhwu (DontSetCR0,$2,$4,$6) } + | MULHHWUDOT reg COMMA reg COMMA reg + { `Pmulhhwu (SetCR0,$2,$4,$6) } + | MULLHW reg COMMA reg COMMA reg + { `Pmullhw (DontSetCR0,$2,$4,$6) } + | MULLHWDOT reg COMMA reg COMMA reg + { `Pmullhw (SetCR0,$2,$4,$6) } + | MULLHWU reg COMMA reg COMMA reg + { `Pmullhwu (DontSetCR0,$2,$4,$6) } + | MULLHWUDOT reg COMMA reg COMMA reg + { `Pmullhwu (SetCR0,$2,$4,$6) } + | NMACCHW reg COMMA reg COMMA reg + { `Pnmacchw (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | NMACCHWDOT reg COMMA reg COMMA reg + { `Pnmacchw (DontSetSOOV,SetCR0,$2,$4,$6) } + | NMACCHWO reg COMMA reg COMMA reg + { `Pnmacchw (SetSOOV,DontSetCR0,$2,$4,$6) } + | NMACCHWODOT reg COMMA reg COMMA reg + { `Pnmacchw (SetSOOV,SetCR0,$2,$4,$6) } + | NMACCHWS reg COMMA reg COMMA reg + { `Pnmacchws (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | NMACCHWSDOT reg COMMA reg COMMA reg + { `Pnmacchws (DontSetSOOV,SetCR0,$2,$4,$6) } + | NMACCHWSO reg COMMA reg COMMA reg + { `Pnmacchws (SetSOOV,DontSetCR0,$2,$4,$6) } + | NMACCHWSODOT reg COMMA reg COMMA reg + { `Pnmacchws (SetSOOV,SetCR0,$2,$4,$6) } + | NMACHHW reg COMMA reg COMMA reg + { `Pnmachhw (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | NMACHHWDOT reg COMMA reg COMMA reg + { `Pnmachhw (DontSetSOOV,SetCR0,$2,$4,$6) } + | NMACHHWO reg COMMA reg COMMA reg + { `Pnmachhw (SetSOOV,DontSetCR0,$2,$4,$6) } + | NMACHHWODOT reg COMMA reg COMMA reg + { `Pnmachhw (SetSOOV,SetCR0,$2,$4,$6) } + | NMACHHWS reg COMMA reg COMMA reg + { `Pnmachhws (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | NMACHHWSDOT reg COMMA reg COMMA reg + { `Pnmachhws (DontSetSOOV,SetCR0,$2,$4,$6) } + | NMACHHWSO reg COMMA reg COMMA reg + { `Pnmachhws (SetSOOV,DontSetCR0,$2,$4,$6) } + | NMACHHWSODOT reg COMMA reg COMMA reg + { `Pnmachhws (SetSOOV,SetCR0,$2,$4,$6) } + | NMACLHW reg COMMA reg COMMA reg + { `Pnmaclhw (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | NMACLHWDOT reg COMMA reg COMMA reg + { `Pnmaclhw (DontSetSOOV,SetCR0,$2,$4,$6) } + | NMACLHWO reg COMMA reg COMMA reg + { `Pnmaclhw (SetSOOV,DontSetCR0,$2,$4,$6) } + | NMACLHWODOT reg COMMA reg COMMA reg + { `Pnmaclhw (SetSOOV,SetCR0,$2,$4,$6) } + | NMACLHWS reg COMMA reg COMMA reg + { `Pnmaclhws (DontSetSOOV,DontSetCR0,$2,$4,$6) } + | NMACLHWSDOT reg COMMA reg COMMA reg + { `Pnmaclhws (DontSetSOOV,SetCR0,$2,$4,$6) } + | NMACLHWSO reg COMMA reg COMMA reg + { `Pnmaclhws (SetSOOV,DontSetCR0,$2,$4,$6) } + | NMACLHWSODOT reg COMMA reg COMMA reg + { `Pnmaclhws (SetSOOV,SetCR0,$2,$4,$6) } + | ICBI reg COMMA reg + { `Picbi ($2,$4) } + | ICBT k COMMA reg COMMA reg + { `Picbt ($2,$4,$6) } + | DCBA reg COMMA reg + { `Pdcba ($2,$4) } + | DCBT reg COMMA reg COMMA k + { `Pdcbt ($2,$4,$6) } + | DCBTST reg COMMA reg COMMA k + { `Pdcbtst ($2,$4,$6) } + | DCBZ reg COMMA reg + { `Pdcbz ($2,$4) } + | DCBST reg COMMA reg + { `Pdcbst ($2,$4) } + | DCBF reg COMMA reg COMMA k + { `Pdcbf ($2,$4,$6) } + | ISYNC + { `Pisync } + | LBARX reg COMMA reg COMMA reg COMMA k + { `Plbarx ($2,$4,$6,$8) } + | LHARX reg COMMA reg COMMA reg COMMA k + { `Plharx ($2,$4,$6,$8) } + | LWARX reg COMMA reg COMMA reg COMMA k + { `Plwarx ($2,$4,$6,$8) } + | STBCXDOT reg COMMA reg COMMA reg + { `Pstbcx ($2,$4,$6) } + | STHCXDOT reg COMMA reg COMMA reg + { `Psthcx ($2,$4,$6) } + | STWCXDOT reg COMMA reg COMMA reg + { `Pstwcx ($2,$4,$6) } + | LDARX reg COMMA reg COMMA reg COMMA k + { `Pldarx ($2,$4,$6,$8) } + | STDCXDOT reg COMMA reg COMMA reg + { `Pstdcx ($2,$4,$6) } + | SYNC k + { `Psync ($2) } + | EIEIO + { `Peieio } + | WAIT k + { `Pwait ($2) } diff --git a/power/gen/pretty.gen b/power/gen/pretty.gen new file mode 100644 index 00000000..4a7eff69 --- /dev/null +++ b/power/gen/pretty.gen @@ -0,0 +1,368 @@ +| `Pb (DontSetAA,DontSetLK,target_addr) -> sprintf "b %d" target_addr +| `Pb (SetAA,DontSetLK,target_addr) -> sprintf "ba %d" target_addr +| `Pb (DontSetAA,SetLK,target_addr) -> sprintf "bl %d" target_addr +| `Pb (SetAA,SetLK,target_addr) -> sprintf "bla %d" target_addr +| `Pbc (DontSetAA,DontSetLK,bO,bI,target_addr) -> sprintf "bc %d,%d,%d" bO bI target_addr +| `Pbc (SetAA,DontSetLK,bO,bI,target_addr) -> sprintf "bca %d,%d,%d" bO bI target_addr +| `Pbc (DontSetAA,SetLK,bO,bI,target_addr) -> sprintf "bcl %d,%d,%d" bO bI target_addr +| `Pbc (SetAA,SetLK,bO,bI,target_addr) -> sprintf "bcla %d,%d,%d" bO bI target_addr +| `Pbclr (DontSetLK,bO,bI,bH) -> sprintf "bclr %d,%d,%d" bO bI bH +| `Pbclr (SetLK,bO,bI,bH) -> sprintf "bclrl %d,%d,%d" bO bI bH +| `Pbcctr (DontSetLK,bO,bI,bH) -> sprintf "bcctr %d,%d,%d" bO bI bH +| `Pbcctr (SetLK,bO,bI,bH) -> sprintf "bcctrl %d,%d,%d" bO bI bH +| `Pcrand (bT,bA,bB) -> sprintf "crand %d,%d,%d" bT bA bB +| `Pcrnand (bT,bA,bB) -> sprintf "crnand %d,%d,%d" bT bA bB +| `Pcror (bT,bA,bB) -> sprintf "cror %d,%d,%d" bT bA bB +| `Pcrxor (bT,bA,bB) -> sprintf "crxor %d,%d,%d" bT bA bB +| `Pcrnor (bT,bA,bB) -> sprintf "crnor %d,%d,%d" bT bA bB +| `Pcreqv (bT,bA,bB) -> sprintf "creqv %d,%d,%d" bT bA bB +| `Pcrandc (bT,bA,bB) -> sprintf "crandc %d,%d,%d" bT bA bB +| `Pcrorc (bT,bA,bB) -> sprintf "crorc %d,%d,%d" bT bA bB +| `Pmcrf (bF,bFA) -> sprintf "mcrf %s,%d" (pp_crf bF) bFA +| `Psc (lEV) -> sprintf "sc %d" lEV +| `Pscv (lEV) -> sprintf "scv %d" lEV +| `Plbz (rT,d,rA) -> sprintf "lbz %s,%d(%s)" (pp_reg rT) d (pp_reg rA) +| `Plbzx (rT,rA,rB) -> sprintf "lbzx %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Plbzu (rT,d,rA) -> sprintf "lbzu %s,%d(%s)" (pp_reg rT) d (pp_reg rA) +| `Plbzux (rT,rA,rB) -> sprintf "lbzux %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Plhz (rT,d,rA) -> sprintf "lhz %s,%d(%s)" (pp_reg rT) d (pp_reg rA) +| `Plhzx (rT,rA,rB) -> sprintf "lhzx %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Plhzu (rT,d,rA) -> sprintf "lhzu %s,%d(%s)" (pp_reg rT) d (pp_reg rA) +| `Plhzux (rT,rA,rB) -> sprintf "lhzux %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Plha (rT,d,rA) -> sprintf "lha %s,%d(%s)" (pp_reg rT) d (pp_reg rA) +| `Plhax (rT,rA,rB) -> sprintf "lhax %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Plhau (rT,d,rA) -> sprintf "lhau %s,%d(%s)" (pp_reg rT) d (pp_reg rA) +| `Plhaux (rT,rA,rB) -> sprintf "lhaux %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Plwz (rT,d,rA) -> sprintf "lwz %s,%d(%s)" (pp_reg rT) d (pp_reg rA) +| `Plwzx (rT,rA,rB) -> sprintf "lwzx %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Plwzu (rT,d,rA) -> sprintf "lwzu %s,%d(%s)" (pp_reg rT) d (pp_reg rA) +| `Plwzux (rT,rA,rB) -> sprintf "lwzux %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Plwa (rT,dS,rA) -> sprintf "lwa %s,%s(%s)" (pp_reg rT) (pp_ds dS) (pp_reg rA) +| `Plwax (rT,rA,rB) -> sprintf "lwax %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Plwaux (rT,rA,rB) -> sprintf "lwaux %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pld (rT,dS,rA) -> sprintf "ld %s,%s(%s)" (pp_reg rT) (pp_ds dS) (pp_reg rA) +| `Pldx (rT,rA,rB) -> sprintf "ldx %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pldu (rT,dS,rA) -> sprintf "ldu %s,%s(%s)" (pp_reg rT) (pp_ds dS) (pp_reg rA) +| `Pldux (rT,rA,rB) -> sprintf "ldux %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pstb (rS,d,rA) -> sprintf "stb %s,%d(%s)" (pp_reg rS) d (pp_reg rA) +| `Pstbx (rS,rA,rB) -> sprintf "stbx %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Pstbu (rS,d,rA) -> sprintf "stbu %s,%d(%s)" (pp_reg rS) d (pp_reg rA) +| `Pstbux (rS,rA,rB) -> sprintf "stbux %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Psth (rS,d,rA) -> sprintf "sth %s,%d(%s)" (pp_reg rS) d (pp_reg rA) +| `Psthx (rS,rA,rB) -> sprintf "sthx %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Psthu (rS,d,rA) -> sprintf "sthu %s,%d(%s)" (pp_reg rS) d (pp_reg rA) +| `Psthux (rS,rA,rB) -> sprintf "sthux %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Pstw (rS,d,rA) -> sprintf "stw %s,%d(%s)" (pp_reg rS) d (pp_reg rA) +| `Pstwx (rS,rA,rB) -> sprintf "stwx %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Pstwu (rS,d,rA) -> sprintf "stwu %s,%d(%s)" (pp_reg rS) d (pp_reg rA) +| `Pstwux (rS,rA,rB) -> sprintf "stwux %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Pstd (rS,dS,rA) -> sprintf "std %s,%s(%s)" (pp_reg rS) (pp_ds dS) (pp_reg rA) +| `Pstdx (rS,rA,rB) -> sprintf "stdx %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Pstdu (rS,dS,rA) -> sprintf "stdu %s,%s(%s)" (pp_reg rS) (pp_ds dS) (pp_reg rA) +| `Pstdux (rS,rA,rB) -> sprintf "stdux %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Plq (rTp,dQ,rA,pT) -> sprintf "lq %d,%d(%s),%d" rTp dQ (pp_reg rA) pT +| `Pstq (rSp,dS,rA) -> sprintf "stq %d,%s(%s)" rSp (pp_ds dS) (pp_reg rA) +| `Plhbrx (rT,rA,rB) -> sprintf "lhbrx %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psthbrx (rS,rA,rB) -> sprintf "sthbrx %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Plwbrx (rT,rA,rB) -> sprintf "lwbrx %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pstwbrx (rS,rA,rB) -> sprintf "stwbrx %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Pldbrx (rT,rA,rB) -> sprintf "ldbrx %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pstdbrx (rS,rA,rB) -> sprintf "stdbrx %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Plmw (rT,d,rA) -> sprintf "lmw %s,%d(%s)" (pp_reg rT) d (pp_reg rA) +| `Pstmw (rS,d,rA) -> sprintf "stmw %s,%d(%s)" (pp_reg rS) d (pp_reg rA) +| `Plswi (rT,rA,nB) -> sprintf "lswi %d,%s,%d" rT (pp_reg rA) nB +| `Plswx (rT,rA,rB) -> sprintf "lswx %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pstswi (rS,rA,nB) -> sprintf "stswi %d,%s,%d" rS (pp_reg rA) nB +| `Pstswx (rS,rA,rB) -> sprintf "stswx %d,%s,%s" rS (pp_reg rA) (pp_reg rB) +| `Paddi (rT,rA,sI) -> sprintf "addi %s,%s,%d" (pp_reg rT) (pp_reg rA) sI +| `Paddis (rT,rA,sI) -> sprintf "addis %s,%s,%d" (pp_reg rT) (pp_reg rA) sI +| `Padd (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "add %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Padd (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "add. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Padd (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "addo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Padd (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "addo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubf (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "subf %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubf (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "subf. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubf (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "subfo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubf (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "subfo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Paddic (rT,rA,sI) -> sprintf "addic %s,%s,%d" (pp_reg rT) (pp_reg rA) sI +| `Paddicdot (rT,rA,sI) -> sprintf "addic. %s,%s,%d" (pp_reg rT) (pp_reg rA) sI +| `Psubfic (rT,rA,sI) -> sprintf "subfic %s,%s,%d" (pp_reg rT) (pp_reg rA) sI +| `Paddc (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "addc %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Paddc (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "addc. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Paddc (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "addco %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Paddc (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "addco. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubfc (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "subfc %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubfc (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "subfc. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubfc (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "subfco %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubfc (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "subfco. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Padde (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "adde %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Padde (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "adde. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Padde (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "addeo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Padde (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "addeo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubfe (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "subfe %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubfe (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "subfe. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubfe (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "subfeo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Psubfe (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "subfeo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Paddme (DontSetSOOV,DontSetCR0,rT,rA) -> sprintf "addme %s,%s" (pp_reg rT) (pp_reg rA) +| `Paddme (DontSetSOOV,SetCR0,rT,rA) -> sprintf "addme. %s,%s" (pp_reg rT) (pp_reg rA) +| `Paddme (SetSOOV,DontSetCR0,rT,rA) -> sprintf "addmeo %s,%s" (pp_reg rT) (pp_reg rA) +| `Paddme (SetSOOV,SetCR0,rT,rA) -> sprintf "addmeo. %s,%s" (pp_reg rT) (pp_reg rA) +| `Psubfme (DontSetSOOV,DontSetCR0,rT,rA) -> sprintf "subfme %s,%s" (pp_reg rT) (pp_reg rA) +| `Psubfme (DontSetSOOV,SetCR0,rT,rA) -> sprintf "subfme. %s,%s" (pp_reg rT) (pp_reg rA) +| `Psubfme (SetSOOV,DontSetCR0,rT,rA) -> sprintf "subfmeo %s,%s" (pp_reg rT) (pp_reg rA) +| `Psubfme (SetSOOV,SetCR0,rT,rA) -> sprintf "subfmeo. %s,%s" (pp_reg rT) (pp_reg rA) +| `Paddze (DontSetSOOV,DontSetCR0,rT,rA) -> sprintf "addze %s,%s" (pp_reg rT) (pp_reg rA) +| `Paddze (DontSetSOOV,SetCR0,rT,rA) -> sprintf "addze. %s,%s" (pp_reg rT) (pp_reg rA) +| `Paddze (SetSOOV,DontSetCR0,rT,rA) -> sprintf "addzeo %s,%s" (pp_reg rT) (pp_reg rA) +| `Paddze (SetSOOV,SetCR0,rT,rA) -> sprintf "addzeo. %s,%s" (pp_reg rT) (pp_reg rA) +| `Psubfze (DontSetSOOV,DontSetCR0,rT,rA) -> sprintf "subfze %s,%s" (pp_reg rT) (pp_reg rA) +| `Psubfze (DontSetSOOV,SetCR0,rT,rA) -> sprintf "subfze. %s,%s" (pp_reg rT) (pp_reg rA) +| `Psubfze (SetSOOV,DontSetCR0,rT,rA) -> sprintf "subfzeo %s,%s" (pp_reg rT) (pp_reg rA) +| `Psubfze (SetSOOV,SetCR0,rT,rA) -> sprintf "subfzeo. %s,%s" (pp_reg rT) (pp_reg rA) +| `Pneg (DontSetSOOV,DontSetCR0,rT,rA) -> sprintf "neg %s,%s" (pp_reg rT) (pp_reg rA) +| `Pneg (DontSetSOOV,SetCR0,rT,rA) -> sprintf "neg. %s,%s" (pp_reg rT) (pp_reg rA) +| `Pneg (SetSOOV,DontSetCR0,rT,rA) -> sprintf "nego %s,%s" (pp_reg rT) (pp_reg rA) +| `Pneg (SetSOOV,SetCR0,rT,rA) -> sprintf "nego. %s,%s" (pp_reg rT) (pp_reg rA) +| `Pmulli (rT,rA,sI) -> sprintf "mulli %s,%s,%d" (pp_reg rT) (pp_reg rA) sI +| `Pmullw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "mullw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmullw (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "mullw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmullw (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "mullwo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmullw (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "mullwo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhw (DontSetCR0,rT,rA,rB) -> sprintf "mulhw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhw (SetCR0,rT,rA,rB) -> sprintf "mulhw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhwu (DontSetCR0,rT,rA,rB) -> sprintf "mulhwu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhwu (SetCR0,rT,rA,rB) -> sprintf "mulhwu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivw (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "divw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivw (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divwo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivw (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "divwo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divwu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivwu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "divwu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivwu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divwuo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivwu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "divwuo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivwe (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divwe %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivwe (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "divwe. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivwe (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divweo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivwe (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "divweo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivweu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divweu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivweu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "divweu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivweu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divweuo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivweu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "divweuo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulld (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "mulld %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulld (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "mulld. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulld (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "mulldo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulld (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "mulldo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhd (DontSetCR0,rT,rA,rB) -> sprintf "mulhd %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhd (SetCR0,rT,rA,rB) -> sprintf "mulhd. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhdu (DontSetCR0,rT,rA,rB) -> sprintf "mulhdu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhdu (SetCR0,rT,rA,rB) -> sprintf "mulhdu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivd (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divd %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivd (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "divd. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivd (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divdo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivd (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "divdo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivdu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divdu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivdu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "divdu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivdu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divduo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivdu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "divduo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivde (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divde %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivde (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "divde. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivde (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divdeo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivde (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "divdeo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivdeu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divdeu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivdeu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "divdeu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivdeu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "divdeuo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pdivdeu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "divdeuo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pcmpi (bF,l,rA,sI) -> sprintf "cmpi %s,%d,%s,%d" (pp_crf bF) l (pp_reg rA) sI +| `Pcmp (bF,l,rA,rB) -> sprintf "cmp %s,%d,%s,%s" (pp_crf bF) l (pp_reg rA) (pp_reg rB) +| `Pcmpli (bF,l,rA,uI) -> sprintf "cmpli %s,%d,%s,%d" (pp_crf bF) l (pp_reg rA) uI +| `Pcmpl (bF,l,rA,rB) -> sprintf "cmpl %s,%d,%s,%s" (pp_crf bF) l (pp_reg rA) (pp_reg rB) +| `Pisel (rT,rA,rB,bC) -> sprintf "isel %s,%s,%s,%d" (pp_reg rT) (pp_reg rA) (pp_reg rB) bC +| `Pandi (rA,rS,uI) -> sprintf "andi. %s,%s,%d" (pp_reg rA) (pp_reg rS) uI +| `Pandis (rA,rS,uI) -> sprintf "andis. %s,%s,%d" (pp_reg rA) (pp_reg rS) uI +| `Pori (rA,rS,uI) -> sprintf "ori %s,%s,%d" (pp_reg rA) (pp_reg rS) uI +| `Poris (rA,rS,uI) -> sprintf "oris %s,%s,%d" (pp_reg rA) (pp_reg rS) uI +| `Pxori (rA,rS,uI) -> sprintf "xori %s,%s,%d" (pp_reg rA) (pp_reg rS) uI +| `Pxoris (rA,rS,uI) -> sprintf "xoris %s,%s,%d" (pp_reg rA) (pp_reg rS) uI +| `Pand (DontSetCR0,rA,rS,rB) -> sprintf "and %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pand (SetCR0,rA,rS,rB) -> sprintf "and. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pxor (DontSetCR0,rA,rS,rB) -> sprintf "xor %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pxor (SetCR0,rA,rS,rB) -> sprintf "xor. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pnand (DontSetCR0,rA,rS,rB) -> sprintf "nand %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pnand (SetCR0,rA,rS,rB) -> sprintf "nand. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Por (DontSetCR0,rA,rS,rB) -> sprintf "or %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Por (SetCR0,rA,rS,rB) -> sprintf "or. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pnor (DontSetCR0,rA,rS,rB) -> sprintf "nor %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pnor (SetCR0,rA,rS,rB) -> sprintf "nor. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Peqv (DontSetCR0,rA,rS,rB) -> sprintf "eqv %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Peqv (SetCR0,rA,rS,rB) -> sprintf "eqv. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pandc (DontSetCR0,rA,rS,rB) -> sprintf "andc %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pandc (SetCR0,rA,rS,rB) -> sprintf "andc. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Porc (DontSetCR0,rA,rS,rB) -> sprintf "orc %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Porc (SetCR0,rA,rS,rB) -> sprintf "orc. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pextsb (DontSetCR0,rA,rS) -> sprintf "extsb %s,%s" (pp_reg rA) (pp_reg rS) +| `Pextsb (SetCR0,rA,rS) -> sprintf "extsb. %s,%s" (pp_reg rA) (pp_reg rS) +| `Pextsh (DontSetCR0,rA,rS) -> sprintf "extsh %s,%s" (pp_reg rA) (pp_reg rS) +| `Pextsh (SetCR0,rA,rS) -> sprintf "extsh. %s,%s" (pp_reg rA) (pp_reg rS) +| `Pcntlzw (DontSetCR0,rA,rS) -> sprintf "cntlzw %s,%s" (pp_reg rA) (pp_reg rS) +| `Pcntlzw (SetCR0,rA,rS) -> sprintf "cntlzw. %s,%s" (pp_reg rA) (pp_reg rS) +| `Pcmpb (rA,rS,rB) -> sprintf "cmpb %s,%d,%s" (pp_reg rA) rS (pp_reg rB) +| `Ppopcntb (rA,rS) -> sprintf "popcntb %s,%s" (pp_reg rA) (pp_reg rS) +| `Ppopcntw (rA,rS) -> sprintf "popcntw %s,%s" (pp_reg rA) (pp_reg rS) +| `Pprtyd (rA,rS) -> sprintf "prtyd %s,%s" (pp_reg rA) (pp_reg rS) +| `Pprtyw (rA,rS) -> sprintf "prtyw %s,%s" (pp_reg rA) (pp_reg rS) +| `Pextsw (DontSetCR0,rA,rS) -> sprintf "extsw %s,%s" (pp_reg rA) (pp_reg rS) +| `Pextsw (SetCR0,rA,rS) -> sprintf "extsw. %s,%s" (pp_reg rA) (pp_reg rS) +| `Pcntlzd (DontSetCR0,rA,rS) -> sprintf "cntlzd %s,%s" (pp_reg rA) (pp_reg rS) +| `Pcntlzd (SetCR0,rA,rS) -> sprintf "cntlzd. %s,%s" (pp_reg rA) (pp_reg rS) +| `Ppopcntd (rA,rS) -> sprintf "popcntd %s,%s" (pp_reg rA) (pp_reg rS) +| `Pbpermd (rA,rS,rB) -> sprintf "bpermd %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Prlwinm (DontSetCR0,rA,rS,sH,mB,mE) -> sprintf "rlwinm %s,%s,%d,%d,%d" (pp_reg rA) (pp_reg rS) sH mB mE +| `Prlwinm (SetCR0,rA,rS,sH,mB,mE) -> sprintf "rlwinm. %s,%s,%d,%d,%d" (pp_reg rA) (pp_reg rS) sH mB mE +| `Prlwnm (DontSetCR0,rA,rS,rB,mB,mE) -> sprintf "rlwnm %s,%s,%s,%d,%d" (pp_reg rA) (pp_reg rS) (pp_reg rB) mB mE +| `Prlwnm (SetCR0,rA,rS,rB,mB,mE) -> sprintf "rlwnm. %s,%s,%s,%d,%d" (pp_reg rA) (pp_reg rS) (pp_reg rB) mB mE +| `Prlwimi (DontSetCR0,rA,rS,sH,mB,mE) -> sprintf "rlwimi %s,%s,%d,%d,%d" (pp_reg rA) (pp_reg rS) sH mB mE +| `Prlwimi (SetCR0,rA,rS,sH,mB,mE) -> sprintf "rlwimi. %s,%s,%d,%d,%d" (pp_reg rA) (pp_reg rS) sH mB mE +| `Prldicl (DontSetCR0,rA,rS,sH,mB) -> sprintf "rldicl %s,%s,%d,%d" (pp_reg rA) (pp_reg rS) sH mB +| `Prldicl (SetCR0,rA,rS,sH,mB) -> sprintf "rldicl. %s,%s,%d,%d" (pp_reg rA) (pp_reg rS) sH mB +| `Prldicr (DontSetCR0,rA,rS,sH,mE) -> sprintf "rldicr %s,%s,%d,%d" (pp_reg rA) (pp_reg rS) sH mE +| `Prldicr (SetCR0,rA,rS,sH,mE) -> sprintf "rldicr. %s,%s,%d,%d" (pp_reg rA) (pp_reg rS) sH mE +| `Prldic (DontSetCR0,rA,rS,sH,mB) -> sprintf "rldic %s,%s,%d,%d" (pp_reg rA) (pp_reg rS) sH mB +| `Prldic (SetCR0,rA,rS,sH,mB) -> sprintf "rldic. %s,%s,%d,%d" (pp_reg rA) (pp_reg rS) sH mB +| `Prldcl (DontSetCR0,rA,rS,rB,mB) -> sprintf "rldcl %s,%s,%s,%d" (pp_reg rA) (pp_reg rS) (pp_reg rB) mB +| `Prldcl (SetCR0,rA,rS,rB,mB) -> sprintf "rldcl. %s,%s,%s,%d" (pp_reg rA) (pp_reg rS) (pp_reg rB) mB +| `Prldcr (DontSetCR0,rA,rS,rB,mE) -> sprintf "rldcr %s,%s,%s,%d" (pp_reg rA) (pp_reg rS) (pp_reg rB) mE +| `Prldcr (SetCR0,rA,rS,rB,mE) -> sprintf "rldcr. %s,%s,%s,%d" (pp_reg rA) (pp_reg rS) (pp_reg rB) mE +| `Prldimi (DontSetCR0,rA,rS,sH,mB) -> sprintf "rldimi %s,%s,%d,%d" (pp_reg rA) (pp_reg rS) sH mB +| `Prldimi (SetCR0,rA,rS,sH,mB) -> sprintf "rldimi. %s,%s,%d,%d" (pp_reg rA) (pp_reg rS) sH mB +| `Pslw (DontSetCR0,rA,rS,rB) -> sprintf "slw %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pslw (SetCR0,rA,rS,rB) -> sprintf "slw. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psrw (DontSetCR0,rA,rS,rB) -> sprintf "srw %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psrw (SetCR0,rA,rS,rB) -> sprintf "srw. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psrawi (DontSetCR0,rA,rS,sH) -> sprintf "srawi %s,%s,%d" (pp_reg rA) (pp_reg rS) sH +| `Psrawi (SetCR0,rA,rS,sH) -> sprintf "srawi. %s,%s,%d" (pp_reg rA) (pp_reg rS) sH +| `Psraw (DontSetCR0,rA,rS,rB) -> sprintf "sraw %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psraw (SetCR0,rA,rS,rB) -> sprintf "sraw. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psld (DontSetCR0,rA,rS,rB) -> sprintf "sld %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psld (SetCR0,rA,rS,rB) -> sprintf "sld. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psrd (DontSetCR0,rA,rS,rB) -> sprintf "srd %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psrd (SetCR0,rA,rS,rB) -> sprintf "srd. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psradi (DontSetCR0,rA,rS,sH) -> sprintf "sradi %s,%s,%d" (pp_reg rA) (pp_reg rS) sH +| `Psradi (SetCR0,rA,rS,sH) -> sprintf "sradi. %s,%s,%d" (pp_reg rA) (pp_reg rS) sH +| `Psrad (DontSetCR0,rA,rS,rB) -> sprintf "srad %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Psrad (SetCR0,rA,rS,rB) -> sprintf "srad. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pcdtbcd (rA,rS) -> sprintf "cdtbcd %s,%s" (pp_reg rA) (pp_reg rS) +| `Pcbcdtd (rA,rS) -> sprintf "cbcdtd %s,%s" (pp_reg rA) (pp_reg rS) +| `Paddg6s (rT,rA,rB) -> sprintf "addg6s %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmtspr (sPR,rS) -> sprintf "mtspr %d,%s" sPR (pp_reg rS) +| `Pmfspr (rT,sPR) -> sprintf "mfspr %s,%d" (pp_reg rT) sPR +| `Pmtcrf (fXM,rS) -> sprintf "mtcrf %d,%s" fXM (pp_reg rS) +| `Pmfcr (rT) -> sprintf "mfcr %s" (pp_reg rT) +| `Pmtocrf (fXM,rS) -> sprintf "mtocrf %d,%s" fXM (pp_reg rS) +| `Pmfocrf (rT,fXM) -> sprintf "mfocrf %s,%d" (pp_reg rT) fXM +| `Pmcrxr (bF) -> sprintf "mcrxr %s" (pp_crf bF) +| `Pdlmzb (DontSetCR0,rA,rS,rB) -> sprintf "dlmzb %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pdlmzb (SetCR0,rA,rS,rB) -> sprintf "dlmzb. %s,%s,%s" (pp_reg rA) (pp_reg rS) (pp_reg rB) +| `Pmacchw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "macchw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchw (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "macchw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchw (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "macchwo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchw (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "macchwo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "macchws %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchws (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "macchws. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchws (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "macchwso %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchws (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "macchwso. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "macchwu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchwu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "macchwu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchwu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "macchwuo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchwu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "macchwuo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "macchwsu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "macchwsu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "macchwsuo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmacchwsu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "macchwsuo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "machhw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhw (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "machhw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhw (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "machhwo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhw (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "machhwo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "machhws %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhws (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "machhws. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhws (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "machhwso %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhws (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "machhwso. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "machhwu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhwu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "machhwu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhwu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "machhwuo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhwu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "machhwuo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "machhwsu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "machhwsu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "machhwsuo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmachhwsu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "machhwsuo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "maclhw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhw (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "maclhw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhw (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "maclhwo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhw (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "maclhwo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "maclhws %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhws (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "maclhws. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhws (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "maclhwso %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhws (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "maclhwso. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhwu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "maclhwu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhwu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "maclhwu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhwu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "maclhwuo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhwu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "maclhwuo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhwsu (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "maclhwsu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhwsu (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "maclhwsu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhwsu (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "maclhwsuo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmaclhwsu (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "maclhwsuo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulchw (DontSetCR0,rT,rA,rB) -> sprintf "mulchw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulchw (SetCR0,rT,rA,rB) -> sprintf "mulchw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulchwu (DontSetCR0,rT,rA,rB) -> sprintf "mulchwu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulchwu (SetCR0,rT,rA,rB) -> sprintf "mulchwu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhhw (DontSetCR0,rT,rA,rB) -> sprintf "mulhhw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhhw (SetCR0,rT,rA,rB) -> sprintf "mulhhw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhhwu (DontSetCR0,rT,rA,rB) -> sprintf "mulhhwu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmulhhwu (SetCR0,rT,rA,rB) -> sprintf "mulhhwu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmullhw (DontSetCR0,rT,rA,rB) -> sprintf "mullhw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmullhw (SetCR0,rT,rA,rB) -> sprintf "mullhw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmullhwu (DontSetCR0,rT,rA,rB) -> sprintf "mullhwu %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pmullhwu (SetCR0,rT,rA,rB) -> sprintf "mullhwu. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmacchw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmacchw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmacchw (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmacchw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmacchw (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmacchwo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmacchw (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmacchwo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmacchws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmacchws %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmacchws (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmacchws. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmacchws (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmacchwso %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmacchws (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmacchwso. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmachhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmachhw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmachhw (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmachhw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmachhw (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmachhwo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmachhw (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmachhwo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmachhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmachhws %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmachhws (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmachhws. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmachhws (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmachhwso %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmachhws (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmachhwso. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmaclhw (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmaclhw %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmaclhw (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmaclhw. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmaclhw (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmaclhwo %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmaclhw (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmaclhwo. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmaclhws (DontSetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmaclhws %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmaclhws (DontSetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmaclhws. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmaclhws (SetSOOV,DontSetCR0,rT,rA,rB) -> sprintf "nmaclhwso %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Pnmaclhws (SetSOOV,SetCR0,rT,rA,rB) -> sprintf "nmaclhwso. %s,%s,%s" (pp_reg rT) (pp_reg rA) (pp_reg rB) +| `Picbi (rA,rB) -> sprintf "icbi %s,%s" (pp_reg rA) (pp_reg rB) +| `Picbt (cT,rA,rB) -> sprintf "icbt %d,%s,%s" cT (pp_reg rA) (pp_reg rB) +| `Pdcba (rA,rB) -> sprintf "dcba %s,%s" (pp_reg rA) (pp_reg rB) +| `Pdcbt (rA,rB,tH) -> sprintf "dcbt %s,%s,%d" (pp_reg rA) (pp_reg rB) tH +| `Pdcbtst (rA,rB,tH) -> sprintf "dcbtst %s,%s,%d" (pp_reg rA) (pp_reg rB) tH +| `Pdcbz (rA,rB) -> sprintf "dcbz %s,%s" (pp_reg rA) (pp_reg rB) +| `Pdcbst (rA,rB) -> sprintf "dcbst %s,%s" (pp_reg rA) (pp_reg rB) +| `Pdcbf (rA,rB,l) -> sprintf "dcbf %s,%s,%d" (pp_reg rA) (pp_reg rB) l +| `Pisync -> sprintf "isync " +| `Plbarx (rT,rA,rB,eH) -> sprintf "lbarx %s,%s,%s,%d" (pp_reg rT) (pp_reg rA) (pp_reg rB) eH +| `Plharx (rT,rA,rB,eH) -> sprintf "lharx %s,%s,%s,%d" (pp_reg rT) (pp_reg rA) (pp_reg rB) eH +| `Plwarx (rT,rA,rB,eH) -> sprintf "lwarx %s,%s,%s,%d" (pp_reg rT) (pp_reg rA) (pp_reg rB) eH +| `Pstbcx (rS,rA,rB) -> sprintf "stbcx. %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Psthcx (rS,rA,rB) -> sprintf "sthcx. %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Pstwcx (rS,rA,rB) -> sprintf "stwcx. %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Pldarx (rT,rA,rB,eH) -> sprintf "ldarx %s,%s,%s,%d" (pp_reg rT) (pp_reg rA) (pp_reg rB) eH +| `Pstdcx (rS,rA,rB) -> sprintf "stdcx. %s,%s,%s" (pp_reg rS) (pp_reg rA) (pp_reg rB) +| `Psync (l) -> sprintf "sync %d" l +| `Peieio -> sprintf "eieio " +| `Pwait (wC) -> sprintf "wait %d" wC diff --git a/power/gen/sail_trans_out.gen b/power/gen/sail_trans_out.gen new file mode 100644 index 00000000..09d3cdbf --- /dev/null +++ b/power/gen/sail_trans_out.gen @@ -0,0 +1,1112 @@ + | ("B", [li; aa; lk], _) -> + `Pb( + (trans_out_aa aa), + (trans_out_lk lk), + (trans_out_int (trans_out_li_setaa_setlk_k3 li aa lk))) + | ("Bc", [bo; bi; bd; aa; lk], _) -> + `Pbc( + (trans_out_aa aa), + (trans_out_lk lk), + (trans_out_int bo), + (trans_out_int bi), + (trans_out_int (trans_out_bd_setaa_setlk_k_k_k5 bo bi bd aa lk))) + | ("Bclr", [bo; bi; bh; lk], _) -> + `Pbclr( + (trans_out_lk lk), + (trans_out_int bo), + (trans_out_int bi), + (trans_out_int bh)) + | ("Bcctr", [bo; bi; bh; lk], _) -> + `Pbcctr( + (trans_out_lk lk), + (trans_out_int bo), + (trans_out_int bi), + (trans_out_int bh)) + | ("Crand", [bt; ba; bb], _) -> + `Pcrand( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | ("Crnand", [bt; ba; bb], _) -> + `Pcrnand( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | ("Cror", [bt; ba; bb], _) -> + `Pcror( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | ("Crxor", [bt; ba; bb], _) -> + `Pcrxor( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | ("Crnor", [bt; ba; bb], _) -> + `Pcrnor( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | ("Creqv", [bt; ba; bb], _) -> + `Pcreqv( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | ("Crandc", [bt; ba; bb], _) -> + `Pcrandc( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | ("Crorc", [bt; ba; bb], _) -> + `Pcrorc( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | ("Mcrf", [bf; bfa], _) -> + `Pmcrf( + (trans_out_int bf), + (trans_out_int bfa)) + | ("Sc", [lev], _) -> + `Psc( + (trans_out_int lev)) + | ("Scv", [lev], _) -> + `Pscv( + (trans_out_int lev)) + | ("Lbz", [rt; ra; d], _) -> + `Plbz( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | ("Lbzx", [rt; ra; rb], _) -> + `Plbzx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lbzu", [rt; ra; d], _) -> + `Plbzu( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | ("Lbzux", [rt; ra; rb], _) -> + `Plbzux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lhz", [rt; ra; d], _) -> + `Plhz( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | ("Lhzx", [rt; ra; rb], _) -> + `Plhzx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lhzu", [rt; ra; d], _) -> + `Plhzu( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | ("Lhzux", [rt; ra; rb], _) -> + `Plhzux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lha", [rt; ra; d], _) -> + `Plha( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | ("Lhax", [rt; ra; rb], _) -> + `Plhax( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lhau", [rt; ra; d], _) -> + `Plhau( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | ("Lhaux", [rt; ra; rb], _) -> + `Plhaux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lwz", [rt; ra; d], _) -> + `Plwz( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | ("Lwzx", [rt; ra; rb], _) -> + `Plwzx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lwzu", [rt; ra; d], _) -> + `Plwzu( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | ("Lwzux", [rt; ra; rb], _) -> + `Plwzux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lwa", [rt; ra; ds], _) -> + `Plwa( + (trans_out_reg rt), + (trans_out_int ds), + (trans_out_reg ra)) + | ("Lwax", [rt; ra; rb], _) -> + `Plwax( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lwaux", [rt; ra; rb], _) -> + `Plwaux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Ld", [rt; ra; ds], _) -> + `Pld( + (trans_out_reg rt), + (trans_out_int ds), + (trans_out_reg ra)) + | ("Ldx", [rt; ra; rb], _) -> + `Pldx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Ldu", [rt; ra; ds], _) -> + `Pldu( + (trans_out_reg rt), + (trans_out_int ds), + (trans_out_reg ra)) + | ("Ldux", [rt; ra; rb], _) -> + `Pldux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Stb", [rs; ra; d], _) -> + `Pstb( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | ("Stbx", [rs; ra; rb], _) -> + `Pstbx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Stbu", [rs; ra; d], _) -> + `Pstbu( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | ("Stbux", [rs; ra; rb], _) -> + `Pstbux( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Sth", [rs; ra; d], _) -> + `Psth( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | ("Sthx", [rs; ra; rb], _) -> + `Psthx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Sthu", [rs; ra; d], _) -> + `Psthu( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | ("Sthux", [rs; ra; rb], _) -> + `Psthux( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Stw", [rs; ra; d], _) -> + `Pstw( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | ("Stwx", [rs; ra; rb], _) -> + `Pstwx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Stwu", [rs; ra; d], _) -> + `Pstwu( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | ("Stwux", [rs; ra; rb], _) -> + `Pstwux( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Std", [rs; ra; ds], _) -> + `Pstd( + (trans_out_reg rs), + (trans_out_int ds), + (trans_out_reg ra)) + | ("Stdx", [rs; ra; rb], _) -> + `Pstdx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Stdu", [rs; ra; ds], _) -> + `Pstdu( + (trans_out_reg rs), + (trans_out_int ds), + (trans_out_reg ra)) + | ("Stdux", [rs; ra; rb], _) -> + `Pstdux( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lq", [rtp; ra; dq; pt], _) -> + `Plq( + (trans_out_int rtp), + (trans_out_int dq), + (trans_out_reg ra), + (trans_out_int pt)) + | ("Stq", [rsp; ra; ds], _) -> + `Pstq( + (trans_out_int rsp), + (trans_out_int ds), + (trans_out_reg ra)) + | ("Lhbrx", [rt; ra; rb], _) -> + `Plhbrx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Sthbrx", [rs; ra; rb], _) -> + `Psthbrx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lwbrx", [rt; ra; rb], _) -> + `Plwbrx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Stwbrx", [rs; ra; rb], _) -> + `Pstwbrx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Ldbrx", [rt; ra; rb], _) -> + `Pldbrx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Stdbrx", [rs; ra; rb], _) -> + `Pstdbrx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Lmw", [rt; ra; d], _) -> + `Plmw( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | ("Stmw", [rs; ra; d], _) -> + `Pstmw( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | ("Lswi", [rt; ra; nb], _) -> + `Plswi( + (trans_out_int rt), + (trans_out_reg ra), + (trans_out_int nb)) + | ("Lswx", [rt; ra; rb], _) -> + `Plswx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Stswi", [rs; ra; nb], _) -> + `Pstswi( + (trans_out_int rs), + (trans_out_reg ra), + (trans_out_int nb)) + | ("Stswx", [rs; ra; rb], _) -> + `Pstswx( + (trans_out_int rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Addi", [rt; ra; si], _) -> + `Paddi( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | ("Addis", [rt; ra; si], _) -> + `Paddis( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | ("Add", [rt; ra; rb; oe; rc], _) -> + `Padd( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Subf", [rt; ra; rb; oe; rc], _) -> + `Psubf( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Addic", [rt; ra; si], _) -> + `Paddic( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | ("AddicDot", [rt; ra; si], _) -> + `Paddicdot( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | ("Subfic", [rt; ra; si], _) -> + `Psubfic( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | ("Addc", [rt; ra; rb; oe; rc], _) -> + `Paddc( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Subfc", [rt; ra; rb; oe; rc], _) -> + `Psubfc( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Adde", [rt; ra; rb; oe; rc], _) -> + `Padde( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Subfe", [rt; ra; rb; oe; rc], _) -> + `Psubfe( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Addme", [rt; ra; oe; rc], _) -> + `Paddme( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | ("Subfme", [rt; ra; oe; rc], _) -> + `Psubfme( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | ("Addze", [rt; ra; oe; rc], _) -> + `Paddze( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | ("Subfze", [rt; ra; oe; rc], _) -> + `Psubfze( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | ("Neg", [rt; ra; oe; rc], _) -> + `Pneg( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | ("Mulli", [rt; ra; si], _) -> + `Pmulli( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | ("Mullw", [rt; ra; rb; oe; rc], _) -> + `Pmullw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mulhw", [rt; ra; rb; rc], _) -> + `Pmulhw( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mulhwu", [rt; ra; rb; rc], _) -> + `Pmulhwu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Divw", [rt; ra; rb; oe; rc], _) -> + `Pdivw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Divwu", [rt; ra; rb; oe; rc], _) -> + `Pdivwu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Divwe", [rt; ra; rb; oe; rc], _) -> + `Pdivwe( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Divweu", [rt; ra; rb; oe; rc], _) -> + `Pdivweu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mulld", [rt; ra; rb; oe; rc], _) -> + `Pmulld( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mulhd", [rt; ra; rb; rc], _) -> + `Pmulhd( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mulhdu", [rt; ra; rb; rc], _) -> + `Pmulhdu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Divd", [rt; ra; rb; oe; rc], _) -> + `Pdivd( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Divdu", [rt; ra; rb; oe; rc], _) -> + `Pdivdu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Divde", [rt; ra; rb; oe; rc], _) -> + `Pdivde( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Divdeu", [rt; ra; rb; oe; rc], _) -> + `Pdivdeu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Cmpi", [bf; l; ra; si], _) -> + `Pcmpi( + (trans_out_int bf), + (trans_out_int l), + (trans_out_reg ra), + (trans_out_int si)) + | ("Cmp", [bf; l; ra; rb], _) -> + `Pcmp( + (trans_out_int bf), + (trans_out_int l), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Cmpli", [bf; l; ra; ui], _) -> + `Pcmpli( + (trans_out_int bf), + (trans_out_int l), + (trans_out_reg ra), + (trans_out_int ui)) + | ("Cmpl", [bf; l; ra; rb], _) -> + `Pcmpl( + (trans_out_int bf), + (trans_out_int l), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Isel", [rt; ra; rb; bc], _) -> + `Pisel( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int bc)) + | ("Andi", [rs; ra; ui], _) -> + `Pandi( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | ("Andis", [rs; ra; ui], _) -> + `Pandis( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | ("Ori", [rs; ra; ui], _) -> + `Pori( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | ("Oris", [rs; ra; ui], _) -> + `Poris( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | ("Xori", [rs; ra; ui], _) -> + `Pxori( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | ("Xoris", [rs; ra; ui], _) -> + `Pxoris( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | ("And", [rs; ra; rb; rc], _) -> + `Pand( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Xor", [rs; ra; rb; rc], _) -> + `Pxor( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Nand", [rs; ra; rb; rc], _) -> + `Pnand( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Or", [rs; ra; rb; rc], _) -> + `Por( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Nor", [rs; ra; rb; rc], _) -> + `Pnor( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Eqv", [rs; ra; rb; rc], _) -> + `Peqv( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Andc", [rs; ra; rb; rc], _) -> + `Pandc( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Orc", [rs; ra; rb; rc], _) -> + `Porc( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Extsb", [rs; ra; rc], _) -> + `Pextsb( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Extsh", [rs; ra; rc], _) -> + `Pextsh( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Cntlzw", [rs; ra; rc], _) -> + `Pcntlzw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Cmpb", [rs; ra; rb], _) -> + `Pcmpb( + (trans_out_reg ra), + (trans_out_int rs), + (trans_out_reg rb)) + | ("Popcntb", [rs; ra], _) -> + `Ppopcntb( + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Popcntw", [rs; ra], _) -> + `Ppopcntw( + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Prtyd", [rs; ra], _) -> + `Pprtyd( + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Prtyw", [rs; ra], _) -> + `Pprtyw( + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Extsw", [rs; ra; rc], _) -> + `Pextsw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Cntlzd", [rs; ra; rc], _) -> + `Pcntlzd( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Popcntd", [rs; ra], _) -> + `Ppopcntd( + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Bpermd", [rs; ra; rb], _) -> + `Pbpermd( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Rlwinm", [rs; ra; sh; mb; me; rc], _) -> + `Prlwinm( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb), + (trans_out_int me)) + | ("Rlwnm", [rs; ra; rb; mb; me; rc], _) -> + `Prlwnm( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb), + (trans_out_int mb), + (trans_out_int me)) + | ("Rlwimi", [rs; ra; sh; mb; me; rc], _) -> + `Prlwimi( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb), + (trans_out_int me)) + | ("Rldicl", [rs; ra; sh; mb; rc], _) -> + `Prldicl( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb)) + | ("Rldicr", [rs; ra; sh; me; rc], _) -> + `Prldicr( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int me)) + | ("Rldic", [rs; ra; sh; mb; rc], _) -> + `Prldic( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb)) + | ("Rldcl", [rs; ra; rb; mb; rc], _) -> + `Prldcl( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb), + (trans_out_int mb)) + | ("Rldcr", [rs; ra; rb; me; rc], _) -> + `Prldcr( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb), + (trans_out_int me)) + | ("Rldimi", [rs; ra; sh; mb; rc], _) -> + `Prldimi( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb)) + | ("Slw", [rs; ra; rb; rc], _) -> + `Pslw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Srw", [rs; ra; rb; rc], _) -> + `Psrw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Srawi", [rs; ra; sh; rc], _) -> + `Psrawi( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh)) + | ("Sraw", [rs; ra; rb; rc], _) -> + `Psraw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Sld", [rs; ra; rb; rc], _) -> + `Psld( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Srd", [rs; ra; rb; rc], _) -> + `Psrd( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Sradi", [rs; ra; sh; rc], _) -> + `Psradi( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh)) + | ("Srad", [rs; ra; rb; rc], _) -> + `Psrad( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Cdtbcd", [rs; ra], _) -> + `Pcdtbcd( + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Cbcdtd", [rs; ra], _) -> + `Pcbcdtd( + (trans_out_reg ra), + (trans_out_reg rs)) + | ("Addg6s", [rt; ra; rb], _) -> + `Paddg6s( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mtspr", [rs; spr], _) -> + `Pmtspr( + (trans_out_int spr), + (trans_out_reg rs)) + | ("Mfspr", [rt; spr], _) -> + `Pmfspr( + (trans_out_reg rt), + (trans_out_int spr)) + | ("Mtcrf", [rs; fxm], _) -> + `Pmtcrf( + (trans_out_int fxm), + (trans_out_reg rs)) + | ("Mfcr", [rt], _) -> + `Pmfcr( + (trans_out_reg rt)) + | ("Mtocrf", [rs; fxm], _) -> + `Pmtocrf( + (trans_out_int fxm), + (trans_out_reg rs)) + | ("Mfocrf", [rt; fxm], _) -> + `Pmfocrf( + (trans_out_reg rt), + (trans_out_int fxm)) + | ("Mcrxr", [bf], _) -> + `Pmcrxr( + (trans_out_int bf)) + | ("Dlmzb", [rs; ra; rb; rc], _) -> + `Pdlmzb( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | ("Macchw", [rt; ra; rb; oe; rc], _) -> + `Pmacchw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Macchws", [rt; ra; rb; oe; rc], _) -> + `Pmacchws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Macchwu", [rt; ra; rb; oe; rc], _) -> + `Pmacchwu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Macchwsu", [rt; ra; rb; oe; rc], _) -> + `Pmacchwsu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Machhw", [rt; ra; rb; oe; rc], _) -> + `Pmachhw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Machhws", [rt; ra; rb; oe; rc], _) -> + `Pmachhws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Machhwu", [rt; ra; rb; oe; rc], _) -> + `Pmachhwu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Machhwsu", [rt; ra; rb; oe; rc], _) -> + `Pmachhwsu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Maclhw", [rt; ra; rb; oe; rc], _) -> + `Pmaclhw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Maclhws", [rt; ra; rb; oe; rc], _) -> + `Pmaclhws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Maclhwu", [rt; ra; rb; oe; rc], _) -> + `Pmaclhwu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Maclhwsu", [rt; ra; rb; oe; rc], _) -> + `Pmaclhwsu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mulchw", [rt; ra; rb; rc], _) -> + `Pmulchw( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mulchwu", [rt; ra; rb; rc], _) -> + `Pmulchwu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mulhhw", [rt; ra; rb; rc], _) -> + `Pmulhhw( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mulhhwu", [rt; ra; rb; rc], _) -> + `Pmulhhwu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mullhw", [rt; ra; rb; rc], _) -> + `Pmullhw( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Mullhwu", [rt; ra; rb; rc], _) -> + `Pmullhwu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Nmacchw", [rt; ra; rb; oe; rc], _) -> + `Pnmacchw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Nmacchws", [rt; ra; rb; oe; rc], _) -> + `Pnmacchws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Nmachhw", [rt; ra; rb; oe; rc], _) -> + `Pnmachhw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Nmachhws", [rt; ra; rb; oe; rc], _) -> + `Pnmachhws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Nmaclhw", [rt; ra; rb; oe; rc], _) -> + `Pnmaclhw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Nmaclhws", [rt; ra; rb; oe; rc], _) -> + `Pnmaclhws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Icbi", [ra; rb], _) -> + `Picbi( + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Icbt", [ct; ra; rb], _) -> + `Picbt( + (trans_out_int ct), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Dcba", [ra; rb], _) -> + `Pdcba( + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Dcbt", [th; ra; rb], _) -> + `Pdcbt( + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int th)) + | ("Dcbtst", [th; ra; rb], _) -> + `Pdcbtst( + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int th)) + | ("Dcbz", [ra; rb], _) -> + `Pdcbz( + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Dcbst", [ra; rb], _) -> + `Pdcbst( + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Dcbf", [l; ra; rb], _) -> + `Pdcbf( + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int l)) + | ("Isync", [], _) -> + `Pisync + + | ("Lbarx", [rt; ra; rb; eh], _) -> + `Plbarx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int eh)) + | ("Lharx", [rt; ra; rb; eh], _) -> + `Plharx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int eh)) + | ("Lwarx", [rt; ra; rb; eh], _) -> + `Plwarx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int eh)) + | ("Stbcx", [rs; ra; rb], _) -> + `Pstbcx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Sthcx", [rs; ra; rb], _) -> + `Psthcx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Stwcx", [rs; ra; rb], _) -> + `Pstwcx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Ldarx", [rt; ra; rb; eh], _) -> + `Pldarx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int eh)) + | ("Stdcx", [rs; ra; rb], _) -> + `Pstdcx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | ("Sync", [l], _) -> + `Psync( + (trans_out_int l)) + | ("Eieio", [], _) -> + `Peieio + + | ("Wait", [wc], _) -> + `Pwait( + (trans_out_int wc)) diff --git a/power/gen/sail_trans_out_types.hgen b/power/gen/sail_trans_out_types.hgen new file mode 100644 index 00000000..08214129 --- /dev/null +++ b/power/gen/sail_trans_out_types.hgen @@ -0,0 +1,146 @@ +let trans_out_int ( _fname, _fsize, fbits ) = + Nat_big_num.to_int (SB.integer_of_bit_list fbits) + +let trans_out_reg flv = + let n = trans_out_int flv in + Ireg (match n with + | 0 -> GPR0 + | 1 -> GPR1 + | 2 -> GPR2 + | 3 -> GPR3 + | 4 -> GPR4 + | 5 -> GPR5 + | 6 -> GPR6 + | 7 -> GPR7 + | 8 -> GPR8 + | 9 -> GPR9 + | 10 -> GPR10 + | 11 -> GPR11 + | 12 -> GPR12 + | 13 -> GPR13 + | 14 -> GPR14 + | 15 -> GPR15 + | 16 -> GPR16 + | 17 -> GPR17 + | 18 -> GPR18 + | 19 -> GPR19 + | 20 -> GPR20 + | 21 -> GPR21 + | 22 -> GPR22 + | 23 -> GPR23 + | 24 -> GPR24 + | 25 -> GPR25 + | 26 -> GPR26 + | 27 -> GPR27 + | 28 -> GPR28 + | 29 -> GPR29 + | 30 -> GPR30 + | 31 -> GPR31 + | _ -> failwith "trans_out_reg given number not 0 to 31") + +let trans_out_soov ifv = + match trans_out_int ifv with + | 1 -> SetSOOV + | 0 -> DontSetSOOV + | _ -> failwith "trans_out_soov given number other than 0 and 1" + +let trans_out_cr0 ifv = + match trans_out_int ifv with + | 1 -> SetCR0 + | 0 -> DontSetCR0 + | _ -> failwith "trans_out_cr0 given number other than 0 and 1" + +let trans_out_aa ifv = + match trans_out_int ifv with + | 1 -> SetAA + | 0 -> DontSetAA + | _ -> failwith "trans_out_aa given number other than 0 and 1" + +let trans_out_lk ifv = + match trans_out_int ifv with + | 1 -> SetLK + | 0 -> DontSetLK + | _ -> failwith "trans_out_lk given number other than 0 and 1" + +(*These probably need to be checked that the shift is the correct thing to do*) +(* translating branch target addresses *) +(* CP: this does not seem to match with how the function is used, trying to fix + this now. *) +(* let trans_out_li_setaa_setlk_k3 setaa setlk li = + match li with + | (n,m,bits) -> + match bits with + | [] | [_] | [_;_] -> (n,m,bits) + | _ -> + (n,m, (let front,rest = List.hd bits, List.tl bits in + let second,rest = List.hd rest, List.tl rest in + rest @ [front;second])) *) +let trans_out_li_setaa_setlk_k3 li setaa setlk = + match li with + | (n,m,bits) -> (n,m, bits @ [Bitc_zero;Bitc_zero]) + +(* CP: this does not seem to match with how the function is used, trying to fix + this now. *) +(* let trans_out_bd_setaa_setlk_k_k_k5 setaa setlk bo bi bd = + match bd with + | (n,m,bits) -> + match bits with + | [] | [_] | [_;_] -> (n,m,bits) + | _ -> + (n,m, (let front,rest = List.hd bits, List.tl bits in + let second,rest = List.hd rest, List.tl rest in + rest @ [front;second])) *) +let trans_out_bd_setaa_setlk_k_k_k5 bo bi bd setaa setlk = + match bd with + | (n,m,bits) -> (n,m, bits @ [Bitc_zero;Bitc_zero]) + +(* translating vector-scalar floating-point ops *) +(* all of these translate a 6-bit value into a 5:1 bit pair, but differ + in number and type of arguments *) +(*this is probably wrong, probably I want to do a transformation on the bits then return, but unclear what translation*) +let trans_out_k xt = xt +let trans_out_xk xt = xt +let trans_out_t_k_k4 xt _ _ _ = trans_out_k xt +let trans_out_tx_k_k4 xt _ _ _ = trans_out_xk xt +let trans_out_t_k_reg_reg4 xt xa _ _ = trans_out_k xt +let trans_out_tx_k_reg_reg4 xt xa _ _ = trans_out_xk xt +let trans_out_s_k_reg_reg4 = trans_out_t_k_reg_reg4 +let trans_out_sx_k_reg_reg4 = trans_out_tx_k_reg_reg4 +let trans_out_t_k_k_k6 x _ _ _ _ _ = trans_out_k x +let trans_out_t_k_k_k5 x _ _ _ _ = trans_out_k x +let trans_out_tx_k_k_k6 x _ _ _ _ _= trans_out_k x +let trans_out_tx_k_k_k5 x _ _ _ _ = trans_out_k x +let trans_out_b_k_k4 = trans_out_t_k_k4 +let trans_out_bx_k_k4 = trans_out_tx_k_k4 +let trans_out_a_k_k_k6 xt xa xb _ _ _ = trans_out_k xa +let trans_out_ax_k_k_k6 xt xa xb _ _ _ = trans_out_xk xa +let trans_out_b_k_k_k6 xt xa xb _ _ _ = trans_out_k xb +let trans_out_b_k_k_k5 xt xa xb _ _ = trans_out_k xb +let trans_out_bx_k_k_k6 xt xa xb _ _ _ = trans_out_xk xb +let trans_out_bx_k_k_k5 xt xa xb _ _ = trans_out_xk xb +let trans_out_a_crindex_k_k5 bf xa xb _ _ = trans_out_k xa +let trans_out_ax_crindex_k_k5 bf xa xb _ _ = trans_out_xk xa +let trans_out_b_crindex_k_k5 bf xa xb _ _ = trans_out_k xb +let trans_out_bx_crindex_k_k5 bf xa xb _ _ = trans_out_xk xb +let trans_out_b_crindex_k3 bf xb _ = trans_out_k xb +let trans_out_bx_crindex_k3 bf xb _ = trans_out_xk xb +let trans_out_t_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_k xt +let trans_out_tx_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_xk xt +let trans_out_a_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_k xa +let trans_out_ax_setcr0_k_k_k7 setcr0 xt xa xb _ _ _= trans_out_xk xa +let trans_out_b_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_k xb +let trans_out_bx_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_xk xb +let trans_out_t_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_k xt +let trans_out_tx_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_xk xt +let trans_out_t_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_k xt +let trans_out_tx_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_xk xt +let trans_out_a_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_k xa +let trans_out_ax_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_xk xa +let trans_out_a_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_k xa +let trans_out_ax_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_xk xa +let trans_out_b_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_k xb +let trans_out_bx_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_xk xb +let trans_out_b_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_k xb +let trans_out_bx_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_xk xb +let trans_out_c_k_k_k_k8 xt xa xb xc _ _ _ _ = trans_out_k xc +let trans_out_cx_k_k_k_k8 xt xa xb xc _ _ _ _ = trans_out_xk xc
\ No newline at end of file diff --git a/power/gen/shallow_ast_to_herdtools_ast.gen b/power/gen/shallow_ast_to_herdtools_ast.gen new file mode 100644 index 00000000..1ab732f9 --- /dev/null +++ b/power/gen/shallow_ast_to_herdtools_ast.gen @@ -0,0 +1,1112 @@ + | B (li, aa, lk) -> + `Pb( + (trans_out_aa aa), + (trans_out_lk lk), + (trans_out_int (trans_out_li_setaa_setlk_k3 li aa lk))) + | Bc (bo, bi, bd, aa, lk) -> + `Pbc( + (trans_out_aa aa), + (trans_out_lk lk), + (trans_out_int bo), + (trans_out_int bi), + (trans_out_int (trans_out_bd_setaa_setlk_k_k_k5 bo bi bd aa lk))) + | Bclr (bo, bi, bh, lk) -> + `Pbclr( + (trans_out_lk lk), + (trans_out_int bo), + (trans_out_int bi), + (trans_out_int bh)) + | Bcctr (bo, bi, bh, lk) -> + `Pbcctr( + (trans_out_lk lk), + (trans_out_int bo), + (trans_out_int bi), + (trans_out_int bh)) + | Crand (bt, ba, bb) -> + `Pcrand( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | Crnand (bt, ba, bb) -> + `Pcrnand( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | Cror (bt, ba, bb) -> + `Pcror( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | Crxor (bt, ba, bb) -> + `Pcrxor( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | Crnor (bt, ba, bb) -> + `Pcrnor( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | Creqv (bt, ba, bb) -> + `Pcreqv( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | Crandc (bt, ba, bb) -> + `Pcrandc( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | Crorc (bt, ba, bb) -> + `Pcrorc( + (trans_out_int bt), + (trans_out_int ba), + (trans_out_int bb)) + | Mcrf (bf, bfa) -> + `Pmcrf( + (trans_out_int bf), + (trans_out_int bfa)) + | Sc (lev) -> + `Psc( + (trans_out_int lev)) + | Scv (lev) -> + `Pscv( + (trans_out_int lev)) + | Lbz (rt, ra, d) -> + `Plbz( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | Lbzx (rt, ra, rb) -> + `Plbzx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lbzu (rt, ra, d) -> + `Plbzu( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | Lbzux (rt, ra, rb) -> + `Plbzux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lhz (rt, ra, d) -> + `Plhz( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | Lhzx (rt, ra, rb) -> + `Plhzx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lhzu (rt, ra, d) -> + `Plhzu( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | Lhzux (rt, ra, rb) -> + `Plhzux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lha (rt, ra, d) -> + `Plha( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | Lhax (rt, ra, rb) -> + `Plhax( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lhau (rt, ra, d) -> + `Plhau( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | Lhaux (rt, ra, rb) -> + `Plhaux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lwz (rt, ra, d) -> + `Plwz( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | Lwzx (rt, ra, rb) -> + `Plwzx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lwzu (rt, ra, d) -> + `Plwzu( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | Lwzux (rt, ra, rb) -> + `Plwzux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lwa (rt, ra, ds) -> + `Plwa( + (trans_out_reg rt), + (trans_out_int ds), + (trans_out_reg ra)) + | Lwax (rt, ra, rb) -> + `Plwax( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lwaux (rt, ra, rb) -> + `Plwaux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Ld (rt, ra, ds) -> + `Pld( + (trans_out_reg rt), + (trans_out_int ds), + (trans_out_reg ra)) + | Ldx (rt, ra, rb) -> + `Pldx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Ldu (rt, ra, ds) -> + `Pldu( + (trans_out_reg rt), + (trans_out_int ds), + (trans_out_reg ra)) + | Ldux (rt, ra, rb) -> + `Pldux( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Stb (rs, ra, d) -> + `Pstb( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | Stbx (rs, ra, rb) -> + `Pstbx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Stbu (rs, ra, d) -> + `Pstbu( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | Stbux (rs, ra, rb) -> + `Pstbux( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Sth (rs, ra, d) -> + `Psth( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | Sthx (rs, ra, rb) -> + `Psthx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Sthu (rs, ra, d) -> + `Psthu( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | Sthux (rs, ra, rb) -> + `Psthux( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Stw (rs, ra, d) -> + `Pstw( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | Stwx (rs, ra, rb) -> + `Pstwx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Stwu (rs, ra, d) -> + `Pstwu( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | Stwux (rs, ra, rb) -> + `Pstwux( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Std (rs, ra, ds) -> + `Pstd( + (trans_out_reg rs), + (trans_out_int ds), + (trans_out_reg ra)) + | Stdx (rs, ra, rb) -> + `Pstdx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Stdu (rs, ra, ds) -> + `Pstdu( + (trans_out_reg rs), + (trans_out_int ds), + (trans_out_reg ra)) + | Stdux (rs, ra, rb) -> + `Pstdux( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lq (rtp, ra, dq, pt) -> + `Plq( + (trans_out_int rtp), + (trans_out_int dq), + (trans_out_reg ra), + (trans_out_int pt)) + | Stq (rsp, ra, ds) -> + `Pstq( + (trans_out_int rsp), + (trans_out_int ds), + (trans_out_reg ra)) + | Lhbrx (rt, ra, rb) -> + `Plhbrx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Sthbrx (rs, ra, rb) -> + `Psthbrx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lwbrx (rt, ra, rb) -> + `Plwbrx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Stwbrx (rs, ra, rb) -> + `Pstwbrx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Ldbrx (rt, ra, rb) -> + `Pldbrx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Stdbrx (rs, ra, rb) -> + `Pstdbrx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Lmw (rt, ra, d) -> + `Plmw( + (trans_out_reg rt), + (trans_out_int d), + (trans_out_reg ra)) + | Stmw (rs, ra, d) -> + `Pstmw( + (trans_out_reg rs), + (trans_out_int d), + (trans_out_reg ra)) + | Lswi (rt, ra, nb) -> + `Plswi( + (trans_out_int rt), + (trans_out_reg ra), + (trans_out_int nb)) + | Lswx (rt, ra, rb) -> + `Plswx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Stswi (rs, ra, nb) -> + `Pstswi( + (trans_out_int rs), + (trans_out_reg ra), + (trans_out_int nb)) + | Stswx (rs, ra, rb) -> + `Pstswx( + (trans_out_int rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Addi (rt, ra, si) -> + `Paddi( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | Addis (rt, ra, si) -> + `Paddis( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | Add (rt, ra, rb, oe, rc) -> + `Padd( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Subf (rt, ra, rb, oe, rc) -> + `Psubf( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Addic (rt, ra, si) -> + `Paddic( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | AddicDot (rt, ra, si) -> + `Paddicdot( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | Subfic (rt, ra, si) -> + `Psubfic( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | Addc (rt, ra, rb, oe, rc) -> + `Paddc( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Subfc (rt, ra, rb, oe, rc) -> + `Psubfc( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Adde (rt, ra, rb, oe, rc) -> + `Padde( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Subfe (rt, ra, rb, oe, rc) -> + `Psubfe( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Addme (rt, ra, oe, rc) -> + `Paddme( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | Subfme (rt, ra, oe, rc) -> + `Psubfme( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | Addze (rt, ra, oe, rc) -> + `Paddze( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | Subfze (rt, ra, oe, rc) -> + `Psubfze( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | Neg (rt, ra, oe, rc) -> + `Pneg( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra)) + | Mulli (rt, ra, si) -> + `Pmulli( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_int si)) + | Mullw (rt, ra, rb, oe, rc) -> + `Pmullw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mulhw (rt, ra, rb, rc) -> + `Pmulhw( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mulhwu (rt, ra, rb, rc) -> + `Pmulhwu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Divw (rt, ra, rb, oe, rc) -> + `Pdivw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Divwu (rt, ra, rb, oe, rc) -> + `Pdivwu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Divwe (rt, ra, rb, oe, rc) -> + `Pdivwe( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Divweu (rt, ra, rb, oe, rc) -> + `Pdivweu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mulld (rt, ra, rb, oe, rc) -> + `Pmulld( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mulhd (rt, ra, rb, rc) -> + `Pmulhd( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mulhdu (rt, ra, rb, rc) -> + `Pmulhdu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Divd (rt, ra, rb, oe, rc) -> + `Pdivd( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Divdu (rt, ra, rb, oe, rc) -> + `Pdivdu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Divde (rt, ra, rb, oe, rc) -> + `Pdivde( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Divdeu (rt, ra, rb, oe, rc) -> + `Pdivdeu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Cmpi (bf, l, ra, si) -> + `Pcmpi( + (trans_out_int bf), + (trans_out_bit l), + (trans_out_reg ra), + (trans_out_int si)) + | Cmp (bf, l, ra, rb) -> + `Pcmp( + (trans_out_int bf), + (trans_out_bit l), + (trans_out_reg ra), + (trans_out_reg rb)) + | Cmpli (bf, l, ra, ui) -> + `Pcmpli( + (trans_out_int bf), + (trans_out_bit l), + (trans_out_reg ra), + (trans_out_int ui)) + | Cmpl (bf, l, ra, rb) -> + `Pcmpl( + (trans_out_int bf), + (trans_out_bit l), + (trans_out_reg ra), + (trans_out_reg rb)) + | Isel (rt, ra, rb, bc) -> + `Pisel( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int bc)) + | Andi (rs, ra, ui) -> + `Pandi( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | Andis (rs, ra, ui) -> + `Pandis( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | Ori (rs, ra, ui) -> + `Pori( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | Oris (rs, ra, ui) -> + `Poris( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | Xori (rs, ra, ui) -> + `Pxori( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | Xoris (rs, ra, ui) -> + `Pxoris( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int ui)) + | And (rs, ra, rb, rc) -> + `Pand( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Xor (rs, ra, rb, rc) -> + `Pxor( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Nand (rs, ra, rb, rc) -> + `Pnand( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Or (rs, ra, rb, rc) -> + `Por( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Nor (rs, ra, rb, rc) -> + `Pnor( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Eqv (rs, ra, rb, rc) -> + `Peqv( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Andc (rs, ra, rb, rc) -> + `Pandc( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Orc (rs, ra, rb, rc) -> + `Porc( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Extsb (rs, ra, rc) -> + `Pextsb( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | Extsh (rs, ra, rc) -> + `Pextsh( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | Cntlzw (rs, ra, rc) -> + `Pcntlzw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | Cmpb (rs, ra, rb) -> + `Pcmpb( + (trans_out_reg ra), + (trans_out_int rs), + (trans_out_reg rb)) + | Popcntb (rs, ra) -> + `Ppopcntb( + (trans_out_reg ra), + (trans_out_reg rs)) + | Popcntw (rs, ra) -> + `Ppopcntw( + (trans_out_reg ra), + (trans_out_reg rs)) + | Prtyd (rs, ra) -> + `Pprtyd( + (trans_out_reg ra), + (trans_out_reg rs)) + | Prtyw (rs, ra) -> + `Pprtyw( + (trans_out_reg ra), + (trans_out_reg rs)) + | Extsw (rs, ra, rc) -> + `Pextsw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | Cntlzd (rs, ra, rc) -> + `Pcntlzd( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs)) + | Popcntd (rs, ra) -> + `Ppopcntd( + (trans_out_reg ra), + (trans_out_reg rs)) + | Bpermd (rs, ra, rb) -> + `Pbpermd( + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Rlwinm (rs, ra, sh, mb, me, rc) -> + `Prlwinm( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb), + (trans_out_int me)) + | Rlwnm (rs, ra, rb, mb, me, rc) -> + `Prlwnm( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb), + (trans_out_int mb), + (trans_out_int me)) + | Rlwimi (rs, ra, sh, mb, me, rc) -> + `Prlwimi( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb), + (trans_out_int me)) + | Rldicl (rs, ra, sh, mb, rc) -> + `Prldicl( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb)) + | Rldicr (rs, ra, sh, me, rc) -> + `Prldicr( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int me)) + | Rldic (rs, ra, sh, mb, rc) -> + `Prldic( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb)) + | Rldcl (rs, ra, rb, mb, rc) -> + `Prldcl( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb), + (trans_out_int mb)) + | Rldcr (rs, ra, rb, me, rc) -> + `Prldcr( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb), + (trans_out_int me)) + | Rldimi (rs, ra, sh, mb, rc) -> + `Prldimi( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh), + (trans_out_int mb)) + | Slw (rs, ra, rb, rc) -> + `Pslw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Srw (rs, ra, rb, rc) -> + `Psrw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Srawi (rs, ra, sh, rc) -> + `Psrawi( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh)) + | Sraw (rs, ra, rb, rc) -> + `Psraw( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Sld (rs, ra, rb, rc) -> + `Psld( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Srd (rs, ra, rb, rc) -> + `Psrd( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Sradi (rs, ra, sh, rc) -> + `Psradi( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_int sh)) + | Srad (rs, ra, rb, rc) -> + `Psrad( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Cdtbcd (rs, ra) -> + `Pcdtbcd( + (trans_out_reg ra), + (trans_out_reg rs)) + | Cbcdtd (rs, ra) -> + `Pcbcdtd( + (trans_out_reg ra), + (trans_out_reg rs)) + | Addg6s (rt, ra, rb) -> + `Paddg6s( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mtspr (rs, spr) -> + `Pmtspr( + (trans_out_int spr), + (trans_out_reg rs)) + | Mfspr (rt, spr) -> + `Pmfspr( + (trans_out_reg rt), + (trans_out_int spr)) + | Mtcrf (rs, fxm) -> + `Pmtcrf( + (trans_out_int fxm), + (trans_out_reg rs)) + | Mfcr (rt) -> + `Pmfcr( + (trans_out_reg rt)) + | Mtocrf (rs, fxm) -> + `Pmtocrf( + (trans_out_int fxm), + (trans_out_reg rs)) + | Mfocrf (rt, fxm) -> + `Pmfocrf( + (trans_out_reg rt), + (trans_out_int fxm)) + | Mcrxr (bf) -> + `Pmcrxr( + (trans_out_int bf)) + | Dlmzb (rs, ra, rb, rc) -> + `Pdlmzb( + (trans_out_cr0 rc), + (trans_out_reg ra), + (trans_out_reg rs), + (trans_out_reg rb)) + | Macchw (rt, ra, rb, oe, rc) -> + `Pmacchw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Macchws (rt, ra, rb, oe, rc) -> + `Pmacchws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Macchwu (rt, ra, rb, oe, rc) -> + `Pmacchwu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Macchwsu (rt, ra, rb, oe, rc) -> + `Pmacchwsu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Machhw (rt, ra, rb, oe, rc) -> + `Pmachhw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Machhws (rt, ra, rb, oe, rc) -> + `Pmachhws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Machhwu (rt, ra, rb, oe, rc) -> + `Pmachhwu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Machhwsu (rt, ra, rb, oe, rc) -> + `Pmachhwsu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Maclhw (rt, ra, rb, oe, rc) -> + `Pmaclhw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Maclhws (rt, ra, rb, oe, rc) -> + `Pmaclhws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Maclhwu (rt, ra, rb, oe, rc) -> + `Pmaclhwu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Maclhwsu (rt, ra, rb, oe, rc) -> + `Pmaclhwsu( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mulchw (rt, ra, rb, rc) -> + `Pmulchw( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mulchwu (rt, ra, rb, rc) -> + `Pmulchwu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mulhhw (rt, ra, rb, rc) -> + `Pmulhhw( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mulhhwu (rt, ra, rb, rc) -> + `Pmulhhwu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mullhw (rt, ra, rb, rc) -> + `Pmullhw( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Mullhwu (rt, ra, rb, rc) -> + `Pmullhwu( + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Nmacchw (rt, ra, rb, oe, rc) -> + `Pnmacchw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Nmacchws (rt, ra, rb, oe, rc) -> + `Pnmacchws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Nmachhw (rt, ra, rb, oe, rc) -> + `Pnmachhw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Nmachhws (rt, ra, rb, oe, rc) -> + `Pnmachhws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Nmaclhw (rt, ra, rb, oe, rc) -> + `Pnmaclhw( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Nmaclhws (rt, ra, rb, oe, rc) -> + `Pnmaclhws( + (trans_out_soov oe), + (trans_out_cr0 rc), + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb)) + | Icbi (ra, rb) -> + `Picbi( + (trans_out_reg ra), + (trans_out_reg rb)) + | Icbt (ct, ra, rb) -> + `Picbt( + (trans_out_int ct), + (trans_out_reg ra), + (trans_out_reg rb)) + | Dcba (ra, rb) -> + `Pdcba( + (trans_out_reg ra), + (trans_out_reg rb)) + | Dcbt (th, ra, rb) -> + `Pdcbt( + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int th)) + | Dcbtst (th, ra, rb) -> + `Pdcbtst( + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int th)) + | Dcbz (ra, rb) -> + `Pdcbz( + (trans_out_reg ra), + (trans_out_reg rb)) + | Dcbst (ra, rb) -> + `Pdcbst( + (trans_out_reg ra), + (trans_out_reg rb)) + | Dcbf (l, ra, rb) -> + `Pdcbf( + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_int l)) + | Isync -> + `Pisync + + | Lbarx (rt, ra, rb, eh) -> + `Plbarx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_bit eh)) + | Lharx (rt, ra, rb, eh) -> + `Plharx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_bit eh)) + | Lwarx (rt, ra, rb, eh) -> + `Plwarx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_bit eh)) + | Stbcx (rs, ra, rb) -> + `Pstbcx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Sthcx (rs, ra, rb) -> + `Psthcx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Stwcx (rs, ra, rb) -> + `Pstwcx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Ldarx (rt, ra, rb, eh) -> + `Pldarx( + (trans_out_reg rt), + (trans_out_reg ra), + (trans_out_reg rb), + (trans_out_bit eh)) + | Stdcx (rs, ra, rb) -> + `Pstdcx( + (trans_out_reg rs), + (trans_out_reg ra), + (trans_out_reg rb)) + | Sync (l) -> + `Psync( + (trans_out_int l)) + | Eieio -> + `Peieio + + | Wait (wc) -> + `Pwait( + (trans_out_int wc)) diff --git a/power/gen/shallow_types_to_herdtools_types.hgen b/power/gen/shallow_types_to_herdtools_types.hgen new file mode 100644 index 00000000..c08b0131 --- /dev/null +++ b/power/gen/shallow_types_to_herdtools_types.hgen @@ -0,0 +1,150 @@ +let trans_out_int fbits = + Nat_big_num.to_int (Sail_values.unsigned fbits) + +let trans_out_bit = function + | Sail_values.B1 -> 1 + | Sail_values.B0 -> 0 + | Sail_values.BU -> failwith "trans_out_bit given Undef bit" + + +let trans_out_reg flv = + let n = trans_out_int flv in + Ireg (match n with + | 0 -> GPR0 + | 1 -> GPR1 + | 2 -> GPR2 + | 3 -> GPR3 + | 4 -> GPR4 + | 5 -> GPR5 + | 6 -> GPR6 + | 7 -> GPR7 + | 8 -> GPR8 + | 9 -> GPR9 + | 10 -> GPR10 + | 11 -> GPR11 + | 12 -> GPR12 + | 13 -> GPR13 + | 14 -> GPR14 + | 15 -> GPR15 + | 16 -> GPR16 + | 17 -> GPR17 + | 18 -> GPR18 + | 19 -> GPR19 + | 20 -> GPR20 + | 21 -> GPR21 + | 22 -> GPR22 + | 23 -> GPR23 + | 24 -> GPR24 + | 25 -> GPR25 + | 26 -> GPR26 + | 27 -> GPR27 + | 28 -> GPR28 + | 29 -> GPR29 + | 30 -> GPR30 + | 31 -> GPR31 + | _ -> failwith "trans_out_reg given number not 0 to 31") + +let trans_out_soov = function + | Sail_values.B1 -> SetSOOV + | Sail_values.B0 -> DontSetSOOV + | _ -> failwith "trans_out_soov given undef bit" + +let trans_out_cr0 = function + | Sail_values.B1 -> SetCR0 + | Sail_values.B0 -> DontSetCR0 + | _ -> failwith "trans_out_cr0 given undef bit" + +let trans_out_aa = function + | Sail_values.B1 -> SetAA + | Sail_values.B0 -> DontSetAA + | _ -> failwith "trans_out_aa given undef bit" + +let trans_out_lk = function + | Sail_values.B1 -> SetLK + | Sail_values.B0 -> DontSetLK + | _ -> failwith "trans_out_lk given undef bit" + +(*These probably need to be checked that the shift is the correct thing to do*) +(* translating branch target addresses *) +(* CP: this seems to assume a different parameter order from how it's used, this + was undetected because the previous field value representation was "untyped", + trying to fix this now. *) +(* let trans_out_li_setaa_setlk_k3 setaa setlk li = + match li with + | (n,m,bits) -> + match bits with + | [] | [_] | [_;_] -> (n,m,bits) + | _ -> + (n,m, (let front,rest = List.hd bits, List.tl bits in + let second,rest = List.hd rest, List.tl rest in + rest @ [front;second])) *) +let trans_out_li_setaa_setlk_k3 li setaa setlk = + match li with + | Sail_values.Vector (bits,start,is_inc) -> + Sail_values.Vector (bits @ [Sail_values.B0;Sail_values.B0],start,is_inc) + +(* CP: same here *) +(* let trans_out_bd_setaa_setlk_k_k_k5 setaa setlk bo bi bd = + match bd with + | (n,m,bits) -> + match bits with + | [] | [_] | [_;_] -> (n,m,bits) + | _ -> + (n,m, (let front,rest = List.hd bits, List.tl bits in + let second,rest = List.hd rest, List.tl rest in + rest @ [front;second])) *) +let trans_out_bd_setaa_setlk_k_k_k5 bo bi bd setaa setlk = + match bd with + | Sail_values.Vector (bits,start,is_inc) -> + Sail_values.Vector (bits @ [Sail_values.B0;Sail_values.B0],start,is_inc) + +(* translating vector-scalar floating-point ops *) +(* all of these translate a 6-bit value into a 5:1 bit pair, but differ + in number and type of arguments *) +(*this is probably wrong, probably I want to do a transformation on the bits then return, but unclear what translation*) +let trans_out_k xt = xt +let trans_out_xk xt = xt +let trans_out_t_k_k4 xt _ _ _ = trans_out_k xt +let trans_out_tx_k_k4 xt _ _ _ = trans_out_xk xt +let trans_out_t_k_reg_reg4 xt xa _ _ = trans_out_k xt +let trans_out_tx_k_reg_reg4 xt xa _ _ = trans_out_xk xt +let trans_out_s_k_reg_reg4 = trans_out_t_k_reg_reg4 +let trans_out_sx_k_reg_reg4 = trans_out_tx_k_reg_reg4 +let trans_out_t_k_k_k6 x _ _ _ _ _ = trans_out_k x +let trans_out_t_k_k_k5 x _ _ _ _ = trans_out_k x +let trans_out_tx_k_k_k6 x _ _ _ _ _= trans_out_k x +let trans_out_tx_k_k_k5 x _ _ _ _ = trans_out_k x +let trans_out_b_k_k4 = trans_out_t_k_k4 +let trans_out_bx_k_k4 = trans_out_tx_k_k4 +let trans_out_a_k_k_k6 xt xa xb _ _ _ = trans_out_k xa +let trans_out_ax_k_k_k6 xt xa xb _ _ _ = trans_out_xk xa +let trans_out_b_k_k_k6 xt xa xb _ _ _ = trans_out_k xb +let trans_out_b_k_k_k5 xt xa xb _ _ = trans_out_k xb +let trans_out_bx_k_k_k6 xt xa xb _ _ _ = trans_out_xk xb +let trans_out_bx_k_k_k5 xt xa xb _ _ = trans_out_xk xb +let trans_out_a_crindex_k_k5 bf xa xb _ _ = trans_out_k xa +let trans_out_ax_crindex_k_k5 bf xa xb _ _ = trans_out_xk xa +let trans_out_b_crindex_k_k5 bf xa xb _ _ = trans_out_k xb +let trans_out_bx_crindex_k_k5 bf xa xb _ _ = trans_out_xk xb +let trans_out_b_crindex_k3 bf xb _ = trans_out_k xb +let trans_out_bx_crindex_k3 bf xb _ = trans_out_xk xb +let trans_out_t_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_k xt +let trans_out_tx_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_xk xt +let trans_out_a_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_k xa +let trans_out_ax_setcr0_k_k_k7 setcr0 xt xa xb _ _ _= trans_out_xk xa +let trans_out_b_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_k xb +let trans_out_bx_setcr0_k_k_k7 setcr0 xt xa xb _ _ _ = trans_out_xk xb +let trans_out_t_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_k xt +let trans_out_tx_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_xk xt +let trans_out_t_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_k xt +let trans_out_tx_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_xk xt +let trans_out_a_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_k xa +let trans_out_ax_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_xk xa +let trans_out_a_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_k xa +let trans_out_ax_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_xk xa +let trans_out_b_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_k xb +let trans_out_bx_k_k_k_k7 xt xa xb dm _ _ _ = trans_out_xk xb +let trans_out_b_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_k xb +let trans_out_bx_k_k_k_k8 xt xa xb dm _ _ _ _ = trans_out_xk xb +let trans_out_c_k_k_k_k8 xt xa xb xc _ _ _ _ = trans_out_k xc +let trans_out_cx_k_k_k_k8 xt xa xb xc _ _ _ _ = trans_out_xk xc
\ No newline at end of file diff --git a/power/gen/tokens.gen b/power/gen/tokens.gen new file mode 100644 index 00000000..f9022936 --- /dev/null +++ b/power/gen/tokens.gen @@ -0,0 +1,368 @@ +%token B +%token BA +%token BL +%token BLA +%token BC +%token BCA +%token BCL +%token BCLA +%token BCLR +%token BCLRL +%token BCCTR +%token BCCTRL +%token CRAND +%token CRNAND +%token CROR +%token CRXOR +%token CRNOR +%token CREQV +%token CRANDC +%token CRORC +%token MCRF +%token SC +%token SCV +%token LBZ +%token LBZX +%token LBZU +%token LBZUX +%token LHZ +%token LHZX +%token LHZU +%token LHZUX +%token LHA +%token LHAX +%token LHAU +%token LHAUX +%token LWZ +%token LWZX +%token LWZU +%token LWZUX +%token LWA +%token LWAX +%token LWAUX +%token LD +%token LDX +%token LDU +%token LDUX +%token STB +%token STBX +%token STBU +%token STBUX +%token STH +%token STHX +%token STHU +%token STHUX +%token STW +%token STWX +%token STWU +%token STWUX +%token STD +%token STDX +%token STDU +%token STDUX +%token LQ +%token STQ +%token LHBRX +%token STHBRX +%token LWBRX +%token STWBRX +%token LDBRX +%token STDBRX +%token LMW +%token STMW +%token LSWI +%token LSWX +%token STSWI +%token STSWX +%token ADDI +%token ADDIS +%token ADD +%token ADDDOT +%token ADDO +%token ADDODOT +%token SUBF +%token SUBFDOT +%token SUBFO +%token SUBFODOT +%token ADDIC +%token ADDICDOT +%token SUBFIC +%token ADDC +%token ADDCDOT +%token ADDCO +%token ADDCODOT +%token SUBFC +%token SUBFCDOT +%token SUBFCO +%token SUBFCODOT +%token ADDE +%token ADDEDOT +%token ADDEO +%token ADDEODOT +%token SUBFE +%token SUBFEDOT +%token SUBFEO +%token SUBFEODOT +%token ADDME +%token ADDMEDOT +%token ADDMEO +%token ADDMEODOT +%token SUBFME +%token SUBFMEDOT +%token SUBFMEO +%token SUBFMEODOT +%token ADDZE +%token ADDZEDOT +%token ADDZEO +%token ADDZEODOT +%token SUBFZE +%token SUBFZEDOT +%token SUBFZEO +%token SUBFZEODOT +%token NEG +%token NEGDOT +%token NEGO +%token NEGODOT +%token MULLI +%token MULLW +%token MULLWDOT +%token MULLWO +%token MULLWODOT +%token MULHW +%token MULHWDOT +%token MULHWU +%token MULHWUDOT +%token DIVW +%token DIVWDOT +%token DIVWO +%token DIVWODOT +%token DIVWU +%token DIVWUDOT +%token DIVWUO +%token DIVWUODOT +%token DIVWE +%token DIVWEDOT +%token DIVWEO +%token DIVWEODOT +%token DIVWEU +%token DIVWEUDOT +%token DIVWEUO +%token DIVWEUODOT +%token MULLD +%token MULLDDOT +%token MULLDO +%token MULLDODOT +%token MULHD +%token MULHDDOT +%token MULHDU +%token MULHDUDOT +%token DIVD +%token DIVDDOT +%token DIVDO +%token DIVDODOT +%token DIVDU +%token DIVDUDOT +%token DIVDUO +%token DIVDUODOT +%token DIVDE +%token DIVDEDOT +%token DIVDEO +%token DIVDEODOT +%token DIVDEU +%token DIVDEUDOT +%token DIVDEUO +%token DIVDEUODOT +%token CMPI +%token CMP +%token CMPLI +%token CMPL +%token ISEL +%token ANDIDOT +%token ANDISDOT +%token ORI +%token ORIS +%token XORI +%token XORIS +%token AND +%token ANDDOT +%token XOR +%token XORDOT +%token NAND +%token NANDDOT +%token OR +%token ORDOT +%token NOR +%token NORDOT +%token EQV +%token EQVDOT +%token ANDC +%token ANDCDOT +%token ORC +%token ORCDOT +%token EXTSB +%token EXTSBDOT +%token EXTSH +%token EXTSHDOT +%token CNTLZW +%token CNTLZWDOT +%token CMPB +%token POPCNTB +%token POPCNTW +%token PRTYD +%token PRTYW +%token EXTSW +%token EXTSWDOT +%token CNTLZD +%token CNTLZDDOT +%token POPCNTD +%token BPERMD +%token RLWINM +%token RLWINMDOT +%token RLWNM +%token RLWNMDOT +%token RLWIMI +%token RLWIMIDOT +%token RLDICL +%token RLDICLDOT +%token RLDICR +%token RLDICRDOT +%token RLDIC +%token RLDICDOT +%token RLDCL +%token RLDCLDOT +%token RLDCR +%token RLDCRDOT +%token RLDIMI +%token RLDIMIDOT +%token SLW +%token SLWDOT +%token SRW +%token SRWDOT +%token SRAWI +%token SRAWIDOT +%token SRAW +%token SRAWDOT +%token SLD +%token SLDDOT +%token SRD +%token SRDDOT +%token SRADI +%token SRADIDOT +%token SRAD +%token SRADDOT +%token CDTBCD +%token CBCDTD +%token ADDG6S +%token MTSPR +%token MFSPR +%token MTCRF +%token MFCR +%token MTOCRF +%token MFOCRF +%token MCRXR +%token DLMZB +%token DLMZBDOT +%token MACCHW +%token MACCHWDOT +%token MACCHWO +%token MACCHWODOT +%token MACCHWS +%token MACCHWSDOT +%token MACCHWSO +%token MACCHWSODOT +%token MACCHWU +%token MACCHWUDOT +%token MACCHWUO +%token MACCHWUODOT +%token MACCHWSU +%token MACCHWSUDOT +%token MACCHWSUO +%token MACCHWSUODOT +%token MACHHW +%token MACHHWDOT +%token MACHHWO +%token MACHHWODOT +%token MACHHWS +%token MACHHWSDOT +%token MACHHWSO +%token MACHHWSODOT +%token MACHHWU +%token MACHHWUDOT +%token MACHHWUO +%token MACHHWUODOT +%token MACHHWSU +%token MACHHWSUDOT +%token MACHHWSUO +%token MACHHWSUODOT +%token MACLHW +%token MACLHWDOT +%token MACLHWO +%token MACLHWODOT +%token MACLHWS +%token MACLHWSDOT +%token MACLHWSO +%token MACLHWSODOT +%token MACLHWU +%token MACLHWUDOT +%token MACLHWUO +%token MACLHWUODOT +%token MACLHWSU +%token MACLHWSUDOT +%token MACLHWSUO +%token MACLHWSUODOT +%token MULCHW +%token MULCHWDOT +%token MULCHWU +%token MULCHWUDOT +%token MULHHW +%token MULHHWDOT +%token MULHHWU +%token MULHHWUDOT +%token MULLHW +%token MULLHWDOT +%token MULLHWU +%token MULLHWUDOT +%token NMACCHW +%token NMACCHWDOT +%token NMACCHWO +%token NMACCHWODOT +%token NMACCHWS +%token NMACCHWSDOT +%token NMACCHWSO +%token NMACCHWSODOT +%token NMACHHW +%token NMACHHWDOT +%token NMACHHWO +%token NMACHHWODOT +%token NMACHHWS +%token NMACHHWSDOT +%token NMACHHWSO +%token NMACHHWSODOT +%token NMACLHW +%token NMACLHWDOT +%token NMACLHWO +%token NMACLHWODOT +%token NMACLHWS +%token NMACLHWSDOT +%token NMACLHWSO +%token NMACLHWSODOT +%token ICBI +%token ICBT +%token DCBA +%token DCBT +%token DCBTST +%token DCBZ +%token DCBST +%token DCBF +%token ISYNC +%token LBARX +%token LHARX +%token LWARX +%token STBCXDOT +%token STHCXDOT +%token STWCXDOT +%token LDARX +%token STDCXDOT +%token SYNC +%token EIEIO +%token WAIT diff --git a/power/gen/trans_sail.gen b/power/gen/trans_sail.gen new file mode 100644 index 00000000..b6f406f2 --- /dev/null +++ b/power/gen/trans_sail.gen @@ -0,0 +1,1516 @@ + | `Pb(setaa0, setlk1, k2) -> + ("B", + [("LI", IInt.Bvector (Some 24), SB.bit_list_of_integer 24 (Nat_big_num.of_int (trans_li_setaa_setlk_k setaa0 setlk1 k2))); + ("AA", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_aa setaa0))); + ("LK", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_lk setlk1)))], + [(* always empty base effects*)] + ) + | `Pbc(setaa0, setlk1, k2, k3, k4) -> + ("Bc", + [("BO", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2)); + ("BI", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k3)); + ("BD", IInt.Bvector (Some 14), SB.bit_list_of_integer 14 (Nat_big_num.of_int (trans_bd_setaa_setlk_k_k_k setaa0 setlk1 k2 k3 k4))); + ("AA", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_aa setaa0))); + ("LK", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_lk setlk1)))], + [(* always empty base effects*)] + ) + | `Pbclr(setlk0, k1, k2, k3) -> + ("Bclr", + [("BO", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BI", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2)); + ("BH", IInt.Bvector (Some 2), SB.bit_list_of_integer 2 (Nat_big_num.of_int k3)); + ("LK", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_lk setlk0)))], + [(* always empty base effects*)] + ) + | `Pbcctr(setlk0, k1, k2, k3) -> + ("Bcctr", + [("BO", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BI", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2)); + ("BH", IInt.Bvector (Some 2), SB.bit_list_of_integer 2 (Nat_big_num.of_int k3)); + ("LK", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_lk setlk0)))], + [(* always empty base effects*)] + ) + | `Pcrand(k0, k1, k2) -> + ("Crand", + [("BT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("BA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pcrnand(k0, k1, k2) -> + ("Crnand", + [("BT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("BA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pcror(k0, k1, k2) -> + ("Cror", + [("BT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("BA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pcrxor(k0, k1, k2) -> + ("Crxor", + [("BT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("BA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pcrnor(k0, k1, k2) -> + ("Crnor", + [("BT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("BA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pcreqv(k0, k1, k2) -> + ("Creqv", + [("BT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("BA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pcrandc(k0, k1, k2) -> + ("Crandc", + [("BT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("BA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pcrorc(k0, k1, k2) -> + ("Crorc", + [("BT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("BA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("BB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pmcrf(crindex0, k1) -> + ("Mcrf", + [("BF", IInt.Bvector (Some 3), SB.bit_list_of_integer 3 (Nat_big_num.of_int crindex0)); + ("BFA", IInt.Bvector (Some 3), SB.bit_list_of_integer 3 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Psc(k0) -> + ("Sc", + [("LEV", IInt.Bvector (Some 7), SB.bit_list_of_integer 7 (Nat_big_num.of_int k0))], + [(* always empty base effects*)] + ) + | `Pscv(k0) -> + ("Scv", + [("LEV", IInt.Bvector (Some 7), SB.bit_list_of_integer 7 (Nat_big_num.of_int k0))], + [(* always empty base effects*)] + ) + | `Plbz(reg0, k1, reg2) -> + ("Lbz", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Plbzx(reg0, reg1, reg2) -> + ("Lbzx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plbzu(reg0, k1, reg2) -> + ("Lbzu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Plbzux(reg0, reg1, reg2) -> + ("Lbzux", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plhz(reg0, k1, reg2) -> + ("Lhz", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Plhzx(reg0, reg1, reg2) -> + ("Lhzx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plhzu(reg0, k1, reg2) -> + ("Lhzu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Plhzux(reg0, reg1, reg2) -> + ("Lhzux", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plha(reg0, k1, reg2) -> + ("Lha", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Plhax(reg0, reg1, reg2) -> + ("Lhax", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plhau(reg0, k1, reg2) -> + ("Lhau", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Plhaux(reg0, reg1, reg2) -> + ("Lhaux", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plwz(reg0, k1, reg2) -> + ("Lwz", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Plwzx(reg0, reg1, reg2) -> + ("Lwzx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plwzu(reg0, k1, reg2) -> + ("Lwzu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Plwzux(reg0, reg1, reg2) -> + ("Lwzux", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plwa(reg0, ds1, reg2) -> + ("Lwa", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("DS", IInt.Bvector (Some 14), SB.bit_list_of_integer 14 (Nat_big_num.of_int ds1))], + [(* always empty base effects*)] + ) + | `Plwax(reg0, reg1, reg2) -> + ("Lwax", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plwaux(reg0, reg1, reg2) -> + ("Lwaux", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pld(reg0, ds1, reg2) -> + ("Ld", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("DS", IInt.Bvector (Some 14), SB.bit_list_of_integer 14 (Nat_big_num.of_int ds1))], + [(* always empty base effects*)] + ) + | `Pldx(reg0, reg1, reg2) -> + ("Ldx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pldu(reg0, ds1, reg2) -> + ("Ldu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("DS", IInt.Bvector (Some 14), SB.bit_list_of_integer 14 (Nat_big_num.of_int ds1))], + [(* always empty base effects*)] + ) + | `Pldux(reg0, reg1, reg2) -> + ("Ldux", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstb(reg0, k1, reg2) -> + ("Stb", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Pstbx(reg0, reg1, reg2) -> + ("Stbx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstbu(reg0, k1, reg2) -> + ("Stbu", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Pstbux(reg0, reg1, reg2) -> + ("Stbux", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Psth(reg0, k1, reg2) -> + ("Sth", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Psthx(reg0, reg1, reg2) -> + ("Sthx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Psthu(reg0, k1, reg2) -> + ("Sthu", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Psthux(reg0, reg1, reg2) -> + ("Sthux", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstw(reg0, k1, reg2) -> + ("Stw", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Pstwx(reg0, reg1, reg2) -> + ("Stwx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstwu(reg0, k1, reg2) -> + ("Stwu", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Pstwux(reg0, reg1, reg2) -> + ("Stwux", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstd(reg0, ds1, reg2) -> + ("Std", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("DS", IInt.Bvector (Some 14), SB.bit_list_of_integer 14 (Nat_big_num.of_int ds1))], + [(* always empty base effects*)] + ) + | `Pstdx(reg0, reg1, reg2) -> + ("Stdx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstdu(reg0, ds1, reg2) -> + ("Stdu", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("DS", IInt.Bvector (Some 14), SB.bit_list_of_integer 14 (Nat_big_num.of_int ds1))], + [(* always empty base effects*)] + ) + | `Pstdux(reg0, reg1, reg2) -> + ("Stdux", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plq(k0, k1, reg2, k3) -> + ("Lq", + [("RTp", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("DQ", IInt.Bvector (Some 12), SB.bit_list_of_integer 12 (Nat_big_num.of_int k1)); + ("PT", IInt.Bvector (Some 4), SB.bit_list_of_integer 4 (Nat_big_num.of_int k3))], + [(* always empty base effects*)] + ) + | `Pstq(k0, ds1, reg2) -> + ("Stq", + [("RSp", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("DS", IInt.Bvector (Some 14), SB.bit_list_of_integer 14 (Nat_big_num.of_int ds1))], + [(* always empty base effects*)] + ) + | `Plhbrx(reg0, reg1, reg2) -> + ("Lhbrx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Psthbrx(reg0, reg1, reg2) -> + ("Sthbrx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plwbrx(reg0, reg1, reg2) -> + ("Lwbrx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstwbrx(reg0, reg1, reg2) -> + ("Stwbrx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pldbrx(reg0, reg1, reg2) -> + ("Ldbrx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstdbrx(reg0, reg1, reg2) -> + ("Stdbrx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Plmw(reg0, k1, reg2) -> + ("Lmw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Pstmw(reg0, k1, reg2) -> + ("Stmw", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("D", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Plswi(k0, reg1, k2) -> + ("Lswi", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("NB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Plswx(reg0, reg1, reg2) -> + ("Lswx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstswi(k0, reg1, k2) -> + ("Stswi", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("NB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pstswx(k0, reg1, reg2) -> + ("Stswx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k0)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Paddi(reg0, reg1, k2) -> + ("Addi", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("SI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Paddis(reg0, reg1, k2) -> + ("Addis", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("SI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Padd(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Add", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Psubf(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Subf", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Paddic(reg0, reg1, k2) -> + ("Addic", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("SI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Paddicdot(reg0, reg1, k2) -> + ("AddicDot", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("SI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Psubfic(reg0, reg1, k2) -> + ("Subfic", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("SI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Paddc(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Addc", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Psubfc(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Subfc", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Padde(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Adde", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Psubfe(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Subfe", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Paddme(setsoov0, setcr01, reg2, reg3) -> + ("Addme", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Psubfme(setsoov0, setcr01, reg2, reg3) -> + ("Subfme", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Paddze(setsoov0, setcr01, reg2, reg3) -> + ("Addze", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Psubfze(setsoov0, setcr01, reg2, reg3) -> + ("Subfze", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pneg(setsoov0, setcr01, reg2, reg3) -> + ("Neg", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmulli(reg0, reg1, k2) -> + ("Mulli", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("SI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pmullw(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Mullw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmulhw(setcr00, reg1, reg2, reg3) -> + ("Mulhw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pmulhwu(setcr00, reg1, reg2, reg3) -> + ("Mulhwu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pdivw(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Divw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pdivwu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Divwu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pdivwe(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Divwe", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pdivweu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Divweu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmulld(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Mulld", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmulhd(setcr00, reg1, reg2, reg3) -> + ("Mulhd", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pmulhdu(setcr00, reg1, reg2, reg3) -> + ("Mulhdu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pdivd(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Divd", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pdivdu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Divdu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pdivde(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Divde", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pdivdeu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Divdeu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pcmpi(crindex0, k1, reg2, k3) -> + ("Cmpi", + [("BF", IInt.Bvector (Some 3), SB.bit_list_of_integer 3 (Nat_big_num.of_int crindex0)); + ("L", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int k1)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("SI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k3))], + [(* always empty base effects*)] + ) + | `Pcmp(crindex0, k1, reg2, reg3) -> + ("Cmp", + [("BF", IInt.Bvector (Some 3), SB.bit_list_of_integer 3 (Nat_big_num.of_int crindex0)); + ("L", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int k1)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3)))], + [(* always empty base effects*)] + ) + | `Pcmpli(crindex0, k1, reg2, k3) -> + ("Cmpli", + [("BF", IInt.Bvector (Some 3), SB.bit_list_of_integer 3 (Nat_big_num.of_int crindex0)); + ("L", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int k1)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("UI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k3))], + [(* always empty base effects*)] + ) + | `Pcmpl(crindex0, k1, reg2, reg3) -> + ("Cmpl", + [("BF", IInt.Bvector (Some 3), SB.bit_list_of_integer 3 (Nat_big_num.of_int crindex0)); + ("L", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int k1)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3)))], + [(* always empty base effects*)] + ) + | `Pisel(reg0, reg1, reg2, k3) -> + ("Isel", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("BC", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k3))], + [(* always empty base effects*)] + ) + | `Pandi(reg0, reg1, k2) -> + ("Andi", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("UI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pandis(reg0, reg1, k2) -> + ("Andis", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("UI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pori(reg0, reg1, k2) -> + ("Ori", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("UI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Poris(reg0, reg1, k2) -> + ("Oris", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("UI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pxori(reg0, reg1, k2) -> + ("Xori", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("UI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pxoris(reg0, reg1, k2) -> + ("Xoris", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("UI", IInt.Bvector (Some 16), SB.bit_list_of_integer 16 (Nat_big_num.of_int k2))], + [(* always empty base effects*)] + ) + | `Pand(setcr00, reg1, reg2, reg3) -> + ("And", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pxor(setcr00, reg1, reg2, reg3) -> + ("Xor", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pnand(setcr00, reg1, reg2, reg3) -> + ("Nand", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Por(setcr00, reg1, reg2, reg3) -> + ("Or", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pnor(setcr00, reg1, reg2, reg3) -> + ("Nor", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Peqv(setcr00, reg1, reg2, reg3) -> + ("Eqv", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pandc(setcr00, reg1, reg2, reg3) -> + ("Andc", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Porc(setcr00, reg1, reg2, reg3) -> + ("Orc", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pextsb(setcr00, reg1, reg2) -> + ("Extsb", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pextsh(setcr00, reg1, reg2) -> + ("Extsh", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pcntlzw(setcr00, reg1, reg2) -> + ("Cntlzw", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pcmpb(reg0, k1, reg2) -> + ("Cmpb", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k1)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Ppopcntb(reg0, reg1) -> + ("Popcntb", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0)))], + [(* always empty base effects*)] + ) + | `Ppopcntw(reg0, reg1) -> + ("Popcntw", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0)))], + [(* always empty base effects*)] + ) + | `Pprtyd(reg0, reg1) -> + ("Prtyd", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0)))], + [(* always empty base effects*)] + ) + | `Pprtyw(reg0, reg1) -> + ("Prtyw", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0)))], + [(* always empty base effects*)] + ) + | `Pextsw(setcr00, reg1, reg2) -> + ("Extsw", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pcntlzd(setcr00, reg1, reg2) -> + ("Cntlzd", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Ppopcntd(reg0, reg1) -> + ("Popcntd", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0)))], + [(* always empty base effects*)] + ) + | `Pbpermd(reg0, reg1, reg2) -> + ("Bpermd", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Prlwinm(setcr00, reg1, reg2, k3, k4, k5) -> + ("Rlwinm", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("SH", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k3)); + ("MB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k4)); + ("ME", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k5)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Prlwnm(setcr00, reg1, reg2, reg3, k4, k5) -> + ("Rlwnm", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("MB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k4)); + ("ME", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k5)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Prlwimi(setcr00, reg1, reg2, k3, k4, k5) -> + ("Rlwimi", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("SH", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k3)); + ("MB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k4)); + ("ME", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k5)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Prldicl(setcr00, reg1, reg2, k3, k4) -> + ("Rldicl", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("sh", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k3)); + ("mb", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k4)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Prldicr(setcr00, reg1, reg2, k3, k4) -> + ("Rldicr", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("sh", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k3)); + ("me", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k4)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Prldic(setcr00, reg1, reg2, k3, k4) -> + ("Rldic", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("sh", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k3)); + ("mb", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k4)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Prldcl(setcr00, reg1, reg2, reg3, k4) -> + ("Rldcl", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("mb", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k4)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Prldcr(setcr00, reg1, reg2, reg3, k4) -> + ("Rldcr", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("me", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k4)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Prldimi(setcr00, reg1, reg2, k3, k4) -> + ("Rldimi", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("sh", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k3)); + ("mb", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k4)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pslw(setcr00, reg1, reg2, reg3) -> + ("Slw", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Psrw(setcr00, reg1, reg2, reg3) -> + ("Srw", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Psrawi(setcr00, reg1, reg2, k3) -> + ("Srawi", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("SH", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k3)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Psraw(setcr00, reg1, reg2, reg3) -> + ("Sraw", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Psld(setcr00, reg1, reg2, reg3) -> + ("Sld", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Psrd(setcr00, reg1, reg2, reg3) -> + ("Srd", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Psradi(setcr00, reg1, reg2, k3) -> + ("Sradi", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("sh", IInt.Bvector (Some 6), SB.bit_list_of_integer 6 (Nat_big_num.of_int k3)); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Psrad(setcr00, reg1, reg2, reg3) -> + ("Srad", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pcdtbcd(reg0, reg1) -> + ("Cdtbcd", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0)))], + [(* always empty base effects*)] + ) + | `Pcbcdtd(reg0, reg1) -> + ("Cbcdtd", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0)))], + [(* always empty base effects*)] + ) + | `Paddg6s(reg0, reg1, reg2) -> + ("Addg6s", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pmtspr(k0, reg1) -> + ("Mtspr", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("spr", IInt.Bvector (Some 10), SB.bit_list_of_integer 10 (Nat_big_num.of_int k0))], + [(* always empty base effects*)] + ) + | `Pmfspr(reg0, k1) -> + ("Mfspr", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("spr", IInt.Bvector (Some 10), SB.bit_list_of_integer 10 (Nat_big_num.of_int k1))], + [(* always empty base effects*)] + ) + | `Pmtcrf(crmask0, reg1) -> + ("Mtcrf", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("FXM", IInt.Bvector (Some 8), SB.bit_list_of_integer 8 (Nat_big_num.of_int crmask0))], + [(* always empty base effects*)] + ) + | `Pmfcr(reg0) -> + ("Mfcr", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0)))], + [(* always empty base effects*)] + ) + | `Pmtocrf(crmask0, reg1) -> + ("Mtocrf", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("FXM", IInt.Bvector (Some 8), SB.bit_list_of_integer 8 (Nat_big_num.of_int crmask0))], + [(* always empty base effects*)] + ) + | `Pmfocrf(reg0, crmask1) -> + ("Mfocrf", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("FXM", IInt.Bvector (Some 8), SB.bit_list_of_integer 8 (Nat_big_num.of_int crmask1))], + [(* always empty base effects*)] + ) + | `Pmcrxr(crindex0) -> + ("Mcrxr", + [("BF", IInt.Bvector (Some 3), SB.bit_list_of_integer 3 (Nat_big_num.of_int crindex0))], + [(* always empty base effects*)] + ) + | `Pdlmzb(setcr00, reg1, reg2, reg3) -> + ("Dlmzb", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pmacchw(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Macchw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmacchws(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Macchws", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmacchwu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Macchwu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmacchwsu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Macchwsu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmachhw(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Machhw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmachhws(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Machhws", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmachhwu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Machhwu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmachhwsu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Machhwsu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmaclhw(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Maclhw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmaclhws(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Maclhws", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmaclhwu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Maclhwu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmaclhwsu(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Maclhwsu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pmulchw(setcr00, reg1, reg2, reg3) -> + ("Mulchw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pmulchwu(setcr00, reg1, reg2, reg3) -> + ("Mulchwu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pmulhhw(setcr00, reg1, reg2, reg3) -> + ("Mulhhw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pmulhhwu(setcr00, reg1, reg2, reg3) -> + ("Mulhhwu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pmullhw(setcr00, reg1, reg2, reg3) -> + ("Mullhw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pmullhwu(setcr00, reg1, reg2, reg3) -> + ("Mullhwu", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr00)))], + [(* always empty base effects*)] + ) + | `Pnmacchw(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Nmacchw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pnmacchws(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Nmacchws", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pnmachhw(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Nmachhw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pnmachhws(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Nmachhws", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pnmaclhw(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Nmaclhw", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Pnmaclhws(setsoov0, setcr01, reg2, reg3, reg4) -> + ("Nmaclhws", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg3))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg4))); + ("OE", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_soov setsoov0))); + ("Rc", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int (trans_cr0 setcr01)))], + [(* always empty base effects*)] + ) + | `Picbi(reg0, reg1) -> + ("Icbi", + [("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1)))], + [(* always empty base effects*)] + ) + | `Picbt(k0, reg1, reg2) -> + ("Icbt", + [("CT", IInt.Bvector (Some 4), SB.bit_list_of_integer 4 (Nat_big_num.of_int k0)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pdcba(reg0, reg1) -> + ("Dcba", + [("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1)))], + [(* always empty base effects*)] + ) + | `Pdcbt(reg0, reg1, k2) -> + ("Dcbt", + [("TH", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1)))], + [(* always empty base effects*)] + ) + | `Pdcbtst(reg0, reg1, k2) -> + ("Dcbtst", + [("TH", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int k2)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1)))], + [(* always empty base effects*)] + ) + | `Pdcbz(reg0, reg1) -> + ("Dcbz", + [("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1)))], + [(* always empty base effects*)] + ) + | `Pdcbst(reg0, reg1) -> + ("Dcbst", + [("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1)))], + [(* always empty base effects*)] + ) + | `Pdcbf(reg0, reg1, k2) -> + ("Dcbf", + [("L", IInt.Bvector (Some 2), SB.bit_list_of_integer 2 (Nat_big_num.of_int k2)); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1)))], + [(* always empty base effects*)] + ) + | `Pisync -> + ("Isync", + [], + [(* always empty base effects*)] + ) + | `Plbarx(reg0, reg1, reg2, k3) -> + ("Lbarx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("EH", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int k3))], + [(* always empty base effects*)] + ) + | `Plharx(reg0, reg1, reg2, k3) -> + ("Lharx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("EH", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int k3))], + [(* always empty base effects*)] + ) + | `Plwarx(reg0, reg1, reg2, k3) -> + ("Lwarx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("EH", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int k3))], + [(* always empty base effects*)] + ) + | `Pstbcx(reg0, reg1, reg2) -> + ("Stbcx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Psthcx(reg0, reg1, reg2) -> + ("Sthcx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pstwcx(reg0, reg1, reg2) -> + ("Stwcx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Pldarx(reg0, reg1, reg2, k3) -> + ("Ldarx", + [("RT", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2))); + ("EH", IInt.Bit, SB.bit_list_of_integer 1 (Nat_big_num.of_int k3))], + [(* always empty base effects*)] + ) + | `Pstdcx(reg0, reg1, reg2) -> + ("Stdcx", + [("RS", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg0))); + ("RA", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg1))); + ("RB", IInt.Bvector (Some 5), SB.bit_list_of_integer 5 (Nat_big_num.of_int (int_of_reg reg2)))], + [(* always empty base effects*)] + ) + | `Psync(k0) -> + ("Sync", + [("L", IInt.Bvector (Some 2), SB.bit_list_of_integer 2 (Nat_big_num.of_int k0))], + [(* always empty base effects*)] + ) + | `Peieio -> + ("Eieio", + [], + [(* always empty base effects*)] + ) + | `Pwait(k0) -> + ("Wait", + [("WC", IInt.Bvector (Some 2), SB.bit_list_of_integer 2 (Nat_big_num.of_int k0))], + [(* always empty base effects*)] + ) diff --git a/power/gen/trans_sail_types.hgen b/power/gen/trans_sail_types.hgen new file mode 100644 index 00000000..380fd6e7 --- /dev/null +++ b/power/gen/trans_sail_types.hgen @@ -0,0 +1,61 @@ +(* SS: should re-check interpretation of 1 and 0 *) +let trans_soov = function + | SetSOOV -> 1 + | DontSetSOOV -> 0 + +let trans_cr0 = function + | SetCR0 -> 1 + | DontSetCR0 -> 0 + +let trans_aa = function + | SetAA -> 1 + | DontSetAA -> 0 + +let trans_lk = function + | SetLK -> 1 + | DontSetLK -> 0 + + +(* translating branch target addresses *) +let trans_li_setaa_setlk_k setaa setlk li = li asr 2 +let trans_bd_setaa_setlk_k_k_k setaa setlk bo bi bd = bd asr 2 + +(* translating vector-scalar floating-point ops *) +(* all of these translate a 6-bit value into a 5:1 bit pair, but differ + in number and type of arguments *) +let trans_k xt = xt land 0x1F +let trans_xk xt = xt land 0x20 +let trans_t_k_k xt _ = trans_k xt +let trans_tx_k_k xt _ = trans_xk xt +let trans_t_k_reg_reg xt xa _ = trans_k xt +let trans_tx_k_reg_reg xt xa _ = trans_xk xt +let trans_s_k_reg_reg = trans_t_k_reg_reg +let trans_sx_k_reg_reg = trans_tx_k_reg_reg +let trans_t_k_k_k = trans_t_k_reg_reg +let trans_tx_k_k_k = trans_tx_k_reg_reg +let trans_b_k_k = trans_t_k_k +let trans_bx_k_k = trans_tx_k_k +let trans_a_k_k_k xt xa xb = trans_k xa +let trans_ax_k_k_k xt xa xb = trans_xk xa +let trans_b_k_k_k xt xa xb = trans_k xb +let trans_bx_k_k_k xt xa xb = trans_xk xb +let trans_a_crindex_k_k bf xa xb = trans_k xa +let trans_ax_crindex_k_k bf xa xb = trans_xk xa +let trans_b_crindex_k_k bf xa xb = trans_k xb +let trans_bx_crindex_k_k bf xa xb = trans_xk xb +let trans_b_crindex_k bf xb = trans_k xb +let trans_bx_crindex_k bf xb = trans_xk xb +let trans_t_setcr0_k_k_k setcr0 xt xa xb = trans_k xt +let trans_tx_setcr0_k_k_k setcr0 xt xa xb = trans_xk xt +let trans_a_setcr0_k_k_k setcr0 xt xa xb = trans_k xa +let trans_ax_setcr0_k_k_k setcr0 xt xa xb = trans_xk xa +let trans_b_setcr0_k_k_k setcr0 xt xa xb = trans_k xb +let trans_bx_setcr0_k_k_k setcr0 xt xa xb = trans_xk xb +let trans_t_k_k_k_k xt xa xb dm = trans_k xt +let trans_tx_k_k_k_k xt xa xb dm = trans_xk xt +let trans_a_k_k_k_k xt xa xb dm = trans_k xa +let trans_ax_k_k_k_k xt xa xb dm = trans_xk xa +let trans_b_k_k_k_k xt xa xb dm = trans_k xb +let trans_bx_k_k_k_k xt xa xb dm = trans_xk xb +let trans_c_k_k_k_k xt xa xb xc = trans_k xc +let trans_cx_k_k_k_k xt xa xb xc = trans_xk xc
\ No newline at end of file diff --git a/power/power.sail b/power/power.sail new file mode 100644 index 00000000..026502b1 --- /dev/null +++ b/power/power.sail @@ -0,0 +1,4607 @@ +(*========================================================================*) +(* *) +(* Copyright (c) 2015-2017 Gabriel Kerneis, Susmit Sarkar, Kathyrn Gray *) +(* Copyright (c) 2015-2017 Peter Sewell *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(*========================================================================*) + +(* XXX binary coded decimal *) +(*function bit[12] DEC_TO_BCD ( (bit[10]) declet ) = { + (bit[4]) hundreds := 0; + (bit[4]) tens := 0; + (bit[4]) ones := 0; + foreach (i from 0 to 9) { + if hundreds >= 5 then hundreds := hundreds + 3; + if tens >= 5 then tens := tens + 3; + if ones >= 5 then ones := ones + 3; + hundreds := hundreds << 1; + hundreds[3] := tens[0]; + tens := tens << 1; + tens[3] := ones[0]; + ones := ones << 1; + ones[3] := declet[i] }; + hundreds:tens:ones }*) + +function bit[12] DEC_TO_BCD ( (bit[10]) [p,q,r,s,t,u,v,w,x,y]) = { + a := ((~(s) & v & w) | (t & v & w & s) | (v & w & ~(x))); + b := ((p & s & x & ~(t)) | (p & ~(w)) | (p & ~(v))); + c := ((q & s & x & ~(t)) | (q & ~(w)) | (q & ~(v))); + d := r; + + e := ((v & ~(w) & x) | (s & v & w & x) | (~(t) & v & x & w)); + f := ((p & t & v & w & x & ~(s)) | (s & ~(x) & v) | (s & ~(v))); + g := ((q & t & w & v & x & ~(s)) | (t & ~(x) & v) | (t & ~(v))); + h := u; + + i := ((t & v & w & x) | (s & v & w & x) | (v & ~(w) & ~(x))); + j := ((p & ~(s) & ~(t) & w & v) | (s & v & ~(w) & x) | (p & w & ~(x) & v) | (w & ~(v))); + k := ((q & ~(s) & ~(t) & v & w) | (t & v & ~(w) & x) | (q & v & w & ~(x)) | (x & ~(v))); + m := y; + [a,b,c,d,e,f,g,h,i,j,k,m] +} + +(*function bit[10] BCD_TO_DEC ( (bit[12]) bcd ) = + (bit[10]) (([|2** 10|]) (bcd[0..3] * 100)) + ([|2** 7|]) ((([|2** 7|]) (bcd[4..7] * 10)) + bcd[8..11]) +*) + +function bit[10] BCD_TO_DEC ( (bit[12]) [a,b,c,d,e,f,g,h,i,j,k,m] ) = { + p := ((f & a & i & ~(e)) | (j & a & ~(i)) | (b & ~(a))); + q := ((g & a & i & ~(e)) | (k & a & ~(i)) | (c & ~(a))); + r := d; + s := ((j & ~(a) & e & ~(i)) | (f & ~(i) & ~(e)) | (f & ~(a) & ~(e)) | (e & i)); + t := ((k & ~(a) & e & ~(i)) | (g & ~(i) & ~(e)) | (g & ~(a) & ~(e)) | (a & i)); + u := h; + v := (a | e | i); + w := ((~(e) & j & ~(i)) | (e & i) | a); + x := ((~(a) & k & ~(i)) | (a & i) | e); + y := m; + [p,q,r,s,t,u,v,w,x,y] +} + +(* XXX carry out *) +function forall Nat 'a . bit carry_out ( (bit['a]) _,carry ) = carry +(* XXX Storage control *) +function forall Type 'a . 'a real_addr ( x ) = x +(* XXX For stvxl and lvxl - what does that do? *) +function forall Type 'a . unit mark_as_not_likely_to_be_needed_again_anytime_soon ( x ) = () + +(* XXX *) +val extern forall Nat 'k, Nat 'r, + 0 <= 'k, 'k <= 64, 'r + 'k = 64. + (bit[64], [|'k|]) -> [|0:'r|] effect pure countLeadingZeroes + +function forall Nat 'n, Nat 'm . + bit['m] EXTS_EXPLICIT((bit['n]) v, ([:'m:]) m) = + (v[0] ^^ (m - length(v))) : v + +val forall Nat 'n, Nat 'm, 0 <= 'n, 'n <= 'm, 'm <= 63 . + ([|'n|],[|'m|]) -> bit[64] + effect pure + MASK + +function (bit[64]) MASK(start, stop) = { + (bit[64]) mask_temp := 0; + if(start > stop) then { + mask_temp[start .. 63] := bitone ^^ (64 - start); + mask_temp[0 .. stop] := bitone ^^ (stop + 1); + } else { + mask_temp[start .. stop ] := bitone ^^ (stop - start + 1); + }; + mask_temp; +} + +val forall Nat 'n, 0 <= 'n, 'n <= 63 . + (bit[64], [|'n|]) -> bit[64] effect pure ROTL + +function (bit[64]) ROTL(v, n) = v[n .. 63] : v[0 .. (n - 1)] + +(* Branch facility registers *) + +typedef cr = register bits [ 32 : 63 ] { + 32 .. 35 : CR0; + 32 : LT; 33 : GT; 34 : EQ; 35 : SO; + 36 .. 39 : CR1; + 36 : FX; 37 : FEX; 38 : VX; 39 : OX; + 40 .. 43 : CR2; + 44 .. 47 : CR3; + 48 .. 51 : CR4; + 52 .. 55 : CR5; + 56 .. 59 : CR6; + (* name clashing - do we need hierarchical naming for fields, or do + we just don't care? LT, GT, etc. are not used in the code anyway. + 56 : LT; 57 : GT; 58 : EQ; 59 : SO; + *) + 60 .. 63 : CR7; +} +register (cr) CR + +register (bit[64]) CTR +register (bit[64]) LR + +typedef xer = register bits [ 0 : 63 ] { + 32 : SO; + 33 : OV; + 34 : CA; +} +register (xer) XER + +register alias CA = XER.CA + +(* Fixed-point registers *) + +register (bit[64]) GPR0 +register (bit[64]) GPR1 +register (bit[64]) GPR2 +register (bit[64]) GPR3 +register (bit[64]) GPR4 +register (bit[64]) GPR5 +register (bit[64]) GPR6 +register (bit[64]) GPR7 +register (bit[64]) GPR8 +register (bit[64]) GPR9 +register (bit[64]) GPR10 +register (bit[64]) GPR11 +register (bit[64]) GPR12 +register (bit[64]) GPR13 +register (bit[64]) GPR14 +register (bit[64]) GPR15 +register (bit[64]) GPR16 +register (bit[64]) GPR17 +register (bit[64]) GPR18 +register (bit[64]) GPR19 +register (bit[64]) GPR20 +register (bit[64]) GPR21 +register (bit[64]) GPR22 +register (bit[64]) GPR23 +register (bit[64]) GPR24 +register (bit[64]) GPR25 +register (bit[64]) GPR26 +register (bit[64]) GPR27 +register (bit[64]) GPR28 +register (bit[64]) GPR29 +register (bit[64]) GPR30 +register (bit[64]) GPR31 + +let (vector <0, 32, inc, (register<(bit[64])>) >) GPR = + [ GPR0, GPR1, GPR2, GPR3, GPR4, GPR5, GPR6, GPR7, GPR8, GPR9, GPR10, + GPR11, GPR12, GPR13, GPR14, GPR15, GPR16, GPR17, GPR18, GPR19, GPR20, + GPR21, GPR22, GPR23, GPR24, GPR25, GPR26, GPR27, GPR28, GPR29, GPR30, GPR31 + ] + +register (bit[32:63]) VRSAVE + +register (bit[64]) SPRG3 +register (bit[64]) SPRG4 +register (bit[64]) SPRG5 +register (bit[64]) SPRG6 +register (bit[64]) SPRG7 + +let (vector <0, 1024, inc, (register<(bit[64])>) >) SPR = + [ 1=XER, 8=LR, 9=CTR(*, 256=VRSAVE (*32 bit, so not 64, caught by type checker at last*)*), 259=SPRG3, 260=SPRG4, 261=SPRG5, 262=SPRG6, 263=SPRG7 + ] + +(* XXX DCR is implementation-dependent; also, some DCR are only 32 bits + instead of 64, and mtdcrux/mfdcrux do special tricks in that case, not + shown in pseudo-code. We just define two dummy DCR here, using sparse + vector definition. *) +register (vector <0, 64, inc, bit>) DCR0 +register (vector <0, 64, inc, bit>) DCR1 +let (vector <0, 1024, inc, (register<(vector<0, 64, inc, bit>)>) >) DCR = + [ 0=DCR0, 1=DCR1 ; default=undefined] + +(* Floating-point registers *) + +register (bit[64]) FPR0 +register (bit[64]) FPR1 +register (bit[64]) FPR2 +register (bit[64]) FPR3 +register (bit[64]) FPR4 +register (bit[64]) FPR5 +register (bit[64]) FPR6 +register (bit[64]) FPR7 +register (bit[64]) FPR8 +register (bit[64]) FPR9 +register (bit[64]) FPR10 +register (bit[64]) FPR11 +register (bit[64]) FPR12 +register (bit[64]) FPR13 +register (bit[64]) FPR14 +register (bit[64]) FPR15 +register (bit[64]) FPR16 +register (bit[64]) FPR17 +register (bit[64]) FPR18 +register (bit[64]) FPR19 +register (bit[64]) FPR20 +register (bit[64]) FPR21 +register (bit[64]) FPR22 +register (bit[64]) FPR23 +register (bit[64]) FPR24 +register (bit[64]) FPR25 +register (bit[64]) FPR26 +register (bit[64]) FPR27 +register (bit[64]) FPR28 +register (bit[64]) FPR29 +register (bit[64]) FPR30 +register (bit[64]) FPR31 + +let (vector <0, 32, inc, (register<(bit[64])>) >) FPR = + [ FPR0, FPR1, FPR2, FPR3, FPR4, FPR5, FPR6, FPR7, FPR8, FPR9, FPR10, + FPR11, FPR12, FPR13, FPR14, FPR15, FPR16, FPR17, FPR18, FPR19, FPR20, + FPR21, FPR22, FPR23, FPR24, FPR25, FPR26, FPR27, FPR28, FPR29, FPR30, FPR31 + ] + +typedef fpscr = register bits [ 0 : 63 ] { + 32 : FX; + 33 : FEX; + 34 : VX; + 35 : OX; + 36 : UX; + 37 : ZX; + 38 : XX; + 39 : VXSNAN; + 40 : VXISI; + 41 : VXIDI; + 42 : VXZDZ; + 43 : VXIMZ; + 44 : VXVC; + 45 : FR; + 46 : FI; + 47 .. 51 : FPRF; + 47 : C; + 48 .. 51 : FPCC; + 48 : FL; 49 : FG; 50 : FE; 51 : FU; + 53 : VXSOFT; + 54 : VXSQRT; + 55 : VXCVI; + 56 : VE; + 57 : OE; + 58 : UE; + 59 : ZE; + 60 : XE; + 61 : NI; + 62 .. 63 : RN; +} +register (fpscr) FPSCR + +(* Pair-wise access to FPR registers *) + +register alias FPRp0 = FPR0 : FPR1 +register alias FPRp2 = FPR2 : FPR3 +register alias FPRp4 = FPR4 : FPR5 +register alias FPRp6 = FPR6 : FPR7 +register alias FPRp8 = FPR8 : FPR9 +register alias FPRp10 = FPR10 : FPR11 +register alias FPRp12 = FPR12 : FPR13 +register alias FPRp14 = FPR14 : FPR15 +register alias FPRp16 = FPR16 : FPR17 +register alias FPRp18 = FPR18 : FPR19 +register alias FPRp20 = FPR20 : FPR21 +register alias FPRp22 = FPR22 : FPR23 +register alias FPRp24 = FPR24 : FPR25 +register alias FPRp26 = FPR26 : FPR27 +register alias FPRp28 = FPR28 : FPR29 +register alias FPRp30 = FPR30 : FPR31 + +let (vector <0, 32, inc, (register<(bit[128])>)>) FPRp = + [ 0 = FPRp0, 2 = FPRp2, 4 = FPRp4, 6 = FPRp6, 8 = FPRp8, 10 = FPRp10, + 12 = FPRp12, 14 = FPRp14, 16 = FPRp16, 18 = FPRp18, 20 = FPRp20, 22 = + FPRp22, 24 = FPRp24, 26 = FPRp26, 28 = FPRp28, 30 = FPRp30 ] + + +val bit[32] -> bit[64] effect pure DOUBLE +val bit[64] -> bit[32] effect { undef } SINGLE + +function bit[64] DOUBLE word = { + (bit[64]) temp := 0; + if word[1..8] > 0 & word[1..8] < 255 + then { + temp[0..1] := word[0..1]; + temp[2] := ~(word[1]); + temp[3] := ~(word[1]); + temp[4] := ~(word[1]); + temp[5..63] := word[2..31] : 0b00000000000000000000000000000; + } else if word[1..8] == 0 & word[9..31] != 0 + then { + sign := word[0]; + exp := 0 - 126; + (bit[53]) frac := 0b0 : word[9..31] : 0b00000000000000000000000000000; + foreach (i from 0 to 52) { + if frac[0] == 0 + then { frac[0..52] := frac[1..52] : 0b0; + exp := exp - 1; } + else () + }; + temp[0] := sign; + temp[1..11] := (bit[1:11]) exp + 1023; + temp[12..63] := frac[1..52]; + } else { + temp[0..1] := word[0..1]; + temp[2] := word[1]; + temp[3] := word[1]; + temp[4] := word[1]; + temp[5..63] := word[2..31] : 0b00000000000000000000000000000; + }; + temp +} + +function bit[32] SINGLE ((bit[64]) frs) = { + (bit[32]) word := 0; + if (frs[1..11] > 896) | (frs[1..63] == 0) + then { word[0..1] := frs[0..1]; + word[2..31] := frs[5..34]; } + else if (874 <= frs[1..11]) & (frs[1..11] <= 896) + then { + sign := frs[0]; + (bit[11]) exp := frs[1..11] - 1023; + (bit[53]) frac := 0b1 : frs[12..63]; + foreach (i from 0 to 53) { + if exp < (0 - 126) + then { frac[0..52] := 0b0 : frac[0..51]; + exp := exp + 1; } + else ()}; + } else word := undefined; + word +} + +(* Vector registers *) + +register (bit[128]) VR0 +register (bit[128]) VR1 +register (bit[128]) VR2 +register (bit[128]) VR3 +register (bit[128]) VR4 +register (bit[128]) VR5 +register (bit[128]) VR6 +register (bit[128]) VR7 +register (bit[128]) VR8 +register (bit[128]) VR9 +register (bit[128]) VR10 +register (bit[128]) VR11 +register (bit[128]) VR12 +register (bit[128]) VR13 +register (bit[128]) VR14 +register (bit[128]) VR15 +register (bit[128]) VR16 +register (bit[128]) VR17 +register (bit[128]) VR18 +register (bit[128]) VR19 +register (bit[128]) VR20 +register (bit[128]) VR21 +register (bit[128]) VR22 +register (bit[128]) VR23 +register (bit[128]) VR24 +register (bit[128]) VR25 +register (bit[128]) VR26 +register (bit[128]) VR27 +register (bit[128]) VR28 +register (bit[128]) VR29 +register (bit[128]) VR30 +register (bit[128]) VR31 + +let (vector <0, 32, inc, (register<(bit[128])>) >) VR = + [ VR0, VR1, VR2, VR3, VR4, VR5, VR6, VR7, VR8, VR9, VR10, + VR11, VR12, VR13, VR14, VR15, VR16, VR17, VR18, VR19, VR20, + VR21, VR22, VR23, VR24, VR25, VR26, VR27, VR28, VR29, VR30, VR31 + ] + +typedef vscr = register bits [ 96 : 127 ] { + 111 : NJ; + 127 : SAT; +} +register (vscr) VSCR + +(*(* XXX extend with zeroes -- the resulting size in completely unknown and depends of context *) +val extern forall Nat 'n, Nat 'm. (implicit<'m>,bit['n]) -> bit['m] effect pure EXTZ*) + +(* Chop has a very weird definition where the resulting size depends of + context, but in practice it is used with the following definition everywhere, + except in vaddcuw which probably needs to be patched accordingly. *) +val forall Nat 'n, Nat 'm, 'm <= 'n. (bit['n], [:'m:]) -> bit['m] effect pure Chop +function forall Nat 'n, Nat 'm. (bit['m]) Chop(x, y) = x[0..y] + +val forall Nat 'o, Nat 'n, Nat 'm, Nat 'k, 'n <= 0. + (implicit<'k>, [:'o:], [:'n:], [|'m|]) -> bit['k] effect { wreg } Clamp + +function forall Nat 'o,Nat 'n, Nat 'm, Nat 'k, 'n <= 0. (bit['k]) +Clamp(([:'o:]) x, ([:'n:]) y, ([|'m|]) z) = { + ([|'n:'m|]) result := 0; + if (x<y) then { + result := y; + VSCR.SAT := 1; + } else if (x > z) then { + result := z; + VSCR.SAT := 1; + } else { + result := x; + }; + (bit['k]) result; +} + +(* XXX *) +val extern bit[32] -> bit[32] effect pure RoundToSPIntCeil +val extern bit[32] -> bit[32] effect pure RoundToSPIntFloor +val extern bit[32] -> bit[32] effect pure RoundToSPIntNear +val extern bit[32] -> bit[32] effect pure RoundToSPIntTrunc +val extern bit[32] -> bit[32] effect pure RoundToNearSP +val extern bit[32] -> bit[32] effect pure ReciprocalEstimateSP +val extern bit[32] -> bit[32] effect pure ReciprocalSquareRootEstimateSP +val extern bit[32] -> bit[32] effect pure LogBase2EstimateSP +val extern bit[32] -> bit[32] effect pure Power2EstimateSP +val extern (bit[32], bit[5]) -> bit[32] effect pure ConvertSPtoSXWsaturate +val extern (bit[32], bit[5]) -> bit[32] effect pure ConvertSPtoUXWsaturate + + +register (bit[64]) NIA (* next instruction address *) +register (bit[64]) CIA (* current instruction address *) + + +val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMw' +val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr' +val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr_reserve' +val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> bool effect { wmv } MEMw_conditional' + +(* announce write address for plain write *) +val extern forall Nat 'N, 'N IN {1,2,4,8,16}. (bit[64] (*address*), [:'N:] (*size*)) -> unit effect {eamem} MEMw_EA + +(* announce write address for write conditional *) +val extern forall Nat 'N, 'N IN {1,2,4,8,16}. (bit[64] (*address*), [:'N:] (*size*)) -> unit effect {eamem} MEMw_EA_cond + +val extern unit -> unit effect { barr } I_Sync +val extern unit -> unit effect { barr } H_Sync (*corresponds to Sync in barrier kinds*) +val extern unit -> unit effect { barr } LW_Sync +val extern unit -> unit effect { barr } EIEIO_Sync + +val extern unit -> unit effect { depend } recalculate_dependency + +val forall Nat 'n, Nat 'm, 'n *8 = 'm. (implicit<'m>,(bit['m])) -> (bit['m]) effect pure byte_reverse +function forall Nat 'n, Nat 'm, 'n*8 = 'm. (bit['m]) effect pure byte_reverse((bit['m]) input) = { + (bit['m]) output := 0; + j := length(input); + foreach (i from 0 to (length(input)) by 8) { + output[i..i+7] := input[j - 7 ..j]; + j := j - 8; }; + output +} + +(* XXX effect for trap? *) +val extern unit -> unit effect {escape} trap + +register (bit[1]) mode64bit +register (bit[1]) bigendianmode + +val forall Nat 'W, 'W IN {8,16,32,64,128}. bit['W] -> bit['W] effect pure reverse_endianness +function rec forall Nat 'W, 'W IN {8, 16, 32, 64, 128}. bit['W] reverse_endianness ((bit['W]) value) = +{ + (nat) width := length(value); + (nat) half := width quot 2; + if width == 8 then value + else reverse_endianness(value[half .. (width - 1)]) : reverse_endianness(value[0 .. (half - 1)]); +} + +function forall Nat 'n. unit effect { wmv } MEMw ((bit[64]) ea, ([|'n|]) size, (bit[8*'n]) value) = +{ + if bigendianmode then + MEMw'(ea, size, reverse_endianness(value)) + else + MEMw'(ea, size, value) +} + +function forall Nat 'n. (bit[8 * 'n]) effect { rmem } MEMr ((bit[64]) ea, ([|'n|]) size) = +{ + if bigendianmode then + reverse_endianness(MEMr'(ea, size)) + else + MEMr'(ea, size) +} + +function forall Nat 'n. (bit[8 * 'n]) effect { rmem } MEMr_reserve ((bit[64]) ea, ([|'n|]) size) = +{ + if bigendianmode then + reverse_endianness(MEMr_reserve'(ea, size)) + else + MEMr_reserve'(ea, size) +} + +function forall Nat 'n. bool effect { wmv } MEMw_conditional ((bit[64]) ea, ([|'n|]) size, (bit[8*'n]) value) = +{ + if bigendianmode then + MEMw_conditional'(ea, size, reverse_endianness(value)) + else + MEMw_conditional'(ea, size, value) +} + + + +val (bit[64],bit) -> unit effect {rreg,wreg} set_overflow_cr0 +function (unit) set_overflow_cr0(target_register,new_xer_so) = { + m:= 0; + (bit[3]) c:= 0; + (bit[64]) zero := 0; + (if mode64bit + then m := 0 + else m := 32); + (if target_register[m..63] <_s zero[m..63] + then c := 0b100 + else if target_register[m..63] >_s zero[m..63] + then c := 0b010 + else c := 0b001); + CR.CR0 := c:[new_xer_so] +} + +function (unit) set_SO_OV(overflow) = { + XER.OV := overflow; + XER.SO := (XER.SO | overflow); +} + +function forall Nat 'n. (bit['n]) zero_or_undef ((bit['n]) x) = { + (bit['n]) out := 0; + foreach (i from 0 to ((length(x)) - 1)) { + out[i] := if x[i] then undefined else 0 + }; + out +} + +scattered function unit execute +scattered typedef ast = const union + +val bit[32] -> option<ast> effect pure decode + +scattered function option<ast> decode + +union ast member (bit[24], bit, bit) B + +function clause decode (0b010010 : (bit[24]) LI : [AA] : [LK] as instr) = Some(B(LI,AA,LK)) + +function clause execute (B (LI, AA, LK)) = + { + if AA then NIA := EXTS(LI : 0b00) else NIA := CIA + EXTS(LI : 0b00); + if LK then LR := CIA + 4 else () + } + +union ast member (bit[5], bit[5], bit[14], bit, bit) Bc + +function clause decode (0b010000 : +(bit[5]) BO : +(bit[5]) BI : +(bit[14]) BD : +[AA] : +[LK] as instr) = + Some(Bc(BO,BI,BD,AA,LK)) + +function clause execute (Bc (BO, BI, BD, AA, LK)) = + { + if mode64bit then M := 0 else M := 32; + (bit[64]) ctr_temp := CTR; + if ~(BO[2]) + then { + ctr_temp := ctr_temp - 1; + CTR := ctr_temp + } + else (); + ctr_ok := (BO[2] | ~(ctr_temp[M .. 63] == 0) ^ BO[3]); + cond_ok := (BO[0] | CR[BI + 32] ^ ~(BO[1])); + if ctr_ok & cond_ok + then if AA then NIA := EXTS(BD : 0b00) else NIA := CIA + EXTS(BD : 0b00) + else (); + if LK then LR := CIA + 4 else () + } + +union ast member (bit[5], bit[5], bit[2], bit) Bclr + +function clause decode (0b010011 : +(bit[5]) BO : +(bit[5]) BI : +(bit[3]) _ : +(bit[2]) BH : +0b0000010000 : +[LK] as instr) = + Some(Bclr(BO,BI,BH,LK)) + +function clause execute (Bclr (BO, BI, BH, LK)) = + { + if mode64bit then M := 0 else M := 32; + (bit[64]) ctr_temp := CTR; + if ~(BO[2]) + then { + ctr_temp := ctr_temp - 1; + CTR := ctr_temp + } + else (); + ctr_ok := (BO[2] | ~(ctr_temp[M .. 63] == 0) ^ BO[3]); + cond_ok := (BO[0] | CR[BI + 32] ^ ~(BO[1])); + if ctr_ok & cond_ok then NIA := LR[0 .. 61] : 0b00 else (); + if LK then LR := CIA + 4 else () + } + +union ast member (bit[5], bit[5], bit[2], bit) Bcctr + +function clause decode (0b010011 : +(bit[5]) BO : +(bit[5]) BI : +(bit[3]) _ : +(bit[2]) BH : +0b1000010000 : +[LK] as instr) = + Some(Bcctr(BO,BI,BH,LK)) + +function clause execute (Bcctr (BO, BI, BH, LK)) = + { + cond_ok := (BO[0] | CR[BI + 32] ^ ~(BO[1])); + if cond_ok then NIA := CTR[0 .. 61] : 0b00 else (); + if LK then LR := CIA + 4 else () + } + +union ast member (bit[5], bit[5], bit[5]) Crand + +function clause decode (0b010011 : +(bit[5]) BT : +(bit[5]) BA : +(bit[5]) BB : +0b0100000001 : +(bit[1]) _ as instr) = + Some(Crand(BT,BA,BB)) + +function clause execute (Crand (BT, BA, BB)) = CR[BT + 32] := (CR[BA + 32] & CR[BB + 32]) + +union ast member (bit[5], bit[5], bit[5]) Crnand + +function clause decode (0b010011 : +(bit[5]) BT : +(bit[5]) BA : +(bit[5]) BB : +0b0011100001 : +(bit[1]) _ as instr) = + Some(Crnand(BT,BA,BB)) + +function clause execute (Crnand (BT, BA, BB)) = CR[BT + 32] := ~(CR[BA + 32] & CR[BB + 32]) + +union ast member (bit[5], bit[5], bit[5]) Cror + +function clause decode (0b010011 : +(bit[5]) BT : +(bit[5]) BA : +(bit[5]) BB : +0b0111000001 : +(bit[1]) _ as instr) = + Some(Cror(BT,BA,BB)) + +function clause execute (Cror (BT, BA, BB)) = CR[BT + 32] := (CR[BA + 32] | CR[BB + 32]) + +union ast member (bit[5], bit[5], bit[5]) Crxor + +function clause decode (0b010011 : +(bit[5]) BT : +(bit[5]) BA : +(bit[5]) BB : +0b0011000001 : +(bit[1]) _ as instr) = + Some(Crxor(BT,BA,BB)) + +function clause execute (Crxor (BT, BA, BB)) = CR[BT + 32] := CR[BA + 32] ^ CR[BB + 32] + +union ast member (bit[5], bit[5], bit[5]) Crnor + +function clause decode (0b010011 : +(bit[5]) BT : +(bit[5]) BA : +(bit[5]) BB : +0b0000100001 : +(bit[1]) _ as instr) = + Some(Crnor(BT,BA,BB)) + +function clause execute (Crnor (BT, BA, BB)) = CR[BT + 32] := ~(CR[BA + 32] | CR[BB + 32]) + +union ast member (bit[5], bit[5], bit[5]) Creqv + +function clause decode (0b010011 : +(bit[5]) BT : +(bit[5]) BA : +(bit[5]) BB : +0b0100100001 : +(bit[1]) _ as instr) = + Some(Creqv(BT,BA,BB)) + +function clause execute (Creqv (BT, BA, BB)) = CR[BT + 32] := CR[BA + 32] ^ ~(CR[BB + 32]) + +union ast member (bit[5], bit[5], bit[5]) Crandc + +function clause decode (0b010011 : +(bit[5]) BT : +(bit[5]) BA : +(bit[5]) BB : +0b0010000001 : +(bit[1]) _ as instr) = + Some(Crandc(BT,BA,BB)) + +function clause execute (Crandc (BT, BA, BB)) = CR[BT + 32] := (CR[BA + 32] & ~(CR[BB + 32])) + +union ast member (bit[5], bit[5], bit[5]) Crorc + +function clause decode (0b010011 : +(bit[5]) BT : +(bit[5]) BA : +(bit[5]) BB : +0b0110100001 : +(bit[1]) _ as instr) = + Some(Crorc(BT,BA,BB)) + +function clause execute (Crorc (BT, BA, BB)) = CR[BT + 32] := (CR[BA + 32] | ~(CR[BB + 32])) + +union ast member (bit[3], bit[3]) Mcrf + +function clause decode (0b010011 : +(bit[3]) BF : +(bit[2]) _ : +(bit[3]) BFA : +(bit[2]) _ : +(bit[5]) _ : +0b0000000000 : +(bit[1]) _ as instr) = + Some(Mcrf(BF,BFA)) + +function clause execute (Mcrf (BF, BFA)) = + CR[4 * BF + 32..4 * BF + 35] := CR[4 * BFA + 32 .. 4 * BFA + 35] + +union ast member (bit[7]) Sc + +function clause decode (0b010001 : +(bit[5]) _ : +(bit[5]) _ : +(bit[4]) _ : +(bit[7]) LEV : +(bit[3]) _ : +0b1 : +(bit[1]) _ as instr) = + Some(Sc(LEV)) + +function clause execute (Sc (LEV)) = () + +union ast member (bit[7]) Scv + +function clause decode (0b010001 : +(bit[5]) _ : +(bit[5]) _ : +(bit[4]) _ : +(bit[7]) LEV : +(bit[3]) _ : +0b0 : +0b1 as instr) = + Some(Scv(LEV)) + +function clause execute (Scv (LEV)) = () + +union ast member (bit[5], bit[5], bit[16]) Lbz + +function clause decode (0b100010 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Lbz(RT,RA,D)) + +function clause execute (Lbz (RT, RA, D)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(D); + GPR[RT] := 0b00000000000000000000000000000000000000000000000000000000 : MEMr(EA,1) + } + +union ast member (bit[5], bit[5], bit[5]) Lbzx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0001010111 : +(bit[1]) _ as instr) = + Some(Lbzx(RT,RA,RB)) + +function clause execute (Lbzx (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := 0b00000000000000000000000000000000000000000000000000000000 : MEMr(EA,1) + } + +union ast member (bit[5], bit[5], bit[16]) Lbzu + +function clause decode (0b100011 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Lbzu(RT,RA,D)) + +function clause execute (Lbzu (RT, RA, D)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + EXTS(D); + GPR[RA] := EA; + GPR[RT] := 0b00000000000000000000000000000000000000000000000000000000 : MEMr(EA,1) + } + +union ast member (bit[5], bit[5], bit[5]) Lbzux + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0001110111 : +(bit[1]) _ as instr) = + Some(Lbzux(RT,RA,RB)) + +function clause execute (Lbzux (RT, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + GPR[RA] := EA; + GPR[RT] := 0b00000000000000000000000000000000000000000000000000000000 : MEMr(EA,1) + } + +union ast member (bit[5], bit[5], bit[16]) Lhz + +function clause decode (0b101000 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Lhz(RT,RA,D)) + +function clause execute (Lhz (RT, RA, D)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(D); + GPR[RT] := 0b000000000000000000000000000000000000000000000000 : MEMr(EA,2) + } + +union ast member (bit[5], bit[5], bit[5]) Lhzx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0100010111 : +(bit[1]) _ as instr) = + Some(Lhzx(RT,RA,RB)) + +function clause execute (Lhzx (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := 0b000000000000000000000000000000000000000000000000 : MEMr(EA,2) + } + +union ast member (bit[5], bit[5], bit[16]) Lhzu + +function clause decode (0b101001 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Lhzu(RT,RA,D)) + +function clause execute (Lhzu (RT, RA, D)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + EXTS(D); + GPR[RA] := EA; + GPR[RT] := 0b000000000000000000000000000000000000000000000000 : MEMr(EA,2) + } + +union ast member (bit[5], bit[5], bit[5]) Lhzux + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0100110111 : +(bit[1]) _ as instr) = + Some(Lhzux(RT,RA,RB)) + +function clause execute (Lhzux (RT, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + GPR[RA] := EA; + GPR[RT] := 0b000000000000000000000000000000000000000000000000 : MEMr(EA,2) + } + +union ast member (bit[5], bit[5], bit[16]) Lha + +function clause decode (0b101010 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Lha(RT,RA,D)) + +function clause execute (Lha (RT, RA, D)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(D); + GPR[RT] := EXTS(MEMr(EA,2)) + } + +union ast member (bit[5], bit[5], bit[5]) Lhax + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0101010111 : +(bit[1]) _ as instr) = + Some(Lhax(RT,RA,RB)) + +function clause execute (Lhax (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := EXTS(MEMr(EA,2)) + } + +union ast member (bit[5], bit[5], bit[16]) Lhau + +function clause decode (0b101011 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Lhau(RT,RA,D)) + +function clause execute (Lhau (RT, RA, D)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + EXTS(D); + GPR[RA] := EA; + GPR[RT] := EXTS(MEMr(EA,2)) + } + +union ast member (bit[5], bit[5], bit[5]) Lhaux + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0101110111 : +(bit[1]) _ as instr) = + Some(Lhaux(RT,RA,RB)) + +function clause execute (Lhaux (RT, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + GPR[RA] := EA; + GPR[RT] := EXTS(MEMr(EA,2)) + } + +union ast member (bit[5], bit[5], bit[16]) Lwz + +function clause decode (0b100000 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Lwz(RT,RA,D)) + +function clause execute (Lwz (RT, RA, D)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(D); + GPR[RT] := 0b00000000000000000000000000000000 : MEMr(EA,4) + } + +union ast member (bit[5], bit[5], bit[5]) Lwzx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0000010111 : +(bit[1]) _ as instr) = + Some(Lwzx(RT,RA,RB)) + +function clause execute (Lwzx (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := 0b00000000000000000000000000000000 : MEMr(EA,4) + } + +union ast member (bit[5], bit[5], bit[16]) Lwzu + +function clause decode (0b100001 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Lwzu(RT,RA,D)) + +function clause execute (Lwzu (RT, RA, D)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + EXTS(D); + GPR[RA] := EA; + GPR[RT] := 0b00000000000000000000000000000000 : MEMr(EA,4) + } + +union ast member (bit[5], bit[5], bit[5]) Lwzux + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0000110111 : +(bit[1]) _ as instr) = + Some(Lwzux(RT,RA,RB)) + +function clause execute (Lwzux (RT, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + GPR[RA] := EA; + GPR[RT] := 0b00000000000000000000000000000000 : MEMr(EA,4) + } + +union ast member (bit[5], bit[5], bit[14]) Lwa + +function clause decode (0b111010 : +(bit[5]) RT : +(bit[5]) RA : +(bit[14]) DS : +0b10 as instr) = + Some(Lwa(RT,RA,DS)) + +function clause execute (Lwa (RT, RA, DS)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(DS : 0b00); + GPR[RT] := EXTS(MEMr(EA,4)) + } + +union ast member (bit[5], bit[5], bit[5]) Lwax + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0101010101 : +(bit[1]) _ as instr) = + Some(Lwax(RT,RA,RB)) + +function clause execute (Lwax (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := EXTS(MEMr(EA,4)) + } + +union ast member (bit[5], bit[5], bit[5]) Lwaux + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0101110101 : +(bit[1]) _ as instr) = + Some(Lwaux(RT,RA,RB)) + +function clause execute (Lwaux (RT, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + GPR[RA] := EA; + GPR[RT] := EXTS(MEMr(EA,4)) + } + +union ast member (bit[5], bit[5], bit[14]) Ld + +function clause decode (0b111010 : +(bit[5]) RT : +(bit[5]) RA : +(bit[14]) DS : +0b00 as instr) = + Some(Ld(RT,RA,DS)) + +function clause execute (Ld (RT, RA, DS)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(DS : 0b00); + GPR[RT] := MEMr(EA,8) + } + +union ast member (bit[5], bit[5], bit[5]) Ldx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0000010101 : +(bit[1]) _ as instr) = + Some(Ldx(RT,RA,RB)) + +function clause execute (Ldx (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := MEMr(EA,8) + } + +union ast member (bit[5], bit[5], bit[14]) Ldu + +function clause decode (0b111010 : +(bit[5]) RT : +(bit[5]) RA : +(bit[14]) DS : +0b01 as instr) = + Some(Ldu(RT,RA,DS)) + +function clause execute (Ldu (RT, RA, DS)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + EXTS(DS : 0b00); + GPR[RA] := EA; + GPR[RT] := MEMr(EA,8) + } + +union ast member (bit[5], bit[5], bit[5]) Ldux + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0000110101 : +(bit[1]) _ as instr) = + Some(Ldux(RT,RA,RB)) + +function clause execute (Ldux (RT, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + GPR[RA] := EA; + GPR[RT] := MEMr(EA,8) + } + +union ast member (bit[5], bit[5], bit[16]) Stb + +function clause decode (0b100110 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Stb(RS,RA,D)) + +function clause execute (Stb (RS, RA, D)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(D); + MEMw_EA(EA,1); + MEMw(EA,1) := (GPR[RS])[56 .. 63] + } + +union ast member (bit[5], bit[5], bit[5]) Stbx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0011010111 : +(bit[1]) _ as instr) = + Some(Stbx(RS,RA,RB)) + +function clause execute (Stbx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA(EA,1); + MEMw(EA,1) := (GPR[RS])[56 .. 63] + } + +union ast member (bit[5], bit[5], bit[16]) Stbu + +function clause decode (0b100111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Stbu(RS,RA,D)) + +function clause execute (Stbu (RS, RA, D)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + EXTS(D); + MEMw_EA(EA,1); + GPR[RA] := EA; + MEMw(EA,1) := (GPR[RS])[56 .. 63] + } + +union ast member (bit[5], bit[5], bit[5]) Stbux + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0011110111 : +(bit[1]) _ as instr) = + Some(Stbux(RS,RA,RB)) + +function clause execute (Stbux (RS, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + MEMw_EA(EA,1); + GPR[RA] := EA; + MEMw(EA,1) := (GPR[RS])[56 .. 63] + } + +union ast member (bit[5], bit[5], bit[16]) Sth + +function clause decode (0b101100 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Sth(RS,RA,D)) + +function clause execute (Sth (RS, RA, D)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(D); + MEMw_EA(EA,2); + MEMw(EA,2) := (GPR[RS])[48 .. 63] + } + +union ast member (bit[5], bit[5], bit[5]) Sthx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0110010111 : +(bit[1]) _ as instr) = + Some(Sthx(RS,RA,RB)) + +function clause execute (Sthx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA(EA,2); + MEMw(EA,2) := (GPR[RS])[48 .. 63] + } + +union ast member (bit[5], bit[5], bit[16]) Sthu + +function clause decode (0b101101 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Sthu(RS,RA,D)) + +function clause execute (Sthu (RS, RA, D)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + EXTS(D); + MEMw_EA(EA,2); + GPR[RA] := EA; + MEMw(EA,2) := (GPR[RS])[48 .. 63] + } + +union ast member (bit[5], bit[5], bit[5]) Sthux + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0110110111 : +(bit[1]) _ as instr) = + Some(Sthux(RS,RA,RB)) + +function clause execute (Sthux (RS, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + MEMw_EA(EA,2); + GPR[RA] := EA; + MEMw(EA,2) := (GPR[RS])[48 .. 63] + } + +union ast member (bit[5], bit[5], bit[16]) Stw + +function clause decode (0b100100 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Stw(RS,RA,D)) + +function clause execute (Stw (RS, RA, D)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(D); + MEMw_EA(EA,4); + MEMw(EA,4) := (GPR[RS])[32 .. 63] + } + +union ast member (bit[5], bit[5], bit[5]) Stwx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0010010111 : +(bit[1]) _ as instr) = + Some(Stwx(RS,RA,RB)) + +function clause execute (Stwx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA(EA,4); + MEMw(EA,4) := (GPR[RS])[32 .. 63] + } + +union ast member (bit[5], bit[5], bit[16]) Stwu + +function clause decode (0b100101 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Stwu(RS,RA,D)) + +function clause execute (Stwu (RS, RA, D)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + EXTS(D); + MEMw_EA(EA,4); + GPR[RA] := EA; + MEMw(EA,4) := (GPR[RS])[32 .. 63] + } + +union ast member (bit[5], bit[5], bit[5]) Stwux + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0010110111 : +(bit[1]) _ as instr) = + Some(Stwux(RS,RA,RB)) + +function clause execute (Stwux (RS, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + MEMw_EA(EA,4); + GPR[RA] := EA; + MEMw(EA,4) := (GPR[RS])[32 .. 63] + } + +union ast member (bit[5], bit[5], bit[14]) Std + +function clause decode (0b111110 : +(bit[5]) RS : +(bit[5]) RA : +(bit[14]) DS : +0b00 as instr) = + Some(Std(RS,RA,DS)) + +function clause execute (Std (RS, RA, DS)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(DS : 0b00); + MEMw_EA(EA,8); + MEMw(EA,8) := GPR[RS] + } + +union ast member (bit[5], bit[5], bit[5]) Stdx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0010010101 : +(bit[1]) _ as instr) = + Some(Stdx(RS,RA,RB)) + +function clause execute (Stdx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA(EA,8); + MEMw(EA,8) := GPR[RS] + } + +union ast member (bit[5], bit[5], bit[14]) Stdu + +function clause decode (0b111110 : +(bit[5]) RS : +(bit[5]) RA : +(bit[14]) DS : +0b01 as instr) = + Some(Stdu(RS,RA,DS)) + +function clause execute (Stdu (RS, RA, DS)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + EXTS(DS : 0b00); + MEMw_EA(EA,8); + GPR[RA] := EA; + MEMw(EA,8) := GPR[RS] + } + +union ast member (bit[5], bit[5], bit[5]) Stdux + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0010110101 : +(bit[1]) _ as instr) = + Some(Stdux(RS,RA,RB)) + +function clause execute (Stdux (RS, RA, RB)) = + { + (bit[64]) EA := 0; + EA := GPR[RA] + GPR[RB]; + MEMw_EA(EA,8); + GPR[RA] := EA; + MEMw(EA,8) := GPR[RS] + } + +union ast member (bit[5], bit[5], bit[12], bit[4]) Lq + +function clause decode (0b111000 : +(bit[5]) RTp : +(bit[5]) RA : +(bit[12]) DQ : +(bit[4]) PT as instr) = + Some(Lq(RTp,RA,DQ,PT)) + +function clause execute (Lq (RTp, RA, DQ, PT)) = + { + (bit[64]) EA := 0; + (bit[64]) b := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(DQ : 0b0000); + (bit[128]) mem := MEMr(EA,16); + if bigendianmode + then { + GPR[RTp] := mem[0 .. 63]; + GPR[RTp + 1] := mem[64 .. 127] + } + else { + (bit[128]) bytereverse := byte_reverse(mem); + GPR[RTp] := bytereverse[0 .. 63]; + GPR[RTp + 1] := bytereverse[64 .. 127] + } + } + +union ast member (bit[5], bit[5], bit[14]) Stq + +function clause decode (0b111110 : +(bit[5]) RSp : +(bit[5]) RA : +(bit[14]) DS : +0b10 as instr) = + Some(Stq(RSp,RA,DS)) + +function clause execute (Stq (RSp, RA, DS)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(DS : 0b00); + MEMw_EA(EA,16); + (bit[128]) mem := 0; + mem[0..63] := GPR[RSp]; + mem[64..127] := GPR[RSp + 1]; + if ~(bigendianmode) then mem := byte_reverse(mem) else (); + MEMw(EA,16) := mem + } + +union ast member (bit[5], bit[5], bit[5]) Lhbrx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b1100010110 : +(bit[1]) _ as instr) = + Some(Lhbrx(RT,RA,RB)) + +function clause execute (Lhbrx (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + load_data := MEMr(EA,2); + GPR[RT] := + 0b000000000000000000000000000000000000000000000000 : load_data[8 .. 15] : load_data[0 .. 7] + } + +union ast member (bit[5], bit[5], bit[5]) Sthbrx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1110010110 : +(bit[1]) _ as instr) = + Some(Sthbrx(RS,RA,RB)) + +function clause execute (Sthbrx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA(EA,2); + MEMw(EA,2) := (GPR[RS])[56 .. 63] : (GPR[RS])[48 .. 55] + } + +union ast member (bit[5], bit[5], bit[5]) Lwbrx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b1000010110 : +(bit[1]) _ as instr) = + Some(Lwbrx(RT,RA,RB)) + +function clause execute (Lwbrx (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + load_data := MEMr(EA,4); + GPR[RT] := + 0b00000000000000000000000000000000 : + load_data[24 .. 31] : load_data[16 .. 23] : load_data[8 .. 15] : load_data[0 .. 7] + } + +union ast member (bit[5], bit[5], bit[5]) Stwbrx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1010010110 : +(bit[1]) _ as instr) = + Some(Stwbrx(RS,RA,RB)) + +function clause execute (Stwbrx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA(EA,4); + MEMw(EA,4) := + (GPR[RS])[56 .. 63] : (GPR[RS])[48 .. 55] : (GPR[RS])[40 .. 47] : (GPR[RS])[32 .. 39] + } + +union ast member (bit[5], bit[5], bit[5]) Ldbrx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b1000010100 : +(bit[1]) _ as instr) = + Some(Ldbrx(RT,RA,RB)) + +function clause execute (Ldbrx (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + load_data := MEMr(EA,8); + GPR[RT] := + load_data[56 .. 63] : + load_data[48 .. 55] : + load_data[40 .. 47] : + load_data[32 .. 39] : + load_data[24 .. 31] : load_data[16 .. 23] : load_data[8 .. 15] : load_data[0 .. 7] + } + +union ast member (bit[5], bit[5], bit[5]) Stdbrx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1010010100 : +(bit[1]) _ as instr) = + Some(Stdbrx(RS,RA,RB)) + +function clause execute (Stdbrx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA(EA,8); + MEMw(EA,8) := + (GPR[RS])[56 .. 63] : + (GPR[RS])[48 .. 55] : + (GPR[RS])[40 .. 47] : + (GPR[RS])[32 .. 39] : + (GPR[RS])[24 .. 31] : (GPR[RS])[16 .. 23] : (GPR[RS])[8 .. 15] : (GPR[RS])[0 .. 7] + } + +union ast member (bit[5], bit[5], bit[16]) Lmw + +function clause decode (0b101110 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Lmw(RT,RA,D)) + +function clause execute (Lmw (RT, RA, D)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(D); + size := ([|32|]) (32 - RT) * 4; + buffer := MEMr(EA,size); + i := 0; + foreach (r from RT to 31 by 1 in inc) + { + GPR[r] := 0b00000000000000000000000000000000 : buffer[i .. i + 31]; + i := i + 32 + } + } + +union ast member (bit[5], bit[5], bit[16]) Stmw + +function clause decode (0b101111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) D as instr) = + Some(Stmw(RS,RA,D)) + +function clause execute (Stmw (RS, RA, D)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + EXTS(D); + size := ([|32|]) (32 - RS) * 4; + MEMw_EA(EA,size); + (bit[994]) buffer := [0 = 0,993 = 0; default=0]; + i := 0; + foreach (r from RS to 31 by 1 in inc) + { + buffer[i..i + 31] := (GPR[r])[32 .. 63]; + i := i + 32 + }; + MEMw(EA,size) := buffer[0 .. size * 8 - 1] + } + +union ast member (bit[5], bit[5], bit[5]) Lswi + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) NB : +0b1001010101 : +(bit[1]) _ as instr) = + Some(Lswi(RT,RA,NB)) + +function clause execute (Lswi (RT, RA, NB)) = + { + (bit[64]) EA := 0; + if RA == 0 then EA := 0 else EA := GPR[RA]; + ([|31|]) r := 0; + r := RT - 1; + ([|32|]) size := if NB == 0 then 32 else NB; + (bit[256]) membuffer := MEMr(EA,size); + j := 0; + i := 32; + foreach (n from (if NB == 0 then 32 else NB) to 1 by 1 in dec) + { + if i == 32 + then { + r := ([|31|]) (r + 1) mod 32; + GPR[r] := 0 + } + else (); + (GPR[r])[i..i + 7] := membuffer[j .. j + 7]; + j := j + 8; + i := i + 8; + if i == 64 then i := 32 else (); + EA := EA + 1 + } + } + +union ast member (bit[5], bit[5], bit[5]) Lswx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b1000010101 : +(bit[1]) _ as instr) = + Some(Lswx(RT,RA,RB)) + +function clause execute (Lswx (RT, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + ([|31|]) r := 0; + EA := b + GPR[RB]; + r := RT - 1; + i := 32; + ([|128|]) n_top := XER[57 .. 63]; + recalculate_dependency(()); + if n_top == 0 + then GPR[RT] := undefined + else { + (bit[512]) membuffer := MEMr(EA,n_top); + j := 0; + n_r := n_top quot 4; + n_mod := n_top mod 4; + n_r := if n_mod == 0 then n_r else n_r + 1; + foreach (n from n_r to 1 by 1 in dec) + { + r := ([|32|]) (r + 1) mod 32; + (bit[64]) temp := 0; + if n == 1 + then switch n_mod { + case 0 -> temp[32..63] := membuffer[j .. j + 31] + case 1 -> temp[32..39] := membuffer[j .. j + 7] + case 2 -> temp[32..47] := membuffer[j .. j + 15] + case 3 -> temp[32..55] := membuffer[j .. j + 23] + } + else temp[32..63] := membuffer[j .. j + 31]; + j := j + 32; + GPR[r] := temp + } + } + } + +union ast member (bit[5], bit[5], bit[5]) Stswi + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) NB : +0b1011010101 : +(bit[1]) _ as instr) = + Some(Stswi(RS,RA,NB)) + +function clause execute (Stswi (RS, RA, NB)) = + { + (bit[64]) EA := 0; + if RA == 0 then EA := 0 else EA := GPR[RA]; + ([|31|]) r := 0; + r := RS - 1; + ([|32|]) size := if NB == 0 then 32 else NB; + MEMw_EA(EA,size); + (bit[256]) membuffer := [0 = 0,255 = 0; default=0]; + j := 0; + i := 32; + foreach (n from (if NB == 0 then 32 else NB) to 1 by 1 in dec) + { + if i == 32 then r := ([|32|]) (r + 1) mod 32 else (); + membuffer[j..j + 7] := (GPR[r])[i .. i + 7]; + j := j + 8; + i := i + 8; + if i == 64 then i := 32 else () + }; + MEMw(EA,size) := membuffer[0 .. size * 8 - 1] + } + +union ast member (bit[5], bit[5], bit[5]) Stswx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1010010101 : +(bit[1]) _ as instr) = + Some(Stswx(RS,RA,RB)) + +function clause execute (Stswx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + ([|31|]) r := 0; + EA := b + GPR[RB]; + r := RS - 1; + i := 32; + ([|128|]) n_top := XER[57 .. 63]; + recalculate_dependency(()); + MEMw_EA(EA,n_top); + (bit[512]) membuffer := [0 = 0,511 = 0; default=0]; + j := 0; + foreach (n from n_top to 1 by 1 in dec) + { + if i == 32 then r := ([|32|]) (r + 1) mod 32 else (); + membuffer[j..j + 7] := (GPR[r])[i .. i + 7]; + i := i + 8; + j := j + 8; + if i == 64 then i := 32 else () + }; + if ~(n_top == 0) then MEMw(EA,n_top) := membuffer[0 .. n_top * 8 - 1] else () + } + +union ast member (bit[5], bit[5], bit[16]) Addi + +function clause decode (0b001110 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) SI as instr) = + Some(Addi(RT,RA,SI)) + +function clause execute (Addi (RT, RA, SI)) = + if RA == 0 then GPR[RT] := EXTS(SI) else GPR[RT] := GPR[RA] + EXTS(SI) + +union ast member (bit[5], bit[5], bit[16]) Addis + +function clause decode (0b001111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) SI as instr) = + Some(Addis(RT,RA,SI)) + +function clause execute (Addis (RT, RA, SI)) = + if RA == 0 + then GPR[RT] := EXTS(SI : 0b0000000000000000) + else GPR[RT] := GPR[RA] + EXTS(SI : 0b0000000000000000) + +union ast member (bit[5], bit[5], bit[5], bit, bit) Add + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b100001010 : +[Rc] as instr) = + Some(Add(RT,RA,RB,OE,Rc)) + +function clause execute (Add (RT, RA, RB, OE, Rc)) = + let (temp, overflow, _) = (GPR[RA] +_s GPR[RB]) in + { + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Subf + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b000101000 : +[Rc] as instr) = + Some(Subf(RT,RA,RB,OE,Rc)) + +function clause execute (Subf (RT, RA, RB, OE, Rc)) = + let (t1, o1, _) = (~(GPR[RA]) +_s GPR[RB]) in + let (t2, o2, _) = (t1 +_s (bit) 1) in + { + (bit[64]) temp := t2; + overflow := (o1 | o2); + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[16]) Addic + +function clause decode (0b001100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) SI as instr) = + Some(Addic(RT,RA,SI)) + +function clause execute (Addic (RT, RA, SI)) = + let (temp, _, carry) = (GPR[RA] +_s EXTS(SI)) in + { + GPR[RT] := temp; + CA := carry + } + +union ast member (bit[5], bit[5], bit[16]) AddicDot + +function clause decode (0b001101 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) SI as instr) = + Some(AddicDot(RT,RA,SI)) + +function clause execute (AddicDot (RT, RA, SI)) = + let (temp, overflow, carry) = (GPR[RA] +_s EXTS(SI)) in + { + GPR[RT] := temp; + CA := carry; + set_overflow_cr0(temp,overflow | XER.SO) + } + +union ast member (bit[5], bit[5], bit[16]) Subfic + +function clause decode (0b001000 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) SI as instr) = + Some(Subfic(RT,RA,SI)) + +function clause execute (Subfic (RT, RA, SI)) = + let (t1, o1, c1) = (~(GPR[RA]) +_s EXTS(SI)) in + let (t2, o2, c2) = (t1 +_s (bit) 1) in + { + (bit[64]) temp := t2; + GPR[RT] := temp; + CA := (c1 | c2) + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Addc + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b000001010 : +[Rc] as instr) = + Some(Addc(RT,RA,RB,OE,Rc)) + +function clause execute (Addc (RT, RA, RB, OE, Rc)) = + let (temp, overflow, carry) = (GPR[RA] +_s GPR[RB]) in + { + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + CA := carry; + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Subfc + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b000001000 : +[Rc] as instr) = + Some(Subfc(RT,RA,RB,OE,Rc)) + +function clause execute (Subfc (RT, RA, RB, OE, Rc)) = + let (t1, o1, c1) = (~(GPR[RA]) +_s GPR[RB]) in + let (t2, o2, c2) = (t1 +_s (bit) 1) in + { + (bit[64]) temp := t2; + overflow := (o1 | o2); + carry := (c1 | c2); + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + CA := carry; + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Adde + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b010001010 : +[Rc] as instr) = + Some(Adde(RT,RA,RB,OE,Rc)) + +function clause execute (Adde (RT, RA, RB, OE, Rc)) = + let (t1, o1, c1) = (GPR[RA] +_s GPR[RB]) in + let (t2, o2, c2) = (t1 +_s (bit) CA) in + { + (bit[64]) temp := t2; + overflow := (o1 | o2); + carry := (c1 | c2); + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + CA := carry; + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Subfe + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b010001000 : +[Rc] as instr) = + Some(Subfe(RT,RA,RB,OE,Rc)) + +function clause execute (Subfe (RT, RA, RB, OE, Rc)) = + let (t1, o1, c1) = (~(GPR[RA]) +_s GPR[RB]) in + let (t2, o2, c2) = (t1 +_s (bit) CA) in + { + (bit[64]) temp := t2; + overflow := (o1 | o2); + carry := (c1 | c2); + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + CA := carry; + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit, bit) Addme + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) _ : +[OE] : +0b011101010 : +[Rc] as instr) = + Some(Addme(RT,RA,OE,Rc)) + +function clause execute (Addme (RT, RA, OE, Rc)) = + let (t1, o1, c1) = (GPR[RA] +_s CA) in + let (t2, o2, c2) = (t1 +_s 0b1111111111111111111111111111111111111111111111111111111111111111) in + { + (bit[64]) temp := t2; + overflow := (o1 | o2); + carry := (c1 | c2); + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + CA := carry; + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit, bit) Subfme + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) _ : +[OE] : +0b011101000 : +[Rc] as instr) = + Some(Subfme(RT,RA,OE,Rc)) + +function clause execute (Subfme (RT, RA, OE, Rc)) = + let (t1, o1, c1) = (~(GPR[RA]) +_s CA) in + let (t2, o2, c2) = (t1 +_s 0b1111111111111111111111111111111111111111111111111111111111111111) in + { + (bit[64]) temp := t2; + overflow := (o1 | o2); + carry := (c1 | c2); + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + CA := carry; + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit, bit) Addze + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) _ : +[OE] : +0b011001010 : +[Rc] as instr) = + Some(Addze(RT,RA,OE,Rc)) + +function clause execute (Addze (RT, RA, OE, Rc)) = + let (temp, overflow, carry) = (GPR[RA] +_s CA) in + { + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + CA := carry; + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit, bit) Subfze + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) _ : +[OE] : +0b011001000 : +[Rc] as instr) = + Some(Subfze(RT,RA,OE,Rc)) + +function clause execute (Subfze (RT, RA, OE, Rc)) = + let (temp, overflow, carry) = (~(GPR[RA]) +_s CA) in + { + GPR[RT] := temp; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(temp,xer_so) + } + else (); + CA := carry; + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit, bit) Neg + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) _ : +[OE] : +0b001101000 : +[Rc] as instr) = + Some(Neg(RT,RA,OE,Rc)) + +function clause execute (Neg (RT, RA, OE, Rc)) = + let (temp, overflow, _) = (~(GPR[RA]) +_s (bit) 1) in + { + GPR[RT] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else (); + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[16]) Mulli + +function clause decode (0b000111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[16]) SI as instr) = + Some(Mulli(RT,RA,SI)) + +function clause execute (Mulli (RT, RA, SI)) = + { + (bit[128]) prod := GPR[RA] *_s EXTS(SI); + GPR[RT] := prod[64 .. 127] + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Mullw + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b011101011 : +[Rc] as instr) = + Some(Mullw(RT,RA,RB,OE,Rc)) + +function clause execute (Mullw (RT, RA, RB, OE, Rc)) = + let (prod, overflow, _) = ((GPR[RA])[32 .. 63] *_s (GPR[RB])[32 .. 63]) in + { + GPR[RT] := prod; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(prod,xer_so) + } + else (); + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Mulhw + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +(bit[1]) _ : +0b001001011 : +[Rc] as instr) = + Some(Mulhw(RT,RA,RB,Rc)) + +function clause execute (Mulhw (RT, RA, RB, Rc)) = + { + (bit[64]) prod := 0; + (bit) overflow := 0; + let (p, o, _) = ((GPR[RA])[32 .. 63] *_s (GPR[RB])[32 .. 63]) in + { + prod := p; + overflow := o + }; + (GPR[RT])[32..63] := prod[0 .. 31]; + (GPR[RT])[0..31] := undefined; + if Rc + then { + (bit) xer_so := XER.SO; + if mode64bit + then CR.CR0 := [undefined,undefined,undefined,xer_so] + else set_overflow_cr0(prod,xer_so) + } + else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Mulhwu + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +(bit[1]) _ : +0b000001011 : +[Rc] as instr) = + Some(Mulhwu(RT,RA,RB,Rc)) + +function clause execute (Mulhwu (RT, RA, RB, Rc)) = + { + (bit[64]) prod := (GPR[RA])[32 .. 63] * (GPR[RB])[32 .. 63]; + (GPR[RT])[32..63] := prod[0 .. 31]; + (GPR[RT])[0..31] := undefined; + if Rc + then { + (bit) xer_so := XER.SO; + if mode64bit + then CR.CR0 := [undefined,undefined,undefined,xer_so] + else set_overflow_cr0(prod,xer_so) + } + else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Divw + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b111101011 : +[Rc] as instr) = + Some(Divw(RT,RA,RB,OE,Rc)) + +function clause execute (Divw (RT, RA, RB, OE, Rc)) = + { + (bit[32]) dividend := (GPR[RA])[32 .. 63]; + (bit[32]) divisor := (GPR[RB])[32 .. 63]; + (bit[64]) divided := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit) overflow := 0; + let (d, o, _) = (dividend quot_s divisor) in + { + divided[32..63] := d; + overflow := o + }; + (GPR[RT])[32..63] := divided[32 .. 63]; + (GPR[RT])[0..31] := undefined; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + if mode64bit | overflow + then CR.CR0 := [undefined,undefined,undefined,xer_so] + else set_overflow_cr0(divided,xer_so) + } + else (); + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Divwu + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b111001011 : +[Rc] as instr) = + Some(Divwu(RT,RA,RB,OE,Rc)) + +function clause execute (Divwu (RT, RA, RB, OE, Rc)) = + { + (bit[32]) dividend := (GPR[RA])[32 .. 63]; + (bit[32]) divisor := (GPR[RB])[32 .. 63]; + (bit[64]) divided := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit) overflow := 0; + let (d, o, _) = (dividend quot divisor) in + { + divided[32..63] := d; + overflow := o + }; + (GPR[RT])[32..63] := divided[32 .. 63]; + (GPR[RT])[0..31] := undefined; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + if mode64bit | overflow + then CR.CR0 := [undefined,undefined,undefined,xer_so] + else set_overflow_cr0(divided,xer_so) + } + else (); + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Divwe + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b110101011 : +[Rc] as instr) = + Some(Divwe(RT,RA,RB,OE,Rc)) + +function clause execute (Divwe (RT, RA, RB, OE, Rc)) = + { + (bit[64]) dividend := (GPR[RA])[32 .. 63] : 0b00000000000000000000000000000000; + (bit[32]) divisor := (GPR[RB])[32 .. 63]; + (bit[64]) divided := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit) overflow := 0; + let (d, o, _) = (dividend quot_s divisor) in + { + divided[32..63] := d[32 .. 63]; + overflow := o + }; + (GPR[RT])[32..63] := divided[32 .. 63]; + (GPR[RT])[0..31] := undefined; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + if mode64bit | overflow + then CR.CR0 := [undefined,undefined,undefined,xer_so] + else set_overflow_cr0(divided,xer_so) + } + else (); + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Divweu + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b110001011 : +[Rc] as instr) = + Some(Divweu(RT,RA,RB,OE,Rc)) + +function clause execute (Divweu (RT, RA, RB, OE, Rc)) = + { + (bit[64]) dividend := (GPR[RA])[32 .. 63] : 0b00000000000000000000000000000000; + (bit[32]) divisor := (GPR[RB])[32 .. 63]; + (bit[64]) divided := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit) overflow := 0; + let (d, o, _) = (dividend quot divisor) in + { + divided[32..63] := d[32 .. 63]; + overflow := o + }; + (GPR[RT])[32..63] := divided[32 .. 63]; + (GPR[RT])[0..31] := undefined; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + if mode64bit | overflow + then CR.CR0 := [undefined,undefined,undefined,xer_so] + else set_overflow_cr0(divided,xer_so) + } + else (); + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Mulld + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b011101001 : +[Rc] as instr) = + Some(Mulld(RT,RA,RB,OE,Rc)) + +function clause execute (Mulld (RT, RA, RB, OE, Rc)) = + { + (bit[128]) prod := 0; + (bit) overflow := 0; + let (p, o, _) = (GPR[RA] *_s GPR[RB]) in + { + prod := p; + overflow := o + }; + GPR[RT] := prod[64 .. 127]; + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + set_overflow_cr0(prod[64 .. 127],xer_so) + } + else (); + if OE then set_SO_OV(overflow) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Mulhd + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +(bit[1]) _ : +0b001001001 : +[Rc] as instr) = + Some(Mulhd(RT,RA,RB,Rc)) + +function clause execute (Mulhd (RT, RA, RB, Rc)) = + { + (bit[128]) prod := GPR[RA] *_s GPR[RB]; + GPR[RT] := prod[0 .. 63]; + if Rc then set_overflow_cr0(prod[0 .. 63],XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Mulhdu + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +(bit[1]) _ : +0b000001001 : +[Rc] as instr) = + Some(Mulhdu(RT,RA,RB,Rc)) + +function clause execute (Mulhdu (RT, RA, RB, Rc)) = + { + (bit[128]) prod := GPR[RA] * GPR[RB]; + GPR[RT] := prod[0 .. 63]; + if Rc then set_overflow_cr0(prod[0 .. 63],XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Divd + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b111101001 : +[Rc] as instr) = + Some(Divd(RT,RA,RB,OE,Rc)) + +function clause execute (Divd (RT, RA, RB, OE, Rc)) = + { + (bit[64]) dividend := GPR[RA]; + (bit[64]) divisor := GPR[RB]; + (bit[64]) divided := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit) overflow := 0; + let (d, o, _) = (dividend quot_s divisor) in + { + divided := d; + overflow := o + }; + GPR[RT] := divided; + if OE then set_SO_OV(overflow) else (); + if Rc then set_overflow_cr0(divided,overflow | XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Divdu + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b111001001 : +[Rc] as instr) = + Some(Divdu(RT,RA,RB,OE,Rc)) + +function clause execute (Divdu (RT, RA, RB, OE, Rc)) = + { + (bit[64]) dividend := GPR[RA]; + (bit[64]) divisor := GPR[RB]; + (bit[64]) divided := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit) overflow := 0; + let (d, o, _) = (dividend quot divisor) in + { + divided := d; + overflow := o + }; + GPR[RT] := divided; + if OE then set_SO_OV(overflow) else (); + if Rc then set_overflow_cr0(divided,overflow | XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Divde + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b110101001 : +[Rc] as instr) = + Some(Divde(RT,RA,RB,OE,Rc)) + +function clause execute (Divde (RT, RA, RB, OE, Rc)) = + { + (bit[128]) dividend := + GPR[RA] : 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit[64]) divisor := GPR[RB]; + (bit[128]) divided := 0; + (bit) overflow := 0; + let (d, o, _) = (dividend quot_s divisor) in + { + divided := d; + overflow := o + }; + GPR[RT] := divided[64 .. 127]; + if OE then set_SO_OV(overflow) else (); + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + if overflow + then CR.CR0 := [undefined,undefined,undefined,xer_so] + else set_overflow_cr0(divided[64 .. 127],xer_so) + } + else () + } + +union ast member (bit[5], bit[5], bit[5], bit, bit) Divdeu + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b110001001 : +[Rc] as instr) = + Some(Divdeu(RT,RA,RB,OE,Rc)) + +function clause execute (Divdeu (RT, RA, RB, OE, Rc)) = + { + (bit[128]) dividend := + GPR[RA] : 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit[64]) divisor := GPR[RB]; + (bit[128]) divided := 0; + (bit) overflow := 0; + let (d, o, _) = (dividend quot divisor) in + { + divided := d; + overflow := o + }; + GPR[RT] := divided[64 .. 127]; + if OE then set_SO_OV(overflow) else (); + if Rc + then { + (bit) xer_so := XER.SO; + if OE & overflow then xer_so := overflow else (); + if overflow + then CR.CR0 := [undefined,undefined,undefined,xer_so] + else set_overflow_cr0(divided[64 .. 127],xer_so) + } + else () + } + +union ast member (bit[3], bit, bit[5], bit[16]) Cmpi + +function clause decode (0b001011 : +(bit[3]) BF : +(bit[1]) _ : +[L] : +(bit[5]) RA : +(bit[16]) SI as instr) = + Some(Cmpi(BF,L,RA,SI)) + +function clause execute (Cmpi (BF, L, RA, SI)) = + { + (bit[64]) a := 0; + if L == 0 then a := EXTS((GPR[RA])[32 .. 63]) else a := GPR[RA]; + if a < EXTS(SI) then c := 0b100 else if a > EXTS(SI) then c := 0b010 else c := 0b001; + CR[4 * BF + 32..4 * BF + 35] := c : [XER.SO] + } + +union ast member (bit[3], bit, bit[5], bit[5]) Cmp + +function clause decode (0b011111 : +(bit[3]) BF : +(bit[1]) _ : +[L] : +(bit[5]) RA : +(bit[5]) RB : +0b0000000000 : +(bit[1]) _ as instr) = + Some(Cmp(BF,L,RA,RB)) + +function clause execute (Cmp (BF, L, RA, RB)) = + { + (bit[64]) a := 0; + (bit[64]) b := 0; + if L == 0 + then { + a := EXTS((GPR[RA])[32 .. 63]); + b := EXTS((GPR[RB])[32 .. 63]) + } + else { + a := GPR[RA]; + b := GPR[RB] + }; + if a < b then c := 0b100 else if a > b then c := 0b010 else c := 0b001; + CR[4 * BF + 32..4 * BF + 35] := c : [XER.SO] + } + +union ast member (bit[3], bit, bit[5], bit[16]) Cmpli + +function clause decode (0b001010 : +(bit[3]) BF : +(bit[1]) _ : +[L] : +(bit[5]) RA : +(bit[16]) UI as instr) = + Some(Cmpli(BF,L,RA,UI)) + +function clause execute (Cmpli (BF, L, RA, UI)) = + { + (bit[64]) a := 0; + (bit[3]) c := 0; + if L == 0 then a := 0b00000000000000000000000000000000 : (GPR[RA])[32 .. 63] else a := GPR[RA]; + if a <_u 0b000000000000000000000000000000000000000000000000 : UI + then c := 0b100 + else if a >_u 0b000000000000000000000000000000000000000000000000 : UI + then c := 0b010 + else c := 0b001; + CR[4 * BF + 32..4 * BF + 35] := c : [XER.SO] + } + +union ast member (bit[3], bit, bit[5], bit[5]) Cmpl + +function clause decode (0b011111 : +(bit[3]) BF : +(bit[1]) _ : +[L] : +(bit[5]) RA : +(bit[5]) RB : +0b0000100000 : +(bit[1]) _ as instr) = + Some(Cmpl(BF,L,RA,RB)) + +function clause execute (Cmpl (BF, L, RA, RB)) = + { + (bit[64]) a := 0; + (bit[64]) b := 0; + (bit[3]) c := 0; + if L == 0 + then { + a := 0b00000000000000000000000000000000 : (GPR[RA])[32 .. 63]; + b := 0b00000000000000000000000000000000 : (GPR[RB])[32 .. 63] + } + else { + a := GPR[RA]; + b := GPR[RB] + }; + if a <_u b then c := 0b100 else if a >_u b then c := 0b010 else c := 0b001; + CR[4 * BF + 32..4 * BF + 35] := c : [XER.SO] + } + +union ast member (bit[5], bit[5], bit[5], bit[5]) Isel + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +(bit[5]) BC : +0b01111 : +(bit[1]) _ as instr) = + Some(Isel(RT,RA,RB,BC)) + +function clause execute (Isel (RT, RA, RB, BC)) = + { + (bit[64]) a := 0; + if RA == 0 then a := 0 else a := GPR[RA]; + if CR[BC + 32] == 1 + then { + GPR[RT] := a; + discard := GPR[RB] + } + else GPR[RT] := GPR[RB] + } + +union ast member (bit[5], bit[5], bit[16]) Andi + +function clause decode (0b011100 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) UI as instr) = + Some(Andi(RS,RA,UI)) + +function clause execute (Andi (RS, RA, UI)) = + { + (bit[64]) temp := (GPR[RS] & 0b000000000000000000000000000000000000000000000000 : UI); + GPR[RA] := temp; + set_overflow_cr0(temp,XER.SO) + } + +union ast member (bit[5], bit[5], bit[16]) Andis + +function clause decode (0b011101 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) UI as instr) = + Some(Andis(RS,RA,UI)) + +function clause execute (Andis (RS, RA, UI)) = + { + (bit[64]) temp := (GPR[RS] & 0b00000000000000000000000000000000 : UI : 0b0000000000000000); + GPR[RA] := temp; + set_overflow_cr0(temp,XER.SO) + } + +union ast member (bit[5], bit[5], bit[16]) Ori + +function clause decode (0b011000 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) UI as instr) = + Some(Ori(RS,RA,UI)) + +function clause execute (Ori (RS, RA, UI)) = + GPR[RA] := (GPR[RS] | 0b000000000000000000000000000000000000000000000000 : UI) + +union ast member (bit[5], bit[5], bit[16]) Oris + +function clause decode (0b011001 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) UI as instr) = + Some(Oris(RS,RA,UI)) + +function clause execute (Oris (RS, RA, UI)) = + GPR[RA] := (GPR[RS] | 0b00000000000000000000000000000000 : UI : 0b0000000000000000) + +union ast member (bit[5], bit[5], bit[16]) Xori + +function clause decode (0b011010 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) UI as instr) = + Some(Xori(RS,RA,UI)) + +function clause execute (Xori (RS, RA, UI)) = + GPR[RA] := GPR[RS] ^ 0b000000000000000000000000000000000000000000000000 : UI + +union ast member (bit[5], bit[5], bit[16]) Xoris + +function clause decode (0b011011 : +(bit[5]) RS : +(bit[5]) RA : +(bit[16]) UI as instr) = + Some(Xoris(RS,RA,UI)) + +function clause execute (Xoris (RS, RA, UI)) = + GPR[RA] := GPR[RS] ^ 0b00000000000000000000000000000000 : UI : 0b0000000000000000 + +union ast member (bit[5], bit[5], bit[5], bit) And + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0000011100 : +[Rc] as instr) = + Some(And(RS,RA,RB,Rc)) + +function clause execute (And (RS, RA, RB, Rc)) = + { + (bit[64]) temp := (GPR[RS] & GPR[RB]); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Xor + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0100111100 : +[Rc] as instr) = + Some(Xor(RS,RA,RB,Rc)) + +function clause execute (Xor (RS, RA, RB, Rc)) = + { + (bit[64]) temp := 0; + if RS == RB + then { + temp := GPR[RS]; + temp := 0; + GPR[RA] := 0 + } + else { + temp := GPR[RS] ^ GPR[RB]; + GPR[RA] := temp + }; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Nand + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0111011100 : +[Rc] as instr) = + Some(Nand(RS,RA,RB,Rc)) + +function clause execute (Nand (RS, RA, RB, Rc)) = + { + (bit[64]) temp := ~(GPR[RS] & GPR[RB]); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Or + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0110111100 : +[Rc] as instr) = + Some(Or(RS,RA,RB,Rc)) + +function clause execute (Or (RS, RA, RB, Rc)) = + { + (bit[64]) temp := (GPR[RS] | GPR[RB]); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Nor + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0001111100 : +[Rc] as instr) = + Some(Nor(RS,RA,RB,Rc)) + +function clause execute (Nor (RS, RA, RB, Rc)) = + { + (bit[64]) temp := ~(GPR[RS] | GPR[RB]); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Eqv + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0100011100 : +[Rc] as instr) = + Some(Eqv(RS,RA,RB,Rc)) + +function clause execute (Eqv (RS, RA, RB, Rc)) = + { + (bit[64]) temp := GPR[RS] ^ ~(GPR[RB]); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Andc + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0000111100 : +[Rc] as instr) = + Some(Andc(RS,RA,RB,Rc)) + +function clause execute (Andc (RS, RA, RB, Rc)) = + { + (bit[64]) temp := (GPR[RS] & ~(GPR[RB])); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Orc + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0110011100 : +[Rc] as instr) = + Some(Orc(RS,RA,RB,Rc)) + +function clause execute (Orc (RS, RA, RB, Rc)) = + { + (bit[64]) temp := (GPR[RS] | ~(GPR[RB])); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit) Extsb + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b1110111010 : +[Rc] as instr) = + Some(Extsb(RS,RA,Rc)) + +function clause execute (Extsb (RS, RA, Rc)) = + { + (bit[64]) temp := 0; + s := (GPR[RS])[56]; + temp[56..63] := (GPR[RS])[56 .. 63]; + (GPR[RA])[56..63] := temp[56 .. 63]; + temp[0..55] := s ^^ 56; + (GPR[RA])[0..55] := temp[0 .. 55]; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit) Extsh + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b1110011010 : +[Rc] as instr) = + Some(Extsh(RS,RA,Rc)) + +function clause execute (Extsh (RS, RA, Rc)) = + { + (bit[64]) temp := 0; + s := (GPR[RS])[48]; + temp[48..63] := (GPR[RS])[48 .. 63]; + (GPR[RA])[48..63] := temp[48 .. 63]; + temp[0..47] := s ^^ 48; + (GPR[RA])[0..47] := temp[0 .. 47]; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit) Cntlzw + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b0000011010 : +[Rc] as instr) = + Some(Cntlzw(RS,RA,Rc)) + +function clause execute (Cntlzw (RS, RA, Rc)) = + { + temp := (bit[64]) (countLeadingZeroes(GPR[RS],32)); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5]) Cmpb + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0111111100 : +(bit[1]) _ as instr) = + Some(Cmpb(RS,RA,RB)) + +function clause execute (Cmpb (RS, RA, RB)) = + foreach (n from 0 to 7 by 1 in inc) + if (GPR[RS])[8 * n .. 8 * n + 7] == (GPR[RB])[8 * n .. 8 * n + 7] + then (GPR[RA])[8 * n..8 * n + 7] := 0b11111111 + else (GPR[RA])[8 * n..8 * n + 7] := (bit[8]) 0 + +union ast member (bit[5], bit[5]) Popcntb + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b0001111010 : +(bit[1]) _ as instr) = + Some(Popcntb(RS,RA)) + +function clause execute (Popcntb (RS, RA)) = + foreach (i from 0 to 7 by 1 in inc) + { + ([|64|]) n := 0; + foreach (j from 0 to 7 by 1 in inc) if (GPR[RS])[i * 8 + j] == 1 then n := n + 1 else (); + (GPR[RA])[i * 8..i * 8 + 7] := (bit[8]) n + } + +union ast member (bit[5], bit[5]) Popcntw + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b0101111010 : +(bit[1]) _ as instr) = + Some(Popcntw(RS,RA)) + +function clause execute (Popcntw (RS, RA)) = + foreach (i from 0 to 1 by 1 in inc) + { + ([|64|]) n := 0; + foreach (j from 0 to 31 by 1 in inc) if (GPR[RS])[i * 32 + j] == 1 then n := n + 1 else (); + (GPR[RA])[i * 32..i * 32 + 31] := (bit[32]) n + } + +union ast member (bit[5], bit[5]) Prtyd + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b0010111010 : +(bit[1]) _ as instr) = + Some(Prtyd(RS,RA)) + +function clause execute (Prtyd (RS, RA)) = + { + s := 0; + foreach (i from 0 to 7 by 1 in inc) s := s ^ (GPR[RS])[i * 8 + 7]; + GPR[RA] := 0b000000000000000000000000000000000000000000000000000000000000000 : [s] + } + +union ast member (bit[5], bit[5]) Prtyw + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b0010011010 : +(bit[1]) _ as instr) = + Some(Prtyw(RS,RA)) + +function clause execute (Prtyw (RS, RA)) = + { + s := 0; + t := 0; + foreach (i from 0 to 3 by 1 in inc) s := s ^ (GPR[RS])[i * 8 + 7]; + foreach (i from 4 to 7 by 1 in inc) t := t ^ (GPR[RS])[i * 8 + 7]; + (GPR[RA])[0..31] := 0b0000000000000000000000000000000 : [s]; + (GPR[RA])[32..63] := 0b0000000000000000000000000000000 : [t] + } + +union ast member (bit[5], bit[5], bit) Extsw + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b1111011010 : +[Rc] as instr) = + Some(Extsw(RS,RA,Rc)) + +function clause execute (Extsw (RS, RA, Rc)) = + { + s := (GPR[RS])[32]; + (bit[64]) temp := 0; + temp[32..63] := (GPR[RS])[32 .. 63]; + temp[0..31] := s ^^ 32; + if Rc then set_overflow_cr0(temp,XER.SO) else (); + GPR[RA] := temp + } + +union ast member (bit[5], bit[5], bit) Cntlzd + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b0000111010 : +[Rc] as instr) = + Some(Cntlzd(RS,RA,Rc)) + +function clause execute (Cntlzd (RS, RA, Rc)) = + { + temp := (bit[64]) (countLeadingZeroes(GPR[RS],0)); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5]) Popcntd + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b0111111010 : +(bit[1]) _ as instr) = + Some(Popcntd(RS,RA)) + +function clause execute (Popcntd (RS, RA)) = + { + ([|64|]) n := 0; + foreach (i from 0 to 63 by 1 in inc) if (GPR[RS])[i] == 1 then n := n + 1 else (); + GPR[RA] := (bit[64]) n + } + +union ast member (bit[5], bit[5], bit[5]) Bpermd + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0011111100 : +(bit[1]) _ as instr) = + Some(Bpermd(RS,RA,RB)) + +function clause execute (Bpermd (RS, RA, RB)) = + { + (bit[8]) perm := 0; + foreach (i from 0 to 7 by 1 in inc) + { + index := (GPR[RS])[8 * i .. 8 * i + 7]; + if index <_u (bit[8]) 64 + then perm[i] := (GPR[RB])[index] + else { + perm[i] := 0; + discard := GPR[RB] + } + }; + GPR[RA] := 0b00000000000000000000000000000000000000000000000000000000 : perm[0 .. 7] + } + +union ast member (bit[5], bit[5], bit[5], bit[5], bit[5], bit) Rlwinm + +function clause decode (0b010101 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) SH : +(bit[5]) MB : +(bit[5]) ME : +[Rc] as instr) = + Some(Rlwinm(RS,RA,SH,MB,ME,Rc)) + +function clause execute (Rlwinm (RS, RA, SH, MB, ME, Rc)) = + { + n := SH; + r := ROTL((GPR[RS])[32 .. 63] : (GPR[RS])[32 .. 63],n); + m := MASK(MB + 32,ME + 32); + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit[5], bit[5], bit) Rlwnm + +function clause decode (0b010111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +(bit[5]) MB : +(bit[5]) ME : +[Rc] as instr) = + Some(Rlwnm(RS,RA,RB,MB,ME,Rc)) + +function clause execute (Rlwnm (RS, RA, RB, MB, ME, Rc)) = + { + n := (GPR[RB])[59 .. 63]; + r := ROTL((GPR[RS])[32 .. 63] : (GPR[RS])[32 .. 63],n); + m := MASK(MB + 32,ME + 32); + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit[5], bit[5], bit) Rlwimi + +function clause decode (0b010100 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) SH : +(bit[5]) MB : +(bit[5]) ME : +[Rc] as instr) = + Some(Rlwimi(RS,RA,SH,MB,ME,Rc)) + +function clause execute (Rlwimi (RS, RA, SH, MB, ME, Rc)) = + { + n := SH; + r := ROTL((GPR[RS])[32 .. 63] : (GPR[RS])[32 .. 63],n); + m := MASK(MB + 32,ME + 32); + (bit[64]) temp := (r & m | GPR[RA] & ~(m)); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[6], bit[6], bit) Rldicl + +function clause decode (0b011110 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +(bit[6]) mb : +0b000 : +(bit[1]) _ : +[Rc] as instr) = + Some(Rldicl(RS,RA,instr[16 .. 20] : instr[30 .. 30],mb,Rc)) + +function clause execute (Rldicl (RS, RA, sh, mb, Rc)) = + { + n := [sh[5]] : sh[0 .. 4]; + r := ROTL(GPR[RS],n); + b := [mb[5]] : mb[0 .. 4]; + m := MASK(b,63); + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[6], bit[6], bit) Rldicr + +function clause decode (0b011110 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +(bit[6]) me : +0b001 : +(bit[1]) _ : +[Rc] as instr) = + Some(Rldicr(RS,RA,instr[16 .. 20] : instr[30 .. 30],me,Rc)) + +function clause execute (Rldicr (RS, RA, sh, me, Rc)) = + { + n := [sh[5]] : sh[0 .. 4]; + r := ROTL(GPR[RS],n); + e := [me[5]] : me[0 .. 4]; + m := MASK(0,e); + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[6], bit[6], bit) Rldic + +function clause decode (0b011110 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +(bit[6]) mb : +0b010 : +(bit[1]) _ : +[Rc] as instr) = + Some(Rldic(RS,RA,instr[16 .. 20] : instr[30 .. 30],mb,Rc)) + +function clause execute (Rldic (RS, RA, sh, mb, Rc)) = + { + n := [sh[5]] : sh[0 .. 4]; + r := ROTL(GPR[RS],n); + b := [mb[5]] : mb[0 .. 4]; + m := MASK(b,(bit[6]) (~(n))); + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit[6], bit) Rldcl + +function clause decode (0b011110 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +(bit[6]) mb : +0b1000 : +[Rc] as instr) = + Some(Rldcl(RS,RA,RB,mb,Rc)) + +function clause execute (Rldcl (RS, RA, RB, mb, Rc)) = + { + n := (GPR[RB])[58 .. 63]; + r := ROTL(GPR[RS],n); + b := [mb[5]] : mb[0 .. 4]; + m := MASK(b,63); + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit[6], bit) Rldcr + +function clause decode (0b011110 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +(bit[6]) me : +0b1001 : +[Rc] as instr) = + Some(Rldcr(RS,RA,RB,me,Rc)) + +function clause execute (Rldcr (RS, RA, RB, me, Rc)) = + { + n := (GPR[RB])[58 .. 63]; + r := ROTL(GPR[RS],n); + e := [me[5]] : me[0 .. 4]; + m := MASK(0,e); + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[6], bit[6], bit) Rldimi + +function clause decode (0b011110 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +(bit[6]) mb : +0b011 : +(bit[1]) _ : +[Rc] as instr) = + Some(Rldimi(RS,RA,instr[16 .. 20] : instr[30 .. 30],mb,Rc)) + +function clause execute (Rldimi (RS, RA, sh, mb, Rc)) = + { + n := [sh[5]] : sh[0 .. 4]; + r := ROTL(GPR[RS],n); + b := [mb[5]] : mb[0 .. 4]; + m := MASK(b,(bit[6]) (~(n))); + (bit[64]) temp := (r & m | GPR[RA] & ~(m)); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Slw + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0000011000 : +[Rc] as instr) = + Some(Slw(RS,RA,RB,Rc)) + +function clause execute (Slw (RS, RA, RB, Rc)) = + { + n := (GPR[RB])[59 .. 63]; + r := ROTL((GPR[RS])[32 .. 63] : (GPR[RS])[32 .. 63],n); + if (GPR[RB])[58] == 0 + then m := MASK(32,63 - n) + else m := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Srw + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1000011000 : +[Rc] as instr) = + Some(Srw(RS,RA,RB,Rc)) + +function clause execute (Srw (RS, RA, RB, Rc)) = + { + n := (GPR[RB])[59 .. 63]; + r := ROTL((GPR[RS])[32 .. 63] : (GPR[RS])[32 .. 63],64 - n); + if (GPR[RB])[58] == 0 + then m := MASK(n + 32,63) + else m := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Srawi + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) SH : +0b1100111000 : +[Rc] as instr) = + Some(Srawi(RS,RA,SH,Rc)) + +function clause execute (Srawi (RS, RA, SH, Rc)) = + { + n := SH; + r := ROTL((GPR[RS])[32 .. 63] : (GPR[RS])[32 .. 63],64 - n); + m := MASK(n + 32,63); + s := (GPR[RS])[32]; + (bit[64]) temp := (r & m | s ^^ 64 & ~(m)); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else (); + XER.CA := if n >_u (bit[5]) 0 then s & ~((r & ~(m)) == 0) else 0 + } + +union ast member (bit[5], bit[5], bit[5], bit) Sraw + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1100011000 : +[Rc] as instr) = + Some(Sraw(RS,RA,RB,Rc)) + +function clause execute (Sraw (RS, RA, RB, Rc)) = + { + n := (GPR[RB])[59 .. 63]; + r := ROTL((GPR[RS])[32 .. 63] : (GPR[RS])[32 .. 63],64 - n); + if (GPR[RB])[58] == 0 + then m := MASK(n + 32,63) + else m := 0b0000000000000000000000000000000000000000000000000000000000000000; + s := (GPR[RS])[32]; + (bit[64]) temp := (r & m | s ^^ 64 & ~(m)); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else (); + XER.CA := if n >_u (bit[5]) 0 then s & ~((r & ~(m)) == 0) else 0 + } + +union ast member (bit[5], bit[5], bit[5], bit) Sld + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0000011011 : +[Rc] as instr) = + Some(Sld(RS,RA,RB,Rc)) + +function clause execute (Sld (RS, RA, RB, Rc)) = + { + n := (GPR[RB])[58 .. 63]; + r := ROTL(GPR[RS],n); + if (GPR[RB])[57] == 0 + then m := MASK(0,63 - n) + else m := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[5], bit) Srd + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1000011011 : +[Rc] as instr) = + Some(Srd(RS,RA,RB,Rc)) + +function clause execute (Srd (RS, RA, RB, Rc)) = + { + n := (GPR[RB])[58 .. 63]; + r := ROTL(GPR[RS],64 - n); + if (GPR[RB])[57] == 0 + then m := MASK(n,63) + else m := 0b0000000000000000000000000000000000000000000000000000000000000000; + (bit[64]) temp := (r & m); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else () + } + +union ast member (bit[5], bit[5], bit[6], bit) Sradi + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b110011101 : +(bit[1]) _ : +[Rc] as instr) = + Some(Sradi(RS,RA,instr[16 .. 20] : instr[30 .. 30],Rc)) + +function clause execute (Sradi (RS, RA, sh, Rc)) = + { + n := [sh[5]] : sh[0 .. 4]; + r := ROTL(GPR[RS],64 - n); + m := MASK(n,63); + s := (GPR[RS])[0]; + (bit[64]) temp := (r & m | s ^^ 64 & ~(m)); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else (); + XER.CA := if n >_u (bit[6]) 0 then s & ~((r & ~(m)) == 0) else 0 + } + +union ast member (bit[5], bit[5], bit[5], bit) Srad + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1100011010 : +[Rc] as instr) = + Some(Srad(RS,RA,RB,Rc)) + +function clause execute (Srad (RS, RA, RB, Rc)) = + { + n := (GPR[RB])[58 .. 63]; + r := ROTL(GPR[RS],64 - n); + if (GPR[RB])[57] == 0 + then m := MASK(n,63) + else m := 0b0000000000000000000000000000000000000000000000000000000000000000; + s := (GPR[RS])[0]; + (bit[64]) temp := (r & m | s ^^ 64 & ~(m)); + GPR[RA] := temp; + if Rc then set_overflow_cr0(temp,XER.SO) else (); + XER.CA := if n >_u (bit[6]) 0 then s & ~((r & ~(m)) == 0) else 0 + } + +union ast member (bit[5], bit[5]) Cdtbcd + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b0100011010 : +(bit[1]) _ as instr) = + Some(Cdtbcd(RS,RA)) + +function clause execute (Cdtbcd (RS, RA)) = + foreach (i from 0 to 1 by 1 in inc) + { + n := i * 32; + (GPR[RA])[n + 0..n + 7] := (bit[8]) 0; + (GPR[RA])[n + 8..n + 19] := DEC_TO_BCD((GPR[RS])[n + 12 .. n + 21]); + (GPR[RA])[n + 20..n + 31] := DEC_TO_BCD((GPR[RS])[n + 22 .. n + 31]) + } + +union ast member (bit[5], bit[5]) Cbcdtd + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) _ : +0b0100111010 : +(bit[1]) _ as instr) = + Some(Cbcdtd(RS,RA)) + +function clause execute (Cbcdtd (RS, RA)) = + foreach (i from 0 to 1 by 1 in inc) + { + n := i * 32; + (GPR[RA])[n + 0..n + 11] := (bit[12]) 0; + (GPR[RA])[n + 12..n + 21] := BCD_TO_DEC((GPR[RS])[n + 8 .. n + 19]); + (GPR[RA])[n + 22..n + 31] := BCD_TO_DEC((GPR[RS])[n + 20 .. n + 31]) + } + +union ast member (bit[5], bit[5], bit[5]) Addg6s + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +(bit[1]) _ : +0b001001010 : +(bit[1]) _ as instr) = + Some(Addg6s(RT,RA,RB)) + +function clause execute (Addg6s (RT, RA, RB)) = + { + (bit[16]) dc := 0; + foreach (i from 0 to 15 by 1 in inc) + let (v, _, co) = ((GPR[RA])[4 * i .. 63] + (GPR[RB])[4 * i .. 63]) in dc[i] := carry_out(v,co); + c := + (dc[0] ^^ 4) : + (dc[1] ^^ 4) : + (dc[2] ^^ 4) : + (dc[3] ^^ 4) : + (dc[4] ^^ 4) : + (dc[5] ^^ 4) : + (dc[6] ^^ 4) : + (dc[7] ^^ 4) : + (dc[8] ^^ 4) : + (dc[9] ^^ 4) : + (dc[10] ^^ 4) : + (dc[11] ^^ 4) : + (dc[12] ^^ 4) : (dc[13] ^^ 4) : (dc[14] ^^ 4) : (dc[15] ^^ 4); + GPR[RT] := (~(c) & 0b0110011001100110011001100110011001100110011001100110011001100110) + } + +union ast member (bit[5], bit[10]) Mtspr + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[10]) spr : +0b0111010011 : +(bit[1]) _ as instr) = + Some(Mtspr(RS,spr)) + +function clause execute (Mtspr (RS, spr)) = + { + n := spr[5 .. 9] : spr[0 .. 4]; + if n == 13 + then trap(()) + else if n == 1 + then { + (bit[64]) reg := GPR[RS]; + (bit[32]) front := zero_or_undef(reg[0 .. 31]); + (bit) xer_so := reg[32]; + (bit) xer_ov := reg[33]; + (bit) xer_ca := reg[34]; + (bit[22]) mid := zero_or_undef(reg[35 .. 56]); + (bit[7]) bot := reg[57 .. 63]; + XER := front : [xer_so] : [xer_ov] : [xer_ca] : mid : bot + } + else if length(SPR[n]) == 64 + then SPR[n] := GPR[RS] + else if n == 152 then CTRL := (GPR[RS])[32 .. 63] else () + } + +union ast member (bit[5], bit[10]) Mfspr + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[10]) spr : +0b0101010011 : +(bit[1]) _ as instr) = + Some(Mfspr(RT,spr)) + +function clause execute (Mfspr (RT, spr)) = + { + n := spr[5 .. 9] : spr[0 .. 4]; + if length(SPR[n]) == 64 + then GPR[RT] := SPR[n] + else GPR[RT] := 0b00000000000000000000000000000000 : SPR[n] + } + +union ast member (bit[5], bit[8]) Mtcrf + +function clause decode (0b011111 : +(bit[5]) RS : +0b0 : +(bit[8]) FXM : +(bit[1]) _ : +0b0010010000 : +(bit[1]) _ as instr) = + Some(Mtcrf(RS,FXM)) + +function clause execute (Mtcrf (RS, FXM)) = + { + mask := + (FXM[0] ^^ 4) : + (FXM[1] ^^ 4) : + (FXM[2] ^^ 4) : + (FXM[3] ^^ 4) : (FXM[4] ^^ 4) : (FXM[5] ^^ 4) : (FXM[6] ^^ 4) : (FXM[7] ^^ 4); + CR := ((bit[32]) ((GPR[RS])[32 .. 63] & mask) | (bit[32]) (CR & ~((bit[32]) mask))) + } + +union ast member (bit[5]) Mfcr + +function clause decode (0b011111 : +(bit[5]) RT : +0b0 : +(bit[9]) _ : +0b0000010011 : +(bit[1]) _ as instr) = + Some(Mfcr(RT)) + +function clause execute (Mfcr (RT)) = GPR[RT] := 0b00000000000000000000000000000000 : CR + +union ast member (bit[5], bit[8]) Mtocrf + +function clause decode (0b011111 : +(bit[5]) RS : +0b1 : +(bit[8]) FXM : +(bit[1]) _ : +0b0010010000 : +(bit[1]) _ as instr) = + Some(Mtocrf(RS,FXM)) + +function clause execute (Mtocrf (RS, FXM)) = + { + ([|7|]) n := 0; + count := 0; + foreach (i from 0 to 7 by 1 in inc) + if FXM[i] == 1 + then { + n := i; + count := count + 1 + } + else (); + if count == 1 + then CR[4 * n + 32..4 * n + 35] := (GPR[RS])[4 * n + 32 .. 4 * n + 35] + else CR := undefined + } + +union ast member (bit[5], bit[8]) Mfocrf + +function clause decode (0b011111 : +(bit[5]) RT : +0b1 : +(bit[8]) FXM : +(bit[1]) _ : +0b0000010011 : +(bit[1]) _ as instr) = + Some(Mfocrf(RT,FXM)) + +function clause execute (Mfocrf (RT, FXM)) = + { + ([|7|]) n := 0; + count := 0; + foreach (i from 0 to 7 by 1 in inc) + if FXM[i] == 1 + then { + n := i; + count := count + 1 + } + else (); + if count == 1 + then { + (bit[64]) temp := undefined; + temp[4 * n + 32..4 * n + 35] := CR[4 * n + 32 .. 4 * n + 35]; + GPR[RT] := temp + } + else GPR[RT] := undefined + } + +union ast member (bit[3]) Mcrxr + +function clause decode (0b011111 : +(bit[3]) BF : +(bit[2]) _ : +(bit[5]) _ : +(bit[5]) _ : +0b1000000000 : +(bit[1]) _ as instr) = + Some(Mcrxr(BF)) + +function clause execute (Mcrxr (BF)) = + { + CR[4 * BF + 32..4 * BF + 35] := XER[32 .. 35]; + XER[32..35] := 0b0000 + } + +union ast member (bit[5], bit[5], bit[5], bit) Dlmzb + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0001001110 : +[Rc] as instr) = + Some(Dlmzb(RS,RA,RB,Rc)) + +function clause execute (Dlmzb (RS, RA, RB, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Macchw + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b010101100 : +[Rc] as instr) = + Some(Macchw(RT,RA,RB,OE,Rc)) + +function clause execute (Macchw (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Macchws + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b011101100 : +[Rc] as instr) = + Some(Macchws(RT,RA,RB,OE,Rc)) + +function clause execute (Macchws (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Macchwu + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b010001100 : +[Rc] as instr) = + Some(Macchwu(RT,RA,RB,OE,Rc)) + +function clause execute (Macchwu (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Macchwsu + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b011001100 : +[Rc] as instr) = + Some(Macchwsu(RT,RA,RB,OE,Rc)) + +function clause execute (Macchwsu (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Machhw + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b000101100 : +[Rc] as instr) = + Some(Machhw(RT,RA,RB,OE,Rc)) + +function clause execute (Machhw (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Machhws + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b001101100 : +[Rc] as instr) = + Some(Machhws(RT,RA,RB,OE,Rc)) + +function clause execute (Machhws (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Machhwu + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b000001100 : +[Rc] as instr) = + Some(Machhwu(RT,RA,RB,OE,Rc)) + +function clause execute (Machhwu (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Machhwsu + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b001001100 : +[Rc] as instr) = + Some(Machhwsu(RT,RA,RB,OE,Rc)) + +function clause execute (Machhwsu (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Maclhw + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b110101100 : +[Rc] as instr) = + Some(Maclhw(RT,RA,RB,OE,Rc)) + +function clause execute (Maclhw (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Maclhws + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b111101100 : +[Rc] as instr) = + Some(Maclhws(RT,RA,RB,OE,Rc)) + +function clause execute (Maclhws (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Maclhwu + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b110001100 : +[Rc] as instr) = + Some(Maclhwu(RT,RA,RB,OE,Rc)) + +function clause execute (Maclhwu (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Maclhwsu + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b111001100 : +[Rc] as instr) = + Some(Maclhwsu(RT,RA,RB,OE,Rc)) + +function clause execute (Maclhwsu (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit) Mulchw + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0010101000 : +[Rc] as instr) = + Some(Mulchw(RT,RA,RB,Rc)) + +function clause execute (Mulchw (RT, RA, RB, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit) Mulchwu + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0010001000 : +[Rc] as instr) = + Some(Mulchwu(RT,RA,RB,Rc)) + +function clause execute (Mulchwu (RT, RA, RB, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit) Mulhhw + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0000101000 : +[Rc] as instr) = + Some(Mulhhw(RT,RA,RB,Rc)) + +function clause execute (Mulhhw (RT, RA, RB, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit) Mulhhwu + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0000001000 : +[Rc] as instr) = + Some(Mulhhwu(RT,RA,RB,Rc)) + +function clause execute (Mulhhwu (RT, RA, RB, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit) Mullhw + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0110101000 : +[Rc] as instr) = + Some(Mullhw(RT,RA,RB,Rc)) + +function clause execute (Mullhw (RT, RA, RB, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit) Mullhwu + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0110001000 : +[Rc] as instr) = + Some(Mullhwu(RT,RA,RB,Rc)) + +function clause execute (Mullhwu (RT, RA, RB, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Nmacchw + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b010101110 : +[Rc] as instr) = + Some(Nmacchw(RT,RA,RB,OE,Rc)) + +function clause execute (Nmacchw (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Nmacchws + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b011101110 : +[Rc] as instr) = + Some(Nmacchws(RT,RA,RB,OE,Rc)) + +function clause execute (Nmacchws (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Nmachhw + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b000101110 : +[Rc] as instr) = + Some(Nmachhw(RT,RA,RB,OE,Rc)) + +function clause execute (Nmachhw (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Nmachhws + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b001101110 : +[Rc] as instr) = + Some(Nmachhws(RT,RA,RB,OE,Rc)) + +function clause execute (Nmachhws (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Nmaclhw + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b110101110 : +[Rc] as instr) = + Some(Nmaclhw(RT,RA,RB,OE,Rc)) + +function clause execute (Nmaclhw (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5], bit[5], bit, bit) Nmaclhws + +function clause decode (0b000100 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +[OE] : +0b111101110 : +[Rc] as instr) = + Some(Nmaclhws(RT,RA,RB,OE,Rc)) + +function clause execute (Nmaclhws (RT, RA, RB, OE, Rc)) = () + +union ast member (bit[5], bit[5]) Icbi + +function clause decode (0b011111 : +(bit[5]) _ : +(bit[5]) RA : +(bit[5]) RB : +0b1111010110 : +(bit[1]) _ as instr) = + Some(Icbi(RA,RB)) + +function clause execute (Icbi (RA, RB)) = () + +union ast member (bit[4], bit[5], bit[5]) Icbt + +function clause decode (0b011111 : +(bit[1]) _ : +(bit[4]) CT : +(bit[5]) RA : +(bit[5]) RB : +0b0000010110 : +(bit[1]) _ as instr) = + Some(Icbt(CT,RA,RB)) + +function clause execute (Icbt (CT, RA, RB)) = () + +union ast member (bit[5], bit[5]) Dcba + +function clause decode (0b011111 : +(bit[5]) _ : +(bit[5]) RA : +(bit[5]) RB : +0b1011110110 : +(bit[1]) _ as instr) = + Some(Dcba(RA,RB)) + +function clause execute (Dcba (RA, RB)) = () + +union ast member (bit[5], bit[5], bit[5]) Dcbt + +function clause decode (0b011111 : +(bit[5]) TH : +(bit[5]) RA : +(bit[5]) RB : +0b0100010110 : +(bit[1]) _ as instr) = + Some(Dcbt(TH,RA,RB)) + +function clause execute (Dcbt (TH, RA, RB)) = () + +union ast member (bit[5], bit[5], bit[5]) Dcbtst + +function clause decode (0b011111 : +(bit[5]) TH : +(bit[5]) RA : +(bit[5]) RB : +0b0011110110 : +(bit[1]) _ as instr) = + Some(Dcbtst(TH,RA,RB)) + +function clause execute (Dcbtst (TH, RA, RB)) = () + +union ast member (bit[5], bit[5]) Dcbz + +function clause decode (0b011111 : +(bit[5]) _ : +(bit[5]) RA : +(bit[5]) RB : +0b1111110110 : +(bit[1]) _ as instr) = + Some(Dcbz(RA,RB)) + +function clause execute (Dcbz (RA, RB)) = () + +union ast member (bit[5], bit[5]) Dcbst + +function clause decode (0b011111 : +(bit[5]) _ : +(bit[5]) RA : +(bit[5]) RB : +0b0000110110 : +(bit[1]) _ as instr) = + Some(Dcbst(RA,RB)) + +function clause execute (Dcbst (RA, RB)) = () + +union ast member (bit[2], bit[5], bit[5]) Dcbf + +function clause decode (0b011111 : +(bit[3]) _ : +(bit[2]) L : +(bit[5]) RA : +(bit[5]) RB : +0b0001010110 : +(bit[1]) _ as instr) = + Some(Dcbf(L,RA,RB)) + +function clause execute (Dcbf (L, RA, RB)) = () + +union ast member Isync + +function clause decode (0b010011 : +(bit[5]) _ : +(bit[5]) _ : +(bit[5]) _ : +0b0010010110 : +(bit[1]) _ as instr) = + Some(Isync()) + +function clause execute Isync = I_Sync(()) + +union ast member (bit[5], bit[5], bit[5], bit) Lbarx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0000110100 : +[EH] as instr) = + Some(Lbarx(RT,RA,RB,EH)) + +function clause execute (Lbarx (RT, RA, RB, EH)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := 0b00000000000000000000000000000000000000000000000000000000 : MEMr_reserve(EA,1) + } + +union ast member (bit[5], bit[5], bit[5], bit) Lharx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0001110100 : +[EH] as instr) = + Some(Lharx(RT,RA,RB,EH)) + +function clause execute (Lharx (RT, RA, RB, EH)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := 0b000000000000000000000000000000000000000000000000 : MEMr_reserve(EA,2) + } + +union ast member (bit[5], bit[5], bit[5], bit) Lwarx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0000010100 : +[EH] as instr) = + Some(Lwarx(RT,RA,RB,EH)) + +function clause execute (Lwarx (RT, RA, RB, EH)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := 0b00000000000000000000000000000000 : MEMr_reserve(EA,4) + } + +union ast member (bit[5], bit[5], bit[5]) Stbcx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1010110110 : +0b1 as instr) = + Some(Stbcx(RS,RA,RB)) + +function clause execute (Stbcx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA_cond(EA,1); + status := MEMw_conditional(EA,1,(GPR[RS])[56 .. 63]); + CR0 := 0b00 : [status] : [XER.SO] + } + +union ast member (bit[5], bit[5], bit[5]) Sthcx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b1011010110 : +0b1 as instr) = + Some(Sthcx(RS,RA,RB)) + +function clause execute (Sthcx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA_cond(EA,2); + status := MEMw_conditional(EA,2,(GPR[RS])[48 .. 63]); + CR0 := 0b00 : [status] : [XER.SO] + } + +union ast member (bit[5], bit[5], bit[5]) Stwcx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0010010110 : +0b1 as instr) = + Some(Stwcx(RS,RA,RB)) + +function clause execute (Stwcx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA_cond(EA,4); + status := MEMw_conditional(EA,4,(GPR[RS])[32 .. 63]); + CR0 := 0b00 : [status] : [XER.SO] + } + +union ast member (bit[5], bit[5], bit[5], bit) Ldarx + +function clause decode (0b011111 : +(bit[5]) RT : +(bit[5]) RA : +(bit[5]) RB : +0b0001010100 : +[EH] as instr) = + Some(Ldarx(RT,RA,RB,EH)) + +function clause execute (Ldarx (RT, RA, RB, EH)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + GPR[RT] := MEMr_reserve(EA,8) + } + +union ast member (bit[5], bit[5], bit[5]) Stdcx + +function clause decode (0b011111 : +(bit[5]) RS : +(bit[5]) RA : +(bit[5]) RB : +0b0011010110 : +0b1 as instr) = + Some(Stdcx(RS,RA,RB)) + +function clause execute (Stdcx (RS, RA, RB)) = + { + (bit[64]) b := 0; + (bit[64]) EA := 0; + if RA == 0 then b := 0 else b := GPR[RA]; + EA := b + GPR[RB]; + MEMw_EA_cond(EA,8); + status := MEMw_conditional(EA,8,GPR[RS]); + CR0 := 0b00 : [status] : [XER.SO] + } + +union ast member (bit[2]) Sync + +function clause decode (0b011111 : +(bit[3]) _ : +(bit[2]) L : +(bit[5]) _ : +(bit[5]) _ : +0b1001010110 : +(bit[1]) _ as instr) = + Some(Sync(L)) + +function clause execute (Sync (L)) = + switch L { case 0b00 -> { H_Sync(()) } case 0b01 -> { LW_Sync(()) } } + +union ast member Eieio + +function clause decode (0b011111 : +(bit[5]) _ : +(bit[5]) _ : +(bit[5]) _ : +0b1101010110 : +(bit[1]) _ as instr) = + Some(Eieio()) + +function clause execute Eieio = EIEIO_Sync(()) + +union ast member (bit[2]) Wait + +function clause decode (0b011111 : +(bit[3]) _ : +(bit[2]) WC : +(bit[5]) _ : +(bit[5]) _ : +0b0000111110 : +(bit[1]) _ as instr) = + Some(Wait(WC)) + +function clause execute (Wait (WC)) = () + + +typedef decode_failure = enumerate { no_matching_pattern; unsupported_instruction; illegal_instruction } + +function clause decode _ = None + +end decode +end execute +end ast + +val ast -> option<ast> effect pure supported_instructions +function option<ast> supported_instructions ((ast) instr) = { + switch instr { + (* case (Mbar(_)) -> None *) + case (Sync(0b10)) -> None + case (Sync(0b11)) -> None + case _ -> Some(instr) + } +} + +val ast -> bit effect pure illegal_instructions_pred +function bit illegal_instructions_pred ((ast) instr) = { + switch instr { + case (Bcctr(BO,BI,BH,LK)) -> ~(BO[2]) + case (Lbzu(RT,RA,D)) -> (RA == 0) | (RA == RT) + case (Lbzux(RT,RA,_)) ->(RA == 0) | (RA == RT) + case (Lhzu(RT,RA,D)) -> (RA == 0) | (RA == RT) + case (Lhzux(RT,RA,RB)) -> (RA == 0) | (RA == RT) + case (Lhau(RT,RA,D)) -> (RA == 0) | (RA == RT) + case (Lhaux(RT,RA,RB)) -> (RA == 0) | (RA == RT) + case (Lwzu(RA,RT,D)) -> (RA == 0) | (RA == RT) + case (Lwzux(RT,RA,RB)) -> (RA == 0) | (RA == RT) + case (Lwaux(RA,RT,RB)) -> (RA == 0) | (RA == RT) + case (Ldu(RT,RA,DS)) -> (RA == 0) | (RA == RT) + case (Ldux(RT,RA,RB)) -> (RA == 0) | (RA == RT) + case (Stbu(RS,RA,D)) -> (RA == 0) + case (Stbux(RS,RA,RB)) -> (RA == 0) + case (Sthu(RS,RA,RB)) -> (RA == 0) + case (Sthux(RS,RA,RB)) -> (RA == 0) + case (Stwu(RS,RA,D)) -> (RA == 0) + case (Stwux(RS,RA,RB)) -> (RA == 0) + case (Stdu(RS,RA,DS)) -> (RA == 0) + case (Stdux(RS,RA,RB)) -> (RA == 0) + case (Lmw(RT,RA,D)) -> (RA == 0) | ((RT <= RA) & (RA <= 31)) + case (Lswi(RT,RA,NB)) -> + let (([|32|]) n) = (if ~(NB == 0) then NB else 32) in + let ceil = + (if (n mod 4) == 0 + then n quot 4 else (n quot 4) + 1) in + (RT <= RA) & (RA <= ((bit[5]) (((bit[5]) (RT + ceil)) - 1))) + (* Can't read XER at the time meant, so will need to rethink *) + (* case (Lswx(RT,RA,RB)) -> + let (([|32|]) n) = (XER[57..63]) in + let ceil = + (if (n mod 4 == 0) + then n quot 4 else (n quot 4) + 1) in + let ((bit[5]) upper_bound) = (RT + ceil) in + (RT <= RA & RA <= upper_bound) | + (RT <= RB & RB <= upper_bound) | + (RT == RA) | (RT == RB)*) +(*Floating point instructions*) +(* case (Lfsu(FRT,RA,D)) -> (RA == 0) + case (Lfsux(FRT,RA,RB)) -> (RA == 0) + case (Lfdu(FRT,RA,D)) -> (RA == 0) + case (Lfdux(FRT,RA,RB)) -> (RA == 0) + case (Stfsu(FRS,RA,D)) -> (RA == 0) + case (Stfsux(FRS,RA,RB)) -> (RA == 0) + case (Stfdu(FRS,D,RA)) -> (RA == 0) + case (Stfdux(FRS,RA,RB)) -> (RA == 0) + case (Lfdp(FRTp,RA,DS)) -> (FRTp mod 2 == 1) + case (Stfdp(FRSp,RA,DS)) -> (FRSp mod 2 == 1) + case (Lfdpx(FRTp,RA,RB)) -> (FRTp mod 2 == 1) + case (Stfdpx(FRSp,RA,RB)) -> (FRSp mod 2 == 1)*) + case (Lq(RTp,RA,DQ,Pt)) -> ((RTp mod 2 ==1) | RTp == RA) + case (Stq(RSp,RA,RS)) -> (RSp mod 2 == 1) + case (Mtspr(RS, spr)) -> + ~ ((spr == 1) | (spr == 8) | (spr == 9) | (spr == 256) | + (spr == 512) | (spr == 896) | (spr == 898)) +(*One of these causes a stack overflow error, don't want to debug why now*) + (*case (Mfspr(RT, spr)) -> + ~ ((spr == 1) | (spr == 8) | (spr == 9) | (spr == 136) | + (spr == 256) | (spr == 259) | (spr == 260) | (spr == 261) | + (spr == 262) | (spr == 263) | (spr == 268) | (spr == 268) | + (spr == 269) | (spr == 512) | (spr == 526) | (spr == 526) | + (spr == 527) | (spr == 896) | (spr == 898)) + case (Se_illegal) -> true + case (E_lhau(RT,RA,D8)) -> (RA == 0 | RA == RT) + case (E_Lhzu(RT,RA,D8)) -> (RA == 0 | RA == RT) + case (E_lwzu(RT,RA,D8)) -> (RA == 0 | RA == RT) + case (E_stbu(RS,RA,D8)) -> (RA == 0) + case (E_sthu(RS,RA,D8)) -> (RA == 0) + case (E_stwu(RS,RA,D8)) -> (RA == 0) + case (E_lmw(RT,RA,D8)) -> (RT <= RA & RA <= 31)*) + case _ -> false + } +} + +val ast -> option<ast> effect pure illegal_instructions +function option<ast> illegal_instructions instr = + if (illegal_instructions_pred (instr)) + then None else Some(instr) + +(* old fetch-decode-execute *) +(*function unit fde () = { + NIA := CIA + 4; + instr := decode(MEMr(CIA, 4)); + instr := supported_instructions(instr); + execute(instr); + CIA := NIA; +}*) diff --git a/power/power_embed.lem.fixed b/power/power_embed.lem.fixed new file mode 100644 index 00000000..52e25bdf --- /dev/null +++ b/power/power_embed.lem.fixed @@ -0,0 +1,6743 @@ +(*Generated by Sail from generated/power.sail.*) +open import Pervasives_extra +open import Sail_impl_base +open import Prompt +open import Sail_values +open import Power_embed_types +open import Power_extras_embed +let DEC_TO_BCD (Vector [p;q;r;s;t;u;v;w;x;y] _ _) = + let a = ((~s) &. (v &. w)) |. ((t &. (v &. (w &. s))) |. (v &. (w &. (~x)))) in + let b = (p &. (s &. (x &. (~t)))) |. ((p &. (~w)) |. (p &. (~v))) in + let c = (q &. (s &. (x &. (~t)))) |. ((q &. (~w)) |. (q &. (~v))) in + let d = r in + let e = (v &. ((~w) &. x)) |. ((s &. (v &. (w &. x))) |. ((~t) &. (v &. (x &. w)))) in + let f = (p &. (t &. (v &. (w &. (x &. (~s)))))) |. ((s &. ((~x) &. v)) |. (s &. (~v))) in + let g = (q &. (t &. (w &. (v &. (x &. (~s)))))) |. ((t &. ((~x) &. v)) |. (t &. (~v))) in + let h = u in + let i = (t &. (v &. (w &. x))) |. ((s &. (v &. (w &. x))) |. (v &. ((~w) &. (~x)))) in + let j = + (p &. ((~s) &. ((~t) &. (w &. v)))) |. + ((s &. (v &. ((~w) &. x))) |. ((p &. (w &. ((~x) &. v))) |. (w &. (~v)))) in + let k = + (q &. ((~s) &. ((~t) &. (v &. w)))) |. + ((t &. (v &. ((~w) &. x))) |. ((q &. (v &. (w &. (~x)))) |. (x &. (~v)))) in + let m = y in + Vector [a;b;c;d;e;f;g;h;i;j;k;m] 0 true + +let BCD_TO_DEC (Vector [a;b;c;d;e;f;g;h;i;j;k;m] _ _) = + let p = (f &. (a &. (i &. (~e)))) |. ((j &. (a &. (~i))) |. (b &. (~a))) in + let q = (g &. (a &. (i &. (~e)))) |. ((k &. (a &. (~i))) |. (c &. (~a))) in + let r = d in + let s = + (j &. ((~a) &. (e &. (~i)))) |. ((f &. ((~i) &. (~e))) |. ((f &. ((~a) &. (~e))) |. (e &. i))) in + let t = + (k &. ((~a) &. (e &. (~i)))) |. ((g &. ((~i) &. (~e))) |. ((g &. ((~a) &. (~e))) |. (a &. i))) in + let u = h in + let v = a |. (e |. i) in + let w = ((~e) &. (j &. (~i))) |. ((e &. i) |. a) in + let x = ((~a) &. (k &. (~i))) |. ((a &. i) |. e) in + let y = m in + Vector [p;q;r;s;t;u;v;w;x;y] 0 true + +let carry_out (_, carry) = carry + +let real_addr x = x + +let mark_as_not_likely_to_be_needed_again_anytime_soon x = () + +let EXTS_EXPLICIT (v, m) = (duplicate (access v (0:ii), m - (length (reset_vector_start v)))) ^^ v + +let MASK (start, stop) = + let mask_temp = to_vec_inc ((64:ii),(0:ii)) in + if bitU_to_bool (gt (start, stop)) + then + let mask_temp = update mask_temp start (63:ii) (duplicate (B1, (64:ii) - start)) in + update mask_temp (0:ii) stop (duplicate (B1, stop + (1:ii))) + else update mask_temp start stop (duplicate (B1, (stop - start) + (1:ii))) + +let ROTL (v, n) = (slice v n (63:ii)) ^^ (slice v (0:ii) (n - (1:ii))) + +let DOUBLE word = + let temp = to_vec_inc ((64:ii),(0:ii)) in + if bitU_to_bool + ((gt_vec_range (slice word (1:ii) (8:ii), (0:ii))) &. + (lt_vec_range (slice word (1:ii) (8:ii), (255:ii)))) + then + let temp = update temp (0:ii) (1:ii) (slice word (0:ii) (1:ii)) in + let temp = update_pos temp (2:ii) (~(access word (1:ii))) in + let temp = update_pos temp (3:ii) (~(access word (1:ii))) in + let temp = update_pos temp (4:ii) (~(access word (1:ii))) in + update + temp (5:ii) (63:ii) + (set_vector_start 5 + ((slice word (2:ii) (31:ii)) ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0] 0 true))) + else + if bitU_to_bool + ((eq_vec_range (slice word (1:ii) (8:ii), (0:ii))) &. + (neq_vec_range (slice word (9:ii) (31:ii), (0:ii)))) + then + let sign = access word (0:ii) in + let exp = (0:ii) - (126:ii) in + let frac = + (Vector [B0] 0 true) ^^ + ((slice word (9:ii) (31:ii)) ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0] 0 true)) in + let (exp, frac) = + (foreach_inc ((0:ii),(52:ii),(1:ii)) (exp,frac) + (fun i (exp,frac) -> + let (frac, exp) = + if bitU_to_bool + (eq (match (access frac (0:ii)) with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + let frac = + update frac (0:ii) (52:ii) ((slice frac (1:ii) (52:ii)) ^^ (Vector [B0] 0 true)) in + let exp = exp - (1:ii) in + (frac,exp) + else (frac,exp) in + (exp,frac))) in + let temp = update_pos temp (0:ii) sign in + let temp = + update + temp (1:ii) (11:ii) + (add_VIV (reset_vector_start (to_vec_inc ((11:ii),exp))) (1023:ii)) in + update temp (12:ii) (63:ii) (set_vector_start 12 (slice frac (1:ii) (52:ii))) + else + let temp = update temp (0:ii) (1:ii) (slice word (0:ii) (1:ii)) in + let temp = update_pos temp (2:ii) (access word (1:ii)) in + let temp = update_pos temp (3:ii) (access word (1:ii)) in + let temp = update_pos temp (4:ii) (access word (1:ii)) in + update + temp (5:ii) (63:ii) + (set_vector_start 5 + ((slice word (2:ii) (31:ii)) ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0] 0 true))) + +let SINGLE frs = + let word = to_vec_inc ((32:ii),(0:ii)) in + if bitU_to_bool + ((gt_vec_range (slice frs (1:ii) (11:ii), (896:ii))) |. + (eq_vec_range (slice frs (1:ii) (63:ii), (0:ii)))) + then + let word = update word (0:ii) (1:ii) (slice frs (0:ii) (1:ii)) in + update word (2:ii) (31:ii) (set_vector_start 2 (slice frs (5:ii) (34:ii))) + else + if bitU_to_bool + ((lteq_range_vec ((874:ii), slice frs (1:ii) (11:ii))) &. + (lteq_vec_range (slice frs (1:ii) (11:ii), (896:ii)))) + then + let sign = access frs (0:ii) in + let exp = + set_vector_start 0 (minus_VIV (reset_vector_start (slice frs (1:ii) (11:ii))) (1023:ii)) in + let frac = (Vector [B1] 0 true) ^^ (slice frs (12:ii) (63:ii)) in + let (exp, frac) = + (foreach_inc ((0:ii),(53:ii),(1:ii)) (exp,frac) + (fun i (exp,frac) -> + let (frac, exp) = + if bitU_to_bool (lt_vec_range (exp, (0:ii) - (126:ii))) + then + let frac = + update frac (0:ii) (52:ii) ((Vector [B0] 0 true) ^^ (slice frac (0:ii) (51:ii))) in + let exp = set_vector_start 0 (add_VIV (reset_vector_start exp) (1:ii)) in + (frac,exp) + else (frac,exp) in + (exp,frac))) in + word + else to_vec_inc_undef (32:ii) + +let Chop (x, y) = slice x (0:ii) y + +let byte_reverse (m', input) = + let output = to_vec_inc (length input,(0:ii)) in + let j = length (reset_vector_start input) in + let (j, output) = + (foreach_inc ((0:ii),length (reset_vector_start input),(8:ii)) (j,output) + (fun i (j,output) -> + let output = update output i (i + (7:ii)) (slice input (j - (7:ii)) j) in + let j = j - (8:ii) in + (j,output))) in + output + +let rec reverse_endianness value = + let width = length (reset_vector_start value) in + let half = quot width (2:ii) in + if bitU_to_bool (eq_range (width, (8:ii))) + then value + else + (reverse_endianness + (reset_vector_start (set_vector_start 0 (slice value half (width - (1:ii)))))) ^^ + (reverse_endianness (reset_vector_start (slice value (0:ii) (half - (1:ii))))) + +let zero_or_undef x = + let out = to_vec_inc (length x,(0:ii)) in + (foreach_inc ((0:ii),(length (reset_vector_start x)) - (1:ii),(1:ii)) out + (fun i out -> update_pos out i (if bitU_to_bool (access x i) then BU else B0))) + +let GPRs = + Vector ["GPR0";"GPR1";"GPR2";"GPR3";"GPR4";"GPR5";"GPR6";"GPR7";"GPR8";"GPR9";"GPR10";"GPR11";"GPR12";"GPR13";"GPR14";"GPR15";"GPR16";"GPR17";"GPR18";"GPR19";"GPR20"; + "GPR21";"GPR22";"GPR23";"GPR24";"GPR25";"GPR26";"GPR27";"GPR28";"GPR29";"GPR30";"GPR31"] 0 true + +let SPRs = + make_indexed_vector + [(1,"XER");(8,"LR");(9,"CTR");(259,"SPRG3");(260,"SPRG4");(261,"SPRG5"); + (262,"SPRG6");(263,"SPRG7")] + "" 0 1024 true + +let DCRs = make_indexed_vector [(0,"DCR0");(1,"DCR1")] "" 0 1024 true + +let length_spr i = + match toNatural i with + | (1:nn) -> (64:ii) + | (8:nn) -> (64:ii) + | (9:nn) -> (64:ii) + | (259:nn) -> (64:ii) + | (260:nn) -> (64:ii) + | (261:nn) -> (64:ii) + | (262:nn) -> (64:ii) + | (263:nn) -> (64:ii) + end + +let DCR = make_indexed_vector [(0,DCR0);(1,DCR1)] (UndefinedRegister 64) 0 1024 true + +let Clamp (k', x, y, z) = + let result = (0:ii) in + (if bitU_to_bool (lt (x, y)) + then + let result = y in + write_reg_bitfield VSCR "SAT" B1 >> + return result + else + if bitU_to_bool (gt (x, z)) + then + let result = z in + write_reg_bitfield VSCR "SAT" B1 >> + return result + else return x) >>= fun result -> + return (to_vec_inc (k',result)) + +let MEMw (ea, size, value) = + read_reg bigendianmode >>= fun w__0 -> + if bitU_to_bool (most_significant w__0) + then + MEMw' + (reset_vector_start ea, + size, + reset_vector_start (reverse_endianness (reset_vector_start value))) + else MEMw' (reset_vector_start ea,size,reset_vector_start value) + +let MEMr (ea, size) = + read_reg bigendianmode >>= fun w__0 -> + if bitU_to_bool (most_significant w__0) + then + MEMr' (reset_vector_start ea,size) >>= fun w__1 -> + return (reverse_endianness (reset_vector_start w__1)) + else MEMr' (reset_vector_start ea,size) + +let MEMr_reserve (ea, size) = + read_reg bigendianmode >>= fun w__0 -> + if bitU_to_bool (most_significant w__0) + then + MEMr_reserve' (reset_vector_start ea,size) >>= fun w__1 -> + return (reverse_endianness (reset_vector_start w__1)) + else MEMr_reserve' (reset_vector_start ea,size) + +let MEMw_conditional (ea, size, value) = + read_reg bigendianmode >>= fun w__0 -> + if bitU_to_bool (most_significant w__0) + then + MEMw_conditional' + (reset_vector_start ea, + size, + reset_vector_start (reverse_endianness (reset_vector_start value))) + else MEMw_conditional' (reset_vector_start ea,size,reset_vector_start value) + +let set_SO_OV overflow = + write_reg_bitfield XER "OV" overflow >> + read_reg_bitfield XER "SO" >>= fun w__0 -> + write_reg_bitfield XER "SO" (w__0 |. overflow) + +let supported_instructions instr = + match instr with + | Sync ((Vector [B1;B0] _ _)) -> Nothing + | Sync ((Vector [B1;B1] _ _)) -> Nothing + | _ -> Just instr + end + +let CIA_fp = RFull "CIA" + +let NIA_fp = RFull "NIA" + +let mode64bit_fp = RFull "mode64bit" + +let bigendianmode_fp = RFull "bigendianmode" + +let set_overflow_cr0 (target_register, new_xer_so) = + let m = (0:ii) in + let c = to_vec_inc ((3:ii),(0:ii)) in + let zero = to_vec_inc ((64:ii),(0:ii)) in + read_reg mode64bit >>= fun w__0 -> + let m = if bitU_to_bool (most_significant w__0) then (0:ii) else (32:ii) in + let c = + if bitU_to_bool (lt_vec_signed (slice target_register m (63:ii), slice zero m (63:ii))) + then Vector [B1;B0;B0] 0 true + else + if bitU_to_bool (gt_vec_signed (slice target_register m (63:ii), slice zero m (63:ii))) + then Vector [B0;B1;B0] 0 true + else Vector [B0;B0;B1] 0 true in + write_reg_field CR "CR0" (set_vector_start 32 (c ^^ (Vector [new_xer_so] 0 true))) + +let SPR = + make_indexed_vector + [(1,XER);(8,LR);(9,CTR);(259,SPRG3);(260,SPRG4);(261,SPRG5); + (262,SPRG6);(263,SPRG7)] + (UndefinedRegister 64) 0 1024 true + +let FPRp = + make_indexed_vector + [(0,RegisterPair FPR0 FPR1);(2,RegisterPair FPR2 FPR3);(4,RegisterPair FPR4 FPR5);(6,RegisterPair FPR6 FPR7);(8,RegisterPair FPR8 FPR9);(10,RegisterPair FPR10 FPR11); + (12,RegisterPair FPR12 FPR13);(14,RegisterPair FPR14 FPR15);(16,RegisterPair FPR16 FPR17);(18,RegisterPair FPR18 FPR19);(20,RegisterPair FPR20 FPR21);(22,RegisterPair FPR22 FPR23); + (24,RegisterPair FPR24 FPR25);(26,RegisterPair FPR26 FPR27);(28,RegisterPair FPR28 FPR29);(30,RegisterPair FPR30 FPR31)] + (UndefinedRegister 128) 0 32 true + +let illegal_instructions_pred instr = + match instr with + | Bcctr (BO,BI,BH,LK) -> ~(access BO (2:ii)) + | Lbzu (RT,RA,D) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lbzux (RT,RA,_) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lhzu (RT,RA,D) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lhzux (RT,RA,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lhau (RT,RA,D) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lhaux (RT,RA,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lwzu (RA,RT,D) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lwzux (RT,RA,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lwaux (RA,RT,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Ldu (RT,RA,DS) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Ldux (RT,RA,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Stbu (RS,RA,D) -> eq_vec_range (RA, (0:ii)) + | Stbux (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Sthu (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Sthux (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Stwu (RS,RA,D) -> eq_vec_range (RA, (0:ii)) + | Stwux (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Stdu (RS,RA,DS) -> eq_vec_range (RA, (0:ii)) + | Stdux (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Lmw (RT,RA,D) -> + (eq_vec_range (RA, (0:ii))) |. ((lteq_vec (RT, RA)) &. (lteq_vec_range (RA, (31:ii)))) + | Lswi (RT,RA,NB) -> + let n = + if bitU_to_bool (~(eq_vec_range (NB, (0:ii)))) + then unsigned (reset_vector_start NB) + else (32:ii) in + let ceil = + if bitU_to_bool (eq_range (modulo n (4:ii), (0:ii))) + then quot n (4:ii) + else (quot n (4:ii)) + (1:ii) in + (lteq_vec (RT, RA)) &. + (lteq_vec + (RA, + minus_VIV + (reset_vector_start (set_vector_start 0 (add_VIV (reset_vector_start RT) ceil))) + (1:ii))) + | Lq (RTp,RA,DQ,Pt) -> + (eq_vec_range (minus_VIV (reset_vector_start RTp) (2:ii), (1:ii))) |. (eq_vec (RTp, RA)) + | Stq (RSp,RA,RS) -> eq_vec_range (minus_VIV (reset_vector_start RSp) (2:ii), (1:ii)) + | Mtspr (RS,spr) -> + ~((eq_vec_range (spr, (1:ii))) |. + ((eq_vec_range (spr, (8:ii))) |. + ((eq_vec_range (spr, (9:ii))) |. + ((eq_vec_range (spr, (256:ii))) |. + ((eq_vec_range (spr, (512:ii))) |. + ((eq_vec_range (spr, (896:ii))) |. (eq_vec_range (spr, (898:ii))))))))) + | _ -> B0 + end + +let GPR = + Vector [GPR0;GPR1;GPR2;GPR3;GPR4;GPR5;GPR6;GPR7;GPR8;GPR9;GPR10;GPR11;GPR12;GPR13;GPR14;GPR15;GPR16;GPR17;GPR18;GPR19;GPR20; + GPR21;GPR22;GPR23;GPR24;GPR25;GPR26;GPR27;GPR28;GPR29;GPR30;GPR31] 0 true + +let FPR = + Vector [FPR0;FPR1;FPR2;FPR3;FPR4;FPR5;FPR6;FPR7;FPR8;FPR9;FPR10;FPR11;FPR12;FPR13;FPR14;FPR15;FPR16;FPR17;FPR18;FPR19;FPR20; + FPR21;FPR22;FPR23;FPR24;FPR25;FPR26;FPR27;FPR28;FPR29;FPR30;FPR31] 0 true + +let VR = + Vector [VR0;VR1;VR2;VR3;VR4;VR5;VR6;VR7;VR8;VR9;VR10;VR11;VR12;VR13;VR14;VR15;VR16;VR17;VR18;VR19;VR20; + VR21;VR22;VR23;VR24;VR25;VR26;VR27;VR28;VR29;VR30;VR31] 0 true + +let decode = function + | ((Vector [B0;B1;B0;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;AA;LK] _ _) as instr) -> + let LI = slice_raw instr (6:ii) (29:ii) in + Just (B (reset_vector_start LI,AA,LK)) + | ((Vector [B0;B1;B0;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;AA;LK] _ _) as instr) -> + let BO = slice_raw instr (6:ii) (10:ii) in + let BI = slice_raw instr (11:ii) (15:ii) in + let BD = slice_raw instr (16:ii) (29:ii) in + Just (Bc (reset_vector_start BO,reset_vector_start BI,reset_vector_start BD,AA,LK)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;LK] _ _) as instr) -> + let BO = slice_raw instr (6:ii) (10:ii) in + let BI = slice_raw instr (11:ii) (15:ii) in + let BH = slice_raw instr (19:ii) (20:ii) in + Just (Bclr (reset_vector_start BO,reset_vector_start BI,reset_vector_start BH,LK)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B0;B0;B0;B0;LK] _ _) as instr) -> + let BO = slice_raw instr (6:ii) (10:ii) in + let BI = slice_raw instr (11:ii) (15:ii) in + let BH = slice_raw instr (19:ii) (20:ii) in + Just (Bcctr (reset_vector_start BO,reset_vector_start BI,reset_vector_start BH,LK)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crand (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B1;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crnand (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B0;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Cror (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crxor (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crnor (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B1;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Creqv (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crandc (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crorc (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let BFA = slice_raw instr (11:ii) (13:ii) in + Just (Mcrf (reset_vector_start BF,reset_vector_start BFA)) + | ((Vector [B0;B1;B0;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;_] _ _) as instr) -> + let LEV = slice_raw instr (20:ii) (26:ii) in + Just (Sc (reset_vector_start LEV)) + | ((Vector [B0;B1;B0;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1] _ _) as instr) -> + let LEV = slice_raw instr (20:ii) (26:ii) in + Just (Scv (reset_vector_start LEV)) + | ((Vector [B1;B0;B0;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lbz (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lbzx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lbzu (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lbzux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lhz (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhzx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lhzu (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhzux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lha (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhax (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lhau (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhaux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lwz (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwzx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lwzu (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwzux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Lwa (reset_vector_start RT,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwax (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B1;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwaux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Ld (reset_vector_start RT,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Ldx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Ldu (reset_vector_start RT,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Ldux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stb (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stbx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stbu (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stbux (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Sth (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sthx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Sthu (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sthux (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stw (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stwx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stwu (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stwux (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Std (reset_vector_start RS,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stdx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Stdu (reset_vector_start RS,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B1;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stdux (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RTp = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DQ = slice_raw instr (16:ii) (27:ii) in + let PT = slice_raw instr (28:ii) (31:ii) in + Just (Lq (reset_vector_start RTp,reset_vector_start RA,reset_vector_start DQ,reset_vector_start PT)) + | ((Vector [B1;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0] _ _) as instr) -> + let RSp = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Stq (reset_vector_start RSp,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhbrx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sthbrx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwbrx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stwbrx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B0;B1;B0;B0;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Ldbrx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B0;B0;B1;B0;B1;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stdbrx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lmw (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B1;B0;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stmw (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B1;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let NB = slice_raw instr (16:ii) (20:ii) in + Just (Lswi (reset_vector_start RT,reset_vector_start RA,reset_vector_start NB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lswx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B1;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let NB = slice_raw instr (16:ii) (20:ii) in + Just (Stswi (reset_vector_start RS,reset_vector_start RA,reset_vector_start NB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B0;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stswx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B0;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Addi (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B0;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Addis (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B0;B0;B0;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Add (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Subf (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B1;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Addic (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B0;B1;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (AddicDot (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B0;B1;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Subfic (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B0;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Addc (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Subfc (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B0;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Adde (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Subfe (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Addme (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Subfme (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B0;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Addze (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Subfze (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B1;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Neg (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Mulli (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mullw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B1;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B0;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B1;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divwe (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B0;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divweu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulld (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhd (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhdu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B1;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divd (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B0;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divdu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B1;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divde (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B0;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divdeu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B1;B0;B1;B1;_;_;_;_;L;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Cmpi (reset_vector_start BF,L,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;L;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Cmp (reset_vector_start BF,L,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B0;B1;B0;B1;B0;_;_;_;_;L;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Cmpli (reset_vector_start BF,L,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;L;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Cmpl (reset_vector_start BF,L,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + let BC = slice_raw instr (21:ii) (25:ii) in + Just (Isel (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,reset_vector_start BC)) + | ((Vector [B0;B1;B1;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Andi (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Andis (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Ori (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Oris (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Xori (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Xoris (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (And (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B1;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Xor (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nand (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B1;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Or (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B1;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nor (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Eqv (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Andc (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B0;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Orc (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B0;B1;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Extsb (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B0;B0;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Extsh (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Cntlzw (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B1;B1;B1;B1;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Cmpb (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Popcntb (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Popcntw (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Prtyd (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Prtyw (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B1;B0;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Extsw (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Cntlzd (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Popcntd (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B1;B1;B1;B1;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Bpermd (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B0;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SH = slice_raw instr (16:ii) (20:ii) in + let MB = slice_raw instr (21:ii) (25:ii) in + let ME = slice_raw instr (26:ii) (30:ii) in + Just (Rlwinm (reset_vector_start RS,reset_vector_start RA,reset_vector_start SH,reset_vector_start MB,reset_vector_start ME,Rc)) + | ((Vector [B0;B1;B0;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + let MB = slice_raw instr (21:ii) (25:ii) in + let ME = slice_raw instr (26:ii) (30:ii) in + Just (Rlwnm (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,reset_vector_start MB,reset_vector_start ME,Rc)) + | ((Vector [B0;B1;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SH = slice_raw instr (16:ii) (20:ii) in + let MB = slice_raw instr (21:ii) (25:ii) in + let ME = slice_raw instr (26:ii) (30:ii) in + Just (Rlwimi (reset_vector_start RS,reset_vector_start RA,reset_vector_start SH,reset_vector_start MB,reset_vector_start ME,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let mb = slice_raw instr (21:ii) (26:ii) in + Just (Rldicl (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) + (20:ii)) ^^ + (slice instr + (30:ii) + (30:ii))),reset_vector_start mb,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let me = slice_raw instr (21:ii) (26:ii) in + Just (Rldicr (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) + (20:ii)) ^^ + (slice instr + (30:ii) + (30:ii))),reset_vector_start me,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let mb = slice_raw instr (21:ii) (26:ii) in + Just (Rldic (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) (20:ii)) ^^ + (slice instr + (30:ii) (30:ii))),reset_vector_start mb,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + let mb = slice_raw instr (21:ii) (26:ii) in + Just (Rldcl (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,reset_vector_start mb,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + let me = slice_raw instr (21:ii) (26:ii) in + Just (Rldcr (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,reset_vector_start me,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let mb = slice_raw instr (21:ii) (26:ii) in + Just (Rldimi (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) + (20:ii)) ^^ + (slice instr + (30:ii) + (30:ii))),reset_vector_start mb,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Slw (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Srw (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B1;B1;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SH = slice_raw instr (16:ii) (20:ii) in + Just (Srawi (reset_vector_start RS,reset_vector_start RA,reset_vector_start SH,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B0;B1;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sraw (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sld (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Srd (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B1;B1;B1;B0;B1;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Sradi (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) (20:ii)) ^^ + (slice instr + (30:ii) (30:ii))),Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B0;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Srad (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Cdtbcd (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Cbcdtd (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B0;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Addg6s (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B0;B1;B0;B0;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let spr = slice_raw instr (11:ii) (20:ii) in + Just (Mtspr (reset_vector_start RS,reset_vector_start spr)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B0;B1;B0;B0;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let spr = slice_raw instr (11:ii) (20:ii) in + Just (Mfspr (reset_vector_start RT,reset_vector_start spr)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;B0;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B0;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let FXM = slice_raw instr (12:ii) (19:ii) in + Just (Mtcrf (reset_vector_start RS,reset_vector_start FXM)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;B0;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B0;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + Just (Mfcr (reset_vector_start RT)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;B1;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B0;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let FXM = slice_raw instr (12:ii) (19:ii) in + Just (Mtocrf (reset_vector_start RS,reset_vector_start FXM)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;B1;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B0;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let FXM = slice_raw instr (12:ii) (19:ii) in + Just (Mfocrf (reset_vector_start RT,reset_vector_start FXM)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + Just (Mcrxr (reset_vector_start BF)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B0;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dlmzb (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Macchw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Macchws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Macchwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Macchwsu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Machhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B1;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Machhws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Machhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B1;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Machhwsu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Maclhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Maclhws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Maclhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Maclhwsu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulchw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulchwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mullhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mullhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmacchw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmacchws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmachhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B1;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmachhws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmaclhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmaclhws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B1;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Icbi (reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let CT = slice_raw instr (7:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Icbt (reset_vector_start CT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B1;B1;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcba (reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let TH = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbt (reset_vector_start TH,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B1;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let TH = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbtst (reset_vector_start TH,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B1;B1;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbz (reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbst (reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let L = slice_raw instr (9:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbf (reset_vector_start L,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + Just (Isync) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B0;B1;B0;B0;EH] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lbarx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,EH)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B1;B1;B0;B1;B0;B0;EH] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lharx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,EH)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B0;B0;EH] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwarx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,EH)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B0;B1;B1;B0;B1;B1;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stbcx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B1;B0;B1;B0;B1;B1;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sthcx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B1;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stwcx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B0;B1;B0;B1;B0;B0;EH] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Ldarx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,EH)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B0;B1;B0;B1;B1;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stdcx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B1;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let L = slice_raw instr (9:ii) (10:ii) in + Just (Sync (reset_vector_start L)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B1;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + Just (Eieio) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B1;B1;B1;B0;_] _ _) as instr) -> + let WC = slice_raw instr (9:ii) (10:ii) in + Just (Wait (reset_vector_start WC)) + | _ -> Nothing + end + +let illegal_instructions instr = + if bitU_to_bool (illegal_instructions_pred instr) + then Nothing + else Just instr + +let recalculate_lswx_reg_footprint instr = + let iR = [] in + let oR = [] in + let Nias = [NIAFP_successor] in + let Dia = DIAFP_none in + let ik = IK_mem_read Read_plain in + let (RT, RA, RB) = match instr with | Lswx (RT,RA,RB) -> (RT,RA,RB) end in + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let r = (0:ii) in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice ("XER",(57:ii),(63:ii))) :: iR in + let aR = iR in + let r = minus_VII (reset_vector_start RT) (1:ii) in + let i = (32:ii) in + read_reg_range XER (57:ii) (63:ii) >>= fun w__0 -> + let n_top = unsigned (reset_vector_start w__0) in + let (r, oR) = + if bitU_to_bool (eq_range (n_top, (0:ii))) + then + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + (r,oR) + else + let j = (0:ii) in + let n_r = quot n_top (4:ii) in + let n_mod = modulo n_top (4:ii) in + let n_r = if bitU_to_bool (eq_range (n_mod, (0:ii))) then n_r else n_r + (1:ii) in + let (oR, j, r) = + (foreach_dec (n_r,(1:ii),(1:ii)) (oR,j,r) + (fun n (oR,j,r) -> + let r = modulo (r + (1:ii)) (32:ii) in + let j = j + (32:ii) in + let oR = (RFull (access GPRs r)) :: oR in + (oR,j,r))) in + (r,oR) in + return (iR,oR,aR,Nias,Dia,ik) + +let recalculate_stswx_reg_footprint instr = + let iR = [] in + let oR = [] in + let Nias = [NIAFP_successor] in + let Dia = DIAFP_none in + let ik = IK_mem_write Write_plain in + let (RS, RA, RB) = match instr with | Stswx (RS,RA,RB) -> (RS,RA,RB) end in + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let r = (0:ii) in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice ("XER",(57:ii),(63:ii))) :: iR in + let aR = iR in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let i = (32:ii) in + read_reg_range XER (57:ii) (63:ii) >>= fun w__0 -> + let n_top = unsigned (reset_vector_start w__0) in + let j = (0:ii) in + let (j, i, iR, r) = + (foreach_dec (n_top,(1:ii),(1:ii)) (j,i,iR,r) + (fun n (j,i,iR,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + let iR = (RSlice (access GPRs r,i,i + (7:ii))) :: iR in + let i = i + (8:ii) in + let j = j + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + (j,i,iR,r))) in + let ik = IK_mem_write Write_plain in + return (iR,oR,aR,Nias,Dia,ik) + + + +let execute_B (LI, AA, LK) = + (if bitU_to_bool AA + then + write_reg + NIA + (set_vector_start 0 (exts ((64:ii),reset_vector_start (LI ^^ (Vector [B0;B0] 0 true))))) + else + read_reg CIA >>= fun w__0 -> + write_reg + NIA + (set_vector_start 0 + (add_VVV + w__0 + (reset_vector_start (exts ((64:ii),reset_vector_start (LI ^^ (Vector [B0;B0] 0 true)))))))) >> + if bitU_to_bool LK + then + read_reg CIA >>= fun w__1 -> + write_reg LR (set_vector_start 0 (add_VIV w__1 (4:ii))) + else return () + +let execute_Bc (BO, BI, BD, AA, LK) = + let M = (0:ii) in + read_reg mode64bit >>= fun w__0 -> + let M = if bitU_to_bool (most_significant w__0) then (0:ii) else (32:ii) in + read_reg CTR >>= fun ctr_temp -> + (if bitU_to_bool (~(access BO (2:ii))) + then + let ctr_temp = set_vector_start 0 (minus_VIV (reset_vector_start ctr_temp) (1:ii)) in + write_reg CTR ctr_temp >> + return ctr_temp + else return ctr_temp) >>= fun ctr_temp -> + let ctr_ok = + (access BO (2:ii)) |. + ((~(eq_vec_range (slice ctr_temp M (63:ii), (0:ii)))) +. (access BO (3:ii))) in + read_reg_bit CR (add_VII (reset_vector_start BI) (32:ii)) >>= fun w__1 -> + let cond_ok = (access BO (0:ii)) |. (w__1 +. (~(access BO (1:ii)))) in + (if bitU_to_bool (ctr_ok &. cond_ok) + then + if bitU_to_bool AA + then + write_reg + NIA + (set_vector_start 0 (exts ((64:ii),reset_vector_start (BD ^^ (Vector [B0;B0] 0 true))))) + else + read_reg CIA >>= fun w__2 -> + write_reg + NIA + (set_vector_start 0 + (add_VVV + w__2 + (reset_vector_start (exts ((64:ii),reset_vector_start (BD ^^ (Vector [B0;B0] 0 true))))))) + else return ()) >> + if bitU_to_bool LK + then + read_reg CIA >>= fun w__3 -> + write_reg LR (set_vector_start 0 (add_VIV w__3 (4:ii))) + else return () + +let execute_Bclr (BO, BI, BH, LK) = + let M = (0:ii) in + read_reg mode64bit >>= fun w__0 -> + let M = if bitU_to_bool (most_significant w__0) then (0:ii) else (32:ii) in + read_reg CTR >>= fun ctr_temp -> + (if bitU_to_bool (~(access BO (2:ii))) + then + let ctr_temp = set_vector_start 0 (minus_VIV (reset_vector_start ctr_temp) (1:ii)) in + write_reg CTR ctr_temp >> + return ctr_temp + else return ctr_temp) >>= fun ctr_temp -> + let ctr_ok = + (access BO (2:ii)) |. + ((~(eq_vec_range (slice ctr_temp M (63:ii), (0:ii)))) +. (access BO (3:ii))) in + read_reg_bit CR (add_VII (reset_vector_start BI) (32:ii)) >>= fun w__1 -> + let cond_ok = (access BO (0:ii)) |. (w__1 +. (~(access BO (1:ii)))) in + (if bitU_to_bool (ctr_ok &. cond_ok) + then + read_reg_range LR (0:ii) (61:ii) >>= fun w__2 -> + write_reg NIA (w__2 ^^ (Vector [B0;B0] 0 true)) + else return ()) >> + if bitU_to_bool LK + then + read_reg CIA >>= fun w__3 -> + write_reg LR (set_vector_start 0 (add_VIV w__3 (4:ii))) + else return () + +let execute_Bcctr (BO, BI, BH, LK) = + read_reg_bit CR (add_VII (reset_vector_start BI) (32:ii)) >>= fun w__0 -> + let cond_ok = (access BO (0:ii)) |. (w__0 +. (~(access BO (1:ii)))) in + (if bitU_to_bool cond_ok + then + read_reg_range CTR (0:ii) (61:ii) >>= fun w__1 -> + write_reg NIA (w__1 ^^ (Vector [B0;B0] 0 true)) + else return ()) >> + if bitU_to_bool LK + then + read_reg CIA >>= fun w__2 -> + write_reg LR (set_vector_start 0 (add_VIV w__2 (4:ii))) + else return () + +let execute_Crand (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 &. w__1) + +let execute_Crnand (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (~(w__0 &. w__1)) + +let execute_Cror (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 |. w__1) + +let execute_Crxor (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 +. w__1) + +let execute_Crnor (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (~(w__0 |. w__1)) + +let execute_Creqv (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 +. (~w__1)) + +let execute_Crandc (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 &. (~w__1)) + +let execute_Crorc (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 |. (~w__1)) + +let execute_Mcrf (BF, BFA) = + read_reg_range CR + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BFA))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BFA))) (35:ii)) >>= fun w__0 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + w__0 + +let execute_Sc LEV = return () + +let execute_Scv LEV = return () + +let execute_Lbz (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMr (reset_vector_start EA,(1:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lbzx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(1:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lbzu (RT, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(1:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lbzux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(1:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lhz (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lhzx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lhzu (RT, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lhzux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lha (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__1))) + +let execute_Lhax (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__2))) + +let execute_Lhau (RT, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__1))) + +let execute_Lhaux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__2))) + +let execute_Lwz (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lwzx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lwzu (RT, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lwzux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lwa (RT, RA, DS) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start b) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__1))) + +let execute_Lwax (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__2))) + +let execute_Lwaux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__2))) + +let execute_Ld (RT, RA, DS) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start b) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + MEMr (reset_vector_start EA,(8:ii)) >>= fun w__1 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__1 + +let execute_Ldx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(8:ii)) >>= fun w__2 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__2 + +let execute_Ldu (RT, RA, DS) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(8:ii)) >>= fun w__1 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__1 + +let execute_Ldux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(8:ii)) >>= fun w__2 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__2 + +let execute_Stb (RS, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(1:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Stbx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(1:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Stbu (RS, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(1:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Stbux (RS, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(1:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Sth (RS, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Sthx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Sthu (RS, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Sthux (RS, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Stw (RS, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Stwx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Stwu (RS, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Stwux (RS, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Std (RS, RA, DS) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start b) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__1 -> + MEMw (reset_vector_start EA,(8:ii),reset_vector_start w__1) + +let execute_Stdx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__2 -> + MEMw (reset_vector_start EA,(8:ii),reset_vector_start w__2) + +let execute_Stdu (RS, RA, DS) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__1 -> + MEMw (reset_vector_start EA,(8:ii),reset_vector_start w__1) + +let execute_Stdux (RS, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__2 -> + MEMw (reset_vector_start EA,(8:ii),reset_vector_start w__2) + +let execute_Lhbrx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun load_data -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + ((slice load_data (8:ii) (15:ii)) ^^ (slice load_data (0:ii) (7:ii)))) + +let execute_Sthbrx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (55:ii) >>= fun w__3 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (w__2 ^^ w__3)) + +let execute_Lwbrx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun load_data -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + ((slice load_data (24:ii) (31:ii)) ^^ + ((slice load_data (16:ii) (23:ii)) ^^ + ((slice load_data (8:ii) (15:ii)) ^^ (slice load_data (0:ii) (7:ii)))))) + +let execute_Stwbrx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (55:ii) >>= fun w__3 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (40:ii) (47:ii) >>= fun w__4 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (39:ii) >>= fun w__5 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (w__2 ^^ (w__3 ^^ (w__4 ^^ w__5)))) + +let execute_Ldbrx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(8:ii)) >>= fun load_data -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((slice load_data (56:ii) (63:ii)) ^^ + ((slice load_data (48:ii) (55:ii)) ^^ + ((slice load_data (40:ii) (47:ii)) ^^ + ((slice load_data (32:ii) (39:ii)) ^^ + ((slice load_data (24:ii) (31:ii)) ^^ + ((slice load_data (16:ii) (23:ii)) ^^ + ((slice load_data (8:ii) (15:ii)) ^^ (slice load_data (0:ii) (7:ii))))))))) + +let execute_Stdbrx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (55:ii) >>= fun w__3 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (40:ii) (47:ii) >>= fun w__4 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (39:ii) >>= fun w__5 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (24:ii) (31:ii) >>= fun w__6 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (16:ii) (23:ii) >>= fun w__7 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (8:ii) (15:ii) >>= fun w__8 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (0:ii) (7:ii) >>= fun w__9 -> + MEMw + (reset_vector_start EA, + (8:ii), + reset_vector_start (w__2 ^^ (w__3 ^^ (w__4 ^^ (w__5 ^^ (w__6 ^^ (w__7 ^^ (w__8 ^^ w__9)))))))) + +let execute_Lmw (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + let size = (minus_IVI (32:ii) (reset_vector_start RT)) * (4:ii) in + MEMr (reset_vector_start EA,size) >>= fun buffer -> + let i = (0:ii) in + (foreachM_inc (unsigned (reset_vector_start RT),(31:ii),(1:ii)) i + (fun r i -> + write_reg + (access GPR r) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (slice buffer i (i + (31:ii)))) >> + let i = i + (32:ii) in + return i)) >>= fun i -> + return () + +let execute_Stmw (RS, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + let size = (minus_IVI (32:ii) (reset_vector_start RS)) * (4:ii) in + MEMw_EA (reset_vector_start EA,size) >> + let buffer = make_indexed_vector [(0,B0);(993,B0)] B0 0 994 true in + let i = (0:ii) in + (foreachM_inc (unsigned (reset_vector_start RS),(31:ii),(1:ii)) (i,buffer) + (fun r (i,buffer) -> + read_reg_range (access GPR r) (32:ii) (63:ii) >>= fun w__1 -> + let buffer = update buffer i (i + (31:ii)) w__1 in + let i = i + (32:ii) in + return (i,buffer))) >>= fun (i, buffer) -> + MEMw + (reset_vector_start EA, + size, + reset_vector_start (slice buffer (0:ii) ((size * (8:ii)) - (1:ii)))) + +let execute_Lswi (RT, RA, NB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let EA = to_vec_inc ((64:ii),(0:ii)) in + return EA + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun EA -> + let r = (0:ii) in + let r = minus_VII (reset_vector_start RT) (1:ii) in + let size = + if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB) in + MEMr (reset_vector_start EA,size) >>= fun membuffer -> + let j = (0:ii) in + let i = (32:ii) in + (foreachM_dec (if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB),(1:ii),(1:ii)) (EA,i,j,r) + (fun n (EA,i,j,r) -> + (if bitU_to_bool (eq_range (i, (32:ii))) + then + let r = modulo (r + (1:ii)) (32:ii) in + write_reg (access GPR r) (to_vec_inc ((64:ii),(0:ii))) >> + return r + else return r) >>= fun r -> + write_reg_range (access GPR r) i (i + (7:ii)) (slice membuffer j (j + (7:ii))) >> + let j = j + (8:ii) in + let i = i + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + let EA = set_vector_start 0 (add_VIV (reset_vector_start EA) (1:ii)) in + return (EA,i,j,r))) >>= fun (EA, i, j, r) -> + return () + +let execute_Lswx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let r = (0:ii) in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + let r = minus_VII (reset_vector_start RT) (1:ii) in + let i = (32:ii) in + read_reg_range XER (57:ii) (63:ii) >>= fun w__2 -> + let n_top = unsigned (reset_vector_start w__2) in + recalculate_dependency () >> + (if bitU_to_bool (eq_range (n_top, (0:ii))) + then + write_reg (access GPR (unsigned (reset_vector_start RT))) (to_vec_inc_undef (64:ii)) >> + return r + else + MEMr (reset_vector_start EA,n_top) >>= fun membuffer -> + let j = (0:ii) in + let n_r = quot n_top (4:ii) in + let n_mod = modulo n_top (4:ii) in + let n_r = if bitU_to_bool (eq_range (n_mod, (0:ii))) then n_r else n_r + (1:ii) in + (foreachM_dec (n_r,(1:ii),(1:ii)) (j,r) + (fun n (j,r) -> + let r = modulo (r + (1:ii)) (32:ii) in + let temp = to_vec_inc ((64:ii),(0:ii)) in + let temp = + if bitU_to_bool (eq_range (n, (1:ii))) + then + match toNatural n_mod with + | (0:nn) -> + update temp (32:ii) (63:ii) (set_vector_start 32 (slice membuffer j (j + (31:ii)))) + | (1:nn) -> + update temp (32:ii) (39:ii) (set_vector_start 32 (slice membuffer j (j + (7:ii)))) + | (2:nn) -> + update temp (32:ii) (47:ii) (set_vector_start 32 (slice membuffer j (j + (15:ii)))) + | (3:nn) -> + update temp (32:ii) (55:ii) (set_vector_start 32 (slice membuffer j (j + (23:ii)))) + end + else update temp (32:ii) (63:ii) (set_vector_start 32 (slice membuffer j (j + (31:ii)))) in + let j = j + (32:ii) in + write_reg (access GPR r) temp >> + return (j,r))) >>= fun (j, r) -> + return r) >>= fun r -> + return () + +let execute_Stswi (RS, RA, NB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let EA = to_vec_inc ((64:ii),(0:ii)) in + return EA + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun EA -> + let r = (0:ii) in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let size = + if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB) in + MEMw_EA (reset_vector_start EA,size) >> + let membuffer = make_indexed_vector [(0,B0);(255,B0)] B0 0 256 true in + let j = (0:ii) in + let i = (32:ii) in + (foreachM_dec (if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB),(1:ii),(1:ii)) (i,j,membuffer,r) + (fun n (i,j,membuffer,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + read_reg_range (access GPR r) i (i + (7:ii)) >>= fun w__1 -> + let membuffer = update membuffer j (j + (7:ii)) w__1 in + let j = j + (8:ii) in + let i = i + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + return (i,j,membuffer,r))) >>= fun (i, j, membuffer, r) -> + MEMw + (reset_vector_start EA, + size, + reset_vector_start (slice membuffer (0:ii) ((size * (8:ii)) - (1:ii)))) + +let execute_Stswx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let r = (0:ii) in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let i = (32:ii) in + read_reg_range XER (57:ii) (63:ii) >>= fun w__2 -> + let n_top = unsigned (reset_vector_start w__2) in + recalculate_dependency () >> + MEMw_EA (reset_vector_start EA,n_top) >> + let membuffer = make_indexed_vector [(0,B0);(511,B0)] B0 0 512 true in + let j = (0:ii) in + (foreachM_dec (n_top,(1:ii),(1:ii)) (j,i,membuffer,r) + (fun n (j,i,membuffer,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + read_reg_range (access GPR r) i (i + (7:ii)) >>= fun w__3 -> + let membuffer = update membuffer j (j + (7:ii)) w__3 in + let i = i + (8:ii) in + let j = j + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + return (j,i,membuffer,r))) >>= fun (j, i, membuffer, r) -> + if bitU_to_bool (~(eq_range (n_top, (0:ii)))) + then + MEMw + (reset_vector_start EA, + n_top, + reset_vector_start (slice membuffer (0:ii) ((n_top * (8:ii)) - (1:ii)))) + else return () + +let execute_Addi (RT, RA, SI) = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start SI))) + else + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 + (add_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start SI))))) + +let execute_Addis (RT, RA, SI) = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 + (exts + ((64:ii), + reset_vector_start (SI ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true))))) + else + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 + (add_VVV + (reset_vector_start w__0) + (reset_vector_start (exts + ((64:ii), + reset_vector_start (SI ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true))))))) + +let execute_Add (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (temp, overflow, _) = + match (addSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v0v', v1v', v2v') -> (v0v',v1v',v2v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subf (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (t1, o1, _) = + match (addSO_VVV + (reset_vector_start (bitwise_not (reset_vector_start w__0))) + (reset_vector_start w__1)) with + | (v3v', v4v', v5v') -> (v3v',v4v',v5v') + end in + let (t2, o2, _) = + match (addSO_VBV (reset_vector_start t1) B1) with | (v6v', v7v', v8v') -> (v6v',v7v',v8v') end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Addic (RT, RA, SI) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let (temp, _, carry) = + match (addSO_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start SI)))) with + | (v9v', v10v', v11v') -> (v9v',v10v',v11v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + write_reg_bitfield XER "CA" carry + +let execute_AddicDot (RT, RA, SI) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let (temp, overflow, carry) = + match (addSO_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start SI)))) with + | (v12v', v13v', v14v') -> (v12v',v13v',v14v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + write_reg_bitfield XER "CA" carry >> + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),overflow |. w__1) + +let execute_Subfic (RT, RA, SI) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let (t1, o1, c1) = + match (addSO_VVV + (reset_vector_start (bitwise_not (reset_vector_start w__0))) + (reset_vector_start (exts ((64:ii),reset_vector_start SI)))) with + | (v15v', v16v', v17v') -> (v15v',v16v',v17v') + end in + let (t2, o2, c2) = + match (addSO_VBV (reset_vector_start t1) B1) with + | (v18v', v19v', v20v') -> (v18v',v19v',v20v') + end in + let temp = set_vector_start 0 t2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + write_reg_bitfield XER "CA" (c1 |. c2) + +let execute_Addc (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (temp, overflow, carry) = + match (addSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v21v', v22v', v23v') -> (v21v',v22v',v23v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subfc (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VVV + (reset_vector_start (bitwise_not (reset_vector_start w__0))) + (reset_vector_start w__1)) with + | (v24v', v25v', v26v') -> (v24v',v25v',v26v') + end in + let (t2, o2, c2) = + match (addSO_VBV (reset_vector_start t1) B1) with + | (v27v', v28v', v29v') -> (v27v',v28v',v29v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Adde (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v30v', v31v', v32v') -> (v30v',v31v',v32v') + end in + read_reg_bitfield XER "CA" >>= fun w__2 -> + let (t2, o2, c2) = + match (addSO_VBV (reset_vector_start t1) w__2) with + | (v33v', v34v', v35v') -> (v33v',v34v',v35v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subfe (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VVV + (reset_vector_start (bitwise_not (reset_vector_start w__0))) + (reset_vector_start w__1)) with + | (v36v', v37v', v38v') -> (v36v',v37v',v38v') + end in + read_reg_bitfield XER "CA" >>= fun w__2 -> + let (t2, o2, c2) = + match (addSO_VBV (reset_vector_start t1) w__2) with + | (v39v', v40v', v41v') -> (v39v',v40v',v41v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Addme (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg_bitfield XER "CA" >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VBV (reset_vector_start w__0) w__1) with + | (v42v', v43v', v44v') -> (v42v',v43v',v44v') + end in + let (t2, o2, c2) = + match (addSO_VVV + (reset_vector_start t1) + (reset_vector_start (Vector [B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1] 0 true))) with + | (v45v', v46v', v47v') -> (v45v',v46v',v47v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subfme (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg_bitfield XER "CA" >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VBV (reset_vector_start (bitwise_not (reset_vector_start w__0))) w__1) with + | (v48v', v49v', v50v') -> (v48v',v49v',v50v') + end in + let (t2, o2, c2) = + match (addSO_VVV + (reset_vector_start t1) + (reset_vector_start (Vector [B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1] 0 true))) with + | (v51v', v52v', v53v') -> (v51v',v52v',v53v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Addze (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg_bitfield XER "CA" >>= fun w__1 -> + let (temp, overflow, carry) = + match (addSO_VBV (reset_vector_start w__0) w__1) with + | (v54v', v55v', v56v') -> (v54v',v55v',v56v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subfze (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg_bitfield XER "CA" >>= fun w__1 -> + let (temp, overflow, carry) = + match (addSO_VBV (reset_vector_start (bitwise_not (reset_vector_start w__0))) w__1) with + | (v57v', v58v', v59v') -> (v57v',v58v',v59v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Neg (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let (temp, overflow, _) = + match (addSO_VBV (reset_vector_start (bitwise_not (reset_vector_start w__0))) B1) with + | (v60v', v61v', v62v') -> (v60v',v61v',v62v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),w__1) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Mulli (RT, RA, SI) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let prod = + set_vector_start 0 + (multS_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start SI)))) in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (slice prod (64:ii) (127:ii))) + +let execute_Mullw (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let (prod, overflow, _) = + match (multSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v63v', v64v', v65v') -> (v63v',v64v',v65v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 prod) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 prod),xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Mulhw (RT, RA, RB, Rc) = + let prod = to_vec_inc ((64:ii),(0:ii)) in + let overflow = B0 in + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let (p, o, _) = + match (multSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v66v', v67v', v68v') -> (v66v',v67v',v68v') + end in + let prod = set_vector_start 0 p in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (set_vector_start 32 (slice prod (0:ii) (31:ii))) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool (most_significant w__2) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start prod,xer_so) + else return () + +let execute_Mulhwu (RT, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let prod = set_vector_start 0 (mult_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (set_vector_start 32 (slice prod (0:ii) (31:ii))) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool (most_significant w__2) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start prod,xer_so) + else return () + +let execute_Divw (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let dividend = set_vector_start 0 w__0 in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let divisor = set_vector_start 0 w__1 in + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotSO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v69v', v70v', v71v') -> (v69v',v70v',v71v') + end in + let divided = update divided (32:ii) (63:ii) (set_vector_start 32 d) in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (slice divided (32:ii) (63:ii)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool ((most_significant w__2) |. overflow) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start divided,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Divwu (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let dividend = set_vector_start 0 w__0 in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let divisor = set_vector_start 0 w__1 in + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v72v', v73v', v74v') -> (v72v',v73v',v74v') + end in + let divided = update divided (32:ii) (63:ii) (set_vector_start 32 d) in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (slice divided (32:ii) (63:ii)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool ((most_significant w__2) |. overflow) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start divided,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Divwe (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let dividend = + w__0 ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let divisor = set_vector_start 0 w__1 in + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotSO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v75v', v76v', v77v') -> (v75v',v76v',v77v') + end in + let divided = update divided (32:ii) (63:ii) (slice d (32:ii) (63:ii)) in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (slice divided (32:ii) (63:ii)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool ((most_significant w__2) |. overflow) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start divided,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Divweu (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let dividend = + w__0 ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let divisor = set_vector_start 0 w__1 in + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v78v', v79v', v80v') -> (v78v',v79v',v80v') + end in + let divided = update divided (32:ii) (63:ii) (slice d (32:ii) (63:ii)) in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (slice divided (32:ii) (63:ii)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool ((most_significant w__2) |. overflow) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start divided,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Mulld (RT, RA, RB, OE, Rc) = + let prod = to_vec_inc ((128:ii),(0:ii)) in + let overflow = B0 in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (p, o, _) = + match (multSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v81v', v82v', v83v') -> (v81v',v82v',v83v') + end in + let prod = set_vector_start 0 p in + let overflow = o in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (slice prod (64:ii) (127:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 (slice prod (64:ii) (127:ii))),xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Mulhd (RT, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let prod = set_vector_start 0 (multS_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RT))) (slice prod (0:ii) (63:ii)) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start (slice prod (0:ii) (63:ii)),w__2) + else return () + +let execute_Mulhdu (RT, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let prod = set_vector_start 0 (mult_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RT))) (slice prod (0:ii) (63:ii)) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start (slice prod (0:ii) (63:ii)),w__2) + else return () + +let execute_Divd (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun dividend -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun divisor -> + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotSO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v84v', v85v', v86v') -> (v84v',v85v',v86v') + end in + let divided = set_vector_start 0 d in + let overflow = o in + write_reg (access GPR (unsigned (reset_vector_start RT))) divided >> + (if bitU_to_bool OE + then set_SO_OV overflow + else return ()) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__0 -> + set_overflow_cr0 (reset_vector_start divided,overflow |. w__0) + else return () + +let execute_Divdu (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun dividend -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun divisor -> + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v87v', v88v', v89v') -> (v87v',v88v',v89v') + end in + let divided = set_vector_start 0 d in + let overflow = o in + write_reg (access GPR (unsigned (reset_vector_start RT))) divided >> + (if bitU_to_bool OE + then set_SO_OV overflow + else return ()) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__0 -> + set_overflow_cr0 (reset_vector_start divided,overflow |. w__0) + else return () + +let execute_Divde (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let dividend = + w__0 ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true) in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun divisor -> + let divided = to_vec_inc ((128:ii),(0:ii)) in + let overflow = B0 in + let (d, o, _) = + match (quotSO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v90v', v91v', v92v') -> (v90v',v91v',v92v') + end in + let divided = set_vector_start 0 d in + let overflow = o in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (slice divided (64:ii) (127:ii))) >> + (if bitU_to_bool OE + then set_SO_OV overflow + else return ()) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + if bitU_to_bool overflow + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else + set_overflow_cr0 + (reset_vector_start (set_vector_start 0 (slice divided (64:ii) (127:ii))), + xer_so) + else return () + +let execute_Divdeu (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let dividend = + w__0 ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true) in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun divisor -> + let divided = to_vec_inc ((128:ii),(0:ii)) in + let overflow = B0 in + let (d, o, _) = + match (quotO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v93v', v94v', v95v') -> (v93v',v94v',v95v') + end in + let divided = set_vector_start 0 d in + let overflow = o in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (slice divided (64:ii) (127:ii))) >> + (if bitU_to_bool OE + then set_SO_OV overflow + else return ()) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + if bitU_to_bool overflow + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else + set_overflow_cr0 + (reset_vector_start (set_vector_start 0 (slice divided (64:ii) (127:ii))), + xer_so) + else return () + +let execute_Cmpi (BF, L, RA, SI) = + let a = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let a = set_vector_start 0 (exts ((64:ii),reset_vector_start w__0)) in + return a + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun a -> + let c = make_indexed_vector [] B0 0 3 true in + let c = + if bitU_to_bool (lt_vec (a, exts ((64:ii),reset_vector_start SI))) + then Vector [B1;B0;B0] 0 true + else + if bitU_to_bool (gt_vec (a, exts ((64:ii),reset_vector_start SI))) + then Vector [B0;B1;B0] 0 true + else Vector [B0;B0;B1] 0 true in + read_reg_bitfield XER "SO" >>= fun w__2 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + (c ^^ (Vector [w__2] 0 true)) + +let execute_Cmp (BF, L, RA, RB) = + let a = to_vec_inc ((64:ii),(0:ii)) in + let b = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let a = set_vector_start 0 (exts ((64:ii),reset_vector_start w__0)) in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let b = set_vector_start 0 (exts ((64:ii),reset_vector_start w__1)) in + return (a,b) + else + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__2 -> + let a = w__2 in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__3 -> + let b = w__3 in + return (a,b)) >>= fun (a, b) -> + let c = make_indexed_vector [] B0 0 3 true in + let c = + if bitU_to_bool (lt_vec (a, b)) + then Vector [B1;B0;B0] 0 true + else if bitU_to_bool (gt_vec (a, b)) then Vector [B0;B1;B0] 0 true else Vector [B0;B0;B1] 0 true in + read_reg_bitfield XER "SO" >>= fun w__4 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + (c ^^ (Vector [w__4] 0 true)) + +let execute_Cmpli (BF, L, RA, UI) = + let a = to_vec_inc ((64:ii),(0:ii)) in + let c = to_vec_inc ((3:ii),(0:ii)) in + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let a = + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__0 in + return a + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun a -> + let c = + if bitU_to_bool + (lt_vec_unsigned + (a, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI)) + then Vector [B1;B0;B0] 0 true + else + if bitU_to_bool + (gt_vec_unsigned + (a, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI)) + then Vector [B0;B1;B0] 0 true + else Vector [B0;B0;B1] 0 true in + read_reg_bitfield XER "SO" >>= fun w__2 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + (c ^^ (Vector [w__2] 0 true)) + +let execute_Cmpl (BF, L, RA, RB) = + let a = to_vec_inc ((64:ii),(0:ii)) in + let b = to_vec_inc ((64:ii),(0:ii)) in + let c = to_vec_inc ((3:ii),(0:ii)) in + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let a = + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__0 in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let b = + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1 in + return (a,b) + else + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__2 -> + let a = w__2 in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__3 -> + let b = w__3 in + return (a,b)) >>= fun (a, b) -> + let c = + if bitU_to_bool (lt_vec_unsigned (a, b)) + then Vector [B1;B0;B0] 0 true + else + if bitU_to_bool (gt_vec_unsigned (a, b)) + then Vector [B0;B1;B0] 0 true + else Vector [B0;B0;B1] 0 true in + read_reg_bitfield XER "SO" >>= fun w__4 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + (c ^^ (Vector [w__4] 0 true)) + +let execute_Isel (RT, RA, RB, BC) = + let a = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let a = to_vec_inc ((64:ii),(0:ii)) in + return a + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun a -> + read_reg_bit CR (add_VII (reset_vector_start BC) (32:ii)) >>= fun w__1 -> + if bitU_to_bool (eq (match w__1 with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + write_reg (access GPR (unsigned (reset_vector_start RT))) a >> + let discard = access GPR (unsigned (reset_vector_start RB)) in + return () + else + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__2 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__2 + +let execute_Andi (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = + set_vector_start 0 + (bitwise_and + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + +let execute_Andis (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = + set_vector_start 0 + (bitwise_and + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (UI ^^ (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + +let execute_Ori (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + (set_vector_start 0 + (bitwise_or + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI))) + +let execute_Oris (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + (set_vector_start 0 + (bitwise_or + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (UI ^^ (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true))))) + +let execute_Xori (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + (set_vector_start 0 + (bitwise_xor + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI))) + +let execute_Xoris (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + (set_vector_start 0 + (bitwise_xor + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (UI ^^ (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true))))) + +let execute_And (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_and (w__0, w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Xor (RS, RA, RB, Rc) = + let temp = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec (RS, RB)) + then + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = w__0 in + let temp = to_vec_inc ((64:ii),(0:ii)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) (to_vec_inc ((64:ii),(0:ii))) >> + return temp + else + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__1 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__2 -> + let temp = set_vector_start 0 (bitwise_xor (w__1, w__2)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + return temp) >>= fun temp -> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return () + +let execute_Nand (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_not (reset_vector_start (bitwise_and (w__0, w__1)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Or (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_or (w__0, w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Nor (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_not (reset_vector_start (bitwise_or (w__0, w__1)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Eqv (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_xor (w__0, bitwise_not (reset_vector_start w__1))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Andc (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_and (w__0, bitwise_not (reset_vector_start w__1))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Orc (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_or (w__0, bitwise_not (reset_vector_start w__1))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Extsb (RS, RA, Rc) = + let temp = to_vec_inc ((64:ii),(0:ii)) in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (56:ii) >>= fun s -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__0 -> + let temp = update temp (56:ii) (63:ii) w__0 in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (56:ii) + (63:ii) + (slice temp (56:ii) (63:ii)) >> + let temp = update temp (0:ii) (55:ii) (duplicate (s, (56:ii))) in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (0:ii) + (55:ii) + (slice temp (0:ii) (55:ii)) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Extsh (RS, RA, Rc) = + let temp = to_vec_inc ((64:ii),(0:ii)) in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (48:ii) >>= fun s -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__0 -> + let temp = update temp (48:ii) (63:ii) w__0 in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (48:ii) + (63:ii) + (slice temp (48:ii) (63:ii)) >> + let temp = update temp (0:ii) (47:ii) (duplicate (s, (48:ii))) in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (0:ii) + (47:ii) + (slice temp (0:ii) (47:ii)) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Cntlzw (RS, RA, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = to_vec_inc ((64:ii),countLeadingZeroes (reset_vector_start w__0,(32:ii))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Cmpb (RS, RA, RB) = + (foreachM_inc ((0:ii),(7:ii),(1:ii)) () + (fun n _ -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) + ((8:ii) * n) (((8:ii) * n) + (7:ii)) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) + ((8:ii) * n) (((8:ii) * n) + (7:ii)) >>= fun w__1 -> + if bitU_to_bool (eq_vec (w__0, w__1)) + then + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) ((8:ii) * n) + (((8:ii) * n) + (7:ii)) + (Vector [B1;B1;B1;B1;B1;B1;B1;B1] 0 true) + else + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) ((8:ii) * n) + (((8:ii) * n) + (7:ii)) + (to_vec_inc ((8:ii),(0:ii))))) + +let execute_Popcntb (RS, RA) = + (foreachM_inc ((0:ii),(7:ii),(1:ii)) () + (fun i _ -> + let n = (0:ii) in + (foreachM_inc ((0:ii),(7:ii),(1:ii)) n + (fun j n -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (8:ii)) + j) >>= fun w__0 -> + let n = + if bitU_to_bool (eq (match w__0 with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then n + (1:ii) + else n in + return n)) >>= fun n -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (i * (8:ii)) + ((i * (8:ii)) + (7:ii)) + (to_vec_inc ((8:ii),n)))) + +let execute_Popcntw (RS, RA) = + (foreachM_inc ((0:ii),(1:ii),(1:ii)) () + (fun i _ -> + let n = (0:ii) in + (foreachM_inc ((0:ii),(31:ii),(1:ii)) n + (fun j n -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (32:ii)) + j) >>= fun w__0 -> + let n = + if bitU_to_bool (eq (match w__0 with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then n + (1:ii) + else n in + return n)) >>= fun n -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (i * (32:ii)) + ((i * (32:ii)) + (31:ii)) + (to_vec_inc ((32:ii),n)))) + +let execute_Prtyd (RS, RA) = + let s = (0:ii) in + (foreachM_inc ((0:ii),(7:ii),(1:ii)) s + (fun i s -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (8:ii)) + (7:ii)) >>= fun w__0 -> + let s = + match ((if bitU_to_bool (is_one s) + then B1 + else B0) +. w__0) with + | B0 -> (0:ii) + | B1 -> (1:ii) + end in + return s)) >>= fun s -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (Vector [if bitU_to_bool (is_one s) then B1 else B0] 0 true)) + +let execute_Prtyw (RS, RA) = + let s = (0:ii) in + let t = (0:ii) in + (foreachM_inc ((0:ii),(3:ii),(1:ii)) s + (fun i s -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (8:ii)) + (7:ii)) >>= fun w__0 -> + let s = + match ((if bitU_to_bool (is_one s) + then B1 + else B0) +. w__0) with + | B0 -> (0:ii) + | B1 -> (1:ii) + end in + return s)) >>= fun s -> + (foreachM_inc ((4:ii),(7:ii),(1:ii)) t + (fun i t -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (8:ii)) + (7:ii)) >>= fun w__1 -> + let t = + match ((if bitU_to_bool (is_one t) + then B1 + else B0) +. w__1) with + | B0 -> (0:ii) + | B1 -> (1:ii) + end in + return t)) >>= fun t -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (0:ii) + (31:ii) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (Vector [if bitU_to_bool (is_one s) then B1 else B0] 0 true)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (32:ii) + (63:ii) + (set_vector_start 32 + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (Vector [if bitU_to_bool (is_one t) then B1 else B0] 0 true))) + +let execute_Extsw (RS, RA, Rc) = + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (32:ii) >>= fun s -> + let temp = to_vec_inc ((64:ii),(0:ii)) in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + let temp = update temp (32:ii) (63:ii) w__0 in + let temp = update temp (0:ii) (31:ii) (duplicate (s, (32:ii))) in + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return ()) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) temp + +let execute_Cntlzd (RS, RA, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = to_vec_inc ((64:ii),countLeadingZeroes (reset_vector_start w__0,(0:ii))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Popcntd (RS, RA) = + let n = (0:ii) in + (foreachM_inc ((0:ii),(63:ii),(1:ii)) n + (fun i n -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) i >>= fun w__0 -> + let n = + if bitU_to_bool (eq (match w__0 with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then n + (1:ii) + else n in + return n)) >>= fun n -> + write_reg (access GPR (unsigned (reset_vector_start RA))) (to_vec_inc ((64:ii),n)) + +let execute_Bpermd (RS, RA, RB) = + let perm = to_vec_inc ((8:ii),(0:ii)) in + (foreachM_inc ((0:ii),(7:ii),(1:ii)) perm + (fun i perm -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) + ((8:ii) * i) (((8:ii) * i) + (7:ii)) >>= fun index -> + if bitU_to_bool (lt_vec_unsigned (index, to_vec_inc ((8:ii),(64:ii)))) + then + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (unsigned + (reset_vector_start index)) >>= fun w__0 -> + let perm = update_pos perm i w__0 in + return perm + else + let perm = update_pos perm i B0 in + let discard = access GPR (unsigned (reset_vector_start RB)) in + return perm)) >>= fun perm -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (slice perm (0:ii) (7:ii))) + +let execute_Rlwinm (RS, RA, SH, MB, ME, Rc) = + let n = SH in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),unsigned (reset_vector_start n)) in + let m = MASK (add_VII (reset_vector_start MB) (32:ii),add_VII (reset_vector_start ME) (32:ii)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Rlwnm (RS, RA, RB, MB, ME, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (59:ii) (63:ii) >>= fun n -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),unsigned (reset_vector_start n)) in + let m = MASK (add_VII (reset_vector_start MB) (32:ii),add_VII (reset_vector_start ME) (32:ii)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Rlwimi (RS, RA, SH, MB, ME, Rc) = + let n = SH in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),unsigned (reset_vector_start n)) in + let m = MASK (add_VII (reset_vector_start MB) (32:ii),add_VII (reset_vector_start ME) (32:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__2 -> + let temp = + set_vector_start 0 + (bitwise_or (bitwise_and (r, m), bitwise_and (w__2, bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return () + +let execute_Rldicl (RS, RA, sh, mb, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let b = (Vector [access mb (5:ii)] 0 true) ^^ (slice mb (0:ii) (4:ii)) in + let m = MASK (unsigned (reset_vector_start b),(63:ii)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldicr (RS, RA, sh, me, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let e = (Vector [access me (5:ii)] 0 true) ^^ (slice me (0:ii) (4:ii)) in + let m = MASK ((0:ii),unsigned (reset_vector_start e)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldic (RS, RA, sh, mb, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let b = (Vector [access mb (5:ii)] 0 true) ^^ (slice mb (0:ii) (4:ii)) in + let m = + MASK + (unsigned (reset_vector_start b), + unsigned (reset_vector_start (bitwise_not (reset_vector_start n)))) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldcl (RS, RA, RB, mb, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let b = (Vector [access mb (5:ii)] 0 true) ^^ (slice mb (0:ii) (4:ii)) in + let m = MASK (unsigned (reset_vector_start b),(63:ii)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldcr (RS, RA, RB, me, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let e = (Vector [access me (5:ii)] 0 true) ^^ (slice me (0:ii) (4:ii)) in + let m = MASK ((0:ii),unsigned (reset_vector_start e)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldimi (RS, RA, sh, mb, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let b = (Vector [access mb (5:ii)] 0 true) ^^ (slice mb (0:ii) (4:ii)) in + let m = + MASK + (unsigned (reset_vector_start b), + unsigned (reset_vector_start (bitwise_not (reset_vector_start n)))) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__1 -> + let temp = + set_vector_start 0 + (bitwise_or (bitwise_and (r, m), bitwise_and (w__1, bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Slw (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (59:ii) (63:ii) >>= fun n -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),unsigned (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (58:ii) >>= fun w__2 -> + let m = + if bitU_to_bool (eq (match w__2 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK ((32:ii),minus_IVI (63:ii) (reset_vector_start n)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return () + +let execute_Srw (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (59:ii) (63:ii) >>= fun n -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),minus_IVI (64:ii) (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (58:ii) >>= fun w__2 -> + let m = + if bitU_to_bool (eq (match w__2 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK (add_VII (reset_vector_start n) (32:ii),(63:ii)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return () + +let execute_Srawi (RS, RA, SH, Rc) = + let n = SH in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),minus_IVI (64:ii) (reset_vector_start n)) in + let m = MASK (add_VII (reset_vector_start n) (32:ii),(63:ii)) in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (32:ii) >>= fun s -> + let temp = + set_vector_start 0 + (bitwise_or + (bitwise_and (r, m), + bitwise_and (duplicate (s, (64:ii)), bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return ()) >> + write_reg_bitfield + XER "CA" + (if bitU_to_bool (gt_vec_unsigned (n, to_vec_inc ((5:ii),(0:ii)))) + then s &. (~(eq_vec_range (bitwise_and (r, bitwise_not (reset_vector_start m)), (0:ii)))) + else B0) + +let execute_Sraw (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (59:ii) (63:ii) >>= fun n -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),minus_IVI (64:ii) (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (58:ii) >>= fun w__2 -> + let m = + if bitU_to_bool (eq (match w__2 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK (add_VII (reset_vector_start n) (32:ii),(63:ii)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (32:ii) >>= fun s -> + let temp = + set_vector_start 0 + (bitwise_or + (bitwise_and (r, m), + bitwise_and (duplicate (s, (64:ii)), bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return ()) >> + write_reg_bitfield + XER "CA" + (if bitU_to_bool (gt_vec_unsigned (n, to_vec_inc ((5:ii),(0:ii)))) + then s &. (~(eq_vec_range (bitwise_and (r, bitwise_not (reset_vector_start m)), (0:ii)))) + else B0) + +let execute_Sld (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (57:ii) >>= fun w__1 -> + let m = + if bitU_to_bool (eq (match w__1 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK ((0:ii),minus_IVI (63:ii) (reset_vector_start n)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Srd (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,minus_IVI (64:ii) (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (57:ii) >>= fun w__1 -> + let m = + if bitU_to_bool (eq (match w__1 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK (unsigned (reset_vector_start n),(63:ii)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Sradi (RS, RA, sh, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,minus_IVI (64:ii) (reset_vector_start n)) in + let m = MASK (unsigned (reset_vector_start n),(63:ii)) in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (0:ii) >>= fun s -> + let temp = + set_vector_start 0 + (bitwise_or + (bitwise_and (r, m), + bitwise_and (duplicate (s, (64:ii)), bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return ()) >> + write_reg_bitfield + XER "CA" + (if bitU_to_bool (gt_vec_unsigned (n, to_vec_inc ((6:ii),(0:ii)))) + then s &. (~(eq_vec_range (bitwise_and (r, bitwise_not (reset_vector_start m)), (0:ii)))) + else B0) + +let execute_Srad (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,minus_IVI (64:ii) (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (57:ii) >>= fun w__1 -> + let m = + if bitU_to_bool (eq (match w__1 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK (unsigned (reset_vector_start n),(63:ii)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (0:ii) >>= fun s -> + let temp = + set_vector_start 0 + (bitwise_or + (bitwise_and (r, m), + bitwise_and (duplicate (s, (64:ii)), bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return ()) >> + write_reg_bitfield + XER "CA" + (if bitU_to_bool (gt_vec_unsigned (n, to_vec_inc ((6:ii),(0:ii)))) + then s &. (~(eq_vec_range (bitwise_and (r, bitwise_not (reset_vector_start m)), (0:ii)))) + else B0) + +let execute_Cdtbcd (RS, RA) = + (foreachM_inc ((0:ii),(1:ii),(1:ii)) () + (fun i _ -> + let n = i * (32:ii) in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (0:ii)) + (n + (7:ii)) + (to_vec_inc ((8:ii),(0:ii))) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (n + (12:ii)) (n + (21:ii)) >>= fun w__0 -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (8:ii)) + (n + (19:ii)) + (DEC_TO_BCD (reset_vector_start (set_vector_start 0 w__0))) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (n + (22:ii)) (n + (31:ii)) >>= fun w__1 -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (20:ii)) + (n + (31:ii)) + (DEC_TO_BCD (reset_vector_start (set_vector_start 0 w__1))))) + +let execute_Cbcdtd (RS, RA) = + (foreachM_inc ((0:ii),(1:ii),(1:ii)) () + (fun i _ -> + let n = i * (32:ii) in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (0:ii)) + (n + (11:ii)) + (to_vec_inc ((12:ii),(0:ii))) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (n + (8:ii)) (n + (19:ii)) >>= fun w__0 -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (12:ii)) + (n + (21:ii)) + (BCD_TO_DEC (reset_vector_start (set_vector_start 0 w__0))) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (n + (20:ii)) (n + (31:ii)) >>= fun w__1 -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (22:ii)) + (n + (31:ii)) + (BCD_TO_DEC (reset_vector_start (set_vector_start 0 w__1))))) + +let execute_Addg6s (RT, RA, RB) = + let dc = to_vec_inc ((16:ii),(0:ii)) in + (foreachM_inc ((0:ii),(15:ii),(1:ii)) dc + (fun i dc -> + read_reg_range (access GPR (unsigned (reset_vector_start RA))) ((4:ii) * i) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) ((4:ii) * i) (63:ii) >>= fun w__1 -> + let (v, _, co) = + match (addO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v96v', v97v', v98v') -> (v96v',v97v',v98v') + end in + let dc = update_pos dc i (carry_out (reset_vector_start (set_vector_start 0 v),co)) in + return dc)) >>= fun dc -> + let c = + (duplicate (access dc (0:ii), (4:ii))) ^^ + ((duplicate (access dc (1:ii), (4:ii))) ^^ + ((duplicate (access dc (2:ii), (4:ii))) ^^ + ((duplicate (access dc (3:ii), (4:ii))) ^^ + ((duplicate (access dc (4:ii), (4:ii))) ^^ + ((duplicate (access dc (5:ii), (4:ii))) ^^ + ((duplicate (access dc (6:ii), (4:ii))) ^^ + ((duplicate (access dc (7:ii), (4:ii))) ^^ + ((duplicate (access dc (8:ii), (4:ii))) ^^ + ((duplicate (access dc (9:ii), (4:ii))) ^^ + ((duplicate (access dc (10:ii), (4:ii))) ^^ + ((duplicate (access dc (11:ii), (4:ii))) ^^ + ((duplicate (access dc (12:ii), (4:ii))) ^^ + ((duplicate (access dc (13:ii), (4:ii))) ^^ + ((duplicate (access dc (14:ii), (4:ii))) ^^ (duplicate (access dc (15:ii), (4:ii))))))))))))))))) in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 + (bitwise_and + (bitwise_not (reset_vector_start c), + Vector [B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0; + B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1; + B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1; + B0] 0 true))) + +let execute_Mtspr (RS, spr) = + let n = (slice spr (5:ii) (9:ii)) ^^ (slice spr (0:ii) (4:ii)) in + if bitU_to_bool (eq_vec_range (n, (13:ii))) + then trap () + else + if bitU_to_bool (eq_vec_range (n, (1:ii))) + then + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun reg -> + let front = zero_or_undef (reset_vector_start (slice reg (0:ii) (31:ii))) in + let xer_so = access reg (32:ii) in + let xer_ov = access reg (33:ii) in + let xer_ca = access reg (34:ii) in + let mid = zero_or_undef (reset_vector_start (set_vector_start 0 (slice reg (35:ii) (56:ii)))) in + let bot = set_vector_start 0 (slice reg (57:ii) (63:ii)) in + write_reg + XER + (front ^^ + ((Vector [xer_so] 0 true) ^^ + ((Vector [xer_ov] 0 true) ^^ ((Vector [xer_ca] 0 true) ^^ (mid ^^ bot))))) + else + read_reg (access SPR (unsigned (reset_vector_start n))) >>= fun w__0 -> + if bitU_to_bool (eq_range (length (reset_vector_start w__0), (64:ii))) + then + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__1 -> + write_reg (access SPR (unsigned (reset_vector_start n))) w__1 + else + if bitU_to_bool (eq_vec_range (n, (152:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun CTRL -> + return () + else return () + +let execute_Mfspr (RT, spr) = + let n = (slice spr (5:ii) (9:ii)) ^^ (slice spr (0:ii) (4:ii)) in + read_reg (access SPR (unsigned (reset_vector_start n))) >>= fun w__0 -> + if bitU_to_bool (eq_range (length (reset_vector_start w__0), (64:ii))) + then + read_reg (access SPR (unsigned (reset_vector_start n))) >>= fun w__1 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__1 + else + read_reg (access SPR (unsigned (reset_vector_start n))) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Mtcrf (RS, FXM) = + let mask = + (duplicate (access FXM (0:ii), (4:ii))) ^^ + ((duplicate (access FXM (1:ii), (4:ii))) ^^ + ((duplicate (access FXM (2:ii), (4:ii))) ^^ + ((duplicate (access FXM (3:ii), (4:ii))) ^^ + ((duplicate (access FXM (4:ii), (4:ii))) ^^ + ((duplicate (access FXM (5:ii), (4:ii))) ^^ + ((duplicate (access FXM (6:ii), (4:ii))) ^^ (duplicate (access FXM (7:ii), (4:ii))))))))) in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg CR >>= fun w__1 -> + write_reg + CR + (set_vector_start 32 + (bitwise_or + (set_vector_start 0 (bitwise_and (w__0, mask)), + set_vector_start 0 (bitwise_and (w__1, bitwise_not (reset_vector_start mask)))))) + +let execute_Mfcr RT = + read_reg CR >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__0) + +let execute_Mtocrf (RS, FXM) = + let n = (0:ii) in + let count = (0:ii) in + let (count, n) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (count,n) + (fun i (count,n) -> + let (n, count) = + if bitU_to_bool (eq (match (access FXM i) with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + let n = i in + let count = count + (1:ii) in + (n,count) + else (n,count) in + (count,n))) in + if bitU_to_bool (eq_range (count, (1:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RS))) + (((4:ii) * n) + (32:ii)) (((4:ii) * n) + (35:ii)) >>= fun w__0 -> + write_reg_range CR (((4:ii) * n) + (32:ii)) (((4:ii) * n) + (35:ii)) w__0 + else write_reg CR (to_vec_inc_undef (32:ii)) + +let execute_Mfocrf (RT, FXM) = + let n = (0:ii) in + let count = (0:ii) in + let (count, n) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (count,n) + (fun i (count,n) -> + let (n, count) = + if bitU_to_bool (eq (match (access FXM i) with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + let n = i in + let count = count + (1:ii) in + (n,count) + else (n,count) in + (count,n))) in + if bitU_to_bool (eq_range (count, (1:ii))) + then + let temp = to_vec_inc_undef (64:ii) in + read_reg_range CR (((4:ii) * n) + (32:ii)) (((4:ii) * n) + (35:ii)) >>= fun w__0 -> + let temp = update temp (((4:ii) * n) + (32:ii)) (((4:ii) * n) + (35:ii)) w__0 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp + else write_reg (access GPR (unsigned (reset_vector_start RT))) (to_vec_inc_undef (64:ii)) + +let execute_Mcrxr BF = + read_reg_range XER (32:ii) (35:ii) >>= fun w__0 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + w__0 >> + write_reg_range XER (32:ii) (35:ii) (set_vector_start 32 (Vector [B0;B0;B0;B0] 0 true)) + +let execute_Dlmzb (RS, RA, RB, Rc) = return () + +let execute_Macchw (RT, RA, RB, OE, Rc) = return () + +let execute_Macchws (RT, RA, RB, OE, Rc) = return () + +let execute_Macchwu (RT, RA, RB, OE, Rc) = return () + +let execute_Macchwsu (RT, RA, RB, OE, Rc) = return () + +let execute_Machhw (RT, RA, RB, OE, Rc) = return () + +let execute_Machhws (RT, RA, RB, OE, Rc) = return () + +let execute_Machhwu (RT, RA, RB, OE, Rc) = return () + +let execute_Machhwsu (RT, RA, RB, OE, Rc) = return () + +let execute_Maclhw (RT, RA, RB, OE, Rc) = return () + +let execute_Maclhws (RT, RA, RB, OE, Rc) = return () + +let execute_Maclhwu (RT, RA, RB, OE, Rc) = return () + +let execute_Maclhwsu (RT, RA, RB, OE, Rc) = return () + +let execute_Mulchw (RT, RA, RB, Rc) = return () + +let execute_Mulchwu (RT, RA, RB, Rc) = return () + +let execute_Mulhhw (RT, RA, RB, Rc) = return () + +let execute_Mulhhwu (RT, RA, RB, Rc) = return () + +let execute_Mullhw (RT, RA, RB, Rc) = return () + +let execute_Mullhwu (RT, RA, RB, Rc) = return () + +let execute_Nmacchw (RT, RA, RB, OE, Rc) = return () + +let execute_Nmacchws (RT, RA, RB, OE, Rc) = return () + +let execute_Nmachhw (RT, RA, RB, OE, Rc) = return () + +let execute_Nmachhws (RT, RA, RB, OE, Rc) = return () + +let execute_Nmaclhw (RT, RA, RB, OE, Rc) = return () + +let execute_Nmaclhws (RT, RA, RB, OE, Rc) = return () + +let execute_Icbi (RA, RB) = return () + +let execute_Icbt (CT, RA, RB) = return () + +let execute_Dcba (RA, RB) = return () + +let execute_Dcbt (TH, RA, RB) = return () + +let execute_Dcbtst (TH, RA, RB) = return () + +let execute_Dcbz (RA, RB) = return () + +let execute_Dcbst (RA, RB) = return () + +let execute_Dcbf (L, RA, RB) = return () + +let execute_Isync () = I_Sync () + +let execute_Lbarx (RT, RA, RB, EH) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr_reserve (reset_vector_start EA,(1:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lharx (RT, RA, RB, EH) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr_reserve (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lwarx (RT, RA, RB, EH) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr_reserve (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Stbcx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA_cond (reset_vector_start EA,(1:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + MEMw_conditional (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__2)) >>= fun status -> + read_reg_bitfield XER "SO" >>= fun w__3 -> + let CR0 = (Vector [B0;B0] 0 true) ^^ ((Vector [status] 0 true) ^^ (Vector [w__3] 0 true)) in + return () + +let execute_Sthcx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA_cond (reset_vector_start EA,(2:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__2 -> + MEMw_conditional (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__2)) >>= fun status -> + read_reg_bitfield XER "SO" >>= fun w__3 -> + let CR0 = (Vector [B0;B0] 0 true) ^^ ((Vector [status] 0 true) ^^ (Vector [w__3] 0 true)) in + return () + +let execute_Stwcx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA_cond (reset_vector_start EA,(4:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__2 -> + MEMw_conditional (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__2)) >>= fun status -> + read_reg_bitfield XER "SO" >>= fun w__3 -> + let CR0 = (Vector [B0;B0] 0 true) ^^ ((Vector [status] 0 true) ^^ (Vector [w__3] 0 true)) in + return () + +let execute_Ldarx (RT, RA, RB, EH) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr_reserve (reset_vector_start EA,(8:ii)) >>= fun w__2 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__2 + +let execute_Stdcx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA_cond (reset_vector_start EA,(8:ii)) >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__2 -> + MEMw_conditional (reset_vector_start EA,(8:ii),reset_vector_start w__2) >>= fun status -> + read_reg_bitfield XER "SO" >>= fun w__3 -> + let CR0 = (Vector [B0;B0] 0 true) ^^ ((Vector [status] 0 true) ^^ (Vector [w__3] 0 true)) in + return () + +let execute_Sync L = + match L with | Vector [B0;B0] _ _ -> H_Sync () | Vector [B0;B1] _ _ -> LW_Sync () end + +let execute_Eieio () = EIEIO_Sync () + +let execute_Wait WC = return () + +let execute = function + + | B (LI,AA,LK) -> execute_B (LI,AA,LK) + | Bc (BO,BI,BD,AA,LK) -> execute_Bc (BO,BI,BD,AA,LK) + | Bclr (BO,BI,BH,LK) -> execute_Bclr (BO,BI,BH,LK) + | Bcctr (BO,BI,BH,LK) -> execute_Bcctr (BO,BI,BH,LK) + | Crand (BT,BA,BB) -> execute_Crand (BT,BA,BB) + | Crnand (BT,BA,BB) -> execute_Crnand (BT,BA,BB) + | Cror (BT,BA,BB) -> execute_Cror (BT,BA,BB) + | Crxor (BT,BA,BB) -> execute_Crxor (BT,BA,BB) + | Crnor (BT,BA,BB) -> execute_Crnor (BT,BA,BB) + | Creqv (BT,BA,BB) -> execute_Creqv (BT,BA,BB) + | Crandc (BT,BA,BB) -> execute_Crandc (BT,BA,BB) + | Crorc (BT,BA,BB) -> execute_Crorc (BT,BA,BB) + | Mcrf (BF,BFA) -> execute_Mcrf (BF,BFA) + | Sc (LEV) -> execute_Sc (LEV) + | Scv (LEV) -> execute_Scv (LEV) + | Lbz (RT,RA,D) -> execute_Lbz (RT,RA,D) + | Lbzx (RT,RA,RB) -> execute_Lbzx (RT,RA,RB) + | Lbzu (RT,RA,D) -> execute_Lbzu (RT,RA,D) + | Lbzux (RT,RA,RB) -> execute_Lbzux (RT,RA,RB) + | Lhz (RT,RA,D) -> execute_Lhz (RT,RA,D) + | Lhzx (RT,RA,RB) -> execute_Lhzx (RT,RA,RB) + | Lhzu (RT,RA,D) -> execute_Lhzu (RT,RA,D) + | Lhzux (RT,RA,RB) -> execute_Lhzux (RT,RA,RB) + | Lha (RT,RA,D) -> execute_Lha (RT,RA,D) + | Lhax (RT,RA,RB) -> execute_Lhax (RT,RA,RB) + | Lhau (RT,RA,D) -> execute_Lhau (RT,RA,D) + | Lhaux (RT,RA,RB) -> execute_Lhaux (RT,RA,RB) + | Lwz (RT,RA,D) -> execute_Lwz (RT,RA,D) + | Lwzx (RT,RA,RB) -> execute_Lwzx (RT,RA,RB) + | Lwzu (RT,RA,D) -> execute_Lwzu (RT,RA,D) + | Lwzux (RT,RA,RB) -> execute_Lwzux (RT,RA,RB) + | Lwa (RT,RA,DS) -> execute_Lwa (RT,RA,DS) + | Lwax (RT,RA,RB) -> execute_Lwax (RT,RA,RB) + | Lwaux (RT,RA,RB) -> execute_Lwaux (RT,RA,RB) + | Ld (RT,RA,DS) -> execute_Ld (RT,RA,DS) + | Ldx (RT,RA,RB) -> execute_Ldx (RT,RA,RB) + | Ldu (RT,RA,DS) -> execute_Ldu (RT,RA,DS) + | Ldux (RT,RA,RB) -> execute_Ldux (RT,RA,RB) + | Stb (RS,RA,D) -> execute_Stb (RS,RA,D) + | Stbx (RS,RA,RB) -> execute_Stbx (RS,RA,RB) + | Stbu (RS,RA,D) -> execute_Stbu (RS,RA,D) + | Stbux (RS,RA,RB) -> execute_Stbux (RS,RA,RB) + | Sth (RS,RA,D) -> execute_Sth (RS,RA,D) + | Sthx (RS,RA,RB) -> execute_Sthx (RS,RA,RB) + | Sthu (RS,RA,D) -> execute_Sthu (RS,RA,D) + | Sthux (RS,RA,RB) -> execute_Sthux (RS,RA,RB) + | Stw (RS,RA,D) -> execute_Stw (RS,RA,D) + | Stwx (RS,RA,RB) -> execute_Stwx (RS,RA,RB) + | Stwu (RS,RA,D) -> execute_Stwu (RS,RA,D) + | Stwux (RS,RA,RB) -> execute_Stwux (RS,RA,RB) + | Std (RS,RA,DS) -> execute_Std (RS,RA,DS) + | Stdx (RS,RA,RB) -> execute_Stdx (RS,RA,RB) + | Stdu (RS,RA,DS) -> execute_Stdu (RS,RA,DS) + | Stdux (RS,RA,RB) -> execute_Stdux (RS,RA,RB) + | Lhbrx (RT,RA,RB) -> execute_Lhbrx (RT,RA,RB) + | Sthbrx (RS,RA,RB) -> execute_Sthbrx (RS,RA,RB) + | Lwbrx (RT,RA,RB) -> execute_Lwbrx (RT,RA,RB) + | Stwbrx (RS,RA,RB) -> execute_Stwbrx (RS,RA,RB) + | Ldbrx (RT,RA,RB) -> execute_Ldbrx (RT,RA,RB) + | Stdbrx (RS,RA,RB) -> execute_Stdbrx (RS,RA,RB) + | Lmw (RT,RA,D) -> execute_Lmw (RT,RA,D) + | Stmw (RS,RA,D) -> execute_Stmw (RS,RA,D) + | Lswi (RT,RA,NB) -> execute_Lswi (RT,RA,NB) + | Lswx (RT,RA,RB) -> execute_Lswx (RT,RA,RB) + | Stswi (RS,RA,NB) -> execute_Stswi (RS,RA,NB) + | Stswx (RS,RA,RB) -> execute_Stswx (RS,RA,RB) + | Addi (RT,RA,SI) -> execute_Addi (RT,RA,SI) + | Addis (RT,RA,SI) -> execute_Addis (RT,RA,SI) + | Add (RT,RA,RB,OE,Rc) -> execute_Add (RT,RA,RB,OE,Rc) + | Subf (RT,RA,RB,OE,Rc) -> execute_Subf (RT,RA,RB,OE,Rc) + | Addic (RT,RA,SI) -> execute_Addic (RT,RA,SI) + | AddicDot (RT,RA,SI) -> execute_AddicDot (RT,RA,SI) + | Subfic (RT,RA,SI) -> execute_Subfic (RT,RA,SI) + | Addc (RT,RA,RB,OE,Rc) -> execute_Addc (RT,RA,RB,OE,Rc) + | Subfc (RT,RA,RB,OE,Rc) -> execute_Subfc (RT,RA,RB,OE,Rc) + | Adde (RT,RA,RB,OE,Rc) -> execute_Adde (RT,RA,RB,OE,Rc) + | Subfe (RT,RA,RB,OE,Rc) -> execute_Subfe (RT,RA,RB,OE,Rc) + | Addme (RT,RA,OE,Rc) -> execute_Addme (RT,RA,OE,Rc) + | Subfme (RT,RA,OE,Rc) -> execute_Subfme (RT,RA,OE,Rc) + | Addze (RT,RA,OE,Rc) -> execute_Addze (RT,RA,OE,Rc) + | Subfze (RT,RA,OE,Rc) -> execute_Subfze (RT,RA,OE,Rc) + | Neg (RT,RA,OE,Rc) -> execute_Neg (RT,RA,OE,Rc) + | Mulli (RT,RA,SI) -> execute_Mulli (RT,RA,SI) + | Mullw (RT,RA,RB,OE,Rc) -> execute_Mullw (RT,RA,RB,OE,Rc) + | Mulhw (RT,RA,RB,Rc) -> execute_Mulhw (RT,RA,RB,Rc) + | Mulhwu (RT,RA,RB,Rc) -> execute_Mulhwu (RT,RA,RB,Rc) + | Divw (RT,RA,RB,OE,Rc) -> execute_Divw (RT,RA,RB,OE,Rc) + | Divwu (RT,RA,RB,OE,Rc) -> execute_Divwu (RT,RA,RB,OE,Rc) + | Divwe (RT,RA,RB,OE,Rc) -> execute_Divwe (RT,RA,RB,OE,Rc) + | Divweu (RT,RA,RB,OE,Rc) -> execute_Divweu (RT,RA,RB,OE,Rc) + | Mulld (RT,RA,RB,OE,Rc) -> execute_Mulld (RT,RA,RB,OE,Rc) + | Mulhd (RT,RA,RB,Rc) -> execute_Mulhd (RT,RA,RB,Rc) + | Mulhdu (RT,RA,RB,Rc) -> execute_Mulhdu (RT,RA,RB,Rc) + | Divd (RT,RA,RB,OE,Rc) -> execute_Divd (RT,RA,RB,OE,Rc) + | Divdu (RT,RA,RB,OE,Rc) -> execute_Divdu (RT,RA,RB,OE,Rc) + | Divde (RT,RA,RB,OE,Rc) -> execute_Divde (RT,RA,RB,OE,Rc) + | Divdeu (RT,RA,RB,OE,Rc) -> execute_Divdeu (RT,RA,RB,OE,Rc) + | Cmpi (BF,L,RA,SI) -> execute_Cmpi (BF,L,RA,SI) + | Cmp (BF,L,RA,RB) -> execute_Cmp (BF,L,RA,RB) + | Cmpli (BF,L,RA,UI) -> execute_Cmpli (BF,L,RA,UI) + | Cmpl (BF,L,RA,RB) -> execute_Cmpl (BF,L,RA,RB) + | Isel (RT,RA,RB,BC) -> execute_Isel (RT,RA,RB,BC) + | Andi (RS,RA,UI) -> execute_Andi (RS,RA,UI) + | Andis (RS,RA,UI) -> execute_Andis (RS,RA,UI) + | Ori (RS,RA,UI) -> execute_Ori (RS,RA,UI) + | Oris (RS,RA,UI) -> execute_Oris (RS,RA,UI) + | Xori (RS,RA,UI) -> execute_Xori (RS,RA,UI) + | Xoris (RS,RA,UI) -> execute_Xoris (RS,RA,UI) + | And (RS,RA,RB,Rc) -> execute_And (RS,RA,RB,Rc) + | Xor (RS,RA,RB,Rc) -> execute_Xor (RS,RA,RB,Rc) + | Nand (RS,RA,RB,Rc) -> execute_Nand (RS,RA,RB,Rc) + | Or (RS,RA,RB,Rc) -> execute_Or (RS,RA,RB,Rc) + | Nor (RS,RA,RB,Rc) -> execute_Nor (RS,RA,RB,Rc) + | Eqv (RS,RA,RB,Rc) -> execute_Eqv (RS,RA,RB,Rc) + | Andc (RS,RA,RB,Rc) -> execute_Andc (RS,RA,RB,Rc) + | Orc (RS,RA,RB,Rc) -> execute_Orc (RS,RA,RB,Rc) + | Extsb (RS,RA,Rc) -> execute_Extsb (RS,RA,Rc) + | Extsh (RS,RA,Rc) -> execute_Extsh (RS,RA,Rc) + | Cntlzw (RS,RA,Rc) -> execute_Cntlzw (RS,RA,Rc) + | Cmpb (RS,RA,RB) -> execute_Cmpb (RS,RA,RB) + | Popcntb (RS,RA) -> execute_Popcntb (RS,RA) + | Popcntw (RS,RA) -> execute_Popcntw (RS,RA) + | Prtyd (RS,RA) -> execute_Prtyd (RS,RA) + | Prtyw (RS,RA) -> execute_Prtyw (RS,RA) + | Extsw (RS,RA,Rc) -> execute_Extsw (RS,RA,Rc) + | Cntlzd (RS,RA,Rc) -> execute_Cntlzd (RS,RA,Rc) + | Popcntd (RS,RA) -> execute_Popcntd (RS,RA) + | Bpermd (RS,RA,RB) -> execute_Bpermd (RS,RA,RB) + | Rlwinm (RS,RA,SH,MB,ME,Rc) -> execute_Rlwinm (RS,RA,SH,MB,ME,Rc) + | Rlwnm (RS,RA,RB,MB,ME,Rc) -> execute_Rlwnm (RS,RA,RB,MB,ME,Rc) + | Rlwimi (RS,RA,SH,MB,ME,Rc) -> execute_Rlwimi (RS,RA,SH,MB,ME,Rc) + | Rldicl (RS,RA,sh,mb,Rc) -> execute_Rldicl (RS,RA,sh,mb,Rc) + | Rldicr (RS,RA,sh,me,Rc) -> execute_Rldicr (RS,RA,sh,me,Rc) + | Rldic (RS,RA,sh,mb,Rc) -> execute_Rldic (RS,RA,sh,mb,Rc) + | Rldcl (RS,RA,RB,mb,Rc) -> execute_Rldcl (RS,RA,RB,mb,Rc) + | Rldcr (RS,RA,RB,me,Rc) -> execute_Rldcr (RS,RA,RB,me,Rc) + | Rldimi (RS,RA,sh,mb,Rc) -> execute_Rldimi (RS,RA,sh,mb,Rc) + | Slw (RS,RA,RB,Rc) -> execute_Slw (RS,RA,RB,Rc) + | Srw (RS,RA,RB,Rc) -> execute_Srw (RS,RA,RB,Rc) + | Srawi (RS,RA,SH,Rc) -> execute_Srawi (RS,RA,SH,Rc) + | Sraw (RS,RA,RB,Rc) -> execute_Sraw (RS,RA,RB,Rc) + | Sld (RS,RA,RB,Rc) -> execute_Sld (RS,RA,RB,Rc) + | Srd (RS,RA,RB,Rc) -> execute_Srd (RS,RA,RB,Rc) + | Sradi (RS,RA,sh,Rc) -> execute_Sradi (RS,RA,sh,Rc) + | Srad (RS,RA,RB,Rc) -> execute_Srad (RS,RA,RB,Rc) + | Cdtbcd (RS,RA) -> execute_Cdtbcd (RS,RA) + | Cbcdtd (RS,RA) -> execute_Cbcdtd (RS,RA) + | Addg6s (RT,RA,RB) -> execute_Addg6s (RT,RA,RB) + | Mtspr (RS,spr) -> execute_Mtspr (RS,spr) + | Mfspr (RT,spr) -> execute_Mfspr (RT,spr) + | Mtcrf (RS,FXM) -> execute_Mtcrf (RS,FXM) + | Mfcr (RT) -> execute_Mfcr (RT) + | Mtocrf (RS,FXM) -> execute_Mtocrf (RS,FXM) + | Mfocrf (RT,FXM) -> execute_Mfocrf (RT,FXM) + | Mcrxr (BF) -> execute_Mcrxr (BF) + | Dlmzb (RS,RA,RB,Rc) -> execute_Dlmzb (RS,RA,RB,Rc) + | Macchw (RT,RA,RB,OE,Rc) -> execute_Macchw (RT,RA,RB,OE,Rc) + | Macchws (RT,RA,RB,OE,Rc) -> execute_Macchws (RT,RA,RB,OE,Rc) + | Macchwu (RT,RA,RB,OE,Rc) -> execute_Macchwu (RT,RA,RB,OE,Rc) + | Macchwsu (RT,RA,RB,OE,Rc) -> execute_Macchwsu (RT,RA,RB,OE,Rc) + | Machhw (RT,RA,RB,OE,Rc) -> execute_Machhw (RT,RA,RB,OE,Rc) + | Machhws (RT,RA,RB,OE,Rc) -> execute_Machhws (RT,RA,RB,OE,Rc) + | Machhwu (RT,RA,RB,OE,Rc) -> execute_Machhwu (RT,RA,RB,OE,Rc) + | Machhwsu (RT,RA,RB,OE,Rc) -> execute_Machhwsu (RT,RA,RB,OE,Rc) + | Maclhw (RT,RA,RB,OE,Rc) -> execute_Maclhw (RT,RA,RB,OE,Rc) + | Maclhws (RT,RA,RB,OE,Rc) -> execute_Maclhws (RT,RA,RB,OE,Rc) + | Maclhwu (RT,RA,RB,OE,Rc) -> execute_Maclhwu (RT,RA,RB,OE,Rc) + | Maclhwsu (RT,RA,RB,OE,Rc) -> execute_Maclhwsu (RT,RA,RB,OE,Rc) + | Mulchw (RT,RA,RB,Rc) -> execute_Mulchw (RT,RA,RB,Rc) + | Mulchwu (RT,RA,RB,Rc) -> execute_Mulchwu (RT,RA,RB,Rc) + | Mulhhw (RT,RA,RB,Rc) -> execute_Mulhhw (RT,RA,RB,Rc) + | Mulhhwu (RT,RA,RB,Rc) -> execute_Mulhhwu (RT,RA,RB,Rc) + | Mullhw (RT,RA,RB,Rc) -> execute_Mullhw (RT,RA,RB,Rc) + | Mullhwu (RT,RA,RB,Rc) -> execute_Mullhwu (RT,RA,RB,Rc) + | Nmacchw (RT,RA,RB,OE,Rc) -> execute_Nmacchw (RT,RA,RB,OE,Rc) + | Nmacchws (RT,RA,RB,OE,Rc) -> execute_Nmacchws (RT,RA,RB,OE,Rc) + | Nmachhw (RT,RA,RB,OE,Rc) -> execute_Nmachhw (RT,RA,RB,OE,Rc) + | Nmachhws (RT,RA,RB,OE,Rc) -> execute_Nmachhws (RT,RA,RB,OE,Rc) + | Nmaclhw (RT,RA,RB,OE,Rc) -> execute_Nmaclhw (RT,RA,RB,OE,Rc) + | Nmaclhws (RT,RA,RB,OE,Rc) -> execute_Nmaclhws (RT,RA,RB,OE,Rc) + | Icbi (RA,RB) -> execute_Icbi (RA,RB) + | Icbt (CT,RA,RB) -> execute_Icbt (CT,RA,RB) + | Dcba (RA,RB) -> execute_Dcba (RA,RB) + | Dcbt (TH,RA,RB) -> execute_Dcbt (TH,RA,RB) + | Dcbtst (TH,RA,RB) -> execute_Dcbtst (TH,RA,RB) + | Dcbz (RA,RB) -> execute_Dcbz (RA,RB) + | Dcbst (RA,RB) -> execute_Dcbst (RA,RB) + | Dcbf (L,RA,RB) -> execute_Dcbf (L,RA,RB) + | Isync -> execute_Isync () + | Lbarx (RT,RA,RB,EH) -> execute_Lbarx (RT,RA,RB,EH) + | Lharx (RT,RA,RB,EH) -> execute_Lharx (RT,RA,RB,EH) + | Lwarx (RT,RA,RB,EH) -> execute_Lwarx (RT,RA,RB,EH) + | Stbcx (RS,RA,RB) -> execute_Stbcx (RS,RA,RB) + | Sthcx (RS,RA,RB) -> execute_Sthcx (RS,RA,RB) + | Stwcx (RS,RA,RB) -> execute_Stwcx (RS,RA,RB) + | Ldarx (RT,RA,RB,EH) -> execute_Ldarx (RT,RA,RB,EH) + | Stdcx (RS,RA,RB) -> execute_Stdcx (RS,RA,RB) + | Sync (L) -> execute_Sync (L) + | Eieio -> execute_Eieio () + | Wait (WC) -> execute_Wait (WC) + end + +let initial_analysis instr = + let iR = [] in + let oR = [] in + let aR = [] in + let ik = IK_simple in + let Nias = [NIAFP_successor] in + let Dia = DIAFP_none in + match instr with + | B (LI,AA,LK) -> + let oR = NIA_fp :: oR in + let iR = if bitU_to_bool AA then CIA_fp :: iR else iR in + let oR = if bitU_to_bool LK then (RFull "LR") :: oR else oR in + (if bitU_to_bool AA + then + return (set_vector_start 0 + (exts ((64:ii),reset_vector_start (LI ^^ (Vector [B0;B0] 0 true))))) + else + read_reg CIA >>= fun w__0 -> + return (set_vector_start 0 + (add_VVV + w__0 + (reset_vector_start (exts ((64:ii),reset_vector_start (LI ^^ (Vector [B0;B0] 0 true)))))))) >>= fun nia' -> + let Nias = [NIAFP_concrete_address (reset_vector_start nia')] in + let ik = IK_simple in + return (aR,oR,iR,Nias,ik) + | Bc (BO,BI,BD,AA,LK) -> + let iR = mode64bit_fp :: iR in + let iR = (RFull "CTR") :: iR in + let oR = if bitU_to_bool (~(access BO (2:ii))) then (RFull "CTR") :: oR else oR in + let iR = (RSliceBit ("CR",add_VII (reset_vector_start BI) (32:ii))) :: iR in + let oR = NIA_fp :: oR in + let iR = if bitU_to_bool AA then CIA_fp :: iR else iR in + (if bitU_to_bool AA + then + return (set_vector_start 0 + (exts ((64:ii),reset_vector_start (BD ^^ (Vector [B0;B0] 0 true))))) + else + read_reg CIA >>= fun w__1 -> + return (set_vector_start 0 + (add_VVV + w__1 + (reset_vector_start (exts ((64:ii),reset_vector_start (BD ^^ (Vector [B0;B0] 0 true)))))))) >>= fun w__2 -> + let Nias = [NIAFP_concrete_address (reset_vector_start w__2);NIAFP_successor] in + let (oR, iR) = + if bitU_to_bool LK + then + let oR = (RFull "LR") :: oR in + let iR = CIA_fp :: iR in + (oR,iR) + else (oR,iR) in + let ik = IK_cond_branch in + return (aR,oR,iR,Nias,ik) + | Bclr (BO,BI,BH,LK) -> + let iR = mode64bit_fp :: iR in + let iR = (RFull "CTR") :: iR in + let oR = if bitU_to_bool (~(access BO (2:ii))) then (RFull "CTR") :: oR else oR in + let iR = (RSliceBit ("CR",add_VII (reset_vector_start BI) (32:ii))) :: iR in + let iR = (RSlice ("LR",(0:ii),(61:ii))) :: iR in + let oR = NIA_fp :: oR in + let Nias = [NIAFP_LR;NIAFP_successor] in + let (oR, iR) = + if bitU_to_bool LK + then + let oR = (RFull "LR") :: oR in + let iR = CIA_fp :: iR in + (oR,iR) + else (oR,iR) in + let ik = IK_cond_branch in + return (aR,oR,iR,Nias,ik) + | Bcctr (BO,BI,BH,LK) -> + let iR = (RSliceBit ("CR",add_VII (reset_vector_start BI) (32:ii))) :: iR in + let iR = (RSlice ("CTR",(0:ii),(61:ii))) :: iR in + let oR = NIA_fp :: oR in + let Nias = [NIAFP_CTR;NIAFP_successor] in + let (oR, iR) = + if bitU_to_bool LK + then + let oR = (RFull "LR") :: oR in + let iR = CIA_fp :: iR in + (oR,iR) + else (oR,iR) in + let ik = IK_cond_branch in + return (aR,oR,iR,Nias,ik) + | Crand (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crnand (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Cror (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crxor (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crnor (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Creqv (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crandc (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crorc (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mcrf (BF,BFA) -> + let iR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BFA))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BFA))) + (35:ii))) :: + iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Sc (LEV) -> + let Nias = if bitU_to_bool (eq_vec_range (LEV, (63:ii))) then [] else [NIAFP_successor] in + return (aR,oR,iR,Nias,ik) + | Scv (LEV) -> return (aR,oR,iR,Nias,ik) + | Lbz (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lbzx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lbzu (RT,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lbzux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhz (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhzx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhzu (RT,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhzux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lha (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhax (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhau (RT,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhaux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwz (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwzx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwzu (RT,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwzux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwa (RT,RA,DS) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwax (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwaux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Ld (RT,RA,DS) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Ldx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Ldu (RT,RA,DS) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Ldux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stb (RS,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stbx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stbu (RS,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stbux (RS,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Sth (RS,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Sthx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Sthu (RS,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Sthux (RS,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stw (RS,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stwx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stwu (RS,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stwux (RS,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Std (RS,RA,DS) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stdx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stdu (RS,RA,DS) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stdux (RS,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lq (RTp,RA,DQ,PT) -> + let iR = bigendianmode_fp :: iR in + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RTp)))) :: + (RFull (access GPRs (add_VII (reset_vector_start RTp) (1:ii)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stq (RSp,RA,DS) -> + let iR = bigendianmode_fp :: iR in + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RSp)))) :: + (RFull (access GPRs (add_VII (reset_vector_start RSp) (1:ii)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lhbrx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Sthbrx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(55:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lwbrx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stwbrx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(55:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(40:ii),(47:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(39:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Ldbrx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stdbrx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(55:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(40:ii),(47:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(39:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(24:ii),(31:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(16:ii),(23:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(8:ii),(15:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(0:ii),(7:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lmw (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let i = (0:ii) in + let aR = iR in + let (i, oR) = + (foreach_inc (unsigned (reset_vector_start RT),(31:ii),(1:ii)) (i,oR) + (fun r (i,oR) -> + let oR = (RFull (access GPRs r)) :: oR in + let i = i + (32:ii) in + (i,oR))) in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stmw (RS,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let i = (0:ii) in + let (i, iR) = + (foreach_inc (unsigned (reset_vector_start RS),(31:ii),(1:ii)) (i,iR) + (fun r (i,iR) -> + let iR = (RSlice (access GPRs r,(32:ii),(63:ii))) :: iR in + let i = i + (32:ii) in + (i,iR))) in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lswi (RT,RA,NB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let r = (0:ii) in + let r = minus_VII (reset_vector_start RT) (1:ii) in + let j = (0:ii) in + let i = (32:ii) in + let (i, j, oR, r) = + (foreach_dec (if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB),(1:ii),(1:ii)) (i,j,oR,r) + (fun n (i,j,oR,r) -> + let (r, oR) = + if bitU_to_bool (eq_range (i, (32:ii))) + then + let r = modulo (r + (1:ii)) (32:ii) in + let oR = (RFull (access GPRs r)) :: oR in + (r,oR) + else (r,oR) in + let oR = (RSlice (access GPRs r,i,i + (7:ii))) :: oR in + let j = j + (8:ii) in + let i = i + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + (i,j,oR,r))) in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lswx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice ("XER",(57:ii),(63:ii))) :: iR in + let aR = iR in + let oR = (foreach_inc ((0:ii),(31:ii),(1:ii)) oR (fun r oR -> (RFull (access GPRs r)) :: oR)) in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stswi (RS,RA,NB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let r = (0:ii) in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let j = (0:ii) in + let i = (32:ii) in + let (i, j, iR, r) = + (foreach_dec (if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB),(1:ii),(1:ii)) (i,j,iR,r) + (fun n (i,j,iR,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + let iR = (RSlice (access GPRs r,i,i + (7:ii))) :: iR in + let j = j + (8:ii) in + let i = i + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + (i,j,iR,r))) in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stswx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let r = (0:ii) in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice ("XER",(57:ii),(63:ii))) :: iR in + let aR = iR in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let i = (32:ii) in + let n_top = unsigned (reset_vector_start (Vector [B1;B1;B1;B1;B1;B1;B1] 0 true)) in + let j = (0:ii) in + let (j, i, iR, r) = + (foreach_dec (n_top,(1:ii),(1:ii)) (j,i,iR,r) + (fun n (j,i,iR,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + let iR = (RSlice (access GPRs r,i,i + (7:ii))) :: iR in + let i = i + (8:ii) in + let j = j + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + (j,i,iR,r))) in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Addi (RT,RA,SI) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Addis (RT,RA,SI) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Add (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subf (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Addic (RT,RA,SI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | AddicDot (RT,RA,SI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: (RField ("XER","CA")) :: oR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + return (aR,oR,iR,Nias,ik) + | Subfic (RT,RA,SI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Addc (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subfc (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Adde (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let iR = (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subfe (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let iR = (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Addme (RT,RA,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subfme (RT,RA,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Addze (RT,RA,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subfze (RT,RA,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Neg (RT,RA,OE,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulli (RT,RA,SI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mullw (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulhw (RT,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulhwu (RT,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divw (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divwu (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divwe (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divweu (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulld (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulhd (RT,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulhdu (RT,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divd (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divdu (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divde (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divdeu (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Cmpi (BF,L,RA,SI) -> + let iR = + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii)) + else RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Cmp (BF,L,RA,RB) -> + let iR = + if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR + else + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = + (RSlice ("CR",unsigned (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Cmpli (BF,L,RA,UI) -> + let iR = + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii)) + else RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Cmpl (BF,L,RA,RB) -> + let iR = + if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR + else + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Isel (RT,RA,RB,BC) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RSliceBit ("CR",add_VII (reset_vector_start BC) (32:ii))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Andi (RS,RA,UI) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: (RField ("XER","SO")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let oR = (RField ("CR","CR0")) :: oR in + return (aR,oR,iR,Nias,ik) + | Andis (RS,RA,UI) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: (RField ("XER","SO")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let oR = (RField ("CR","CR0")) :: oR in + return (aR,oR,iR,Nias,ik) + | Ori (RS,RA,UI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Oris (RS,RA,UI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Xori (RS,RA,UI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Xoris (RS,RA,UI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | And (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Xor (RS,RA,RB,Rc) -> + let (iR, oR) = + if bitU_to_bool (eq_vec (RS, RB)) + then + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + (iR,oR) + else + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + (iR,oR) in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Nand (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Or (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Nor (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Eqv (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Andc (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Orc (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Extsb (RS,RA,Rc) -> + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(56:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(56:ii),(63:ii))) :: oR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(0:ii),(55:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Extsh (RS,RA,Rc) -> + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(48:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(48:ii),(63:ii))) :: oR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(0:ii),(47:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Cntlzw (RS,RA,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Cmpb (RS,RA,RB) -> + let (oR, iR) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (oR,iR) + (fun n (oR,iR) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(8:ii) * n,((8:ii) * n) + (7:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(8:ii) * n,((8:ii) * n) + + (7:ii))) :: + iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(8:ii) * n,((8:ii) * n) + (7:ii))) :: + oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Popcntb (RS,RA) -> + let (oR, iR) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let iR = + (foreach_inc ((0:ii),(7:ii),(1:ii)) iR + (fun j iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (8:ii)) + j)) :: iR)) in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),i * (8:ii),(i * (8:ii)) + (7:ii))) :: + oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Popcntw (RS,RA) -> + let (oR, iR) = + (foreach_inc ((0:ii),(1:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let iR = + (foreach_inc ((0:ii),(31:ii),(1:ii)) iR + (fun j iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (32:ii)) + j)) :: iR)) in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),i * (32:ii),(i * (32:ii)) + + (31:ii))) :: + oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Prtyd (RS,RA) -> + let iR = + (foreach_inc ((0:ii),(7:ii),(1:ii)) iR + (fun i iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (8:ii)) + (7:ii))) :: iR)) in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Prtyw (RS,RA) -> + let iR = + (foreach_inc ((0:ii),(3:ii),(1:ii)) iR + (fun i iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (8:ii)) + (7:ii))) :: iR)) in + let iR = + (foreach_inc ((4:ii),(7:ii),(1:ii)) iR + (fun i iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (8:ii)) + (7:ii))) :: iR)) in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(0:ii),(31:ii))) :: oR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Extsw (RS,RA,Rc) -> + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(32:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Cntlzd (RS,RA,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Popcntd (RS,RA) -> + let iR = + (foreach_inc ((0:ii),(63:ii),(1:ii)) iR + (fun i iR -> (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),i)) :: iR)) in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Bpermd (RS,RA,RB) -> + let (oR, iR) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(8:ii) * i,((8:ii) * i) + (7:ii))) :: + iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Rlwinm (RS,RA,SH,MB,ME,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rlwnm (RS,RA,RB,MB,ME,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(59:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rlwimi (RS,RA,SH,MB,ME,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldicl (RS,RA,sh,mb,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldicr (RS,RA,sh,me,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldic (RS,RA,sh,mb,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldcl (RS,RA,RB,mb,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldcr (RS,RA,RB,me,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldimi (RS,RA,sh,mb,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Slw (RS,RA,RB,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(59:ii),(63:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(58:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Srw (RS,RA,RB,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(59:ii),(63:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(58:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Srawi (RS,RA,SH,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(32:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Sraw (RS,RA,RB,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(59:ii),(63:ii))) :: iR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: + (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(58:ii))) :: + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(32:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Sld (RS,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(57:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Srd (RS,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(57:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Sradi (RS,RA,sh,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(0:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Srad (RS,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(57:ii))) :: + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(0:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Cdtbcd (RS,RA) -> + let (oR, iR) = + (foreach_inc ((0:ii),(1:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let n = i * (32:ii) in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),n + (12:ii),n + (31:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),n + (0:ii),n + (31:ii))) :: oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Cbcdtd (RS,RA) -> + let (oR, iR) = + (foreach_inc ((0:ii),(1:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let n = i * (32:ii) in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),n + (8:ii),n + (31:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),n + (0:ii),n + (31:ii))) :: oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Addg6s (RT,RA,RB) -> + let iR = + (foreach_inc ((0:ii),(15:ii),(1:ii)) iR + (fun i iR -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(4:ii) * i,(63:ii))) :: iR in + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(4:ii) * i,(63:ii))) :: iR)) in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mtspr (RS,spr) -> + let n = (slice spr (5:ii) (9:ii)) ^^ (slice spr (0:ii) (4:ii)) in + let (iR, oR) = + if bitU_to_bool (eq_vec_range (n, (1:ii))) + then + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull "XER") :: oR in + (iR,oR) + else + let iR = (RFull (access SPRs (unsigned (reset_vector_start n)))) :: iR in + let (iR, oR) = + if bitU_to_bool (eq_range (length_spr (unsigned (reset_vector_start n)), (64:ii))) + then + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access SPRs (unsigned (reset_vector_start n)))) :: oR in + (iR,oR) + else + let (iR, oR) = + if bitU_to_bool (eq_vec_range (n, (152:ii))) + then + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let oR = (RFull "CTRL") :: oR in + (iR,oR) + else (iR,oR) in + (iR,oR) in + (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mfspr (RT,spr) -> + let n = (slice spr (5:ii) (9:ii)) ^^ (slice spr (0:ii) (4:ii)) in + let iR = (RFull (access SPRs (unsigned (reset_vector_start n)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mtcrf (RS,FXM) -> + let iR = + (RFull "CR") :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let oR = (RFull "CR") :: oR in + return (aR,oR,iR,Nias,ik) + | Mfcr (RT) -> + let iR = (RFull "CR") :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mtocrf (RS,FXM) -> + let n = (0:ii) in + let count = (0:ii) in + let (count, n) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (count,n) + (fun i (count,n) -> + let (n, count) = + if bitU_to_bool + (eq (match (access FXM i) with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + let n = i in + let count = count + (1:ii) in + (n,count) + else (n,count) in + (count,n))) in + let (oR, iR) = + if bitU_to_bool (eq_range (count, (1:ii))) + then + let oR = (RSlice ("CR",((4:ii) * n) + (32:ii),((4:ii) * n) + (35:ii))) :: oR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),((4:ii) * n) + (32:ii),((4:ii) * + n) + + (35:ii))) :: + iR in + (oR,iR) + else + let oR = (RFull "CR") :: oR in + (oR,iR) in + return (aR,oR,iR,Nias,ik) + | Mfocrf (RT,FXM) -> + let n = (0:ii) in + let count = (0:ii) in + let (count, n) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (count,n) + (fun i (count,n) -> + let (n, count) = + if bitU_to_bool + (eq (match (access FXM i) with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + let n = i in + let count = count + (1:ii) in + (n,count) + else (n,count) in + (count,n))) in + let (iR, oR) = + if bitU_to_bool (eq_range (count, (1:ii))) + then + let iR = (RSlice ("CR",((4:ii) * n) + (32:ii),((4:ii) * n) + (35:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + (iR,oR) + else + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mcrxr (BF) -> + let iR = (RSlice ("XER",(32:ii),(35:ii))) :: iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + (RSlice ("XER",(32:ii),(35:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Dlmzb (RS,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Macchws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Macchwu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Macchwsu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Machhws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Machhwu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Machhwsu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Maclhw (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Maclhws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Maclhwu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Maclhwsu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Mulchw (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mulchwu (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mulhhw (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mulhhwu (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mullhw (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mullhwu (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmacchw (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmacchws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmachhw (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmachhws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmaclhw (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmaclhws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Icbi (RA,RB) -> return (aR,oR,iR,Nias,ik) + | Icbt (CT,RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcba (RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbt (TH,RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbtst (TH,RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbz (RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbst (RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbf (L,RA,RB) -> return (aR,oR,iR,Nias,ik) + | Isync -> + let ik = IK_barrier Barrier_Isync in + return (aR,oR,iR,Nias,ik) + | Lbarx (RT,RA,RB,EH) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_reserve in + return (aR,oR,iR,Nias,ik) + | Lharx (RT,RA,RB,EH) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_reserve in + return (aR,oR,iR,Nias,ik) + | Lwarx (RT,RA,RB,EH) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_reserve in + return (aR,oR,iR,Nias,ik) + | Stbcx (RS,RA,RB) -> + let ik = IK_mem_write Write_conditional in + return (aR,oR,iR,Nias,ik) + | Sthcx (RS,RA,RB) -> + let ik = IK_mem_write Write_conditional in + return (aR,oR,iR,Nias,ik) + | Stwcx (RS,RA,RB) -> + let ik = IK_mem_write Write_conditional in + return (aR,oR,iR,Nias,ik) + | Ldarx (RT,RA,RB,EH) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_reserve in + return (aR,oR,iR,Nias,ik) + | Stdcx (RS,RA,RB) -> + let ik = IK_mem_write Write_conditional in + return (aR,oR,iR,Nias,ik) + | Sync (L) -> + let ik = + match L with + | Vector [B0;B0] _ _ -> IK_barrier Barrier_Sync + | Vector [B0;B1] _ _ -> IK_barrier Barrier_LwSync + end in + return (aR,oR,iR,Nias,ik) + | Eieio -> + let ik = IK_barrier Barrier_Eieio in + return (aR,oR,iR,Nias,ik) + | Wait (WC) -> return (aR,oR,iR,Nias,ik) + end >>= fun (aR, oR, iR, Nias, ik) -> + return (iR,oR,aR,Nias,Dia,ik) + diff --git a/power/power_embed_sequential.lem.fixed b/power/power_embed_sequential.lem.fixed new file mode 100644 index 00000000..7560b0a0 --- /dev/null +++ b/power/power_embed_sequential.lem.fixed @@ -0,0 +1,6743 @@ +(*Generated by Sail from generated/power.sail.*) +open import Pervasives_extra +open import Sail_impl_base +open import State +open import Sail_values +open import Power_embed_types +open import Power_extras_embed_sequential +let DEC_TO_BCD (Vector [p;q;r;s;t;u;v;w;x;y] _ _) = + let a = ((~s) &. (v &. w)) |. ((t &. (v &. (w &. s))) |. (v &. (w &. (~x)))) in + let b = (p &. (s &. (x &. (~t)))) |. ((p &. (~w)) |. (p &. (~v))) in + let c = (q &. (s &. (x &. (~t)))) |. ((q &. (~w)) |. (q &. (~v))) in + let d = r in + let e = (v &. ((~w) &. x)) |. ((s &. (v &. (w &. x))) |. ((~t) &. (v &. (x &. w)))) in + let f = (p &. (t &. (v &. (w &. (x &. (~s)))))) |. ((s &. ((~x) &. v)) |. (s &. (~v))) in + let g = (q &. (t &. (w &. (v &. (x &. (~s)))))) |. ((t &. ((~x) &. v)) |. (t &. (~v))) in + let h = u in + let i = (t &. (v &. (w &. x))) |. ((s &. (v &. (w &. x))) |. (v &. ((~w) &. (~x)))) in + let j = + (p &. ((~s) &. ((~t) &. (w &. v)))) |. + ((s &. (v &. ((~w) &. x))) |. ((p &. (w &. ((~x) &. v))) |. (w &. (~v)))) in + let k = + (q &. ((~s) &. ((~t) &. (v &. w)))) |. + ((t &. (v &. ((~w) &. x))) |. ((q &. (v &. (w &. (~x)))) |. (x &. (~v)))) in + let m = y in + Vector [a;b;c;d;e;f;g;h;i;j;k;m] 0 true + +let BCD_TO_DEC (Vector [a;b;c;d;e;f;g;h;i;j;k;m] _ _) = + let p = (f &. (a &. (i &. (~e)))) |. ((j &. (a &. (~i))) |. (b &. (~a))) in + let q = (g &. (a &. (i &. (~e)))) |. ((k &. (a &. (~i))) |. (c &. (~a))) in + let r = d in + let s = + (j &. ((~a) &. (e &. (~i)))) |. ((f &. ((~i) &. (~e))) |. ((f &. ((~a) &. (~e))) |. (e &. i))) in + let t = + (k &. ((~a) &. (e &. (~i)))) |. ((g &. ((~i) &. (~e))) |. ((g &. ((~a) &. (~e))) |. (a &. i))) in + let u = h in + let v = a |. (e |. i) in + let w = ((~e) &. (j &. (~i))) |. ((e &. i) |. a) in + let x = ((~a) &. (k &. (~i))) |. ((a &. i) |. e) in + let y = m in + Vector [p;q;r;s;t;u;v;w;x;y] 0 true + +let carry_out (_, carry) = carry + +let real_addr x = x + +let mark_as_not_likely_to_be_needed_again_anytime_soon x = () + +let EXTS_EXPLICIT (v, m) = (duplicate (access v (0:ii), m - (length (reset_vector_start v)))) ^^ v + +let MASK (start, stop) = + let mask_temp = to_vec_inc ((64:ii),(0:ii)) in + if bitU_to_bool (gt (start, stop)) + then + let mask_temp = update mask_temp start (63:ii) (duplicate (B1, (64:ii) - start)) in + update mask_temp (0:ii) stop (duplicate (B1, stop + (1:ii))) + else update mask_temp start stop (duplicate (B1, (stop - start) + (1:ii))) + +let ROTL (v, n) = (slice v n (63:ii)) ^^ (slice v (0:ii) (n - (1:ii))) + +let DOUBLE word = + let temp = to_vec_inc ((64:ii),(0:ii)) in + if bitU_to_bool + ((gt_vec_range (slice word (1:ii) (8:ii), (0:ii))) &. + (lt_vec_range (slice word (1:ii) (8:ii), (255:ii)))) + then + let temp = update temp (0:ii) (1:ii) (slice word (0:ii) (1:ii)) in + let temp = update_pos temp (2:ii) (~(access word (1:ii))) in + let temp = update_pos temp (3:ii) (~(access word (1:ii))) in + let temp = update_pos temp (4:ii) (~(access word (1:ii))) in + update + temp (5:ii) (63:ii) + (set_vector_start 5 + ((slice word (2:ii) (31:ii)) ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0] 0 true))) + else + if bitU_to_bool + ((eq_vec_range (slice word (1:ii) (8:ii), (0:ii))) &. + (neq_vec_range (slice word (9:ii) (31:ii), (0:ii)))) + then + let sign = access word (0:ii) in + let exp = (0:ii) - (126:ii) in + let frac = + (Vector [B0] 0 true) ^^ + ((slice word (9:ii) (31:ii)) ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0] 0 true)) in + let (exp, frac) = + (foreach_inc ((0:ii),(52:ii),(1:ii)) (exp,frac) + (fun i (exp,frac) -> + let (frac, exp) = + if bitU_to_bool + (eq (match (access frac (0:ii)) with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + let frac = + update frac (0:ii) (52:ii) ((slice frac (1:ii) (52:ii)) ^^ (Vector [B0] 0 true)) in + let exp = exp - (1:ii) in + (frac,exp) + else (frac,exp) in + (exp,frac))) in + let temp = update_pos temp (0:ii) sign in + let temp = + update + temp (1:ii) (11:ii) + (add_VIV (reset_vector_start (to_vec_inc ((11:ii),exp))) (1023:ii)) in + update temp (12:ii) (63:ii) (set_vector_start 12 (slice frac (1:ii) (52:ii))) + else + let temp = update temp (0:ii) (1:ii) (slice word (0:ii) (1:ii)) in + let temp = update_pos temp (2:ii) (access word (1:ii)) in + let temp = update_pos temp (3:ii) (access word (1:ii)) in + let temp = update_pos temp (4:ii) (access word (1:ii)) in + update + temp (5:ii) (63:ii) + (set_vector_start 5 + ((slice word (2:ii) (31:ii)) ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0] 0 true))) + +let SINGLE frs = + let word = to_vec_inc ((32:ii),(0:ii)) in + if bitU_to_bool + ((gt_vec_range (slice frs (1:ii) (11:ii), (896:ii))) |. + (eq_vec_range (slice frs (1:ii) (63:ii), (0:ii)))) + then + let word = update word (0:ii) (1:ii) (slice frs (0:ii) (1:ii)) in + update word (2:ii) (31:ii) (set_vector_start 2 (slice frs (5:ii) (34:ii))) + else + if bitU_to_bool + ((lteq_range_vec ((874:ii), slice frs (1:ii) (11:ii))) &. + (lteq_vec_range (slice frs (1:ii) (11:ii), (896:ii)))) + then + let sign = access frs (0:ii) in + let exp = + set_vector_start 0 (minus_VIV (reset_vector_start (slice frs (1:ii) (11:ii))) (1023:ii)) in + let frac = (Vector [B1] 0 true) ^^ (slice frs (12:ii) (63:ii)) in + let (exp, frac) = + (foreach_inc ((0:ii),(53:ii),(1:ii)) (exp,frac) + (fun i (exp,frac) -> + let (frac, exp) = + if bitU_to_bool (lt_vec_range (exp, (0:ii) - (126:ii))) + then + let frac = + update frac (0:ii) (52:ii) ((Vector [B0] 0 true) ^^ (slice frac (0:ii) (51:ii))) in + let exp = set_vector_start 0 (add_VIV (reset_vector_start exp) (1:ii)) in + (frac,exp) + else (frac,exp) in + (exp,frac))) in + word + else to_vec_inc_undef (32:ii) + +let Chop (x, y) = slice x (0:ii) y + +let byte_reverse (m', input) = + let output = to_vec_inc (length input,(0:ii)) in + let j = length (reset_vector_start input) in + let (j, output) = + (foreach_inc ((0:ii),length (reset_vector_start input),(8:ii)) (j,output) + (fun i (j,output) -> + let output = update output i (i + (7:ii)) (slice input (j - (7:ii)) j) in + let j = j - (8:ii) in + (j,output))) in + output + +let rec reverse_endianness value = + let width = length (reset_vector_start value) in + let half = quot width (2:ii) in + if bitU_to_bool (eq_range (width, (8:ii))) + then value + else + (reverse_endianness + (reset_vector_start (set_vector_start 0 (slice value half (width - (1:ii)))))) ^^ + (reverse_endianness (reset_vector_start (slice value (0:ii) (half - (1:ii))))) + +let zero_or_undef x = + let out = to_vec_inc (length x,(0:ii)) in + (foreach_inc ((0:ii),(length (reset_vector_start x)) - (1:ii),(1:ii)) out + (fun i out -> update_pos out i (if bitU_to_bool (access x i) then BU else B0))) + +let GPRs = + Vector ["GPR0";"GPR1";"GPR2";"GPR3";"GPR4";"GPR5";"GPR6";"GPR7";"GPR8";"GPR9";"GPR10";"GPR11";"GPR12";"GPR13";"GPR14";"GPR15";"GPR16";"GPR17";"GPR18";"GPR19";"GPR20"; + "GPR21";"GPR22";"GPR23";"GPR24";"GPR25";"GPR26";"GPR27";"GPR28";"GPR29";"GPR30";"GPR31"] 0 true + +let SPRs = + make_indexed_vector + [(1,"XER");(8,"LR");(9,"CTR");(259,"SPRG3");(260,"SPRG4");(261,"SPRG5"); + (262,"SPRG6");(263,"SPRG7")] + "" 0 1024 true + +let DCRs = make_indexed_vector [(0,"DCR0");(1,"DCR1")] "" 0 1024 true + +let length_spr i = + match toNatural i with + | (1:nn) -> (64:ii) + | (8:nn) -> (64:ii) + | (9:nn) -> (64:ii) + | (259:nn) -> (64:ii) + | (260:nn) -> (64:ii) + | (261:nn) -> (64:ii) + | (262:nn) -> (64:ii) + | (263:nn) -> (64:ii) + end + +let DCR = make_indexed_vector [(0,DCR0);(1,DCR1)] (UndefinedRegister 64) 0 1024 true + +let Clamp (k', x, y, z) = + let result = (0:ii) in + (if bitU_to_bool (lt (x, y)) + then + let result = y in + write_reg_bitfield VSCR "SAT" B1 >> + return result + else + if bitU_to_bool (gt (x, z)) + then + let result = z in + write_reg_bitfield VSCR "SAT" B1 >> + return result + else return x) >>= fun result -> + return (to_vec_inc (k',result)) + +let MEMw (ea, size, value) = + read_reg bigendianmode >>= fun w__0 -> + if bitU_to_bool (most_significant w__0) + then + MEMw' + (reset_vector_start ea, + size, + reset_vector_start (reverse_endianness (reset_vector_start value))) + else MEMw' (reset_vector_start ea,size,reset_vector_start value) + +let MEMr (ea, size) = + read_reg bigendianmode >>= fun w__0 -> + if bitU_to_bool (most_significant w__0) + then + MEMr' (reset_vector_start ea,size) >>= fun w__1 -> + return (reverse_endianness (reset_vector_start w__1)) + else MEMr' (reset_vector_start ea,size) + +let MEMr_reserve (ea, size) = + read_reg bigendianmode >>= fun w__0 -> + if bitU_to_bool (most_significant w__0) + then + MEMr_reserve' (reset_vector_start ea,size) >>= fun w__1 -> + return (reverse_endianness (reset_vector_start w__1)) + else MEMr_reserve' (reset_vector_start ea,size) + +let MEMw_conditional (ea, size, value) = + read_reg bigendianmode >>= fun w__0 -> + if bitU_to_bool (most_significant w__0) + then + MEMw_conditional' + (reset_vector_start ea, + size, + reset_vector_start (reverse_endianness (reset_vector_start value))) + else MEMw_conditional' (reset_vector_start ea,size,reset_vector_start value) + +let set_SO_OV overflow = + write_reg_bitfield XER "OV" overflow >> + read_reg_bitfield XER "SO" >>= fun w__0 -> + write_reg_bitfield XER "SO" (w__0 |. overflow) + +let supported_instructions instr = + match instr with + | Sync ((Vector [B1;B0] _ _)) -> Nothing + | Sync ((Vector [B1;B1] _ _)) -> Nothing + | _ -> Just instr + end + +let CIA_fp = RFull "CIA" + +let NIA_fp = RFull "NIA" + +let mode64bit_fp = RFull "mode64bit" + +let bigendianmode_fp = RFull "bigendianmode" + +let set_overflow_cr0 (target_register, new_xer_so) = + let m = (0:ii) in + let c = to_vec_inc ((3:ii),(0:ii)) in + let zero = to_vec_inc ((64:ii),(0:ii)) in + read_reg mode64bit >>= fun w__0 -> + let m = if bitU_to_bool (most_significant w__0) then (0:ii) else (32:ii) in + let c = + if bitU_to_bool (lt_vec_signed (slice target_register m (63:ii), slice zero m (63:ii))) + then Vector [B1;B0;B0] 0 true + else + if bitU_to_bool (gt_vec_signed (slice target_register m (63:ii), slice zero m (63:ii))) + then Vector [B0;B1;B0] 0 true + else Vector [B0;B0;B1] 0 true in + write_reg_field CR "CR0" (set_vector_start 32 (c ^^ (Vector [new_xer_so] 0 true))) + +let SPR = + make_indexed_vector + [(1,XER);(8,LR);(9,CTR);(259,SPRG3);(260,SPRG4);(261,SPRG5); + (262,SPRG6);(263,SPRG7)] + (UndefinedRegister 64) 0 1024 true + +let FPRp = + make_indexed_vector + [(0,RegisterPair FPR0 FPR1);(2,RegisterPair FPR2 FPR3);(4,RegisterPair FPR4 FPR5);(6,RegisterPair FPR6 FPR7);(8,RegisterPair FPR8 FPR9);(10,RegisterPair FPR10 FPR11); + (12,RegisterPair FPR12 FPR13);(14,RegisterPair FPR14 FPR15);(16,RegisterPair FPR16 FPR17);(18,RegisterPair FPR18 FPR19);(20,RegisterPair FPR20 FPR21);(22,RegisterPair FPR22 FPR23); + (24,RegisterPair FPR24 FPR25);(26,RegisterPair FPR26 FPR27);(28,RegisterPair FPR28 FPR29);(30,RegisterPair FPR30 FPR31)] + (UndefinedRegister 128) 0 32 true + +let illegal_instructions_pred instr = + match instr with + | Bcctr (BO,BI,BH,LK) -> ~(access BO (2:ii)) + | Lbzu (RT,RA,D) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lbzux (RT,RA,_) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lhzu (RT,RA,D) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lhzux (RT,RA,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lhau (RT,RA,D) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lhaux (RT,RA,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lwzu (RA,RT,D) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lwzux (RT,RA,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Lwaux (RA,RT,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Ldu (RT,RA,DS) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Ldux (RT,RA,RB) -> (eq_vec_range (RA, (0:ii))) |. (eq_vec (RA, RT)) + | Stbu (RS,RA,D) -> eq_vec_range (RA, (0:ii)) + | Stbux (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Sthu (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Sthux (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Stwu (RS,RA,D) -> eq_vec_range (RA, (0:ii)) + | Stwux (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Stdu (RS,RA,DS) -> eq_vec_range (RA, (0:ii)) + | Stdux (RS,RA,RB) -> eq_vec_range (RA, (0:ii)) + | Lmw (RT,RA,D) -> + (eq_vec_range (RA, (0:ii))) |. ((lteq_vec (RT, RA)) &. (lteq_vec_range (RA, (31:ii)))) + | Lswi (RT,RA,NB) -> + let n = + if bitU_to_bool (~(eq_vec_range (NB, (0:ii)))) + then unsigned (reset_vector_start NB) + else (32:ii) in + let ceil = + if bitU_to_bool (eq_range (modulo n (4:ii), (0:ii))) + then quot n (4:ii) + else (quot n (4:ii)) + (1:ii) in + (lteq_vec (RT, RA)) &. + (lteq_vec + (RA, + minus_VIV + (reset_vector_start (set_vector_start 0 (add_VIV (reset_vector_start RT) ceil))) + (1:ii))) + | Lq (RTp,RA,DQ,Pt) -> + (eq_vec_range (minus_VIV (reset_vector_start RTp) (2:ii), (1:ii))) |. (eq_vec (RTp, RA)) + | Stq (RSp,RA,RS) -> eq_vec_range (minus_VIV (reset_vector_start RSp) (2:ii), (1:ii)) + | Mtspr (RS,spr) -> + ~((eq_vec_range (spr, (1:ii))) |. + ((eq_vec_range (spr, (8:ii))) |. + ((eq_vec_range (spr, (9:ii))) |. + ((eq_vec_range (spr, (256:ii))) |. + ((eq_vec_range (spr, (512:ii))) |. + ((eq_vec_range (spr, (896:ii))) |. (eq_vec_range (spr, (898:ii))))))))) + | _ -> B0 + end + +let GPR = + Vector [GPR0;GPR1;GPR2;GPR3;GPR4;GPR5;GPR6;GPR7;GPR8;GPR9;GPR10;GPR11;GPR12;GPR13;GPR14;GPR15;GPR16;GPR17;GPR18;GPR19;GPR20; + GPR21;GPR22;GPR23;GPR24;GPR25;GPR26;GPR27;GPR28;GPR29;GPR30;GPR31] 0 true + +let FPR = + Vector [FPR0;FPR1;FPR2;FPR3;FPR4;FPR5;FPR6;FPR7;FPR8;FPR9;FPR10;FPR11;FPR12;FPR13;FPR14;FPR15;FPR16;FPR17;FPR18;FPR19;FPR20; + FPR21;FPR22;FPR23;FPR24;FPR25;FPR26;FPR27;FPR28;FPR29;FPR30;FPR31] 0 true + +let VR = + Vector [VR0;VR1;VR2;VR3;VR4;VR5;VR6;VR7;VR8;VR9;VR10;VR11;VR12;VR13;VR14;VR15;VR16;VR17;VR18;VR19;VR20; + VR21;VR22;VR23;VR24;VR25;VR26;VR27;VR28;VR29;VR30;VR31] 0 true + +let decode = function + | ((Vector [B0;B1;B0;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;AA;LK] _ _) as instr) -> + let LI = slice_raw instr (6:ii) (29:ii) in + Just (B (reset_vector_start LI,AA,LK)) + | ((Vector [B0;B1;B0;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;AA;LK] _ _) as instr) -> + let BO = slice_raw instr (6:ii) (10:ii) in + let BI = slice_raw instr (11:ii) (15:ii) in + let BD = slice_raw instr (16:ii) (29:ii) in + Just (Bc (reset_vector_start BO,reset_vector_start BI,reset_vector_start BD,AA,LK)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B0;B0;B0;LK] _ _) as instr) -> + let BO = slice_raw instr (6:ii) (10:ii) in + let BI = slice_raw instr (11:ii) (15:ii) in + let BH = slice_raw instr (19:ii) (20:ii) in + Just (Bclr (reset_vector_start BO,reset_vector_start BI,reset_vector_start BH,LK)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B0;B0;B0;B0;LK] _ _) as instr) -> + let BO = slice_raw instr (6:ii) (10:ii) in + let BI = slice_raw instr (11:ii) (15:ii) in + let BH = slice_raw instr (19:ii) (20:ii) in + Just (Bcctr (reset_vector_start BO,reset_vector_start BI,reset_vector_start BH,LK)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crand (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B1;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crnand (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B0;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Cror (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B0;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crxor (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crnor (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B1;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Creqv (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crandc (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B1;B0;B0;B0;B0;B1;_] _ _) as instr) -> + let BT = slice_raw instr (6:ii) (10:ii) in + let BA = slice_raw instr (11:ii) (15:ii) in + let BB = slice_raw instr (16:ii) (20:ii) in + Just (Crorc (reset_vector_start BT,reset_vector_start BA,reset_vector_start BB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let BFA = slice_raw instr (11:ii) (13:ii) in + Just (Mcrf (reset_vector_start BF,reset_vector_start BFA)) + | ((Vector [B0;B1;B0;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;_] _ _) as instr) -> + let LEV = slice_raw instr (20:ii) (26:ii) in + Just (Sc (reset_vector_start LEV)) + | ((Vector [B0;B1;B0;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1] _ _) as instr) -> + let LEV = slice_raw instr (20:ii) (26:ii) in + Just (Scv (reset_vector_start LEV)) + | ((Vector [B1;B0;B0;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lbz (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lbzx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lbzu (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lbzux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lhz (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhzx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lhzu (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhzux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lha (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhax (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lhau (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhaux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lwz (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwzx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lwzu (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwzux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Lwa (reset_vector_start RT,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwax (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B1;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwaux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Ld (reset_vector_start RT,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Ldx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Ldu (reset_vector_start RT,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Ldux (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stb (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stbx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stbu (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stbux (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Sth (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sthx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Sthu (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sthux (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stw (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stwx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B0;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stwu (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B1;B1;B0;B1;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stwux (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Std (reset_vector_start RS,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stdx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Stdu (reset_vector_start RS,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B1;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stdux (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B1;B1;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RTp = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DQ = slice_raw instr (16:ii) (27:ii) in + let PT = slice_raw instr (28:ii) (31:ii) in + Just (Lq (reset_vector_start RTp,reset_vector_start RA,reset_vector_start DQ,reset_vector_start PT)) + | ((Vector [B1;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0] _ _) as instr) -> + let RSp = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let DS = slice_raw instr (16:ii) (29:ii) in + Just (Stq (reset_vector_start RSp,reset_vector_start RA,reset_vector_start DS)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lhbrx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sthbrx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwbrx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stwbrx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B0;B1;B0;B0;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Ldbrx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B0;B0;B1;B0;B1;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stdbrx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B1;B0;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Lmw (reset_vector_start RT,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B1;B0;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let D = slice_raw instr (16:ii) (31:ii) in + Just (Stmw (reset_vector_start RS,reset_vector_start RA,reset_vector_start D)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B1;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let NB = slice_raw instr (16:ii) (20:ii) in + Just (Lswi (reset_vector_start RT,reset_vector_start RA,reset_vector_start NB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lswx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B1;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let NB = slice_raw instr (16:ii) (20:ii) in + Just (Stswi (reset_vector_start RS,reset_vector_start RA,reset_vector_start NB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B0;B0;B1;B0;B1;B0;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stswx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B0;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Addi (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B0;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Addis (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B0;B0;B0;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Add (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Subf (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B1;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Addic (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B0;B1;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (AddicDot (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B0;B1;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Subfic (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B0;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Addc (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Subfc (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B0;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Adde (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Subfe (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Addme (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Subfme (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B0;B0;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Addze (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Subfze (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B1;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Neg (reset_vector_start RT,reset_vector_start RA,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Mulli (reset_vector_start RT,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mullw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B1;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B0;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B1;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divwe (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B0;B0;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divweu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulld (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhd (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhdu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B1;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divd (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B0;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divdu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B1;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divde (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B0;B0;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Divdeu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B1;B0;B1;B1;_;_;_;_;L;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SI = slice_raw instr (16:ii) (31:ii) in + Just (Cmpi (reset_vector_start BF,L,reset_vector_start RA,reset_vector_start SI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;L;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Cmp (reset_vector_start BF,L,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B0;B1;B0;B1;B0;_;_;_;_;L;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Cmpli (reset_vector_start BF,L,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;L;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B0;B0;B0;B0;B0;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Cmpl (reset_vector_start BF,L,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + let BC = slice_raw instr (21:ii) (25:ii) in + Just (Isel (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,reset_vector_start BC)) + | ((Vector [B0;B1;B1;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Andi (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Andis (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B0;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Ori (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B0;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Oris (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B0;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Xori (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let UI = slice_raw instr (16:ii) (31:ii) in + Just (Xoris (reset_vector_start RS,reset_vector_start RA,reset_vector_start UI)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (And (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B1;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Xor (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B0;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nand (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B1;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Or (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B1;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nor (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Eqv (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Andc (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B0;B1;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Orc (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B0;B1;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Extsb (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B0;B0;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Extsh (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Cntlzw (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B1;B1;B1;B1;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Cmpb (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Popcntb (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Popcntw (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Prtyd (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Prtyw (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B1;B0;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Extsw (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Cntlzd (reset_vector_start RS,reset_vector_start RA,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Popcntd (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B1;B1;B1;B1;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Bpermd (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B0;B1;B0;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SH = slice_raw instr (16:ii) (20:ii) in + let MB = slice_raw instr (21:ii) (25:ii) in + let ME = slice_raw instr (26:ii) (30:ii) in + Just (Rlwinm (reset_vector_start RS,reset_vector_start RA,reset_vector_start SH,reset_vector_start MB,reset_vector_start ME,Rc)) + | ((Vector [B0;B1;B0;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + let MB = slice_raw instr (21:ii) (25:ii) in + let ME = slice_raw instr (26:ii) (30:ii) in + Just (Rlwnm (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,reset_vector_start MB,reset_vector_start ME,Rc)) + | ((Vector [B0;B1;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SH = slice_raw instr (16:ii) (20:ii) in + let MB = slice_raw instr (21:ii) (25:ii) in + let ME = slice_raw instr (26:ii) (30:ii) in + Just (Rlwimi (reset_vector_start RS,reset_vector_start RA,reset_vector_start SH,reset_vector_start MB,reset_vector_start ME,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let mb = slice_raw instr (21:ii) (26:ii) in + Just (Rldicl (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) + (20:ii)) ^^ + (slice instr + (30:ii) + (30:ii))),reset_vector_start mb,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let me = slice_raw instr (21:ii) (26:ii) in + Just (Rldicr (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) + (20:ii)) ^^ + (slice instr + (30:ii) + (30:ii))),reset_vector_start me,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let mb = slice_raw instr (21:ii) (26:ii) in + Just (Rldic (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) (20:ii)) ^^ + (slice instr + (30:ii) (30:ii))),reset_vector_start mb,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + let mb = slice_raw instr (21:ii) (26:ii) in + Just (Rldcl (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,reset_vector_start mb,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B1;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + let me = slice_raw instr (21:ii) (26:ii) in + Just (Rldcr (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,reset_vector_start me,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let mb = slice_raw instr (21:ii) (26:ii) in + Just (Rldimi (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) + (20:ii)) ^^ + (slice instr + (30:ii) + (30:ii))),reset_vector_start mb,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Slw (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Srw (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B1;B1;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let SH = slice_raw instr (16:ii) (20:ii) in + Just (Srawi (reset_vector_start RS,reset_vector_start RA,reset_vector_start SH,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B0;B1;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sraw (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sld (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B1;B1;B0;B1;B1;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Srd (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B1;B1;B1;B0;B1;_;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Sradi (reset_vector_start RS,reset_vector_start RA,reset_vector_start ((slice instr + (16:ii) (20:ii)) ^^ + (slice instr + (30:ii) (30:ii))),Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B0;B0;B1;B1;B0;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Srad (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Cdtbcd (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B1;B1;B1;B0;B1;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + Just (Cbcdtd (reset_vector_start RS,reset_vector_start RA)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B0;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Addg6s (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B1;B0;B1;B0;B0;B1;B1;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let spr = slice_raw instr (11:ii) (20:ii) in + Just (Mtspr (reset_vector_start RS,reset_vector_start spr)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B1;B0;B1;B0;B0;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let spr = slice_raw instr (11:ii) (20:ii) in + Just (Mfspr (reset_vector_start RT,reset_vector_start spr)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;B0;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B0;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let FXM = slice_raw instr (12:ii) (19:ii) in + Just (Mtcrf (reset_vector_start RS,reset_vector_start FXM)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;B0;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B0;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + Just (Mfcr (reset_vector_start RT)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;B1;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B0;B0;B0;_] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let FXM = slice_raw instr (12:ii) (19:ii) in + Just (Mtocrf (reset_vector_start RS,reset_vector_start FXM)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;B1;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B0;B1;B1;_] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let FXM = slice_raw instr (12:ii) (19:ii) in + Just (Mfocrf (reset_vector_start RT,reset_vector_start FXM)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B0;B0;B0;B0;B0;B0;B0;_] _ _) as instr) -> + let BF = slice_raw instr (6:ii) (8:ii) in + Just (Mcrxr (reset_vector_start BF)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B0;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dlmzb (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Macchw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Macchws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Macchwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Macchwsu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Machhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B1;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Machhws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Machhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B1;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Machhwsu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Maclhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B1;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Maclhws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Maclhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B0;B0;B1;B1;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Maclhwsu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulchw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulchwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mulhhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B1;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mullhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B1;B0;B0;B0;B1;B0;B0;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Mullhwu (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B0;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmacchw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B1;B1;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmacchws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B0;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmachhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B0;B0;B1;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmachhws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B0;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmaclhw (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B0;B0;B1;B0;B0;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;OE;B1;B1;B1;B1;B0;B1;B1;B1;B0;Rc] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Nmaclhws (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,OE,Rc)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B1;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Icbi (reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let CT = slice_raw instr (7:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Icbt (reset_vector_start CT,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B1;B1;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcba (reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B1;B0;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let TH = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbt (reset_vector_start TH,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B1;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let TH = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbtst (reset_vector_start TH,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B1;B1;B1;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbz (reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbst (reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let L = slice_raw instr (9:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Dcbf (reset_vector_start L,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B0;B0;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + Just (Isync) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B0;B1;B0;B0;EH] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lbarx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,EH)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B1;B1;B0;B1;B0;B0;EH] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lharx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,EH)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B0;B1;B0;B1;B0;B0;EH] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Lwarx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,EH)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B0;B1;B1;B0;B1;B1;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stbcx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B1;B1;B0;B1;B0;B1;B1;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Sthcx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B0;B0;B1;B0;B1;B1;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stwcx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B1;B0;B1;B0;B1;B0;B0;EH] _ _) as instr) -> + let RT = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Ldarx (reset_vector_start RT,reset_vector_start RA,reset_vector_start RB,EH)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B1;B1;B0;B1;B0;B1;B1;B0;B1] _ _) as instr) -> + let RS = slice_raw instr (6:ii) (10:ii) in + let RA = slice_raw instr (11:ii) (15:ii) in + let RB = slice_raw instr (16:ii) (20:ii) in + Just (Stdcx (reset_vector_start RS,reset_vector_start RA,reset_vector_start RB)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B0;B0;B1;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + let L = slice_raw instr (9:ii) (10:ii) in + Just (Sync (reset_vector_start L)) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B1;B1;B0;B1;B0;B1;B0;B1;B1;B0;_] _ _) as instr) -> + Just (Eieio) + | ((Vector [B0;B1;B1;B1;B1;B1;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;B0;B0;B0;B0;B1;B1;B1;B1;B1;B0;_] _ _) as instr) -> + let WC = slice_raw instr (9:ii) (10:ii) in + Just (Wait (reset_vector_start WC)) + | _ -> Nothing + end + +let illegal_instructions instr = + if bitU_to_bool (illegal_instructions_pred instr) + then Nothing + else Just instr + +let recalculate_lswx_reg_footprint instr = + let iR = [] in + let oR = [] in + let Nias = [NIAFP_successor] in + let Dia = DIAFP_none in + let ik = IK_mem_read Read_plain in + let (RT, RA, RB) = match instr with | Lswx (RT,RA,RB) -> (RT,RA,RB) end in + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let r = (0:ii) in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice ("XER",(57:ii),(63:ii))) :: iR in + let aR = iR in + let r = minus_VII (reset_vector_start RT) (1:ii) in + let i = (32:ii) in + read_reg_range XER (57:ii) (63:ii) >>= fun w__0 -> + let n_top = unsigned (reset_vector_start w__0) in + let (r, oR) = + if bitU_to_bool (eq_range (n_top, (0:ii))) + then + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + (r,oR) + else + let j = (0:ii) in + let n_r = quot n_top (4:ii) in + let n_mod = modulo n_top (4:ii) in + let n_r = if bitU_to_bool (eq_range (n_mod, (0:ii))) then n_r else n_r + (1:ii) in + let (oR, j, r) = + (foreach_dec (n_r,(1:ii),(1:ii)) (oR,j,r) + (fun n (oR,j,r) -> + let r = modulo (r + (1:ii)) (32:ii) in + let j = j + (32:ii) in + let oR = (RFull (access GPRs r)) :: oR in + (oR,j,r))) in + (r,oR) in + return (iR,oR,aR,Nias,Dia,ik) + +let recalculate_stswx_reg_footprint instr = + let iR = [] in + let oR = [] in + let Nias = [NIAFP_successor] in + let Dia = DIAFP_none in + let ik = IK_mem_write Write_plain in + let (RS, RA, RB) = match instr with | Stswx (RS,RA,RB) -> (RS,RA,RB) end in + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let r = (0:ii) in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice ("XER",(57:ii),(63:ii))) :: iR in + let aR = iR in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let i = (32:ii) in + read_reg_range XER (57:ii) (63:ii) >>= fun w__0 -> + let n_top = unsigned (reset_vector_start w__0) in + let j = (0:ii) in + let (j, i, iR, r) = + (foreach_dec (n_top,(1:ii),(1:ii)) (j,i,iR,r) + (fun n (j,i,iR,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + let iR = (RSlice (access GPRs r,i,i + (7:ii))) :: iR in + let i = i + (8:ii) in + let j = j + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + (j,i,iR,r))) in + let ik = IK_mem_write Write_plain in + return (iR,oR,aR,Nias,Dia,ik) + + + +let execute_B (LI, AA, LK) = + (if bitU_to_bool AA + then + write_reg + NIA + (set_vector_start 0 (exts ((64:ii),reset_vector_start (LI ^^ (Vector [B0;B0] 0 true))))) + else + read_reg CIA >>= fun w__0 -> + write_reg + NIA + (set_vector_start 0 + (add_VVV + w__0 + (reset_vector_start (exts ((64:ii),reset_vector_start (LI ^^ (Vector [B0;B0] 0 true)))))))) >> + if bitU_to_bool LK + then + read_reg CIA >>= fun w__1 -> + write_reg LR (set_vector_start 0 (add_VIV w__1 (4:ii))) + else return () + +let execute_Bc (BO, BI, BD, AA, LK) = + let M = (0:ii) in + read_reg mode64bit >>= fun w__0 -> + let M = if bitU_to_bool (most_significant w__0) then (0:ii) else (32:ii) in + read_reg CTR >>= fun ctr_temp -> + (if bitU_to_bool (~(access BO (2:ii))) + then + let ctr_temp = set_vector_start 0 (minus_VIV (reset_vector_start ctr_temp) (1:ii)) in + write_reg CTR ctr_temp >> + return ctr_temp + else return ctr_temp) >>= fun ctr_temp -> + let ctr_ok = + (access BO (2:ii)) |. + ((~(eq_vec_range (slice ctr_temp M (63:ii), (0:ii)))) +. (access BO (3:ii))) in + read_reg_bit CR (add_VII (reset_vector_start BI) (32:ii)) >>= fun w__1 -> + let cond_ok = (access BO (0:ii)) |. (w__1 +. (~(access BO (1:ii)))) in + (if bitU_to_bool (ctr_ok &. cond_ok) + then + if bitU_to_bool AA + then + write_reg + NIA + (set_vector_start 0 (exts ((64:ii),reset_vector_start (BD ^^ (Vector [B0;B0] 0 true))))) + else + read_reg CIA >>= fun w__2 -> + write_reg + NIA + (set_vector_start 0 + (add_VVV + w__2 + (reset_vector_start (exts ((64:ii),reset_vector_start (BD ^^ (Vector [B0;B0] 0 true))))))) + else return ()) >> + if bitU_to_bool LK + then + read_reg CIA >>= fun w__3 -> + write_reg LR (set_vector_start 0 (add_VIV w__3 (4:ii))) + else return () + +let execute_Bclr (BO, BI, BH, LK) = + let M = (0:ii) in + read_reg mode64bit >>= fun w__0 -> + let M = if bitU_to_bool (most_significant w__0) then (0:ii) else (32:ii) in + read_reg CTR >>= fun ctr_temp -> + (if bitU_to_bool (~(access BO (2:ii))) + then + let ctr_temp = set_vector_start 0 (minus_VIV (reset_vector_start ctr_temp) (1:ii)) in + write_reg CTR ctr_temp >> + return ctr_temp + else return ctr_temp) >>= fun ctr_temp -> + let ctr_ok = + (access BO (2:ii)) |. + ((~(eq_vec_range (slice ctr_temp M (63:ii), (0:ii)))) +. (access BO (3:ii))) in + read_reg_bit CR (add_VII (reset_vector_start BI) (32:ii)) >>= fun w__1 -> + let cond_ok = (access BO (0:ii)) |. (w__1 +. (~(access BO (1:ii)))) in + (if bitU_to_bool (ctr_ok &. cond_ok) + then + read_reg_range LR (0:ii) (61:ii) >>= fun w__2 -> + write_reg NIA (w__2 ^^ (Vector [B0;B0] 0 true)) + else return ()) >> + if bitU_to_bool LK + then + read_reg CIA >>= fun w__3 -> + write_reg LR (set_vector_start 0 (add_VIV w__3 (4:ii))) + else return () + +let execute_Bcctr (BO, BI, BH, LK) = + read_reg_bit CR (add_VII (reset_vector_start BI) (32:ii)) >>= fun w__0 -> + let cond_ok = (access BO (0:ii)) |. (w__0 +. (~(access BO (1:ii)))) in + (if bitU_to_bool cond_ok + then + read_reg_range CTR (0:ii) (61:ii) >>= fun w__1 -> + write_reg NIA (w__1 ^^ (Vector [B0;B0] 0 true)) + else return ()) >> + if bitU_to_bool LK + then + read_reg CIA >>= fun w__2 -> + write_reg LR (set_vector_start 0 (add_VIV w__2 (4:ii))) + else return () + +let execute_Crand (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 &. w__1) + +let execute_Crnand (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (~(w__0 &. w__1)) + +let execute_Cror (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 |. w__1) + +let execute_Crxor (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 +. w__1) + +let execute_Crnor (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (~(w__0 |. w__1)) + +let execute_Creqv (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 +. (~w__1)) + +let execute_Crandc (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 &. (~w__1)) + +let execute_Crorc (BT, BA, BB) = + read_reg_bit CR (add_VII (reset_vector_start BA) (32:ii)) >>= fun w__0 -> + read_reg_bit CR (add_VII (reset_vector_start BB) (32:ii)) >>= fun w__1 -> + write_reg_bit CR (add_VII (reset_vector_start BT) (32:ii)) (w__0 |. (~w__1)) + +let execute_Mcrf (BF, BFA) = + read_reg_range CR + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BFA))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BFA))) (35:ii)) >>= fun w__0 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + w__0 + +let execute_Sc LEV = return () + +let execute_Scv LEV = return () + +let execute_Lbz (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMr (reset_vector_start EA,(1:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lbzx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(1:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lbzu (RT, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(1:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lbzux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(1:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lhz (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lhzx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lhzu (RT, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lhzux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lha (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__1))) + +let execute_Lhax (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__2))) + +let execute_Lhau (RT, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__1))) + +let execute_Lhaux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__2))) + +let execute_Lwz (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lwzx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lwzu (RT, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1) + +let execute_Lwzux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lwa (RT, RA, DS) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start b) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__1 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__1))) + +let execute_Lwax (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__2))) + +let execute_Lwaux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start w__2))) + +let execute_Ld (RT, RA, DS) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start b) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + MEMr (reset_vector_start EA,(8:ii)) >>= fun w__1 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__1 + +let execute_Ldx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(8:ii)) >>= fun w__2 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__2 + +let execute_Ldu (RT, RA, DS) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(8:ii)) >>= fun w__1 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__1 + +let execute_Ldux (RT, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + MEMr (reset_vector_start EA,(8:ii)) >>= fun w__2 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__2 + +let execute_Stb (RS, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(1:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Stbx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(1:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Stbu (RS, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(1:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Stbux (RS, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(1:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Sth (RS, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Sthx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Sthu (RS, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Sthux (RS, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Stw (RS, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Stwx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Stwu (RS, RA, D) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start w__0) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__1)) + +let execute_Stwux (RS, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__2 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__2)) + +let execute_Std (RS, RA, DS) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start b) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__1 -> + MEMw (reset_vector_start EA,(8:ii),reset_vector_start w__1) + +let execute_Stdx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__2 -> + MEMw (reset_vector_start EA,(8:ii),reset_vector_start w__2) + +let execute_Stdu (RS, RA, DS) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let EA = + set_vector_start 0 + (add_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start (DS ^^ (Vector [B0;B0] 0 true)))))) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__1 -> + MEMw (reset_vector_start EA,(8:ii),reset_vector_start w__1) + +let execute_Stdux (RS, RA, RB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) EA >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__2 -> + MEMw (reset_vector_start EA,(8:ii),reset_vector_start w__2) + +let execute_Lhbrx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(2:ii)) >>= fun load_data -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + ((slice load_data (8:ii) (15:ii)) ^^ (slice load_data (0:ii) (7:ii)))) + +let execute_Sthbrx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(2:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (55:ii) >>= fun w__3 -> + MEMw (reset_vector_start EA,(2:ii),reset_vector_start (w__2 ^^ w__3)) + +let execute_Lwbrx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(4:ii)) >>= fun load_data -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + ((slice load_data (24:ii) (31:ii)) ^^ + ((slice load_data (16:ii) (23:ii)) ^^ + ((slice load_data (8:ii) (15:ii)) ^^ (slice load_data (0:ii) (7:ii)))))) + +let execute_Stwbrx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(4:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (55:ii) >>= fun w__3 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (40:ii) (47:ii) >>= fun w__4 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (39:ii) >>= fun w__5 -> + MEMw (reset_vector_start EA,(4:ii),reset_vector_start (w__2 ^^ (w__3 ^^ (w__4 ^^ w__5)))) + +let execute_Ldbrx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr (reset_vector_start EA,(8:ii)) >>= fun load_data -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((slice load_data (56:ii) (63:ii)) ^^ + ((slice load_data (48:ii) (55:ii)) ^^ + ((slice load_data (40:ii) (47:ii)) ^^ + ((slice load_data (32:ii) (39:ii)) ^^ + ((slice load_data (24:ii) (31:ii)) ^^ + ((slice load_data (16:ii) (23:ii)) ^^ + ((slice load_data (8:ii) (15:ii)) ^^ (slice load_data (0:ii) (7:ii))))))))) + +let execute_Stdbrx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA (reset_vector_start EA,(8:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (55:ii) >>= fun w__3 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (40:ii) (47:ii) >>= fun w__4 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (39:ii) >>= fun w__5 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (24:ii) (31:ii) >>= fun w__6 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (16:ii) (23:ii) >>= fun w__7 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (8:ii) (15:ii) >>= fun w__8 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (0:ii) (7:ii) >>= fun w__9 -> + MEMw + (reset_vector_start EA, + (8:ii), + reset_vector_start (w__2 ^^ (w__3 ^^ (w__4 ^^ (w__5 ^^ (w__6 ^^ (w__7 ^^ (w__8 ^^ w__9)))))))) + +let execute_Lmw (RT, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + let size = (minus_IVI (32:ii) (reset_vector_start RT)) * (4:ii) in + MEMr (reset_vector_start EA,size) >>= fun buffer -> + let i = (0:ii) in + (foreachM_inc (unsigned (reset_vector_start RT),(31:ii),(1:ii)) i + (fun r i -> + write_reg + (access GPR r) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (slice buffer i (i + (31:ii)))) >> + let i = i + (32:ii) in + return i)) >>= fun i -> + return () + +let execute_Stmw (RS, RA, D) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let EA = + set_vector_start 0 + (add_VVV (reset_vector_start b) (reset_vector_start (exts ((64:ii),reset_vector_start D)))) in + let size = (minus_IVI (32:ii) (reset_vector_start RS)) * (4:ii) in + MEMw_EA (reset_vector_start EA,size) >> + let buffer = make_indexed_vector [(0,B0);(993,B0)] B0 0 994 true in + let i = (0:ii) in + (foreachM_inc (unsigned (reset_vector_start RS),(31:ii),(1:ii)) (i,buffer) + (fun r (i,buffer) -> + read_reg_range (access GPR r) (32:ii) (63:ii) >>= fun w__1 -> + let buffer = update buffer i (i + (31:ii)) w__1 in + let i = i + (32:ii) in + return (i,buffer))) >>= fun (i, buffer) -> + MEMw + (reset_vector_start EA, + size, + reset_vector_start (slice buffer (0:ii) ((size * (8:ii)) - (1:ii)))) + +let execute_Lswi (RT, RA, NB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let EA = to_vec_inc ((64:ii),(0:ii)) in + return EA + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun EA -> + let r = (0:ii) in + let r = minus_VII (reset_vector_start RT) (1:ii) in + let size = + if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB) in + MEMr (reset_vector_start EA,size) >>= fun membuffer -> + let j = (0:ii) in + let i = (32:ii) in + (foreachM_dec (if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB),(1:ii),(1:ii)) (EA,i,j,r) + (fun n (EA,i,j,r) -> + (if bitU_to_bool (eq_range (i, (32:ii))) + then + let r = modulo (r + (1:ii)) (32:ii) in + write_reg (access GPR r) (to_vec_inc ((64:ii),(0:ii))) >> + return r + else return r) >>= fun r -> + write_reg_range (access GPR r) i (i + (7:ii)) (slice membuffer j (j + (7:ii))) >> + let j = j + (8:ii) in + let i = i + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + let EA = set_vector_start 0 (add_VIV (reset_vector_start EA) (1:ii)) in + return (EA,i,j,r))) >>= fun (EA, i, j, r) -> + return () + +let execute_Lswx (RT, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let r = (0:ii) in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + let r = minus_VII (reset_vector_start RT) (1:ii) in + let i = (32:ii) in + read_reg_range XER (57:ii) (63:ii) >>= fun w__2 -> + let n_top = unsigned (reset_vector_start w__2) in + recalculate_dependency () >> + (if bitU_to_bool (eq_range (n_top, (0:ii))) + then + write_reg (access GPR (unsigned (reset_vector_start RT))) (to_vec_inc_undef (64:ii)) >> + return r + else + MEMr (reset_vector_start EA,n_top) >>= fun membuffer -> + let j = (0:ii) in + let n_r = quot n_top (4:ii) in + let n_mod = modulo n_top (4:ii) in + let n_r = if bitU_to_bool (eq_range (n_mod, (0:ii))) then n_r else n_r + (1:ii) in + (foreachM_dec (n_r,(1:ii),(1:ii)) (j,r) + (fun n (j,r) -> + let r = modulo (r + (1:ii)) (32:ii) in + let temp = to_vec_inc ((64:ii),(0:ii)) in + let temp = + if bitU_to_bool (eq_range (n, (1:ii))) + then + match toNatural n_mod with + | (0:nn) -> + update temp (32:ii) (63:ii) (set_vector_start 32 (slice membuffer j (j + (31:ii)))) + | (1:nn) -> + update temp (32:ii) (39:ii) (set_vector_start 32 (slice membuffer j (j + (7:ii)))) + | (2:nn) -> + update temp (32:ii) (47:ii) (set_vector_start 32 (slice membuffer j (j + (15:ii)))) + | (3:nn) -> + update temp (32:ii) (55:ii) (set_vector_start 32 (slice membuffer j (j + (23:ii)))) + end + else update temp (32:ii) (63:ii) (set_vector_start 32 (slice membuffer j (j + (31:ii)))) in + let j = j + (32:ii) in + write_reg (access GPR r) temp >> + return (j,r))) >>= fun (j, r) -> + return r) >>= fun r -> + return () + +let execute_Stswi (RS, RA, NB) = + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let EA = to_vec_inc ((64:ii),(0:ii)) in + return EA + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun EA -> + let r = (0:ii) in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let size = + if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB) in + MEMw_EA (reset_vector_start EA,size) >> + let membuffer = make_indexed_vector [(0,B0);(255,B0)] B0 0 256 true in + let j = (0:ii) in + let i = (32:ii) in + (foreachM_dec (if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB),(1:ii),(1:ii)) (i,j,membuffer,r) + (fun n (i,j,membuffer,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + read_reg_range (access GPR r) i (i + (7:ii)) >>= fun w__1 -> + let membuffer = update membuffer j (j + (7:ii)) w__1 in + let j = j + (8:ii) in + let i = i + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + return (i,j,membuffer,r))) >>= fun (i, j, membuffer, r) -> + MEMw + (reset_vector_start EA, + size, + reset_vector_start (slice membuffer (0:ii) ((size * (8:ii)) - (1:ii)))) + +let execute_Stswx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + let r = (0:ii) in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let i = (32:ii) in + read_reg_range XER (57:ii) (63:ii) >>= fun w__2 -> + let n_top = unsigned (reset_vector_start w__2) in + recalculate_dependency () >> + MEMw_EA (reset_vector_start EA,n_top) >> + let membuffer = make_indexed_vector [(0,B0);(511,B0)] B0 0 512 true in + let j = (0:ii) in + (foreachM_dec (n_top,(1:ii),(1:ii)) (j,i,membuffer,r) + (fun n (j,i,membuffer,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + read_reg_range (access GPR r) i (i + (7:ii)) >>= fun w__3 -> + let membuffer = update membuffer j (j + (7:ii)) w__3 in + let i = i + (8:ii) in + let j = j + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + return (j,i,membuffer,r))) >>= fun (j, i, membuffer, r) -> + if bitU_to_bool (~(eq_range (n_top, (0:ii)))) + then + MEMw + (reset_vector_start EA, + n_top, + reset_vector_start (slice membuffer (0:ii) ((n_top * (8:ii)) - (1:ii)))) + else return () + +let execute_Addi (RT, RA, SI) = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (exts ((64:ii),reset_vector_start SI))) + else + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 + (add_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start SI))))) + +let execute_Addis (RT, RA, SI) = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 + (exts + ((64:ii), + reset_vector_start (SI ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true))))) + else + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 + (add_VVV + (reset_vector_start w__0) + (reset_vector_start (exts + ((64:ii), + reset_vector_start (SI ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true))))))) + +let execute_Add (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (temp, overflow, _) = + match (addSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v0v', v1v', v2v') -> (v0v',v1v',v2v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subf (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (t1, o1, _) = + match (addSO_VVV + (reset_vector_start (bitwise_not (reset_vector_start w__0))) + (reset_vector_start w__1)) with + | (v3v', v4v', v5v') -> (v3v',v4v',v5v') + end in + let (t2, o2, _) = + match (addSO_VBV (reset_vector_start t1) B1) with | (v6v', v7v', v8v') -> (v6v',v7v',v8v') end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Addic (RT, RA, SI) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let (temp, _, carry) = + match (addSO_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start SI)))) with + | (v9v', v10v', v11v') -> (v9v',v10v',v11v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + write_reg_bitfield XER "CA" carry + +let execute_AddicDot (RT, RA, SI) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let (temp, overflow, carry) = + match (addSO_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start SI)))) with + | (v12v', v13v', v14v') -> (v12v',v13v',v14v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + write_reg_bitfield XER "CA" carry >> + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),overflow |. w__1) + +let execute_Subfic (RT, RA, SI) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let (t1, o1, c1) = + match (addSO_VVV + (reset_vector_start (bitwise_not (reset_vector_start w__0))) + (reset_vector_start (exts ((64:ii),reset_vector_start SI)))) with + | (v15v', v16v', v17v') -> (v15v',v16v',v17v') + end in + let (t2, o2, c2) = + match (addSO_VBV (reset_vector_start t1) B1) with + | (v18v', v19v', v20v') -> (v18v',v19v',v20v') + end in + let temp = set_vector_start 0 t2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + write_reg_bitfield XER "CA" (c1 |. c2) + +let execute_Addc (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (temp, overflow, carry) = + match (addSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v21v', v22v', v23v') -> (v21v',v22v',v23v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subfc (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VVV + (reset_vector_start (bitwise_not (reset_vector_start w__0))) + (reset_vector_start w__1)) with + | (v24v', v25v', v26v') -> (v24v',v25v',v26v') + end in + let (t2, o2, c2) = + match (addSO_VBV (reset_vector_start t1) B1) with + | (v27v', v28v', v29v') -> (v27v',v28v',v29v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Adde (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v30v', v31v', v32v') -> (v30v',v31v',v32v') + end in + read_reg_bitfield XER "CA" >>= fun w__2 -> + let (t2, o2, c2) = + match (addSO_VBV (reset_vector_start t1) w__2) with + | (v33v', v34v', v35v') -> (v33v',v34v',v35v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subfe (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VVV + (reset_vector_start (bitwise_not (reset_vector_start w__0))) + (reset_vector_start w__1)) with + | (v36v', v37v', v38v') -> (v36v',v37v',v38v') + end in + read_reg_bitfield XER "CA" >>= fun w__2 -> + let (t2, o2, c2) = + match (addSO_VBV (reset_vector_start t1) w__2) with + | (v39v', v40v', v41v') -> (v39v',v40v',v41v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Addme (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg_bitfield XER "CA" >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VBV (reset_vector_start w__0) w__1) with + | (v42v', v43v', v44v') -> (v42v',v43v',v44v') + end in + let (t2, o2, c2) = + match (addSO_VVV + (reset_vector_start t1) + (reset_vector_start (Vector [B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1] 0 true))) with + | (v45v', v46v', v47v') -> (v45v',v46v',v47v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subfme (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg_bitfield XER "CA" >>= fun w__1 -> + let (t1, o1, c1) = + match (addSO_VBV (reset_vector_start (bitwise_not (reset_vector_start w__0))) w__1) with + | (v48v', v49v', v50v') -> (v48v',v49v',v50v') + end in + let (t2, o2, c2) = + match (addSO_VVV + (reset_vector_start t1) + (reset_vector_start (Vector [B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1;B1; + B1] 0 true))) with + | (v51v', v52v', v53v') -> (v51v',v52v',v53v') + end in + let temp = set_vector_start 0 t2 in + let overflow = o1 |. o2 in + let carry = c1 |. c2 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start temp,xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Addze (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg_bitfield XER "CA" >>= fun w__1 -> + let (temp, overflow, carry) = + match (addSO_VBV (reset_vector_start w__0) w__1) with + | (v54v', v55v', v56v') -> (v54v',v55v',v56v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Subfze (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg_bitfield XER "CA" >>= fun w__1 -> + let (temp, overflow, carry) = + match (addSO_VBV (reset_vector_start (bitwise_not (reset_vector_start w__0))) w__1) with + | (v57v', v58v', v59v') -> (v57v',v58v',v59v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),xer_so) + else return ()) >> + write_reg_bitfield XER "CA" carry >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Neg (RT, RA, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let (temp, overflow, _) = + match (addSO_VBV (reset_vector_start (bitwise_not (reset_vector_start w__0))) B1) with + | (v60v', v61v', v62v') -> (v60v',v61v',v62v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 temp) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start (set_vector_start 0 temp),w__1) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Mulli (RT, RA, SI) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let prod = + set_vector_start 0 + (multS_VVV + (reset_vector_start w__0) + (reset_vector_start (exts ((64:ii),reset_vector_start SI)))) in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (slice prod (64:ii) (127:ii))) + +let execute_Mullw (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let (prod, overflow, _) = + match (multSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v63v', v64v', v65v') -> (v63v',v64v',v65v') + end in + write_reg (access GPR (unsigned (reset_vector_start RT))) (set_vector_start 0 prod) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 prod),xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Mulhw (RT, RA, RB, Rc) = + let prod = to_vec_inc ((64:ii),(0:ii)) in + let overflow = B0 in + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let (p, o, _) = + match (multSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v66v', v67v', v68v') -> (v66v',v67v',v68v') + end in + let prod = set_vector_start 0 p in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (set_vector_start 32 (slice prod (0:ii) (31:ii))) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool (most_significant w__2) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start prod,xer_so) + else return () + +let execute_Mulhwu (RT, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let prod = set_vector_start 0 (mult_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (set_vector_start 32 (slice prod (0:ii) (31:ii))) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool (most_significant w__2) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start prod,xer_so) + else return () + +let execute_Divw (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let dividend = set_vector_start 0 w__0 in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let divisor = set_vector_start 0 w__1 in + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotSO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v69v', v70v', v71v') -> (v69v',v70v',v71v') + end in + let divided = update divided (32:ii) (63:ii) (set_vector_start 32 d) in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (slice divided (32:ii) (63:ii)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool ((most_significant w__2) |. overflow) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start divided,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Divwu (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let dividend = set_vector_start 0 w__0 in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let divisor = set_vector_start 0 w__1 in + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v72v', v73v', v74v') -> (v72v',v73v',v74v') + end in + let divided = update divided (32:ii) (63:ii) (set_vector_start 32 d) in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (slice divided (32:ii) (63:ii)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool ((most_significant w__2) |. overflow) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start divided,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Divwe (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let dividend = + w__0 ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let divisor = set_vector_start 0 w__1 in + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotSO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v75v', v76v', v77v') -> (v75v',v76v',v77v') + end in + let divided = update divided (32:ii) (63:ii) (slice d (32:ii) (63:ii)) in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (slice divided (32:ii) (63:ii)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool ((most_significant w__2) |. overflow) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start divided,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Divweu (RT, RA, RB, OE, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let dividend = + w__0 ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let divisor = set_vector_start 0 w__1 in + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v78v', v79v', v80v') -> (v78v',v79v',v80v') + end in + let divided = update divided (32:ii) (63:ii) (slice d (32:ii) (63:ii)) in + let overflow = o in + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (32:ii) + (63:ii) + (slice divided (32:ii) (63:ii)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RT))) (0:ii) + (31:ii) + (to_vec_inc_undef (((31:ii) - (0:ii)) + (1:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + read_reg mode64bit >>= fun w__2 -> + if bitU_to_bool ((most_significant w__2) |. overflow) + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else set_overflow_cr0 (reset_vector_start divided,xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Mulld (RT, RA, RB, OE, Rc) = + let prod = to_vec_inc ((128:ii),(0:ii)) in + let overflow = B0 in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let (p, o, _) = + match (multSO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v81v', v82v', v83v') -> (v81v',v82v',v83v') + end in + let prod = set_vector_start 0 p in + let overflow = o in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (slice prod (64:ii) (127:ii))) >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + set_overflow_cr0 (reset_vector_start (set_vector_start 0 (slice prod (64:ii) (127:ii))),xer_so) + else return ()) >> + if bitU_to_bool OE + then set_SO_OV overflow + else return () + +let execute_Mulhd (RT, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let prod = set_vector_start 0 (multS_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RT))) (slice prod (0:ii) (63:ii)) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start (slice prod (0:ii) (63:ii)),w__2) + else return () + +let execute_Mulhdu (RT, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let prod = set_vector_start 0 (mult_VVV (reset_vector_start w__0) (reset_vector_start w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RT))) (slice prod (0:ii) (63:ii)) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start (slice prod (0:ii) (63:ii)),w__2) + else return () + +let execute_Divd (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun dividend -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun divisor -> + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotSO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v84v', v85v', v86v') -> (v84v',v85v',v86v') + end in + let divided = set_vector_start 0 d in + let overflow = o in + write_reg (access GPR (unsigned (reset_vector_start RT))) divided >> + (if bitU_to_bool OE + then set_SO_OV overflow + else return ()) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__0 -> + set_overflow_cr0 (reset_vector_start divided,overflow |. w__0) + else return () + +let execute_Divdu (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun dividend -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun divisor -> + let divided = + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let overflow = B0 in + let (d, o, _) = + match (quotO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v87v', v88v', v89v') -> (v87v',v88v',v89v') + end in + let divided = set_vector_start 0 d in + let overflow = o in + write_reg (access GPR (unsigned (reset_vector_start RT))) divided >> + (if bitU_to_bool OE + then set_SO_OV overflow + else return ()) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__0 -> + set_overflow_cr0 (reset_vector_start divided,overflow |. w__0) + else return () + +let execute_Divde (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let dividend = + w__0 ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true) in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun divisor -> + let divided = to_vec_inc ((128:ii),(0:ii)) in + let overflow = B0 in + let (d, o, _) = + match (quotSO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v90v', v91v', v92v') -> (v90v',v91v',v92v') + end in + let divided = set_vector_start 0 d in + let overflow = o in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (slice divided (64:ii) (127:ii))) >> + (if bitU_to_bool OE + then set_SO_OV overflow + else return ()) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + if bitU_to_bool overflow + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else + set_overflow_cr0 + (reset_vector_start (set_vector_start 0 (slice divided (64:ii) (127:ii))), + xer_so) + else return () + +let execute_Divdeu (RT, RA, RB, OE, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__0 -> + let dividend = + w__0 ^^ + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true) in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun divisor -> + let divided = to_vec_inc ((128:ii),(0:ii)) in + let overflow = B0 in + let (d, o, _) = + match (quotO_VVV (reset_vector_start dividend) (reset_vector_start divisor)) with + | (v93v', v94v', v95v') -> (v93v',v94v',v95v') + end in + let divided = set_vector_start 0 d in + let overflow = o in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 (slice divided (64:ii) (127:ii))) >> + (if bitU_to_bool OE + then set_SO_OV overflow + else return ()) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun xer_so -> + let xer_so = if bitU_to_bool (OE &. overflow) then overflow else xer_so in + if bitU_to_bool overflow + then write_reg_field CR "CR0" (set_vector_start 32 (Vector [BU;BU;BU;xer_so] 0 true)) + else + set_overflow_cr0 + (reset_vector_start (set_vector_start 0 (slice divided (64:ii) (127:ii))), + xer_so) + else return () + +let execute_Cmpi (BF, L, RA, SI) = + let a = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let a = set_vector_start 0 (exts ((64:ii),reset_vector_start w__0)) in + return a + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun a -> + let c = make_indexed_vector [] B0 0 3 true in + let c = + if bitU_to_bool (lt_vec (a, exts ((64:ii),reset_vector_start SI))) + then Vector [B1;B0;B0] 0 true + else + if bitU_to_bool (gt_vec (a, exts ((64:ii),reset_vector_start SI))) + then Vector [B0;B1;B0] 0 true + else Vector [B0;B0;B1] 0 true in + read_reg_bitfield XER "SO" >>= fun w__2 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + (c ^^ (Vector [w__2] 0 true)) + +let execute_Cmp (BF, L, RA, RB) = + let a = to_vec_inc ((64:ii),(0:ii)) in + let b = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let a = set_vector_start 0 (exts ((64:ii),reset_vector_start w__0)) in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let b = set_vector_start 0 (exts ((64:ii),reset_vector_start w__1)) in + return (a,b) + else + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__2 -> + let a = w__2 in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__3 -> + let b = w__3 in + return (a,b)) >>= fun (a, b) -> + let c = make_indexed_vector [] B0 0 3 true in + let c = + if bitU_to_bool (lt_vec (a, b)) + then Vector [B1;B0;B0] 0 true + else if bitU_to_bool (gt_vec (a, b)) then Vector [B0;B1;B0] 0 true else Vector [B0;B0;B1] 0 true in + read_reg_bitfield XER "SO" >>= fun w__4 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + (c ^^ (Vector [w__4] 0 true)) + +let execute_Cmpli (BF, L, RA, UI) = + let a = to_vec_inc ((64:ii),(0:ii)) in + let c = to_vec_inc ((3:ii),(0:ii)) in + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let a = + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__0 in + return a + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun a -> + let c = + if bitU_to_bool + (lt_vec_unsigned + (a, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI)) + then Vector [B1;B0;B0] 0 true + else + if bitU_to_bool + (gt_vec_unsigned + (a, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI)) + then Vector [B0;B1;B0] 0 true + else Vector [B0;B0;B1] 0 true in + read_reg_bitfield XER "SO" >>= fun w__2 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + (c ^^ (Vector [w__2] 0 true)) + +let execute_Cmpl (BF, L, RA, RB) = + let a = to_vec_inc ((64:ii),(0:ii)) in + let b = to_vec_inc ((64:ii),(0:ii)) in + let c = to_vec_inc ((3:ii),(0:ii)) in + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RA))) (32:ii) (63:ii) >>= fun w__0 -> + let a = + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__0 in + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (32:ii) (63:ii) >>= fun w__1 -> + let b = + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__1 in + return (a,b) + else + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__2 -> + let a = w__2 in + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__3 -> + let b = w__3 in + return (a,b)) >>= fun (a, b) -> + let c = + if bitU_to_bool (lt_vec_unsigned (a, b)) + then Vector [B1;B0;B0] 0 true + else + if bitU_to_bool (gt_vec_unsigned (a, b)) + then Vector [B0;B1;B0] 0 true + else Vector [B0;B0;B1] 0 true in + read_reg_bitfield XER "SO" >>= fun w__4 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + (c ^^ (Vector [w__4] 0 true)) + +let execute_Isel (RT, RA, RB, BC) = + let a = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let a = to_vec_inc ((64:ii),(0:ii)) in + return a + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun a -> + read_reg_bit CR (add_VII (reset_vector_start BC) (32:ii)) >>= fun w__1 -> + if bitU_to_bool (eq (match w__1 with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + write_reg (access GPR (unsigned (reset_vector_start RT))) a >> + let discard = access GPR (unsigned (reset_vector_start RB)) in + return () + else + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__2 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__2 + +let execute_Andi (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = + set_vector_start 0 + (bitwise_and + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + +let execute_Andis (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = + set_vector_start 0 + (bitwise_and + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (UI ^^ (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + +let execute_Ori (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + (set_vector_start 0 + (bitwise_or + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI))) + +let execute_Oris (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + (set_vector_start 0 + (bitwise_or + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (UI ^^ (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true))))) + +let execute_Xori (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + (set_vector_start 0 + (bitwise_xor + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + UI))) + +let execute_Xoris (RS, RA, UI) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + (set_vector_start 0 + (bitwise_xor + (w__0, + (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (UI ^^ (Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true))))) + +let execute_And (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_and (w__0, w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Xor (RS, RA, RB, Rc) = + let temp = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec (RS, RB)) + then + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = w__0 in + let temp = to_vec_inc ((64:ii),(0:ii)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) (to_vec_inc ((64:ii),(0:ii))) >> + return temp + else + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__1 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__2 -> + let temp = set_vector_start 0 (bitwise_xor (w__1, w__2)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + return temp) >>= fun temp -> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return () + +let execute_Nand (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_not (reset_vector_start (bitwise_and (w__0, w__1)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Or (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_or (w__0, w__1)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Nor (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_not (reset_vector_start (bitwise_or (w__0, w__1)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Eqv (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_xor (w__0, bitwise_not (reset_vector_start w__1))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Andc (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_and (w__0, bitwise_not (reset_vector_start w__1))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Orc (RS, RA, RB, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let temp = set_vector_start 0 (bitwise_or (w__0, bitwise_not (reset_vector_start w__1))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Extsb (RS, RA, Rc) = + let temp = to_vec_inc ((64:ii),(0:ii)) in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (56:ii) >>= fun s -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__0 -> + let temp = update temp (56:ii) (63:ii) w__0 in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (56:ii) + (63:ii) + (slice temp (56:ii) (63:ii)) >> + let temp = update temp (0:ii) (55:ii) (duplicate (s, (56:ii))) in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (0:ii) + (55:ii) + (slice temp (0:ii) (55:ii)) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Extsh (RS, RA, Rc) = + let temp = to_vec_inc ((64:ii),(0:ii)) in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (48:ii) >>= fun s -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__0 -> + let temp = update temp (48:ii) (63:ii) w__0 in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (48:ii) + (63:ii) + (slice temp (48:ii) (63:ii)) >> + let temp = update temp (0:ii) (47:ii) (duplicate (s, (48:ii))) in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (0:ii) + (47:ii) + (slice temp (0:ii) (47:ii)) >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Cntlzw (RS, RA, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = to_vec_inc ((64:ii),countLeadingZeroes (reset_vector_start w__0,(32:ii))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Cmpb (RS, RA, RB) = + (foreachM_inc ((0:ii),(7:ii),(1:ii)) () + (fun n _ -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) + ((8:ii) * n) (((8:ii) * n) + (7:ii)) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) + ((8:ii) * n) (((8:ii) * n) + (7:ii)) >>= fun w__1 -> + if bitU_to_bool (eq_vec (w__0, w__1)) + then + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) ((8:ii) * n) + (((8:ii) * n) + (7:ii)) + (Vector [B1;B1;B1;B1;B1;B1;B1;B1] 0 true) + else + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) ((8:ii) * n) + (((8:ii) * n) + (7:ii)) + (to_vec_inc ((8:ii),(0:ii))))) + +let execute_Popcntb (RS, RA) = + (foreachM_inc ((0:ii),(7:ii),(1:ii)) () + (fun i _ -> + let n = (0:ii) in + (foreachM_inc ((0:ii),(7:ii),(1:ii)) n + (fun j n -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (8:ii)) + j) >>= fun w__0 -> + let n = + if bitU_to_bool (eq (match w__0 with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then n + (1:ii) + else n in + return n)) >>= fun n -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (i * (8:ii)) + ((i * (8:ii)) + (7:ii)) + (to_vec_inc ((8:ii),n)))) + +let execute_Popcntw (RS, RA) = + (foreachM_inc ((0:ii),(1:ii),(1:ii)) () + (fun i _ -> + let n = (0:ii) in + (foreachM_inc ((0:ii),(31:ii),(1:ii)) n + (fun j n -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (32:ii)) + j) >>= fun w__0 -> + let n = + if bitU_to_bool (eq (match w__0 with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then n + (1:ii) + else n in + return n)) >>= fun n -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (i * (32:ii)) + ((i * (32:ii)) + (31:ii)) + (to_vec_inc ((32:ii),n)))) + +let execute_Prtyd (RS, RA) = + let s = (0:ii) in + (foreachM_inc ((0:ii),(7:ii),(1:ii)) s + (fun i s -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (8:ii)) + (7:ii)) >>= fun w__0 -> + let s = + match ((if bitU_to_bool (is_one s) + then B1 + else B0) +. w__0) with + | B0 -> (0:ii) + | B1 -> (1:ii) + end in + return s)) >>= fun s -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (Vector [if bitU_to_bool (is_one s) then B1 else B0] 0 true)) + +let execute_Prtyw (RS, RA) = + let s = (0:ii) in + let t = (0:ii) in + (foreachM_inc ((0:ii),(3:ii),(1:ii)) s + (fun i s -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (8:ii)) + (7:ii)) >>= fun w__0 -> + let s = + match ((if bitU_to_bool (is_one s) + then B1 + else B0) +. w__0) with + | B0 -> (0:ii) + | B1 -> (1:ii) + end in + return s)) >>= fun s -> + (foreachM_inc ((4:ii),(7:ii),(1:ii)) t + (fun i t -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) ((i * (8:ii)) + (7:ii)) >>= fun w__1 -> + let t = + match ((if bitU_to_bool (is_one t) + then B1 + else B0) +. w__1) with + | B0 -> (0:ii) + | B1 -> (1:ii) + end in + return t)) >>= fun t -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (0:ii) + (31:ii) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (Vector [if bitU_to_bool (is_one s) then B1 else B0] 0 true)) >> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (32:ii) + (63:ii) + (set_vector_start 32 + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (Vector [if bitU_to_bool (is_one t) then B1 else B0] 0 true))) + +let execute_Extsw (RS, RA, Rc) = + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (32:ii) >>= fun s -> + let temp = to_vec_inc ((64:ii),(0:ii)) in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + let temp = update temp (32:ii) (63:ii) w__0 in + let temp = update temp (0:ii) (31:ii) (duplicate (s, (32:ii))) in + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return ()) >> + write_reg (access GPR (unsigned (reset_vector_start RA))) temp + +let execute_Cntlzd (RS, RA, Rc) = + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let temp = to_vec_inc ((64:ii),countLeadingZeroes (reset_vector_start w__0,(0:ii))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Popcntd (RS, RA) = + let n = (0:ii) in + (foreachM_inc ((0:ii),(63:ii),(1:ii)) n + (fun i n -> + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) i >>= fun w__0 -> + let n = + if bitU_to_bool (eq (match w__0 with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then n + (1:ii) + else n in + return n)) >>= fun n -> + write_reg (access GPR (unsigned (reset_vector_start RA))) (to_vec_inc ((64:ii),n)) + +let execute_Bpermd (RS, RA, RB) = + let perm = to_vec_inc ((8:ii),(0:ii)) in + (foreachM_inc ((0:ii),(7:ii),(1:ii)) perm + (fun i perm -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) + ((8:ii) * i) (((8:ii) * i) + (7:ii)) >>= fun index -> + if bitU_to_bool (lt_vec_unsigned (index, to_vec_inc ((8:ii),(64:ii)))) + then + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (unsigned + (reset_vector_start index)) >>= fun w__0 -> + let perm = update_pos perm i w__0 in + return perm + else + let perm = update_pos perm i B0 in + let discard = access GPR (unsigned (reset_vector_start RB)) in + return perm)) >>= fun perm -> + write_reg + (access GPR (unsigned (reset_vector_start RA))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + (slice perm (0:ii) (7:ii))) + +let execute_Rlwinm (RS, RA, SH, MB, ME, Rc) = + let n = SH in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),unsigned (reset_vector_start n)) in + let m = MASK (add_VII (reset_vector_start MB) (32:ii),add_VII (reset_vector_start ME) (32:ii)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Rlwnm (RS, RA, RB, MB, ME, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (59:ii) (63:ii) >>= fun n -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),unsigned (reset_vector_start n)) in + let m = MASK (add_VII (reset_vector_start MB) (32:ii),add_VII (reset_vector_start ME) (32:ii)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Rlwimi (RS, RA, SH, MB, ME, Rc) = + let n = SH in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),unsigned (reset_vector_start n)) in + let m = MASK (add_VII (reset_vector_start MB) (32:ii),add_VII (reset_vector_start ME) (32:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__2 -> + let temp = + set_vector_start 0 + (bitwise_or (bitwise_and (r, m), bitwise_and (w__2, bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return () + +let execute_Rldicl (RS, RA, sh, mb, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let b = (Vector [access mb (5:ii)] 0 true) ^^ (slice mb (0:ii) (4:ii)) in + let m = MASK (unsigned (reset_vector_start b),(63:ii)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldicr (RS, RA, sh, me, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let e = (Vector [access me (5:ii)] 0 true) ^^ (slice me (0:ii) (4:ii)) in + let m = MASK ((0:ii),unsigned (reset_vector_start e)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldic (RS, RA, sh, mb, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let b = (Vector [access mb (5:ii)] 0 true) ^^ (slice mb (0:ii) (4:ii)) in + let m = + MASK + (unsigned (reset_vector_start b), + unsigned (reset_vector_start (bitwise_not (reset_vector_start n)))) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldcl (RS, RA, RB, mb, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let b = (Vector [access mb (5:ii)] 0 true) ^^ (slice mb (0:ii) (4:ii)) in + let m = MASK (unsigned (reset_vector_start b),(63:ii)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldcr (RS, RA, RB, me, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let e = (Vector [access me (5:ii)] 0 true) ^^ (slice me (0:ii) (4:ii)) in + let m = MASK ((0:ii),unsigned (reset_vector_start e)) in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return () + +let execute_Rldimi (RS, RA, sh, mb, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let b = (Vector [access mb (5:ii)] 0 true) ^^ (slice mb (0:ii) (4:ii)) in + let m = + MASK + (unsigned (reset_vector_start b), + unsigned (reset_vector_start (bitwise_not (reset_vector_start n)))) in + read_reg (access GPR (unsigned (reset_vector_start RA))) >>= fun w__1 -> + let temp = + set_vector_start 0 + (bitwise_or (bitwise_and (r, m), bitwise_and (w__1, bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Slw (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (59:ii) (63:ii) >>= fun n -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),unsigned (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (58:ii) >>= fun w__2 -> + let m = + if bitU_to_bool (eq (match w__2 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK ((32:ii),minus_IVI (63:ii) (reset_vector_start n)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return () + +let execute_Srw (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (59:ii) (63:ii) >>= fun n -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),minus_IVI (64:ii) (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (58:ii) >>= fun w__2 -> + let m = + if bitU_to_bool (eq (match w__2 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK (add_VII (reset_vector_start n) (32:ii),(63:ii)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return () + +let execute_Srawi (RS, RA, SH, Rc) = + let n = SH in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),minus_IVI (64:ii) (reset_vector_start n)) in + let m = MASK (add_VII (reset_vector_start n) (32:ii),(63:ii)) in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (32:ii) >>= fun s -> + let temp = + set_vector_start 0 + (bitwise_or + (bitwise_and (r, m), + bitwise_and (duplicate (s, (64:ii)), bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return ()) >> + write_reg_bitfield + XER "CA" + (if bitU_to_bool (gt_vec_unsigned (n, to_vec_inc ((5:ii),(0:ii)))) + then s &. (~(eq_vec_range (bitwise_and (r, bitwise_not (reset_vector_start m)), (0:ii)))) + else B0) + +let execute_Sraw (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (59:ii) (63:ii) >>= fun n -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__1 -> + let r = ROTL (reset_vector_start (w__0 ^^ w__1),minus_IVI (64:ii) (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (58:ii) >>= fun w__2 -> + let m = + if bitU_to_bool (eq (match w__2 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK (add_VII (reset_vector_start n) (32:ii),(63:ii)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (32:ii) >>= fun s -> + let temp = + set_vector_start 0 + (bitwise_or + (bitwise_and (r, m), + bitwise_and (duplicate (s, (64:ii)), bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__3 -> + set_overflow_cr0 (reset_vector_start temp,w__3) + else return ()) >> + write_reg_bitfield + XER "CA" + (if bitU_to_bool (gt_vec_unsigned (n, to_vec_inc ((5:ii),(0:ii)))) + then s &. (~(eq_vec_range (bitwise_and (r, bitwise_not (reset_vector_start m)), (0:ii)))) + else B0) + +let execute_Sld (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,unsigned (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (57:ii) >>= fun w__1 -> + let m = + if bitU_to_bool (eq (match w__1 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK ((0:ii),minus_IVI (63:ii) (reset_vector_start n)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Srd (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,minus_IVI (64:ii) (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (57:ii) >>= fun w__1 -> + let m = + if bitU_to_bool (eq (match w__1 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK (unsigned (reset_vector_start n),(63:ii)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + let temp = set_vector_start 0 (bitwise_and (r, m)) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return () + +let execute_Sradi (RS, RA, sh, Rc) = + let n = (Vector [access sh (5:ii)] 0 true) ^^ (slice sh (0:ii) (4:ii)) in + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,minus_IVI (64:ii) (reset_vector_start n)) in + let m = MASK (unsigned (reset_vector_start n),(63:ii)) in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (0:ii) >>= fun s -> + let temp = + set_vector_start 0 + (bitwise_or + (bitwise_and (r, m), + bitwise_and (duplicate (s, (64:ii)), bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__1 -> + set_overflow_cr0 (reset_vector_start temp,w__1) + else return ()) >> + write_reg_bitfield + XER "CA" + (if bitU_to_bool (gt_vec_unsigned (n, to_vec_inc ((6:ii),(0:ii)))) + then s &. (~(eq_vec_range (bitwise_and (r, bitwise_not (reset_vector_start m)), (0:ii)))) + else B0) + +let execute_Srad (RS, RA, RB, Rc) = + read_reg_range (access GPR (unsigned (reset_vector_start RB))) (58:ii) (63:ii) >>= fun n -> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__0 -> + let r = ROTL (reset_vector_start w__0,minus_IVI (64:ii) (reset_vector_start n)) in + let m = make_indexed_vector [] B0 0 64 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RB))) (57:ii) >>= fun w__1 -> + let m = + if bitU_to_bool (eq (match w__1 with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then MASK (unsigned (reset_vector_start n),(63:ii)) + else + Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0] 0 true in + read_reg_bit (access GPR (unsigned (reset_vector_start RS))) (0:ii) >>= fun s -> + let temp = + set_vector_start 0 + (bitwise_or + (bitwise_and (r, m), + bitwise_and (duplicate (s, (64:ii)), bitwise_not (reset_vector_start m)))) in + write_reg (access GPR (unsigned (reset_vector_start RA))) temp >> + (if bitU_to_bool Rc + then + read_reg_bitfield XER "SO" >>= fun w__2 -> + set_overflow_cr0 (reset_vector_start temp,w__2) + else return ()) >> + write_reg_bitfield + XER "CA" + (if bitU_to_bool (gt_vec_unsigned (n, to_vec_inc ((6:ii),(0:ii)))) + then s &. (~(eq_vec_range (bitwise_and (r, bitwise_not (reset_vector_start m)), (0:ii)))) + else B0) + +let execute_Cdtbcd (RS, RA) = + (foreachM_inc ((0:ii),(1:ii),(1:ii)) () + (fun i _ -> + let n = i * (32:ii) in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (0:ii)) + (n + (7:ii)) + (to_vec_inc ((8:ii),(0:ii))) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (n + (12:ii)) (n + (21:ii)) >>= fun w__0 -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (8:ii)) + (n + (19:ii)) + (DEC_TO_BCD (reset_vector_start (set_vector_start 0 w__0))) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (n + (22:ii)) (n + (31:ii)) >>= fun w__1 -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (20:ii)) + (n + (31:ii)) + (DEC_TO_BCD (reset_vector_start (set_vector_start 0 w__1))))) + +let execute_Cbcdtd (RS, RA) = + (foreachM_inc ((0:ii),(1:ii),(1:ii)) () + (fun i _ -> + let n = i * (32:ii) in + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (0:ii)) + (n + (11:ii)) + (to_vec_inc ((12:ii),(0:ii))) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (n + (8:ii)) (n + (19:ii)) >>= fun w__0 -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (12:ii)) + (n + (21:ii)) + (BCD_TO_DEC (reset_vector_start (set_vector_start 0 w__0))) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (n + (20:ii)) (n + (31:ii)) >>= fun w__1 -> + write_reg_range + (access GPR (unsigned (reset_vector_start RA))) (n + (22:ii)) + (n + (31:ii)) + (BCD_TO_DEC (reset_vector_start (set_vector_start 0 w__1))))) + +let execute_Addg6s (RT, RA, RB) = + let dc = to_vec_inc ((16:ii),(0:ii)) in + (foreachM_inc ((0:ii),(15:ii),(1:ii)) dc + (fun i dc -> + read_reg_range (access GPR (unsigned (reset_vector_start RA))) ((4:ii) * i) (63:ii) >>= fun w__0 -> + read_reg_range (access GPR (unsigned (reset_vector_start RB))) ((4:ii) * i) (63:ii) >>= fun w__1 -> + let (v, _, co) = + match (addO_VVV (reset_vector_start w__0) (reset_vector_start w__1)) with + | (v96v', v97v', v98v') -> (v96v',v97v',v98v') + end in + let dc = update_pos dc i (carry_out (reset_vector_start (set_vector_start 0 v),co)) in + return dc)) >>= fun dc -> + let c = + (duplicate (access dc (0:ii), (4:ii))) ^^ + ((duplicate (access dc (1:ii), (4:ii))) ^^ + ((duplicate (access dc (2:ii), (4:ii))) ^^ + ((duplicate (access dc (3:ii), (4:ii))) ^^ + ((duplicate (access dc (4:ii), (4:ii))) ^^ + ((duplicate (access dc (5:ii), (4:ii))) ^^ + ((duplicate (access dc (6:ii), (4:ii))) ^^ + ((duplicate (access dc (7:ii), (4:ii))) ^^ + ((duplicate (access dc (8:ii), (4:ii))) ^^ + ((duplicate (access dc (9:ii), (4:ii))) ^^ + ((duplicate (access dc (10:ii), (4:ii))) ^^ + ((duplicate (access dc (11:ii), (4:ii))) ^^ + ((duplicate (access dc (12:ii), (4:ii))) ^^ + ((duplicate (access dc (13:ii), (4:ii))) ^^ + ((duplicate (access dc (14:ii), (4:ii))) ^^ (duplicate (access dc (15:ii), (4:ii))))))))))))))))) in + write_reg + (access GPR (unsigned (reset_vector_start RT))) + (set_vector_start 0 + (bitwise_and + (bitwise_not (reset_vector_start c), + Vector [B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0; + B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1; + B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1;B0;B0;B1;B1; + B0] 0 true))) + +let execute_Mtspr (RS, spr) = + let n = (slice spr (5:ii) (9:ii)) ^^ (slice spr (0:ii) (4:ii)) in + if bitU_to_bool (eq_vec_range (n, (13:ii))) + then trap () + else + if bitU_to_bool (eq_vec_range (n, (1:ii))) + then + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun reg -> + let front = zero_or_undef (reset_vector_start (slice reg (0:ii) (31:ii))) in + let xer_so = access reg (32:ii) in + let xer_ov = access reg (33:ii) in + let xer_ca = access reg (34:ii) in + let mid = zero_or_undef (reset_vector_start (set_vector_start 0 (slice reg (35:ii) (56:ii)))) in + let bot = set_vector_start 0 (slice reg (57:ii) (63:ii)) in + write_reg + XER + (front ^^ + ((Vector [xer_so] 0 true) ^^ + ((Vector [xer_ov] 0 true) ^^ ((Vector [xer_ca] 0 true) ^^ (mid ^^ bot))))) + else + read_reg (access SPR (unsigned (reset_vector_start n))) >>= fun w__0 -> + if bitU_to_bool (eq_range (length (reset_vector_start w__0), (64:ii))) + then + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__1 -> + write_reg (access SPR (unsigned (reset_vector_start n))) w__1 + else + if bitU_to_bool (eq_vec_range (n, (152:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun CTRL -> + return () + else return () + +let execute_Mfspr (RT, spr) = + let n = (slice spr (5:ii) (9:ii)) ^^ (slice spr (0:ii) (4:ii)) in + read_reg (access SPR (unsigned (reset_vector_start n))) >>= fun w__0 -> + if bitU_to_bool (eq_range (length (reset_vector_start w__0), (64:ii))) + then + read_reg (access SPR (unsigned (reset_vector_start n))) >>= fun w__1 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__1 + else + read_reg (access SPR (unsigned (reset_vector_start n))) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Mtcrf (RS, FXM) = + let mask = + (duplicate (access FXM (0:ii), (4:ii))) ^^ + ((duplicate (access FXM (1:ii), (4:ii))) ^^ + ((duplicate (access FXM (2:ii), (4:ii))) ^^ + ((duplicate (access FXM (3:ii), (4:ii))) ^^ + ((duplicate (access FXM (4:ii), (4:ii))) ^^ + ((duplicate (access FXM (5:ii), (4:ii))) ^^ + ((duplicate (access FXM (6:ii), (4:ii))) ^^ (duplicate (access FXM (7:ii), (4:ii))))))))) in + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__0 -> + read_reg CR >>= fun w__1 -> + write_reg + CR + (set_vector_start 32 + (bitwise_or + (set_vector_start 0 (bitwise_and (w__0, mask)), + set_vector_start 0 (bitwise_and (w__1, bitwise_not (reset_vector_start mask)))))) + +let execute_Mfcr RT = + read_reg CR >>= fun w__0 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__0) + +let execute_Mtocrf (RS, FXM) = + let n = (0:ii) in + let count = (0:ii) in + let (count, n) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (count,n) + (fun i (count,n) -> + let (n, count) = + if bitU_to_bool (eq (match (access FXM i) with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + let n = i in + let count = count + (1:ii) in + (n,count) + else (n,count) in + (count,n))) in + if bitU_to_bool (eq_range (count, (1:ii))) + then + read_reg_range (access GPR (unsigned (reset_vector_start RS))) + (((4:ii) * n) + (32:ii)) (((4:ii) * n) + (35:ii)) >>= fun w__0 -> + write_reg_range CR (((4:ii) * n) + (32:ii)) (((4:ii) * n) + (35:ii)) w__0 + else write_reg CR (to_vec_inc_undef (32:ii)) + +let execute_Mfocrf (RT, FXM) = + let n = (0:ii) in + let count = (0:ii) in + let (count, n) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (count,n) + (fun i (count,n) -> + let (n, count) = + if bitU_to_bool (eq (match (access FXM i) with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + let n = i in + let count = count + (1:ii) in + (n,count) + else (n,count) in + (count,n))) in + if bitU_to_bool (eq_range (count, (1:ii))) + then + let temp = to_vec_inc_undef (64:ii) in + read_reg_range CR (((4:ii) * n) + (32:ii)) (((4:ii) * n) + (35:ii)) >>= fun w__0 -> + let temp = update temp (((4:ii) * n) + (32:ii)) (((4:ii) * n) + (35:ii)) w__0 in + write_reg (access GPR (unsigned (reset_vector_start RT))) temp + else write_reg (access GPR (unsigned (reset_vector_start RT))) (to_vec_inc_undef (64:ii)) + +let execute_Mcrxr BF = + read_reg_range XER (32:ii) (35:ii) >>= fun w__0 -> + write_reg_range + CR (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii)) + (add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (35:ii)) + w__0 >> + write_reg_range XER (32:ii) (35:ii) (set_vector_start 32 (Vector [B0;B0;B0;B0] 0 true)) + +let execute_Dlmzb (RS, RA, RB, Rc) = return () + +let execute_Macchw (RT, RA, RB, OE, Rc) = return () + +let execute_Macchws (RT, RA, RB, OE, Rc) = return () + +let execute_Macchwu (RT, RA, RB, OE, Rc) = return () + +let execute_Macchwsu (RT, RA, RB, OE, Rc) = return () + +let execute_Machhw (RT, RA, RB, OE, Rc) = return () + +let execute_Machhws (RT, RA, RB, OE, Rc) = return () + +let execute_Machhwu (RT, RA, RB, OE, Rc) = return () + +let execute_Machhwsu (RT, RA, RB, OE, Rc) = return () + +let execute_Maclhw (RT, RA, RB, OE, Rc) = return () + +let execute_Maclhws (RT, RA, RB, OE, Rc) = return () + +let execute_Maclhwu (RT, RA, RB, OE, Rc) = return () + +let execute_Maclhwsu (RT, RA, RB, OE, Rc) = return () + +let execute_Mulchw (RT, RA, RB, Rc) = return () + +let execute_Mulchwu (RT, RA, RB, Rc) = return () + +let execute_Mulhhw (RT, RA, RB, Rc) = return () + +let execute_Mulhhwu (RT, RA, RB, Rc) = return () + +let execute_Mullhw (RT, RA, RB, Rc) = return () + +let execute_Mullhwu (RT, RA, RB, Rc) = return () + +let execute_Nmacchw (RT, RA, RB, OE, Rc) = return () + +let execute_Nmacchws (RT, RA, RB, OE, Rc) = return () + +let execute_Nmachhw (RT, RA, RB, OE, Rc) = return () + +let execute_Nmachhws (RT, RA, RB, OE, Rc) = return () + +let execute_Nmaclhw (RT, RA, RB, OE, Rc) = return () + +let execute_Nmaclhws (RT, RA, RB, OE, Rc) = return () + +let execute_Icbi (RA, RB) = return () + +let execute_Icbt (CT, RA, RB) = return () + +let execute_Dcba (RA, RB) = return () + +let execute_Dcbt (TH, RA, RB) = return () + +let execute_Dcbtst (TH, RA, RB) = return () + +let execute_Dcbz (RA, RB) = return () + +let execute_Dcbst (RA, RB) = return () + +let execute_Dcbf (L, RA, RB) = return () + +let execute_Isync () = I_Sync () + +let execute_Lbarx (RT, RA, RB, EH) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr_reserve (reset_vector_start EA,(1:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lharx (RT, RA, RB, EH) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr_reserve (reset_vector_start EA,(2:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Lwarx (RT, RA, RB, EH) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr_reserve (reset_vector_start EA,(4:ii)) >>= fun w__2 -> + write_reg + (access GPR (unsigned (reset_vector_start RT))) + ((Vector [B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0; + B0;B0;B0;B0;B0;B0;B0;B0;B0;B0;B0] 0 true) ^^ + w__2) + +let execute_Stbcx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA_cond (reset_vector_start EA,(1:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (56:ii) (63:ii) >>= fun w__2 -> + MEMw_conditional (reset_vector_start EA,(1:ii),reset_vector_start (set_vector_start 0 w__2)) >>= fun status -> + read_reg_bitfield XER "SO" >>= fun w__3 -> + let CR0 = (Vector [B0;B0] 0 true) ^^ ((Vector [status] 0 true) ^^ (Vector [w__3] 0 true)) in + return () + +let execute_Sthcx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA_cond (reset_vector_start EA,(2:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (48:ii) (63:ii) >>= fun w__2 -> + MEMw_conditional (reset_vector_start EA,(2:ii),reset_vector_start (set_vector_start 0 w__2)) >>= fun status -> + read_reg_bitfield XER "SO" >>= fun w__3 -> + let CR0 = (Vector [B0;B0] 0 true) ^^ ((Vector [status] 0 true) ^^ (Vector [w__3] 0 true)) in + return () + +let execute_Stwcx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA_cond (reset_vector_start EA,(4:ii)) >> + read_reg_range (access GPR (unsigned (reset_vector_start RS))) (32:ii) (63:ii) >>= fun w__2 -> + MEMw_conditional (reset_vector_start EA,(4:ii),reset_vector_start (set_vector_start 0 w__2)) >>= fun status -> + read_reg_bitfield XER "SO" >>= fun w__3 -> + let CR0 = (Vector [B0;B0] 0 true) ^^ ((Vector [status] 0 true) ^^ (Vector [w__3] 0 true)) in + return () + +let execute_Ldarx (RT, RA, RB, EH) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMr_reserve (reset_vector_start EA,(8:ii)) >>= fun w__2 -> + write_reg (access GPR (unsigned (reset_vector_start RT))) w__2 + +let execute_Stdcx (RS, RA, RB) = + let b = to_vec_inc ((64:ii),(0:ii)) in + let EA = to_vec_inc ((64:ii),(0:ii)) in + (if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then + let b = to_vec_inc ((64:ii),(0:ii)) in + return b + else read_reg (access GPR (unsigned (reset_vector_start RA)))) >>= fun b -> + read_reg (access GPR (unsigned (reset_vector_start RB))) >>= fun w__1 -> + let EA = set_vector_start 0 (add_VVV (reset_vector_start b) (reset_vector_start w__1)) in + MEMw_EA_cond (reset_vector_start EA,(8:ii)) >> + read_reg (access GPR (unsigned (reset_vector_start RS))) >>= fun w__2 -> + MEMw_conditional (reset_vector_start EA,(8:ii),reset_vector_start w__2) >>= fun status -> + read_reg_bitfield XER "SO" >>= fun w__3 -> + let CR0 = (Vector [B0;B0] 0 true) ^^ ((Vector [status] 0 true) ^^ (Vector [w__3] 0 true)) in + return () + +let execute_Sync L = + match L with | Vector [B0;B0] _ _ -> H_Sync () | Vector [B0;B1] _ _ -> LW_Sync () end + +let execute_Eieio () = EIEIO_Sync () + +let execute_Wait WC = return () + +let execute = function + + | B (LI,AA,LK) -> execute_B (LI,AA,LK) + | Bc (BO,BI,BD,AA,LK) -> execute_Bc (BO,BI,BD,AA,LK) + | Bclr (BO,BI,BH,LK) -> execute_Bclr (BO,BI,BH,LK) + | Bcctr (BO,BI,BH,LK) -> execute_Bcctr (BO,BI,BH,LK) + | Crand (BT,BA,BB) -> execute_Crand (BT,BA,BB) + | Crnand (BT,BA,BB) -> execute_Crnand (BT,BA,BB) + | Cror (BT,BA,BB) -> execute_Cror (BT,BA,BB) + | Crxor (BT,BA,BB) -> execute_Crxor (BT,BA,BB) + | Crnor (BT,BA,BB) -> execute_Crnor (BT,BA,BB) + | Creqv (BT,BA,BB) -> execute_Creqv (BT,BA,BB) + | Crandc (BT,BA,BB) -> execute_Crandc (BT,BA,BB) + | Crorc (BT,BA,BB) -> execute_Crorc (BT,BA,BB) + | Mcrf (BF,BFA) -> execute_Mcrf (BF,BFA) + | Sc (LEV) -> execute_Sc (LEV) + | Scv (LEV) -> execute_Scv (LEV) + | Lbz (RT,RA,D) -> execute_Lbz (RT,RA,D) + | Lbzx (RT,RA,RB) -> execute_Lbzx (RT,RA,RB) + | Lbzu (RT,RA,D) -> execute_Lbzu (RT,RA,D) + | Lbzux (RT,RA,RB) -> execute_Lbzux (RT,RA,RB) + | Lhz (RT,RA,D) -> execute_Lhz (RT,RA,D) + | Lhzx (RT,RA,RB) -> execute_Lhzx (RT,RA,RB) + | Lhzu (RT,RA,D) -> execute_Lhzu (RT,RA,D) + | Lhzux (RT,RA,RB) -> execute_Lhzux (RT,RA,RB) + | Lha (RT,RA,D) -> execute_Lha (RT,RA,D) + | Lhax (RT,RA,RB) -> execute_Lhax (RT,RA,RB) + | Lhau (RT,RA,D) -> execute_Lhau (RT,RA,D) + | Lhaux (RT,RA,RB) -> execute_Lhaux (RT,RA,RB) + | Lwz (RT,RA,D) -> execute_Lwz (RT,RA,D) + | Lwzx (RT,RA,RB) -> execute_Lwzx (RT,RA,RB) + | Lwzu (RT,RA,D) -> execute_Lwzu (RT,RA,D) + | Lwzux (RT,RA,RB) -> execute_Lwzux (RT,RA,RB) + | Lwa (RT,RA,DS) -> execute_Lwa (RT,RA,DS) + | Lwax (RT,RA,RB) -> execute_Lwax (RT,RA,RB) + | Lwaux (RT,RA,RB) -> execute_Lwaux (RT,RA,RB) + | Ld (RT,RA,DS) -> execute_Ld (RT,RA,DS) + | Ldx (RT,RA,RB) -> execute_Ldx (RT,RA,RB) + | Ldu (RT,RA,DS) -> execute_Ldu (RT,RA,DS) + | Ldux (RT,RA,RB) -> execute_Ldux (RT,RA,RB) + | Stb (RS,RA,D) -> execute_Stb (RS,RA,D) + | Stbx (RS,RA,RB) -> execute_Stbx (RS,RA,RB) + | Stbu (RS,RA,D) -> execute_Stbu (RS,RA,D) + | Stbux (RS,RA,RB) -> execute_Stbux (RS,RA,RB) + | Sth (RS,RA,D) -> execute_Sth (RS,RA,D) + | Sthx (RS,RA,RB) -> execute_Sthx (RS,RA,RB) + | Sthu (RS,RA,D) -> execute_Sthu (RS,RA,D) + | Sthux (RS,RA,RB) -> execute_Sthux (RS,RA,RB) + | Stw (RS,RA,D) -> execute_Stw (RS,RA,D) + | Stwx (RS,RA,RB) -> execute_Stwx (RS,RA,RB) + | Stwu (RS,RA,D) -> execute_Stwu (RS,RA,D) + | Stwux (RS,RA,RB) -> execute_Stwux (RS,RA,RB) + | Std (RS,RA,DS) -> execute_Std (RS,RA,DS) + | Stdx (RS,RA,RB) -> execute_Stdx (RS,RA,RB) + | Stdu (RS,RA,DS) -> execute_Stdu (RS,RA,DS) + | Stdux (RS,RA,RB) -> execute_Stdux (RS,RA,RB) + | Lhbrx (RT,RA,RB) -> execute_Lhbrx (RT,RA,RB) + | Sthbrx (RS,RA,RB) -> execute_Sthbrx (RS,RA,RB) + | Lwbrx (RT,RA,RB) -> execute_Lwbrx (RT,RA,RB) + | Stwbrx (RS,RA,RB) -> execute_Stwbrx (RS,RA,RB) + | Ldbrx (RT,RA,RB) -> execute_Ldbrx (RT,RA,RB) + | Stdbrx (RS,RA,RB) -> execute_Stdbrx (RS,RA,RB) + | Lmw (RT,RA,D) -> execute_Lmw (RT,RA,D) + | Stmw (RS,RA,D) -> execute_Stmw (RS,RA,D) + | Lswi (RT,RA,NB) -> execute_Lswi (RT,RA,NB) + | Lswx (RT,RA,RB) -> execute_Lswx (RT,RA,RB) + | Stswi (RS,RA,NB) -> execute_Stswi (RS,RA,NB) + | Stswx (RS,RA,RB) -> execute_Stswx (RS,RA,RB) + | Addi (RT,RA,SI) -> execute_Addi (RT,RA,SI) + | Addis (RT,RA,SI) -> execute_Addis (RT,RA,SI) + | Add (RT,RA,RB,OE,Rc) -> execute_Add (RT,RA,RB,OE,Rc) + | Subf (RT,RA,RB,OE,Rc) -> execute_Subf (RT,RA,RB,OE,Rc) + | Addic (RT,RA,SI) -> execute_Addic (RT,RA,SI) + | AddicDot (RT,RA,SI) -> execute_AddicDot (RT,RA,SI) + | Subfic (RT,RA,SI) -> execute_Subfic (RT,RA,SI) + | Addc (RT,RA,RB,OE,Rc) -> execute_Addc (RT,RA,RB,OE,Rc) + | Subfc (RT,RA,RB,OE,Rc) -> execute_Subfc (RT,RA,RB,OE,Rc) + | Adde (RT,RA,RB,OE,Rc) -> execute_Adde (RT,RA,RB,OE,Rc) + | Subfe (RT,RA,RB,OE,Rc) -> execute_Subfe (RT,RA,RB,OE,Rc) + | Addme (RT,RA,OE,Rc) -> execute_Addme (RT,RA,OE,Rc) + | Subfme (RT,RA,OE,Rc) -> execute_Subfme (RT,RA,OE,Rc) + | Addze (RT,RA,OE,Rc) -> execute_Addze (RT,RA,OE,Rc) + | Subfze (RT,RA,OE,Rc) -> execute_Subfze (RT,RA,OE,Rc) + | Neg (RT,RA,OE,Rc) -> execute_Neg (RT,RA,OE,Rc) + | Mulli (RT,RA,SI) -> execute_Mulli (RT,RA,SI) + | Mullw (RT,RA,RB,OE,Rc) -> execute_Mullw (RT,RA,RB,OE,Rc) + | Mulhw (RT,RA,RB,Rc) -> execute_Mulhw (RT,RA,RB,Rc) + | Mulhwu (RT,RA,RB,Rc) -> execute_Mulhwu (RT,RA,RB,Rc) + | Divw (RT,RA,RB,OE,Rc) -> execute_Divw (RT,RA,RB,OE,Rc) + | Divwu (RT,RA,RB,OE,Rc) -> execute_Divwu (RT,RA,RB,OE,Rc) + | Divwe (RT,RA,RB,OE,Rc) -> execute_Divwe (RT,RA,RB,OE,Rc) + | Divweu (RT,RA,RB,OE,Rc) -> execute_Divweu (RT,RA,RB,OE,Rc) + | Mulld (RT,RA,RB,OE,Rc) -> execute_Mulld (RT,RA,RB,OE,Rc) + | Mulhd (RT,RA,RB,Rc) -> execute_Mulhd (RT,RA,RB,Rc) + | Mulhdu (RT,RA,RB,Rc) -> execute_Mulhdu (RT,RA,RB,Rc) + | Divd (RT,RA,RB,OE,Rc) -> execute_Divd (RT,RA,RB,OE,Rc) + | Divdu (RT,RA,RB,OE,Rc) -> execute_Divdu (RT,RA,RB,OE,Rc) + | Divde (RT,RA,RB,OE,Rc) -> execute_Divde (RT,RA,RB,OE,Rc) + | Divdeu (RT,RA,RB,OE,Rc) -> execute_Divdeu (RT,RA,RB,OE,Rc) + | Cmpi (BF,L,RA,SI) -> execute_Cmpi (BF,L,RA,SI) + | Cmp (BF,L,RA,RB) -> execute_Cmp (BF,L,RA,RB) + | Cmpli (BF,L,RA,UI) -> execute_Cmpli (BF,L,RA,UI) + | Cmpl (BF,L,RA,RB) -> execute_Cmpl (BF,L,RA,RB) + | Isel (RT,RA,RB,BC) -> execute_Isel (RT,RA,RB,BC) + | Andi (RS,RA,UI) -> execute_Andi (RS,RA,UI) + | Andis (RS,RA,UI) -> execute_Andis (RS,RA,UI) + | Ori (RS,RA,UI) -> execute_Ori (RS,RA,UI) + | Oris (RS,RA,UI) -> execute_Oris (RS,RA,UI) + | Xori (RS,RA,UI) -> execute_Xori (RS,RA,UI) + | Xoris (RS,RA,UI) -> execute_Xoris (RS,RA,UI) + | And (RS,RA,RB,Rc) -> execute_And (RS,RA,RB,Rc) + | Xor (RS,RA,RB,Rc) -> execute_Xor (RS,RA,RB,Rc) + | Nand (RS,RA,RB,Rc) -> execute_Nand (RS,RA,RB,Rc) + | Or (RS,RA,RB,Rc) -> execute_Or (RS,RA,RB,Rc) + | Nor (RS,RA,RB,Rc) -> execute_Nor (RS,RA,RB,Rc) + | Eqv (RS,RA,RB,Rc) -> execute_Eqv (RS,RA,RB,Rc) + | Andc (RS,RA,RB,Rc) -> execute_Andc (RS,RA,RB,Rc) + | Orc (RS,RA,RB,Rc) -> execute_Orc (RS,RA,RB,Rc) + | Extsb (RS,RA,Rc) -> execute_Extsb (RS,RA,Rc) + | Extsh (RS,RA,Rc) -> execute_Extsh (RS,RA,Rc) + | Cntlzw (RS,RA,Rc) -> execute_Cntlzw (RS,RA,Rc) + | Cmpb (RS,RA,RB) -> execute_Cmpb (RS,RA,RB) + | Popcntb (RS,RA) -> execute_Popcntb (RS,RA) + | Popcntw (RS,RA) -> execute_Popcntw (RS,RA) + | Prtyd (RS,RA) -> execute_Prtyd (RS,RA) + | Prtyw (RS,RA) -> execute_Prtyw (RS,RA) + | Extsw (RS,RA,Rc) -> execute_Extsw (RS,RA,Rc) + | Cntlzd (RS,RA,Rc) -> execute_Cntlzd (RS,RA,Rc) + | Popcntd (RS,RA) -> execute_Popcntd (RS,RA) + | Bpermd (RS,RA,RB) -> execute_Bpermd (RS,RA,RB) + | Rlwinm (RS,RA,SH,MB,ME,Rc) -> execute_Rlwinm (RS,RA,SH,MB,ME,Rc) + | Rlwnm (RS,RA,RB,MB,ME,Rc) -> execute_Rlwnm (RS,RA,RB,MB,ME,Rc) + | Rlwimi (RS,RA,SH,MB,ME,Rc) -> execute_Rlwimi (RS,RA,SH,MB,ME,Rc) + | Rldicl (RS,RA,sh,mb,Rc) -> execute_Rldicl (RS,RA,sh,mb,Rc) + | Rldicr (RS,RA,sh,me,Rc) -> execute_Rldicr (RS,RA,sh,me,Rc) + | Rldic (RS,RA,sh,mb,Rc) -> execute_Rldic (RS,RA,sh,mb,Rc) + | Rldcl (RS,RA,RB,mb,Rc) -> execute_Rldcl (RS,RA,RB,mb,Rc) + | Rldcr (RS,RA,RB,me,Rc) -> execute_Rldcr (RS,RA,RB,me,Rc) + | Rldimi (RS,RA,sh,mb,Rc) -> execute_Rldimi (RS,RA,sh,mb,Rc) + | Slw (RS,RA,RB,Rc) -> execute_Slw (RS,RA,RB,Rc) + | Srw (RS,RA,RB,Rc) -> execute_Srw (RS,RA,RB,Rc) + | Srawi (RS,RA,SH,Rc) -> execute_Srawi (RS,RA,SH,Rc) + | Sraw (RS,RA,RB,Rc) -> execute_Sraw (RS,RA,RB,Rc) + | Sld (RS,RA,RB,Rc) -> execute_Sld (RS,RA,RB,Rc) + | Srd (RS,RA,RB,Rc) -> execute_Srd (RS,RA,RB,Rc) + | Sradi (RS,RA,sh,Rc) -> execute_Sradi (RS,RA,sh,Rc) + | Srad (RS,RA,RB,Rc) -> execute_Srad (RS,RA,RB,Rc) + | Cdtbcd (RS,RA) -> execute_Cdtbcd (RS,RA) + | Cbcdtd (RS,RA) -> execute_Cbcdtd (RS,RA) + | Addg6s (RT,RA,RB) -> execute_Addg6s (RT,RA,RB) + | Mtspr (RS,spr) -> execute_Mtspr (RS,spr) + | Mfspr (RT,spr) -> execute_Mfspr (RT,spr) + | Mtcrf (RS,FXM) -> execute_Mtcrf (RS,FXM) + | Mfcr (RT) -> execute_Mfcr (RT) + | Mtocrf (RS,FXM) -> execute_Mtocrf (RS,FXM) + | Mfocrf (RT,FXM) -> execute_Mfocrf (RT,FXM) + | Mcrxr (BF) -> execute_Mcrxr (BF) + | Dlmzb (RS,RA,RB,Rc) -> execute_Dlmzb (RS,RA,RB,Rc) + | Macchw (RT,RA,RB,OE,Rc) -> execute_Macchw (RT,RA,RB,OE,Rc) + | Macchws (RT,RA,RB,OE,Rc) -> execute_Macchws (RT,RA,RB,OE,Rc) + | Macchwu (RT,RA,RB,OE,Rc) -> execute_Macchwu (RT,RA,RB,OE,Rc) + | Macchwsu (RT,RA,RB,OE,Rc) -> execute_Macchwsu (RT,RA,RB,OE,Rc) + | Machhw (RT,RA,RB,OE,Rc) -> execute_Machhw (RT,RA,RB,OE,Rc) + | Machhws (RT,RA,RB,OE,Rc) -> execute_Machhws (RT,RA,RB,OE,Rc) + | Machhwu (RT,RA,RB,OE,Rc) -> execute_Machhwu (RT,RA,RB,OE,Rc) + | Machhwsu (RT,RA,RB,OE,Rc) -> execute_Machhwsu (RT,RA,RB,OE,Rc) + | Maclhw (RT,RA,RB,OE,Rc) -> execute_Maclhw (RT,RA,RB,OE,Rc) + | Maclhws (RT,RA,RB,OE,Rc) -> execute_Maclhws (RT,RA,RB,OE,Rc) + | Maclhwu (RT,RA,RB,OE,Rc) -> execute_Maclhwu (RT,RA,RB,OE,Rc) + | Maclhwsu (RT,RA,RB,OE,Rc) -> execute_Maclhwsu (RT,RA,RB,OE,Rc) + | Mulchw (RT,RA,RB,Rc) -> execute_Mulchw (RT,RA,RB,Rc) + | Mulchwu (RT,RA,RB,Rc) -> execute_Mulchwu (RT,RA,RB,Rc) + | Mulhhw (RT,RA,RB,Rc) -> execute_Mulhhw (RT,RA,RB,Rc) + | Mulhhwu (RT,RA,RB,Rc) -> execute_Mulhhwu (RT,RA,RB,Rc) + | Mullhw (RT,RA,RB,Rc) -> execute_Mullhw (RT,RA,RB,Rc) + | Mullhwu (RT,RA,RB,Rc) -> execute_Mullhwu (RT,RA,RB,Rc) + | Nmacchw (RT,RA,RB,OE,Rc) -> execute_Nmacchw (RT,RA,RB,OE,Rc) + | Nmacchws (RT,RA,RB,OE,Rc) -> execute_Nmacchws (RT,RA,RB,OE,Rc) + | Nmachhw (RT,RA,RB,OE,Rc) -> execute_Nmachhw (RT,RA,RB,OE,Rc) + | Nmachhws (RT,RA,RB,OE,Rc) -> execute_Nmachhws (RT,RA,RB,OE,Rc) + | Nmaclhw (RT,RA,RB,OE,Rc) -> execute_Nmaclhw (RT,RA,RB,OE,Rc) + | Nmaclhws (RT,RA,RB,OE,Rc) -> execute_Nmaclhws (RT,RA,RB,OE,Rc) + | Icbi (RA,RB) -> execute_Icbi (RA,RB) + | Icbt (CT,RA,RB) -> execute_Icbt (CT,RA,RB) + | Dcba (RA,RB) -> execute_Dcba (RA,RB) + | Dcbt (TH,RA,RB) -> execute_Dcbt (TH,RA,RB) + | Dcbtst (TH,RA,RB) -> execute_Dcbtst (TH,RA,RB) + | Dcbz (RA,RB) -> execute_Dcbz (RA,RB) + | Dcbst (RA,RB) -> execute_Dcbst (RA,RB) + | Dcbf (L,RA,RB) -> execute_Dcbf (L,RA,RB) + | Isync -> execute_Isync () + | Lbarx (RT,RA,RB,EH) -> execute_Lbarx (RT,RA,RB,EH) + | Lharx (RT,RA,RB,EH) -> execute_Lharx (RT,RA,RB,EH) + | Lwarx (RT,RA,RB,EH) -> execute_Lwarx (RT,RA,RB,EH) + | Stbcx (RS,RA,RB) -> execute_Stbcx (RS,RA,RB) + | Sthcx (RS,RA,RB) -> execute_Sthcx (RS,RA,RB) + | Stwcx (RS,RA,RB) -> execute_Stwcx (RS,RA,RB) + | Ldarx (RT,RA,RB,EH) -> execute_Ldarx (RT,RA,RB,EH) + | Stdcx (RS,RA,RB) -> execute_Stdcx (RS,RA,RB) + | Sync (L) -> execute_Sync (L) + | Eieio -> execute_Eieio () + | Wait (WC) -> execute_Wait (WC) + end + +let initial_analysis instr = + let iR = [] in + let oR = [] in + let aR = [] in + let ik = IK_simple in + let Nias = [NIAFP_successor] in + let Dia = DIAFP_none in + match instr with + | B (LI,AA,LK) -> + let oR = NIA_fp :: oR in + let iR = if bitU_to_bool AA then CIA_fp :: iR else iR in + let oR = if bitU_to_bool LK then (RFull "LR") :: oR else oR in + (if bitU_to_bool AA + then + return (set_vector_start 0 + (exts ((64:ii),reset_vector_start (LI ^^ (Vector [B0;B0] 0 true))))) + else + read_reg CIA >>= fun w__0 -> + return (set_vector_start 0 + (add_VVV + w__0 + (reset_vector_start (exts ((64:ii),reset_vector_start (LI ^^ (Vector [B0;B0] 0 true)))))))) >>= fun nia' -> + let Nias = [NIAFP_concrete_address (reset_vector_start nia')] in + let ik = IK_simple in + return (aR,oR,iR,Nias,ik) + | Bc (BO,BI,BD,AA,LK) -> + let iR = mode64bit_fp :: iR in + let iR = (RFull "CTR") :: iR in + let oR = if bitU_to_bool (~(access BO (2:ii))) then (RFull "CTR") :: oR else oR in + let iR = (RSliceBit ("CR",add_VII (reset_vector_start BI) (32:ii))) :: iR in + let oR = NIA_fp :: oR in + let iR = if bitU_to_bool AA then CIA_fp :: iR else iR in + (if bitU_to_bool AA + then + return (set_vector_start 0 + (exts ((64:ii),reset_vector_start (BD ^^ (Vector [B0;B0] 0 true))))) + else + read_reg CIA >>= fun w__1 -> + return (set_vector_start 0 + (add_VVV + w__1 + (reset_vector_start (exts ((64:ii),reset_vector_start (BD ^^ (Vector [B0;B0] 0 true)))))))) >>= fun w__2 -> + let Nias = [NIAFP_concrete_address (reset_vector_start w__2);NIAFP_successor] in + let (oR, iR) = + if bitU_to_bool LK + then + let oR = (RFull "LR") :: oR in + let iR = CIA_fp :: iR in + (oR,iR) + else (oR,iR) in + let ik = IK_cond_branch in + return (aR,oR,iR,Nias,ik) + | Bclr (BO,BI,BH,LK) -> + let iR = mode64bit_fp :: iR in + let iR = (RFull "CTR") :: iR in + let oR = if bitU_to_bool (~(access BO (2:ii))) then (RFull "CTR") :: oR else oR in + let iR = (RSliceBit ("CR",add_VII (reset_vector_start BI) (32:ii))) :: iR in + let iR = (RSlice ("LR",(0:ii),(61:ii))) :: iR in + let oR = NIA_fp :: oR in + let Nias = [NIAFP_LR;NIAFP_successor] in + let (oR, iR) = + if bitU_to_bool LK + then + let oR = (RFull "LR") :: oR in + let iR = CIA_fp :: iR in + (oR,iR) + else (oR,iR) in + let ik = IK_cond_branch in + return (aR,oR,iR,Nias,ik) + | Bcctr (BO,BI,BH,LK) -> + let iR = (RSliceBit ("CR",add_VII (reset_vector_start BI) (32:ii))) :: iR in + let iR = (RSlice ("CTR",(0:ii),(61:ii))) :: iR in + let oR = NIA_fp :: oR in + let Nias = [NIAFP_CTR;NIAFP_successor] in + let (oR, iR) = + if bitU_to_bool LK + then + let oR = (RFull "LR") :: oR in + let iR = CIA_fp :: iR in + (oR,iR) + else (oR,iR) in + let ik = IK_cond_branch in + return (aR,oR,iR,Nias,ik) + | Crand (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crnand (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Cror (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crxor (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crnor (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Creqv (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crandc (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Crorc (BT,BA,BB) -> + let iR = + (RSliceBit ("CR",add_VII (reset_vector_start BA) (32:ii))) :: + (RSliceBit ("CR",add_VII (reset_vector_start BB) (32:ii))) :: iR in + let oR = (RSliceBit ("CR",add_VII (reset_vector_start BT) (32:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mcrf (BF,BFA) -> + let iR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BFA))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BFA))) + (35:ii))) :: + iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Sc (LEV) -> + let Nias = if bitU_to_bool (eq_vec_range (LEV, (63:ii))) then [] else [NIAFP_successor] in + return (aR,oR,iR,Nias,ik) + | Scv (LEV) -> return (aR,oR,iR,Nias,ik) + | Lbz (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lbzx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lbzu (RT,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lbzux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhz (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhzx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhzu (RT,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhzux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lha (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhax (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhau (RT,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lhaux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwz (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwzx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwzu (RT,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwzux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwa (RT,RA,DS) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwax (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lwaux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Ld (RT,RA,DS) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Ldx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Ldu (RT,RA,DS) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Ldux (RT,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stb (RS,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stbx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stbu (RS,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stbux (RS,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Sth (RS,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Sthx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Sthu (RS,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Sthux (RS,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stw (RS,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stwx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stwu (RS,RA,D) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stwux (RS,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Std (RS,RA,DS) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stdx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stdu (RS,RA,DS) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stdux (RS,RA,RB) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let aR = iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lq (RTp,RA,DQ,PT) -> + let iR = bigendianmode_fp :: iR in + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RTp)))) :: + (RFull (access GPRs (add_VII (reset_vector_start RTp) (1:ii)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stq (RSp,RA,DS) -> + let iR = bigendianmode_fp :: iR in + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RSp)))) :: + (RFull (access GPRs (add_VII (reset_vector_start RSp) (1:ii)))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lhbrx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Sthbrx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(55:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lwbrx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stwbrx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(55:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(40:ii),(47:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(39:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Ldbrx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stdbrx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(55:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(40:ii),(47:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(39:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(24:ii),(31:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(16:ii),(23:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(8:ii),(15:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(0:ii),(7:ii))) :: iR in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lmw (RT,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let i = (0:ii) in + let aR = iR in + let (i, oR) = + (foreach_inc (unsigned (reset_vector_start RT),(31:ii),(1:ii)) (i,oR) + (fun r (i,oR) -> + let oR = (RFull (access GPRs r)) :: oR in + let i = i + (32:ii) in + (i,oR))) in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stmw (RS,RA,D) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let i = (0:ii) in + let (i, iR) = + (foreach_inc (unsigned (reset_vector_start RS),(31:ii),(1:ii)) (i,iR) + (fun r (i,iR) -> + let iR = (RSlice (access GPRs r,(32:ii),(63:ii))) :: iR in + let i = i + (32:ii) in + (i,iR))) in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Lswi (RT,RA,NB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let r = (0:ii) in + let r = minus_VII (reset_vector_start RT) (1:ii) in + let j = (0:ii) in + let i = (32:ii) in + let (i, j, oR, r) = + (foreach_dec (if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB),(1:ii),(1:ii)) (i,j,oR,r) + (fun n (i,j,oR,r) -> + let (r, oR) = + if bitU_to_bool (eq_range (i, (32:ii))) + then + let r = modulo (r + (1:ii)) (32:ii) in + let oR = (RFull (access GPRs r)) :: oR in + (r,oR) + else (r,oR) in + let oR = (RSlice (access GPRs r,i,i + (7:ii))) :: oR in + let j = j + (8:ii) in + let i = i + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + (i,j,oR,r))) in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Lswx (RT,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice ("XER",(57:ii),(63:ii))) :: iR in + let aR = iR in + let oR = (foreach_inc ((0:ii),(31:ii),(1:ii)) oR (fun r oR -> (RFull (access GPRs r)) :: oR)) in + let ik = IK_mem_read Read_plain in + return (aR,oR,iR,Nias,ik) + | Stswi (RS,RA,NB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let aR = iR in + let r = (0:ii) in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let j = (0:ii) in + let i = (32:ii) in + let (i, j, iR, r) = + (foreach_dec (if bitU_to_bool (eq_vec_range (NB, (0:ii))) + then (32:ii) + else unsigned (reset_vector_start NB),(1:ii),(1:ii)) (i,j,iR,r) + (fun n (i,j,iR,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + let iR = (RSlice (access GPRs r,i,i + (7:ii))) :: iR in + let j = j + (8:ii) in + let i = i + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + (i,j,iR,r))) in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Stswx (RS,RA,RB) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let r = (0:ii) in + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: + (RSlice ("XER",(57:ii),(63:ii))) :: iR in + let aR = iR in + let r = minus_VII (reset_vector_start RS) (1:ii) in + let i = (32:ii) in + let n_top = unsigned (reset_vector_start (Vector [B1;B1;B1;B1;B1;B1;B1] 0 true)) in + let j = (0:ii) in + let (j, i, iR, r) = + (foreach_dec (n_top,(1:ii),(1:ii)) (j,i,iR,r) + (fun n (j,i,iR,r) -> + let r = if bitU_to_bool (eq_range (i, (32:ii))) then modulo (r + (1:ii)) (32:ii) else r in + let iR = (RSlice (access GPRs r,i,i + (7:ii))) :: iR in + let i = i + (8:ii) in + let j = j + (8:ii) in + let i = if bitU_to_bool (eq_range (i, (64:ii))) then (32:ii) else i in + (j,i,iR,r))) in + let ik = IK_mem_write Write_plain in + return (aR,oR,iR,Nias,ik) + | Addi (RT,RA,SI) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Addis (RT,RA,SI) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Add (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subf (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Addic (RT,RA,SI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | AddicDot (RT,RA,SI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: (RField ("XER","CA")) :: oR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + return (aR,oR,iR,Nias,ik) + | Subfic (RT,RA,SI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = + (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Addc (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subfc (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Adde (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let iR = (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subfe (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let iR = (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Addme (RT,RA,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subfme (RT,RA,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Addze (RT,RA,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Subfze (RT,RA,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: (RField ("XER","CA")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Neg (RT,RA,OE,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulli (RT,RA,SI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mullw (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulhw (RT,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulhwu (RT,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divw (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divwu (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divwe (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divweu (RT,RA,RB,OE,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RT)),(0:ii),(31:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = mode64bit_fp :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulld (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulhd (RT,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mulhdu (RT,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divd (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divdu (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divde (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Divdeu (RT,RA,RB,OE,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let (iR, oR) = + if bitU_to_bool OE + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("XER","OV")) :: (RField ("XER","SO")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Cmpi (BF,L,RA,SI) -> + let iR = + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii)) + else RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Cmp (BF,L,RA,RB) -> + let iR = + if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR + else + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = + (RSlice ("CR",unsigned (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Cmpli (BF,L,RA,UI) -> + let iR = + (if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii)) + else RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Cmpl (BF,L,RA,RB) -> + let iR = + if bitU_to_bool (eq (match L with | B0 -> (0:ii) | B1 -> (1:ii) end, (0:ii))) + then + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(32:ii),(63:ii))) :: iR + else + (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let iR = (RField ("XER","SO")) :: iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + oR in + return (aR,oR,iR,Nias,ik) + | Isel (RT,RA,RB,BC) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RSliceBit ("CR",add_VII (reset_vector_start BC) (32:ii))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Andi (RS,RA,UI) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: (RField ("XER","SO")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let oR = (RField ("CR","CR0")) :: oR in + return (aR,oR,iR,Nias,ik) + | Andis (RS,RA,UI) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: (RField ("XER","SO")) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let oR = (RField ("CR","CR0")) :: oR in + return (aR,oR,iR,Nias,ik) + | Ori (RS,RA,UI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Oris (RS,RA,UI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Xori (RS,RA,UI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Xoris (RS,RA,UI) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | And (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Xor (RS,RA,RB,Rc) -> + let (iR, oR) = + if bitU_to_bool (eq_vec (RS, RB)) + then + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + (iR,oR) + else + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + (iR,oR) in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Nand (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Or (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Nor (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Eqv (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Andc (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Orc (RS,RA,RB,Rc) -> + let iR = + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Extsb (RS,RA,Rc) -> + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(56:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(56:ii),(63:ii))) :: iR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(56:ii),(63:ii))) :: oR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(0:ii),(55:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Extsh (RS,RA,Rc) -> + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(48:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(48:ii),(63:ii))) :: iR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(48:ii),(63:ii))) :: oR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(0:ii),(47:ii))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Cntlzw (RS,RA,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Cmpb (RS,RA,RB) -> + let (oR, iR) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (oR,iR) + (fun n (oR,iR) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(8:ii) * n,((8:ii) * n) + (7:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(8:ii) * n,((8:ii) * n) + + (7:ii))) :: + iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(8:ii) * n,((8:ii) * n) + (7:ii))) :: + oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Popcntb (RS,RA) -> + let (oR, iR) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let iR = + (foreach_inc ((0:ii),(7:ii),(1:ii)) iR + (fun j iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (8:ii)) + j)) :: iR)) in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),i * (8:ii),(i * (8:ii)) + (7:ii))) :: + oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Popcntw (RS,RA) -> + let (oR, iR) = + (foreach_inc ((0:ii),(1:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let iR = + (foreach_inc ((0:ii),(31:ii),(1:ii)) iR + (fun j iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (32:ii)) + j)) :: iR)) in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),i * (32:ii),(i * (32:ii)) + + (31:ii))) :: + oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Prtyd (RS,RA) -> + let iR = + (foreach_inc ((0:ii),(7:ii),(1:ii)) iR + (fun i iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (8:ii)) + (7:ii))) :: iR)) in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Prtyw (RS,RA) -> + let iR = + (foreach_inc ((0:ii),(3:ii),(1:ii)) iR + (fun i iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (8:ii)) + (7:ii))) :: iR)) in + let iR = + (foreach_inc ((4:ii),(7:ii),(1:ii)) iR + (fun i iR -> + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(i * (8:ii)) + (7:ii))) :: iR)) in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(0:ii),(31:ii))) :: oR in + let oR = (RSlice (access GPRs (unsigned (reset_vector_start RA)),(32:ii),(63:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Extsw (RS,RA,Rc) -> + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(32:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Cntlzd (RS,RA,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Popcntd (RS,RA) -> + let iR = + (foreach_inc ((0:ii),(63:ii),(1:ii)) iR + (fun i iR -> (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),i)) :: iR)) in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Bpermd (RS,RA,RB) -> + let (oR, iR) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(8:ii) * i,((8:ii) * i) + (7:ii))) :: + iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Rlwinm (RS,RA,SH,MB,ME,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rlwnm (RS,RA,RB,MB,ME,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(59:ii),(63:ii))) :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rlwimi (RS,RA,SH,MB,ME,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldicl (RS,RA,sh,mb,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldicr (RS,RA,sh,me,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldic (RS,RA,sh,mb,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldcl (RS,RA,RB,mb,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldcr (RS,RA,RB,me,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Rldimi (RS,RA,sh,mb,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Slw (RS,RA,RB,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(59:ii),(63:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(58:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Srw (RS,RA,RB,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(59:ii),(63:ii))) :: iR in + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(58:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Srawi (RS,RA,SH,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(32:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Sraw (RS,RA,RB,Rc) -> + let iR = (RSlice (access GPRs (unsigned (reset_vector_start RB)),(59:ii),(63:ii))) :: iR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: + (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(58:ii))) :: + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(32:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Sld (RS,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(57:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Srd (RS,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(57:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Sradi (RS,RA,sh,Rc) -> + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let iR = (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(0:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Srad (RS,RA,RB,Rc) -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(58:ii),(63:ii))) :: + (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: + (RSliceBit (access GPRs (unsigned (reset_vector_start RB)),(57:ii))) :: + (RSliceBit (access GPRs (unsigned (reset_vector_start RS)),(0:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: oR in + let (iR, oR) = + if bitU_to_bool Rc + then + let iR = (RField ("XER","SO")) :: iR in + let oR = (RField ("CR","CR0")) :: oR in + (iR,oR) + else (iR,oR) in + let oR = (RField ("XER","CA")) :: oR in + return (aR,oR,iR,Nias,ik) + | Cdtbcd (RS,RA) -> + let (oR, iR) = + (foreach_inc ((0:ii),(1:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let n = i * (32:ii) in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),n + (12:ii),n + (31:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),n + (0:ii),n + (31:ii))) :: oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Cbcdtd (RS,RA) -> + let (oR, iR) = + (foreach_inc ((0:ii),(1:ii),(1:ii)) (oR,iR) + (fun i (oR,iR) -> + let n = i * (32:ii) in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),n + (8:ii),n + (31:ii))) :: iR in + let oR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),n + (0:ii),n + (31:ii))) :: oR in + (oR,iR))) in + return (aR,oR,iR,Nias,ik) + | Addg6s (RT,RA,RB) -> + let iR = + (foreach_inc ((0:ii),(15:ii),(1:ii)) iR + (fun i iR -> + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RA)),(4:ii) * i,(63:ii))) :: iR in + (RSlice (access GPRs (unsigned (reset_vector_start RB)),(4:ii) * i,(63:ii))) :: iR)) in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mtspr (RS,spr) -> + let n = (slice spr (5:ii) (9:ii)) ^^ (slice spr (0:ii) (4:ii)) in + let (iR, oR) = + if bitU_to_bool (eq_vec_range (n, (1:ii))) + then + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull "XER") :: oR in + (iR,oR) + else + let iR = (RFull (access SPRs (unsigned (reset_vector_start n)))) :: iR in + let (iR, oR) = + if bitU_to_bool (eq_range (length_spr (unsigned (reset_vector_start n)), (64:ii))) + then + let iR = (RFull (access GPRs (unsigned (reset_vector_start RS)))) :: iR in + let oR = (RFull (access SPRs (unsigned (reset_vector_start n)))) :: oR in + (iR,oR) + else + let (iR, oR) = + if bitU_to_bool (eq_vec_range (n, (152:ii))) + then + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let oR = (RFull "CTRL") :: oR in + (iR,oR) + else (iR,oR) in + (iR,oR) in + (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mfspr (RT,spr) -> + let n = (slice spr (5:ii) (9:ii)) ^^ (slice spr (0:ii) (4:ii)) in + let iR = (RFull (access SPRs (unsigned (reset_vector_start n)))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mtcrf (RS,FXM) -> + let iR = + (RFull "CR") :: + (RSlice (access GPRs (unsigned (reset_vector_start RS)),(32:ii),(63:ii))) :: iR in + let oR = (RFull "CR") :: oR in + return (aR,oR,iR,Nias,ik) + | Mfcr (RT) -> + let iR = (RFull "CR") :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + return (aR,oR,iR,Nias,ik) + | Mtocrf (RS,FXM) -> + let n = (0:ii) in + let count = (0:ii) in + let (count, n) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (count,n) + (fun i (count,n) -> + let (n, count) = + if bitU_to_bool + (eq (match (access FXM i) with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + let n = i in + let count = count + (1:ii) in + (n,count) + else (n,count) in + (count,n))) in + let (oR, iR) = + if bitU_to_bool (eq_range (count, (1:ii))) + then + let oR = (RSlice ("CR",((4:ii) * n) + (32:ii),((4:ii) * n) + (35:ii))) :: oR in + let iR = + (RSlice (access GPRs (unsigned (reset_vector_start RS)),((4:ii) * n) + (32:ii),((4:ii) * + n) + + (35:ii))) :: + iR in + (oR,iR) + else + let oR = (RFull "CR") :: oR in + (oR,iR) in + return (aR,oR,iR,Nias,ik) + | Mfocrf (RT,FXM) -> + let n = (0:ii) in + let count = (0:ii) in + let (count, n) = + (foreach_inc ((0:ii),(7:ii),(1:ii)) (count,n) + (fun i (count,n) -> + let (n, count) = + if bitU_to_bool + (eq (match (access FXM i) with | B0 -> (0:ii) | B1 -> (1:ii) end, (1:ii))) + then + let n = i in + let count = count + (1:ii) in + (n,count) + else (n,count) in + (count,n))) in + let (iR, oR) = + if bitU_to_bool (eq_range (count, (1:ii))) + then + let iR = (RSlice ("CR",((4:ii) * n) + (32:ii),((4:ii) * n) + (35:ii))) :: iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + (iR,oR) + else + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + (iR,oR) in + return (aR,oR,iR,Nias,ik) + | Mcrxr (BF) -> + let iR = (RSlice ("XER",(32:ii),(35:ii))) :: iR in + let oR = + (RSlice ("CR",add_VII (reset_vector_start (mult_IVV (4:ii) (reset_vector_start BF))) (32:ii),add_VII + (reset_vector_start (mult_IVV + (4:ii) + (reset_vector_start BF))) + (35:ii))) :: + (RSlice ("XER",(32:ii),(35:ii))) :: oR in + return (aR,oR,iR,Nias,ik) + | Dlmzb (RS,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Macchws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Macchwu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Macchwsu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Machhws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Machhwu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Machhwsu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Maclhw (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Maclhws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Maclhwu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Maclhwsu (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Mulchw (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mulchwu (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mulhhw (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mulhhwu (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mullhw (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Mullhwu (RT,RA,RB,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmacchw (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmacchws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmachhw (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmachhws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmaclhw (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Nmaclhws (RT,RA,RB,OE,Rc) -> return (aR,oR,iR,Nias,ik) + | Icbi (RA,RB) -> return (aR,oR,iR,Nias,ik) + | Icbt (CT,RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcba (RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbt (TH,RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbtst (TH,RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbz (RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbst (RA,RB) -> return (aR,oR,iR,Nias,ik) + | Dcbf (L,RA,RB) -> return (aR,oR,iR,Nias,ik) + | Isync -> + let ik = IK_barrier Barrier_Isync in + return (aR,oR,iR,Nias,ik) + | Lbarx (RT,RA,RB,EH) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_reserve in + return (aR,oR,iR,Nias,ik) + | Lharx (RT,RA,RB,EH) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_reserve in + return (aR,oR,iR,Nias,ik) + | Lwarx (RT,RA,RB,EH) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_reserve in + return (aR,oR,iR,Nias,ik) + | Stbcx (RS,RA,RB) -> + let ik = IK_mem_write Write_conditional in + return (aR,oR,iR,Nias,ik) + | Sthcx (RS,RA,RB) -> + let ik = IK_mem_write Write_conditional in + return (aR,oR,iR,Nias,ik) + | Stwcx (RS,RA,RB) -> + let ik = IK_mem_write Write_conditional in + return (aR,oR,iR,Nias,ik) + | Ldarx (RT,RA,RB,EH) -> + let iR = + if bitU_to_bool (eq_vec_range (RA, (0:ii))) + then iR + else (RFull (access GPRs (unsigned (reset_vector_start RA)))) :: iR in + let iR = (RFull (access GPRs (unsigned (reset_vector_start RB)))) :: iR in + let aR = iR in + let oR = (RFull (access GPRs (unsigned (reset_vector_start RT)))) :: oR in + let ik = IK_mem_read Read_reserve in + return (aR,oR,iR,Nias,ik) + | Stdcx (RS,RA,RB) -> + let ik = IK_mem_write Write_conditional in + return (aR,oR,iR,Nias,ik) + | Sync (L) -> + let ik = + match L with + | Vector [B0;B0] _ _ -> IK_barrier Barrier_Sync + | Vector [B0;B1] _ _ -> IK_barrier Barrier_LwSync + end in + return (aR,oR,iR,Nias,ik) + | Eieio -> + let ik = IK_barrier Barrier_Eieio in + return (aR,oR,iR,Nias,ik) + | Wait (WC) -> return (aR,oR,iR,Nias,ik) + end >>= fun (aR, oR, iR, Nias, ik) -> + return (iR,oR,aR,Nias,Dia,ik) + diff --git a/power/power_extras.lem b/power/power_extras.lem new file mode 100644 index 00000000..b126aced --- /dev/null +++ b/power/power_extras.lem @@ -0,0 +1,96 @@ +open import Pervasives_extra +open import Interp_ast +open import Interp_interface +open import Sail_impl_base +open import Interp_inter_imp +import Set_extra + +let rec countLeadingZeros_helper bits = + match bits with + | (Interp_ast.V_lit (L_aux L_zero _))::bits -> + let (n,loc) = match countLeadingZeros_helper bits with + | (Interp_ast.V_lit (L_aux (L_num n) loc)) -> (n,loc) + | _ -> failwith "countLeadingZeros_helper: unexpected value" end in + Interp_ast.V_lit (L_aux (L_num (n+1)) loc) + | _ -> Interp_ast.V_lit (L_aux (L_num 0) Interp_ast.Unknown) +end +let rec countLeadingZeros e = + match e with + | Interp_ast.V_tuple v -> + match v with + | [Interp_ast.V_track v r;Interp_ast.V_track v2 r2] -> + Interp.taint (countLeadingZeros (Interp_ast.V_tuple [v;v2])) (r union r2) + | [Interp_ast.V_track v r;v2] -> Interp.taint (countLeadingZeros (Interp_ast.V_tuple [v;v2])) r + | [v;Interp_ast.V_track v2 r2] -> Interp.taint (countLeadingZeros (Interp_ast.V_tuple [v;v2])) r2 + | [Interp_ast.V_unknown;_] -> Interp_ast.V_unknown + | [_;Interp_ast.V_unknown] -> Interp_ast.V_unknown + | [Interp_ast.V_vector _ _ bits;Interp_ast.V_lit (L_aux (L_num n) _)] -> + countLeadingZeros_helper (snd (List.splitAt (natFromInteger n) bits)) + | _ -> failwith "countLeadingZeros: unexpected value" + end + | _ -> failwith "countLeadingZeros: unexpected value" +end + +(*Power specific external functions*) +let power_externs = [ + ("countLeadingZeroes", countLeadingZeros); +] + +(*All external functions*) +(*let external_functions = Interp_lib.function_map ++ power_externs*) + +(*List of memory functions; needs to be expanded with all of the memory functions needed for PPCMem. + Should probably be expanded into a parameter to mode as with above + *) + +let memory_parameter_transformer mode v = + match v with + | Interp_ast.V_tuple [location;length] -> + let (v,loc_regs) = extern_with_track mode extern_vector_value location in + + match length with + | Interp_ast.V_lit (L_aux (L_num len) _) -> + (v,(natFromInteger len),loc_regs) + | Interp_ast.V_track (Interp_ast.V_lit (L_aux (L_num len) _)) size_regs -> + match loc_regs with + | Nothing -> (v,(natFromInteger len),Just (List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs))) + | Just loc_regs -> + (v,(natFromInteger len),Just (loc_regs++(List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs)))) + end + | _ -> failwith "memory_parameter_transformer: unexpected value" + end + | _ -> failwith "memory_parameter_transformer: unexpected value" + end + +let power_read_memory_functions : memory_reads = + [ ("MEMr'", (MR Read_plain memory_parameter_transformer)); + ("MEMr_reserve'", (MR Read_reserve memory_parameter_transformer)); + ] +let power_memory_writes : memory_writes = [] + (* [ ("MEMw", (MW Write_plain memory_parameter_transformer Nothing)); + ("MEMw_conditional", (MW Write_conditional memory_parameter_transformer + (Just (fun (IState interp_state c) success -> + let v = Interp.V_lit (L_aux (if success then L_one else L_zero) Unknown) in + IState (Interp.add_answer_to_stack interp_state v) c)) + )); + ] *) + +let power_memory_eas : memory_write_eas = + [ ("MEMw_EA", (MEA Write_plain memory_parameter_transformer)); + ("MEMw_EA_cond", (MEA Write_conditional memory_parameter_transformer)) + ] + +let power_memory_vals : memory_write_vals = + [ ("MEMw'", (MV (fun mode v -> Nothing) Nothing)); + ("MEMw_conditional'", (MV (fun mode v -> Nothing) + (Just (fun (IState interp_state c) success -> + let v = Interp_ast.V_lit (L_aux (if success then L_one else L_zero) Unknown) in + IState (Interp.add_answer_to_stack interp_state v) c)))); + ] + +let power_barrier_functions = [ + ("I_Sync", Barrier_Isync); + ("H_Sync", Barrier_Sync); + ("LW_Sync", Barrier_LwSync); + ("EIEIO_Sync", Barrier_Eieio); +] diff --git a/power/power_extras_embed.lem b/power/power_extras_embed.lem new file mode 100644 index 00000000..c83a87a7 --- /dev/null +++ b/power/power_extras_embed.lem @@ -0,0 +1,50 @@ +open import Pervasives +open import Sail_impl_base +open import Sail_values +open import Prompt + +val MEMr' : (vector bitU * integer) -> M (vector bitU) +val MEMr_reserve' : (vector bitU * integer) -> M (vector bitU) + +let MEMr' (addr,size) = read_mem true Read_plain addr size +let MEMr_reserve' (addr,size) = read_mem true Read_reserve addr size + + +val MEMw_EA : (vector bitU * integer) -> M unit +val MEMr_EA_cond : (vector bitU * integer) -> M unit + +let MEMw_EA (addr,size) = write_mem_ea Write_plain addr size +let MEMw_EA_cond (addr,size) = write_mem_ea Write_conditional addr size + + +val MEMw' : (vector bitU * integer * vector bitU) -> M unit +val MEMw_conditional' : (vector bitU * integer * vector bitU) -> M bitU + +let MEMw' (_,_,value) = write_mem_val value >>= fun _ -> return () +let MEMw_conditional' (_,_,value) = write_mem_val value >>= fun b -> return (bool_to_bitU b) + + +val I_Sync : unit -> M unit +val H_Sync : unit -> M unit +val LW_Sync : unit -> M unit +val EIEIO_Sync : unit -> M unit + +let I_Sync () = barrier Barrier_Isync +let H_Sync () = barrier Barrier_Sync +let LW_Sync () = barrier Barrier_LwSync +let EIEIO_Sync () = barrier Barrier_Eieio + +let recalculate_dependency () = footprint + +let trap () = exit "error" +(* this needs to change, but for that we'd have to make the type checker know about trap + * as an effect *) + +val countLeadingZeroes : vector bitU * integer -> integer +let countLeadingZeroes (Vector bits _ _ ,n) = + let (_,bits) = List.splitAt (natFromInteger n) bits in + integerFromNat (List.length (takeWhile ((=) B0) bits)) + + +let duplicate (bit,length) = + Vector (List.replicate (natFromInteger length) bit) 0 true diff --git a/power/power_extras_embed_sequential.lem b/power/power_extras_embed_sequential.lem new file mode 100644 index 00000000..4ec33151 --- /dev/null +++ b/power/power_extras_embed_sequential.lem @@ -0,0 +1,50 @@ +open import Pervasives +open import Sail_impl_base +open import Sail_values +open import State + +val MEMr' : (vector bitU * integer) -> M (vector bitU) +val MEMr_reserve' : (vector bitU * integer) -> M (vector bitU) + +let MEMr' (addr,size) = read_mem true Read_plain addr size +let MEMr_reserve' (addr,size) = read_mem true Read_reserve addr size + + +val MEMw_EA : (vector bitU * integer) -> M unit +val MEMr_EA_cond : (vector bitU * integer) -> M unit + +let MEMw_EA (addr,size) = write_mem_ea Write_plain addr size +let MEMw_EA_cond (addr,size) = write_mem_ea Write_conditional addr size + + +val MEMw' : (vector bitU * integer * vector bitU) -> M unit +val MEMw_conditional' : (vector bitU * integer * vector bitU) -> M bitU + +let MEMw' (_,_,value) = write_mem_val value >>= fun _ -> return () +let MEMw_conditional' (_,_,value) = write_mem_val value >>= fun b -> return (bool_to_bitU b) + + +val I_Sync : unit -> M unit +val H_Sync : unit -> M unit +val LW_Sync : unit -> M unit +val EIEIO_Sync : unit -> M unit + +let I_Sync () = barrier Barrier_Isync +let H_Sync () = barrier Barrier_Sync +let LW_Sync () = barrier Barrier_LwSync +let EIEIO_Sync () = barrier Barrier_Eieio + +let recalculate_dependency () = footprint + +let trap () = exit "error" +(* this needs to change, but for that we'd have to make the type checker know about trap + * as an effect *) + +val countLeadingZeroes : vector bitU * integer -> integer +let countLeadingZeroes (Vector bits _ _ ,n) = + let (_,bits) = List.splitAt (natFromInteger n) bits in + integerFromNat (List.length (takeWhile ((=) B0) bits)) + + +let duplicate (bit,length) = + Vector (List.replicate (natFromInteger length) bit) 0 true diff --git a/power/power_regfp.sail b/power/power_regfp.sail new file mode 100644 index 00000000..35ecb37b --- /dev/null +++ b/power/power_regfp.sail @@ -0,0 +1,1483 @@ +(*========================================================================*) +(* *) +(* Copyright (c) 2015-2017 Gabriel Kerneis, Susmit Sarkar, Kathyrn Gray *) +(* Copyright (c) 2015-2017 Peter Sewell *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(*========================================================================*) + +let (vector <0, 32, inc, string >) GPRs = + [ "GPR0", "GPR1", "GPR2", "GPR3", "GPR4", "GPR5", "GPR6", "GPR7", "GPR8", "GPR9", "GPR10", + "GPR11", "GPR12", "GPR13", "GPR14", "GPR15", "GPR16", "GPR17", "GPR18", "GPR19", "GPR20", + "GPR21", "GPR22", "GPR23", "GPR24", "GPR25", "GPR26", "GPR27", "GPR28", "GPR29", "GPR30", "GPR31" + ] + +let (vector <0, 1024, inc, string >) SPRs = + [ 1="XER", 8="LR", 9="CTR"(*, 256=VRSAVE (*32 bit, so not 64, caught by type checker at last*)*), 259="SPRG3", 260="SPRG4", 261="SPRG5", 262="SPRG6", 263="SPRG7" + ] + +let (vector <0, 1024, inc, string >) DCRs = + [ 0="DCR0", 1="DCR1" ; default=undefined] + +function nat length_spr i = switch i { + case 1 -> 64 + case 8 -> 64 + case 9 -> 64 + case 259 -> 64 + case 260 -> 64 + case 261 -> 64 + case 262 -> 64 + case 263 -> 64 +} + +let CIA_fp = RFull("CIA") +let NIA_fp = RFull("NIA") +let mode64bit_fp = RFull("mode64bit") +let bigendianmode_fp = RFull("bigendianmode") + +val ast -> (regfps,regfps,regfps,niafps,diafp,instruction_kind) effect {rreg} initial_analysis +function (regfps,regfps,regfps,niafps,diafp,instruction_kind) initial_analysis (instr) = { + iR := [|| ||]; + oR := [|| ||]; + aR := [|| ||]; + ik := IK_simple; + Nias := [|| NIAFP_successor ||]; + Dia := DIAFP_none; + switch instr { + case (B (LI, AA, LK)) -> { + oR := NIA_fp :: oR; + if AA then iR := CIA_fp :: iR; + if LK then oR := RFull("LR") :: oR; + (bit[64]) nia' := if AA then EXTS(LI : 0b00) else CIA + EXTS(LI : 0b00); + Nias := [|| NIAFP_concrete_address(nia') ||]; + ik := IK_simple (* IK_uncond_branch *); + } + case (Bc (BO, BI, BD, AA, LK)) -> { + iR := mode64bit_fp :: iR; + iR := RFull("CTR") :: iR; + if ~(BO[2]) then oR := RFull("CTR") :: oR; + iR := RSliceBit("CR",BI + 32) :: iR; + (* TODO: actually whether CIA is read and NIA written depends on runtime data *) + (* if ctr_ok .. *) + oR := NIA_fp :: oR; + if AA then iR := CIA_fp :: iR; + Nias := [|| NIAFP_successor, NIAFP_concrete_address(if AA then EXTS(BD : 0b00) else CIA + EXTS(BD : 0b00)) ||]; + if LK then {oR := RFull("LR") :: oR; iR := CIA_fp :: iR}; + ik := IK_cond_branch + } + case (Bclr (BO, BI, BH, LK)) -> { + iR := mode64bit_fp :: iR; + iR := RFull("CTR") :: iR; + if ~(BO[2]) then oR := RFull("CTR") :: oR; + iR := RSliceBit("CR",BI + 32) :: iR; + (* TODO: actually whether LR is read, NIA written depends on runtime data *) + (* if ctr_ok .. *) iR := RSlice("LR",0,61) :: iR; + oR := NIA_fp :: oR; + Nias := [|| NIAFP_successor, NIAFP_LR ||]; + if LK then {oR := RFull("LR") :: oR; iR := CIA_fp :: iR;}; + ik := IK_cond_branch; + } + case (Bcctr (BO, BI, BH, LK)) -> { + iR := RSliceBit("CR",BI + 32) :: iR; + (* TODO: actually whether CTR is read and NIA written depends on runtime data *) + (* if cond_ok *) iR := RSlice("CTR",0,61) :: iR; + oR := NIA_fp :: oR; + Nias := [|| NIAFP_successor, NIAFP_CTR ||]; + if LK then {oR := RFull("LR") :: oR; iR := CIA_fp :: iR;}; + ik := IK_cond_branch; + } + case (Crand (BT, BA, BB)) -> { + iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR; + oR := RSliceBit("CR",BT + 32) :: oR; + } + case (Crnand (BT, BA, BB)) -> { + iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR; + oR := RSliceBit("CR",BT + 32) :: oR; + } + case (Cror (BT, BA, BB)) -> { + iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR; + oR := RSliceBit("CR",BT + 32) :: oR; + } + case (Crxor (BT, BA, BB)) -> { + iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR; + oR := RSliceBit("CR",BT + 32) :: oR; + } + case (Crnor (BT, BA, BB)) -> { + iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR; + oR := RSliceBit("CR",BT + 32) :: oR; + } + case (Creqv (BT, BA, BB)) -> { + iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR; + oR := RSliceBit("CR",BT + 32) :: oR; + } + case (Crandc (BT, BA, BB)) -> { + iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR; + oR := RSliceBit("CR",BT + 32) :: oR; + } + case (Crorc (BT, BA, BB)) -> { + iR := RSliceBit("CR",BA + 32) :: RSliceBit("CR",BB + 32) :: iR; + oR := RSliceBit("CR",BT + 32) :: oR; + } + case (Mcrf (BF, BFA)) -> { + iR := RSlice("CR",4 * BFA + 32,4 * BFA + 35) :: iR; + oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: oR; + } + case (Sc (LEV)) -> { + (* fake test end instruction *) + Nias := if LEV==63 then [|| ||] else [|| NIAFP_successor ||]; + } + case (Scv (LEV)) -> () + case (Lbz (RT, RA, D)) -> { + if RA == 0 then () else iR := (RFull(GPRs[RA])) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lbzx (RT, RA, RB)) -> { + if RA == 0 then () else iR := (RFull(GPRs[RA])) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lbzu (RT, RA, D)) -> { + iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lbzux (RT, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lhz (RT, RA, D)) -> { + if RA == 0 then () else iR := (RFull(GPRs[RA])) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lhzx (RT, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lhzu (RT, RA, D)) -> { + iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lhzux (RT, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lha (RT, RA, D)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lhax (RT, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lhau (RT, RA, D)) -> { + iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lhaux (RT, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lwz (RT, RA, D)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lwzx (RT, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lwzu (RT, RA, D)) -> { + iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lwzux (RT, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lwa (RT, RA, DS)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lwax (RT, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Lwaux (RT, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Ld (RT, RA, DS)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Ldx (RT, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Ldu (RT, RA, DS)) -> { + iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Ldux (RT, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Stb (RS, RA, D)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + iR := RSlice(GPRs[RS],56,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Stbx (RS, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + iR := RSlice(GPRs[RS],56,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Stbu (RS, RA, D)) -> { + iR := RFull(GPRs[RA]) :: iR; + aR := iR; + iR := RSlice(GPRs[RS],56,63) :: iR; + oR := RFull(GPRs[RA]) :: oR; + ik := IK_mem_write(Write_plain); + } + case (Stbux (RS, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + aR := iR; + iR := RSlice(GPRs[RS],56,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Sth (RS, RA, D)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + iR := RSlice(GPRs[RS],48,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Sthx (RS, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + iR := RFull(GPRs[RB]) :: RSlice(GPRs[RS],48,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Sthu (RS, RA, D)) -> { + iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RA]) :: oR; + iR := RSlice(GPRs[RS],48,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Sthux (RS, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + aR := iR; + iR := RSlice(GPRs[RS],48,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Stw (RS, RA, D)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + iR := RSlice(GPRs[RS],32,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Stwx (RS, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + iR := RSlice(GPRs[RS],32,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Stwu (RS, RA, D)) -> { + iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + aR := iR; + iR := RSlice(GPRs[RS],32,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Stwux (RS, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + aR := iR; + iR := RSlice(GPRs[RS],32,63) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Std (RS, RA, DS)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + iR := RFull(GPRs[RS]) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Stdx (RS, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + iR := RFull(GPRs[RS]) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Stdu (RS, RA, DS)) -> { + iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + aR := iR; + iR := RFull(GPRs[RS]) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Stdux (RS, RA, RB)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + aR := iR; + iR := RFull(GPRs[RS]) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Lq (RTp, RA, DQ, PT)) -> { + iR := bigendianmode_fp :: iR; + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + oR := RFull(GPRs[RTp]) :: RFull(GPRs[RTp + 1]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Stq (RSp, RA, DS)) -> { + iR := bigendianmode_fp :: iR; + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + iR := RFull(GPRs[RSp]) :: RFull(GPRs[RSp + 1]) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Lhbrx (RT, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Sthbrx (RS, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + iR := RSlice(GPRs[RS],56,63) :: RSlice(GPRs[RS],48,55) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Lwbrx (RT, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Stwbrx (RS, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + iR := RSlice(GPRs[RS],56,63) :: RSlice(GPRs[RS],48,55) :: RSlice(GPRs[RS],40,47) :: RSlice(GPRs[RS],32,39) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Ldbrx (RT, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_plain); + } + case (Stdbrx (RS, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + iR := RSlice(GPRs[RS],56,63) :: RSlice(GPRs[RS],48,55) :: RSlice(GPRs[RS],40,47) :: RSlice(GPRs[RS],32,39) :: RSlice(GPRs[RS],24,31) :: RSlice(GPRs[RS],16,23) :: RSlice(GPRs[RS],8,15) :: RSlice(GPRs[RS],0,7) :: iR; + ik := IK_mem_write(Write_plain); + } + case (Lmw (RT, RA, D)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + i := 0; + aR := iR; + foreach (r from RT to 31 by 1 in inc) { + oR := RFull(GPRs[r]) :: oR; + i := i + 32 + }; + ik := IK_mem_read(Read_plain); + } + case (Stmw (RS, RA, D)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + i := 0; + foreach (r from RS to 31 by 1 in inc) { + iR := RSlice(GPRs[r],32,63) :: iR; + i := i + 32 + }; + ik := IK_mem_write(Write_plain); + } + case (Lswi (RT, RA, NB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + ([|31|]) r := 0; + r := RT - 1; + j := 0; + i := 32; + foreach (n from (if NB == 0 then 32 else NB) to 1 by 1 in dec) { + if i == 32 then { + r := ([|31|]) (r + 1) mod 32; + oR := RFull(GPRs[r]) :: oR; + }; + oR := RSlice(GPRs[r],i,i + 7) :: oR; + j := j + 8; + i := i + 8; + if i == 64 then i := 32; + }; + ik := IK_mem_read(Read_plain); + } + case (Lswx (RT, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: RSlice("XER",57,63) :: iR; + aR := iR; + (* as long as XER[57 .. 63] is unknown all registers could be written to *) + foreach (r from 0 to 31 by 1 in inc) {oR := RFull(GPRs[r]) :: oR}; + ik := IK_mem_read(Read_plain); + } + case (Stswi (RS, RA, NB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + aR := iR; + ([|31|]) r := 0; + r := RS - 1; + j := 0; + i := 32; + foreach (n from (if NB == 0 then 32 else NB) to 1 by 1 in dec) { + if i == 32 then r := ([|32|]) (r + 1) mod 32; + iR := RSlice(GPRs[r],i,i + 7) :: iR; + j := j + 8; + i := i + 8; + if i == 64 then i := 32 + }; + ik := IK_mem_write(Write_plain); + } + case (Stswx (RS, RA, RB)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + ([|31|]) r := 0; + iR := RFull(GPRs[RB]) :: RSlice("XER",57,63) :: iR; + aR := iR; + r := RS - 1; + i := 32; + ([|128|]) n_top := 0b1111111; (* maximal XER[57 .. 63]; *) + j := 0; + foreach (n from n_top to 1 by 1 in dec) { + if i == 32 then r := ([|32|]) (r + 1) mod 32; + iR := RSlice(GPRs[r],i,i + 7) :: iR; + i := i + 8; + j := j + 8; + if i == 64 then i := 32 + }; + ik := IK_mem_write(Write_plain); + } + case (Addi (RT, RA, SI)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + } + case (Addis (RT, RA, SI)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + } + case (Add (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Subf (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Addic (RT, RA, SI)) -> { + iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RT]) :: RField("XER","CA") :: oR; + } + case (AddicDot (RT, RA, SI)) -> { + iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RT]) :: RField("XER","CA") :: oR; + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + case (Subfic (RT, RA, SI)) -> { + iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RT]) :: RField("XER","CA") :: oR; + } + case (Addc (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Subfc (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Adde (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + iR := RField("XER","CA") :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Subfe (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + iR := RField("XER","CA") :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Addme (RT, RA, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RField("XER","CA") :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Subfme (RT, RA, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RField("XER","CA") :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Addze (RT, RA, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RField("XER","CA") :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Subfze (RT, RA, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RField("XER","CA") :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Neg (RT, RA, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Mulli (RT, RA, SI)) -> { + iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + } + case (Mullw (RT, RA, RB, OE, Rc)) -> { + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Mulhw (RT, RA, RB, Rc)) -> { + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR; + oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR; + if Rc then { + iR := mode64bit_fp :: iR; + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Mulhwu (RT, RA, RB, Rc)) -> { + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR; + oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR; + if Rc then { + iR := mode64bit_fp :: iR; + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Divw (RT, RA, RB, OE, Rc)) -> { + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR; + oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR; + if Rc then { + iR := mode64bit_fp :: iR; + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Divwu (RT, RA, RB, OE, Rc)) -> { + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR; + oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR; + if Rc then { + iR := mode64bit_fp :: iR; + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Divwe (RT, RA, RB, OE, Rc)) -> { + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR; + oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR; + if Rc then { + iR := mode64bit_fp :: iR; + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Divweu (RT, RA, RB, OE, Rc)) -> { + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR; + oR := RSlice(GPRs[RT],32,63) :: RSlice(GPRs[RT],0,31) :: oR; + if Rc then { + iR := mode64bit_fp :: iR; + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Mulld (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Mulhd (RT, RA, RB, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Mulhdu (RT, RA, RB, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Divd (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Divdu (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Divde (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Divdeu (RT, RA, RB, OE, Rc)) -> { + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + if OE then { + iR := RField("XER","SO") :: iR; (* set_SO_OV *) + oR := RField("XER","OV") :: RField("XER","SO") :: oR; (* set_SO_OV *) + } + } + case (Cmpi (BF, L, RA, SI)) -> { + iR := (if L == 0 then RSlice(GPRs[RA],32,63) else RFull(GPRs[RA])) :: iR; + iR := RField("XER","SO") :: iR; + oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: oR; + } + case (Cmp (BF, L, RA, RB)) -> { + if L == 0 then + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR + else iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + iR := RField("XER","SO") :: iR; + oR := RSlice("CR",4 * BF,4 * BF + 35) :: oR; + } + case (Cmpli (BF, L, RA, UI)) -> { + iR := (if L == 0 then RSlice(GPRs[RA],32,63) else RFull(GPRs[RA])) :: iR; + iR := RField("XER","SO") :: iR; + oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: oR; + } + case (Cmpl (BF, L, RA, RB)) -> { + if L == 0 then + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR + else + iR := RFull(GPRs[RA]) :: RFull(GPRs[RB]) :: iR; + iR := RField("XER","SO") :: iR; + oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: oR; + } +(* case (Twi (TO, RA, SI)) -> { + iR := RSlice(GPRs[RA],32,63) :: iR; + } + case (Tw (TO, RA, RB)) -> { + iR := RSlice(GPRs[RA],32,63) :: RSlice(GPRs[RB],32,63) :: iR; + } + case (Tdi (TO, RA, SI)) -> () + case (Td (TO, RA, RB)) -> () *) + case (Isel (RT, RA, RB, BC)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RSliceBit("CR",BC + 32) :: iR; + iR := RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + } + case (Andi (RS, RA, UI)) -> { + iR := RFull(GPRs[RS]) :: RField("XER","SO") :: iR; + oR := RFull(GPRs[RA]) :: oR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + case (Andis (RS, RA, UI)) -> { + iR := RFull(GPRs[RS]) :: RField("XER","SO") :: iR; + oR := RFull(GPRs[RA]) :: oR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + case (Ori (RS, RA, UI)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + } + case (Oris (RS, RA, UI)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + } + case (Xori (RS, RA, UI)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + } + case (Xoris (RS, RA, UI)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + } + case (And (RS, RA, RB, Rc)) -> { + iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Xor (RS, RA, RB, Rc)) -> { + if RS == RB then { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + } + else { + iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + }; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Nand (RS, RA, RB, Rc)) -> { + iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Or (RS, RA, RB, Rc)) -> { + iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Nor (RS, RA, RB, Rc)) -> { + iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Eqv (RS, RA, RB, Rc)) -> { + iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Andc (RS, RA, RB, Rc)) -> { + iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Orc (RS, RA, RB, Rc)) -> { + iR := RFull(GPRs[RS]) :: RFull(GPRs[RB]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Extsb (RS, RA, Rc)) -> { + iR := RSliceBit(GPRs[RS],56) :: iR; + iR := RSlice(GPRs[RS],56,63) :: iR; + oR := RSlice(GPRs[RA],56,63) :: oR; + oR := RSlice(GPRs[RA],0,55) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Extsh (RS, RA, Rc)) -> { + iR := RSliceBit(GPRs[RS],48) :: iR; + iR := RSlice(GPRs[RS],48,63) :: iR; + oR := RSlice(GPRs[RA],48,63) :: oR; + oR := RSlice(GPRs[RA],0,47) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Cntlzw (RS, RA, Rc)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + } + } + case (Cmpb (RS, RA, RB)) -> { + foreach (n from 0 to 7 by 1 in inc) { + iR := RSlice(GPRs[RS],8 * n,8 * n + 7) :: RSlice(GPRs[RB],8 * n,8 * n + 7) :: iR; + oR := RSlice(GPRs[RA],8 * n,8 * n + 7) :: oR; + } + } + case (Popcntb (RS, RA)) -> { + foreach (i from 0 to 7 by 1 in inc) { + foreach (j from 0 to 7 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 8 + j) :: iR; + oR := RSlice(GPRs[RA],i * 8,i * 8 + 7) :: oR; + } + } + case (Popcntw (RS, RA)) -> { + foreach (i from 0 to 1 by 1 in inc) { + foreach (j from 0 to 31 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 32 + j) :: iR; + oR := RSlice(GPRs[RA],i * 32,i * 32 + 31) :: oR; + } + } + case (Prtyd (RS, RA)) -> { + foreach (i from 0 to 7 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 8 + 7) :: iR; + oR := RFull(GPRs[RA]) :: oR; + } + case (Prtyw (RS, RA)) -> { + foreach (i from 0 to 3 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 8 + 7) :: iR; + foreach (i from 4 to 7 by 1 in inc) iR := RSliceBit(GPRs[RS],i * 8 + 7) :: iR; + oR := RSlice(GPRs[RA],0,31) :: oR; + oR := RSlice(GPRs[RA],32,63) :: oR; + } + case (Extsw (RS, RA, Rc)) -> { + iR := RSliceBit(GPRs[RS],32) :: iR; + iR := RSlice(GPRs[RS],32,63) :: iR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RFull(GPRs[RA]) :: oR; + } + case (Cntlzd (RS, RA, Rc)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Popcntd (RS, RA)) -> { + foreach (i from 0 to 63 by 1 in inc) iR := RSliceBit(GPRs[RS],i) :: iR; + oR := RFull(GPRs[RA]) :: oR; + } + (* TODO: here the footprint depends on dynamic data *) + case (Bpermd (RS, RA, RB)) -> { + foreach (i from 0 to 7 by 1 in inc) { + iR := RSlice(GPRs[RS],8 * i,8 * i + 7) :: iR; + iR := RFull(GPRs[RB]) :: iR; (* this is actually only a single bit, *) + (* which one it is depends on the read before *) + oR := RFull(GPRs[RA]) :: oR; + } + } + case (Rlwinm (RS, RA, SH, MB, ME, Rc)) -> { + iR := RSlice(GPRs[RS],32,63) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Rlwnm (RS, RA, RB, MB, ME, Rc)) -> { + iR := RSlice(GPRs[RB],59,63) :: RSlice(GPRs[RS],32,63) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Rlwimi (RS, RA, SH, MB, ME, Rc)) -> { + iR := RSlice(GPRs[RS],32,63) :: iR; + iR := RFull(GPRs[RA]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Rldicl (RS, RA, sh, mb, Rc)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Rldicr (RS, RA, sh, me, Rc)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Rldic (RS, RA, sh, mb, Rc)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Rldcl (RS, RA, RB, mb, Rc)) -> { + iR := RSlice(GPRs[RB],58,63) :: iR; + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Rldcr (RS, RA, RB, me, Rc)) -> { + iR := RSlice(GPRs[RB],58,63) :: iR; + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Rldimi (RS, RA, sh, mb, Rc)) -> { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Slw (RS, RA, RB, Rc)) -> { + iR := RSlice(GPRs[RB],59,63) :: iR; + iR := RSlice(GPRs[RS],32,63) :: iR; + iR := RSliceBit(GPRs[RB],58) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Srw (RS, RA, RB, Rc)) -> { + iR := RSlice(GPRs[RB],59,63) :: iR; + iR := RSlice(GPRs[RS],32,63) :: iR; + iR := RSliceBit(GPRs[RB],58) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Srawi (RS, RA, SH, Rc)) -> { + iR := RSlice(GPRs[RS],32,63) :: iR; + iR := RSliceBit(GPRs[RS],32) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + } + case (Sraw (RS, RA, RB, Rc)) -> { + iR := RSlice(GPRs[RB],59,63) :: iR; + iR := RSlice(GPRs[RS],32,63) :: RSliceBit(GPRs[RB],58) :: RSliceBit(GPRs[RS],32) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + } + case (Sld (RS, RA, RB, Rc)) -> { + iR := RSlice(GPRs[RB],58,63) :: RFull(GPRs[RS]) :: iR; + iR := RSliceBit(GPRs[RB],57) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Srd (RS, RA, RB, Rc)) -> { + iR := RSlice(GPRs[RB],58,63) :: RFull(GPRs[RS]) :: iR; + iR := RSliceBit(GPRs[RB],57) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + } + case (Sradi (RS, RA, sh, Rc)) -> { + iR := RFull(GPRs[RS]) :: iR; + iR := RSliceBit(GPRs[RS],0) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + } + case (Srad (RS, RA, RB, Rc)) -> { + iR := RSlice(GPRs[RB],58,63) :: RFull(GPRs[RS]) :: RSliceBit(GPRs[RB],57) :: RSliceBit(GPRs[RS],0) :: iR; + oR := RFull(GPRs[RA]) :: oR; + if Rc then { + iR := RField("XER","SO") :: iR; + oR := RField("CR","CR0") :: oR; (* set_overflow_cr0 *) + }; + oR := RField("XER","CA") :: oR; + } + case (Cdtbcd (RS, RA)) -> { + foreach (i from 0 to 1 by 1 in inc) { + n := i * 32; + iR := RSlice(GPRs[RS],n + 12,n + 31) :: iR; + oR := RSlice(GPRs[RA],n + 0,n + 31) :: oR; + } + } + case (Cbcdtd (RS, RA)) -> { + foreach (i from 0 to 1 by 1 in inc) { + n := i * 32; + iR := RSlice(GPRs[RS],n + 8,n + 31) :: iR; + oR := RSlice(GPRs[RA],n + 0,n + 31) :: oR; + } + } + case (Addg6s (RT, RA, RB)) -> { + foreach (i from 0 to 15 by 1 in inc) { + iR := RSlice(GPRs[RA],4 * i,63) :: iR; + iR := RSlice(GPRs[RB],4 * i,63) :: iR; + }; + oR := RFull(GPRs[RT]) :: oR; + } + case (Mtspr (RS, spr)) -> { + n := spr[5 .. 9] : spr[0 .. 4]; + if n == 1 then { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull("XER") :: oR; + } + else { + (* the below is debatable: to determine the length of that register, does it + * really need to read the content? *) + iR := RFull(SPRs[n]) ::iR; + if length_spr(n) == 64 then { + iR := RFull(GPRs[RS]) :: iR; + oR := RFull(SPRs[n]) :: oR; + } + else if n == 152 then { + iR := RSlice(GPRs[RS],32,63) :: iR; + oR := RFull("CTRL") :: oR; + } + else (); + } + } + case (Mfspr (RT, spr)) -> { + n := spr[5 .. 9] : spr[0 .. 4]; + iR := RFull(SPRs[n]) :: iR; + oR := RFull(GPRs[RT]) :: oR; + } + case (Mtcrf (RS, FXM)) -> { + iR := RFull("CR") :: RSlice(GPRs[RS],32,63) :: iR; + oR := RFull("CR") :: oR; + } + case (Mfcr (RT)) -> { + iR := RFull("CR") :: iR; + oR := RFull(GPRs[RT]) :: oR; + } + case (Mtocrf (RS, FXM)) -> { + ([|7|]) n := 0; + count := 0; + foreach (i from 0 to 7 by 1 in inc) + if FXM[i] == 1 + then { + n := i; + count := count + 1 + } + else (); + if count == 1 + then { + oR := RSlice("CR",4 * n + 32,4 * n + 35) :: oR; + iR := RSlice(GPRs[RS],4 * n + 32,4 * n + 35) :: iR; + } + else oR := RFull("CR") :: oR; + } + case (Mfocrf (RT, FXM)) -> { + ([|7|]) n := 0; + count := 0; + foreach (i from 0 to 7 by 1 in inc) + if FXM[i] == 1 + then { + n := i; + count := count + 1 + } + else (); + if count == 1 + then { + iR := RSlice("CR",4 * n + 32,4 * n + 35) :: iR; + oR := RFull(GPRs[RT]) :: oR; + } + else oR := RFull(GPRs[RT]) :: oR; + } + case (Mcrxr (BF)) -> { + iR := RSlice("XER",32,35) :: iR; + oR := RSlice("CR",4 * BF + 32,4 * BF + 35) :: RSlice("XER",32,35) :: oR; + } + case (Dlmzb (RS, RA, RB, Rc)) -> () + case (Macchws (RT, RA, RB, OE, Rc)) -> () + case (Macchwu (RT, RA, RB, OE, Rc)) -> () + case (Macchwsu (RT, RA, RB, OE, Rc)) -> () + case (Machhws (RT, RA, RB, OE, Rc)) -> () + case (Machhwu (RT, RA, RB, OE, Rc)) -> () + case (Machhwsu (RT, RA, RB, OE, Rc)) -> () + case (Maclhw (RT, RA, RB, OE, Rc)) -> () + case (Maclhws (RT, RA, RB, OE, Rc)) -> () + case (Maclhwu (RT, RA, RB, OE, Rc)) -> () + case (Maclhwsu (RT, RA, RB, OE, Rc)) -> () + case (Mulchw (RT, RA, RB, Rc)) -> () + case (Mulchwu (RT, RA, RB, Rc)) -> () + case (Mulhhw (RT, RA, RB, Rc)) -> () + case (Mulhhwu (RT, RA, RB, Rc)) -> () + case (Mullhw (RT, RA, RB, Rc)) -> () + case (Mullhwu (RT, RA, RB, Rc)) -> () + case (Nmacchw (RT, RA, RB, OE, Rc)) -> () + case (Nmacchws (RT, RA, RB, OE, Rc)) -> () + case (Nmachhw (RT, RA, RB, OE, Rc)) -> () + case (Nmachhws (RT, RA, RB, OE, Rc)) -> () + case (Nmaclhw (RT, RA, RB, OE, Rc)) -> () + case (Nmaclhws (RT, RA, RB, OE, Rc)) -> () + case (Icbi (RA, RB)) -> () + case (Icbt (CT, RA, RB)) -> () + case (Dcba (RA, RB)) -> () + case (Dcbt (TH, RA, RB)) -> () + case (Dcbtst (TH, RA, RB)) -> () + case (Dcbz (RA, RB)) -> () + case (Dcbst (RA, RB)) -> () + case (Dcbf (L, RA, RB)) -> () + case Isync -> { + ik := IK_barrier(Barrier_Isync); + } + case (Lbarx (RT, RA, RB, EH)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_reserve); + } + case (Lharx (RT, RA, RB, EH)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_reserve); + } + case (Lwarx (RT, RA, RB, EH)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_reserve); + } + case (Stbcx (RS, RA, RB)) -> { + ik := IK_mem_write(Write_conditional); + } + case (Sthcx (RS, RA, RB)) -> { + ik := IK_mem_write(Write_conditional); + } + case (Stwcx (RS, RA, RB)) -> { + ik := IK_mem_write(Write_conditional); + } + case (Ldarx (RT, RA, RB, EH)) -> { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + iR := RFull(GPRs[RB]) :: iR; + aR := iR; + oR := RFull(GPRs[RT]) :: oR; + ik := IK_mem_read(Read_reserve); + } + case (Stdcx (RS, RA, RB)) -> { + ik := IK_mem_write(Write_conditional); + } + case (Sync (L)) -> { + ik := switch L { + case 0b00 -> { IK_barrier(Barrier_Sync) } + case 0b01 -> { IK_barrier(Barrier_LwSync) } + } + } + case Eieio -> { + ik := IK_barrier(Barrier_Eieio) + } + case (Wait (WC)) -> () + }; + (iR,oR,aR,Nias,Dia,ik) +} + +val ast -> (regfps,regfps,regfps,niafps,diafp,instruction_kind) effect {rreg} recalculate_lswx_reg_footprint +(* run when footprint transition is taken, supplying n_top = XER[57 .. 63] as a parameter *) +function (regfps,regfps,regfps,niafps,diafp,instruction_kind) recalculate_lswx_reg_footprint instr = { + (regfps) iR := [|| ||]; + (regfps) oR := [|| ||]; + Nias := [|| NIAFP_successor ||]; + Dia := DIAFP_none; + ik := IK_mem_read(Read_plain); + let (RT,RA,RB) = switch instr {case (Lswx (RT, RA, RB)) -> (RT,RA,RB)} in { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + ([|31|]) r := 0; + iR := RFull(GPRs[RB]) :: RSlice("XER",57,63) :: iR; + aR := iR; + r := RT - 1; + i := 32; + ([|128|]) n_top := XER[57 .. 63]; + if n_top == 0 then + oR := RFull(GPRs[RT]) :: oR + else { + j := 0; + n_r := n_top quot 4; + n_mod := n_top mod 4; + n_r := if n_mod == 0 then n_r else n_r + 1; + foreach (n from n_r to 1 by 1 in dec) { + r := ([|32|]) (r + 1) mod 32; + j := j + 32; + oR := RFull(GPRs[r]) :: oR + } + }; + (iR,oR,aR,Nias,Dia,ik)} +} + +val ast -> (regfps,regfps,regfps,niafps,diafp,instruction_kind) effect {rreg} recalculate_stswx_reg_footprint +(* run when footprint transition is taken, supplying n_top = XER[57 .. 63] as a parameter *) +function (regfps,regfps,regfps,niafps,diafp,instruction_kind) recalculate_stswx_reg_footprint instr = { + (regfps) iR := [|| ||]; + (regfps) oR := [|| ||]; + Nias := [|| NIAFP_successor ||]; + Dia := DIAFP_none; + ik := IK_mem_write(Write_plain); + let (RS,RA,RB) = switch instr {case (Stswx (RS, RA, RB)) -> (RS,RA,RB)} in { + if RA == 0 then () else iR := RFull(GPRs[RA]) :: iR; + ([|31|]) r := 0; + iR := RFull(GPRs[RB]) :: RSlice("XER",57,63) :: iR; + aR := iR; + r := RS - 1; + i := 32; + ([|128|]) n_top := XER[57 .. 63]; + j := 0; + foreach (n from n_top to 1 by 1 in dec) { + if i == 32 then r := ([|32|]) (r + 1) mod 32; + iR := RSlice(GPRs[r],i,i + 7) :: iR; + i := i + 8; + j := j + 8; + if i == 64 then i := 32 + }; + ik := IK_mem_write(Write_plain); + (iR,oR,aR,Nias,Dia,ik)} +}
\ No newline at end of file diff --git a/risc-v/Makefile b/risc-v/Makefile index 856a48eb..bc46e4c2 100644 --- a/risc-v/Makefile +++ b/risc-v/Makefile @@ -1,13 +1,22 @@ - SAIL:=../src/sail.native -SOURCES:=riscv.sail ../etc/regfp.sail riscv_regfp.sail -all: lem_ast shallow +LEM:=../../lem/lem + +SOURCES:=riscv_types.sail riscv.sail ../etc/regfp.sail riscv_regfp.sail + + +all: riscv.lem riscv.ml riscv_embed.lem + +riscv.lem: $(SOURCES) + $(SAIL) -lem_ast -o riscv $(SOURCES) + +riscv.ml: riscv.lem ../src/lem_interp/interp_ast.lem + $(LEM) -ocaml -lib ../src/lem_interp/ $< -lem_ast: $(SOURCES) $(SAIL) - $(SAIL) -lem_ast $(SOURCES) -shallow: $(SOURCES) $(SAIL) - $(SAIL) -lem_lib Riscv_extras_embed -lem $(SOURCES) +riscv_embed.lem: $(SOURCES) +# also generates riscv_embed_sequential.lem, riscv_embed_types.lem, riscv_toFromInterp.lem + $(SAIL) -lem -lem_lib Riscv_extras_embed -o riscv $(SOURCES) clean: - rm -f riscv.lem riscv_embed*.lem + rm -f riscv.lem riscv.ml + rm -f riscv_embed*.lem riscv_toFromInterp.lem diff --git a/risc-v/hgen/ast.hgen b/risc-v/gen/ast.hgen index 8983b5ae..b1968173 100644 --- a/risc-v/hgen/ast.hgen +++ b/risc-v/gen/ast.hgen @@ -5,9 +5,13 @@ | `RISCVIType of bit12 * reg * reg * riscvIop | `RISCVShiftIop of bit6 * reg * reg * riscvSop | `RISCVRType of reg * reg * reg * riscvRop -| `RISCVLoad of bit12 * reg * reg * bool * wordWidth -| `RISCVStore of bit12 * reg * reg * wordWidth +| `RISCVLoad of bit12 * reg * reg * bool * wordWidth * bool * bool +| `RISCVStore of bit12 * reg * reg * wordWidth * bool * bool | `RISCVADDIW of bit12 * reg * reg | `RISCVSHIFTW of bit5 * reg * reg * riscvSop | `RISCVRTYPEW of reg * reg * reg * riscvRopw | `RISCVFENCE of bit4 * bit4 +| `RISCVFENCEI +| `RISCVLoadRes of bool * bool * reg * wordWidth * reg +| `RISCVStoreCon of bool * bool * reg * reg * wordWidth * reg +| `RISCVAMO of riscvAmoop * bool * bool * reg * reg * wordWidth * reg diff --git a/risc-v/gen/fold.hgen b/risc-v/gen/fold.hgen new file mode 100644 index 00000000..4c51e114 --- /dev/null +++ b/risc-v/gen/fold.hgen @@ -0,0 +1,16 @@ +| `RISCVThreadStart -> (y_reg, y_sreg) +| `RISCVUTYPE (_, r0, _) -> fold_reg r0 (y_reg, y_sreg) +| `RISCVJAL (_, r0) -> fold_reg r0 (y_reg, y_sreg) +| `RISCVJALR (_, r0, r1) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVBType (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVIType (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVShiftIop (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVRType (r0, r1, r2, _) -> fold_reg r0 (fold_reg r1 (fold_reg r2 (y_reg, y_sreg))) +| `RISCVLoad (_, r0, r1, _, _, _, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVStore (_, r0, r1, _, _, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVADDIW (_, r0, r1) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVSHIFTW (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) +| `RISCVRTYPEW (r0, r1, r2, _) -> fold_reg r0 (fold_reg r1 (fold_reg r2 (y_reg, y_sreg))) +| `RISCVLoadRes (_, _, rs1, _, rd) -> fold_reg rs1 (fold_reg rd (y_reg, y_sreg)) +| `RISCVStoreCon (_, _, rs2, rs1, _, rd) -> fold_reg rs2 (fold_reg rs1 (fold_reg rd (y_reg, y_sreg))) +| `RISCVAMO (_, _, _, rs2, rs1, _, rd) -> fold_reg rs2 (fold_reg rs1 (fold_reg rd (y_reg, y_sreg))) diff --git a/risc-v/hgen/herdtools_ast_to_shallow_ast.hgen b/risc-v/gen/herdtools_ast_to_shallow_ast.hgen index 50026612..07c1d082 100644 --- a/risc-v/hgen/herdtools_ast_to_shallow_ast.hgen +++ b/risc-v/gen/herdtools_ast_to_shallow_ast.hgen @@ -3,10 +3,10 @@ translate_imm20 "imm" imm, translate_reg "rd" rd, translate_uop op) -| `RISCVJAL(imm, rd) -> JAL0( +| `RISCVJAL(imm, rd) -> RISCV_JAL( translate_imm21 "imm" imm, translate_reg "rd" rd) -| `RISCVJALR(imm, rs, rd) -> JALR0( +| `RISCVJALR(imm, rs, rd) -> RISCV_JALR( translate_imm12 "imm" imm, translate_reg "rs" rd, translate_reg "rd" rd) @@ -30,17 +30,21 @@ translate_reg "rs1" rs1, translate_reg "rd" rd, translate_rop op) -| `RISCVLoad(imm, rs, rd, unsigned, width) -> LOAD( +| `RISCVLoad(imm, rs, rd, unsigned, width, aq, rl) -> LOAD( translate_imm12 "imm" imm, translate_reg "rs" rs, translate_reg "rd" rd, translate_bool "unsigned" unsigned, - translate_wordWidth width) -| `RISCVStore(imm, rs, rd, width) -> STORE ( + translate_wordWidth width, + translate_bool "aq" aq, + translate_bool "rl" rl) +| `RISCVStore(imm, rs, rd, width, aq, rl) -> STORE ( translate_imm12 "imm" imm, translate_reg "rs" rs, translate_reg "rd" rd, - translate_wordWidth width) + translate_wordWidth width, + translate_bool "aq" aq, + translate_bool "rl" rl) | `RISCVADDIW(imm, rs, rd) -> ADDIW( translate_imm12 "imm" imm, translate_reg "rs" rs, @@ -56,5 +60,27 @@ translate_reg "rd" rd, translate_ropw op) | `RISCVFENCE(pred, succ) -> FENCE( - translate_imm4 "pred" pred, - translate_imm4 "succ" succ) + translate_imm4 "pred" pred, + translate_imm4 "succ" succ) +| `RISCVFENCEI -> FENCEI +| `RISCVLoadRes(aq, rl, rs1, width, rd) -> LOADRES( + translate_bool "aq" aq, + translate_bool "rl" rl, + translate_reg "rs1" rs1, + translate_wordWidth width, + translate_reg "rd" rd) +| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> STORECON( + translate_bool "aq" aq, + translate_bool "rl" rl, + translate_reg "rs2" rs2, + translate_reg "rs1" rs1, + translate_wordWidth width, + translate_reg "rd" rd) +| `RISCVAMO (op, aq, rl, rs2, rs1, width, rd) -> AMO( + translate_amoop op, + translate_bool "aq" aq, + translate_bool "rl" rl, + translate_reg "rs2" rs2, + translate_reg "rs1" rs1, + translate_wordWidth width, + translate_reg "rd" rd) diff --git a/risc-v/hgen/herdtools_types_to_shallow_types.hgen b/risc-v/gen/herdtools_types_to_shallow_types.hgen index 4d8bd87a..e6edd24d 100644 --- a/risc-v/hgen/herdtools_types_to_shallow_types.hgen +++ b/risc-v/gen/herdtools_types_to_shallow_types.hgen @@ -4,48 +4,59 @@ let translate_reg name value = Sail_values.to_vec0 is_inc (Nat_big_num.of_int 5,Nat_big_num.of_int (reg_to_int value)) let translate_uop op = match op with - | RISCVLUI -> LUI0 - | RISCVAUIPC -> AUIPC + | RISCVLUI -> RISCV_LUI + | RISCVAUIPC -> RISCV_AUIPC let translate_bop op = match op with - | RISCVBEQ -> BEQ0 - | RISCVBNE -> BNE - | RISCVBLT -> BLT - | RISCVBGE -> BGE - | RISCVBLTU -> BLTU - | RISCVBGEU -> BGEU + | RISCVBEQ -> RISCV_BEQ + | RISCVBNE -> RISCV_BNE + | RISCVBLT -> RISCV_BLT + | RISCVBGE -> RISCV_BGE + | RISCVBLTU -> RISCV_BLTU + | RISCVBGEU -> RISCV_BGEU let translate_iop op = match op with - | RISCVADDI -> ADDI0 - | RISCVSLTI -> SLTI0 - | RISCVSLTIU -> SLTIU0 - | RISCVXORI -> XORI0 - | RISCVORI -> ORI0 - | RISCVANDI -> ANDI0 + | RISCVADDI -> RISCV_ADDI + | RISCVSLTI -> RISCV_SLTI + | RISCVSLTIU -> RISCV_SLTIU + | RISCVXORI -> RISCV_XORI + | RISCVORI -> RISCV_ORI + | RISCVANDI -> RISCV_ANDI let translate_sop op = match op with - | RISCVSLLI -> SLLI - | RISCVSRLI -> SRLI - | RISCVSRAI -> SRAI + | RISCVSLLI -> RISCV_SLLI + | RISCVSRLI -> RISCV_SRLI + | RISCVSRAI -> RISCV_SRAI let translate_rop op = match op with - | RISCVADD -> ADD0 - | RISCVSUB -> SUB0 - | RISCVSLL -> SLL0 - | RISCVSLT -> SLT0 - | RISCVSLTU -> SLTU0 - | RISCVXOR -> XOR0 - | RISCVSRL -> SRL0 - | RISCVSRA -> SRA0 - | RISCVOR -> OR0 - | RISCVAND -> AND0 + | RISCVADD -> RISCV_ADD + | RISCVSUB -> RISCV_SUB + | RISCVSLL -> RISCV_SLL + | RISCVSLT -> RISCV_SLT + | RISCVSLTU -> RISCV_SLTU + | RISCVXOR -> RISCV_XOR + | RISCVSRL -> RISCV_SRL + | RISCVSRA -> RISCV_SRA + | RISCVOR -> RISCV_OR + | RISCVAND -> RISCV_AND let translate_ropw op = match op with - | RISCVADDW -> ADDW - | RISCVSUBW -> SUBW - | RISCVSLLW -> SLLW - | RISCVSRLW -> SRLW - | RISCVSRAW -> SRAW + | RISCVADDW -> RISCV_ADDW + | RISCVSUBW -> RISCV_SUBW + | RISCVSLLW -> RISCV_SLLW + | RISCVSRLW -> RISCV_SRLW + | RISCVSRAW -> RISCV_SRAW + +let translate_amoop op = match op with + | RISCVAMOSWAP -> AMOSWAP + | RISCVAMOADD -> AMOADD + | RISCVAMOXOR -> AMOXOR + | RISCVAMOAND -> AMOAND + | RISCVAMOOR -> AMOOR + | RISCVAMOMIN -> AMOMIN + | RISCVAMOMAX -> AMOMAX + | RISCVAMOMINU -> AMOMINU + | RISCVAMOMAXU -> AMOMAXU let translate_wordWidth op = match op with | RISCVBYTE -> BYTE diff --git a/risc-v/gen/lexer.hgen b/risc-v/gen/lexer.hgen new file mode 100644 index 00000000..e42b8a62 --- /dev/null +++ b/risc-v/gen/lexer.hgen @@ -0,0 +1,190 @@ +"lui" , UTYPE { op=RISCVLUI }; +"auipc" , UTYPE { op=RISCVAUIPC }; + +"jal", JAL (); +"jalr", JALR (); + +"beq", BTYPE {op=RISCVBEQ}; +"bne", BTYPE {op=RISCVBNE}; +"blt", BTYPE {op=RISCVBLT}; +"bge", BTYPE {op=RISCVBGE}; +"bltu", BTYPE {op=RISCVBLTU}; +"bgeu", BTYPE {op=RISCVBGEU}; + +"addi", ITYPE {op=RISCVADDI}; +"stli", ITYPE {op=RISCVSLTI}; +"sltiu", ITYPE {op=RISCVSLTIU}; +"xori", ITYPE {op=RISCVXORI}; +"ori", ITYPE {op=RISCVORI}; +"andi", ITYPE {op=RISCVANDI}; + +"slli", SHIFTIOP{op=RISCVSLLI}; +"srli", SHIFTIOP{op=RISCVSRLI}; +"srai", SHIFTIOP{op=RISCVSRAI}; + +"add", RTYPE{op=RISCVADD}; +"sub", RTYPE{op=RISCVSUB}; +"sll", RTYPE{op=RISCVSLL}; +"slt", RTYPE{op=RISCVSLT}; +"sltu", RTYPE{op=RISCVSLT}; +"xor", RTYPE{op=RISCVXOR}; +"srl", RTYPE{op=RISCVSRL}; +"sra", RTYPE{op=RISCVSRA}; +"or", RTYPE{op=RISCVOR}; +"and", RTYPE{op=RISCVAND}; + +"lb", LOAD{unsigned=false; width=RISCVBYTE; aq=false; rl=false}; +"lbu", LOAD{unsigned=true; width=RISCVBYTE; aq=false; rl=false}; +"lh", LOAD{unsigned=false; width=RISCVHALF; aq=false; rl=false}; +"lhu", LOAD{unsigned=true; width=RISCVHALF; aq=false; rl=false}; +"lw", LOAD{unsigned=false; width=RISCVWORD; aq=false; rl=false}; +"lwu", LOAD{unsigned=true; width=RISCVWORD; aq=false; rl=false}; +"ld", LOAD{unsigned=false; width=RISCVDOUBLE; aq=false; rl=false}; + +"lb.aq", LOAD{unsigned=false; width=RISCVBYTE; aq=true; rl=false}; +"lbu.aq", LOAD{unsigned=true; width=RISCVBYTE; aq=true; rl=false}; +"lh.aq", LOAD{unsigned=false; width=RISCVHALF; aq=true; rl=false}; +"lhu.aq", LOAD{unsigned=true; width=RISCVHALF; aq=true; rl=false}; +"lw.aq", LOAD{unsigned=false; width=RISCVWORD; aq=true; rl=false}; +"lwu.aq", LOAD{unsigned=true; width=RISCVWORD; aq=true; rl=false}; +"ld.aq", LOAD{unsigned=false; width=RISCVDOUBLE; aq=true; rl=false}; + +"lb.aq.rl", LOAD{unsigned=false; width=RISCVBYTE; aq=true; rl=true}; +"lbu.aq.rl", LOAD{unsigned=true; width=RISCVBYTE; aq=true; rl=true}; +"lh.aq.rl", LOAD{unsigned=false; width=RISCVHALF; aq=true; rl=true}; +"lhu.aq.rl", LOAD{unsigned=true; width=RISCVHALF; aq=true; rl=true}; +"lw.aq.rl", LOAD{unsigned=false; width=RISCVWORD; aq=true; rl=true}; +"lwu.aq.rl", LOAD{unsigned=true; width=RISCVWORD; aq=true; rl=true}; +"ld.aq.rl", LOAD{unsigned=false; width=RISCVDOUBLE; aq=true; rl=true}; + +"sb", STORE{width=RISCVBYTE; aq=false; rl=false}; +"sh", STORE{width=RISCVHALF; aq=false; rl=false}; +"sw", STORE{width=RISCVWORD; aq=false; rl=false}; +"sd", STORE{width=RISCVDOUBLE; aq=false; rl=false}; + +"sb.rl", STORE{width=RISCVBYTE; aq=false; rl=true}; +"sh.rl", STORE{width=RISCVHALF; aq=false; rl=true}; +"sw.rl", STORE{width=RISCVWORD; aq=false; rl=true}; +"sd.rl", STORE{width=RISCVDOUBLE; aq=false; rl=true}; + +"sb.aq.rl", STORE{width=RISCVBYTE; aq=true; rl=true}; +"sh.aq.rl", STORE{width=RISCVHALF; aq=true; rl=true}; +"sw.aq.rl", STORE{width=RISCVWORD; aq=true; rl=true}; +"sd.aq.rl", STORE{width=RISCVDOUBLE; aq=true; rl=true}; + +"addiw", ADDIW (); + +"slliw", SHIFTW{op=RISCVSLLI}; +"srliw", SHIFTW{op=RISCVSRLI}; +"sraiw", SHIFTW{op=RISCVSRAI}; + +"addw", RTYPEW{op=RISCVADDW}; +"subw", RTYPEW{op=RISCVSUBW}; +"sslw", RTYPEW{op=RISCVSLLW}; +"srlw", RTYPEW{op=RISCVSRLW}; +"sraw", RTYPEW{op=RISCVSRAW}; + +"fence", FENCE (); +"r", FENCEOPTION Fence_R; +"w", FENCEOPTION Fence_W; +"rw", FENCEOPTION Fence_RW; + +"fence.i", FENCEI (); + +"lr.w", LOADRES {width=RISCVWORD; aq=false; rl=false}; +"lr.w.aq", LOADRES {width=RISCVWORD; aq=true; rl=false}; +"lr.w.aq.rl", LOADRES {width=RISCVWORD; aq=true; rl=true}; +"lr.d", LOADRES {width=RISCVDOUBLE; aq=false; rl=false}; +"lr.d.aq", LOADRES {width=RISCVDOUBLE; aq=true; rl=false}; +"lr.d.aq.rl", LOADRES {width=RISCVDOUBLE; aq=true; rl=true}; + +"sc.w", STORECON {width=RISCVWORD; aq=false; rl=false}; +"sc.w.rl", STORECON {width=RISCVWORD; aq=false; rl=true}; +"sc.w.aq.rl", STORECON {width=RISCVWORD; aq=true; rl=true}; +"sc.d", STORECON {width=RISCVDOUBLE; aq=false; rl=false}; +"sc.d.rl", STORECON {width=RISCVDOUBLE; aq=false; rl=true}; +"sc.d.aq.rl", STORECON {width=RISCVDOUBLE; aq=true; rl=true}; + +"amoswap.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOSWAP}; +"amoadd.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOADD}; +"amoand.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOAND}; +"amoor.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOOR}; +"amoxor.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOXOR}; +"amomax.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMAX}; +"amomin.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMIN}; +"amomaxu.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMAXU}; +"amominu.w", AMO {width=RISCVWORD; aq=false; rl=false; op=RISCVAMOMINU}; + +"amoswap.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOSWAP}; +"amoadd.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOADD}; +"amoand.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOAND}; +"amoor.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOOR}; +"amoxor.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOXOR}; +"amomax.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMAX}; +"amomin.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMIN}; +"amomaxu.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMAXU}; +"amominu.d", AMO {width=RISCVDOUBLE; aq=false; rl=false; op=RISCVAMOMINU}; + +"amoswap.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOSWAP}; +"amoadd.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOADD}; +"amoand.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOAND}; +"amoor.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOOR}; +"amoxor.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOXOR}; +"amomax.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMAX}; +"amomin.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMIN}; +"amomaxu.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMAXU}; +"amominu.w.aq", AMO {width=RISCVWORD; aq=true; rl=false; op=RISCVAMOMINU}; + +"amoswap.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOSWAP}; +"amoadd.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOADD}; +"amoand.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOAND}; +"amoor.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOOR}; +"amoxor.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOXOR}; +"amomax.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMAX}; +"amomin.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMIN}; +"amomaxu.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMAXU}; +"amominu.d.aq", AMO {width=RISCVDOUBLE; aq=true; rl=false; op=RISCVAMOMINU}; + +"amoswap.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOSWAP}; +"amoadd.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOADD}; +"amoand.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOAND}; +"amoor.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOOR}; +"amoxor.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOXOR}; +"amomax.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMAX}; +"amomin.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMIN}; +"amomaxu.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMAXU}; +"amominu.w.rl", AMO {width=RISCVWORD; aq=false; rl=true; op=RISCVAMOMINU}; + +"amoswap.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOSWAP}; +"amoadd.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOADD}; +"amoand.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOAND}; +"amoor.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOOR}; +"amoxor.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOXOR}; +"amomax.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMAX}; +"amomin.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMIN}; +"amomaxu.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMAXU}; +"amominu.d.rl", AMO {width=RISCVDOUBLE; aq=false; rl=true; op=RISCVAMOMINU}; + +"amoswap.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOSWAP}; +"amoadd.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOADD}; +"amoand.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOAND}; +"amoor.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOOR}; +"amoxor.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOXOR}; +"amomax.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMAX}; +"amomin.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMIN}; +"amomaxu.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMAXU}; +"amominu.w.aq.rl", AMO {width=RISCVWORD; aq=true; rl=true; op=RISCVAMOMINU}; + +"amoswap.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOSWAP}; +"amoadd.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOADD}; +"amoand.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOAND}; +"amoor.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOOR}; +"amoxor.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOXOR}; +"amomax.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMAX}; +"amomin.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMIN}; +"amomaxu.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMAXU}; +"amominu.d.aq.rl", AMO {width=RISCVDOUBLE; aq=true; rl=true; op=RISCVAMOMINU}; + +(** pseudo instructions *********************************************) + +"li", LI () diff --git a/risc-v/gen/map.hgen b/risc-v/gen/map.hgen new file mode 100644 index 00000000..bab5ced8 --- /dev/null +++ b/risc-v/gen/map.hgen @@ -0,0 +1,15 @@ +| `RISCVUTYPE (x, r0, y) -> `RISCVUTYPE (x, map_reg r0, y) +| `RISCVJAL (x, r0) -> `RISCVJAL (x, map_reg r0) +| `RISCVJALR (x, r0, r1) -> `RISCVJALR (x, map_reg r0, map_reg r1) +| `RISCVBType (x, r0, r1, y) -> `RISCVBType (x, map_reg r0, map_reg r1, y) +| `RISCVIType (x, r0, r1, y) -> `RISCVIType (x, map_reg r0, map_reg r1, y) +| `RISCVShiftIop (x, r0, r1, y) -> `RISCVShiftIop (x, map_reg r0, map_reg r1, y) +| `RISCVRType (r0, r1, r2, y) -> `RISCVRType (r0, map_reg r1, map_reg r2, y) +| `RISCVLoad (x, r0, r1, y, z, a, b) -> `RISCVLoad (x, map_reg r0, map_reg r1, y, z, a, b) +| `RISCVStore (x, r0, r1, y, z, a) -> `RISCVStore (x, map_reg r0, map_reg r1, y, z, a) +| `RISCVADDIW (x, r0, r1) -> `RISCVADDIW (x, map_reg r0, map_reg r1) +| `RISCVSHIFTW (x, r0, r1, y) -> `RISCVSHIFTW (x, map_reg r0, map_reg r1, y) +| `RISCVRTYPEW (r0, r1, r2, x) -> `RISCVRTYPEW (r0, map_reg r1, map_reg r2, x) +| `RISCVLoadRes (aq, rl, rs1, w, rd) -> `RISCVLoadRes (aq, rl, map_reg rs1, w, map_reg rd) +| `RISCVStoreCon (aq, rl, rs2, rs1, w, rd) -> `RISCVStoreCon (aq, rl, map_reg rs2, map_reg rs1, w, map_reg rd) +| `RISCVAMO (op, aq, rl, rs2, rs1, w, rd) -> `RISCVAMO (op, aq, rl, map_reg rs2, map_reg rs1, w, map_reg rd) diff --git a/risc-v/gen/parser.hgen b/risc-v/gen/parser.hgen new file mode 100644 index 00000000..210e38fb --- /dev/null +++ b/risc-v/gen/parser.hgen @@ -0,0 +1,74 @@ +| UTYPE reg COMMA NUM + { (* it's not clear if NUM here should be before or after filling the + lowest 12 bits with zeros, or if it should be signed or unsigned; + currently assuming: NUM does not include the 12 zeros, and is unsigned *) + if not (iskbituimm 20 $4) then failwith "immediate is not 20bit" + else `RISCVUTYPE ($4, $2, $1.op) } +| JAL reg COMMA NUM + { if not ($4 mod 2 = 0) then failwith "odd offset" + else if not (iskbitsimm 21 $4) then failwith "offset is not 21bit" + else `RISCVJAL ($4, $2) } +| JALR reg COMMA reg COMMA NUM + { if not (iskbitsimm 12 $6) then failwith "offset is not 12bit" + else `RISCVJALR ($6, $4, $2) } +| BTYPE reg COMMA reg COMMA NUM + { if not ($6 mod 2 = 0) then failwith "odd offset" + else if not (iskbitsimm 13 $6) then failwith "offset is not 13bit" + else `RISCVBType ($6, $4, $2, $1.op) } +| ITYPE reg COMMA reg COMMA NUM + { if $1.op <> RISCVSLTIU && not (iskbitsimm 12 $6) then failwith "immediate is not 12bit" + else if $1.op = RISCVSLTIU && not (iskbituimm 12 $6) then failwith "unsigned immediate is not 12bit" + else `RISCVIType ($6, $4, $2, $1.op) } +| ADDIW reg COMMA reg COMMA NUM + { if not (iskbitsimm 12 $6) then failwith "immediate is not 12bit" + else `RISCVADDIW ($6, $4, $2) } +| SHIFTIOP reg COMMA reg COMMA NUM + { if not (iskbituimm 6 $6) then failwith "unsigned immediate is not 6bit" + else `RISCVShiftIop ($6, $4, $2, $1.op) } +| SHIFTW reg COMMA reg COMMA NUM + { if not (iskbituimm 5 $6) then failwith "unsigned immediate is not 5bit" + else `RISCVSHIFTW ($6, $4, $2, $1.op) } +| RTYPE reg COMMA reg COMMA reg + { `RISCVRType ($6, $4, $2, $1.op) } +| LOAD reg COMMA NUM LPAR reg RPAR + { if not (iskbitsimm 12 $4) then failwith "offset is not 12bit" + else `RISCVLoad ($4, $6, $2, $1.unsigned, $1.width, $1.aq, $1.rl) } +| STORE reg COMMA NUM LPAR reg RPAR + { if not (iskbitsimm 12 $4) then failwith "offset is not 12bit" + else `RISCVStore ($4, $2, $6, $1.width, $1.aq, $1.rl) } +| RTYPEW reg COMMA reg COMMA reg + { `RISCVRTYPEW ($6, $4, $2, $1.op) } +| FENCE FENCEOPTION COMMA FENCEOPTION + { match ($2, $4) with + | (Fence_RW, Fence_RW) -> `RISCVFENCE (0b0011, 0b0011) + | (Fence_R, Fence_RW) -> `RISCVFENCE (0b0010, 0b0011) + | (Fence_R, Fence_R) -> `RISCVFENCE (0b0010, 0b0010) + | (Fence_RW, Fence_W) -> `RISCVFENCE (0b0011, 0b0001) + | (Fence_W, Fence_W) -> `RISCVFENCE (0b0001, 0b0001) + | (Fence_RW, Fence_R) -> failwith "'fence rw,r' is not supported" + | (Fence_R, Fence_W) -> failwith "'fence r,w' is not supported" + | (Fence_W, Fence_RW) -> failwith "'fence w,rw' is not supported" + | (Fence_W, Fence_R) -> failwith "'fence w,r' is not supported" + } +| FENCEI + { `RISCVFENCEI } +| LOADRES reg COMMA LPAR reg RPAR + { `RISCVLoadRes ($1.aq, $1.rl, $5, $1.width, $2) } +| LOADRES reg COMMA NUM LPAR reg RPAR + { if $4 <> 0 then failwith "'lr' offset must be 0" else + `RISCVLoadRes ($1.aq, $1.rl, $6, $1.width, $2) } +| STORECON reg COMMA reg COMMA LPAR reg RPAR + { `RISCVStoreCon ($1.aq, $1.rl, $4, $7, $1.width, $2) } +| STORECON reg COMMA reg COMMA NUM LPAR reg RPAR + { if $6 <> 0 then failwith "'sc' offset must be 0" else + `RISCVStoreCon ($1.aq, $1.rl, $4, $8, $1.width, $2) } +| AMO reg COMMA reg COMMA LPAR reg RPAR + { `RISCVAMO ($1.op, $1.aq, $1.rl, $4, $7, $1.width, $2) } +| AMO reg COMMA reg COMMA NUM LPAR reg RPAR + { if $6 <> 0 then failwith "'amo<op>' offset must be 0" else + `RISCVAMO ($1.op, $1.aq, $1.rl, $4, $8, $1.width, $2) } + +/* pseudo-ops */ +| LI reg COMMA NUM + { if not (iskbitsimm 12 $4) then failwith "immediate is not 12bit (li is currently implemented only with small immediate)" + else `RISCVIType ($4, IReg R0, $2, RISCVORI) } diff --git a/risc-v/hgen/pretty.hgen b/risc-v/gen/pretty.hgen index 1da3ef11..fc1c0000 100644 --- a/risc-v/hgen/pretty.hgen +++ b/risc-v/gen/pretty.hgen @@ -7,9 +7,24 @@ | `RISCVIType(imm, rs2, rs1, op) -> sprintf "%s %s, %s, %d" (pp_riscv_iop op) (pp_reg rs1) (pp_reg rs2) imm | `RISCVShiftIop(imm, rs, rd, op) -> sprintf "%s %s, %s, %d" (pp_riscv_sop op) (pp_reg rd) (pp_reg rs) imm | `RISCVRType (rs2, rs1, rd, op) -> sprintf "%s %s, %s, %s" (pp_riscv_rop op) (pp_reg rd) (pp_reg rs1) (pp_reg rs2) -| `RISCVLoad(imm, rs, rd, unsigned, width) -> sprintf "%s %s, %d(%s)" (pp_riscv_load_op (unsigned, width)) (pp_reg rd) imm (pp_reg rs) -| `RISCVStore(imm, rs2, rs1, width) -> sprintf "%s %s, %d(%s)" (pp_riscv_store_op width) (pp_reg rs2) imm (pp_reg rs1) + +| `RISCVLoad(imm, rs, rd, unsigned, width, aq, rl) -> + sprintf "%s %s, %d(%s)" (pp_riscv_load_op (unsigned, width, aq, rl)) (pp_reg rd) imm (pp_reg rs) + +| `RISCVStore(imm, rs2, rs1, width, aq, rl) -> + sprintf "%s %s, %d(%s)" (pp_riscv_store_op (width, aq, rl)) (pp_reg rs2) imm (pp_reg rs1) + | `RISCVADDIW(imm, rs, rd) -> sprintf "addiw %s, %s, %d" (pp_reg rd) (pp_reg rs) imm | `RISCVSHIFTW(imm, rs, rd, op) -> sprintf "%s %s, %s, %d" (pp_riscv_sop op) (pp_reg rd) (pp_reg rs) imm | `RISCVRTYPEW(rs2, rs1, rd, op) -> sprintf "%s %s, %s, %s" (pp_riscv_ropw op) (pp_reg rd) (pp_reg rs1) (pp_reg rs2) | `RISCVFENCE(pred, succ) -> sprintf "fence %s, %s" (pp_riscv_fence_option pred) (pp_riscv_fence_option succ) +| `RISCVFENCEI -> sprintf "fence.i" + +| `RISCVLoadRes(aq, rl, rs1, width, rd) -> + sprintf "%s %s, (%s)" (pp_riscv_load_reserved_op (aq, rl, width)) (pp_reg rd) (pp_reg rs1) + +| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> + sprintf "%s %s, %s, (%s)" (pp_riscv_store_conditional_op (aq, rl, width)) (pp_reg rd) (pp_reg rs2) (pp_reg rs1) + +| `RISCVAMO(op, aq, rl, rs2, rs1, width, rd) -> + sprintf "%s %s, %s, (%s)" (pp_riscv_amo_op (op, aq, rl, width)) (pp_reg rd) (pp_reg rs2) (pp_reg rs1) diff --git a/risc-v/gen/pretty_xml.hgen b/risc-v/gen/pretty_xml.hgen new file mode 100644 index 00000000..b0306161 --- /dev/null +++ b/risc-v/gen/pretty_xml.hgen @@ -0,0 +1,137 @@ +| `RISCVThreadStart -> ("op_thread_start", []) + +| `RISCVStopFetching -> ("op_stop_fetching", []) + +| `RISCVUTYPE(imm, rd, op) -> + ("op_U_type", + [ ("op", pp_riscv_uop op); + ("uimm", sprintf "%d" imm); + ("dest", pp_reg rd); + ]) + +| `RISCVJAL(imm, rd) -> + ("op_jal", + [ ("offset", sprintf "%d" imm); + ("dest", pp_reg rd); + ]) + +| `RISCVJALR(imm, rs1, rd) -> + ("op_jalr", + [ ("offset", sprintf "%d" imm); + ("base", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVBType(imm, rs2, rs1, op) -> + ("op_branch", + [ ("op", pp_riscv_bop op); + ("offset", sprintf "%d" imm); + ("src2", pp_reg rs2); + ("src1", pp_reg rs1); + ]) + +| `RISCVIType(imm, rs1, rd, op) -> + ("op_I_type", + [ ("op", pp_riscv_iop op); + ("iimm", sprintf "%d" imm); + ("src", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVShiftIop(imm, rs1, rd, op) -> + ("op_IS_type", + [ ("op", pp_riscv_sop op); + ("shamt", sprintf "%d" imm); + ("src", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVSHIFTW(imm, rs1, rd, op) -> + ("op_ISW_type", + [ ("op", pp_riscv_sop op); + ("shamt", sprintf "%d" imm); + ("src", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVRType (rs2, rs1, rd, op) -> + ("op_R_type", + [ ("op", pp_riscv_rop op); + ("src2", pp_reg rs2); + ("src1", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVLoad(imm, rs1, rd, unsigned, width, aq, rl) -> + ("op_load", + [ ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("unsigned", if unsigned then "true" else "false"); + ("base", pp_reg rs1); + ("offset", sprintf "%d" imm); + ("dest", pp_reg rd); + ]) + +| `RISCVStore(imm, rs2, rs1, width, aq, rl) -> + ("op_store", + [ ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("src", pp_reg rs2); + ("base", pp_reg rs1); + ("offset", sprintf "%d" imm); + ]) + +| `RISCVADDIW(imm, rs1, rd) -> + ("op_addiw", + [ ("iimm", sprintf "%d" imm); + ("src", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVRTYPEW(rs2, rs1, rd, op) -> + ("op_RW_type", + [ ("op", pp_riscv_ropw op); + ("src2", pp_reg rs2); + ("src1", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVFENCE(pred, succ) -> + ("op_fence", + [ ("pred", pp_riscv_fence_option pred); + ("succ", pp_riscv_fence_option succ); + ]) + +| `RISCVFENCEI -> ("op_fence_i", []) + +| `RISCVLoadRes(aq, rl, rs1, width, rd) -> + ("op_lr", + [ ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("addr", pp_reg rs1); + ("dest", pp_reg rd); + ]) + +| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> + ("op_sc", + [ ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("addr", pp_reg rs1); + ("src", pp_reg rs2); + ("dest", pp_reg rd); + ]) + +| `RISCVAMO(op, aq, rl, rs2, rs1, width, rd) -> + ("op_amo", + [ ("op", pp_riscv_amo_op_part op); + ("aq", if aq then "true" else "false"); + ("rl", if rl then "true" else "false"); + ("width", pp_word_width width); + ("src", pp_reg rs2); + ("addr", pp_reg rs1); + ("dest", pp_reg rd); + ]) diff --git a/risc-v/hgen/sail_trans_out.hgen b/risc-v/gen/sail_trans_out.hgen index dca5bea1..2f9a80f1 100644 --- a/risc-v/hgen/sail_trans_out.hgen +++ b/risc-v/gen/sail_trans_out.hgen @@ -6,9 +6,18 @@ | ("ITYPE", [imm; rs1; rd; op]) -> `RISCVIType(translate_out_simm12 imm, translate_out_ireg rs1, translate_out_ireg rd, translate_out_iop op) | ("SHIFTIOP", [imm; rs; rd; op]) -> `RISCVShiftIop(translate_out_imm6 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) | ("RTYPE", [rs2; rs1; rd; op]) -> `RISCVRType (translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_rop op) -| ("LOAD", [imm; rs; rd; unsigned; width]) -> `RISCVLoad(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_bool unsigned, translate_out_wordWidth width) -| ("STORE", [imm; rs; rd; width]) -> `RISCVStore(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_wordWidth width) +| ("LOAD", [imm; rs; rd; unsigned; width; aq; rl]) + -> `RISCVLoad(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_bool unsigned, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) +| ("STORE", [imm; rs; rd; width; aq; rl]) + -> `RISCVStore(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) | ("ADDIW", [imm; rs; rd]) -> `RISCVADDIW(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) | ("SHIFTW", [imm; rs; rd; op]) -> `RISCVSHIFTW(translate_out_imm5 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) | ("RTYPEW", [rs2; rs1; rd; op]) -> `RISCVRTYPEW(translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_ropw op) | ("FENCE", [pred; succ]) -> `RISCVFENCE(translate_out_imm4 pred, translate_out_imm4 succ) +| ("FENCEI", []) -> `RISCVFENCEI +| ("LOADRES", [aq; rl; rs1; width; rd]) + -> `RISCVLoadRes(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) +| ("STORECON", [aq; rl; rs2; rs1; width; rd]) + -> `RISCVStoreCon(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) +| ("AMO", [op; aq; rl; rs2; rs1; width; rd]) + -> `RISCVAMO(translate_out_amoop op, translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) diff --git a/risc-v/hgen/shallow_ast_to_herdtools_ast.hgen b/risc-v/gen/shallow_ast_to_herdtools_ast.hgen index 6158ebd7..3025992e 100644 --- a/risc-v/hgen/shallow_ast_to_herdtools_ast.hgen +++ b/risc-v/gen/shallow_ast_to_herdtools_ast.hgen @@ -1,14 +1,23 @@ | EBREAK -> `RISCVStopFetching | UTYPE( imm, rd, op) -> `RISCVUTYPE(translate_out_simm20 imm, translate_out_ireg rd, translate_out_uop op) -| JAL0( imm, rd) -> `RISCVJAL(translate_out_simm21 imm, translate_out_ireg rd) -| JALR0( imm, rs, rd) -> `RISCVJALR(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) +| RISCV_JAL( imm, rd) -> `RISCVJAL(translate_out_simm21 imm, translate_out_ireg rd) +| RISCV_JALR( imm, rs, rd) -> `RISCVJALR(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) | BTYPE( imm, rs2, rs1, op) -> `RISCVBType(translate_out_simm13 imm, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_bop op) | ITYPE( imm, rs1, rd, op) -> `RISCVIType(translate_out_simm12 imm, translate_out_ireg rs1, translate_out_ireg rd, translate_out_iop op) | SHIFTIOP( imm, rs, rd, op) -> `RISCVShiftIop(translate_out_imm6 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) | RTYPE( rs2, rs1, rd, op) -> `RISCVRType (translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_rop op) -| LOAD( imm, rs, rd, unsigned, width) -> `RISCVLoad(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_bool unsigned, translate_out_wordWidth width) -| STORE( imm, rs, rd, width) -> `RISCVStore(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_wordWidth width) +| LOAD( imm, rs, rd, unsigned, width, aq, rl) + -> `RISCVLoad(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_bool unsigned, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) +| STORE( imm, rs, rd, width, aq, rl) + -> `RISCVStore(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_wordWidth width, translate_out_bool aq, translate_out_bool rl) | ADDIW( imm, rs, rd) -> `RISCVADDIW(translate_out_simm12 imm, translate_out_ireg rs, translate_out_ireg rd) | SHIFTW( imm, rs, rd, op) -> `RISCVSHIFTW(translate_out_imm5 imm, translate_out_ireg rs, translate_out_ireg rd, translate_out_sop op) | RTYPEW( rs2, rs1, rd, op) -> `RISCVRTYPEW(translate_out_ireg rs2, translate_out_ireg rs1, translate_out_ireg rd, translate_out_ropw op) | FENCE( pred, succ) -> `RISCVFENCE(translate_out_imm4 pred, translate_out_imm4 succ) +| FENCEI -> `RISCVFENCEI +| LOADRES( aq, rl, rs1, width, rd) + -> `RISCVLoadRes(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) +| STORECON( aq, rl, rs2, rs1, width, rd) + -> `RISCVStoreCon(translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) +| AMO( op, aq, rl, rs2, rs1, width, rd) + -> `RISCVAMO(translate_out_amoop op, translate_out_bool aq, translate_out_bool rl, translate_out_ireg rs2, translate_out_ireg rs1, translate_out_wordWidth width, translate_out_ireg rd) diff --git a/risc-v/hgen/shallow_types_to_herdtools_types.hgen b/risc-v/gen/shallow_types_to_herdtools_types.hgen index a891d7d0..6b3b7f51 100644 --- a/risc-v/hgen/shallow_types_to_herdtools_types.hgen +++ b/risc-v/gen/shallow_types_to_herdtools_types.hgen @@ -10,48 +10,59 @@ let translate_out_signed_int inst bits = let translate_out_ireg ireg = IReg (int_to_ireg (translate_out_int ireg)) let translate_out_uop op = match op with - | LUI0 -> RISCVLUI - | AUIPC -> RISCVAUIPC + | RISCV_LUI -> RISCVLUI + | RISCV_AUIPC -> RISCVAUIPC let translate_out_bop op = match op with - | BEQ0 -> RISCVBEQ - | BNE -> RISCVBNE - | BLT -> RISCVBLT - | BGE -> RISCVBGE - | BLTU -> RISCVBLTU - | BGEU -> RISCVBGEU + | RISCV_BEQ -> RISCVBEQ + | RISCV_BNE -> RISCVBNE + | RISCV_BLT -> RISCVBLT + | RISCV_BGE -> RISCVBGE + | RISCV_BLTU -> RISCVBLTU + | RISCV_BGEU -> RISCVBGEU let translate_out_iop op = match op with - | ADDI0 -> RISCVADDI - | SLTI0 -> RISCVSLTI - | SLTIU0 -> RISCVSLTIU - | XORI0 -> RISCVXORI - | ORI0 -> RISCVORI - | ANDI0 -> RISCVANDI + | RISCV_ADDI -> RISCVADDI + | RISCV_SLTI -> RISCVSLTI + | RISCV_SLTIU -> RISCVSLTIU + | RISCV_XORI -> RISCVXORI + | RISCV_ORI -> RISCVORI + | RISCV_ANDI -> RISCVANDI let translate_out_sop op = match op with - | SLLI -> RISCVSLLI - | SRLI -> RISCVSRLI - | SRAI -> RISCVSRAI + | RISCV_SLLI -> RISCVSLLI + | RISCV_SRLI -> RISCVSRLI + | RISCV_SRAI -> RISCVSRAI let translate_out_rop op = match op with - | ADD0 -> RISCVADD - | SUB0 -> RISCVSUB - | SLL0 -> RISCVSLL - | SLT0 -> RISCVSLT - | SLTU0 -> RISCVSLTU - | XOR0 -> RISCVXOR - | SRL0 -> RISCVSRL - | SRA0 -> RISCVSRA - | OR0 -> RISCVOR - | AND0 -> RISCVAND + | RISCV_ADD -> RISCVADD + | RISCV_SUB -> RISCVSUB + | RISCV_SLL -> RISCVSLL + | RISCV_SLT -> RISCVSLT + | RISCV_SLTU -> RISCVSLTU + | RISCV_XOR -> RISCVXOR + | RISCV_SRL -> RISCVSRL + | RISCV_SRA -> RISCVSRA + | RISCV_OR -> RISCVOR + | RISCV_AND -> RISCVAND let translate_out_ropw op = match op with - | ADDW -> RISCVADDW - | SUBW -> RISCVSUBW - | SLLW -> RISCVSLLW - | SRLW -> RISCVSRLW - | SRAW -> RISCVSRAW + | RISCV_ADDW -> RISCVADDW + | RISCV_SUBW -> RISCVSUBW + | RISCV_SLLW -> RISCVSLLW + | RISCV_SRLW -> RISCVSRLW + | RISCV_SRAW -> RISCVSRAW + +let translate_out_amoop op = match op with + | AMOSWAP -> RISCVAMOSWAP + | AMOADD -> RISCVAMOADD + | AMOXOR -> RISCVAMOXOR + | AMOAND -> RISCVAMOAND + | AMOOR -> RISCVAMOOR + | AMOMIN -> RISCVAMOMIN + | AMOMAX -> RISCVAMOMAX + | AMOMINU -> RISCVAMOMINU + | AMOMAXU -> RISCVAMOMAXU let translate_out_wordWidth op = match op with | BYTE -> RISCVBYTE diff --git a/risc-v/hgen/token_types.hgen b/risc-v/gen/token_types.hgen index 2980b985..f29e318d 100644 --- a/risc-v/hgen/token_types.hgen +++ b/risc-v/gen/token_types.hgen @@ -5,11 +5,19 @@ type token_BType = {op : riscvBop } type token_IType = {op : riscvIop } type token_ShiftIop = {op : riscvSop } type token_RTYPE = {op : riscvRop } -type token_Load = {unsigned: bool; width : wordWidth } -type token_Store = {width : wordWidth } +type token_Load = {unsigned: bool; width : wordWidth; aq: bool; rl: bool } +type token_Store = {width : wordWidth; aq: bool; rl: bool } type token_ADDIW = unit type token_SHIFTW = {op : riscvSop } type token_RTYPEW = {op : riscvRopw } type token_FENCE = unit +type token_FENCEI = unit +type token_LoadRes = {width : wordWidth; aq: bool; rl: bool } +type token_StoreCon = {width : wordWidth; aq: bool; rl: bool } +type token_AMO = {width : wordWidth; aq: bool; rl: bool; op: riscvAmoop } type token_FENCEOPTION = Fence_R | Fence_W | Fence_RW + +(* pseudo-ops *) + +type token_LI = unit diff --git a/risc-v/hgen/tokens.hgen b/risc-v/gen/tokens.hgen index f952cf77..f812adbd 100644 --- a/risc-v/hgen/tokens.hgen +++ b/risc-v/gen/tokens.hgen @@ -12,3 +12,8 @@ %token <RISCVHGenBase.token_RTYPEW> RTYPEW %token <RISCVHGenBase.token_FENCE> FENCE %token <RISCVHGenBase.token_FENCEOPTION> FENCEOPTION +%token <RISCVHGenBase.token_FENCEI> FENCEI +%token <RISCVHGenBase.token_LoadRes> LOADRES +%token <RISCVHGenBase.token_StoreCon> STORECON +%token <RISCVHGenBase.token_AMO> AMO +%token <RISCVHGenBase.token_LI> LI diff --git a/risc-v/hgen/trans_sail.hgen b/risc-v/gen/trans_sail.hgen index df22d9dc..8b7cbe11 100644 --- a/risc-v/hgen/trans_sail.hgen +++ b/risc-v/gen/trans_sail.hgen @@ -58,7 +58,7 @@ translate_rop "op" op; ], []) -| `RISCVLoad(imm, rs, rd, unsigned, width) -> +| `RISCVLoad(imm, rs, rd, unsigned, width, aq, rl) -> ("LOAD", [ translate_imm12 "imm" imm; @@ -66,15 +66,19 @@ translate_reg "rd" rd; translate_bool "unsigned" unsigned; translate_width "width" width; + translate_bool "aq" aq; + translate_bool "rl" rl; ], []) -| `RISCVStore(imm, rs2, rs1, width) -> +| `RISCVStore(imm, rs2, rs1, width, aq, rl) -> ("STORE", [ translate_imm12 "imm" imm; translate_reg "rs2" rs2; translate_reg "rs1" rs1; translate_width "width" width; + translate_bool "aq" aq; + translate_bool "rl" rl; ], []) | `RISCVADDIW(imm, rs, rd) -> @@ -110,3 +114,40 @@ translate_imm4 "succ" succ; ], []) +| `RISCVFENCEI -> + ("FENCEI", + [], + []) +| `RISCVLoadRes(aq, rl, rs1, width, rd) -> + ("LOADRES", + [ + translate_bool "aq" aq; + translate_bool "rl" rl; + translate_reg "rs1" rs1; + translate_width "width" width; + translate_reg "rd" rd; + ], + []) +| `RISCVStoreCon(aq, rl, rs2, rs1, width, rd) -> + ("STORECON", + [ + translate_bool "aq" aq; + translate_bool "rl" rl; + translate_reg "rs2" rs2; + translate_reg "rs1" rs1; + translate_width "width" width; + translate_reg "rd" rd; + ], + []) +| `RISCVAMO(op, aq, rl, rs2, rs1, width, rd) -> + ("AMO", + [ + translate_amoop "op" op; + translate_bool "aq" aq; + translate_bool "rl" rl; + translate_reg "rs2" rs2; + translate_reg "rs1" rs1; + translate_width "width" width; + translate_reg "rd" rd; + ], + []) diff --git a/risc-v/hgen/types.hgen b/risc-v/gen/types.hgen index 87fc9b95..a0b75606 100644 --- a/risc-v/hgen/types.hgen +++ b/risc-v/gen/types.hgen @@ -99,22 +99,71 @@ type wordWidth = | RISCVWORD | RISCVDOUBLE -let pp_riscv_load_op (unsigned, width) = match (unsigned, width) with - | (false, RISCVBYTE) -> "lb" - | (true, RISCVBYTE) -> "lbu" - | (false, RISCVHALF) -> "lh" - | (true, RISCVHALF) -> "lhu" - | (false, RISCVWORD) -> "lw" - | (true, RISCVWORD) -> "lwu" - | (_, RISCVDOUBLE) -> "ld" - | _ -> failwith "unexpected load op" - -let pp_riscv_store_op width = match width with -| RISCVBYTE -> "sb" -| RISCVHALF -> "sh" -| RISCVWORD -> "sw" -| RISCVDOUBLE -> "sd" -| _ -> failwith "unexpected store op" +let pp_word_width width : string = + begin match width with + | RISCVBYTE -> "b" + | RISCVHALF -> "h" + | RISCVWORD -> "w" + | RISCVDOUBLE -> "d" + end + +let pp_riscv_load_op (unsigned, width, aq, rl) = + "l" ^ + (pp_word_width width) ^ + (if unsigned then "u" else "") ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") + +let pp_riscv_store_op (width, aq, rl) = + "s" ^ + (pp_word_width width) ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") + +let pp_riscv_load_reserved_op (aq, rl, width) = + "lr." ^ + (pp_word_width width) ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") + +let pp_riscv_store_conditional_op (aq, rl, width) = + "sc." ^ + (pp_word_width width) ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") + +type riscvAmoop = + | RISCVAMOSWAP + | RISCVAMOADD + | RISCVAMOXOR + | RISCVAMOAND + | RISCVAMOOR + | RISCVAMOMIN + | RISCVAMOMAX + | RISCVAMOMINU + | RISCVAMOMAXU + +let pp_riscv_amo_op_part = function + | RISCVAMOSWAP -> "swap" + | RISCVAMOADD -> "add" + | RISCVAMOXOR -> "xor" + | RISCVAMOAND -> "and" + | RISCVAMOOR -> "or" + | RISCVAMOMIN -> "min" + | RISCVAMOMAX -> "max" + | RISCVAMOMINU -> "minu" + | RISCVAMOMAXU -> "maxu" + +let pp_riscv_amo_op (op, aq, rl, width) = + "amo" ^ + pp_riscv_amo_op_part op ^ + begin match width with + | RISCVWORD -> ".w" + | RISCVDOUBLE -> ".d" + | _ -> assert false + end ^ + (if aq then ".aq" else "") ^ + (if rl then ".rl" else "") let pp_riscv_fence_option = function | 0b0011 -> "rw" diff --git a/risc-v/hgen/types_sail_trans_out.hgen b/risc-v/gen/types_sail_trans_out.hgen index e22110d0..66a2020c 100644 --- a/risc-v/hgen/types_sail_trans_out.hgen +++ b/risc-v/gen/types_sail_trans_out.hgen @@ -84,3 +84,15 @@ let translate_out_ropw op = match translate_out_enum op with | 3 -> RISCVSRLW | 4 -> RISCVSRAW | _ -> failwith "Unknown ropw in sail translate out" + +let translate_out_amoop op = match translate_out_enum op with +| 0 -> RISCVAMOSWAP +| 1 -> RISCVAMOADD +| 2 -> RISCVAMOXOR +| 3 -> RISCVAMOAND +| 4 -> RISCVAMOOR +| 5 -> RISCVAMOMIN +| 6 -> RISCVAMOMAX +| 7 -> RISCVAMOMINU +| 8 -> RISCVAMOMAXU +| _ -> failwith "Unknown amoop in sail translate out" diff --git a/risc-v/hgen/types_trans_sail.hgen b/risc-v/gen/types_trans_sail.hgen index 1bf174fa..238c7e5b 100644 --- a/risc-v/hgen/types_trans_sail.hgen +++ b/risc-v/gen/types_trans_sail.hgen @@ -11,29 +11,47 @@ let translate_enum enum_values name value = (name, Range0 (Some size), IInt.bit_list_of_integer size (Nat_big_num.of_int index)) let translate_uop = translate_enum [RISCVLUI; RISCVAUIPC] + let translate_bop = translate_enum [RISCVBEQ; RISCVBNE; RISCVBLT; RISCVBGE; RISCVBLTU; RISCVBGEU] (* branch ops *) + let translate_iop = translate_enum [RISCVADDI; RISCVSLTI; RISCVSLTIU; RISCVXORI; RISCVORI; RISCVANDI] (* immediate ops *) + let translate_sop = translate_enum [RISCVSLLI; RISCVSRLI; RISCVSRAI] (* shift ops *) + let translate_rop = translate_enum [RISCVADD; RISCVSUB; RISCVSLL; RISCVSLT; RISCVSLTU; RISCVXOR; RISCVSRL; RISCVSRA; RISCVOR; RISCVAND] (* reg-reg ops *) + let translate_ropw = translate_enum [RISCVADDW; RISCVSUBW; RISCVSLLW; RISCVSRLW; RISCVSRAW] (* reg-reg 32-bit ops *) + +let translate_amoop = translate_enum [RISCVAMOSWAP; RISCVAMOADD; RISCVAMOXOR; RISCVAMOAND; RISCVAMOOR; RISCVAMOMIN; RISCVAMOMAX; RISCVAMOMINU; RISCVAMOMAXU] + let translate_width = translate_enum [RISCVBYTE; RISCVHALF; RISCVWORD; RISCVDOUBLE] + let translate_reg name value = (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int (reg_to_int value))) + let translate_imm21 name value = (name, Bvector (Some 21), bit_list_of_integer 21 (Nat_big_num.of_int value)) + let translate_imm20 name value = (name, Bvector (Some 20), bit_list_of_integer 20 (Nat_big_num.of_int value)) + let translate_imm16 name value = (name, Bvector (Some 16), bit_list_of_integer 16 (Nat_big_num.of_int value)) + let translate_imm13 name value = (name, Bvector (Some 13), bit_list_of_integer 13 (Nat_big_num.of_int value)) + let translate_imm12 name value = (name, Bvector (Some 12), bit_list_of_integer 12 (Nat_big_num.of_int value)) + let translate_imm6 name value = (name, Bvector (Some 6), bit_list_of_integer 6 (Nat_big_num.of_int value)) + let translate_imm5 name value = (name, Bvector (Some 5), bit_list_of_integer 5 (Nat_big_num.of_int value)) + let translate_imm4 name value = (name, Bvector (Some 4), bit_list_of_integer 4 (Nat_big_num.of_int value)) + let translate_bool name value = (name, Bit, [if value then Bitc_one else Bitc_zero]) diff --git a/risc-v/hgen/fold.hgen b/risc-v/hgen/fold.hgen deleted file mode 100644 index 03318805..00000000 --- a/risc-v/hgen/fold.hgen +++ /dev/null @@ -1,13 +0,0 @@ -| `RISCVThreadStart -> (y_reg, y_sreg) -| `RISCVUTYPE (_, r0, _) -> fold_reg r0 (y_reg, y_sreg) -| `RISCVJAL (_, r0) -> fold_reg r0 (y_reg, y_sreg) -| `RISCVJALR (_, r0, r1) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVBType (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVIType (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVShiftIop (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVRType (r0, r1, r2, _) -> fold_reg r0 (fold_reg r1 (fold_reg r2 (y_reg, y_sreg))) -| `RISCVLoad (_, r0, r1, _, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVStore (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVADDIW (_, r0, r1) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVSHIFTW (_, r0, r1, _) -> fold_reg r0 (fold_reg r1 (y_reg, y_sreg)) -| `RISCVRTYPEW (r0, r1, r2, _) -> fold_reg r0 (fold_reg r1 (fold_reg r2 (y_reg, y_sreg))) diff --git a/risc-v/hgen/lexer.hgen b/risc-v/hgen/lexer.hgen deleted file mode 100644 index 5f2c8326..00000000 --- a/risc-v/hgen/lexer.hgen +++ /dev/null @@ -1,64 +0,0 @@ -"lui" , UTYPE { op=RISCVLUI }; -"auipc" , UTYPE { op=RISCVAUIPC }; - -"jal", JAL (); -"jalr", JALR (); - -"beq", BTYPE {op=RISCVBEQ}; -"bne", BTYPE {op=RISCVBNE}; -"blt", BTYPE {op=RISCVBLT}; -"bge", BTYPE {op=RISCVBGE}; -"bltu", BTYPE {op=RISCVBLTU}; -"bgeu", BTYPE {op=RISCVBGEU}; - -"addi", ITYPE {op=RISCVADDI}; -"stli", ITYPE {op=RISCVSLTI}; -"sltiu", ITYPE {op=RISCVSLTIU}; -"xori", ITYPE {op=RISCVXORI}; -"ori", ITYPE {op=RISCVORI}; -"andi", ITYPE {op=RISCVANDI}; - -"slli", SHIFTIOP{op=RISCVSLLI}; -"srli", SHIFTIOP{op=RISCVSRLI}; -"srai", SHIFTIOP{op=RISCVSRAI}; - -"add", RTYPE{op=RISCVADD}; -"sub", RTYPE{op=RISCVSUB}; -"sll", RTYPE{op=RISCVSLL}; -"slt", RTYPE{op=RISCVSLT}; -"sltu", RTYPE{op=RISCVSLT}; -"xor", RTYPE{op=RISCVXOR}; -"srl", RTYPE{op=RISCVSRL}; -"sra", RTYPE{op=RISCVSRA}; -"or", RTYPE{op=RISCVOR}; -"and", RTYPE{op=RISCVAND}; - -"lb", LOAD{unsigned=false; width=RISCVBYTE}; -"lbu", LOAD{unsigned=true; width=RISCVBYTE}; -"lh", LOAD{unsigned=false; width=RISCVHALF}; -"lhu", LOAD{unsigned=true; width=RISCVHALF}; -"lw", LOAD{unsigned=false; width=RISCVWORD}; -"lwu", LOAD{unsigned=true; width=RISCVWORD}; -"ld", LOAD{unsigned=false; width=RISCVDOUBLE}; - -"sb", STORE{width=RISCVBYTE}; -"sh", STORE{width=RISCVHALF}; -"sw", STORE{width=RISCVWORD}; -"sd", STORE{width=RISCVDOUBLE}; - -"addiw", ADDIW (); - -"slliw", SHIFTW{op=RISCVSLLI}; -"srliw", SHIFTW{op=RISCVSRLI}; -"sraiw", SHIFTW{op=RISCVSRAI}; - -"addw", RTYPEW{op=RISCVADDW}; -"subw", RTYPEW{op=RISCVSUBW}; -"sslw", RTYPEW{op=RISCVSLLW}; -"srlw", RTYPEW{op=RISCVSRLW}; -"sraw", RTYPEW{op=RISCVSRAW}; - -"fence", FENCE (); -"r", FENCEOPTION Fence_R; -"w", FENCEOPTION Fence_W; -"rw", FENCEOPTION Fence_RW; diff --git a/risc-v/hgen/map.hgen b/risc-v/hgen/map.hgen deleted file mode 100644 index ff14c428..00000000 --- a/risc-v/hgen/map.hgen +++ /dev/null @@ -1,12 +0,0 @@ -| `RISCVUTYPE (x, r0, y) -> `RISCVUTYPE (x, map_reg r0, y) -| `RISCVJAL (x, r0) -> `RISCVJAL (x, map_reg r0) -| `RISCVJALR (x, r0, r1) -> `RISCVJALR (x, map_reg r0, map_reg r1) -| `RISCVBType (x, r0, r1, y) -> `RISCVBType (x, map_reg r0, map_reg r1, y) -| `RISCVIType (x, r0, r1, y) -> `RISCVIType (x, map_reg r0, map_reg r1, y) -| `RISCVShiftIop (x, r0, r1, y) -> `RISCVShiftIop (x, map_reg r0, map_reg r1, y) -| `RISCVRType (r0, r1, r2, y) -> `RISCVRType (r0, map_reg r1, map_reg r2, y) -| `RISCVLoad (x, r0, r1, y, z) -> `RISCVLoad (x, map_reg r0, map_reg r1, y, z) -| `RISCVStore (x, r0, r1, y) -> `RISCVStore (x, map_reg r0, map_reg r1, y) -| `RISCVADDIW (x, r0, r1) -> `RISCVADDIW (x, map_reg r0, map_reg r1) -| `RISCVSHIFTW (x, r0, r1, y) -> `RISCVSHIFTW (x, map_reg r0, map_reg r1, y) -| `RISCVRTYPEW (r0, r1, r2, x) -> `RISCVRTYPEW (r0, map_reg r1, map_reg r2, x) diff --git a/risc-v/hgen/parser.hgen b/risc-v/hgen/parser.hgen deleted file mode 100644 index 37fd8d8d..00000000 --- a/risc-v/hgen/parser.hgen +++ /dev/null @@ -1,36 +0,0 @@ -| UTYPE reg COMMA NUM - { `RISCVUTYPE($4, $2, $1.op) } -| JAL reg COMMA NUM - { `RISCVJAL($4, $2) } -| JALR reg COMMA reg COMMA NUM - { `RISCVJALR($6, $4, $2) } -| BTYPE reg COMMA reg COMMA NUM - { `RISCVBType($6, $4, $2, $1.op) } -| ITYPE reg COMMA reg COMMA NUM - { `RISCVIType($6, $4, $2, $1.op) } -| SHIFTIOP reg COMMA reg COMMA NUM - { `RISCVShiftIop($6, $4, $2, $1.op) } -| RTYPE reg COMMA reg COMMA reg - { `RISCVRType ($6, $4, $2, $1.op) } -| LOAD reg COMMA NUM LPAR reg RPAR - { `RISCVLoad($4, $6, $2, $1.unsigned, $1.width) } -| STORE reg COMMA NUM LPAR reg RPAR - { `RISCVStore($4, $2, $6, $1.width) } -| ADDIW reg COMMA reg COMMA NUM - { `RISCVADDIW ($6, $4, $2) } -| SHIFTW reg COMMA reg COMMA NUM - { `RISCVSHIFTW ($6, $4, $2, $1.op) } -| RTYPEW reg COMMA reg COMMA reg - { `RISCVRTYPEW ($6, $4, $2, $1.op) } -| FENCE FENCEOPTION COMMA FENCEOPTION - { match ($2, $4) with - | (Fence_RW, Fence_RW) -> `RISCVFENCE (0b0011, 0b0011) - | (Fence_R, Fence_RW) -> `RISCVFENCE (0b0010, 0b0011) - | (Fence_RW, Fence_W) -> `RISCVFENCE (0b0011, 0b0001) - | (Fence_RW, Fence_R) -> failwith "'fence rw,r' is not supported" - | (Fence_R, Fence_R) -> failwith "'fence r,r' is not supported" - | (Fence_R, Fence_W) -> failwith "'fence r,w' is not supported" - | (Fence_W, Fence_RW) -> failwith "'fence w,rw' is not supported" - | (Fence_W, Fence_R) -> failwith "'fence w,r' is not supported" - | (Fence_W, Fence_W) -> failwith "'fence w,w' is not supported" - } diff --git a/risc-v/riscv.sail b/risc-v/riscv.sail index 4a80adb0..3d52d111 100644 --- a/risc-v/riscv.sail +++ b/risc-v/riscv.sail @@ -1,317 +1,404 @@ -default Order dec - -typedef regval = bit[64] -typedef regno = bit[5] - -register (regval) x0 -register (regval) x1 -register (regval) x2 -register (regval) x3 -register (regval) x4 -register (regval) x5 -register (regval) x6 -register (regval) x7 -register (regval) x8 -register (regval) x9 -register (regval) x10 -register (regval) x11 -register (regval) x12 -register (regval) x13 -register (regval) x14 -register (regval) x15 -register (regval) x16 -register (regval) x17 -register (regval) x18 -register (regval) x19 -register (regval) x20 -register (regval) x21 -register (regval) x22 -register (regval) x23 -register (regval) x24 -register (regval) x25 -register (regval) x26 -register (regval) x27 -register (regval) x28 -register (regval) x29 -register (regval) x30 -register (regval) x31 - -register (bit[64]) PC -register (bit[64]) nextPC - -let (vector <0, 32, inc, (register<(regval)>)>) GPRs = - [x0, x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19,x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,x30,x31] - -function (regval) rGPR ((regno) r) = - if (r == 0) then - 0 - else - GPRs[r] - -function unit wGPR((regno) r, (regval) v) = - if (r != 0) then - GPRs[r] := v - -function forall 'a. 'a effect { escape } not_implemented((string) message) = -{ - exit message; -} - -val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr -val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea -val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval -val extern unit -> unit effect { barr } MEM_fence_rw_rw -val extern unit -> unit effect { barr } MEM_fence_r_rw -val extern unit -> unit effect { barr } MEM_fence_rw_w - -(* Ideally these would be sail builtin *) -function (bit[64]) shift_right_arith64 ((bit[64]) v, (bit[6]) shift) = - let (bit[128]) v128 = EXTS(v) in - (v128 >> shift)[63..0] - -function (bit[32]) shift_right_arith32 ((bit[32]) v, (bit[5]) shift) = - let (bit[64]) v64 = EXTS(v) in - (v64 >> shift)[31..0] - -typedef uop = enumerate {LUI; AUIPC} (* upper immediate ops *) -typedef bop = enumerate {BEQ; BNE; BLT; BGE; BLTU; BGEU} (* branch ops *) -typedef iop = enumerate {ADDI; SLTI; SLTIU; XORI; ORI; ANDI} (* immediate ops *) -typedef sop = enumerate {SLLI; SRLI; SRAI} (* shift ops *) -typedef rop = enumerate {ADD; SUB; SLL; SLT; SLTU; XOR; SRL; SRA; OR; AND} (* reg-reg ops *) -typedef ropw = enumerate {ADDW; SUBW; SLLW; SRLW; SRAW} (* reg-reg 32-bit ops *) - -typedef word_width = enumerate {BYTE; HALF; WORD; DOUBLE} - -scattered function unit execute scattered typedef ast = const union val bit[32] -> option<ast> effect pure decode - scattered function option<ast> decode +scattered function unit execute + +(********************************************************************) union ast member ((bit[20]), regno, uop) UTYPE -function clause decode ((bit[20]) imm : (regno) rd : 0b0110111) = Some(UTYPE(imm, rd, LUI)) -function clause decode ((bit[20]) imm : (regno) rd : 0b0010111) = Some(UTYPE(imm, rd, AUIPC)) +function clause decode ((bit[20]) imm : (regno) rd : 0b0110111) = Some(UTYPE(imm, rd, RISCV_LUI)) +function clause decode ((bit[20]) imm : (regno) rd : 0b0010111) = Some(UTYPE(imm, rd, RISCV_AUIPC)) function clause execute (UTYPE(imm, rd, op)) = let (bit[64]) off = EXTS(imm : 0x000) in let ret = switch (op) { - case LUI -> off - case AUIPC -> PC + off + case RISCV_LUI -> off + case RISCV_AUIPC -> PC + off } in wGPR(rd, ret) -union ast member ((bit[21]), regno) JAL -function clause decode ((bit[20]) imm : (regno) rd : 0b1101111) = Some (JAL(imm[19] : imm[7..0] : imm[8] : imm[18..13] : imm[12..9] : 0b0, rd)) -function clause execute (JAL(imm, rd)) = - let (bit[64]) offset = EXTS(imm) in { - nextPC := PC + offset; - wGPR(rd, PC + 4); - } +(********************************************************************) +union ast member ((bit[21]), regno) RISCV_JAL + +function clause decode ((bit[20]) imm : (regno) rd : 0b1101111) = Some (RISCV_JAL(imm[19] : imm[7..0] : imm[8] : imm[18..13] : imm[12..9] : 0b0, rd)) + +function clause execute (RISCV_JAL(imm, rd)) = { + (bit[64]) pc := PC; + wGPR(rd, pc + 4); + (bit[64]) offset := EXTS(imm); + nextPC := pc + offset; +} + +(********************************************************************) +union ast member((bit[12]), regno, regno) RISCV_JALR -union ast member((bit[12]), regno, regno) JALR function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b1100111) = - Some(JALR(imm, rs1, rd)) -function clause execute (JALR(imm, rs1, rd)) = - let (bit[64]) newPC = rGPR(rs1) + EXTS(imm) in { - nextPC := newPC[63..1] : 0b0; - wGPR(rd, PC + 4); - } + Some(RISCV_JALR(imm, rs1, rd)) +function clause execute (RISCV_JALR(imm, rs1, rd)) = { + (* write rd before anything else to prevent unintended strength *) + wGPR(rd, PC + 4); + (bit[64]) newPC := rGPR(rs1) + EXTS(imm); + nextPC := newPC[63..1] : 0b0; +} + +(********************************************************************) union ast member ((bit[13]), regno, regno, bop) BTYPE -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b000 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, BEQ)) -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b001 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, BNE)) -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b100 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, BLT)) -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b101 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, BGE)) -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b110 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, BLTU)) -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b111 : (bit[5]) imm5 : 0b1100011) = Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, BGEU)) + +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b000 : (bit[5]) imm5 : 0b1100011) = + Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, RISCV_BEQ)) +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b001 : (bit[5]) imm5 : 0b1100011) = + Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, RISCV_BNE)) +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b100 : (bit[5]) imm5 : 0b1100011) = + Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, RISCV_BLT)) +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b101 : (bit[5]) imm5 : 0b1100011) = + Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, RISCV_BGE)) +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b110 : (bit[5]) imm5 : 0b1100011) = + Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, RISCV_BLTU)) +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b111 : (bit[5]) imm5 : 0b1100011) = + Some(BTYPE(imm7[6] : imm5[0] : imm7[5..0] : imm5[4..1] : 0b0, rs2, rs1, RISCV_BGEU)) function clause execute (BTYPE(imm, rs2, rs1, op)) = let rs1_val = rGPR(rs1) in let rs2_val = rGPR(rs2) in let taken = switch(op) { - case BEQ -> rs1_val == rs2_val - case BNE -> rs1_val != rs2_val - case BLT -> rs1_val <_s rs2_val - case BGE -> rs1_val >=_s rs2_val - case BLTU -> rs1_val <_u rs2_val - case BGEU -> unsigned(rs1_val) >= unsigned(rs2_val) (* XXX sail missing >=_u *) + case RISCV_BEQ -> rs1_val == rs2_val + case RISCV_BNE -> rs1_val != rs2_val + case RISCV_BLT -> rs1_val <_s rs2_val + case RISCV_BGE -> rs1_val >=_s rs2_val + case RISCV_BLTU -> rs1_val <_u rs2_val + case RISCV_BGEU -> unsigned(rs1_val) >= unsigned(rs2_val) (* XXX sail missing >=_u *) } in if (taken) then nextPC := PC + EXTS(imm) +(********************************************************************) union ast member ((bit[12]), regno, regno, iop) ITYPE -function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, ADDI)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b010 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, SLTI)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b011 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, SLTIU)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b100 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, XORI)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b110 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, ORI)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b111 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, ANDI)) + +function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, RISCV_ADDI)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b010 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, RISCV_SLTI)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b011 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, RISCV_SLTIU)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b100 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, RISCV_XORI)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b110 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, RISCV_ORI)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b111 : (regno) rd : 0b0010011) = Some(ITYPE(imm, rs1, rd, RISCV_ANDI)) + function clause execute (ITYPE (imm, rs1, rd, op)) = let rs1_val = rGPR(rs1) in let imm64 = (bit[64]) (EXTS(imm)) in let (bit[64]) result = switch(op) { - case ADDI -> rs1_val + imm64 - case SLTI -> EXTZ(rs1_val <_s imm64) - case SLTIU -> EXTZ(rs1_val <_u imm64) - case XORI -> rs1_val ^ imm64 - case ORI -> rs1_val | imm64 - case ANDI -> rs1_val & imm64 + case RISCV_ADDI -> rs1_val + imm64 + case RISCV_SLTI -> EXTZ(rs1_val <_s imm64) + case RISCV_SLTIU -> EXTZ(rs1_val <_u imm64) + case RISCV_XORI -> rs1_val ^ imm64 + case RISCV_ORI -> rs1_val | imm64 + case RISCV_ANDI -> rs1_val & imm64 } in wGPR(rd, result) +(********************************************************************) union ast member ((bit[6]), regno, regno, sop) SHIFTIOP -function clause decode (0b000000 : (bit[6]) shamt : (regno) rs1 : 0b001 : (regno) rd : 0b0010011) = Some(SHIFTIOP(shamt, rs1, rd, SLLI)) -function clause decode (0b000000 : (bit[6]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0010011) = Some(SHIFTIOP(shamt, rs1, rd, SRLI)) -function clause decode (0b010000 : (bit[6]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0010011) = Some(SHIFTIOP(shamt, rs1, rd, SRAI)) + +function clause decode (0b000000 : (bit[6]) shamt : (regno) rs1 : 0b001 : (regno) rd : 0b0010011) = Some(SHIFTIOP(shamt, rs1, rd, RISCV_SLLI)) +function clause decode (0b000000 : (bit[6]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0010011) = Some(SHIFTIOP(shamt, rs1, rd, RISCV_SRLI)) +function clause decode (0b010000 : (bit[6]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0010011) = Some(SHIFTIOP(shamt, rs1, rd, RISCV_SRAI)) + function clause execute (SHIFTIOP(shamt, rs1, rd, op)) = let rs1_val = rGPR(rs1) in let result = switch(op) { - case SLLI -> rs1_val >> shamt - case SRLI -> rs1_val << shamt - case SRAI -> shift_right_arith64(rs1_val, shamt) + case RISCV_SLLI -> rs1_val >> shamt + case RISCV_SRLI -> rs1_val << shamt + case RISCV_SRAI -> shift_right_arith64(rs1_val, shamt) } in wGPR(rd, result) +(********************************************************************) union ast member (regno, regno, regno, rop) RTYPE -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, ADD)) -function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SUB)) -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b001 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SLL)) -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SLT)) -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SLTU)) -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b100 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, XOR)) -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SRL)) -function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, SRA)) -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b110 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, OR)) -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b111 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, AND)) + +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_ADD)) +function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_SUB)) +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b001 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_SLL)) +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_SLT)) +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_SLTU)) +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b100 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_XOR)) +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_SRL)) +function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_SRA)) +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b110 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_OR)) +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b111 : (regno) rd : 0b0110011) = Some(RTYPE(rs2, rs1, rd, RISCV_AND)) + function clause execute (RTYPE(rs2, rs1, rd, op)) = let rs1_val = rGPR(rs1) in let rs2_val = rGPR(rs2) in let (bit[64]) result = switch(op) { - case ADD -> rs1_val + rs2_val - case SUB -> rs1_val - rs2_val - case SLL -> rs1_val << (rs2_val[5..0]) - case SLT -> EXTZ(rs1_val <_s rs2_val) - case SLTU -> EXTZ(rs1_val <_u rs2_val) - case XOR -> rs1_val ^ rs2_val - case SRL -> rs1_val >> (rs2_val[5..0]) - case SRA -> shift_right_arith64(rs1_val, rs2_val[5..0]) - case OR -> rs1_val | rs2_val - case AND -> rs1_val & rs2_val + case RISCV_ADD -> rs1_val + rs2_val + case RISCV_SUB -> rs1_val - rs2_val + case RISCV_SLL -> rs1_val << (rs2_val[5..0]) + case RISCV_SLT -> EXTZ(rs1_val <_s rs2_val) + case RISCV_SLTU -> EXTZ(rs1_val <_u rs2_val) + case RISCV_XOR -> rs1_val ^ rs2_val + case RISCV_SRL -> rs1_val >> (rs2_val[5..0]) + case RISCV_SRA -> shift_right_arith64(rs1_val, rs2_val[5..0]) + case RISCV_OR -> rs1_val | rs2_val + case RISCV_AND -> rs1_val & rs2_val } in wGPR(rd, result) -union ast member ((bit[12]), regno, regno, bool, word_width) LOAD -function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, BYTE)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b001 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, HALF)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b010 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, WORD)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b011 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, DOUBLE)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b100 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, true, BYTE)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b101 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, true, HALF)) -function clause decode ((bit[12]) imm : (regno) rs1 : 0b110 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, true, WORD)) -function clause execute(LOAD(imm, rs1, rd, unsigned, width)) = +(********************************************************************) +union ast member ((bit[12]), regno, regno, bool, word_width, bool, bool) LOAD + +function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, BYTE, false, false)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b001 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, HALF, false, false)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b010 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, WORD, false, false)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b011 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, false, DOUBLE, false, false)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b100 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, true, BYTE, false, false)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b101 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, true, HALF, false, false)) +function clause decode ((bit[12]) imm : (regno) rs1 : 0b110 : (regno) rd : 0b0000011) = Some(LOAD(imm, rs1, rd, true, WORD, false, false)) + +function clause execute(LOAD(imm, rs1, rd, unsigned, width, aq, rl)) = let (bit[64]) addr = rGPR(rs1) + EXTS(imm) in let (bit[64]) result = if unsigned then switch (width) { - case BYTE -> EXTZ(MEMr(addr, 1)) - case HALF -> EXTZ(MEMr(addr, 2)) - case WORD -> EXTZ(MEMr(addr, 4)) - case DOUBLE -> MEMr(addr, 8) + case BYTE -> EXTZ(mem_read(addr, 1, aq, rl, false)) + case HALF -> EXTZ(mem_read(addr, 2, aq, rl, false)) + case WORD -> EXTZ(mem_read(addr, 4, aq, rl, false)) + case DOUBLE -> mem_read(addr, 8, aq, rl, false) } else switch (width) { - case BYTE -> EXTS(MEMr(addr, 1)) - case HALF -> EXTS(MEMr(addr, 2)) - case WORD -> EXTS(MEMr(addr, 4)) - case DOUBLE -> MEMr(addr, 8) + case BYTE -> EXTS(mem_read(addr, 1, aq, rl, false)) + case HALF -> EXTS(mem_read(addr, 2, aq, rl, false)) + case WORD -> EXTS(mem_read(addr, 4, aq, rl, false)) + case DOUBLE -> mem_read(addr, 8, aq, rl, false) } in wGPR(rd, result) -union ast member ((bit[12]), regno, regno, word_width) STORE -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b000 : (bit[5]) imm5 : 0b0100011) = Some(STORE(imm7 : imm5, rs2, rs1, BYTE)) -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b001 : (bit[5]) imm5 : 0b0100011) = Some(STORE(imm7 : imm5, rs2, rs1, HALF)) -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b010 : (bit[5]) imm5 : 0b0100011) = Some(STORE(imm7 : imm5, rs2, rs1, WORD)) -function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b011 : (bit[5]) imm5 : 0b0100011) = Some(STORE(imm7 : imm5, rs2, rs1, DOUBLE)) -function clause execute (STORE(imm, rs2, rs1, width)) = +(********************************************************************) +union ast member ((bit[12]), regno, regno, word_width, bool, bool) STORE + +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b000 : (bit[5]) imm5 : 0b0100011) = + Some(STORE(imm7 : imm5, rs2, rs1, BYTE, false, false)) +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b001 : (bit[5]) imm5 : 0b0100011) = + Some(STORE(imm7 : imm5, rs2, rs1, HALF, false, false)) +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b010 : (bit[5]) imm5 : 0b0100011) = + Some(STORE(imm7 : imm5, rs2, rs1, WORD, false, false)) +function clause decode ((bit[7]) imm7 : (regno) rs2 : (regno) rs1 : 0b011 : (bit[5]) imm5 : 0b0100011) = + Some(STORE(imm7 : imm5, rs2, rs1, DOUBLE, false, false)) + +function clause execute (STORE(imm, rs2, rs1, width, aq, rl)) = let (bit[64]) addr = rGPR(rs1) + EXTS(imm) in { switch (width) { - case BYTE -> MEMea(addr, 1) - case HALF -> MEMea(addr, 2) - case WORD -> MEMea(addr, 4) - case DOUBLE -> MEMea(addr, 8) + case BYTE -> mem_write_ea(addr, 1, aq, rl, false) + case HALF -> mem_write_ea(addr, 2, aq, rl, false) + case WORD -> mem_write_ea(addr, 4, aq, rl, false) + case DOUBLE -> mem_write_ea(addr, 8, aq, rl, false) }; let rs2_val = rGPR(rs2) in switch (width) { - case BYTE -> MEMval(addr, 1, rs2_val[7..0]) - case HALF -> MEMval(addr, 2, rs2_val[15..0]) - case WORD -> MEMval(addr, 4, rs2_val[31..0]) - case DOUBLE -> MEMval(addr, 8, rs2_val) + case BYTE -> mem_write_value(addr, 1, rs2_val[7..0], aq, rl, false) + case HALF -> mem_write_value(addr, 2, rs2_val[15..0], aq, rl, false) + case WORD -> mem_write_value(addr, 4, rs2_val[31..0], aq, rl, false) + case DOUBLE -> mem_write_value(addr, 8, rs2_val, aq, rl, false) } } +(********************************************************************) union ast member ((bit[12]), regno, regno) ADDIW -function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b0011011) = Some(ADDIW(imm, rs1, rd)) + +function clause decode ((bit[12]) imm : (regno) rs1 : 0b000 : (regno) rd : 0b0011011) = + Some(ADDIW(imm, rs1, rd)) + function clause execute (ADDIW(imm, rs1, rd)) = let (bit[64]) imm64 = EXTS(imm) in let (bit[64]) result64 = imm64 + rGPR(rs1) in let (bit[64]) result32 = EXTS(result64[31..0]) in wGPR(rd, result32) +(********************************************************************) union ast member ((bit[5]), regno, regno, sop) SHIFTW -function clause decode (0b0000000 : (bit[5]) shamt : (regno) rs1 : 0b001 : (regno) rd : 0b0011011) = Some(SHIFTW(shamt, rs1, rd, SLLI)) -function clause decode (0b0000000 : (bit[5]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0011011) = Some(SHIFTW(shamt, rs1, rd, SRLI)) -function clause decode (0b0100000 : (bit[5]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0011011) = Some(SHIFTW(shamt, rs1, rd, SRAI)) + +function clause decode (0b0000000 : (bit[5]) shamt : (regno) rs1 : 0b001 : (regno) rd : 0b0011011) = Some(SHIFTW(shamt, rs1, rd, RISCV_SLLI)) +function clause decode (0b0000000 : (bit[5]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0011011) = Some(SHIFTW(shamt, rs1, rd, RISCV_SRLI)) +function clause decode (0b0100000 : (bit[5]) shamt : (regno) rs1 : 0b101 : (regno) rd : 0b0011011) = Some(SHIFTW(shamt, rs1, rd, RISCV_SRAI)) + function clause execute (SHIFTW(shamt, rs1, rd, op)) = let rs1_val = (rGPR(rs1))[31..0] in let result = switch(op) { - case SLLI -> rs1_val >> shamt - case SRLI -> rs1_val << shamt - case SRAI -> shift_right_arith32(rs1_val, shamt) + case RISCV_SLLI -> rs1_val >> shamt + case RISCV_SRLI -> rs1_val << shamt + case RISCV_SRAI -> shift_right_arith32(rs1_val, shamt) } in wGPR(rd, EXTS(result)) +(********************************************************************) union ast member (regno, regno, regno, ropw) RTYPEW -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, ADDW)) -function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, SUBW)) -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b001 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, SLLW)) -function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, SRLW)) -function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, SRAW)) + +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, RISCV_ADDW)) +function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b000 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, RISCV_SUBW)) +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b001 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, RISCV_SLLW)) +function clause decode (0b0000000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, RISCV_SRLW)) +function clause decode (0b0100000 : (regno) rs2 : (regno) rs1 : 0b101 : (regno) rd : 0b0111011) = Some(RTYPEW(rs2, rs1, rd, RISCV_SRAW)) + function clause execute (RTYPEW(rs2, rs1, rd, op)) = let rs1_val = (rGPR(rs1))[31..0] in let rs2_val = (rGPR(rs2))[31..0] in let (bit[32]) result = switch(op) { - case ADDW -> rs1_val + rs2_val - case SUBW -> rs1_val - rs2_val - case SLLW -> rs1_val << (rs2_val[4..0]) - case SRLW -> rs1_val >> (rs2_val[4..0]) - case SRAW -> shift_right_arith32(rs1_val, rs2_val[4..0]) + case RISCV_ADDW -> rs1_val + rs2_val + case RISCV_SUBW -> rs1_val - rs2_val + case RISCV_SLLW -> rs1_val << (rs2_val[4..0]) + case RISCV_SRLW -> rs1_val >> (rs2_val[4..0]) + case RISCV_SRAW -> shift_right_arith32(rs1_val, rs2_val[4..0]) } in wGPR(rd, EXTS(result)) +(********************************************************************) union ast member (bit[4], bit[4]) FENCE + function clause decode (0b0000 : (bit[4]) pred : (bit[4]) succ : 0b00000 : 0b000 : 0b00000 : 0b0001111) = Some(FENCE (pred, succ)) + function clause execute (FENCE(pred, succ)) = { switch(pred, succ) { case (0b0011, 0b0011) -> MEM_fence_rw_rw() case (0b0010, 0b0011) -> MEM_fence_r_rw() + case (0b0010, 0b0010) -> MEM_fence_r_r() case (0b0011, 0b0001) -> MEM_fence_rw_w() + case (0b0001, 0b0001) -> MEM_fence_w_w() case _ -> not_implemented("unsupported fence") } } +(********************************************************************) union ast member unit FENCEI -function clause decode (0b0000 : 0b0000 : 0b0000 : 0b00000 : 0b001 : 0b00000 : 0b0001111) = Some(FENCEI) -function clause execute FENCEI = () (* XXX TODO *) +function clause decode (0b000000000000 : 0b00000 : 0b001 : 0b00000 : 0b0001111) = Some(FENCEI) +function clause execute FENCEI = MEM_fence_i() +(********************************************************************) union ast member unit ECALL function clause decode (0b000000000000 : 0b00000 : 0b000 : 0b00000 : 0b1110011) = Some(ECALL ()) -function clause execute ECALL = () +function clause execute ECALL = not_implemented("ECALL is not implemented") +(********************************************************************) union ast member unit EBREAK function clause decode (0b000000000001 : 0b00000 : 0b000 : 0b00000 : 0b1110011) = Some(EBREAK ()) function clause execute EBREAK = { exit () } +(********************************************************************) +union ast member (bool, bool, regno, word_width, regno) LOADRES + +function clause decode (0b00010 : [aq] : [rl] : 0b00000 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = Some(LOADRES(aq, rl, rs1, WORD, rd)) +function clause decode (0b00010 : [aq] : [rl] : 0b00000 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = Some(LOADRES(aq, rl, rs1, DOUBLE, rd)) +function clause execute(LOADRES(aq, rl, rs1, width, rd)) = + let (bit[64]) addr = rGPR(rs1) in + let (bit[64]) result = + switch width { + case WORD -> EXTS(mem_read(addr, 4, aq, rl, true)) + case DOUBLE -> mem_read(addr, 8, aq, rl, true) + } in + wGPR(rd, result) + +(********************************************************************) +union ast member (bool, bool, regno, regno, word_width, regno) STORECON + +function clause decode (0b00011 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(STORECON(aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b00011 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(STORECON(aq, rl, rs2, rs1, DOUBLE, rd)) + +function clause execute (STORECON(aq, rl, rs2, rs1, width, rd)) = { + (*(bit)*) status := if speculate_conditional_success() then 0 else 1; + wGPR(rd) := (bit[64]) (EXTZ([status])); + + if status == 1 then () else { + (bit[64]) addr := rGPR(rs1); + switch width { + case WORD -> mem_write_ea(addr, 4, aq, rl, true) + case DOUBLE -> mem_write_ea(addr, 8, aq, rl, true) + }; + rs2_val := rGPR(rs2); + switch width { + case WORD -> mem_write_value(addr, 4, rs2_val[31..0], aq, rl, true) + case DOUBLE -> mem_write_value(addr, 8, rs2_val, aq, rl, true) + }; + }; +} + +(********************************************************************) +union ast member (amoop, bool, bool, regno, regno, word_width, regno) AMO + +function clause decode (0b00001 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(AMO(AMOSWAP, aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b00001 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(AMO(AMOSWAP, aq, rl, rs2, rs1, DOUBLE, rd)) +function clause decode (0b00000 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(AMO(AMOADD , aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b00000 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(AMO(AMOADD , aq, rl, rs2, rs1, DOUBLE, rd)) +function clause decode (0b00100 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(AMO(AMOXOR , aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b00100 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(AMO(AMOXOR , aq, rl, rs2, rs1, DOUBLE, rd)) +function clause decode (0b01100 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(AMO(AMOAND , aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b01100 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(AMO(AMOAND , aq, rl, rs2, rs1, DOUBLE, rd)) +function clause decode (0b01000 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(AMO(AMOOR , aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b01000 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(AMO(AMOOR , aq, rl, rs2, rs1, DOUBLE, rd)) +function clause decode (0b10000 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(AMO(AMOMIN , aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b10000 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(AMO(AMOMIN , aq, rl, rs2, rs1, DOUBLE, rd)) +function clause decode (0b10100 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(AMO(AMOMAX , aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b10100 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(AMO(AMOMAX , aq, rl, rs2, rs1, DOUBLE, rd)) +function clause decode (0b11000 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(AMO(AMOMINU, aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b11000 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(AMO(AMOMINU, aq, rl, rs2, rs1, DOUBLE, rd)) +function clause decode (0b11100 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b010 : (regno) rd : 0b0101111) = + Some(AMO(AMOMAXU, aq, rl, rs2, rs1, WORD, rd)) +function clause decode (0b11100 : [aq] : [rl] : (regno) rs2 : (regno) rs1 : 0b011 : (regno) rd : 0b0101111) = + Some(AMO(AMOMAXU, aq, rl, rs2, rs1, DOUBLE, rd)) + +function clause execute (AMO(op, aq, rl, rs2, rs1, width, rd)) = { + (bit[64]) addr := rGPR(rs1); + + switch (width) { + case WORD -> mem_write_ea(addr, 4, aq & rl, rl, true) + case DOUBLE -> mem_write_ea(addr, 8, aq & rl, rl, true) + }; + + (bit[64]) loaded := + switch (width) { + case WORD -> EXTS(mem_read(addr, 4, aq, aq & rl, true)) + case DOUBLE -> mem_read(addr, 8, aq, aq & rl, true) + }; + wGPR(rd, loaded); + + (bit[64]) rs2_val := rGPR(rs2); + (bit[64]) result := + switch(op) { + case AMOSWAP -> rs2_val + case AMOADD -> rs2_val + loaded + case AMOXOR -> rs2_val ^ loaded + case AMOAND -> rs2_val & loaded + case AMOOR -> rs2_val | loaded + + case AMOMIN -> (bit[64]) (min(signed(rs2_val), signed(loaded))) + case AMOMAX -> (bit[64]) (max(signed(rs2_val), signed(loaded))) + case AMOMINU -> (bit[64]) (min(unsigned(rs2_val), unsigned(loaded))) + case AMOMAXU -> (bit[64]) (max(unsigned(rs2_val), unsigned(loaded))) + }; + + switch (width) { + case WORD -> mem_write_value(addr, 4, result[31..0], aq & rl, rl, true) + case DOUBLE -> mem_write_value(addr, 8, result, aq & rl, rl, true) + }; +} + +(********************************************************************) function clause decode _ = None diff --git a/risc-v/riscv_extras.lem b/risc-v/riscv_extras.lem index aa5d8fb8..4ca5f9b7 100644 --- a/risc-v/riscv_extras.lem +++ b/risc-v/riscv_extras.lem @@ -31,30 +31,53 @@ let memory_parameter_transformer_option_address _mode v = end -let read_memory_functions : memory_reads = - [ ("MEMr", (MR Read_plain memory_parameter_transformer)); - ("MEMr_reserve", (MR Read_reserve memory_parameter_transformer)); +let riscv_read_memory_functions : memory_reads = + [ ("MEMr", (MR Read_plain memory_parameter_transformer)); + ("MEMr_acquire", (MR Read_RISCV_acquire memory_parameter_transformer)); + ("MEMr_strong_acquire", (MR Read_RISCV_strong_acquire memory_parameter_transformer)); + ("MEMr_reserved", (MR Read_RISCV_reserved memory_parameter_transformer)); + ("MEMr_reserved_acquire", (MR Read_RISCV_reserved_acquire memory_parameter_transformer)); + ("MEMr_reserved_strong_acquire", + (MR Read_RISCV_reserved_acquire memory_parameter_transformer)); ] -let memory_writes : memory_writes = +let riscv_memory_writes : memory_writes = [] -let memory_eas : memory_write_eas = - [ ("MEMea", (MEA Write_plain memory_parameter_transformer)); - ("MEMea_conditional", (MEA Write_conditional memory_parameter_transformer)); +let riscv_memory_eas : memory_write_eas = + [ ("MEMea", (MEA Write_plain memory_parameter_transformer)); + ("MEMea_release", (MEA Write_RISCV_release memory_parameter_transformer)); + ("MEMea_strong_release", (MEA Write_RISCV_strong_release memory_parameter_transformer)); + ("MEMea_conditional", (MEA Write_RISCV_conditional memory_parameter_transformer)); + ("MEMea_conditional_release", (MEA Write_RISCV_conditional_release memory_parameter_transformer)); + ("MEMea_conditional_strong_release", + (MEA Write_RISCV_conditional_strong_release + memory_parameter_transformer)); ] -let memory_vals : memory_write_vals = - [ ("MEMval", (MV memory_parameter_transformer_option_address Nothing)); - ("MEMval_conditional", (MV memory_parameter_transformer_option_address - (Just - (fun (IState interp context) b -> - let bit = Interp_ast.V_lit (L_aux (if b then L_one else L_zero) Interp_ast.Unknown) in - (IState (Interp.add_answer_to_stack interp bit) context))))); +let riscv_memory_vals : memory_write_vals = + [ ("MEMval", (MV memory_parameter_transformer_option_address Nothing)); + ("MEMval_release", (MV memory_parameter_transformer_option_address Nothing)); + ("MEMval_strong_release", (MV memory_parameter_transformer_option_address Nothing)); + ("MEMval_conditional", (MV memory_parameter_transformer_option_address Nothing)); + ("MEMval_conditional_release",(MV memory_parameter_transformer_option_address Nothing)); + ("MEMval_conditional_strong_release", + (MV memory_parameter_transformer_option_address Nothing)); + ] -let barrier_functions = +let riscv_speculate_conditional_success : excl_res = + let f = fun (IState interp context) b -> + let bool_res = Interp_ast.V_lit (L_aux (if b then L_one else L_zero) Interp_ast.Unknown) in + IState (Interp.add_answer_to_stack interp bool_res) context + in + Just ("speculate_conditional_success", (ER (Just f))) + +let riscv_barrier_functions = [ ("MEM_fence_rw_rw", Barrier_RISCV_rw_rw); ("MEM_fence_r_rw", Barrier_RISCV_r_rw); + ("MEM_fence_r_r", Barrier_RISCV_r_r); ("MEM_fence_rw_w", Barrier_RISCV_rw_w); + ("MEM_fence_w_w", Barrier_RISCV_w_w); + ("MEM_fence_i", Barrier_RISCV_i); ] diff --git a/risc-v/riscv_extras_embed.lem b/risc-v/riscv_extras_embed.lem index 1146d1cd..32110079 100644 --- a/risc-v/riscv_extras_embed.lem +++ b/risc-v/riscv_extras_embed.lem @@ -4,31 +4,66 @@ open import Sail_impl_base open import Sail_values open import Prompt -val MEMr : (vector bitU * integer) -> M (vector bitU) -val MEMr_reserve : (vector bitU * integer) -> M (vector bitU) +val MEMr : (vector bitU * integer) -> M (vector bitU) +val MEMr_acquire : (vector bitU * integer) -> M (vector bitU) +val MEMr_strong_acquire : (vector bitU * integer) -> M (vector bitU) +val MEMr_reserved : (vector bitU * integer) -> M (vector bitU) +val MEMr_reserved_acquire : (vector bitU * integer) -> M (vector bitU) +val MEMr_reserved_strong_acquire : (vector bitU * integer) -> M (vector bitU) -let MEMr (addr,size) = read_mem false Read_plain addr size -let MEMr_reserve (addr,size) = read_mem false Read_reserve addr size +let MEMr (addr,size) = read_mem false Read_plain addr size +let MEMr_acquire (addr,size) = read_mem false Read_RISCV_acquire addr size +let MEMr_strong_acquire (addr,size) = read_mem false Read_RISCV_strong_acquire addr size +let MEMr_reserved (addr,size) = read_mem false Read_RISCV_reserved addr size +let MEMr_reserved_acquire (addr,size) = read_mem false Read_RISCV_reserved_acquire addr size +let MEMr_reserved_strong_acquire (addr,size) + = read_mem false Read_RISCV_reserved_strong_acquire addr size -val MEMea : (vector bitU * integer) -> M unit -val MEMea_conditional : (vector bitU * integer) -> M unit +val MEMea : (vector bitU * integer) -> M unit +val MEMea_release : (vector bitU * integer) -> M unit +val MEMea_strong_release : (vector bitU * integer) -> M unit +val MEMea_conditional : (vector bitU * integer) -> M unit +val MEMea_conditional_release : (vector bitU * integer) -> M unit +val MEMea_conditional_strong_release : (vector bitU * integer) -> M unit -let MEMea (addr,size) = write_mem_ea Write_plain addr size -let MEMea_conditional (addr,size) = write_mem_ea Write_conditional addr size +let MEMea (addr,size) = write_mem_ea Write_plain addr size +let MEMea_release (addr,size) = write_mem_ea Write_RISCV_release addr size +let MEMea_strong_release (addr,size) = write_mem_ea Write_RISCV_strong_release addr size +let MEMea_conditional (addr,size) = write_mem_ea Write_RISCV_conditional addr size +let MEMea_conditional_release (addr,size) = write_mem_ea Write_RISCV_conditional_release addr size +let MEMea_conditional_strong_release (addr,size) + = write_mem_ea Write_RISCV_conditional_strong_release addr size -val MEMval : (vector bitU * integer * vector bitU) -> M unit -val MEMval_conditional : (vector bitU * integer * vector bitU) -> M bitU +val MEMval : (vector bitU * integer * vector bitU) -> M unit +val MEMval_release : (vector bitU * integer * vector bitU) -> M unit +val MEMval_strong_release : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional_release : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional_strong_release : (vector bitU * integer * vector bitU) -> M unit -let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return () -let MEMval_conditional (_,_,v) = write_mem_val v >>= fun b -> return (if b then B1 else B0) +let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_release (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_strong_release (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_conditional (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_conditional_release (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_conditional_strong_release (_,_,v) + = write_mem_val v >>= fun _ -> return () + +let speculate_conditional_success () = excl_result () >>= fun b -> return (if b then B1 else B0) val MEM_fence_rw_rw : unit -> M unit val MEM_fence_r_rw : unit -> M unit +val MEM_fence_r_r : unit -> M unit val MEM_fence_rw_w : unit -> M unit +val MEM_fence_w_w : unit -> M unit +val MEM_fence_i : unit -> M unit let MEM_fence_rw_rw () = barrier Barrier_RISCV_rw_rw let MEM_fence_r_rw () = barrier Barrier_RISCV_r_rw +let MEM_fence_r_r () = barrier Barrier_RISCV_r_r let MEM_fence_rw_w () = barrier Barrier_RISCV_rw_w +let MEM_fence_w_w () = barrier Barrier_RISCV_w_w +let MEM_fence_i () = barrier Barrier_RISCV_i let duplicate (bit,len) = let bits = repeat [bit] len in diff --git a/risc-v/riscv_extras_embed_sequential.lem b/risc-v/riscv_extras_embed_sequential.lem index f6709ff7..3c922268 100644 --- a/risc-v/riscv_extras_embed_sequential.lem +++ b/risc-v/riscv_extras_embed_sequential.lem @@ -4,32 +4,66 @@ open import Sail_impl_base open import Sail_values open import State -val MEMr : (vector bitU * integer) -> M (vector bitU) -val MEMr_reserve : (vector bitU * integer) -> M (vector bitU) +val MEMr : (vector bitU * integer) -> M (vector bitU) +val MEMr_acquire : (vector bitU * integer) -> M (vector bitU) +val MEMr_strong_acquire : (vector bitU * integer) -> M (vector bitU) +val MEMr_reserved : (vector bitU * integer) -> M (vector bitU) +val MEMr_reserved_acquire : (vector bitU * integer) -> M (vector bitU) +val MEMr_reserved_strong_acquire : (vector bitU * integer) -> M (vector bitU) -let MEMr (addr,size) = read_mem false Read_plain addr size -let MEMr_reserve (addr,size) = read_mem false Read_reserve addr size +let MEMr (addr,size) = read_mem false Read_plain addr size +let MEMr_acquire (addr,size) = read_mem false Read_RISCV_acquire addr size +let MEMr_strong_acquire (addr,size) = read_mem false Read_RISCV_strong_acquire addr size +let MEMr_reserved (addr,size) = read_mem false Read_RISCV_reserved addr size +let MEMr_reserved_acquire (addr,size) = read_mem false Read_RISCV_reserved_acquire addr size +let MEMr_reserved_strong_acquire (addr,size) + = read_mem false Read_RISCV_reserved_strong_acquire addr size -val MEMea : (vector bitU * integer) -> M unit -val MEMea_conditional : (vector bitU * integer) -> M unit +val MEMea : (vector bitU * integer) -> M unit +val MEMea_release : (vector bitU * integer) -> M unit +val MEMea_strong_release : (vector bitU * integer) -> M unit +val MEMea_conditional : (vector bitU * integer) -> M unit +val MEMea_conditional_release : (vector bitU * integer) -> M unit +val MEMea_conditional_strong_release : (vector bitU * integer) -> M unit -let MEMea (addr,size) = write_mem_ea Write_plain addr size -let MEMea_conditional (addr,size) = write_mem_ea Write_conditional addr size +let MEMea (addr,size) = write_mem_ea Write_plain addr size +let MEMea_release (addr,size) = write_mem_ea Write_RISCV_release addr size +let MEMea_strong_release (addr,size) = write_mem_ea Write_RISCV_strong_release addr size +let MEMea_conditional (addr,size) = write_mem_ea Write_RISCV_conditional addr size +let MEMea_conditional_release (addr,size) = write_mem_ea Write_RISCV_conditional_release addr size +let MEMea_conditional_strong_release (addr,size) + = write_mem_ea Write_RISCV_conditional_strong_release addr size +val MEMval : (vector bitU * integer * vector bitU) -> M unit +val MEMval_release : (vector bitU * integer * vector bitU) -> M unit +val MEMval_strong_release : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional_release : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional_strong_release : (vector bitU * integer * vector bitU) -> M unit -val MEMval : (vector bitU * integer * vector bitU) -> M unit -val MEMval_conditional : (vector bitU * integer * vector bitU) -> M bitU +let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_release (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_strong_release (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_conditional (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_conditional_release (_,_,v) = write_mem_val v >>= fun _ -> return () +let MEMval_conditional_strong_release (_,_,v) + = write_mem_val v >>= fun _ -> return () -let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return () -let MEMval_conditional (_,_,v) = write_mem_val v >>= fun b -> return (if b then B1 else B0) +let speculate_conditional_success () = excl_result () >>= fun b -> return (if b then B1 else B0) val MEM_fence_rw_rw : unit -> M unit val MEM_fence_r_rw : unit -> M unit +val MEM_fence_r_r : unit -> M unit val MEM_fence_rw_w : unit -> M unit +val MEM_fence_w_w : unit -> M unit +val MEM_fence_i : unit -> M unit let MEM_fence_rw_rw () = barrier Barrier_RISCV_rw_rw let MEM_fence_r_rw () = barrier Barrier_RISCV_r_rw +let MEM_fence_r_r () = barrier Barrier_RISCV_r_r let MEM_fence_rw_w () = barrier Barrier_RISCV_rw_w +let MEM_fence_w_w () = barrier Barrier_RISCV_w_w +let MEM_fence_i () = barrier Barrier_RISCV_i let duplicate (bit,len) = let bits = repeat [bit] len in diff --git a/risc-v/riscv_regfp.sail b/risc-v/riscv_regfp.sail index 0c7a67d8..dee9cc8e 100644 --- a/risc-v/riscv_regfp.sail +++ b/risc-v/riscv_regfp.sail @@ -20,16 +20,16 @@ function (regfps,regfps,regfps,niafps,diafp,instruction_kind) initial_analysis ( case (UTYPE ( imm, rd, op)) -> { if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR; } - case (JAL ( imm, rd)) -> { + case (RISCV_JAL ( imm, rd)) -> { if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR; let (bit[64]) offset = EXTS(imm) in Nias := [|| NIAFP_concrete_address (PC + offset) ||] } - case (JALR ( imm, rs, rd)) -> { + case (RISCV_JALR ( imm, rs, rd)) -> { if (rs == 0) then () else iR := RFull(GPRstr[rs]) :: iR; if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR; let (bit[64]) offset = EXTS(imm) in - Nias := [|| NIAFP_register (RFull(GPRstr[rs])) ||]; (* XXX this should br rs + offset... *) + Nias := [|| NIAFP_register (RFull(GPRstr[rs])) ||]; } case (BTYPE ( imm, rs2, rs1, op)) -> { if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR; @@ -51,17 +51,29 @@ function (regfps,regfps,regfps,niafps,diafp,instruction_kind) initial_analysis ( if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR; if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR; } - case (LOAD ( imm, rs, rd, unsign, width)) -> { (* XXX "unsigned" causes name conflict in lem shallow embedding... *) + case (LOAD ( imm, rs, rd, unsign, width, aq, rl)) -> { (* XXX "unsigned" causes name conflict in lem shallow embedding... *) if (rs == 0) then () else iR := RFull(GPRstr[rs]) :: iR; if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR; aR := iR; - ik := IK_mem_read (Read_plain); + ik := + switch (aq, rl) { + case (false, false) -> IK_mem_read (Read_plain) + case (true, false) -> IK_mem_read (Read_RISCV_acquire) + case (false, true) -> exit "not implemented" + case (true, true) -> IK_mem_read (Read_RISCV_strong_acquire) + }; } - case (STORE( imm, rs2, rs1, width)) -> { + case (STORE( imm, rs2, rs1, width, aq, rl)) -> { if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR; if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR; if (rs1 == 0) then () else aR := RFull(GPRstr[rs1]) :: aR; - ik := IK_mem_write (Write_plain); + ik := + switch (aq, rl) { + case (false, false) -> IK_mem_write (Write_plain) + case (true, false) -> exit "not implemented" + case (false, true) -> IK_mem_write (Write_RISCV_release) + case (true, true) -> IK_mem_write (Write_RISCV_strong_release) + }; } case (ADDIW ( imm, rs, rd)) -> { if (rs == 0) then () else iR := RFull(GPRstr[rs]) :: iR; @@ -77,7 +89,56 @@ function (regfps,regfps,regfps,niafps,diafp,instruction_kind) initial_analysis ( if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR; } case (FENCE(pred, succ)) -> { - ik := IK_barrier (Barrier_MIPS_SYNC); + ik := + switch(pred, succ) { + case (0b0011, 0b0011) -> IK_barrier (Barrier_RISCV_rw_rw) + case (0b0010, 0b0011) -> IK_barrier (Barrier_RISCV_r_rw) + case (0b0010, 0b0010) -> IK_barrier (Barrier_RISCV_r_r) + case (0b0011, 0b0001) -> IK_barrier (Barrier_RISCV_rw_w) + case (0b0001, 0b0001) -> IK_barrier (Barrier_RISCV_w_w) + case _ -> exit "not implemented" + }; + } + case (FENCEI) -> { + ik := IK_barrier (Barrier_RISCV_i); + } + case (LOADRES ( aq, rl, rs1, width, rd)) -> { + if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR; + if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR; + aR := iR; + ik := switch (aq, rl) { + case (false, false) -> IK_mem_read (Read_RISCV_reserved) + case (true, false) -> IK_mem_read (Read_RISCV_reserved_acquire) + case (false, true) -> exit "not implemented" + case (true, true) -> IK_mem_read (Read_RISCV_reserved_strong_acquire) + }; + } + case (STORECON( aq, rl, rs2, rs1, width, rd)) -> { + if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR; + if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR; + if (rs1 == 0) then () else aR := RFull(GPRstr[rs1]) :: aR; + if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR; + + ik := switch (aq, rl) { + case (false, false) -> IK_mem_write (Write_RISCV_conditional) + case (false, true) -> IK_mem_write (Write_RISCV_conditional_release) + case (true, _) -> exit "not implemented" + }; + } + case (AMO( op, aq, rl, rs2, rs1, width, rd)) -> { + if (rs2 == 0) then () else iR := RFull(GPRstr[rs2]) :: iR; + if (rs1 == 0) then () else iR := RFull(GPRstr[rs1]) :: iR; + if (rs1 == 0) then () else aR := RFull(GPRstr[rs1]) :: aR; + if (rd == 0) then () else oR := RFull(GPRstr[rd]) :: oR; + + ik := switch (aq, rl) { + case (false, false) -> IK_mem_rmw (Read_RISCV_reserved, Write_RISCV_conditional) + case (false, true) -> IK_mem_rmw (Read_RISCV_reserved, Write_RISCV_conditional_release) + case (true, false) -> IK_mem_rmw (Read_RISCV_reserved_acquire, + Write_RISCV_conditional) + case (true, true) -> IK_mem_rmw (Read_RISCV_reserved_strong_acquire, + Write_RISCV_conditional_strong_release) + }; } }; (iR,oR,aR,Nias,Dia,ik) diff --git a/risc-v/riscv_types.sail b/risc-v/riscv_types.sail new file mode 100644 index 00000000..b584ae9b --- /dev/null +++ b/risc-v/riscv_types.sail @@ -0,0 +1,166 @@ +default Order dec + +function forall 'a. 'a effect { escape } not_implemented((string) message) = + exit message + +typedef regval = bit[64] +typedef regno = bit[5] + +(* register (regval) x0 is hard-wired zero *) +register (regval) x1 +register (regval) x2 +register (regval) x3 +register (regval) x4 +register (regval) x5 +register (regval) x6 +register (regval) x7 +register (regval) x8 +register (regval) x9 +register (regval) x10 +register (regval) x11 +register (regval) x12 +register (regval) x13 +register (regval) x14 +register (regval) x15 +register (regval) x16 +register (regval) x17 +register (regval) x18 +register (regval) x19 +register (regval) x20 +register (regval) x21 +register (regval) x22 +register (regval) x23 +register (regval) x24 +register (regval) x25 +register (regval) x26 +register (regval) x27 +register (regval) x28 +register (regval) x29 +register (regval) x30 +register (regval) x31 + +register (bit[64]) PC +register (bit[64]) nextPC + +let (vector <1, 31, inc, (register<(regval)>)>) GPRs = + [ (* x0, *) x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, + x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, + x28, x29, x30, x31 + ] + +function (regval) rGPR ((regno) r) = + if (r == 0) then + 0 + else + GPRs[r] + +function unit wGPR((regno) r, (regval) v) = + if (r != 0) then + GPRs[r] := v + +function unit effect { escape } check_alignment( (bit[64]) addr, (nat) width) = + if (unsigned(addr) mod width != 0) then + exit "misaligned memory access" + +val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr +val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr_acquire +val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr_strong_acquire +val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr_reserved +val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr_reserved_acquire +val extern forall Nat 'n. ( bit[64] , [|'n|] ) -> (bit[8 * 'n]) effect { rmem } MEMr_reserved_strong_acquire + +function forall Nat 'n. (bit[8 * 'n]) effect { rmem, escape } mem_read( (bit[64]) addr, ([|'n|]) width, (bool) aq, (bool) rl, (bool) res) = +{ + if (aq | res) then + check_alignment(addr, width); + + switch (aq, rl, res) { + case (false, false, false) -> MEMr(addr, width) + case (true, false, false) -> MEMr_acquire(addr, width) + case (false, false, true) -> MEMr_reserved(addr, width) + case (true, false, true) -> MEMr_reserved_acquire(addr, width) + case (false, true, false) -> not_implemented("load.rl is not implemented") + case (true, true, false) -> MEMr_strong_acquire(addr, width) + case (false, true, true) -> not_implemented("lr.rl is not implemented") + case (true, true, true) -> MEMr_reserved_strong_acquire(addr, width) + } +} + +val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea +val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea_release +val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea_strong_release +val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea_conditional +val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea_conditional_release +val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea_conditional_strong_release + +function forall Nat 'n. unit effect { eamem, escape } mem_write_ea( (bit[64]) addr , ([|'n|]) width, (bool) aq, (bool) rl, (bool) con) = +{ + if (rl | con) then + check_alignment(addr, width); + + switch (aq, rl, con) { + case (false, false, false) -> MEMea(addr, width) + case (false, true, false) -> MEMea_release(addr, width) + case (false, false, true) -> MEMea_conditional(addr, width) + case (false, true , true) -> MEMea_conditional_release(addr, width) + case (true, false, false) -> not_implemented("store.aq is not implemented") + case (true, true, false) -> MEMea_strong_release(addr, width) + case (true, false, true) -> not_implemented("sc.aq is not implemented") + case (true, true , true) -> MEMea_conditional_strong_release(addr, width) + } +} + +val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval +val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval_release +val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval_strong_release +val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval_conditional +val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval_conditional_release +val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval_conditional_strong_release + +function forall Nat 'n. unit effect { wmv, escape } mem_write_value( (bit[64]) addr , ([|'n|]) width , (bit[8*'n]) value, (bool) aq, (bool) rl, (bool) con) = +{ + if (rl | con) then + check_alignment(addr, width); + + switch (aq, rl, con) { + case (false, false, false) -> MEMval(addr, width, value) + case (false, true, false) -> MEMval_release(addr, width, value) + case (false, false, true) -> MEMval_conditional(addr, width, value) + case (false, true, true) -> MEMval_conditional_release(addr, width, value) + case (true, false, false) -> not_implemented("store.aq is not implemented") + case (true, true, false) -> MEMval_strong_release(addr, width, value) + case (true, false, true) -> not_implemented("sc.aq is not implemented") + case (true, true, true) -> MEMval_conditional_strong_release(addr, width, value) + } +} + +val extern unit -> bool effect {exmem} speculate_conditional_success + +val extern unit -> unit effect { barr } MEM_fence_rw_rw +val extern unit -> unit effect { barr } MEM_fence_r_rw +val extern unit -> unit effect { barr } MEM_fence_r_r +val extern unit -> unit effect { barr } MEM_fence_rw_w +val extern unit -> unit effect { barr } MEM_fence_w_w +val extern unit -> unit effect { barr } MEM_fence_i + +typedef uop = enumerate {RISCV_LUI; RISCV_AUIPC} (* upper immediate ops *) +typedef bop = enumerate {RISCV_BEQ; RISCV_BNE; RISCV_BLT; RISCV_BGE; RISCV_BLTU; RISCV_BGEU} (* branch ops *) +typedef iop = enumerate {RISCV_ADDI; RISCV_SLTI; RISCV_SLTIU; RISCV_XORI; RISCV_ORI; RISCV_ANDI} (* immediate ops *) +typedef sop = enumerate {RISCV_SLLI; RISCV_SRLI; RISCV_SRAI} (* shift ops *) +typedef rop = enumerate {RISCV_ADD; RISCV_SUB; RISCV_SLL; RISCV_SLT; RISCV_SLTU; RISCV_XOR; RISCV_SRL; RISCV_SRA; RISCV_OR; RISCV_AND} (* reg-reg ops *) +typedef ropw = enumerate {RISCV_ADDW; RISCV_SUBW; RISCV_SLLW; RISCV_SRLW; RISCV_SRAW} (* reg-reg 32-bit ops *) +typedef amoop = enumerate {AMOSWAP; AMOADD; AMOXOR; AMOAND; AMOOR; + AMOMIN; AMOMAX; AMOMINU; AMOMAXU} (* AMO ops *) + +typedef word_width = enumerate {BYTE; HALF; WORD; DOUBLE} + +(********************************************************************) + +(* Ideally these would be sail builtin *) +function (bit[64]) shift_right_arith64 ((bit[64]) v, (bit[6]) shift) = + let (bit[128]) v128 = EXTS(v) in + (v128 >> shift)[63..0] + +function (bit[32]) shift_right_arith32 ((bit[32]) v, (bit[5]) shift) = + let (bit[64]) v64 = EXTS(v) in + (v64 >> shift)[31..0] diff --git a/src/LICENCE b/src/LICENCE index 5992fbfc..6b6dcc4f 100644 --- a/src/LICENCE +++ b/src/LICENCE @@ -1,6 +1,6 @@ Sail -Copyright (c) 2013-2017 +Copyright (c) 2013-2017 Kathyrn Gray Shaked Flur Stephen Kell @@ -8,6 +8,14 @@ Copyright (c) 2013-2017 Robert Norton-Wright Christopher Pulte Peter Sewell + Alasdair Armstrong + Brian Campbell + Thomas Bauereiss + Anthony Fox + Jon French + Dominic Mulligan + Stephen Kell + Mark Wassell All rights reserved. diff --git a/src/Makefile b/src/Makefile index 298d22c8..abf03c4f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,6 +9,14 @@ # Robert Norton-Wright # # Christopher Pulte # # Peter Sewell # +# Alasdair Armstrong # +# Brian Campbell # +# Thomas Bauereiss # +# Anthony Fox # +# Jon French # +# Dominic Mulligan # +# Stephen Kell # +# Mark Wassell # # # # All rights reserved. # # # @@ -79,7 +87,8 @@ LEM = $(BITBUCKET_ROOT)/lem/lem LEMLIBOCAML = $(BITBUCKET_ROOT)/lem/ocaml-lib ELFDIR= $(BITBUCKET_ROOT)/linksem ZARITH_DIR=$(LEMLIBOCAML)/dependencies/zarith -ZARITH_LIB=$(ZARITH_DIR)/zarith.cmxa +ZARITH_LIB=$(ZARITH_DIR)/zarith.cma +# ZARITH_LIB=$(ZARITH_DIR)/zarith.cmxa SAIL_LIB_DIR:=$(SAIL_DIR)/lib MIPS_SAIL_DIR:=$(SAIL_DIR)/mips_new_tc @@ -204,8 +213,11 @@ count: _build/cheri_trimmed.sail _build/mips_trimmed.sail %.ml: %.lem $(LEM) -only_changed_output -ocaml -lib lem_interp/ $< +#run_mips.native: _build/mips.ml _build/mips_extras.ml _build/run_with_elf.ml interpreter +# env OCAMLRUNPARAM=l=100M ocamlfind ocamlopt $(OCAML_OPTS) -g -package num -package str -package unix -I $(ELFDIR)/contrib/ocaml-uint/_build/lib -I $(LEMLIBOCAML) -I $(ZARITH_DIR) -I _build/lem_interp/ -I $(ELFDIR)/src -I $(ELFDIR)/src/adaptors -I $(ELFDIR)/src/abis/mips64 -I _build -linkpkg $(ZARITH_LIB) $(LEMLIBOCAML)/extract.cmxa $(ELFDIR)/contrib/ocaml-uint/_build/lib/uint.cmxa $(ELFDIR)/src/linksem.cmxa _build/pprint/src/PPrintLib.cmxa _build/lem_interp/extract.cmxa _build/mips.ml _build/mips_extras.ml _build/run_with_elf.ml -o run_mips.native + run_mips.native: _build/mips.ml _build/mips_extras.ml _build/run_with_elf.ml interpreter - env OCAMLRUNPARAM=l=100M ocamlfind ocamlopt $(OCAML_OPTS) -g -package num -package str -package unix -I $(ELFDIR)/contrib/ocaml-uint/_build/lib -I $(LEMLIBOCAML) -I $(ZARITH_DIR) -I _build/lem_interp/ -I $(ELFDIR)/src -I $(ELFDIR)/src/adaptors -I $(ELFDIR)/src/abis/mips64 -I _build -linkpkg $(ZARITH_LIB) $(LEMLIBOCAML)/extract.cmxa $(ELFDIR)/contrib/ocaml-uint/_build/lib/uint.cmxa $(ELFDIR)/src/linksem.cmxa _build/pprint/src/PPrintLib.cmxa _build/lem_interp/extract.cmxa _build/mips.ml _build/mips_extras.ml _build/run_with_elf.ml -o run_mips.native + env OCAMLRUNPARAM=l=100M ocamlfind ocamlc $(OCAML_OPTS) -g -package num -package str -package unix -I $(ELFDIR)/contrib/ocaml-uint/_build/lib -I $(LEMLIBOCAML) -I $(ZARITH_DIR) -I _build/lem_interp/ -I $(ELFDIR)/src -I $(ELFDIR)/src/adaptors -I $(ELFDIR)/src/abis/mips64 -I _build -linkpkg $(ZARITH_LIB) $(LEMLIBOCAML)/extract.cma $(ELFDIR)/contrib/ocaml-uint/_build/lib/uint.cma $(ELFDIR)/src/linksem.cma _build/pprint/src/PPrintLib.cma _build/lem_interp/extract.cma _build/mips.ml _build/mips_extras.ml _build/run_with_elf.ml -o run_mips.native run_cheri.native: _build/cheri.ml _build/mips_extras.ml _build/run_with_elf_cheri.ml interpreter env OCAMLRUNPARAM=l=100M ocamlfind ocamlopt $(OCAML_OPTS) -g -package num -package str -package unix -I $(ELFDIR)/contrib/ocaml-uint/_build/lib -I $(LEMLIBOCAML) -I $(ZARITH_DIR) -I _build/lem_interp/ -I $(ELFDIR)/src -I $(ELFDIR)/src/adaptors -I $(ELFDIR)/src/abis/mips64 -I _build -linkpkg $(ZARITH_LIB) $(LEMLIBOCAML)/extract.cmxa $(ELFDIR)/contrib/ocaml-uint/_build/lib/uint.cmxa $(ELFDIR)/src/linksem.cmxa _build/pprint/src/PPrintLib.cmxa _build/lem_interp/extract.cmxa _build/cheri.ml _build/mips_extras.ml _build/run_with_elf_cheri.ml -o run_cheri.native diff --git a/src/Makefile-non-opam b/src/Makefile-non-opam index 18fe6aa4..ebd82c09 100644 --- a/src/Makefile-non-opam +++ b/src/Makefile-non-opam @@ -9,6 +9,14 @@ # Robert Norton-Wright # # Christopher Pulte # # Peter Sewell # +# Alasdair Armstrong # +# Brian Campbell # +# Thomas Bauereiss # +# Anthony Fox # +# Jon French # +# Dominic Mulligan # +# Stephen Kell # +# Mark Wassell # # # # All rights reserved. # # # diff --git a/src/ast_util.ml b/src/ast_util.ml index 7d2d320b..6480571c 100644 --- a/src/ast_util.ml +++ b/src/ast_util.ml @@ -10,7 +10,13 @@ (* Christopher Pulte *) (* Peter Sewell *) (* Alasdair Armstrong *) +(* Brian Campbell *) (* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -48,6 +54,8 @@ open Big_int let no_annot = (Parse_ast.Unknown, ()) +let gen_loc l = Parse_ast.Generated l + let inc_ord = Ord_aux (Ord_inc, Parse_ast.Unknown) let dec_ord = Ord_aux (Ord_dec, Parse_ast.Unknown) @@ -249,7 +257,8 @@ let npow2 n = Nexp_aux (Nexp_exp n, Parse_ast.Unknown) let nvar kid = Nexp_aux (Nexp_var kid, Parse_ast.Unknown) let nid id = Nexp_aux (Nexp_id id, Parse_ast.Unknown) -let nc_set kid ints = mk_nc (NC_set (kid, ints)) +let nc_set kid nums = mk_nc (NC_set (kid, nums)) +let nc_int_set kid ints = mk_nc (NC_set (kid, List.map big_int_of_int ints)) let nc_eq n1 n2 = mk_nc (NC_equal (n1, n2)) let nc_neq n1 n2 = mk_nc (NC_not_equal (n1, n2)) let nc_lteq n1 n2 = NC_aux (NC_bounded_le (n1, n2), Parse_ast.Unknown) @@ -412,12 +421,12 @@ let def_loc = function | DEF_spec (VS_aux (_, (l, _))) | DEF_default (DT_aux (_, l)) | DEF_scattered (SD_aux (_, (l, _))) - | DEF_reg_dec (DEC_aux (_, (l, _))) -> + | DEF_reg_dec (DEC_aux (_, (l, _))) + | DEF_fixity (_, _, Id_aux (_, l)) + | DEF_overload (Id_aux (_, l), _) -> l | DEF_internal_mutrec _ - | DEF_comm _ - | DEF_overload _ - | DEF_fixity _ -> + | DEF_comm _ -> Parse_ast.Unknown let string_of_id = function diff --git a/src/ast_util.mli b/src/ast_util.mli index 7e22a6e7..cbf7deec 100644 --- a/src/ast_util.mli +++ b/src/ast_util.mli @@ -10,7 +10,13 @@ (* Christopher Pulte *) (* Peter Sewell *) (* Alasdair Armstrong *) +(* Brian Campbell *) (* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -46,6 +52,7 @@ open Ast open Big_int val no_annot : unit annot +val gen_loc : Parse_ast.l -> Parse_ast.l val mk_id : string -> id val mk_kid : string -> kid @@ -132,6 +139,7 @@ val nc_or : n_constraint -> n_constraint -> n_constraint val nc_true : n_constraint val nc_false : n_constraint val nc_set : kid -> big_int list -> n_constraint +val nc_int_set : kid -> int list -> n_constraint (* Negate a n_constraint. Note that there's no NC_not constructor, so this flips all the inequalites a the n_constraint leaves and uses diff --git a/src/constraint.ml b/src/constraint.ml index 37073ff2..3d5a3689 100644 --- a/src/constraint.ml +++ b/src/constraint.ml @@ -1,3 +1,53 @@ +(**************************************************************************) +(* Sail *) +(* *) +(* Copyright (c) 2013-2017 *) +(* 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 *) +(* *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(**************************************************************************) + open Big_int open Util diff --git a/src/constraint.mli b/src/constraint.mli index 33881fcf..89f2c625 100644 --- a/src/constraint.mli +++ b/src/constraint.mli @@ -1,3 +1,53 @@ +(**************************************************************************) +(* Sail *) +(* *) +(* Copyright (c) 2013-2017 *) +(* 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 *) +(* *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(**************************************************************************) + type nexp type t diff --git a/src/finite_map.ml b/src/finite_map.ml index 411048b6..444e3790 100644 --- a/src/finite_map.ml +++ b/src/finite_map.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/gen_lib/deep_shallow_convert.lem b/src/gen_lib/deep_shallow_convert.lem index 23c34222..76880dbd 100644 --- a/src/gen_lib/deep_shallow_convert.lem +++ b/src/gen_lib/deep_shallow_convert.lem @@ -6,20 +6,20 @@ open import Sail_values class (ToFromInterpValue 'a) - val toInterpValue : 'a -> Interp.value - val fromInterpValue : Interp.value -> 'a + val toInterpValue : 'a -> Interp_ast.value + val fromInterpValue : Interp_ast.value -> 'a end let toInterValueBool = function - | true -> Interp.V_lit (L_aux (L_one) Unknown) - | false -> Interp.V_lit (L_aux (L_zero) Unknown) + | true -> Interp_ast.V_lit (L_aux (L_one) Unknown) + | false -> Interp_ast.V_lit (L_aux (L_zero) Unknown) end let rec fromInterpValueBool v = match v with - | Interp.V_lit (L_aux (L_true) _) -> true - | Interp.V_lit (L_aux (L_false) _) -> false - | Interp.V_lit (L_aux (L_one) _) -> true - | Interp.V_lit (L_aux (L_zero) _) -> false - | Interp.V_tuple [v] -> fromInterpValueBool v + | Interp_ast.V_lit (L_aux (L_one) _) -> true + | Interp_ast.V_lit (L_aux (L_true) _) -> true + | Interp_ast.V_lit (L_aux (L_zero) _) -> false + | Interp_ast.V_lit (L_aux (L_false) _) -> false + | Interp_ast.V_tuple [v] -> fromInterpValueBool v | v -> failwith ("fromInterpValue bool: unexpected value. " ^ Interp.debug_print_value v) end @@ -29,10 +29,10 @@ instance (ToFromInterpValue bool) end -let toInterpValueUnit () = Interp.V_lit (L_aux (L_unit) Unknown) +let toInterpValueUnit () = Interp_ast.V_lit (L_aux (L_unit) Unknown) let rec fromInterpValueUnit v = match v with - | Interp.V_lit (L_aux (L_unit) _) -> () - | Interp.V_tuple [v] -> fromInterpValueUnit v + | Interp_ast.V_lit (L_aux (L_unit) _) -> () + | Interp_ast.V_tuple [v] -> fromInterpValueUnit v | v -> failwith ("fromInterpValue unit: unexpected value. " ^ Interp.debug_print_value v) end @@ -44,8 +44,8 @@ end let toInterpValueInteger i = V_lit (L_aux (L_num i) Unknown) let rec fromInterpValueInteger v = match v with - | Interp.V_lit (L_aux (L_num i) _) -> i - | Interp.V_tuple [v] -> fromInterpValueInteger v + | Interp_ast.V_lit (L_aux (L_num i) _) -> i + | Interp_ast.V_tuple [v] -> fromInterpValueInteger v | v -> failwith ("fromInterpValue integer: unexpected value. " ^ Interp.debug_print_value v) end @@ -57,8 +57,8 @@ end let toInterpValueString s = V_lit (L_aux (L_string s) Unknown) let rec fromInterpValueString v = match v with - | Interp.V_lit (L_aux (L_string s) _) -> s - | Interp.V_tuple [v] -> fromInterpValueString v + | Interp_ast.V_lit (L_aux (L_string s) _) -> s + | Interp_ast.V_tuple [v] -> fromInterpValueString v | v -> failwith ("fromInterpValue integer: unexpected value. " ^ Interp.debug_print_value v) end @@ -69,17 +69,17 @@ end let toInterpValueBitU = function - | I -> Interp.V_lit (L_aux (L_one) Unknown) - | O -> Interp.V_lit (L_aux (L_zero) Unknown) - | Undef -> Interp.V_lit (L_aux (L_undef) Unknown) + | B1 -> Interp_ast.V_lit (L_aux (L_one) Unknown) + | B0 -> Interp_ast.V_lit (L_aux (L_zero) Unknown) + | BU -> Interp_ast.V_lit (L_aux (L_undef) Unknown) end let rec fromInterpValueBitU v = match v with - | Interp.V_lit (L_aux (L_one) _) -> I - | Interp.V_lit (L_aux (L_zero) _) -> O - | Interp.V_lit (L_aux (L_undef) _) -> Undef - | Interp.V_lit (L_aux (L_true) _) -> I - | Interp.V_lit (L_aux (L_false) _) -> O - | Interp.V_tuple [v] -> fromInterpValueBitU v + | Interp_ast.V_lit (L_aux (L_one) _) -> B1 + | Interp_ast.V_lit (L_aux (L_zero) _) -> B0 + | Interp_ast.V_lit (L_aux (L_undef) _) -> BU + | Interp_ast.V_lit (L_aux (L_true) _) -> B1 + | Interp_ast.V_lit (L_aux (L_false) _) -> B0 + | Interp_ast.V_tuple [v] -> fromInterpValueBitU v | v -> failwith ("fromInterpValue bitU: unexpected value. " ^ Interp.debug_print_value v) end @@ -383,29 +383,33 @@ instance forall 'a. ToFromInterpValue 'a => (ToFromInterpValue (maybe 'a)) end -module SI = Interp -module SIA = Interp_ast - - let read_kindToInterpValue = function | Read_plain -> V_ctor (Id_aux (Id "Read_plain") Unknown) (T_id "read_kind") (C_Enum 0) (toInterpValue ()) - | Read_tag -> V_ctor (Id_aux (Id "Read_tag") Unknown) (T_id "read_kind") (C_Enum 1) (toInterpValue ()) - | Read_tag_reserve -> V_ctor (Id_aux (Id "Read_tag_reserve") Unknown) (T_id "read_kind") (C_Enum 1) (toInterpValue ()) - | Read_reserve -> V_ctor (Id_aux (Id "Read_reserve") Unknown) (T_id "read_kind") (C_Enum 2) (toInterpValue ()) - | Read_acquire -> V_ctor (Id_aux (Id "Read_acquire") Unknown) (T_id "read_kind") (C_Enum 3) (toInterpValue ()) - | Read_exclusive -> V_ctor (Id_aux (Id "Read_exclusive") Unknown) (T_id "read_kind") (C_Enum 4) (toInterpValue ()) - | Read_exclusive_acquire -> V_ctor (Id_aux (Id "Read_exclusive_acquire") Unknown) (T_id "read_kind") (C_Enum 5) (toInterpValue ()) - | Read_stream -> V_ctor (Id_aux (Id "Read_stream") Unknown) (T_id "read_kind") (C_Enum 6) (toInterpValue ()) + | Read_reserve -> V_ctor (Id_aux (Id "Read_reserve") Unknown) (T_id "read_kind") (C_Enum 1) (toInterpValue ()) + | Read_acquire -> V_ctor (Id_aux (Id "Read_acquire") Unknown) (T_id "read_kind") (C_Enum 2) (toInterpValue ()) + | Read_exclusive -> V_ctor (Id_aux (Id "Read_exclusive") Unknown) (T_id "read_kind") (C_Enum 3) (toInterpValue ()) + | Read_exclusive_acquire -> V_ctor (Id_aux (Id "Read_exclusive_acquire") Unknown) (T_id "read_kind") (C_Enum 4) (toInterpValue ()) + | Read_stream -> V_ctor (Id_aux (Id "Read_stream") Unknown) (T_id "read_kind") (C_Enum 5) (toInterpValue ()) + | Read_RISCV_acquire -> V_ctor (Id_aux (Id "Read_RISCV_acquire") Unknown) (T_id "read_kind") (C_Enum 6) (toInterpValue ()) + | Read_RISCV_strong_acquire -> V_ctor (Id_aux (Id "Read_RISCV_strong_acquire") Unknown) (T_id "read_kind") (C_Enum 7) (toInterpValue ()) + | Read_RISCV_reserved -> V_ctor (Id_aux (Id "Read_RISCV_reserved") Unknown) (T_id "read_kind") (C_Enum 8) (toInterpValue ()) + | Read_RISCV_reserved_acquire -> V_ctor (Id_aux (Id "Read_RISCV_reserved_acquire") Unknown) (T_id "read_kind") (C_Enum 9) (toInterpValue ()) + | Read_RISCV_reserved_strong_acquire -> V_ctor (Id_aux (Id "Read_RISCV_reserved_strong_acquire") Unknown) (T_id "read_kind") (C_Enum 10) (toInterpValue ()) + | Read_X86_locked -> V_ctor (Id_aux (Id "Read_X86_locked") Unknown) (T_id "read_kind") (C_Enum 11) (toInterpValue ()) end let rec read_kindFromInterpValue v = match v with | V_ctor (Id_aux (Id "Read_plain") _) _ _ v -> Read_plain - | V_ctor (Id_aux (Id "Read_tag") _) _ _ v -> Read_tag - | V_ctor (Id_aux (Id "Read_tag_reserve") _) _ _ v -> Read_tag_reserve | V_ctor (Id_aux (Id "Read_reserve") _) _ _ v -> Read_reserve | V_ctor (Id_aux (Id "Read_acquire") _) _ _ v -> Read_acquire | V_ctor (Id_aux (Id "Read_exclusive") _) _ _ v -> Read_exclusive | V_ctor (Id_aux (Id "Read_exclusive_acquire") _) _ _ v -> Read_exclusive_acquire | V_ctor (Id_aux (Id "Read_stream") _) _ _ v -> Read_stream + | V_ctor (Id_aux (Id "Read_RISCV_acquire") _) _ _ v -> Read_RISCV_acquire + | V_ctor (Id_aux (Id "Read_RISCV_strong_acquire") _) _ _ v -> Read_RISCV_strong_acquire + | V_ctor (Id_aux (Id "Read_RISCV_reserved") _) _ _ v -> Read_RISCV_reserved + | V_ctor (Id_aux (Id "Read_RISCV_reserved_acquire") _) _ _ v -> Read_RISCV_reserved_acquire + | V_ctor (Id_aux (Id "Read_RISCV_reserved_strong_acquire") _) _ _ v -> Read_RISCV_reserved_strong_acquire + | V_ctor (Id_aux (Id "Read_X86_locked") _) _ _ v -> Read_X86_locked | V_tuple [v] -> read_kindFromInterpValue v | v -> failwith ("fromInterpValue read_kind: unexpected value. " ^ Interp.debug_print_value v) @@ -418,21 +422,29 @@ end let write_kindToInterpValue = function | Write_plain -> V_ctor (Id_aux (Id "Write_plain") Unknown) (T_id "write_kind") (C_Enum 0) (toInterpValue ()) - | Write_tag -> V_ctor (Id_aux (Id "Write_tag") Unknown) (T_id "write_kind") (C_Enum 1) (toInterpValue ()) - | Write_tag_conditional -> V_ctor (Id_aux (Id "Write_tag_conditional") Unknown) (T_id "write_kind") (C_Enum 1) (toInterpValue ()) - | Write_conditional -> V_ctor (Id_aux (Id "Write_conditional") Unknown) (T_id "write_kind") (C_Enum 2) (toInterpValue ()) - | Write_release -> V_ctor (Id_aux (Id "Write_release") Unknown) (T_id "write_kind") (C_Enum 3) (toInterpValue ()) - | Write_exclusive -> V_ctor (Id_aux (Id "Write_exclusive") Unknown) (T_id "write_kind") (C_Enum 4) (toInterpValue ()) - | Write_exclusive_release -> V_ctor (Id_aux (Id "Write_exclusive_release") Unknown) (T_id "write_kind") (C_Enum 5) (toInterpValue ()) + | Write_conditional -> V_ctor (Id_aux (Id "Write_conditional") Unknown) (T_id "write_kind") (C_Enum 1) (toInterpValue ()) + | Write_release -> V_ctor (Id_aux (Id "Write_release") Unknown) (T_id "write_kind") (C_Enum 2) (toInterpValue ()) + | Write_exclusive -> V_ctor (Id_aux (Id "Write_exclusive") Unknown) (T_id "write_kind") (C_Enum 3) (toInterpValue ()) + | Write_exclusive_release -> V_ctor (Id_aux (Id "Write_exclusive_release") Unknown) (T_id "write_kind") (C_Enum 4) (toInterpValue ()) + | Write_RISCV_release -> V_ctor (Id_aux (Id "Write_RISCV_release") Unknown) (T_id "write_kind") (C_Enum 5) (toInterpValue ()) + | Write_RISCV_strong_release -> V_ctor (Id_aux (Id "Write_RISCV_strong_release") Unknown) (T_id "write_kind") (C_Enum 6) (toInterpValue ()) + | Write_RISCV_conditional -> V_ctor (Id_aux (Id "Write_RISCV_conditional") Unknown) (T_id "write_kind") (C_Enum 7) (toInterpValue ()) + | Write_RISCV_conditional_release -> V_ctor (Id_aux (Id "Write_RISCV_conditional_release") Unknown) (T_id "write_kind") (C_Enum 8) (toInterpValue ()) + | Write_RISCV_conditional_strong_release -> V_ctor (Id_aux (Id "Write_RISCV_conditional_strong_release") Unknown) (T_id "write_kind") (C_Enum 9) (toInterpValue ()) + | Write_X86_locked -> V_ctor (Id_aux (Id "Write_X86_locked") Unknown) (T_id "write_kind") (C_Enum 10) (toInterpValue ()) end let rec write_kindFromInterpValue v = match v with | V_ctor (Id_aux (Id "Write_plain") _) _ _ v -> Write_plain - | V_ctor (Id_aux (Id "Write_tag") _) _ _ v -> Write_tag - | V_ctor (Id_aux (Id "Write_tag_conditional") _) _ _ v -> Write_tag_conditional | V_ctor (Id_aux (Id "Write_conditional") _) _ _ v -> Write_conditional | V_ctor (Id_aux (Id "Write_release") _) _ _ v -> Write_release | V_ctor (Id_aux (Id "Write_exclusive") _) _ _ v -> Write_exclusive | V_ctor (Id_aux (Id "Write_exclusive_release") _) _ _ v -> Write_exclusive_release + | V_ctor (Id_aux (Id "Write_RISCV_release") _) _ _ v -> Write_RISCV_release + | V_ctor (Id_aux (Id "Write_RISCV_strong_release") _) _ _ v -> Write_RISCV_strong_release + | V_ctor (Id_aux (Id "Write_RISCV_conditional") _) _ _ v -> Write_RISCV_conditional + | V_ctor (Id_aux (Id "Write_RISCV_conditional_release") _) _ _ v -> Write_RISCV_conditional_release + | V_ctor (Id_aux (Id "Write_RISCV_conditional_strong_release") _) _ _ v -> Write_RISCV_conditional_strong_release + | V_ctor (Id_aux (Id "Write_X86_locked") _) _ _ v -> Write_X86_locked | V_tuple [v] -> write_kindFromInterpValue v | v -> failwith ("fromInterpValue write_kind: unexpected value " ^ Interp.debug_print_value v) @@ -455,7 +467,15 @@ let barrier_kindToInterpValue = function | Barrier_DSB_ST -> V_ctor (Id_aux (Id "Barrier_DSB_ST") Unknown) (T_id "barrier_kind") (C_Enum 8) (toInterpValue ()) | Barrier_DSB_LD -> V_ctor (Id_aux (Id "Barrier_DSB_LD") Unknown) (T_id "barrier_kind") (C_Enum 9) (toInterpValue ()) | Barrier_ISB -> V_ctor (Id_aux (Id "Barrier_ISB") Unknown) (T_id "barrier_kind") (C_Enum 10) (toInterpValue ()) - | Barrier_MIPS_SYNC -> V_ctor (Id_aux (Id "Barrier_MIPS_SYNC") Unknown) (T_id "barrier_kind") (C_Enum 11) (toInterpValue ()) + | Barrier_TM_COMMIT -> V_ctor (Id_aux (Id "Barrier_TM_COMMIT") Unknown) (T_id "barrier_kind") (C_Enum 11) (toInterpValue ()) + | Barrier_MIPS_SYNC -> V_ctor (Id_aux (Id "Barrier_MIPS_SYNC") Unknown) (T_id "barrier_kind") (C_Enum 12) (toInterpValue ()) + | Barrier_RISCV_rw_rw -> V_ctor (Id_aux (Id "Barrier_RISCV_rw_rw") Unknown) (T_id "barrier_kind") (C_Enum 13) (toInterpValue ()) + | Barrier_RISCV_r_rw -> V_ctor (Id_aux (Id "Barrier_RISCV_r_rw") Unknown) (T_id "barrier_kind") (C_Enum 14) (toInterpValue ()) + | Barrier_RISCV_r_r -> V_ctor (Id_aux (Id "Barrier_RISCV_r_r") Unknown) (T_id "barrier_kind") (C_Enum 15) (toInterpValue ()) + | Barrier_RISCV_rw_w -> V_ctor (Id_aux (Id "Barrier_RISCV_rw_w") Unknown) (T_id "barrier_kind") (C_Enum 16) (toInterpValue ()) + | Barrier_RISCV_w_w -> V_ctor (Id_aux (Id "Barrier_RISCV_w_w") Unknown) (T_id "barrier_kind") (C_Enum 17) (toInterpValue ()) + | Barrier_RISCV_i -> V_ctor (Id_aux (Id "Barrier_RISCV_i") Unknown) (T_id "barrier_kind") (C_Enum 18) (toInterpValue ()) + | Barrier_x86_MFENCE -> V_ctor (Id_aux (Id "Barrier_x86_MFENCE") Unknown) (T_id "barrier_kind") (C_Enum 19) (toInterpValue ()) end let rec barrier_kindFromInterpValue v = match v with | V_ctor (Id_aux (Id "Barrier_Sync") _) _ _ v -> Barrier_Sync @@ -469,7 +489,15 @@ let rec barrier_kindFromInterpValue v = match v with | V_ctor (Id_aux (Id "Barrier_DSB_ST") _) _ _ v -> Barrier_DSB_ST | V_ctor (Id_aux (Id "Barrier_DSB_LD") _) _ _ v -> Barrier_DSB_LD | V_ctor (Id_aux (Id "Barrier_ISB") _) _ _ v -> Barrier_ISB + | V_ctor (Id_aux (Id "Barrier_TM_COMMIT") _) _ _ v -> Barrier_TM_COMMIT | V_ctor (Id_aux (Id "Barrier_MIPS_SYNC") _) _ _ v -> Barrier_MIPS_SYNC + | V_ctor (Id_aux (Id "Barrier_RISCV_rw_rw") _) _ _ v -> Barrier_RISCV_rw_rw + | V_ctor (Id_aux (Id "Barrier_RISCV_r_rw") _) _ _ v -> Barrier_RISCV_r_rw + | V_ctor (Id_aux (Id "Barrier_RISCV_r_r") _) _ _ v -> Barrier_RISCV_r_r + | V_ctor (Id_aux (Id "Barrier_RISCV_rw_w") _) _ _ v -> Barrier_RISCV_rw_w + | V_ctor (Id_aux (Id "Barrier_RISCV_w_w") _) _ _ v -> Barrier_RISCV_w_w + | V_ctor (Id_aux (Id "Barrier_RISCV_i") _) _ _ v -> Barrier_RISCV_i + | V_ctor (Id_aux (Id "Barrier_x86_MFENCE") _) _ _ v -> Barrier_x86_MFENCE | V_tuple [v] -> barrier_kindFromInterpValue v | v -> failwith ("fromInterpValue barrier_kind: unexpected value. " ^ Interp.debug_print_value v) @@ -480,18 +508,41 @@ instance (ToFromInterpValue barrier_kind) end +let trans_kindToInterpValue = function + | Transaction_start -> V_ctor (Id_aux (Id "Transaction_start") Unknown) (T_id "trans_kind") (C_Enum 0) (toInterpValue ()) + | Transaction_commit -> V_ctor (Id_aux (Id "Transaction_commit") Unknown) (T_id "trans_kind") (C_Enum 1) (toInterpValue ()) + | Transaction_abort -> V_ctor (Id_aux (Id "Transaction_abort") Unknown) (T_id "trans_kind") (C_Enum 2) (toInterpValue ()) + end +let rec trans_kindFromInterpValue v = match v with + | V_ctor (Id_aux (Id "Transaction_start") _) _ _ v -> Transaction_start + | V_ctor (Id_aux (Id "Transaction_commit") _) _ _ v -> Transaction_commit + | V_ctor (Id_aux (Id "Transaction_abort") _) _ _ v -> Transaction_abort + | V_tuple [v] -> trans_kindFromInterpValue v + | v -> failwith ("fromInterpValue trans_kind: unexpected value. " ^ + Interp.debug_print_value v) + end +instance (ToFromInterpValue trans_kind) + let toInterpValue = trans_kindToInterpValue + let fromInterpValue = trans_kindFromInterpValue +end + + let instruction_kindToInterpValue = function | IK_barrier v -> V_ctor (Id_aux (Id "IK_barrier") Unknown) (T_id "instruction_kind") C_Union (toInterpValue v) | IK_mem_read v -> V_ctor (Id_aux (Id "IK_mem_read") Unknown) (T_id "instruction_kind") C_Union (toInterpValue v) | IK_mem_write v -> V_ctor (Id_aux (Id "IK_mem_write") Unknown) (T_id "instruction_kind") C_Union (toInterpValue v) + | IK_mem_rmw v -> V_ctor (Id_aux (Id "IK_mem_rmw") Unknown) (T_id "instruction_kind") C_Union (toInterpValue v) | IK_cond_branch -> V_ctor (Id_aux (Id "IK_cond_branch") Unknown) (T_id "instruction_kind") C_Union (toInterpValue ()) + | IK_trans v -> V_ctor (Id_aux (Id "IK_trans") Unknown) (T_id "instruction_kind") C_Union (toInterpValue v) | IK_simple -> V_ctor (Id_aux (Id "IK_simple") Unknown) (T_id "instruction_kind") C_Union (toInterpValue ()) end let rec instruction_kindFromInterpValue v = match v with | V_ctor (Id_aux (Id "IK_barrier") _) _ _ v -> IK_barrier (fromInterpValue v) | V_ctor (Id_aux (Id "IK_mem_read") _) _ _ v -> IK_mem_read (fromInterpValue v) | V_ctor (Id_aux (Id "IK_mem_write") _) _ _ v -> IK_mem_write (fromInterpValue v) + | V_ctor (Id_aux (Id "IK_mem_rmw") _) _ _ v -> IK_mem_rmw (fromInterpValue v) | V_ctor (Id_aux (Id "IK_cond_branch") _) _ _ v -> IK_cond_branch + | V_ctor (Id_aux (Id "IK_trans") _) _ _ v -> IK_trans (fromInterpValue v) | V_ctor (Id_aux (Id "IK_simple") _) _ _ v -> IK_simple | V_tuple [v] -> instruction_kindFromInterpValue v | v -> failwith ("fromInterpValue instruction_kind: unexpected value. " ^ @@ -503,18 +554,18 @@ instance (ToFromInterpValue instruction_kind) end let regfpToInterpValue = function - | RFull v -> SI.V_ctor (SIA.Id_aux (SIA.Id "RFull") SIA.Unknown) (SIA.T_id "regfp") SI.C_Union (toInterpValue v) - | RSlice v -> SI.V_ctor (SIA.Id_aux (SIA.Id "RSlice") SIA.Unknown) (SIA.T_id "regfp") SI.C_Union (toInterpValue v) - | RSliceBit v -> SI.V_ctor (SIA.Id_aux (SIA.Id "RSliceBit") SIA.Unknown) (SIA.T_id "regfp") SI.C_Union (toInterpValue v) - | RField v -> SI.V_ctor (SIA.Id_aux (SIA.Id "RField") SIA.Unknown) (SIA.T_id "regfp") SI.C_Union (toInterpValue v) + | RFull v -> Interp_ast.V_ctor (Interp_ast.Id_aux (Interp_ast.Id "RFull") Interp_ast.Unknown) (Interp_ast.T_id "regfp") Interp_ast.C_Union (toInterpValue v) + | RSlice v -> Interp_ast.V_ctor (Interp_ast.Id_aux (Interp_ast.Id "RSlice") Interp_ast.Unknown) (Interp_ast.T_id "regfp") Interp_ast.C_Union (toInterpValue v) + | RSliceBit v -> Interp_ast.V_ctor (Interp_ast.Id_aux (Interp_ast.Id "RSliceBit") Interp_ast.Unknown) (Interp_ast.T_id "regfp") Interp_ast.C_Union (toInterpValue v) + | RField v -> Interp_ast.V_ctor (Interp_ast.Id_aux (Interp_ast.Id "RField") Interp_ast.Unknown) (Interp_ast.T_id "regfp") Interp_ast.C_Union (toInterpValue v) end let rec regfpFromInterpValue v = match v with - | SI.V_ctor (SIA.Id_aux (SIA.Id "RFull") _) _ _ v -> RFull (fromInterpValue v) - | SI.V_ctor (SIA.Id_aux (SIA.Id "RSlice") _) _ _ v -> RSlice (fromInterpValue v) - | SI.V_ctor (SIA.Id_aux (SIA.Id "RSliceBit") _) _ _ v -> RSliceBit (fromInterpValue v) - | SI.V_ctor (SIA.Id_aux (SIA.Id "RField") _) _ _ v -> RField (fromInterpValue v) - | SI.V_tuple [v] -> regfpFromInterpValue v + | Interp_ast.V_ctor (Interp_ast.Id_aux (Interp_ast.Id "RFull") _) _ _ v -> RFull (fromInterpValue v) + | Interp_ast.V_ctor (Interp_ast.Id_aux (Interp_ast.Id "RSlice") _) _ _ v -> RSlice (fromInterpValue v) + | Interp_ast.V_ctor (Interp_ast.Id_aux (Interp_ast.Id "RSliceBit") _) _ _ v -> RSliceBit (fromInterpValue v) + | Interp_ast.V_ctor (Interp_ast.Id_aux (Interp_ast.Id "RField") _) _ _ v -> RField (fromInterpValue v) + | Interp_ast.V_tuple [v] -> regfpFromInterpValue v | v -> failwith ("fromInterpValue regfp: unexpected value. " ^ Interp.debug_print_value v) end diff --git a/src/gen_lib/sail_values.ml b/src/gen_lib/sail_values.ml index d160e84a..213acea1 100644 --- a/src/gen_lib/sail_values.ml +++ b/src/gen_lib/sail_values.ml @@ -889,18 +889,25 @@ let shift_op_vec_int op (l,r) = let len = Array.length array in (match op with | "<<" -> - let left = Array.sub array r (len - r) in - let right = Array.make r Vzero in - let result = Array.append left right in - Vvector(result, start, ord) + if (r <= len) then + let left = Array.sub array r (len - r) in + let right = Array.make r Vzero in + let result = Array.append left right in + Vvector(result, start, ord) + else + Vvector(Array.make len Vzero, start, ord) | ">>" -> - let left = Array.make r Vzero in - let right = Array.sub array 0 (len - r) in - let result = Array.append left right in - Vvector(result, start, ord) + if (r <= len) then + let left = Array.make r Vzero in + let right = Array.sub array 0 (len - r) in + let result = Array.append left right in + Vvector(result, start, ord) + else + Vvector(Array.make len Vzero, start, ord) | "<<<" -> - let left = Array.sub array r (len - r) in - let right = Array.sub array 0 r in + let rmod = r mod len in + let left = Array.sub array rmod (len - rmod) in + let right = Array.sub array 0 rmod in let result = Array.append left right in Vvector(result, start, ord) | _ -> assert false) diff --git a/src/gen_lib/state.lem b/src/gen_lib/state.lem index a089f8c5..fa0fcd24 100644 --- a/src/gen_lib/state.lem +++ b/src/gen_lib/state.lem @@ -87,22 +87,29 @@ let set_reg state reg v = <| state with regstate = reg.write_to state.regstate v |> +let is_exclusive = function + | Sail_impl_base.Read_plain -> false + | Sail_impl_base.Read_reserve -> true + | Sail_impl_base.Read_acquire -> false + | Sail_impl_base.Read_exclusive -> true + | Sail_impl_base.Read_exclusive_acquire -> true + | Sail_impl_base.Read_stream -> false + | Sail_impl_base.Read_RISCV_acquire -> false + | Sail_impl_base.Read_RISCV_strong_acquire -> false + | Sail_impl_base.Read_RISCV_reserved -> true + | Sail_impl_base.Read_RISCV_reserved_acquire -> true + | Sail_impl_base.Read_RISCV_reserved_strong_acquire -> true + | Sail_impl_base.Read_X86_locked -> true +end + + val read_mem : forall 'regs 'a 'b. Bitvector 'a, Bitvector 'b => bool -> read_kind -> 'a -> integer -> M 'regs 'b let read_mem dir read_kind addr sz state = let addr = unsigned addr in let addrs = range addr (addr+sz-1) in let memory_value = List.map (fun addr -> Map_extra.find addr state.memstate) addrs in let value = of_bits (Sail_values.internal_mem_value dir memory_value) in - let is_exclusive = match read_kind with - | Sail_impl_base.Read_plain -> false - | Sail_impl_base.Read_reserve -> true - | Sail_impl_base.Read_acquire -> false - | Sail_impl_base.Read_exclusive -> true - | Sail_impl_base.Read_exclusive_acquire -> true - | Sail_impl_base.Read_stream -> false - end in - - if is_exclusive + if is_exclusive read_kind then [(Left value, <| state with last_exclusive_operation_was_load = true |>)] else [(Left value, state)] @@ -116,17 +123,7 @@ let read_tag dir read_kind addr state = | Just t -> t | Nothing -> B0 end in - let is_exclusive = match read_kind with - | Sail_impl_base.Read_plain -> false - | Sail_impl_base.Read_reserve -> true - | Sail_impl_base.Read_acquire -> false - | Sail_impl_base.Read_exclusive -> true - | Sail_impl_base.Read_exclusive_acquire -> true - | Sail_impl_base.Read_stream -> false - end in - - (* TODO Should reading a tag set the exclusive flag? *) - if is_exclusive + if is_exclusive read_kind then [(Left tag, <| state with last_exclusive_operation_was_load = true |>)] else [(Left tag, state)] diff --git a/src/initial_check.ml b/src/initial_check.ml index de5b625b..21e27ac9 100644 --- a/src/initial_check.ml +++ b/src/initial_check.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -46,6 +54,7 @@ open Ast_util open Big_int let opt_undefined_gen = ref false +let opt_magic_hash = ref false module Envmap = Finite_map.Fmap_map(String) module Nameset' = Set.Make(String) @@ -117,10 +126,21 @@ let typ_error l msg opt_id opt_var opt_kind = | None,None,Some(kind) -> " " ^ (kind_to_string kind) | _ -> ""))) -let to_ast_id (Parse_ast.Id_aux(id,l)) = - Id_aux( (match id with - | Parse_ast.Id(x) -> Id(x) - | Parse_ast.DeIid(x) -> DeIid(x)) , l) +let string_of_parse_id_aux = function + | Parse_ast.Id v -> v + | Parse_ast.DeIid v -> v + +let string_contains str char = + try (String.index str char; true) with + | Not_found -> false + +let to_ast_id (Parse_ast.Id_aux(id, l)) = + if string_contains (string_of_parse_id_aux id) '#' && not (!opt_magic_hash) + then typ_error l "Identifier contains hash character" None None None + else Id_aux ((match id with + | Parse_ast.Id(x) -> Id(x) + | Parse_ast.DeIid(x) -> DeIid(x)), + l) let to_ast_var (Parse_ast.Kid_aux(Parse_ast.Var v,l)) = Kid_aux(Var v,l) @@ -483,7 +503,10 @@ and to_ast_exp (k_env : kind Envmap.t) (def_ord : order) (Parse_ast.E_aux(exp,l) | Parse_ast.E_vector_append(e1,e2) -> E_vector_append(to_ast_exp k_env def_ord e1,to_ast_exp k_env def_ord e2) | Parse_ast.E_list(exps) -> E_list(List.map (to_ast_exp k_env def_ord) exps) | Parse_ast.E_cons(e1,e2) -> E_cons(to_ast_exp k_env def_ord e1, to_ast_exp k_env def_ord e2) - | Parse_ast.E_record _ -> raise (Reporting_basic.err_unreachable l "parser generated an E_record") + | Parse_ast.E_record fexps -> + (match to_ast_fexps true k_env def_ord fexps with + | Some fexps -> E_record fexps + | None -> raise (Reporting_basic.err_unreachable l "to_ast_fexps with true returned none")) | Parse_ast.E_record_update(exp,fexps) -> (match to_ast_fexps true k_env def_ord fexps with | Some(fexps) -> E_record_update(to_ast_exp k_env def_ord exp, fexps) @@ -886,7 +909,15 @@ let rec to_ast_defs_helper envs partial_defs = function then (fst !d) :: defs, envs, partial_defs else typ_error l "Scattered type definition never ended" (Some id) None None)) +let rec remove_mutrec = function + | [] -> [] + | Parse_ast.DEF_internal_mutrec fundefs :: defs -> + List.map (fun fdef -> Parse_ast.DEF_fundef fdef) fundefs @ remove_mutrec defs + | def :: defs -> + def :: remove_mutrec defs + let to_ast (default_names : Nameset.t) (kind_env : kind Envmap.t) (def_ord : order) (Parse_ast.Defs(defs)) = + let defs = remove_mutrec defs in let defs,(_,k_env,def_ord),partial_defs = to_ast_defs_helper (default_names,kind_env,def_ord) [] defs in List.iter (fun (id,(d,k)) -> diff --git a/src/initial_check.mli b/src/initial_check.mli index 2a6b8349..01cf3bec 100644 --- a/src/initial_check.mli +++ b/src/initial_check.mli @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -44,6 +52,7 @@ open Ast open Ast_util val opt_undefined_gen : bool ref +val opt_magic_hash : bool ref val process_ast : order -> Parse_ast.defs -> unit defs diff --git a/src/lem_interp/instruction_extractor.lem b/src/lem_interp/instruction_extractor.lem index 8bc19f8c..b49646ea 100644 --- a/src/lem_interp/instruction_extractor.lem +++ b/src/lem_interp/instruction_extractor.lem @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -127,7 +135,10 @@ let rec extract_patt_parm (P_aux p (_,tannot)) = let rec extract_from_execute fcls = match fcls with | [] -> [] | FCL_aux (FCL_Funcl _ (P_aux (P_app (Id_aux (Id i) _) parms) _) _) (_,Just(_,_,_,Effect_aux(Effect_set efs) _,_))::fcls -> - (Instr_form i (List.map extract_patt_parm parms) efs)::extract_from_execute fcls + (Instr_form i (List.map extract_patt_parm parms) efs)::extract_from_execute fcls + | _ :: fcls -> + (* AA: Find out what breaks this *) + extract_from_execute fcls end let rec extract_effects instrs execute = diff --git a/src/lem_interp/interp.lem b/src/lem_interp/interp.lem index 301849cd..486728d9 100644 --- a/src/lem_interp/interp.lem +++ b/src/lem_interp/interp.lem @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -1419,8 +1427,8 @@ let rec match_pattern t_level (P_aux p (_, annot)) value_whole = | V_ctor (Id_aux cid _) t ckind v -> if id = cid then (match (pats,detaint v) with - | ([],(V_lit (L_aux L_unit _))) -> (true,true,eenv) - | ([P_aux (P_lit (L_aux L_unit _)) _],(V_lit (L_aux L_unit _))) -> (true,true,eenv) + | ([],(V_lit (L_aux L_unit _))) -> (true,false,eenv) + | ([P_aux (P_lit (L_aux L_unit _)) _],(V_lit (L_aux L_unit _))) -> (true,false,eenv) | ([p],_) -> match_pattern t_level p v | _ -> (false,false,eenv) end) else (false,false,eenv) diff --git a/src/lem_interp/interp_inter_imp.lem b/src/lem_interp/interp_inter_imp.lem index 68f82ccb..563da2e5 100644 --- a/src/lem_interp/interp_inter_imp.lem +++ b/src/lem_interp/interp_inter_imp.lem @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -440,7 +448,8 @@ let rec interp_to_value_helper debug arg ivh_mode err_str instr direction regist (Ivh_error (Interp_interface.Internal_error ("Write memory value request in a " ^ errk_str)), events_out) | (Interp.Action (Interp.Write_memv_tagged _ _ _ _) _,_,_) -> (Ivh_error (Interp_interface.Internal_error ("Write memory value tagged request in a " ^ errk_str)), events_out) - | _ -> (Ivh_error (Interp_interface.Internal_error ("Non expected action in a " ^ errk_str)), events_out) + | (outcome, _, _) -> + (Ivh_error (Interp_interface.Internal_error ("Non expected action in a " ^ errk_str ^ " " ^ Interp.string_of_outcome outcome)), events_out) end let call_external_functions direction outcome = @@ -470,7 +479,7 @@ let translate_address top_level end_flag thunk_name registers address = let (arg,_) = Interp.to_exp int_mode Interp.eenv intern_val in let internal_direction = if direction = D_increasing then Interp_ast.IInc else Interp_ast.IDec in let (address_error,events) = - interp_to_value_helper debug (Just (Opcode bytes)) Ivh_translate val_str ("",[]) internal_direction + interp_to_value_helper debug (Just (Opcode bytes)) Ivh_translate val_str (V_list []) internal_direction registers [] false (fun _ -> Interp.resume int_mode @@ -505,17 +514,16 @@ let intern_instruction direction (name,parms) = Interp_ast.V_ctor (Interp.id_of_string name) (mk_typ_id "ast") Interp_ast.C_Union (Interp_ast.V_tuple (List.map (value_of_instruction_param direction) parms)) -let instruction_analysis top_level end_flag thunk_name regn_to_reg_details registers instruction = +let instruction_analysis top_level end_flag thunk_name regn_to_reg_details registers (instruction : Interp_ast.value) = let (Context top_env direction _ _ _ _ _ _ _ _ _) = top_level in let (Interp.Env _ _ _ _ _ _ _ _ debug) = top_env in let mode = make_mode true false debug in let int_mode = mode.internal_mode in - let intern_val = intern_instruction direction instruction in - let val_str = Interp.string_of_value intern_val in - let (arg,_) = Interp.to_exp int_mode Interp.eenv intern_val in + let val_str = Interp.string_of_value instruction in + let (arg,_) = Interp.to_exp int_mode Interp.eenv instruction in let internal_direction = if direction = D_increasing then Interp_ast.IInc else Interp_ast.IDec in let (analysis_or_error,events) = - interp_to_value_helper debug Nothing Ivh_analysis val_str ("",[]) internal_direction + interp_to_value_helper debug Nothing Ivh_analysis val_str (V_list []) internal_direction registers [] false (fun _ -> Interp.resume int_mode @@ -573,6 +581,33 @@ let instruction_analysis top_level end_flag thunk_name regn_to_reg_details regis | Interp_ast.V_ctor (Id_aux (Id "NIAFP_register") _) _ _ reg -> NIA_register (reg_to_reg_name reg) | _ -> failwith "Register footprint analysis did not return nia of expected type" end in + let readk_to_readk = function + | "Read_plain" -> Read_plain + | "Read_reserve" -> Read_reserve + | "Read_acquire" -> Read_acquire + | "Read_exclusive" -> Read_exclusive + | "Read_exclusive_acquire" -> Read_exclusive_acquire + | "Read_stream" -> Read_stream + | "Read_RISCV_acquire" -> Read_RISCV_acquire + | "Read_RISCV_strong_acquire" -> Read_RISCV_strong_acquire + | "Read_RISCV_reserved" -> Read_RISCV_reserved + | "Read_RISCV_reserved_acquire" -> Read_RISCV_reserved_acquire + | "Read_RISCV_reserved_strong_acquire" -> Read_RISCV_reserved_strong_acquire + | "Read_X86_locked" -> Read_X86_locked + | r -> failwith ("unknown read kind: " ^ r) end in + let writek_to_writek = function + | "Write_plain" -> Write_plain + | "Write_conditional" -> Write_conditional + | "Write_release" -> Write_release + | "Write_exclusive" -> Write_exclusive + | "Write_exclusive_release" -> Write_exclusive_release + | "Write_RISCV_release" -> Write_RISCV_release + | "Write_RISCV_strong_release" -> Write_RISCV_strong_release + | "Write_RISCV_conditional" -> Write_RISCV_conditional + | "Write_RISCV_conditional_release" -> Write_RISCV_conditional_release + | "Write_RISCV_conditional_strong_release" -> Write_RISCV_conditional_strong_release + | "Write_X86_locked" -> Write_X86_locked + | w -> failwith ("unknown write kind: " ^ w) end in let ik_to_ik = function | Interp_ast.V_ctor (Id_aux (Id "IK_barrier") _) _ _ (Interp_ast.V_ctor (Id_aux (Id b) _) _ _ _) -> @@ -588,27 +623,19 @@ let instruction_analysis top_level end_flag thunk_name regn_to_reg_details regis | "Barrier_DSB_ST" -> Barrier_DSB_ST | "Barrier_DSB_LD" -> Barrier_DSB_LD | "Barrier_ISB" -> Barrier_ISB - | "Barrier_MIPS_SYNC" -> Barrier_MIPS_SYNC + | "Barrier_MIPS_SYNC" -> Barrier_MIPS_SYNC + | "Barrier_x86_MFENCE" -> Barrier_x86_MFENCE end) | Interp_ast.V_ctor (Id_aux (Id "IK_mem_read") _) _ _ (Interp_ast.V_ctor (Id_aux (Id r) _) _ _ _) -> - IK_mem_read (match r with - | "Read_plain" -> Read_plain - | "Read_reserve" -> Read_reserve - | "Read_acquire" -> Read_acquire - | "Read_exclusive" -> Read_exclusive - | "Read_exclusive_acquire" -> Read_exclusive_acquire - | "Read_stream" -> Read_stream - end) + IK_mem_read(readk_to_readk r) | Interp_ast.V_ctor (Id_aux (Id "IK_mem_write") _) _ _ (Interp_ast.V_ctor (Id_aux (Id w) _) _ _ _) -> - IK_mem_write (match w with - | "Write_plain" -> Write_plain - | "Write_conditional" -> Write_conditional - | "Write_release" -> Write_release - | "Write_exclusive" -> Write_exclusive - | "Write_exclusive_release" -> Write_exclusive_release - end) + IK_mem_write(writek_to_writek w) + | Interp_ast.V_ctor (Id_aux (Id "IK_mem_rmw") _) _ _ + (Interp_ast.V_tuple [(Interp_ast.V_ctor (Id_aux (Id readk) _) _ _ _) ; + (Interp_ast.V_ctor (Id_aux (Id writek) _) _ _ _)]) -> + IK_mem_rmw(readk_to_readk readk, writek_to_writek writek) | Interp_ast.V_ctor (Id_aux (Id "IK_cond_branch") _) _ _ _ -> IK_cond_branch | Interp_ast.V_ctor (Id_aux (Id "IK_simple") _) _ _ _ -> @@ -680,7 +707,7 @@ let decode_to_instruction top_level registers value : instruction_or_decode_erro let (arg,_) = Interp.to_exp mode Interp.eenv intern_val in let internal_direction = if direction = D_increasing then Interp_ast.IInc else Interp_ast.IDec in let (instr_decoded_error,events) = - interp_to_value_helper debug (Just value) Ivh_decode val_str ("",[]) internal_direction registers [] false + interp_to_value_helper debug (Just value) Ivh_decode val_str (V_list []) internal_direction registers [] false (fun _ -> Interp.resume mode (Interp.Thunk_frame @@ -688,9 +715,9 @@ let decode_to_instruction top_level registers value : instruction_or_decode_erro top_env Interp.eenv (Interp.emem "decode top level") Interp.Top) Nothing) in match (instr_decoded_error) with | Ivh_value instr -> - let instr_external = interp_value_to_instr_external top_level instr in + (* let instr_external = interp_value_to_instr_external top_level instr in*) let (instr_decoded_error,events) = - interp_to_value_helper debug (Just value) Ivh_unsupported val_str instr_external internal_direction + interp_to_value_helper debug (Just value) Ivh_unsupported val_str instr (*instr_external*) internal_direction registers [] false (fun _ -> Interp.resume mode @@ -699,7 +726,7 @@ let decode_to_instruction top_level registers value : instruction_or_decode_erro (Interp_ast.Unknown, Nothing)) top_env Interp.eenv (Interp.emem "decode second top level") Interp.Top) Nothing) in match (instr_decoded_error) with - | Ivh_value _ -> IDE_instr instr_external instr + | Ivh_value _ -> IDE_instr instr (*instr_external*) | Ivh_value_after_exn v -> Assert_extra.failwith "supported_instructions called exit, so support will be needed for that now" | Ivh_error err -> IDE_decode_error err @@ -713,9 +740,9 @@ end let decode_to_istate (top_level:context) registers (value:opcode) : i_state_or_error = let (Context top_env _ _ _ _ _ _ _ _ _ _) = top_level in match decode_to_instruction top_level registers value with - | IDE_instr instr instrv -> + | IDE_instr instr -> let mode = make_interpreter_mode true false in - let (arg,_) = Interp.to_exp mode Interp.eenv instrv in + let (arg,_) = Interp.to_exp mode Interp.eenv instr in Instr instr (IState (Interp.Thunk_frame (E_aux (E_app (Id_aux (Id "execute") Interp_ast.Unknown) [arg]) (Interp_ast.Unknown,Nothing)) @@ -750,11 +777,11 @@ let instr_external_to_interp_value top_level instr = Interp_ast.V_ctor (Interp_ast.Id_aux (Interp_ast.Id name) Interp_ast.Unknown) (mk_typ_id "ast") Interp_ast.C_Union parmsV -val instruction_to_istate : context -> instruction -> instruction_state -let instruction_to_istate (top_level:context) (((name, parms) as instr):instruction) : instruction_state = +val instruction_to_istate : context -> Interp_ast.value -> instruction_state +let instruction_to_istate (top_level:context) (instr:Interp_ast.value) : instruction_state = let mode = make_interpreter_mode true false in let (Context top_env _ _ _ _ _ _ _ _ _ _) = top_level in - let ast_node = fst (Interp.to_exp mode Interp.eenv (instr_external_to_interp_value top_level instr)) in + let ast_node = fst (Interp.to_exp mode Interp.eenv instr) in (IState (Interp.Thunk_frame (E_aux (E_app (Id_aux (Id "execute") Interp_ast.Unknown) [ast_node]) @@ -1092,7 +1119,7 @@ and state_to_outcome_s pp_instruction_state mode state = (fun env -> interp_exhaustive mode.internal_mode.Interp.debug (Just env) state)) ) -val initial_outcome_s_of_instruction : (instruction_state -> unit -> (string * string)) -> context -> interp_mode -> instruction -> Sail_impl_base.outcome_s unit +val initial_outcome_s_of_instruction : (instruction_state -> unit -> (string * string)) -> context -> interp_mode -> Interp_ast.value -> Sail_impl_base.outcome_s unit let initial_outcome_s_of_instruction pp_instruction_state context mode instruction = let state = instruction_to_istate context instruction in state_to_outcome_s pp_instruction_state mode state @@ -1222,136 +1249,13 @@ let nia_address_of_event nia_reg (event: event) : maybe (maybe address) = | _ -> Nothing end -let nias_of_instruction - thread_ism - (nia_address: list (maybe address)) (* Nothing for unknown/undef*) - (regs_in: list reg_name) - (instruction: instruction) - : list nia - = - let (instruction_name, instruction_fields) = instruction in - - let unknown_nia_address = List.elem Nothing nia_address in - - let nias = [NIA_concrete_address addr | forall (addr MEM (List.mapMaybe id nia_address)) | true] in - - (* it's a fact of the Power2.06B instruction pseudocode that in the B and Bc - cases there should be no Unknown values in nia_values, while in the Bclr - and Bcctr cases nia_values will just be Unknown and the semantics should - match the comments in the machineDefTypes definition of nia *) - (* All our other analysis is on the pseudocode directly, which is arguably - pleasingly robust. We could replace the nias pattern match on - instruction_name with something in that style if the exhaustive interpreter - announced register dependencies to register writes (easy) and if it could - check the form of the register writes to LR and CTR matches the - machineDefTypes nia definition *) - match (thread_ism, instruction_name) with - | ("PPCGEN_ism", "B") -> - let () = ensure (not unknown_nia_address) - "unexpected unknown/undefined address in nia_values 1" in - nias - | ("PPCGEN_ism", "Bc") -> - let () = ensure (not unknown_nia_address) - "unexpected unknown/undefined address in nia_values 2" in - NIA_successor :: nias - | ("PPCGEN_ism", "Bclr") -> [ NIA_successor; NIA_LR ] - | ("PPCGEN_ism", "Bcctr") -> [ NIA_successor; NIA_CTR ] - | ("PPCGEN_ism", "Sc") -> - let () = ensure (not unknown_nia_address) - "unexpected unknown/undefined address in nia_values 3" in - match instruction_fields with - | [(_, _, lev)] -> - (* LEV field is 7 bits long, pad it with false at beginning *) - if lev = [Bitc_zero;Bitc_one;Bitc_one;Bitc_one;Bitc_one;Bitc_one;Bitc_one] - (* (Interp_inter_imp.integer_of_byte_list (Interp_inter_imp.to_bytes (false :: bl))) = 63 *) - then [] - else [NIA_successor] - | _ -> [ NIA_successor ] - end - - (* AARch64 label branch (i.e. address must be known) although - these instructions take the address as an offset from PC, in here - we see the absolute address as it was extracted from the micro ops - just before write to PC *) - | ("AArch64HandSail", "BranchImmediate") -> nias - | ("AArch64HandSail", "BranchConditional") -> NIA_successor :: nias - | ("AArch64HandSail", "CompareAndBranch") -> NIA_successor :: nias - | ("AArch64HandSail", "TestBitAndBranch") -> NIA_successor :: nias - - (* AArch64 calculated address branch *) - | ("AArch64HandSail", "BranchRegister") -> - (* do some parsing of the ast fields to figure out which register holds - the branching address i.e. find n in "BR <Xn>". The ast constructor - from armV8.sail: (reg_index,BranchType) BranchRegister; *) - let n_integer = - match instruction_fields with - | [(_, _, n); _] -> integer_of_bit_list n - | _ -> fail - end - in - let () = ensure (0 <= n_integer && n_integer <= 31) - "expected register number from 0 to 31" - in - if n_integer = 31 then - nias (* BR XZR *) - else - (* look for Xn (which we actually call Rn) in regs_in *) - let n_reg = "R" ^ (String_extra.stringFromInteger n_integer) in - [NIA_register r | forall (r MEM regs_in) - | match r with - | (Reg name _ _ _) -> name = n_reg - | _ -> false - end] - - - (** hacky cut-and-paste for AArch64Gen, duplicating code just to see if this suffices *) - - | ("AArch64GenSail", "BranchImmediate") -> nias - | ("AArch64GenSail", "BranchConditional") -> NIA_successor :: nias - | ("AArch64GenSail", "CompareAndBranch") -> NIA_successor :: nias - | ("AArch64GenSail", "TestBitAndBranch") -> NIA_successor :: nias - - (* AArch64 calculated address branch *) - | ("AArch64GenSail", "branch_unconditional_register") -> - (* do some parsing of the ast fields to figure out which register holds - the branching address i.e. find n in "BR <Xn>". The ast constructor - from armV8.sail: (reg_index,BranchType) BranchRegister; *) - let n_integer = - match instruction_fields with - | [(_, _, n); _] -> integer_of_bit_list n - | _ -> fail - end - in - let () = ensure (0 <= n_integer && n_integer <= 31) - "expected register number from 0 to 31" - in - if n_integer = 31 then - nias (* BR XZR *) - else - (* look for Xn (which we actually call Rn) in regs_in *) - let n_reg = "R" ^ (String_extra.stringFromInteger n_integer) in - [NIA_register r | forall (r MEM regs_in) - | match r with - | (Reg name _ _ _) -> name = n_reg - | _ -> false - end] - - (** end of hacky *) - - | ("AArch64LitmusSail", "CtrlDep") -> NIA_successor :: nias - - - | ("MIPS_ism", "B") -> fail - - | (s1,s2) -> - let () = ensure (not unknown_nia_address) - ("unexpected unknown/undefined address in nia_values 4 (\""^s1^"\", \""^s2^"\")") in - [ NIA_successor ] - end - let interp_instruction_analysis + top_level (interp_exhaustive : ((list (reg_name * register_value)) -> list event)) - instruction nia_reg ism environment = + instruction + nia_reg + (nias_function : (list (maybe address) -> list reg_name -> list nia)) + ism environment = let es = interp_exhaustive environment in @@ -1362,7 +1266,7 @@ let interp_instruction_analysis let nia_address = List.mapMaybe (nia_address_of_event nia_reg) es in - let nias = nias_of_instruction ism nia_address regs_in instruction in + let nias = nias_function nia_address regs_in in let dia = DIA_none in (* FIX THIS! *) @@ -1376,6 +1280,41 @@ let interp_instruction_analysis if forall (inst_kind' MEM inst_kinds). inst_kind' = inst_kind then inst_kind + + else if + (forall (inst_kind' MEM (inst_kind :: inst_kinds)). + match inst_kind' with + | IK_mem_read _ -> true + | IK_mem_write _ -> true + | IK_mem_rmw _ -> false + | IK_barrier _ -> false + | IK_cond_branch -> false + | IK_trans _ -> false + | IK_simple -> false + end) && + (exists (inst_kind' MEM (inst_kind :: inst_kinds)). + match inst_kind' with + | IK_mem_read _ -> true + | _ -> false + end) && + (exists (inst_kind' MEM (inst_kind :: inst_kinds)). + match inst_kind' with + | IK_mem_write _ -> true + | _ -> false + end) + then + match + List.partition + (function IK_mem_read _ -> true | _ -> false end) + (inst_kind :: inst_kinds) + with + | ((IK_mem_read r) :: rs, (IK_mem_write w) :: ws) -> + let () = ensure (forall (r' MEM rs). r' = IK_mem_read r) "more than one kind of read" in + let () = ensure (forall (w' MEM ws). w' = IK_mem_write w) "more than one kind of write" in + IK_mem_rmw (r, w) + | _ -> fail + end + (* the TSTART instruction can also be aborted so it will have two kinds of events *) else if (exists (inst_kind' MEM (inst_kind :: inst_kinds)). inst_kind' = IK_trans Transaction_start) && @@ -1384,7 +1323,9 @@ let interp_instruction_analysis || inst_kind' = IK_trans Transaction_abort) then IK_trans Transaction_start - else failwith "multiple instruction kinds" + + else + failwith "multiple instruction kinds" end in (regs_in, regs_out, regs_feeding_address, nias, dia, inst_kind) @@ -1400,29 +1341,29 @@ val print_and_fail_of_inequal : forall 'a. Show 'a => (instruction -> string) -> (string * 'a) -> (string * 'a) -> unit let print_and_fail_if_inequal - (print_endline,pp_instruction,instruction) + (print_endline,instruction) (name1,xs1) (name2,xs2) = if xs1 = xs2 then () else let () = print_endline (name1^": "^show xs1) in let () = print_endline (name2^": "^show xs2) in - failwith (name1^" and "^ name2^" inequal for instruction " ^ pp_instruction instruction) + failwith (name1^" and "^ name2^" inequal for instruction: \n" ^ Interp.string_of_value instruction) let interp_compare_analyses print_endline - pp_instruction (non_pseudo_registers : set reg_name -> set reg_name) context endianness interp_exhaustive - instruction + (instruction : Interp_ast.value) nia_reg + (nias_function : (list (maybe address) -> list reg_name -> list nia)) ism environment analysis_function reg_info = let (regs_in1,regs_out1,regs_feeding_address1,nias1,dia1,inst_kind1) = - interp_instruction_analysis interp_exhaustive instruction nia_reg ism + interp_instruction_analysis context interp_exhaustive instruction nia_reg nias_function ism environment in let (regs_in1S,regs_out1S,regs_feeding_address1S,nias1S) = (Set.fromList regs_in1, @@ -1447,7 +1388,7 @@ let interp_compare_analyses non_pseudo_registers regs_out2S, non_pseudo_registers regs_feeding_address2S) in - let aux = (print_endline,pp_instruction,instruction) in + let aux = (print_endline,instruction) in let () = (print_and_fail_if_inequal aux) ("regs_in exhaustive",regs_in1S) ("regs_in hand",regs_in2S) in diff --git a/src/lem_interp/interp_interface.lem b/src/lem_interp/interp_interface.lem index dcc9f537..32744da2 100644 --- a/src/lem_interp/interp_interface.lem +++ b/src/lem_interp/interp_interface.lem @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -104,6 +112,10 @@ end and the potential static effects from the funcl clause for this instruction Follows the form of the instruction in instruction_extractor, but populates the parameters with actual values *) + + +type instruction_field_value = list bit + type instruction = (string * list (string * instr_parm_typ * instruction_field_value)) let {coq} instructionEqual i1 i2 = match (i1,i2) with @@ -117,7 +129,7 @@ let inline ~{coq} instructionInequal = unsafe_structural_inequality type v_kind = Bitv | Bytev type decode_error = - | Unsupported_instruction_error of instruction + | Unsupported_instruction_error of Interp_ast.value | Not_an_instruction_error of opcode | Internal_error of string @@ -264,12 +276,12 @@ val initial_instruction_state : context -> string -> list register_value -> inst (* string is a function name, list of value are the parameters to that function *) type instruction_or_decode_error = - | IDE_instr of instruction * Interp_ast.value + | IDE_instr of Interp_ast.value | IDE_decode_error of decode_error (** propose to remove the following type and use the above instead *) type i_state_or_error = - | Instr of instruction * instruction_state + | Instr of Interp_ast.value * instruction_state | Decode_error of decode_error diff --git a/src/lem_interp/interp_lib.lem b/src/lem_interp/interp_lib.lem index 40dbab88..e55fc175 100644 --- a/src/lem_interp/interp_lib.lem +++ b/src/lem_interp/interp_lib.lem @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/lem_interp/interp_utilities.lem b/src/lem_interp/interp_utilities.lem index 1878066f..a178df61 100644 --- a/src/lem_interp/interp_utilities.lem +++ b/src/lem_interp/interp_utilities.lem @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/lem_interp/pretty_interp.ml b/src/lem_interp/pretty_interp.ml index 950e1ac5..129b74c0 100644 --- a/src/lem_interp/pretty_interp.ml +++ b/src/lem_interp/pretty_interp.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/lem_interp/printing_functions.ml b/src/lem_interp/printing_functions.ml index a19256a2..a096b27b 100644 --- a/src/lem_interp/printing_functions.ml +++ b/src/lem_interp/printing_functions.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/lem_interp/run_interp.ml b/src/lem_interp/run_interp.ml index f61d9aaf..a6910024 100644 --- a/src/lem_interp/run_interp.ml +++ b/src/lem_interp/run_interp.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/lem_interp/run_interp_model.ml b/src/lem_interp/run_interp_model.ml index 6978aeb9..bb02ce1e 100644 --- a/src/lem_interp/run_interp_model.ml +++ b/src/lem_interp/run_interp_model.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -433,7 +441,7 @@ let run (List.combine nondets (List.map (fun _ -> Random.bits ()) nondets)) in show "nondeterministic evaluation begun" "" "" ""; let (_,_,_,env') = List.fold_right (fun (next,_) (_,_,_,env') -> - loop mode env' (interp0 (make_mode (mode=Run) !track_dependencies false) next)) + loop mode env' (interp0 (make_mode (mode=Run) !track_dependencies true) next)) choose_order (false,mode,!track_dependencies,env'); in show "nondeterministic evaluation ended" "" "" ""; (step next,env',next) @@ -445,7 +453,7 @@ let run else begin show "undefined triggered a non_det" "" "" ""; let (_,_,_,env') = List.fold_right (fun (next,_) (_,_,_,env') -> - loop mode env' (interp0 (make_mode (mode=Run) !track_dependencies false) next)) + loop mode env' (interp0 (make_mode (mode=Run) !track_dependencies true) next)) choose_order (false,mode,!track_dependencies,env'); in (step i_state,env',i_state) end | Escape0(Some e,_) -> @@ -462,11 +470,11 @@ let run | Write_memv1 _ -> assert false) (*| _ -> assert false*) in - loop mode' env' (Interp_inter_imp.interp0 (make_mode (mode' = Run) !track_dependencies false) next) in + loop mode' env' (Interp_inter_imp.interp0 (make_mode (mode' = Run) !track_dependencies true) next) in let mode = match mode with | None -> if eager_eval then Run else Step | Some m -> m in - let imode = make_mode eager_eval !track_dependencies false in + let imode = make_mode eager_eval !track_dependencies true in let (IState(instr_state,context)) = istate in let (top_exp,(top_env,top_mem)) = top_frame_exp_state instr_state in interactf "%s: %s %s\n" (grey name) (blue "evaluate") diff --git a/src/lem_interp/run_with_elf.ml b/src/lem_interp/run_with_elf.ml index 2a1783db..8533827b 100644 --- a/src/lem_interp/run_with_elf.ml +++ b/src/lem_interp/run_with_elf.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -1198,12 +1206,16 @@ let rec fde_loop count context model mode track_dependencies addr_trans = let opcode = Opcode (get_opcode pc) in let (instruction,istate) = match Interp_inter_imp.decode_to_istate context None opcode with | Instr(instruction,istate) -> - interactf "\n**** Running: %s ****\n" (Printing_functions.instruction_to_string instruction); + let instruction = interp_value_to_instr_external context instruction in + interactf "\n**** Running: %s ****\n" + (Printing_functions.instruction_to_string instruction); (instruction,istate) | Decode_error d -> (match d with - | Interp_interface.Unsupported_instruction_error instr -> - errorf "\n**** Encountered unsupported instruction %s ****\n" (Printing_functions.instruction_to_string instr) + | Interp_interface.Unsupported_instruction_error instruction -> + let instruction = interp_value_to_instr_external context instruction in + errorf "\n**** Encountered unsupported instruction %s ****\n" + (Printing_functions.instruction_to_string instruction) | Interp_interface.Not_an_instruction_error op -> (match op with | Opcode bytes -> diff --git a/src/lem_interp/run_with_elf_cheri.ml b/src/lem_interp/run_with_elf_cheri.ml index e773bf5b..46bc92fb 100644 --- a/src/lem_interp/run_with_elf_cheri.ml +++ b/src/lem_interp/run_with_elf_cheri.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -124,375 +132,13 @@ let register_state_zero register_data rbn : register_value = in register_value_zeros dir width start_index type model = PPC | AArch64 | MIPS -(* -let ppc_register_data_all = [ - (*Pseudo registers*) - ("CIA", (D_increasing, 64, 0)); - ("NIA", (D_increasing, 64, 0)); - ("mode64bit", (D_increasing, 1, 0)); - ("bigendianmode", (D_increasing, 1, 0)); - (* special registers *) - ("CR", (D_increasing, 32, 32)); - ("CTR", (D_increasing, 64, 0 )); - ("LR", (D_increasing, 64, 0 )); - ("XER", (D_increasing, 64, 0 )); - ("VRSAVE",(D_increasing, 32, 32)); - ("FPSCR", (D_increasing, 64, 0 )); - ("VSCR", (D_increasing, 32, 96)); - - (* general purpose registers *) - ("GPR0", (D_increasing, 64, 0 )); - ("GPR1", (D_increasing, 64, 0 )); - ("GPR2", (D_increasing, 64, 0 )); - ("GPR3", (D_increasing, 64, 0 )); - ("GPR4", (D_increasing, 64, 0 )); - ("GPR5", (D_increasing, 64, 0 )); - ("GPR6", (D_increasing, 64, 0 )); - ("GPR7", (D_increasing, 64, 0 )); - ("GPR8", (D_increasing, 64, 0 )); - ("GPR9", (D_increasing, 64, 0 )); - ("GPR10", (D_increasing, 64, 0 )); - ("GPR11", (D_increasing, 64, 0 )); - ("GPR12", (D_increasing, 64, 0 )); - ("GPR13", (D_increasing, 64, 0 )); - ("GPR14", (D_increasing, 64, 0 )); - ("GPR15", (D_increasing, 64, 0 )); - ("GPR16", (D_increasing, 64, 0 )); - ("GPR17", (D_increasing, 64, 0 )); - ("GPR18", (D_increasing, 64, 0 )); - ("GPR19", (D_increasing, 64, 0 )); - ("GPR20", (D_increasing, 64, 0 )); - ("GPR21", (D_increasing, 64, 0 )); - ("GPR22", (D_increasing, 64, 0 )); - ("GPR23", (D_increasing, 64, 0 )); - ("GPR24", (D_increasing, 64, 0 )); - ("GPR25", (D_increasing, 64, 0 )); - ("GPR26", (D_increasing, 64, 0 )); - ("GPR27", (D_increasing, 64, 0 )); - ("GPR28", (D_increasing, 64, 0 )); - ("GPR29", (D_increasing, 64, 0 )); - ("GPR30", (D_increasing, 64, 0 )); - ("GPR31", (D_increasing, 64, 0 )); - (* vector registers *) - ("VR0", (D_increasing, 128, 0 )); - ("VR1", (D_increasing, 128, 0 )); - ("VR2", (D_increasing, 128, 0 )); - ("VR3", (D_increasing, 128, 0 )); - ("VR4", (D_increasing, 128, 0 )); - ("VR5", (D_increasing, 128, 0 )); - ("VR6", (D_increasing, 128, 0 )); - ("VR7", (D_increasing, 128, 0 )); - ("VR8", (D_increasing, 128, 0 )); - ("VR9", (D_increasing, 128, 0 )); - ("VR10", (D_increasing, 128, 0 )); - ("VR11", (D_increasing, 128, 0 )); - ("VR12", (D_increasing, 128, 0 )); - ("VR13", (D_increasing, 128, 0 )); - ("VR14", (D_increasing, 128, 0 )); - ("VR15", (D_increasing, 128, 0 )); - ("VR16", (D_increasing, 128, 0 )); - ("VR17", (D_increasing, 128, 0 )); - ("VR18", (D_increasing, 128, 0 )); - ("VR19", (D_increasing, 128, 0 )); - ("VR20", (D_increasing, 128, 0 )); - ("VR21", (D_increasing, 128, 0 )); - ("VR22", (D_increasing, 128, 0 )); - ("VR23", (D_increasing, 128, 0 )); - ("VR24", (D_increasing, 128, 0 )); - ("VR25", (D_increasing, 128, 0 )); - ("VR26", (D_increasing, 128, 0 )); - ("VR27", (D_increasing, 128, 0 )); - ("VR28", (D_increasing, 128, 0 )); - ("VR29", (D_increasing, 128, 0 )); - ("VR30", (D_increasing, 128, 0 )); - ("VR31", (D_increasing, 128, 0 )); - (* floating-point registers *) - ("FPR0", (D_increasing, 64, 0 )); - ("FPR1", (D_increasing, 64, 0 )); - ("FPR2", (D_increasing, 64, 0 )); - ("FPR3", (D_increasing, 64, 0 )); - ("FPR4", (D_increasing, 64, 0 )); - ("FPR5", (D_increasing, 64, 0 )); - ("FPR6", (D_increasing, 64, 0 )); - ("FPR7", (D_increasing, 64, 0 )); - ("FPR8", (D_increasing, 64, 0 )); - ("FPR9", (D_increasing, 64, 0 )); - ("FPR10", (D_increasing, 64, 0 )); - ("FPR11", (D_increasing, 64, 0 )); - ("FPR12", (D_increasing, 64, 0 )); - ("FPR13", (D_increasing, 64, 0 )); - ("FPR14", (D_increasing, 64, 0 )); - ("FPR15", (D_increasing, 64, 0 )); - ("FPR16", (D_increasing, 64, 0 )); - ("FPR17", (D_increasing, 64, 0 )); - ("FPR18", (D_increasing, 64, 0 )); - ("FPR19", (D_increasing, 64, 0 )); - ("FPR20", (D_increasing, 64, 0 )); - ("FPR21", (D_increasing, 64, 0 )); - ("FPR22", (D_increasing, 64, 0 )); - ("FPR23", (D_increasing, 64, 0 )); - ("FPR24", (D_increasing, 64, 0 )); - ("FPR25", (D_increasing, 64, 0 )); - ("FPR26", (D_increasing, 64, 0 )); - ("FPR27", (D_increasing, 64, 0 )); - ("FPR28", (D_increasing, 64, 0 )); - ("FPR29", (D_increasing, 64, 0 )); - ("FPR30", (D_increasing, 64, 0 )); - ("FPR31", (D_increasing, 64, 0 )); -] - -let initial_stack_and_reg_data_of_PPC_elf_file e_entry all_data_memory = - (* set up initial registers, per 3.4.1 of 64-bit PowerPC ELF Application Binary Interface Supplement 1.9 *) - - let auxiliary_vector_space = Nat_big_num.of_string "17592186042368" (*"0xffffffff800"*) in - (* notionally there should be at least an AT_NULL auxiliary vector entry there, but our examples will never read it *) - - (* take start of stack roughly where running gdb on hello5 on bim says it is*) - let initial_GPR1_stack_pointer = Nat_big_num.of_string "17592186040320" (*"0xffffffff000"*) in - let initial_GPR1_stack_pointer_value = - Sail_impl_base.register_value_of_integer 64 0 Sail_impl_base.D_increasing initial_GPR1_stack_pointer in - (* ELF says we need an initial zero doubleword there *) - let initial_stack_data = - (* the code actually uses the stack, both above and below, so we map a bit more memory*) - (* this is a fairly big but arbitrary chunk *) - (* let initial_stack_data_address = Nat_big_num.sub initial_GPR1_stack_pointer (Nat_big_num.of_int 128) in - [("initial_stack_data", initial_stack_data_address, Lem_list.replicate (128+32) 0 ))] in *) - (* this is the stack memory that test 1938 actually uses *) - [ ("initial_stack_data1", Nat_big_num.sub initial_GPR1_stack_pointer (Nat_big_num.of_int 128), - Lem_list.replicate 8 0 ); - ("initial_stack_data2", Nat_big_num.sub initial_GPR1_stack_pointer (Nat_big_num.of_int 8), - Lem_list.replicate 8 0 ); - ("initial_stack_data3", Nat_big_num.add initial_GPR1_stack_pointer (Nat_big_num.of_int 16), - Lem_list.replicate 8 0 )] in - - (* read TOC from the second field of the function descriptor pointed to by e_entry*) - let initial_GPR2_TOC = - Sail_impl_base.register_value_of_address - (Sail_impl_base.address_of_byte_list - (List.map (fun b -> match b with Some b -> b | None -> failwith "Address had undefined") - (List.map byte_of_byte_lifted - (read_mem all_data_memory - (Nat_big_num.add (Nat_big_num.of_int 8) e_entry) 8)))) - Sail_impl_base.D_increasing in - (* these initial register values are all mandated to be zero, but that's handled by the generic zeroing below - let initial_GPR3_argc = (Nat_big_num.of_int 0) in - let initial_GPR4_argv = (Nat_big_num.of_int 0) in - let initial_GPR5_envp = (Nat_big_num.of_int 0) in - let initial_FPSCR = (Nat_big_num.of_int 0) in - *) - let initial_register_abi_data : (string * Sail_impl_base.register_value) list = - [ ("GPR1", initial_GPR1_stack_pointer_value); - ("GPR2", initial_GPR2_TOC); - (* - ("GPR3", initial_GPR3_argc); - ("GPR4", initial_GPR4_argv); - ("GPR5", initial_GPR5_envp); - ("FPSCR", initial_FPSCR); - *) - ] in - - (initial_stack_data, initial_register_abi_data) - - -let aarch64_reg bit_count name = (name, (D_decreasing, bit_count, bit_count - 1)) - -let aarch64_PC_data = [aarch64_reg 64 "_PC"] - -(* most of the PSTATE fields are aliases to other registers so they - don't appear here *) -let aarch64_PSTATE_data = [ - aarch64_reg 1 "PSTATE_nRW"; - aarch64_reg 1 "PSTATE_E"; - aarch64_reg 5 "PSTATE_M"; -] - -let aarch64_general_purpose_registers_data = [ - aarch64_reg 64 "R0"; - aarch64_reg 64 "R1"; - aarch64_reg 64 "R2"; - aarch64_reg 64 "R3"; - aarch64_reg 64 "R4"; - aarch64_reg 64 "R5"; - aarch64_reg 64 "R6"; - aarch64_reg 64 "R7"; - aarch64_reg 64 "R8"; - aarch64_reg 64 "R9"; - aarch64_reg 64 "R10"; - aarch64_reg 64 "R11"; - aarch64_reg 64 "R12"; - aarch64_reg 64 "R13"; - aarch64_reg 64 "R14"; - aarch64_reg 64 "R15"; - aarch64_reg 64 "R16"; - aarch64_reg 64 "R17"; - aarch64_reg 64 "R18"; - aarch64_reg 64 "R19"; - aarch64_reg 64 "R20"; - aarch64_reg 64 "R21"; - aarch64_reg 64 "R22"; - aarch64_reg 64 "R23"; - aarch64_reg 64 "R24"; - aarch64_reg 64 "R25"; - aarch64_reg 64 "R26"; - aarch64_reg 64 "R27"; - aarch64_reg 64 "R28"; - aarch64_reg 64 "R29"; - aarch64_reg 64 "R30"; -] - -let aarch64_SIMD_registers_data = [ - aarch64_reg 128 "V0"; - aarch64_reg 128 "V1"; - aarch64_reg 128 "V2"; - aarch64_reg 128 "V3"; - aarch64_reg 128 "V4"; - aarch64_reg 128 "V5"; - aarch64_reg 128 "V6"; - aarch64_reg 128 "V7"; - aarch64_reg 128 "V8"; - aarch64_reg 128 "V9"; - aarch64_reg 128 "V10"; - aarch64_reg 128 "V11"; - aarch64_reg 128 "V12"; - aarch64_reg 128 "V13"; - aarch64_reg 128 "V14"; - aarch64_reg 128 "V15"; - aarch64_reg 128 "V16"; - aarch64_reg 128 "V17"; - aarch64_reg 128 "V18"; - aarch64_reg 128 "V19"; - aarch64_reg 128 "V20"; - aarch64_reg 128 "V21"; - aarch64_reg 128 "V22"; - aarch64_reg 128 "V23"; - aarch64_reg 128 "V24"; - aarch64_reg 128 "V25"; - aarch64_reg 128 "V26"; - aarch64_reg 128 "V27"; - aarch64_reg 128 "V28"; - aarch64_reg 128 "V29"; - aarch64_reg 128 "V30"; - aarch64_reg 128 "V31"; -] - -let aarch64_special_purpose_registers_data = [ - aarch64_reg 32 "CurrentEL"; - aarch64_reg 32 "DAIF"; - aarch64_reg 32 "NZCV"; - aarch64_reg 64 "SP_EL0"; - aarch64_reg 64 "SP_EL1"; - aarch64_reg 64 "SP_EL2"; - aarch64_reg 64 "SP_EL3"; - aarch64_reg 32 "SPSel"; - aarch64_reg 32 "SPSR_EL1"; - aarch64_reg 32 "SPSR_EL2"; - aarch64_reg 32 "SPSR_EL3"; - aarch64_reg 64 "ELR_EL1"; - aarch64_reg 64 "ELR_EL2"; - aarch64_reg 64 "ELR_EL3"; -] - -let aarch64_general_system_control_registers_data = [ - aarch64_reg 64 "HCR_EL2"; - aarch64_reg 64 "ID_AA64MMFR0_EL1"; - aarch64_reg 64 "RVBAR_EL1"; - aarch64_reg 64 "RVBAR_EL2"; - aarch64_reg 64 "RVBAR_EL3"; - aarch64_reg 32 "SCR_EL3"; - aarch64_reg 32 "SCTLR_EL1"; - aarch64_reg 32 "SCTLR_EL2"; - aarch64_reg 32 "SCTLR_EL3"; - aarch64_reg 64 "TCR_EL1"; - aarch64_reg 32 "TCR_EL2"; - aarch64_reg 32 "TCR_EL3"; -] - -let aarch64_debug_registers_data = [ - aarch64_reg 32 "DBGPRCR_EL1"; - aarch64_reg 32 "OSDLR_EL1"; -] - -let aarch64_performance_monitors_registers_data = [] -let aarch64_generic_timer_registers_data = [] -let aarch64_generic_interrupt_controller_CPU_interface_registers_data = [] - -let aarch64_external_debug_registers_data = [ - aarch64_reg 32 "EDSCR"; -] - -let aarch32_general_system_control_registers_data = [ - aarch64_reg 32 "SCR"; -] - -let aarch32_debug_registers_data = [ - aarch64_reg 32 "DBGOSDLR"; - aarch64_reg 32 "DBGPRCR"; -] - -let aarch64_register_data_all = - aarch64_PC_data @ - aarch64_PSTATE_data @ - aarch64_general_purpose_registers_data @ - aarch64_SIMD_registers_data @ - aarch64_special_purpose_registers_data @ - aarch64_general_system_control_registers_data @ - aarch64_debug_registers_data @ - aarch64_performance_monitors_registers_data @ - aarch64_generic_timer_registers_data @ - aarch64_generic_interrupt_controller_CPU_interface_registers_data @ - aarch64_external_debug_registers_data @ - aarch32_general_system_control_registers_data @ - aarch32_debug_registers_data - -let initial_stack_and_reg_data_of_AAarch64_elf_file e_entry all_data_memory = - let (reg_SP_EL0_direction, reg_SP_EL0_width, reg_SP_EL0_initial_index) = - List.assoc "SP_EL0" aarch64_register_data_all in - - (* we compiled a small program that prints out SP and run it a few - times on the Nexus9, these are the results: - 0x0000007fe7f903e0 - 0x0000007fdcdbf3f0 - 0x0000007fcbe1ba90 - 0x0000007fcf378280 - 0x0000007fdd54b8d0 - 0x0000007fd961bc10 - 0x0000007ff3be6350 - 0x0000007fd6bf6ef0 - 0x0000007fff7676f0 - 0x0000007ff2c34560 *) - let initial_SP_EL0 = Nat_big_num.of_string "549739036672" (*"0x0000007fff000000"*) in - let initial_SP_EL0_value = - Sail_impl_base.register_value_of_integer - reg_SP_EL0_width - reg_SP_EL0_initial_index - reg_SP_EL0_direction - initial_SP_EL0 - in - - (* ELF says we need an initial zero doubleword there *) - (* the code actually uses the stack, both above and below, so we map a bit more memory*) - let initial_stack_data = - (* this is a fairly big but arbitrary chunk: *) - (* let initial_stack_data_address = Nat_big_num.sub initial_GPR1_stack_pointer (Nat_big_num.of_int 128) in - [("initial_stack_data", initial_stack_data_address, Lem_list.replicate (128+32) 0 ))] in *) - - [ ("initial_stack_data1", Nat_big_num.sub initial_SP_EL0 (Nat_big_num.of_int 16), Lem_list.replicate 8 0); - ("initial_stack_data2", Nat_big_num.sub initial_SP_EL0 (Nat_big_num.of_int 8), Lem_list.replicate 8 0) - ] - in - - let initial_register_abi_data : (string * Sail_impl_base.register_value) list = - [("SP_EL0", initial_SP_EL0_value)] - in - - (initial_stack_data, initial_register_abi_data) -*) let mips_register_data_all = [ (*Pseudo registers*) ("PC", (D_decreasing, 64, 63)); ("branchPending", (D_decreasing, 1, 0)); ("inBranchDelay", (D_decreasing, 1, 0)); + ("inCCallDelay", (D_decreasing, 1, 0)); ("delayedPC", (D_decreasing, 64, 63)); ("nextPC", (D_decreasing, 64, 63)); (* General purpose registers *) @@ -748,50 +394,6 @@ let initial_system_state_of_elf_file name = let (isa_defs, isa_memory_access, isa_externs, isa_model, model_reg_d, startaddr, initial_stack_data, initial_register_abi_data, register_data_all) = match Nat_big_num.to_int e_machine with -(* | 21 (* EM_PPC64 *) -> - let startaddr = - let e_entry = Uint64.of_int64 (Nat_big_num.to_int64 e_entry) in - match Abi_power64.abi_power64_compute_program_entry_point segments e_entry with - | Error.Fail s -> failwith "Failed computing entry point" - | Error.Success s -> Nat_big_num.of_int64 (Uint64.to_int64 s) - in - let (initial_stack_data, initial_register_abi_data) = - initial_stack_and_reg_data_of_PPC_elf_file e_entry !data_mem in - - (Power.defs, - (Power_extras.read_memory_functions,Power_extras.memory_writes,[],[],Power_extras.barrier_functions), - Power_extras.power_externs, - PPC, - D_increasing, - startaddr, - initial_stack_data, - initial_register_abi_data, - ppc_register_data_all) - - | 183 (* EM_AARCH64 *) -> - let startaddr = - let e_entry = Uint64.of_int64 (Nat_big_num.to_int64 e_entry) in - match Abi_aarch64_le.abi_aarch64_le_compute_program_entry_point segments e_entry with - | Error.Fail s -> failwith "Failed computing entry point" - | Error.Success s -> Nat_big_num.of_int64 (Uint64.to_int64 s) - in - - let (initial_stack_data, initial_register_abi_data) = - initial_stack_and_reg_data_of_AAarch64_elf_file e_entry !data_mem in - - (ArmV8.defs, - (ArmV8_extras.aArch64_read_memory_functions, - ArmV8_extras.aArch64_memory_writes, - ArmV8_extras.aArch64_memory_eas, - ArmV8_extras.aArch64_memory_vals, - ArmV8_extras.aArch64_barrier_functions), - [], - AArch64, - D_decreasing, - startaddr, - initial_stack_data, - initial_register_abi_data, - aarch64_register_data_all) *) | 8 (* EM_MIPS *) -> let startaddr = let e_entry = Uint64.of_string (Nat_big_num.to_string e_entry) in @@ -888,50 +490,6 @@ let initial_system_state_of_elf_file name = in - (* Now we examine the rest of the data memory, - removing the footprint of the symbols and chunking it into aligned chunks *) - - let rec remove_symbols_from_data_memory data_mem symbols = - match symbols with - | [] -> data_mem - | (name,address,size,bs)::symbols' -> - let data_mem' = - Mem.filter - (fun a v -> - not (Nat_big_num.greater_equal a address && - Nat_big_num.less a (Nat_big_num.add (Nat_big_num.of_int (List.length bs)) address))) - data_mem in - remove_symbols_from_data_memory data_mem' symbols' in - - let trimmed_data_memory : (Nat_big_num.num * memory_byte) list = - Mem.bindings (remove_symbols_from_data_memory !data_mem symbol_table) in - - (* make sure that's ordered increasingly.... *) - let trimmed_data_memory = - List.sort (fun (a,b) (a',b') -> Nat_big_num.compare a a') trimmed_data_memory in - - let aligned a n = (* a mod n = 0 *) - let n_big = Nat_big_num.of_int n in - Nat_big_num.equal (Nat_big_num.modulus a n_big) ((Nat_big_num.of_int 0)) in - - let isplus a' a n = (* a' = a+n *) - Nat_big_num.equal a' (Nat_big_num.add (Nat_big_num.of_int n) a) in - - let rec chunk_data_memory dm = - match dm with - | (a0,b0)::(a1,b1)::(a2,b2)::(a3,b3)::(a4,b4)::(a5,b5)::(a6,b6)::(a7,b7)::dm' when - (aligned a0 8 && isplus a1 a0 1 && isplus a2 a0 2 && isplus a3 a0 3 && - isplus a4 a0 4 && isplus a5 a0 5 && isplus a6 a0 6 && isplus a7 a0 7) -> - (a0,8,[b0;b1;b2;b3;b4;b5;b6;b7]) :: chunk_data_memory dm' - | (a0,b0)::(a1,b1)::(a2,b2)::(a3,b3)::dm' when - (aligned a0 4 && isplus a1 a0 1 && isplus a2 a0 2 && isplus a3 a0 3) -> - (a0,4,[b0;b1;b2;b3]) :: chunk_data_memory dm' - | (a0,b0)::(a1,b1)::dm' when - (aligned a0 2 && isplus a1 a0 1) -> - (a0,2,[b0;b1]) :: chunk_data_memory dm' - | (a0,b0)::dm' -> - (a0,1,[b0]):: chunk_data_memory dm' - | [] -> [] in let initial_register_state = fun rbn -> @@ -1021,68 +579,10 @@ let stop_condition_met model instr = true | _ -> false) -let is_branch model instruction = - let (name,_,_) = instruction in - match (model , name) with - | (PPC, "B") -> true - | (PPC, "Bc") -> true - | (PPC, "Bclr") -> true - | (PPC, "Bcctr") -> true - | (PPC, _) -> false - | (AArch64, "BranchImmediate") -> true - | (AArch64, "BranchConditional") -> true - | (AArch64, "CompareAndBranch") -> true - | (AArch64, "TestBitAndBranch") -> true - | (AArch64, "BranchRegister") -> true - | (AArch64, _) -> false - | (MIPS, _) -> false (*todo,fill this in*) - let option_int_of_option_integer i = match i with | Some i -> Some (Nat_big_num.to_int i) | None -> None -let set_next_instruction_address model = - match model with - | PPC -> - let cia = Reg.find "CIA" !reg in - let cia_addr = address_of_register_value cia in - (match cia_addr with - | Some cia_addr -> - let nia_addr = add_address_nat cia_addr 4 in - let nia = register_value_of_address nia_addr Sail_impl_base.D_increasing in - reg := Reg.add "NIA" nia !reg - | _ -> failwith "CIA address contains unknown or undefined") - | AArch64 -> - let pc = Reg.find "_PC" !reg in - let pc_addr = address_of_register_value pc in - (match pc_addr with - | Some pc_addr -> - let n_addr = add_address_nat pc_addr 4 in - let n_pc = register_value_of_address n_addr D_decreasing in - reg := Reg.add "_PC" n_pc !reg - | _ -> failwith "_PC address contains unknown or undefined") - | MIPS -> - let pc_addr = address_of_register_value (Reg.find "PC" !reg) in - let branchPending = integer_of_register_value (Reg.find "branchPending" !reg) in - (match (pc_addr, option_int_of_option_integer branchPending) with - | (Some pc_val, Some 0) -> - (* normal -- increment PC *) - let n_addr = add_address_nat pc_val 4 in - let n_pc = register_value_of_address n_addr D_decreasing in - begin - reg := Reg.add "nextPC" n_pc !reg; - reg := Reg.add "inBranchDelay" (register_value_of_integer 1 0 Sail_impl_base.D_decreasing Nat_big_num.zero) !reg; - end - | (Some pc_val, Some 1) -> - (* delay slot -- branch to delayed PC and clear branchPending *) - begin - reg := Reg.add "nextPC" (Reg.find "delayedPC" !reg) !reg; - reg := Reg.add "nextPCC" (Reg.find "delayedPCC" !reg) !reg; - reg := Reg.add "branchPending" (register_value_of_integer 1 0 Sail_impl_base.D_decreasing Nat_big_num.zero) !reg; - reg := Reg.add "inBranchDelay" (register_value_of_integer 1 0 Sail_impl_base.D_decreasing (Nat_big_num.of_int 1)) !reg; - end - | (_, _) -> errorf "PC address contains unknown or undefined"; exit 1) - let add1 = Nat_big_num.add (Nat_big_num.of_int 1) let get_addr_trans_regs _ = @@ -1192,68 +692,10 @@ let rec write_events = function | _ -> failwith "Only register write events expected"); write_events events -let fetch_instruction_opcode_and_update_ia model addr_trans = - match model with - | PPC -> - let cia = Reg.find "CIA" !reg in - let cia_addr = address_of_register_value cia in - (match cia_addr with - | Some cia_addr -> - let cia_a = integer_of_address cia_addr in - let opcode = (get_opcode cia_a) in - begin - reg := Reg.add "CIA" (Reg.find "NIA" !reg) !reg; - Opcode opcode - end - | None -> failwith "CIA address contains unknown or undefined") - | AArch64 -> - let pc = Reg.find "_PC" !reg in - let pc_addr = address_of_register_value pc in - (match pc_addr with - | Some pc_addr -> - let pc_a = integer_of_address pc_addr in - let opcode = (get_opcode pc_a) in - Opcode opcode - | None -> failwith "_PC address contains unknown or undefined") - | MIPS -> - begin - reg := Reg.add "PCC" (Reg.find "nextPCC" !reg) !reg; - let nextPC = Reg.find "nextPC" !reg in - let pc_addr = address_of_register_value nextPC in - (*let unused = interactf "PC: %s\n" (Printing_functions.register_value_to_string nextPC) in*) - (match pc_addr with - | Some pc_addr -> - let pc_a = match addr_trans (get_addr_trans_regs ()) pc_addr with - | Some a, Some events -> write_events (List.rev events); integer_of_address a - | Some a, None -> integer_of_address a - | None, Some events -> - write_events (List.rev events); - let nextPC = Reg.find "nextPC" !reg in - reg := Reg.add "PCC" (Reg.find "nextPCC" !reg) !reg; - let pc_addr = address_of_register_value nextPC in - (match pc_addr with - | Some pc_addr -> - (match addr_trans (get_addr_trans_regs ()) pc_addr with - | Some a, Some events -> write_events (List.rev events); integer_of_address a - | Some a, None -> integer_of_address a - | None, _ -> failwith "Address translation failed twice") - | None -> failwith "no nextPc address") - | _ -> failwith "No address and no events from translate address" - in - let opcode = (get_opcode pc_a) in - begin - reg := Reg.add "PC" (Reg.find "nextPC" !reg) !reg; - Opcode opcode - end - | None -> errorf "nextPC contains unknown or undefined"; exit 1) - end - | _ -> assert false - let get_pc_address = function | MIPS -> Reg.find "PC" !reg | PPC -> Reg.find "CIA" !reg | AArch64 -> Reg.find "_PC" !reg - let option_int_of_reg str = option_int_of_option_integer (integer_of_register_value (Reg.find str !reg)) @@ -1283,6 +725,7 @@ let rec fde_loop count context model mode track_dependencies addr_trans = let npc_addr = add_address_nat pc_val 4 in let npc_reg = register_value_of_address npc_addr Sail_impl_base.D_decreasing in reg := Reg.add "nextPC" npc_reg !reg; + reg := Reg.add "inCCallDelay" (register_value_of_integer 1 0 Sail_impl_base.D_decreasing Nat_big_num.zero) !reg; | Some 1 -> reg := Reg.add "nextPC" (Reg.find "delayedPC" !reg) !reg; reg := Reg.add "nextPCC" (Reg.find "delayedPCC" !reg) !reg; @@ -1290,12 +733,14 @@ let rec fde_loop count context model mode track_dependencies addr_trans = let opcode = Opcode (get_opcode pc) in let (instruction,istate) = match Interp_inter_imp.decode_to_istate context None opcode with | Instr(instruction,istate) -> + let instruction = interp_value_to_instr_external context instruction in interactf "\n**** Running: %s ****\n" (Printing_functions.instruction_to_string instruction); (instruction,istate) | Decode_error d -> (match d with - | Interp_interface.Unsupported_instruction_error instr -> - errorf "\n**** Encountered unsupported instruction %s ****\n" (Printing_functions.instruction_to_string instr) + | Interp_interface.Unsupported_instruction_error instruction -> + let instruction = interp_value_to_instr_external context instruction in + errorf "\n**** Encountered unsupported instruction %s ****\n" (Printing_functions.instruction_to_string instruction) | Interp_interface.Not_an_instruction_error op -> (match op with | Opcode bytes -> diff --git a/src/lem_interp/run_with_elf_cheri128.ml b/src/lem_interp/run_with_elf_cheri128.ml index cd2e7312..5e5bee21 100644 --- a/src/lem_interp/run_with_elf_cheri128.ml +++ b/src/lem_interp/run_with_elf_cheri128.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -124,375 +132,13 @@ let register_state_zero register_data rbn : register_value = in register_value_zeros dir width start_index type model = PPC | AArch64 | MIPS -(* -let ppc_register_data_all = [ - (*Pseudo registers*) - ("CIA", (D_increasing, 64, 0)); - ("NIA", (D_increasing, 64, 0)); - ("mode64bit", (D_increasing, 1, 0)); - ("bigendianmode", (D_increasing, 1, 0)); - (* special registers *) - ("CR", (D_increasing, 32, 32)); - ("CTR", (D_increasing, 64, 0 )); - ("LR", (D_increasing, 64, 0 )); - ("XER", (D_increasing, 64, 0 )); - ("VRSAVE",(D_increasing, 32, 32)); - ("FPSCR", (D_increasing, 64, 0 )); - ("VSCR", (D_increasing, 32, 96)); - - (* general purpose registers *) - ("GPR0", (D_increasing, 64, 0 )); - ("GPR1", (D_increasing, 64, 0 )); - ("GPR2", (D_increasing, 64, 0 )); - ("GPR3", (D_increasing, 64, 0 )); - ("GPR4", (D_increasing, 64, 0 )); - ("GPR5", (D_increasing, 64, 0 )); - ("GPR6", (D_increasing, 64, 0 )); - ("GPR7", (D_increasing, 64, 0 )); - ("GPR8", (D_increasing, 64, 0 )); - ("GPR9", (D_increasing, 64, 0 )); - ("GPR10", (D_increasing, 64, 0 )); - ("GPR11", (D_increasing, 64, 0 )); - ("GPR12", (D_increasing, 64, 0 )); - ("GPR13", (D_increasing, 64, 0 )); - ("GPR14", (D_increasing, 64, 0 )); - ("GPR15", (D_increasing, 64, 0 )); - ("GPR16", (D_increasing, 64, 0 )); - ("GPR17", (D_increasing, 64, 0 )); - ("GPR18", (D_increasing, 64, 0 )); - ("GPR19", (D_increasing, 64, 0 )); - ("GPR20", (D_increasing, 64, 0 )); - ("GPR21", (D_increasing, 64, 0 )); - ("GPR22", (D_increasing, 64, 0 )); - ("GPR23", (D_increasing, 64, 0 )); - ("GPR24", (D_increasing, 64, 0 )); - ("GPR25", (D_increasing, 64, 0 )); - ("GPR26", (D_increasing, 64, 0 )); - ("GPR27", (D_increasing, 64, 0 )); - ("GPR28", (D_increasing, 64, 0 )); - ("GPR29", (D_increasing, 64, 0 )); - ("GPR30", (D_increasing, 64, 0 )); - ("GPR31", (D_increasing, 64, 0 )); - (* vector registers *) - ("VR0", (D_increasing, 128, 0 )); - ("VR1", (D_increasing, 128, 0 )); - ("VR2", (D_increasing, 128, 0 )); - ("VR3", (D_increasing, 128, 0 )); - ("VR4", (D_increasing, 128, 0 )); - ("VR5", (D_increasing, 128, 0 )); - ("VR6", (D_increasing, 128, 0 )); - ("VR7", (D_increasing, 128, 0 )); - ("VR8", (D_increasing, 128, 0 )); - ("VR9", (D_increasing, 128, 0 )); - ("VR10", (D_increasing, 128, 0 )); - ("VR11", (D_increasing, 128, 0 )); - ("VR12", (D_increasing, 128, 0 )); - ("VR13", (D_increasing, 128, 0 )); - ("VR14", (D_increasing, 128, 0 )); - ("VR15", (D_increasing, 128, 0 )); - ("VR16", (D_increasing, 128, 0 )); - ("VR17", (D_increasing, 128, 0 )); - ("VR18", (D_increasing, 128, 0 )); - ("VR19", (D_increasing, 128, 0 )); - ("VR20", (D_increasing, 128, 0 )); - ("VR21", (D_increasing, 128, 0 )); - ("VR22", (D_increasing, 128, 0 )); - ("VR23", (D_increasing, 128, 0 )); - ("VR24", (D_increasing, 128, 0 )); - ("VR25", (D_increasing, 128, 0 )); - ("VR26", (D_increasing, 128, 0 )); - ("VR27", (D_increasing, 128, 0 )); - ("VR28", (D_increasing, 128, 0 )); - ("VR29", (D_increasing, 128, 0 )); - ("VR30", (D_increasing, 128, 0 )); - ("VR31", (D_increasing, 128, 0 )); - (* floating-point registers *) - ("FPR0", (D_increasing, 64, 0 )); - ("FPR1", (D_increasing, 64, 0 )); - ("FPR2", (D_increasing, 64, 0 )); - ("FPR3", (D_increasing, 64, 0 )); - ("FPR4", (D_increasing, 64, 0 )); - ("FPR5", (D_increasing, 64, 0 )); - ("FPR6", (D_increasing, 64, 0 )); - ("FPR7", (D_increasing, 64, 0 )); - ("FPR8", (D_increasing, 64, 0 )); - ("FPR9", (D_increasing, 64, 0 )); - ("FPR10", (D_increasing, 64, 0 )); - ("FPR11", (D_increasing, 64, 0 )); - ("FPR12", (D_increasing, 64, 0 )); - ("FPR13", (D_increasing, 64, 0 )); - ("FPR14", (D_increasing, 64, 0 )); - ("FPR15", (D_increasing, 64, 0 )); - ("FPR16", (D_increasing, 64, 0 )); - ("FPR17", (D_increasing, 64, 0 )); - ("FPR18", (D_increasing, 64, 0 )); - ("FPR19", (D_increasing, 64, 0 )); - ("FPR20", (D_increasing, 64, 0 )); - ("FPR21", (D_increasing, 64, 0 )); - ("FPR22", (D_increasing, 64, 0 )); - ("FPR23", (D_increasing, 64, 0 )); - ("FPR24", (D_increasing, 64, 0 )); - ("FPR25", (D_increasing, 64, 0 )); - ("FPR26", (D_increasing, 64, 0 )); - ("FPR27", (D_increasing, 64, 0 )); - ("FPR28", (D_increasing, 64, 0 )); - ("FPR29", (D_increasing, 64, 0 )); - ("FPR30", (D_increasing, 64, 0 )); - ("FPR31", (D_increasing, 64, 0 )); -] - -let initial_stack_and_reg_data_of_PPC_elf_file e_entry all_data_memory = - (* set up initial registers, per 3.4.1 of 64-bit PowerPC ELF Application Binary Interface Supplement 1.9 *) - - let auxiliary_vector_space = Nat_big_num.of_string "17592186042368" (*"0xffffffff800"*) in - (* notionally there should be at least an AT_NULL auxiliary vector entry there, but our examples will never read it *) - - (* take start of stack roughly where running gdb on hello5 on bim says it is*) - let initial_GPR1_stack_pointer = Nat_big_num.of_string "17592186040320" (*"0xffffffff000"*) in - let initial_GPR1_stack_pointer_value = - Sail_impl_base.register_value_of_integer 64 0 Sail_impl_base.D_increasing initial_GPR1_stack_pointer in - (* ELF says we need an initial zero doubleword there *) - let initial_stack_data = - (* the code actually uses the stack, both above and below, so we map a bit more memory*) - (* this is a fairly big but arbitrary chunk *) - (* let initial_stack_data_address = Nat_big_num.sub initial_GPR1_stack_pointer (Nat_big_num.of_int 128) in - [("initial_stack_data", initial_stack_data_address, Lem_list.replicate (128+32) 0 ))] in *) - (* this is the stack memory that test 1938 actually uses *) - [ ("initial_stack_data1", Nat_big_num.sub initial_GPR1_stack_pointer (Nat_big_num.of_int 128), - Lem_list.replicate 8 0 ); - ("initial_stack_data2", Nat_big_num.sub initial_GPR1_stack_pointer (Nat_big_num.of_int 8), - Lem_list.replicate 8 0 ); - ("initial_stack_data3", Nat_big_num.add initial_GPR1_stack_pointer (Nat_big_num.of_int 16), - Lem_list.replicate 8 0 )] in - - (* read TOC from the second field of the function descriptor pointed to by e_entry*) - let initial_GPR2_TOC = - Sail_impl_base.register_value_of_address - (Sail_impl_base.address_of_byte_list - (List.map (fun b -> match b with Some b -> b | None -> failwith "Address had undefined") - (List.map byte_of_byte_lifted - (read_mem all_data_memory - (Nat_big_num.add (Nat_big_num.of_int 8) e_entry) 8)))) - Sail_impl_base.D_increasing in - (* these initial register values are all mandated to be zero, but that's handled by the generic zeroing below - let initial_GPR3_argc = (Nat_big_num.of_int 0) in - let initial_GPR4_argv = (Nat_big_num.of_int 0) in - let initial_GPR5_envp = (Nat_big_num.of_int 0) in - let initial_FPSCR = (Nat_big_num.of_int 0) in - *) - let initial_register_abi_data : (string * Sail_impl_base.register_value) list = - [ ("GPR1", initial_GPR1_stack_pointer_value); - ("GPR2", initial_GPR2_TOC); - (* - ("GPR3", initial_GPR3_argc); - ("GPR4", initial_GPR4_argv); - ("GPR5", initial_GPR5_envp); - ("FPSCR", initial_FPSCR); - *) - ] in - - (initial_stack_data, initial_register_abi_data) - - -let aarch64_reg bit_count name = (name, (D_decreasing, bit_count, bit_count - 1)) - -let aarch64_PC_data = [aarch64_reg 64 "_PC"] - -(* most of the PSTATE fields are aliases to other registers so they - don't appear here *) -let aarch64_PSTATE_data = [ - aarch64_reg 1 "PSTATE_nRW"; - aarch64_reg 1 "PSTATE_E"; - aarch64_reg 5 "PSTATE_M"; -] - -let aarch64_general_purpose_registers_data = [ - aarch64_reg 64 "R0"; - aarch64_reg 64 "R1"; - aarch64_reg 64 "R2"; - aarch64_reg 64 "R3"; - aarch64_reg 64 "R4"; - aarch64_reg 64 "R5"; - aarch64_reg 64 "R6"; - aarch64_reg 64 "R7"; - aarch64_reg 64 "R8"; - aarch64_reg 64 "R9"; - aarch64_reg 64 "R10"; - aarch64_reg 64 "R11"; - aarch64_reg 64 "R12"; - aarch64_reg 64 "R13"; - aarch64_reg 64 "R14"; - aarch64_reg 64 "R15"; - aarch64_reg 64 "R16"; - aarch64_reg 64 "R17"; - aarch64_reg 64 "R18"; - aarch64_reg 64 "R19"; - aarch64_reg 64 "R20"; - aarch64_reg 64 "R21"; - aarch64_reg 64 "R22"; - aarch64_reg 64 "R23"; - aarch64_reg 64 "R24"; - aarch64_reg 64 "R25"; - aarch64_reg 64 "R26"; - aarch64_reg 64 "R27"; - aarch64_reg 64 "R28"; - aarch64_reg 64 "R29"; - aarch64_reg 64 "R30"; -] - -let aarch64_SIMD_registers_data = [ - aarch64_reg 128 "V0"; - aarch64_reg 128 "V1"; - aarch64_reg 128 "V2"; - aarch64_reg 128 "V3"; - aarch64_reg 128 "V4"; - aarch64_reg 128 "V5"; - aarch64_reg 128 "V6"; - aarch64_reg 128 "V7"; - aarch64_reg 128 "V8"; - aarch64_reg 128 "V9"; - aarch64_reg 128 "V10"; - aarch64_reg 128 "V11"; - aarch64_reg 128 "V12"; - aarch64_reg 128 "V13"; - aarch64_reg 128 "V14"; - aarch64_reg 128 "V15"; - aarch64_reg 128 "V16"; - aarch64_reg 128 "V17"; - aarch64_reg 128 "V18"; - aarch64_reg 128 "V19"; - aarch64_reg 128 "V20"; - aarch64_reg 128 "V21"; - aarch64_reg 128 "V22"; - aarch64_reg 128 "V23"; - aarch64_reg 128 "V24"; - aarch64_reg 128 "V25"; - aarch64_reg 128 "V26"; - aarch64_reg 128 "V27"; - aarch64_reg 128 "V28"; - aarch64_reg 128 "V29"; - aarch64_reg 128 "V30"; - aarch64_reg 128 "V31"; -] - -let aarch64_special_purpose_registers_data = [ - aarch64_reg 32 "CurrentEL"; - aarch64_reg 32 "DAIF"; - aarch64_reg 32 "NZCV"; - aarch64_reg 64 "SP_EL0"; - aarch64_reg 64 "SP_EL1"; - aarch64_reg 64 "SP_EL2"; - aarch64_reg 64 "SP_EL3"; - aarch64_reg 32 "SPSel"; - aarch64_reg 32 "SPSR_EL1"; - aarch64_reg 32 "SPSR_EL2"; - aarch64_reg 32 "SPSR_EL3"; - aarch64_reg 64 "ELR_EL1"; - aarch64_reg 64 "ELR_EL2"; - aarch64_reg 64 "ELR_EL3"; -] - -let aarch64_general_system_control_registers_data = [ - aarch64_reg 64 "HCR_EL2"; - aarch64_reg 64 "ID_AA64MMFR0_EL1"; - aarch64_reg 64 "RVBAR_EL1"; - aarch64_reg 64 "RVBAR_EL2"; - aarch64_reg 64 "RVBAR_EL3"; - aarch64_reg 32 "SCR_EL3"; - aarch64_reg 32 "SCTLR_EL1"; - aarch64_reg 32 "SCTLR_EL2"; - aarch64_reg 32 "SCTLR_EL3"; - aarch64_reg 64 "TCR_EL1"; - aarch64_reg 32 "TCR_EL2"; - aarch64_reg 32 "TCR_EL3"; -] - -let aarch64_debug_registers_data = [ - aarch64_reg 32 "DBGPRCR_EL1"; - aarch64_reg 32 "OSDLR_EL1"; -] - -let aarch64_performance_monitors_registers_data = [] -let aarch64_generic_timer_registers_data = [] -let aarch64_generic_interrupt_controller_CPU_interface_registers_data = [] - -let aarch64_external_debug_registers_data = [ - aarch64_reg 32 "EDSCR"; -] - -let aarch32_general_system_control_registers_data = [ - aarch64_reg 32 "SCR"; -] - -let aarch32_debug_registers_data = [ - aarch64_reg 32 "DBGOSDLR"; - aarch64_reg 32 "DBGPRCR"; -] - -let aarch64_register_data_all = - aarch64_PC_data @ - aarch64_PSTATE_data @ - aarch64_general_purpose_registers_data @ - aarch64_SIMD_registers_data @ - aarch64_special_purpose_registers_data @ - aarch64_general_system_control_registers_data @ - aarch64_debug_registers_data @ - aarch64_performance_monitors_registers_data @ - aarch64_generic_timer_registers_data @ - aarch64_generic_interrupt_controller_CPU_interface_registers_data @ - aarch64_external_debug_registers_data @ - aarch32_general_system_control_registers_data @ - aarch32_debug_registers_data - -let initial_stack_and_reg_data_of_AAarch64_elf_file e_entry all_data_memory = - let (reg_SP_EL0_direction, reg_SP_EL0_width, reg_SP_EL0_initial_index) = - List.assoc "SP_EL0" aarch64_register_data_all in - - (* we compiled a small program that prints out SP and run it a few - times on the Nexus9, these are the results: - 0x0000007fe7f903e0 - 0x0000007fdcdbf3f0 - 0x0000007fcbe1ba90 - 0x0000007fcf378280 - 0x0000007fdd54b8d0 - 0x0000007fd961bc10 - 0x0000007ff3be6350 - 0x0000007fd6bf6ef0 - 0x0000007fff7676f0 - 0x0000007ff2c34560 *) - let initial_SP_EL0 = Nat_big_num.of_string "549739036672" (*"0x0000007fff000000"*) in - let initial_SP_EL0_value = - Sail_impl_base.register_value_of_integer - reg_SP_EL0_width - reg_SP_EL0_initial_index - reg_SP_EL0_direction - initial_SP_EL0 - in - - (* ELF says we need an initial zero doubleword there *) - (* the code actually uses the stack, both above and below, so we map a bit more memory*) - let initial_stack_data = - (* this is a fairly big but arbitrary chunk: *) - (* let initial_stack_data_address = Nat_big_num.sub initial_GPR1_stack_pointer (Nat_big_num.of_int 128) in - [("initial_stack_data", initial_stack_data_address, Lem_list.replicate (128+32) 0 ))] in *) - - [ ("initial_stack_data1", Nat_big_num.sub initial_SP_EL0 (Nat_big_num.of_int 16), Lem_list.replicate 8 0); - ("initial_stack_data2", Nat_big_num.sub initial_SP_EL0 (Nat_big_num.of_int 8), Lem_list.replicate 8 0) - ] - in - - let initial_register_abi_data : (string * Sail_impl_base.register_value) list = - [("SP_EL0", initial_SP_EL0_value)] - in - - (initial_stack_data, initial_register_abi_data) -*) let mips_register_data_all = [ (*Pseudo registers*) ("PC", (D_decreasing, 64, 63)); ("branchPending", (D_decreasing, 1, 0)); ("inBranchDelay", (D_decreasing, 1, 0)); + ("inCCallDelay", (D_decreasing, 1, 0)); ("delayedPC", (D_decreasing, 64, 63)); ("nextPC", (D_decreasing, 64, 63)); (* General purpose registers *) @@ -665,7 +311,7 @@ let cheri_register_data_all = mips_register_data_all @ [ let initial_stack_and_reg_data_of_MIPS_elf_file e_entry all_data_memory = let initial_stack_data = [] in - let initial_cap_val_int = Nat_big_num.of_string "0x1fffe0000000800000000000000000000" in (* hex((0x80000 << 64) + (0x7fff << 113) + (1 << 128)) *) + let initial_cap_val_int = Nat_big_num.of_string "0x1fffe6000000100000000000000000000" in (* hex((0x10000 << 64) + (48 << 105) + (0x7fff << 113) + (1 << 128)) T=0x10000 E=48 perms=0x7fff tag=1 *) let initial_cap_val_reg = Sail_impl_base.register_value_of_integer 129 128 D_decreasing initial_cap_val_int in let initial_register_abi_data : (string * Sail_impl_base.register_value) list = [ ("CP0Status", Sail_impl_base.register_value_of_integer 32 31 D_decreasing (Nat_big_num.of_string "0x00400000")); @@ -748,50 +394,6 @@ let initial_system_state_of_elf_file name = let (isa_defs, isa_memory_access, isa_externs, isa_model, model_reg_d, startaddr, initial_stack_data, initial_register_abi_data, register_data_all) = match Nat_big_num.to_int e_machine with -(* | 21 (* EM_PPC64 *) -> - let startaddr = - let e_entry = Uint64.of_int64 (Nat_big_num.to_int64 e_entry) in - match Abi_power64.abi_power64_compute_program_entry_point segments e_entry with - | Error.Fail s -> failwith "Failed computing entry point" - | Error.Success s -> Nat_big_num.of_int64 (Uint64.to_int64 s) - in - let (initial_stack_data, initial_register_abi_data) = - initial_stack_and_reg_data_of_PPC_elf_file e_entry !data_mem in - - (Power.defs, - (Power_extras.read_memory_functions,Power_extras.memory_writes,[],[],Power_extras.barrier_functions), - Power_extras.power_externs, - PPC, - D_increasing, - startaddr, - initial_stack_data, - initial_register_abi_data, - ppc_register_data_all) - - | 183 (* EM_AARCH64 *) -> - let startaddr = - let e_entry = Uint64.of_int64 (Nat_big_num.to_int64 e_entry) in - match Abi_aarch64_le.abi_aarch64_le_compute_program_entry_point segments e_entry with - | Error.Fail s -> failwith "Failed computing entry point" - | Error.Success s -> Nat_big_num.of_int64 (Uint64.to_int64 s) - in - - let (initial_stack_data, initial_register_abi_data) = - initial_stack_and_reg_data_of_AAarch64_elf_file e_entry !data_mem in - - (ArmV8.defs, - (ArmV8_extras.aArch64_read_memory_functions, - ArmV8_extras.aArch64_memory_writes, - ArmV8_extras.aArch64_memory_eas, - ArmV8_extras.aArch64_memory_vals, - ArmV8_extras.aArch64_barrier_functions), - [], - AArch64, - D_decreasing, - startaddr, - initial_stack_data, - initial_register_abi_data, - aarch64_register_data_all) *) | 8 (* EM_MIPS *) -> let startaddr = let e_entry = Uint64.of_string (Nat_big_num.to_string e_entry) in @@ -887,52 +489,6 @@ let initial_system_state_of_elf_file name = List.map (fun (name, (binding, fp)) -> (fp, name)) (StringMap.bindings map) in - - (* Now we examine the rest of the data memory, - removing the footprint of the symbols and chunking it into aligned chunks *) - - let rec remove_symbols_from_data_memory data_mem symbols = - match symbols with - | [] -> data_mem - | (name,address,size,bs)::symbols' -> - let data_mem' = - Mem.filter - (fun a v -> - not (Nat_big_num.greater_equal a address && - Nat_big_num.less a (Nat_big_num.add (Nat_big_num.of_int (List.length bs)) address))) - data_mem in - remove_symbols_from_data_memory data_mem' symbols' in - - let trimmed_data_memory : (Nat_big_num.num * memory_byte) list = - Mem.bindings (remove_symbols_from_data_memory !data_mem symbol_table) in - - (* make sure that's ordered increasingly.... *) - let trimmed_data_memory = - List.sort (fun (a,b) (a',b') -> Nat_big_num.compare a a') trimmed_data_memory in - - let aligned a n = (* a mod n = 0 *) - let n_big = Nat_big_num.of_int n in - Nat_big_num.equal (Nat_big_num.modulus a n_big) ((Nat_big_num.of_int 0)) in - - let isplus a' a n = (* a' = a+n *) - Nat_big_num.equal a' (Nat_big_num.add (Nat_big_num.of_int n) a) in - - let rec chunk_data_memory dm = - match dm with - | (a0,b0)::(a1,b1)::(a2,b2)::(a3,b3)::(a4,b4)::(a5,b5)::(a6,b6)::(a7,b7)::dm' when - (aligned a0 8 && isplus a1 a0 1 && isplus a2 a0 2 && isplus a3 a0 3 && - isplus a4 a0 4 && isplus a5 a0 5 && isplus a6 a0 6 && isplus a7 a0 7) -> - (a0,8,[b0;b1;b2;b3;b4;b5;b6;b7]) :: chunk_data_memory dm' - | (a0,b0)::(a1,b1)::(a2,b2)::(a3,b3)::dm' when - (aligned a0 4 && isplus a1 a0 1 && isplus a2 a0 2 && isplus a3 a0 3) -> - (a0,4,[b0;b1;b2;b3]) :: chunk_data_memory dm' - | (a0,b0)::(a1,b1)::dm' when - (aligned a0 2 && isplus a1 a0 1) -> - (a0,2,[b0;b1]) :: chunk_data_memory dm' - | (a0,b0)::dm' -> - (a0,1,[b0]):: chunk_data_memory dm' - | [] -> [] in - let initial_register_state = fun rbn -> try @@ -1021,68 +577,10 @@ let stop_condition_met model instr = true | _ -> false) -let is_branch model instruction = - let (name,_,_) = instruction in - match (model , name) with - | (PPC, "B") -> true - | (PPC, "Bc") -> true - | (PPC, "Bclr") -> true - | (PPC, "Bcctr") -> true - | (PPC, _) -> false - | (AArch64, "BranchImmediate") -> true - | (AArch64, "BranchConditional") -> true - | (AArch64, "CompareAndBranch") -> true - | (AArch64, "TestBitAndBranch") -> true - | (AArch64, "BranchRegister") -> true - | (AArch64, _) -> false - | (MIPS, _) -> false (*todo,fill this in*) - let option_int_of_option_integer i = match i with | Some i -> Some (Nat_big_num.to_int i) | None -> None -let set_next_instruction_address model = - match model with - | PPC -> - let cia = Reg.find "CIA" !reg in - let cia_addr = address_of_register_value cia in - (match cia_addr with - | Some cia_addr -> - let nia_addr = add_address_nat cia_addr 4 in - let nia = register_value_of_address nia_addr Sail_impl_base.D_increasing in - reg := Reg.add "NIA" nia !reg - | _ -> failwith "CIA address contains unknown or undefined") - | AArch64 -> - let pc = Reg.find "_PC" !reg in - let pc_addr = address_of_register_value pc in - (match pc_addr with - | Some pc_addr -> - let n_addr = add_address_nat pc_addr 4 in - let n_pc = register_value_of_address n_addr D_decreasing in - reg := Reg.add "_PC" n_pc !reg - | _ -> failwith "_PC address contains unknown or undefined") - | MIPS -> - let pc_addr = address_of_register_value (Reg.find "PC" !reg) in - let branchPending = integer_of_register_value (Reg.find "branchPending" !reg) in - (match (pc_addr, option_int_of_option_integer branchPending) with - | (Some pc_val, Some 0) -> - (* normal -- increment PC *) - let n_addr = add_address_nat pc_val 4 in - let n_pc = register_value_of_address n_addr D_decreasing in - begin - reg := Reg.add "nextPC" n_pc !reg; - reg := Reg.add "inBranchDelay" (register_value_of_integer 1 0 Sail_impl_base.D_decreasing Nat_big_num.zero) !reg; - end - | (Some pc_val, Some 1) -> - (* delay slot -- branch to delayed PC and clear branchPending *) - begin - reg := Reg.add "nextPC" (Reg.find "delayedPC" !reg) !reg; - reg := Reg.add "nextPCC" (Reg.find "delayedPCC" !reg) !reg; - reg := Reg.add "branchPending" (register_value_of_integer 1 0 Sail_impl_base.D_decreasing Nat_big_num.zero) !reg; - reg := Reg.add "inBranchDelay" (register_value_of_integer 1 0 Sail_impl_base.D_decreasing (Nat_big_num.of_int 1)) !reg; - end - | (_, _) -> errorf "PC address contains unknown or undefined"; exit 1) - let add1 = Nat_big_num.add (Nat_big_num.of_int 1) let get_addr_trans_regs _ = @@ -1192,68 +690,10 @@ let rec write_events = function | _ -> failwith "Only register write events expected"); write_events events -let fetch_instruction_opcode_and_update_ia model addr_trans = - match model with - | PPC -> - let cia = Reg.find "CIA" !reg in - let cia_addr = address_of_register_value cia in - (match cia_addr with - | Some cia_addr -> - let cia_a = integer_of_address cia_addr in - let opcode = (get_opcode cia_a) in - begin - reg := Reg.add "CIA" (Reg.find "NIA" !reg) !reg; - Opcode opcode - end - | None -> failwith "CIA address contains unknown or undefined") - | AArch64 -> - let pc = Reg.find "_PC" !reg in - let pc_addr = address_of_register_value pc in - (match pc_addr with - | Some pc_addr -> - let pc_a = integer_of_address pc_addr in - let opcode = (get_opcode pc_a) in - Opcode opcode - | None -> failwith "_PC address contains unknown or undefined") - | MIPS -> - begin - reg := Reg.add "PCC" (Reg.find "nextPCC" !reg) !reg; - let nextPC = Reg.find "nextPC" !reg in - let pc_addr = address_of_register_value nextPC in - (*let unused = interactf "PC: %s\n" (Printing_functions.register_value_to_string nextPC) in*) - (match pc_addr with - | Some pc_addr -> - let pc_a = match addr_trans (get_addr_trans_regs ()) pc_addr with - | Some a, Some events -> write_events (List.rev events); integer_of_address a - | Some a, None -> integer_of_address a - | None, Some events -> - write_events (List.rev events); - let nextPC = Reg.find "nextPC" !reg in - reg := Reg.add "PCC" (Reg.find "nextPCC" !reg) !reg; - let pc_addr = address_of_register_value nextPC in - (match pc_addr with - | Some pc_addr -> - (match addr_trans (get_addr_trans_regs ()) pc_addr with - | Some a, Some events -> write_events (List.rev events); integer_of_address a - | Some a, None -> integer_of_address a - | None, _ -> failwith "Address translation failed twice") - | None -> failwith "no nextPc address") - | _ -> failwith "No address and no events from translate address" - in - let opcode = (get_opcode pc_a) in - begin - reg := Reg.add "PC" (Reg.find "nextPC" !reg) !reg; - Opcode opcode - end - | None -> errorf "nextPC contains unknown or undefined"; exit 1) - end - | _ -> assert false - let get_pc_address = function | MIPS -> Reg.find "PC" !reg | PPC -> Reg.find "CIA" !reg | AArch64 -> Reg.find "_PC" !reg - let option_int_of_reg str = option_int_of_option_integer (integer_of_register_value (Reg.find str !reg)) @@ -1283,6 +723,7 @@ let rec fde_loop count context model mode track_dependencies addr_trans = let npc_addr = add_address_nat pc_val 4 in let npc_reg = register_value_of_address npc_addr Sail_impl_base.D_decreasing in reg := Reg.add "nextPC" npc_reg !reg; + reg := Reg.add "inCCallDelay" (register_value_of_integer 1 0 Sail_impl_base.D_decreasing Nat_big_num.zero) !reg; | Some 1 -> reg := Reg.add "nextPC" (Reg.find "delayedPC" !reg) !reg; reg := Reg.add "nextPCC" (Reg.find "delayedPCC" !reg) !reg; @@ -1290,12 +731,14 @@ let rec fde_loop count context model mode track_dependencies addr_trans = let opcode = Opcode (get_opcode pc) in let (instruction,istate) = match Interp_inter_imp.decode_to_istate context None opcode with | Instr(instruction,istate) -> + let instruction = interp_value_to_instr_external context instruction in interactf "\n**** Running: %s ****\n" (Printing_functions.instruction_to_string instruction); (instruction,istate) | Decode_error d -> (match d with - | Interp_interface.Unsupported_instruction_error instr -> - errorf "\n**** Encountered unsupported instruction %s ****\n" (Printing_functions.instruction_to_string instr) + | Interp_interface.Unsupported_instruction_error instruction -> + let instruction = interp_value_to_instr_external context instruction in + errorf "\n**** Encountered unsupported instruction %s ****\n" (Printing_functions.instruction_to_string instruction) | Interp_interface.Not_an_instruction_error op -> (match op with | Opcode bytes -> diff --git a/src/lem_interp/sail_impl_base.lem b/src/lem_interp/sail_impl_base.lem index c7c6cd20..421219da 100644 --- a/src/lem_interp/sail_impl_base.lem +++ b/src/lem_interp/sail_impl_base.lem @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -42,6 +50,29 @@ open import Pervasives_extra + + +class ( EnumerationType 'a ) + val toNat : 'a -> nat +end + + +val enumeration_typeCompare : forall 'a. EnumerationType 'a => 'a -> 'a -> ordering +let ~{ocaml} enumeration_typeCompare e1 e2 = + compare (toNat e1) (toNat e2) +let inline {ocaml} enumeration_typeCompare = defaultCompare + + +default_instance forall 'a. EnumerationType 'a => (Ord 'a) + let compare = enumeration_typeCompare + let (<) r1 r2 = (enumeration_typeCompare r1 r2) = LT + let (<=) r1 r2 = (enumeration_typeCompare r1 r2) <> GT + let (>) r1 r2 = (enumeration_typeCompare r1 r2) = GT + let (>=) r1 r2 = (enumeration_typeCompare r1 r2) <> LT +end + + + (* maybe isn't a member of type Ord - this should be in the Lem standard library*) instance forall 'a. Ord 'a => (Ord (maybe 'a)) let compare = maybeCompare compare @@ -214,6 +245,28 @@ instance (Ord byte) let (>=) = byteGreaterEq end +let ~{ocaml} opcodeCompare (Opcode o1) (Opcode o2) = + compare o1 o2 +let {ocaml} opcodeCompare = defaultCompare + +let ~{ocaml} opcodeLess b1 b2 = opcodeCompare b1 b2 = LT +let ~{ocaml} opcodeLessEq b1 b2 = opcodeCompare b1 b2 <> GT +let ~{ocaml} opcodeGreater b1 b2 = opcodeCompare b1 b2 = GT +let ~{ocaml} opcodeGreaterEq b1 b2 = opcodeCompare b1 b2 <> LT + +let inline {ocaml} opcodeLess = defaultLess +let inline {ocaml} opcodeLessEq = defaultLessEq +let inline {ocaml} opcodeGreater = defaultGreater +let inline {ocaml} opcodeGreaterEq = defaultGreaterEq + +instance (Ord opcode) + let compare = opcodeCompare + let (<) = opcodeLess + let (<=) = opcodeLessEq + let (>) = opcodeGreater + let (>=) = opcodeGreaterEq +end + let addressCompare (Address b1 i1) (Address b2 i2) = compare i1 i2 (* this cannot be defaultCompare for OCaml because addresses contain big ints *) @@ -419,6 +472,8 @@ end (* Data structures for building up instructions *) +(* careful: changes in the read/write/barrier kinds have to be + reflected in deep_shallow_convert *) type read_kind = (* common reads *) | Read_plain @@ -426,6 +481,12 @@ type read_kind = | Read_reserve (* AArch64 reads *) | Read_acquire | Read_exclusive | Read_exclusive_acquire | Read_stream + (* RISC-V reads *) + | Read_RISCV_acquire | Read_RISCV_strong_acquire + | Read_RISCV_reserved | Read_RISCV_reserved_acquire + | Read_RISCV_reserved_strong_acquire + (* x86 reads *) + | Read_X86_locked (* the read part of a lock'd instruction (rmw) *) instance (Show read_kind) let show = function @@ -435,6 +496,12 @@ instance (Show read_kind) | Read_exclusive -> "Read_exclusive" | Read_exclusive_acquire -> "Read_exclusive_acquire" | Read_stream -> "Read_stream" + | Read_RISCV_acquire -> "Read_RISCV_acquire" + | Read_RISCV_strong_acquire -> "Read_RISCV_strong_acquire" + | Read_RISCV_reserved -> "Read_RISCV_reserved" + | Read_RISCV_reserved_acquire -> "Read_RISCV_reserved_acquire" + | Read_RISCV_reserved_strong_acquire -> "Read_RISCV_reserved_strong_acquire" + | Read_X86_locked -> "Read_X86_locked" end end @@ -445,6 +512,12 @@ type write_kind = | Write_conditional (* AArch64 writes *) | Write_release | Write_exclusive | Write_exclusive_release + (* RISC-V *) + | Write_RISCV_release | Write_RISCV_strong_release + | Write_RISCV_conditional | Write_RISCV_conditional_release + | Write_RISCV_conditional_strong_release + (* x86 writes *) + | Write_X86_locked (* the write part of a lock'd instruction (rmw) *) instance (Show write_kind) let show = function @@ -453,6 +526,12 @@ instance (Show write_kind) | Write_release -> "Write_release" | Write_exclusive -> "Write_exclusive" | Write_exclusive_release -> "Write_exclusive_release" + | Write_RISCV_release -> "Write_RISCV_release" + | Write_RISCV_strong_release -> "Write_RISCV_strong_release" + | Write_RISCV_conditional -> "Write_RISCV_conditional" + | Write_RISCV_conditional_release -> "Write_RISCV_conditional_release" + | Write_RISCV_conditional_strong_release -> "Write_RISCV_conditional_strong_release" + | Write_X86_locked -> "Write_X86_locked" end end @@ -468,7 +547,12 @@ type barrier_kind = (* RISC-V barriers *) | Barrier_RISCV_rw_rw | Barrier_RISCV_r_rw + | Barrier_RISCV_r_r | Barrier_RISCV_rw_w + | Barrier_RISCV_w_w + | Barrier_RISCV_i + (* X86 *) + | Barrier_x86_MFENCE instance (Show barrier_kind) @@ -486,6 +570,13 @@ instance (Show barrier_kind) | Barrier_ISB -> "Barrier_ISB" | Barrier_TM_COMMIT -> "Barrier_TM_COMMIT" | Barrier_MIPS_SYNC -> "Barrier_MIPS_SYNC" + | Barrier_RISCV_rw_rw -> "Barrier_RISCV_rw_rw" + | Barrier_RISCV_r_rw -> "Barrier_RISCV_r_rw" + | Barrier_RISCV_r_r -> "Barrier_RISCV_r_r" + | Barrier_RISCV_rw_w -> "Barrier_RISCV_rw_w" + | Barrier_RISCV_w_w -> "Barrier_RISCV_w_w" + | Barrier_RISCV_i -> "Barrier_RISCV_i" + | Barrier_x86_MFENCE -> "Barrier_x86_MFENCE" end end @@ -502,15 +593,15 @@ instance (Show trans_kind) end type instruction_kind = - | IK_barrier of barrier_kind - | IK_mem_read of read_kind + | IK_barrier of barrier_kind + | IK_mem_read of read_kind | IK_mem_write of write_kind -(* SS reinstating cond_branches -at present branches are not distinguished in the instruction_kind; -they just have particular nias (and will be IK_simple *) - | IK_cond_branch -(* | IK_uncond_branch *) - | IK_trans of trans_kind + | IK_mem_rmw of (read_kind * write_kind) + | IK_cond_branch + (* unconditional branches are not distinguished in the instruction_kind; + they just have particular nias (and will be IK_simple *) + (* | IK_uncond_branch *) + | IK_trans of trans_kind | IK_simple @@ -658,6 +749,13 @@ let ~{ocaml} barrier_number = function | Barrier_ISB -> 10 | Barrier_TM_COMMIT -> 11 | Barrier_MIPS_SYNC -> 12 + | Barrier_RISCV_rw_rw -> 13 + | Barrier_RISCV_r_rw -> 14 + | Barrier_RISCV_r_r -> 15 + | Barrier_RISCV_rw_w -> 16 + | Barrier_RISCV_w_w -> 17 + | Barrier_RISCV_i -> 18 + | Barrier_x86_MFENCE -> 19 end let ~{ocaml} barrier_kindCompare bk1 bk2 = @@ -742,21 +840,20 @@ instance (Ord barrier_kind) let (>=) = barrier_kindGreaterEq end - type event = -| E_read_mem of read_kind * address_lifted * nat * maybe (list reg_name) -| E_read_memt of read_kind * address_lifted * nat * maybe (list reg_name) -| E_write_mem of write_kind * address_lifted * nat * maybe (list reg_name) * memory_value * maybe (list reg_name) -| E_write_ea of write_kind * address_lifted * nat * maybe (list reg_name) -| E_excl_res -| E_write_memv of maybe address_lifted * memory_value * maybe (list reg_name) -| E_write_memvt of maybe address_lifted * (bit_lifted * memory_value) * maybe (list reg_name) -| E_barrier of barrier_kind -| E_footprint -| E_read_reg of reg_name -| E_write_reg of reg_name * register_value -| E_escape -| E_error of string + | E_read_mem of read_kind * address_lifted * nat * maybe (list reg_name) + | E_read_memt of read_kind * address_lifted * nat * maybe (list reg_name) + | E_write_mem of write_kind * address_lifted * nat * maybe (list reg_name) * memory_value * maybe (list reg_name) + | E_write_ea of write_kind * address_lifted * nat * maybe (list reg_name) + | E_excl_res + | E_write_memv of maybe address_lifted * memory_value * maybe (list reg_name) + | E_write_memvt of maybe address_lifted * (bit_lifted * memory_value) * maybe (list reg_name) + | E_barrier of barrier_kind + | E_footprint + | E_read_reg of reg_name + | E_write_reg of reg_name * register_value + | E_escape + | E_error of string let eventCompare e1 e2 = diff --git a/src/lexer.mll b/src/lexer.mll index 3b1a1583..35ab6627 100644 --- a/src/lexer.mll +++ b/src/lexer.mll @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -157,7 +165,7 @@ let binarydigit = ['0'-'1'] let hexdigit = ['0'-'9''A'-'F''a'-'f'] let alphanum = letter|digit let startident = letter|'_' -let ident = alphanum|['_''\''] +let ident = alphanum|['_''\'''#'] let tyvar_start = '\'' let oper_char = ['!''$''%''&''*''+''-''.''/'':''<''=''>''?''@''^''|''~'] let escape_sequence = ('\\' ['\\''\"''\'''n''t''b''r']) | ('\\' digit digit digit) | ('\\' 'x' hexdigit hexdigit) diff --git a/src/lexer2.mll b/src/lexer2.mll index 40e7eec6..e43bd3e1 100644 --- a/src/lexer2.mll +++ b/src/lexer2.mll @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -121,6 +129,7 @@ let kw_table = ("in", (fun x -> In)); ("inc", (fun _ -> Inc)); ("let", (fun x -> Let_)); + ("record", (fun _ -> Record)); ("Int", (fun x -> Int)); ("Order", (fun x -> Order)); ("pure", (fun x -> Pure)); @@ -142,6 +151,7 @@ let kw_table = ("until", (fun _ -> Until)); ("while", (fun _ -> While)); ("do", (fun _ -> Do)); + ("mutual", (fun _ -> Mutual)); ("barr", (fun x -> Barr)); ("depend", (fun x -> Depend)); @@ -169,7 +179,7 @@ let binarydigit = ['0'-'1'] let hexdigit = ['0'-'9''A'-'F''a'-'f'] let alphanum = letter|digit let startident = letter|'_' -let ident = alphanum|['_''\''] +let ident = alphanum|['_''\'''#'] let tyvar_start = '\'' let oper_char = ['!''$''%''&''*''+''-''.''/'':''<''=''>''@''^''|'] let operator = (oper_char+ ('_' ident)?) @@ -200,6 +210,8 @@ rule token = parse | ";" { Semi } | "*" { (Star(r"*")) } | "_" { Under } + | "[|" { LsquareBar } + | "|]" { RsquareBar } | "{|" { LcurlyBar } | "|}" { RcurlyBar } | "|" { Bar } diff --git a/src/monomorphise.ml b/src/monomorphise.ml index 7774e110..6350f511 100644 --- a/src/monomorphise.ml +++ b/src/monomorphise.ml @@ -1,3 +1,53 @@ +(**************************************************************************) +(* Sail *) +(* *) +(* Copyright (c) 2013-2017 *) +(* 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 *) +(* *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(**************************************************************************) + open Parse_ast open Ast open Ast_util diff --git a/src/myocamlbuild.ml b/src/myocamlbuild.ml index 697ee9bd..a437e7e6 100644 --- a/src/myocamlbuild.ml +++ b/src/myocamlbuild.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/ocaml_backend.ml b/src/ocaml_backend.ml index bf5ce83c..6254d580 100644 --- a/src/ocaml_backend.ml +++ b/src/ocaml_backend.ml @@ -1,3 +1,53 @@ +(**************************************************************************) +(* Sail *) +(* *) +(* Copyright (c) 2013-2017 *) +(* 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 *) +(* *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(**************************************************************************) + open Ast open Ast_util open PPrint @@ -91,6 +141,7 @@ let ocaml_typ_id ctx = function | id when Id.compare id (mk_id "bool") = 0 -> string "bool" | id when Id.compare id (mk_id "unit") = 0 -> string "unit" | id when Id.compare id (mk_id "real") = 0 -> string "Num.num" + | id when Id.compare id (mk_id "exception") = 0 -> string "exn" | id when Id.compare id (mk_id "register") = 0 -> string "ref" | id -> zencode ctx id @@ -179,6 +230,7 @@ let rec ocaml_exp ctx (E_aux (exp_aux, _) as exp) = | E_block exps -> begin_end (ocaml_block ctx exps) | E_field (exp, id) -> ocaml_atomic_exp ctx exp ^^ dot ^^ zencode ctx id | E_exit exp -> string "exit 0" + | E_throw exp -> string "raise" ^^ space ^^ ocaml_atomic_exp ctx exp | E_case (exp, pexps) -> begin_end (separate space [string "match"; ocaml_atomic_exp ctx exp; string "with"] ^/^ ocaml_pexps ctx pexps) @@ -197,7 +249,7 @@ let rec ocaml_exp ctx (E_aux (exp_aux, _) as exp) = ^/^ ocaml_exp ctx exp | E_internal_let (lexp, exp1, exp2) -> separate space [string "let"; ocaml_atomic_lexp ctx lexp; - equals; string "ref"; parens (ocaml_atomic_exp ctx exp1 ^^ space ^^ colon ^^ space ^^ ocaml_typ ctx (Rewriter.simple_typ (typ_of exp1))); string "in"] + equals; string "ref"; parens (ocaml_atomic_exp ctx exp1 ^^ space ^^ colon ^^ space ^^ ocaml_typ ctx (Rewrites.simple_typ (typ_of exp1))); string "in"] ^/^ ocaml_exp ctx exp2 | E_loop (Until, cond, body) -> let loop_body = @@ -274,7 +326,7 @@ and ocaml_atomic_exp ctx (E_aux (exp_aux, _) as exp) = | Register typ -> if !opt_trace_ocaml then let var = gensym () in - let str_typ = parens (ocaml_string_typ (Rewriter.simple_typ typ) var) in + let str_typ = parens (ocaml_string_typ (Rewrites.simple_typ typ) var) in parens (separate space [string "let"; var; equals; bang ^^ zencode ctx id; string "in"; string "trace_read" ^^ space ^^ string_lit (string_of_id id) ^^ space ^^ str_typ ^^ semi; var]) else bang ^^ zencode ctx id @@ -293,7 +345,7 @@ and ocaml_assignment ctx (LEXP_aux (lexp_aux, _) as lexp) exp = let traced_exp = if !opt_trace_ocaml then let var = gensym () in - let str_typ = parens (ocaml_string_typ (Rewriter.simple_typ typ) var) in + let str_typ = parens (ocaml_string_typ (Rewrites.simple_typ typ) var) in parens (separate space [string "let"; var; equals; ocaml_atomic_exp ctx exp; string "in"; string "trace_write" ^^ space ^^ string_lit (string_of_id id) ^^ space ^^ str_typ ^^ semi; var]) else ocaml_atomic_exp ctx exp @@ -437,6 +489,17 @@ let rec ocaml_cases ctx = | tu :: tus -> ocaml_case tu ^/^ ocaml_cases ctx tus | [] -> empty +let rec ocaml_exceptions ctx = + let ocaml_exception = function + | Tu_aux (Tu_id id, _) -> separate space [string "exception"; zencode_upper ctx id] + | Tu_aux (Tu_ty_id (typ, id), _) -> + separate space [string "exception"; zencode_upper ctx id; string "of"; ocaml_typ ctx typ] + in + function + | [tu] -> ocaml_exception tu + | tu :: tus -> ocaml_exception tu ^^ string ";;" ^^ hardline ^^ ocaml_exceptions ctx tus + | [] -> empty + let rec ocaml_enum ctx = function | [id] -> zencode_upper ctx id | id :: ids -> zencode_upper ctx id ^/^ (bar ^^ space ^^ ocaml_enum ctx ids) @@ -474,6 +537,8 @@ let ocaml_typedef ctx (TD_aux (td_aux, _)) = ^/^ rbrace) ^^ ocaml_def_end ^^ ocaml_string_of_struct ctx id typq fields + | TD_variant (id, _, _, cases, _) when string_of_id id = "exception" -> + ocaml_exceptions ctx cases | TD_variant (id, _, typq, cases, _) -> separate space [string "type"; ocaml_typquant typq; zencode ctx id; equals] ^//^ ocaml_cases ctx cases diff --git a/src/parse_ast.ml b/src/parse_ast.ml index bdf56cc8..705c7ff4 100644 --- a/src/parse_ast.ml +++ b/src/parse_ast.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -275,7 +283,7 @@ exp_aux = (* Expression *) | E_vector_append of exp * exp (* vector concatenation *) | E_list of (exp) list (* list *) | E_cons of exp * exp (* cons *) - | E_record of fexps (* struct *) + | E_record of exp list (* struct *) | E_record_update of exp * (exp) list (* functional update of struct *) | E_field of exp * id (* field projection from struct *) | E_case of exp * (pexp) list (* pattern matching *) @@ -498,6 +506,7 @@ def = (* Top-level definition *) | DEF_default of default_typing_spec (* default kind and type assumptions *) | DEF_scattered of scattered_def (* scattered definition *) | DEF_reg_dec of dec_spec (* register declaration *) + | DEF_internal_mutrec of fundef list type diff --git a/src/parser.mly b/src/parser.mly index 2cfa8e80..58f5f1e1 100644 --- a/src/parser.mly +++ b/src/parser.mly @@ -9,6 +9,14 @@ /* Robert Norton-Wright */ /* Christopher Pulte */ /* Peter Sewell */ +/* Alasdair Armstrong */ +/* Brian Campbell */ +/* Thomas Bauereiss */ +/* Anthony Fox */ +/* Jon French */ +/* Dominic Mulligan */ +/* Stephen Kell */ +/* Mark Wassell */ /* */ /* All rights reserved. */ /* */ diff --git a/src/parser2.mly b/src/parser2.mly index a752e5c1..21959cf5 100644 --- a/src/parser2.mly +++ b/src/parser2.mly @@ -9,6 +9,14 @@ /* Robert Norton-Wright */ /* Christopher Pulte */ /* Peter Sewell */ +/* Alasdair Armstrong */ +/* Brian Campbell */ +/* Thomas Bauereiss */ +/* Anthony Fox */ +/* Jon French */ +/* Dominic Mulligan */ +/* Stephen Kell */ +/* Mark Wassell */ /* */ /* All rights reserved. */ /* */ @@ -142,13 +150,13 @@ let rec desugar_rchain chain s e = %token Pure Register Return Scattered Sizeof Struct Then True TwoCaret TYPE Typedef %token Undefined Union With Val Constraint Throw Try Catch Exit %token Barr Depend Rreg Wreg Rmem Rmemt Wmem Wmv Wmvt Eamem Exmem Undef Unspec Nondet Escape -%token Repeat Until While Do +%token Repeat Until While Do Record Mutual %nonassoc Then %nonassoc Else %token Bar Comma Dot Eof Minus Semi Under DotDot -%token Lcurly Rcurly Lparen Rparen Lsquare Rsquare LcurlyBar RcurlyBar +%token Lcurly Rcurly Lparen Rparen Lsquare Rsquare LcurlyBar RcurlyBar LsquareBar RsquareBar %token MinusGt /*Terminals with content*/ @@ -957,17 +965,33 @@ atomic_exp: { mk_exp (E_vector_access ($1, $3)) $startpos $endpos } | atomic_exp Lsquare exp DotDot exp Rsquare { mk_exp (E_vector_subrange ($1, $3, $5)) $startpos $endpos } + | Record Lcurly fexp_exp_list Rcurly + { mk_exp (E_record $3) $startpos $endpos } + | Lcurly exp With fexp_exp_list Rcurly + { mk_exp (E_record_update ($2, $4)) $startpos $endpos } | Lsquare exp_list Rsquare { mk_exp (E_vector $2) $startpos $endpos } | Lsquare exp With atomic_exp Eq exp Rsquare { mk_exp (E_vector_update ($2, $4, $6)) $startpos $endpos } | Lsquare exp With atomic_exp DotDot atomic_exp Eq exp Rsquare { mk_exp (E_vector_update_subrange ($2, $4, $6, $8)) $startpos $endpos } + | LsquareBar exp_list RsquareBar + { mk_exp (E_list $2) $startpos $endpos } | Lparen exp Rparen { $2 } | Lparen exp Comma exp_list Rparen { mk_exp (E_tuple ($2 :: $4)) $startpos $endpos } +fexp_exp: + | atomic_exp Eq exp + { mk_exp (E_app_infix ($1, mk_id (Id "=") $startpos($2) $endpos($2), $3)) $startpos $endpos } + +fexp_exp_list: + | fexp_exp + { [$1] } + | fexp_exp Comma fexp_exp_list + { $1 :: $3 } + exp_list: | exp { [$1] } @@ -997,6 +1021,8 @@ type_def: { mk_td (TD_enum ($2, mk_namesectn, $4, false)) $startpos $endpos } | Enum id Eq Lcurly enum Rcurly { mk_td (TD_enum ($2, mk_namesectn, $5, false)) $startpos $endpos } + | Union id Eq Lcurly type_unions Rcurly + { mk_td (TD_variant ($2, mk_namesectn, TypQ_aux (TypQ_tq [], loc $endpos($2) $startpos($3)), $5, false)) $startpos $endpos } | Union id typquant Eq Lcurly type_unions Rcurly { mk_td (TD_variant ($2, mk_namesectn, $3, $6, false)) $startpos $endpos } @@ -1042,6 +1068,12 @@ fun_def: | Function_ funcls { mk_fun (FD_function (mk_recn, mk_tannotn, mk_eannotn, $2)) $startpos $endpos } +fun_def_list: + | fun_def + { [$1] } + | fun_def fun_def_list + { $1 :: $2 } + let_def: | Let_ letbind { $2 } @@ -1115,6 +1147,8 @@ def: { DEF_scattered (mk_sd (SD_scattered_end $2) $startpos $endpos) } | default_def { DEF_default $1 } + | Mutual Lcurly fun_def_list Rcurly + { DEF_internal_mutrec $3 } defs_list: | def @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/pre_lexer.mll b/src/pre_lexer.mll index f648a594..3c308b99 100644 --- a/src/pre_lexer.mll +++ b/src/pre_lexer.mll @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -118,7 +126,7 @@ let binarydigit = ['0'-'1'] let hexdigit = ['0'-'9''A'-'F''a'-'f'] let alphanum = letter|digit let startident = letter|'_' -let ident = alphanum|['_''\''] +let ident = alphanum|['_''\'''#'] let tyvar_start = '\'' let oper_char = ['!''$''%''&''*''+''-''.''/'':''<''=''>''?''@''^''|''~'] let escape_sequence = ('\\' ['\\''\"''\'''n''t''b''r']) | ('\\' digit digit digit) | ('\\' 'x' hexdigit hexdigit) diff --git a/src/pre_parser.mly b/src/pre_parser.mly index b595d55d..0b4833a1 100644 --- a/src/pre_parser.mly +++ b/src/pre_parser.mly @@ -9,6 +9,14 @@ /* Robert Norton-Wright */ /* Christopher Pulte */ /* Peter Sewell */ +/* Alasdair Armstrong */ +/* Brian Campbell */ +/* Thomas Bauereiss */ +/* Anthony Fox */ +/* Jon French */ +/* Dominic Mulligan */ +/* Stephen Kell */ +/* Mark Wassell */ /* */ /* All rights reserved. */ /* */ diff --git a/src/pretty_print.ml b/src/pretty_print.ml index f778fe08..8047ff32 100644 --- a/src/pretty_print.ml +++ b/src/pretty_print.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/pretty_print.mli b/src/pretty_print.mli index b878d29e..d411815f 100644 --- a/src/pretty_print.mli +++ b/src/pretty_print.mli @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/pretty_print_common.ml b/src/pretty_print_common.ml index 315772a4..bad03034 100644 --- a/src/pretty_print_common.ml +++ b/src/pretty_print_common.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/pretty_print_lem.ml b/src/pretty_print_lem.ml index f5f58d14..7ced47ee 100644 --- a/src/pretty_print_lem.ml +++ b/src/pretty_print_lem.ml @@ -9,7 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) (* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -1192,7 +1199,6 @@ let doc_typdef_lem sequential mwords (TD_aux(td, (l, annot))) = match td with break 0 ^^ brackets (align doc_rids)])) | _ -> raise (Reporting_basic.err_unreachable l "register with non-constant indices") - let doc_rec_lem (Rec_aux(r,_)) = match r with | Rec_nonrec -> space | Rec_rec -> space ^^ string "rec" ^^ space diff --git a/src/pretty_print_lem_ast.ml b/src/pretty_print_lem_ast.ml index 4cb7bef2..020b8dbd 100644 --- a/src/pretty_print_lem_ast.ml +++ b/src/pretty_print_lem_ast.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -74,7 +82,7 @@ let lemnum default n = "int" ^ string_of_big_int n else if ge_big_int n zero_big_int then default n - else ("(zero - " ^ (default (abs_big_int n)) ^ ")") + else ("(int0 - " ^ (default (abs_big_int n)) ^ ")") let pp_format_id (Id_aux(i,_)) = match i with @@ -281,38 +289,28 @@ let pp_format_lit_lem (L_aux(lit,l)) = let pp_lem_lit ppf l = base ppf (pp_format_lit_lem l) -let rec pp_format_nes nes = - "[" ^ (* - (list_format "; " - (fun ne -> match ne with - | LtEq(_,n1,n2) -> "(Nec_lteq " ^ pp_format_n_lem n1 ^ " " ^ pp_format_n_lem n2 ^ ")" - | Eq(_,n1,n2) -> "(Nec_eq " ^ pp_format_n_lem n1 ^ " " ^ pp_format_n_lem n2 ^ ")" - | GtEq(_,n1,n2) -> "(Nec_gteq " ^ pp_format_n_lem n1 ^ " " ^ pp_format_n_lem n2 ^ ")" - | In(_,i,ns) | InS(_,{nexp=Nvar i},ns) -> - "(Nec_in \"" ^ i ^ "\" [" ^ (list_format "; " string_of_int ns)^ "])" - | InS(_,_,ns) -> - "(Nec_in \"fresh\" [" ^ (list_format "; " string_of_int ns)^ "])" - | CondCons(_,nes_c,nes_t) -> - "(Nec_cond " ^ (pp_format_nes nes_c) ^ " " ^ (pp_format_nes nes_t) ^ ")" - | BranchCons(_,nes_b) -> - "(Nec_branch " ^ (pp_format_nes nes_b) ^ ")" - ) - nes) ^*) "]" - -let pp_format_annot = function +let tag_id id env = + if Env.is_extern id env "lem_ast" then + "Tag_extern (Just \"" ^ Ast_util.string_of_id id ^ "\")" + else if Env.is_union_constructor id env then + "Tag_ctor" + else + "Tag_empty" + +let pp_format_annot ?tag:(t="Tag_empty") = function | None -> "Nothing" | Some (_, typ, eff) -> - "(Just (" ^ pp_format_typ_lem typ ^ ", " ^ pp_format_effects_lem eff ^ "))" -(* - | NoTyp -> "Nothing" - | Base((_,t),tag,nes,efct,efctsum,_) -> - (*TODO print out bindings for use in pattern match in interpreter*) - "(Just (" ^ pp_format_t_lem t ^ ", " ^ pp_format_tag tag ^ ", " ^ pp_format_nes nes ^ ", " ^ - pp_format_e_lem efct ^ ", " ^ pp_format_e_lem efctsum ^ "))" - | Overload _ -> "Nothing" *) + "(Just (" + ^ pp_format_typ_lem typ ^ ", " + ^ t ^ ", " + ^ "[], " + ^ pp_format_effects_lem eff ^ ", " + ^ pp_format_effects_lem eff + ^ "))" let pp_annot ppf ant = base ppf (pp_format_annot ant) +let pp_annot_tag tag ppf ant = base ppf (pp_format_annot ~tag:tag ant) let rec pp_format_pat_lem (P_aux(p,(l,annot))) = "(P_aux " ^ @@ -345,7 +343,8 @@ let rec pp_lem_let ppf (LB_aux(lb,(l,annot))) = fprintf ppf "@[<0>(%a %a %a)@]" kwd "LB_val" pp_lem_pat pat pp_lem_exp exp in fprintf ppf "@[<0>(LB_aux %a (%a, %a))@]" print_lb lb pp_lem_l l pp_annot annot -and pp_lem_exp ppf (E_aux(e,(l,annot))) = +and pp_lem_exp ppf (E_aux(e,(l,annot)) as exp) = + let env = env_of exp in let print_e ppf e = match e with | E_block(exps) -> fprintf ppf "@[<0>(E_aux %a [%a] %a (%a, %a))@]" @@ -356,13 +355,13 @@ and pp_lem_exp ppf (E_aux(e,(l,annot))) = kwd "(E_nondet" (list_pp pp_semi_lem_exp pp_lem_exp) exps kwd ")" pp_lem_l l pp_annot annot - | E_id(id) -> fprintf ppf "(E_aux (%a %a) (%a, %a))" kwd "E_id" pp_lem_id id pp_lem_l l pp_annot annot + | E_id(id) -> fprintf ppf "(E_aux (%a %a) (%a, %a))" kwd "E_id" pp_lem_id id pp_lem_l l (pp_annot_tag (tag_id id env)) annot | E_lit(lit) -> fprintf ppf "(E_aux (%a %a) (%a, %a))" kwd "E_lit" pp_lem_lit lit pp_lem_l l pp_annot annot | E_cast(typ,exp) -> fprintf ppf "@[<0>(E_aux (E_cast %a %a) (%a, %a))@]" pp_lem_typ typ pp_lem_exp exp pp_lem_l l pp_annot annot | E_internal_cast((_,None),e) -> pp_lem_exp ppf e | E_app(f,args) -> fprintf ppf "@[<0>(E_aux (E_app %a [%a]) (%a, %a))@]" - pp_lem_id f (list_pp pp_semi_lem_exp pp_lem_exp) args pp_lem_l l pp_annot annot + pp_lem_id f (list_pp pp_semi_lem_exp pp_lem_exp) args pp_lem_l l (pp_annot_tag (tag_id f env)) annot | E_app_infix(l',op,r) -> fprintf ppf "@[<0>(E_aux (E_app_infix %a %a %a) (%a, %a))@]" pp_lem_exp l' pp_lem_id op pp_lem_exp r pp_lem_l l pp_annot annot | E_tuple(exps) -> fprintf ppf "@[<0>(E_aux (E_tuple [%a]) (%a, %a))@]" @@ -471,7 +470,7 @@ and pp_lem_case ppf = function | Pat_aux(Pat_exp(pat,exp),(l,annot)) -> fprintf ppf "@[<1>(Pat_aux (Pat_exp %a@ %a) (%a, %a))@]" pp_lem_pat pat pp_lem_exp exp pp_lem_l l pp_annot annot | Pat_aux(Pat_when(pat,guard,exp),(l,annot)) -> - fprintf ppf "@[<1>(Pat_aux (Pat_exp %a@ %a %a) (%a, %a))@]" pp_lem_pat pat pp_lem_exp guard pp_lem_exp exp pp_lem_l l pp_annot annot + fprintf ppf "@[<1>(Pat_aux (Pat_when %a@ %a %a) (%a, %a))@]" pp_lem_pat pat pp_lem_exp guard pp_lem_exp exp pp_lem_l l pp_annot annot and pp_semi_lem_case ppf case = fprintf ppf "@[<1>%a %a@]" pp_lem_case case kwd ";" and pp_lem_lexp ppf (LEXP_aux(lexp,(l,annot))) = diff --git a/src/pretty_print_sail.ml b/src/pretty_print_sail.ml index e585a8f1..4ef506c5 100644 --- a/src/pretty_print_sail.ml +++ b/src/pretty_print_sail.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/pretty_print_sail2.ml b/src/pretty_print_sail2.ml index 59413653..07259a6f 100644 --- a/src/pretty_print_sail2.ml +++ b/src/pretty_print_sail2.ml @@ -1,3 +1,52 @@ +(**************************************************************************) +(* Sail *) +(* *) +(* Copyright (c) 2013-2017 *) +(* 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 *) +(* *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(**************************************************************************) open Ast open Ast_util @@ -169,43 +218,90 @@ let rec doc_pat (P_aux (p_aux, _) as pat) = | P_app (id, pats) -> doc_id id ^^ parens (separate_map (comma ^^ space) doc_pat pats) | _ -> string (string_of_pat pat) +(* if_block_x is true if x should be printed like a block, i.e. with + newlines. Blocks are automatically printed as blocks, so this + returns false for them. *) +let if_block_then (E_aux (e_aux, _)) = + match e_aux with + | E_assign _ | E_if _ -> true + | _ -> false + +let if_block_else (E_aux (e_aux, _)) = + match e_aux with + | E_assign _ -> true + | _ -> false + +let fixities = + let fixities' = + List.fold_left + (fun r (x, y) -> Bindings.add x y r) + Bindings.empty + [ + (mk_id "^", (InfixR, 8)); + (mk_id "*", (InfixL, 7)); + (mk_id "+", (InfixL, 6)); + (mk_id "-", (InfixL, 6)); + (mk_id "!=", (Infix, 4)); + (mk_id ">", (Infix, 4)); + (mk_id "<", (Infix, 4)); + (mk_id ">=", (Infix, 4)); + (mk_id "<=", (Infix, 4)); + (mk_id "&", (InfixR, 3)); + (mk_id "|", (InfixR, 2)); + ] + in + ref (fixities' : (prec * int) Bindings.t) + let rec doc_exp (E_aux (e_aux, _) as exp) = match e_aux with + | E_block [] -> string "()" | E_block [exp] -> doc_exp exp | E_block exps -> surround 2 0 lbrace (doc_block exps) rbrace | E_nondet exps -> assert false (* This is mostly for the -convert option *) | E_app_infix (x, id, y) when Id.compare (mk_id "quot") id == 0 -> separate space [doc_atomic_exp x; string "/"; doc_atomic_exp y] - | E_app_infix (x, id, y) -> separate space [doc_atomic_exp x; doc_id id; doc_atomic_exp y] + | E_app_infix _ -> doc_infix 0 exp | E_tuple exps -> parens (separate_map (comma ^^ space) doc_exp exps) + + (* Various rules to try to format if blocks nicely based on content *) + | E_if (if_exp, then_exp, else_exp) when if_block_then then_exp && if_block_else else_exp -> + (separate space [string "if"; doc_exp if_exp; string "then"] ^//^ doc_exp then_exp) + ^/^ (string "else" ^//^ doc_exp else_exp) + | E_if (if_exp, then_exp, (E_aux (E_if _, _) as else_exp)) when if_block_then then_exp -> + (separate space [string "if"; doc_exp if_exp; string "then"] ^//^ doc_exp then_exp) + ^/^ (string "else" ^^ space ^^ doc_exp else_exp) + | E_if (if_exp, then_exp, else_exp) when if_block_else else_exp -> + (separate space [string "if"; doc_exp if_exp; string "then"; doc_exp then_exp]) + ^^ space ^^ (string "else" ^//^ doc_exp else_exp) + | E_if (if_exp, then_exp, else_exp) when if_block_then then_exp -> + (separate space [string "if"; doc_exp if_exp; string "then"] ^//^ doc_exp then_exp) + ^/^ (string "else" ^^ space ^^ doc_exp else_exp) | E_if (if_exp, then_exp, else_exp) -> group (separate space [string "if"; doc_exp if_exp; string "then"; doc_exp then_exp; string "else"; doc_exp else_exp]) + | E_list exps -> string "[|" ^^ separate_map (comma ^^ space) doc_exp exps ^^ string "|]" | E_cons (exp1, exp2) -> string "E_cons" - | E_record fexps -> string "<|" ^^ doc_fexps fexps ^^ string "|>" + | E_record fexps -> separate space [string "record"; string "{"; doc_fexps fexps; string "}"] | E_loop (While, cond, exp) -> separate space [string "while"; doc_exp cond; string "do"; doc_exp exp] | E_loop (Until, cond, exp) -> separate space [string "repeat"; doc_exp exp; string "until"; doc_exp cond] - | E_record_update (exp, fexps) -> separate space [string "<|"; doc_exp exp; string "with"; doc_fexps fexps; string "|>"] + | E_record_update (exp, fexps) -> + separate space [string "{"; doc_exp exp; string "with"; doc_fexps fexps; string "}"] | E_vector_append (exp1, exp2) -> separate space [doc_atomic_exp exp1; string "@"; doc_atomic_exp exp2] | E_case (exp, pexps) -> separate space [string "match"; doc_exp exp; doc_pexps pexps] | E_let (LB_aux (LB_val (pat, binding), _), exp) -> separate space [string "let"; doc_pat pat; equals; doc_exp binding; string "in"; doc_exp exp] - | E_internal_let (lexp, exp1, exp2) -> - let le = - prefix 2 1 - (separate space [string "internal_let"; doc_lexp lexp; equals]) - (doc_exp exp1) in - doc_op (string "in") le (doc_exp exp2) | E_internal_plet (pat, exp1, exp2) -> let le = prefix 2 1 (separate space [string "internal_plet"; doc_pat pat; equals]) (doc_exp exp1) in doc_op (string "in") le (doc_exp exp2) + | E_internal_let (lexp, binding, exp) -> + separate space [string "var"; doc_lexp lexp; equals; doc_exp binding; string "in"; doc_exp exp] | E_assign (lexp, exp) -> separate space [doc_lexp lexp; equals; doc_exp exp] | E_for (id, exp1, exp2, exp3, order, exp4) -> @@ -225,13 +321,30 @@ let rec doc_exp (E_aux (e_aux, _) as exp) = | _ -> header ^//^ doc_exp exp4 end (* Resugar an assert with an empty message *) - | E_throw exp -> assert false + | E_throw exp -> string "throw" ^^ parens (doc_exp exp) | E_try (exp, pexps) -> assert false | E_return exp -> string "return" ^^ parens (doc_exp exp) | E_internal_return exp -> string "internal_return" ^^ parens (doc_exp exp) | E_app (id, [exp]) when Id.compare (mk_id "pow2") id == 0 -> separate space [string "2"; string "^"; doc_atomic_exp exp] | _ -> doc_atomic_exp exp +and doc_infix n (E_aux (e_aux, _) as exp) = + match e_aux with + | E_app_infix (l, op, r) when n < 10 -> + begin + try + match Bindings.find op !fixities with + | (Infix, m) when m >= n -> separate space [doc_infix (m + 1) l; doc_id op; doc_infix (m + 1) r] + | (Infix, m) when m < n -> parens (separate space [doc_infix (m + 1) l; doc_id op; doc_infix (m + 1) r]) + | (InfixL, m) when m >= n -> separate space [doc_infix m l; doc_id op; doc_infix (m + 1) r] + | (InfixL, m) when m < n -> parens (separate space [doc_infix m l; doc_id op; doc_infix (m + 1) r]) + | (InfixR, m) when m >= n -> separate space [doc_infix (m + 1) l; doc_id op; doc_infix m r] + | (InfixR, m) when m < n -> parens (separate space [doc_infix (m + 1) l; doc_id op; doc_infix m r]) + with + | Not_found -> + separate space [doc_atomic_exp l; doc_id op; doc_atomic_exp r] + end + | _ -> doc_atomic_exp exp and doc_atomic_exp (E_aux (e_aux, _) as exp) = match e_aux with | E_cast (typ, exp) -> @@ -256,10 +369,16 @@ and doc_atomic_exp (E_aux (e_aux, _) as exp) = | E_vector_update_subrange (exp1, exp2, exp3, exp4) -> brackets (separate space [doc_exp exp1; string "with"; doc_atomic_exp exp2; string ".."; doc_atomic_exp exp3; equals; doc_exp exp4]) | _ -> parens (doc_exp exp) +and doc_fexps (FES_aux (FES_Fexps (fexps, _), _)) = + separate_map (comma ^^ space) doc_fexp fexps +and doc_fexp (FE_aux (FE_Fexp (id, exp), _)) = + separate space [doc_id id; equals; doc_exp exp] and doc_block = function | [] -> string "()" | [E_aux (E_let (LB_aux (LB_val (pat, binding), _), E_aux (E_block exps, _)), _)] -> separate space [string "let"; doc_pat pat; equals; doc_exp binding] ^^ semi ^^ hardline ^^ doc_block exps + | [E_aux (E_internal_let (lexp, binding, E_aux (E_block exps, _)), _)] -> + separate space [string "var"; doc_lexp lexp; equals; doc_exp binding] ^^ semi ^^ hardline ^^ doc_block exps | [exp] -> doc_exp exp | exp :: exps -> doc_exp exp ^^ semi ^^ hardline ^^ doc_block exps and doc_lexp (LEXP_aux (l_aux, _) as lexp) = @@ -281,9 +400,6 @@ and doc_pexp (Pat_aux (pat_aux, _)) = | Pat_exp (pat, exp) -> separate space [doc_pat pat; string "=>"; doc_exp exp] | Pat_when (pat, wh, exp) -> separate space [doc_pat pat; string "if"; doc_exp wh; string "=>"; doc_exp exp] -and doc_fexps (FES_aux (FES_Fexps (fexps, _), _)) = separate_map (semi ^^ space) doc_fexp fexps -and doc_fexp (FE_aux (FE_Fexp (id, exp), _)) = - doc_op (string "=") (doc_id id) (doc_exp exp) and doc_letbind (LB_aux (lb_aux, _)) = match lb_aux with | LB_val (pat, exp) -> @@ -348,17 +464,7 @@ let doc_spec (VS_aux(v,_)) = let doc_backend b = Util.option_map (fun id -> string (b ^ ":") ^^ space ^^ utf8string ("\"" ^ String.escaped id ^ "\"")) (ext b) in let docs = Util.option_these (List.map doc_backend ["ocaml"; "lem"]) in - if docs = [] then empty else braces (separate (comma ^^ space) docs) - (* function - | Some s -> - let ext_for backend = utf8string ("\"" ^ String.escaped (s backend) ^ "\"") in - let extern = - if s "ocaml" = s "lem" - then ext_for "ocaml" - else separate space [lbrace; string "ocaml:"; ext_for "ocaml"; string "lem:"; ext_for "lem"; rbrace] - in - equals ^^ space ^^ extern ^^ space - | None -> empty *) + if docs = [] then empty else equals ^^ space ^^ braces (separate (comma ^^ space) docs) in match v with | VS_val_spec(ts,id,ext,is_cast) -> @@ -395,9 +501,13 @@ let rec doc_def def = group (match def with | DEF_fundef f_def -> doc_fundef f_def | DEF_internal_mutrec f_defs -> separate_map hardline doc_fundef f_defs | DEF_val lbind -> string "let" ^^ space ^^ doc_letbind lbind + | DEF_internal_mutrec fundefs -> + (string "mutual {" ^//^ separate_map (hardline ^^ hardline) doc_fundef fundefs) + ^^ hardline ^^ string "}" | DEF_reg_dec dec -> doc_dec dec | DEF_scattered sdef -> doc_scattered sdef | DEF_fixity (prec, n, id) -> + fixities := Bindings.add id (prec, int_of_big_int n) !fixities; separate space [doc_prec prec; doc_int n; doc_id id] | DEF_overload (id, ids) -> separate space [string "overload"; doc_id id; equals; surround 2 0 lbrace (separate_map (comma ^^ break 1) doc_id ids) rbrace] diff --git a/src/process_file.ml b/src/process_file.ml index 344e5951..2d2cbe76 100644 --- a/src/process_file.ml +++ b/src/process_file.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -210,7 +218,7 @@ let rewrite_step defs (name,rewriter) = | Some (f, i) -> begin let filename = f ^ "_rewrite_" ^ string_of_int i ^ "_" ^ name ^ ".sail" in - output "" Lem_ast_out [filename, defs]; + (* output "" Lem_ast_out [filename, defs]; *) let ((ot,_, _) as ext_ot) = open_output_with_check_unformatted filename in Pretty_print_sail2.pp_defs ot defs; close_output_with_check ext_ot; @@ -226,7 +234,8 @@ let rewrite rewriters defs = exit 1 let rewrite_ast = rewrite [("initial", Rewriter.rewrite_defs)] -let rewrite_undefined = rewrite [("undefined", fun x -> Rewriter.rewrite_undefined !opt_lem_mwords x)] -let rewrite_ast_lem = rewrite Rewriter.rewrite_defs_lem -let rewrite_ast_ocaml = rewrite Rewriter.rewrite_defs_ocaml -let rewrite_ast_check = rewrite Rewriter.rewrite_defs_check +let rewrite_undefined = rewrite [("undefined", fun x -> Rewrites.rewrite_undefined !opt_lem_mwords x)] +let rewrite_ast_lem = rewrite Rewrites.rewrite_defs_lem +let rewrite_ast_ocaml = rewrite Rewrites.rewrite_defs_ocaml +let rewrite_ast_sil = rewrite Rewrites.rewrite_defs_sil +let rewrite_ast_check = rewrite Rewrites.rewrite_defs_check diff --git a/src/process_file.mli b/src/process_file.mli index b575bd14..f99bdf54 100644 --- a/src/process_file.mli +++ b/src/process_file.mli @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -48,6 +56,7 @@ val rewrite_ast: Type_check.tannot Ast.defs -> Type_check.tannot Ast.defs val rewrite_undefined: Type_check.tannot Ast.defs -> Type_check.tannot Ast.defs val rewrite_ast_lem : Type_check.tannot Ast.defs -> Type_check.tannot Ast.defs val rewrite_ast_ocaml : Type_check.tannot Ast.defs -> Type_check.tannot Ast.defs +val rewrite_ast_sil : Type_check.tannot Ast.defs -> Type_check.tannot Ast.defs val rewrite_ast_check : Type_check.tannot Ast.defs -> Type_check.tannot Ast.defs val load_file_no_check : Ast.order -> string -> unit Ast.defs diff --git a/src/reporting_basic.ml b/src/reporting_basic.ml index a47ee8ae..166e0517 100644 --- a/src/reporting_basic.ml +++ b/src/reporting_basic.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/reporting_basic.mli b/src/reporting_basic.mli index 3d1cbe13..d2978389 100644 --- a/src/reporting_basic.mli +++ b/src/reporting_basic.mli @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/rewriter.ml b/src/rewriter.ml index 002d7630..4d5e7967 100644 --- a/src/rewriter.ml +++ b/src/rewriter.ml @@ -9,7 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) (* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -58,8 +65,6 @@ type 'a rewriters = { } -let (>>) f g = fun x -> g(f(x)) - let effect_of_fpat (FP_aux (_,(_,a))) = effect_of_annot a let effect_of_lexp (LEXP_aux (_,(_,a))) = effect_of_annot a let effect_of_fexp (FE_aux (_,(_,a))) = effect_of_annot a @@ -75,21 +80,7 @@ let effect_of_pexp (Pat_aux (pexp,(_,a))) = match a with | Pat_when (_, g, e) -> union_effects (effect_of g) (effect_of e)) let effect_of_lb (LB_aux (_,(_,a))) = effect_of_annot a -let get_loc_exp (E_aux (_,(l,_))) = l -let gen_loc l = Parse_ast.Generated l - -let gen_vs (id, spec) = Initial_check.val_spec_of_string dec_ord (mk_id id) spec - let simple_annot l typ = (gen_loc l, Some (Env.empty, typ, no_effect)) -let simple_num l n = E_aux ( - E_lit (L_aux (L_num n, gen_loc l)), - simple_annot (gen_loc l) - (atom_typ (Nexp_aux (Nexp_constant n, gen_loc l)))) -let annot_exp_effect e_aux l env typ effect = E_aux (e_aux, (l, Some (env, typ, effect))) -let annot_exp e_aux l env typ = annot_exp_effect e_aux l env typ no_effect -let annot_pat p_aux l env typ = P_aux (p_aux, (l, Some (env, typ, no_effect))) -let annot_letbind (p_aux, exp) l env typ = - LB_aux (LB_val (annot_pat p_aux l env typ, exp), (l, Some (env, typ, effect_of exp))) let rec small (E_aux (exp,_)) = match exp with | E_id _ @@ -100,27 +91,6 @@ let rec small (E_aux (exp,_)) = match exp with | E_sizeof _ -> true | _ -> false -let fresh_name_counter = ref 0 - -let fresh_name () = - let current = !fresh_name_counter in - let () = fresh_name_counter := (current + 1) in - current -let reset_fresh_name_counter () = - fresh_name_counter := 0 - -let fresh_id pre l = - let current = fresh_name () in - Id_aux (Id (pre ^ string_of_int current), gen_loc l) - -let fresh_id_exp pre ((l,annot)) = - let id = fresh_id pre l in - E_aux (E_id id, (gen_loc l, annot)) - -let fresh_id_pat pre ((l,annot)) = - let id = fresh_id pre l in - P_aux (P_id id, (gen_loc l, annot)) - let union_eff_exps es = List.fold_left union_effects no_effect (List.map effect_of es) @@ -248,78 +218,15 @@ let effectful_effs = function let effectful eaux = effectful_effs (effect_of (propagate_exp_effect eaux)) let effectful_pexp pexp = effectful_effs (snd (propagate_pexp_effect pexp)) -let id_to_string (Id_aux(id,l)) = +(* let id_to_string (Id_aux(id,l)) = match id with | Id(s) -> s - | DeIid(s) -> s - - -(*let rec partial_assoc (eq: 'a -> 'a -> bool) (v: 'a) (ls : ('a *'b) list ) : 'b option = match ls with - | [] -> None - | (v1,v2)::ls -> if (eq v1 v) then Some v2 else partial_assoc eq v ls - -let mk_atom_typ i = {t=Tapp("atom",[TA_nexp i])} - -let simple_num l n : tannot exp = - let typ = simple_annot (mk_atom_typ (mk_c (big_int_of_int n))) in - E_aux (E_lit (L_aux (L_num n,l)), (l,typ)) - -let rec rewrite_nexp_to_exp program_vars l nexp = - let rewrite n = rewrite_nexp_to_exp program_vars l n in - let typ = mk_atom_typ nexp in - let actual_rewrite_n nexp = - match nexp.nexp with - | Nconst i -> E_aux (E_lit (L_aux (L_num (int_of_big_int i),l)), (l,simple_annot typ)) - | Nadd (n1,n2) -> E_aux (E_app_infix (rewrite n1,(Id_aux (Id "+",l)),rewrite n2), - (l, (tag_annot typ (External (Some "add"))))) - | Nmult (n1,n2) -> E_aux (E_app_infix (rewrite n1,(Id_aux (Id "*",l)),rewrite n2), - (l, tag_annot typ (External (Some "multiply")))) - | Nsub (n1,n2) -> E_aux (E_app_infix (rewrite n1,(Id_aux (Id "-",l)),rewrite n2), - (l, tag_annot typ (External (Some "minus")))) - | N2n (n, _) -> E_aux (E_app_infix (E_aux (E_lit (L_aux (L_num 2,l)), (l, simple_annot (mk_atom_typ n_two))), - (Id_aux (Id "**",l)), - rewrite n), (l, tag_annot typ (External (Some "power")))) - | Npow(n,i) -> E_aux (E_app_infix - (rewrite n, (Id_aux (Id "**",l)), - E_aux (E_lit (L_aux (L_num i,l)), - (l, simple_annot (mk_atom_typ (mk_c_int i))))), - (l, tag_annot typ (External (Some "power")))) - | Nneg(n) -> E_aux (E_app_infix (E_aux (E_lit (L_aux (L_num 0,l)), (l, simple_annot (mk_atom_typ n_zero))), - (Id_aux (Id "-",l)), - rewrite n), - (l, tag_annot typ (External (Some "minus")))) - | Nvar v -> (*TODO these need to generate an error as it's a place where there's insufficient specification. - But, for now I need to permit this to make power.sail compile, and most errors are in trap - or vectors *) - (*let _ = Printf.eprintf "unbound variable here %s\n" v in*) - E_aux (E_id (Id_aux (Id v,l)),(l,simple_annot typ)) - | _ -> raise (Reporting_basic.err_unreachable l ("rewrite_nexp given n that can't be rewritten: " ^ (n_to_string nexp))) in - match program_vars with - | None -> actual_rewrite_n nexp - | Some program_vars -> - (match partial_assoc nexp_eq_check nexp program_vars with - | None -> actual_rewrite_n nexp - | Some(None,ev) -> - (*let _ = Printf.eprintf "var case of rewrite, %s\n" ev in*) - E_aux (E_id (Id_aux (Id ev,l)), (l, simple_annot typ)) - | Some(Some f,ev) -> - E_aux (E_app ((Id_aux (Id f,l)), [ (E_aux (E_id (Id_aux (Id ev,l)), (l,simple_annot typ)))]), - (l, tag_annot typ (External (Some f))))) - -let rec match_to_program_vars ns bounds = - match ns with - | [] -> [] - | n::ns -> match find_var_from_nexp n bounds with - | None -> match_to_program_vars ns bounds - | Some(augment,ev) -> - (*let _ = Printf.eprintf "adding n %s to program var %s\n" (n_to_string n) ev in*) - (n,(augment,ev))::(match_to_program_vars ns bounds)*) + | DeIid(s) -> s *) let explode s = let rec exp i l = if i < 0 then l else exp (i - 1) (s.[i] :: l) in exp (String.length s - 1) [] - let vector_string_to_bit_list l lit = let hexchar_to_binlist = function @@ -340,14 +247,14 @@ let vector_string_to_bit_list l lit = | 'E' -> ['1';'1';'1';'0'] | 'F' -> ['1';'1';'1';'1'] | _ -> raise (Reporting_basic.err_unreachable l "hexchar_to_binlist given unrecognized character") in - + let s_bin = match lit with | L_hex s_hex -> List.flatten (List.map hexchar_to_binlist (explode (String.uppercase s_hex))) | L_bin s_bin -> explode s_bin | _ -> raise (Reporting_basic.err_unreachable l "s_bin given non vector literal") in List.map (function '0' -> L_aux (L_zero, gen_loc l) - | '1' -> L_aux (L_one,gen_loc l) + | '1' -> L_aux (L_one, gen_loc l) | _ -> raise (Reporting_basic.err_unreachable (gen_loc l) "binary had non-zero or one")) s_bin let rewrite_pat rewriters (P_aux (pat,(l,annot))) = @@ -371,7 +278,7 @@ let rewrite_pat rewriters (P_aux (pat,(l,annot))) = | P_list pats -> rewrap (P_list (List.map rewrite pats)) | P_cons (pat1, pat2) -> rewrap (P_cons (rewrite pat1, rewrite pat2)) -let rewrite_exp rewriters (E_aux (exp,(l,annot))) = +let rewrite_exp rewriters (E_aux (exp,(l,annot))) = let rewrap e = E_aux (e,(l,annot)) in let rewrite = rewriters.rewrite_exp rewriters in match exp with @@ -396,22 +303,22 @@ let rewrite_exp rewriters (E_aux (exp,(l,annot))) = | E_vector_access (vec,index) -> rewrap (E_vector_access (rewrite vec,rewrite index)) | E_vector_subrange (vec,i1,i2) -> rewrap (E_vector_subrange (rewrite vec,rewrite i1,rewrite i2)) - | E_vector_update (vec,index,new_v) -> + | E_vector_update (vec,index,new_v) -> rewrap (E_vector_update (rewrite vec,rewrite index,rewrite new_v)) | E_vector_update_subrange (vec,i1,i2,new_v) -> rewrap (E_vector_update_subrange (rewrite vec,rewrite i1,rewrite i2,rewrite new_v)) | E_vector_append (v1,v2) -> rewrap (E_vector_append (rewrite v1,rewrite v2)) - | E_list exps -> rewrap (E_list (List.map rewrite exps)) + | E_list exps -> rewrap (E_list (List.map rewrite exps)) | E_cons(h,t) -> rewrap (E_cons (rewrite h,rewrite t)) - | E_record (FES_aux (FES_Fexps(fexps, bool),fannot)) -> - rewrap (E_record - (FES_aux (FES_Fexps - (List.map (fun (FE_aux(FE_Fexp(id,e),fannot)) -> + | E_record (FES_aux (FES_Fexps(fexps, bool),fannot)) -> + rewrap (E_record + (FES_aux (FES_Fexps + (List.map (fun (FE_aux(FE_Fexp(id,e),fannot)) -> FE_aux(FE_Fexp(id,rewrite e),fannot)) fexps, bool), fannot))) | E_record_update (re,(FES_aux (FES_Fexps(fexps, bool),fannot))) -> rewrap (E_record_update ((rewrite re), - (FES_aux (FES_Fexps - (List.map (fun (FE_aux(FE_Fexp(id,e),fannot)) -> + (FES_aux (FES_Fexps + (List.map (fun (FE_aux(FE_Fexp(id,e),fannot)) -> FE_aux(FE_Fexp(id,rewrite e),fannot)) fexps, bool), fannot)))) | E_field(exp,id) -> rewrap (E_field(rewrite exp,id)) | E_case (exp,pexps) -> @@ -429,102 +336,6 @@ let rewrite_exp rewriters (E_aux (exp,(l,annot))) = | E_assert(e1,e2) -> rewrap (E_assert(rewrite e1,rewrite e2)) | E_internal_cast (casted_annot,exp) -> rewrap (E_internal_cast (casted_annot, rewrite exp)) - (* check_exp (env_of exp) (strip_exp exp) (typ_of_annot casted_annot) *) - (*let new_exp = rewrite exp in - (*let _ = Printf.eprintf "Removing an internal_cast with %s\n" (tannot_to_string casted_annot) in*) - (match casted_annot,exp with - | Base((_,t),_,_,_,_,_),E_aux(ec,(ecl,Base((_,exp_t),_,_,_,_,_))) -> - (*let _ = Printf.eprintf "Considering removing an internal cast where the two types are %s and %s\n" - (t_to_string t) (t_to_string exp_t) in*) - (match t.t,exp_t.t with - (*TODO should pass d_env into here so that I can look at the abbreviations if there are any here*) - | Tapp("vector",[TA_nexp n1;TA_nexp nw1;TA_ord o1;_]), - Tapp("vector",[TA_nexp n2;TA_nexp nw2;TA_ord o2;_]) - | Tapp("vector",[TA_nexp n1;TA_nexp nw1;TA_ord o1;_]), - Tapp("reg",[TA_typ {t=(Tapp("vector",[TA_nexp n2; TA_nexp nw2; TA_ord o2;_]))}]) -> - (match n1.nexp with - | Nconst i1 -> if nexp_eq n1 n2 then new_exp else rewrap (E_cast (t_to_typ t,new_exp)) - | _ -> (match o1.order with - | Odec -> - (*let _ = Printf.eprintf "Considering removing a cast or not: %s %s, %b\n" - (n_to_string nw1) (n_to_string n1) (nexp_one_more_than nw1 n1) in*) - rewrap (E_cast (Typ_aux (Typ_var (Kid_aux((Var "length"),Parse_ast.Generated l)), - Parse_ast.Generated l),new_exp)) - | _ -> new_exp)) - | _ -> new_exp - | Base((_,t),_,_,_,_,_),_ -> - (*let _ = Printf.eprintf "Considering removing an internal cast where the remaining type is %s\n%!" - (t_to_string t) in*) - (match t.t with - | Tapp("vector",[TA_nexp n1;TA_nexp nw1;TA_ord o1;_]) -> - (match o1.order with - | Odec -> - let _ = Printf.eprintf "Considering removing a cast or not: %s %s, %b\n" - (n_to_string nw1) (n_to_string n1) (nexp_one_more_than nw1 n1) in - rewrap (E_cast (Typ_aux (Typ_var (Kid_aux((Var "length"), Parse_ast.Generated l)), - Parse_ast.Generated l), new_exp)) - | _ -> new_exp) - | _ -> new_exp) - | _ -> (*let _ = Printf.eprintf "Not a base match?\n" in*) new_exp*) - (*| E_internal_exp (l,impl) -> - match impl with - | Base((_,t),_,_,_,_,bounds) -> - (*let _ = Printf.eprintf "Rewriting internal expression, with type %s, and bounds %s\n" - (t_to_string t) (bounds_to_string bounds) in*) - let bounds = match nmap with | None -> bounds | Some (nm,_) -> add_map_to_bounds nm bounds in - (*let _ = Printf.eprintf "Bounds after looking at nmap %s\n" (bounds_to_string bounds) in*) - (match t.t with - (*Old case; should possibly be removed*) - | Tapp("register",[TA_typ {t= Tapp("vector",[ _; TA_nexp r;_;_])}]) - | Tapp("vector", [_;TA_nexp r;_;_]) - | Tabbrev(_, {t=Tapp("vector",[_;TA_nexp r;_;_])}) -> - (*let _ = Printf.eprintf "vector case with %s, bounds are %s\n" - (n_to_string r) (bounds_to_string bounds) in*) - let nexps = expand_nexp r in - (match (match_to_program_vars nexps bounds) with - | [] -> rewrite_nexp_to_exp None l r - | map -> rewrite_nexp_to_exp (Some map) l r) - | Tapp("implicit", [TA_nexp i]) -> - (*let _ = Printf.eprintf "Implicit case with %s\n" (n_to_string i) in*) - let nexps = expand_nexp i in - (match (match_to_program_vars nexps bounds) with - | [] -> rewrite_nexp_to_exp None l i - | map -> rewrite_nexp_to_exp (Some map) l i) - | _ -> - raise (Reporting_basic.err_unreachable l - ("Internal_exp given unexpected types " ^ (t_to_string t)))) - | _ -> raise (Reporting_basic.err_unreachable l ("Internal_exp given none Base annot"))*) - (*| E_sizeof_internal (l,impl) -> - (match impl with - | Base((_,t),_,_,_,_,bounds) -> - let bounds = match nmap with | None -> bounds | Some (nm,_) -> add_map_to_bounds nm bounds in - (match t.t with - | Tapp("atom",[TA_nexp n]) -> - let nexps = expand_nexp n in - (*let _ = Printf.eprintf "Removing sizeof_internal with type %s\n" (t_to_string t) in*) - (match (match_to_program_vars nexps bounds) with - | [] -> rewrite_nexp_to_exp None l n - | map -> rewrite_nexp_to_exp (Some map) l n) - | _ -> raise (Reporting_basic.err_unreachable l ("Sizeof internal had non-atom type " ^ (t_to_string t)))) - | _ -> raise (Reporting_basic.err_unreachable l ("Sizeof internal had none base annot"))*) - (*| E_internal_exp_user ((l,user_spec),(_,impl)) -> - (match (user_spec,impl) with - | (Base((_,tu),_,_,_,_,_), Base((_,ti),_,_,_,_,bounds)) -> - (*let _ = Printf.eprintf "E_interal_user getting rewritten two types are %s and %s\n" - (t_to_string tu) (t_to_string ti) in*) - let bounds = match nmap with | None -> bounds | Some (nm,_) -> add_map_to_bounds nm bounds in - (match (tu.t,ti.t) with - | (Tapp("implicit", [TA_nexp u]),Tapp("implicit",[TA_nexp i])) -> - (*let _ = Printf.eprintf "Implicit case with %s\n" (n_to_string i) in*) - let nexps = expand_nexp i in - (match (match_to_program_vars nexps bounds) with - | [] -> rewrite_nexp_to_exp None l i - (*add u to program_vars env; for now it will work out properly by accident*) - | map -> rewrite_nexp_to_exp (Some map) l i) - | _ -> - raise (Reporting_basic.err_unreachable l - ("Internal_exp_user given unexpected types " ^ (t_to_string tu) ^ ", " ^ (t_to_string ti)))) - | _ -> raise (Reporting_basic.err_unreachable l ("Internal_exp_user given none Base annot")))*) | E_internal_let (lexp, e1, e2) -> rewrap (E_internal_let (rewriters.rewrite_lexp rewriters lexp, rewriters.rewrite_exp rewriters e1, rewriters.rewrite_exp rewriters e2)) | E_internal_return _ -> raise (Reporting_basic.err_unreachable l "Internal return found before it should have been introduced") @@ -554,7 +365,6 @@ let rewrite_lexp rewriters (LEXP_aux(lexp,(l,annot))) = let rewrite_fun rewriters (FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),(l,fdannot))) = let rewrite_funcl (FCL_aux (FCL_Funcl(id,pat,exp),(l,annot))) = - let _ = reset_fresh_name_counter () in (FCL_aux (FCL_Funcl (id,rewriters.rewrite_pat rewriters pat, rewriters.rewrite_exp rewriters exp),(l,annot))) in FD_aux (FD_function(recopt,tannotopt,effectopt,List.map rewrite_funcl funcls),(l,fdannot)) @@ -580,7 +390,7 @@ let rewriters_base = rewrite_fun = rewrite_fun; rewrite_def = rewrite_def; rewrite_defs = rewrite_defs_base} - + let rewrite_defs (Defs defs) = rewrite_defs_base rewriters_base (Defs defs) module Envmap = Finite_map.Fmap_map(String) @@ -702,6 +512,7 @@ type ('a,'exp,'exp_aux,'lexp,'lexp_aux,'fexp,'fexp_aux,'fexps,'fexps_aux, ; e_sizeof : nexp -> 'exp_aux ; e_constraint : n_constraint -> 'exp_aux ; e_exit : 'exp -> 'exp_aux + ; e_throw : 'exp -> 'exp_aux ; e_return : 'exp -> 'exp_aux ; e_assert : 'exp * 'exp -> 'exp_aux ; e_internal_cast : 'a annot * 'exp -> 'exp_aux @@ -770,6 +581,7 @@ let rec fold_exp_aux alg = function | E_sizeof nexp -> alg.e_sizeof nexp | E_constraint nc -> alg.e_constraint nc | E_exit e -> alg.e_exit (fold_exp alg e) + | E_throw e -> alg.e_throw (fold_exp alg e) | E_return e -> alg.e_return (fold_exp alg e) | E_assert(e1,e2) -> alg.e_assert (fold_exp alg e1, fold_exp alg e2) | E_internal_cast (annot,e) -> alg.e_internal_cast (annot, fold_exp alg e) @@ -842,6 +654,7 @@ let id_exp_alg = ; e_sizeof = (fun nexp -> E_sizeof nexp) ; e_constraint = (fun nc -> E_constraint nc) ; e_exit = (fun e1 -> E_exit (e1)) + ; e_throw = (fun e1 -> E_throw (e1)) ; e_return = (fun e1 -> E_return e1) ; e_assert = (fun (e1,e2) -> E_assert(e1,e2)) ; e_internal_cast = (fun (a,e1) -> E_internal_cast (a,e1)) @@ -937,6 +750,7 @@ let compute_exp_alg bot join = ; e_sizeof = (fun nexp -> (bot, E_sizeof nexp)) ; e_constraint = (fun nc -> (bot, E_constraint nc)) ; e_exit = (fun (v1,e1) -> (v1, E_exit (e1))) + ; e_throw = (fun (v1,e1) -> (v1, E_throw (e1))) ; e_return = (fun (v1,e1) -> (v1, E_return e1)) ; e_assert = (fun ((v1,e1),(v2,e2)) -> (join v1 v2, E_assert(e1,e2)) ) ; e_internal_cast = (fun (a,(v1,e1)) -> (v1, E_internal_cast (a,e1))) @@ -977,2768 +791,3 @@ let compute_exp_alg bot join = ; lB_aux = (fun ((vl,lb),annot) -> (vl,LB_aux (lb,annot))) ; pat_alg = compute_pat_alg bot join } - -let rec rewrite_nexp_ids env (Nexp_aux (nexp, l) as nexp_aux) = match nexp with -| Nexp_id id -> rewrite_nexp_ids env (Env.get_num_def id env) -| Nexp_times (nexp1, nexp2) -> Nexp_aux (Nexp_times (rewrite_nexp_ids env nexp1, rewrite_nexp_ids env nexp2), l) -| Nexp_sum (nexp1, nexp2) -> Nexp_aux (Nexp_sum (rewrite_nexp_ids env nexp1, rewrite_nexp_ids env nexp2), l) -| Nexp_minus (nexp1, nexp2) -> Nexp_aux (Nexp_minus (rewrite_nexp_ids env nexp1, rewrite_nexp_ids env nexp2), l) -| Nexp_exp nexp -> Nexp_aux (Nexp_exp (rewrite_nexp_ids env nexp), l) -| Nexp_neg nexp -> Nexp_aux (Nexp_neg (rewrite_nexp_ids env nexp), l) -| _ -> nexp_aux - -let rewrite_defs_nexp_ids, rewrite_typ_nexp_ids = - let rec rewrite_typ env (Typ_aux (typ, l) as typ_aux) = match typ with - | Typ_fn (arg_t, ret_t, eff) -> - Typ_aux (Typ_fn (rewrite_typ env arg_t, rewrite_typ env ret_t, eff), l) - | Typ_tup ts -> - Typ_aux (Typ_tup (List.map (rewrite_typ env) ts), l) - | Typ_exist (kids, c, typ) -> - Typ_aux (Typ_exist (kids, c, rewrite_typ env typ), l) - | Typ_app (id, targs) -> - Typ_aux (Typ_app (id, List.map (rewrite_typ_arg env) targs), l) - | _ -> typ_aux - and rewrite_typ_arg env (Typ_arg_aux (targ, l) as targ_aux) = match targ with - | Typ_arg_nexp nexp -> - Typ_arg_aux (Typ_arg_nexp (rewrite_nexp_ids env nexp), l) - | Typ_arg_typ typ -> - Typ_arg_aux (Typ_arg_typ (rewrite_typ env typ), l) - | Typ_arg_order ord -> - Typ_arg_aux (Typ_arg_order ord, l) - in - - let rewrite_annot = function - | (l, Some (env, typ, eff)) -> (l, Some (env, rewrite_typ env typ, eff)) - | (l, None) -> (l, None) - in - - rewrite_defs_base { - rewriters_base with rewrite_exp = (fun _ -> map_exp_annot rewrite_annot) - }, - rewrite_typ - - -(* Re-write trivial sizeof expressions - trivial meaning that the - value of the sizeof can be directly inferred from the type - variables in scope. *) -let rewrite_trivial_sizeof, rewrite_trivial_sizeof_exp = - let extract_typ_var l env nexp (id, (_, typ)) = - let var = E_aux (E_id id, (l, Some (env, typ, no_effect))) in - match destruct_atom_nexp env typ with - | Some size when prove env (nc_eq size nexp) -> Some var - | _ -> - begin - match destruct_vector env typ with - | Some (_, len, _, _) when prove env (nc_eq len nexp) -> - Some (E_aux (E_app (mk_id "length", [var]), (l, Some (env, atom_typ len, no_effect)))) - | _ -> None - end - in - let rec split_nexp (Nexp_aux (nexp_aux, l) as nexp) = - match nexp_aux with - | Nexp_sum (n1, n2) -> - mk_exp (E_app (mk_id "add_range", [split_nexp n1; split_nexp n2])) - | Nexp_minus (n1, n2) -> - mk_exp (E_app (mk_id "sub_range", [split_nexp n1; split_nexp n2])) - | Nexp_times (n1, n2) -> - mk_exp (E_app (mk_id "mult_range", [split_nexp n1; split_nexp n2])) - | Nexp_neg nexp -> mk_exp (E_app (mk_id "negate_range", [split_nexp nexp])) - | _ -> mk_exp (E_sizeof nexp) - in - let rec rewrite_e_aux split_sizeof (E_aux (e_aux, (l, _)) as orig_exp) = - let env = env_of orig_exp in - match e_aux with - | E_sizeof (Nexp_aux (Nexp_constant c, _) as nexp) -> - E_aux (E_lit (L_aux (L_num c, l)), (l, Some (env, atom_typ nexp, no_effect))) - | E_sizeof nexp -> - begin - match nexp_simp (rewrite_nexp_ids (env_of orig_exp) nexp) with - | Nexp_aux (Nexp_constant c, _) -> - E_aux (E_lit (L_aux (L_num c, l)), (l, Some (env, atom_typ nexp, no_effect))) - | _ -> - let locals = Env.get_locals env in - let exps = Bindings.bindings locals - |> List.map (extract_typ_var l env nexp) - |> List.map (fun opt -> match opt with Some x -> [x] | None -> []) - |> List.concat - in - match exps with - | (exp :: _) -> check_exp env (strip_exp exp) (typ_of exp) - | [] when split_sizeof -> - fold_exp (rewrite_e_sizeof false) (check_exp env (split_nexp nexp) (typ_of orig_exp)) - | [] -> orig_exp - end - | _ -> orig_exp - and rewrite_e_sizeof split_sizeof = - { id_exp_alg with e_aux = (fun (exp, annot) -> rewrite_e_aux split_sizeof (E_aux (exp, annot))) } - in - rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp (rewrite_e_sizeof true)) }, rewrite_e_aux true - -(* Rewrite sizeof expressions with type-level variables to - term-level expressions - - For each type-level variable used in a sizeof expressions whose value cannot - be directly extracted from existing parameters of the surrounding function, - a further parameter is added; calls to the function are rewritten - accordingly (possibly causing further rewriting in the calling function) *) -let rewrite_sizeof (Defs defs) = - let sizeof_frees exp = - fst (fold_exp - { (compute_exp_alg KidSet.empty KidSet.union) with - e_sizeof = (fun nexp -> (nexp_frees nexp, E_sizeof nexp)) } - exp) in - - (* Collect nexps whose values can be obtained directly from a pattern bind *) - let nexps_from_params pat = - fst (fold_pat - { (compute_pat_alg [] (@)) with - p_aux = (fun ((v,pat),((l,_) as annot)) -> - let v' = match pat with - | P_id id | P_as (_, id) -> - let (Typ_aux (typ,_) as typ_aux) = typ_of_annot annot in - (match typ with - | Typ_app (atom, [Typ_arg_aux (Typ_arg_nexp nexp, _)]) - when string_of_id atom = "atom" -> - [nexp, E_id id] - | Typ_app (vector, _) when string_of_id vector = "vector" -> - let id_length = Id_aux (Id "length", gen_loc l) in - (try - (match Env.get_val_spec id_length (env_of_annot annot) with - | _ -> - let (_,len,_,_) = vector_typ_args_of typ_aux in - let exp = E_app (id_length, [E_aux (E_id id, annot)]) in - [len, exp]) - with - | _ -> []) - | _ -> []) - | _ -> [] in - (v @ v', P_aux (pat,annot)))} pat) in - - (* Substitute collected values in sizeof expressions *) - let rec e_sizeof nmap (Nexp_aux (nexp, l) as nexp_aux) = - try snd (List.find (fun (nexp,_) -> nexp_identical nexp nexp_aux) nmap) - with - | Not_found -> - let binop nexp1 op nexp2 = E_app_infix ( - E_aux (e_sizeof nmap nexp1, simple_annot l (atom_typ nexp1)), - Id_aux (Id op, Parse_ast.Unknown), - E_aux (e_sizeof nmap nexp2, simple_annot l (atom_typ nexp2)) - ) in - let (Nexp_aux (nexp, l) as nexp_aux) = nexp_simp nexp_aux in - (match nexp with - | Nexp_constant i -> E_lit (L_aux (L_num i, l)) - | Nexp_times (nexp1, nexp2) -> binop nexp1 "*" nexp2 - | Nexp_sum (nexp1, nexp2) -> binop nexp1 "+" nexp2 - | Nexp_minus (nexp1, nexp2) -> binop nexp1 "-" nexp2 - | _ -> E_sizeof nexp_aux) in - - let ex_regex = Str.regexp "'ex[0-9]+" in - - (* Rewrite calls to functions which have had parameters added to pass values - of type-level variables; these are added as sizeof expressions first, and - then further rewritten as above. *) - let e_app_aux param_map ((exp, exp_orig), ((l, _) as annot)) = - let env = env_of_annot annot in - let full_exp = E_aux (exp, annot) in - let orig_exp = E_aux (exp_orig, annot) in - match exp with - | E_app (f, args) -> - if Bindings.mem f param_map then - (* Retrieve instantiation of the type variables of the called function - for the given parameters in the original environment *) - let inst = - try instantiation_of orig_exp with - | Type_error (l, err) -> - raise (Reporting_basic.err_typ l (string_of_type_error err)) in - (* Rewrite the inst using orig_kid so that each type variable has it's - original name rather than a mangled typechecker name *) - let inst = KBindings.fold (fun kid uvar b -> KBindings.add (orig_kid kid) uvar b) inst KBindings.empty in - let kid_exp kid = begin - (* We really don't want to see an existential here! *) - assert (not (Str.string_match ex_regex (string_of_kid kid) 0)); - let uvar = try Some (KBindings.find (orig_kid kid) inst) with Not_found -> None in - match uvar with - | Some (U_nexp nexp) -> - let sizeof = E_aux (E_sizeof nexp, (l, Some (env, atom_typ nexp, no_effect))) in - (try rewrite_trivial_sizeof_exp sizeof with - | Type_error (l, err) -> - raise (Reporting_basic.err_typ l (string_of_type_error err))) - (* If the type variable is Not_found then it was probably - introduced by a P_var pattern, so it likely exists as - a variable in scope. It can't be an existential because the assert rules that out. *) - | None -> annot_exp (E_id (id_of_kid (orig_kid kid))) l env (atom_typ (nvar (orig_kid kid))) - | _ -> - raise (Reporting_basic.err_unreachable l - ("failed to infer nexp for type variable " ^ string_of_kid kid ^ - " of function " ^ string_of_id f)) - end in - let kid_exps = List.map kid_exp (KidSet.elements (Bindings.find f param_map)) in - (E_aux (E_app (f, kid_exps @ args), annot), orig_exp) - else (full_exp, orig_exp) - | _ -> (full_exp, orig_exp) in - - (* Plug this into a folding algorithm that also keeps around a copy of the - original expressions, which we use to infer instantiations of type variables - in the original environments *) - let copy_exp_alg = - { e_block = (fun es -> let (es, es') = List.split es in (E_block es, E_block es')) - ; e_nondet = (fun es -> let (es, es') = List.split es in (E_nondet es, E_nondet es')) - ; e_id = (fun id -> (E_id id, E_id id)) - ; e_lit = (fun lit -> (E_lit lit, E_lit lit)) - ; e_cast = (fun (typ,(e,e')) -> (E_cast (typ,e), E_cast (typ,e'))) - ; e_app = (fun (id,es) -> let (es, es') = List.split es in (E_app (id,es), E_app (id,es'))) - ; e_app_infix = (fun ((e1,e1'),id,(e2,e2')) -> (E_app_infix (e1,id,e2), E_app_infix (e1',id,e2'))) - ; e_tuple = (fun es -> let (es, es') = List.split es in (E_tuple es, E_tuple es')) - ; e_if = (fun ((e1,e1'),(e2,e2'),(e3,e3')) -> (E_if (e1,e2,e3), E_if (e1',e2',e3'))) - ; e_for = (fun (id,(e1,e1'),(e2,e2'),(e3,e3'),order,(e4,e4')) -> (E_for (id,e1,e2,e3,order,e4), E_for (id,e1',e2',e3',order,e4'))) - ; e_loop = (fun (lt, (e1, e1'), (e2, e2')) -> (E_loop (lt, e1, e2), E_loop (lt, e1', e2'))) - ; e_vector = (fun es -> let (es, es') = List.split es in (E_vector es, E_vector es')) - ; e_vector_access = (fun ((e1,e1'),(e2,e2')) -> (E_vector_access (e1,e2), E_vector_access (e1',e2'))) - ; e_vector_subrange = (fun ((e1,e1'),(e2,e2'),(e3,e3')) -> (E_vector_subrange (e1,e2,e3), E_vector_subrange (e1',e2',e3'))) - ; e_vector_update = (fun ((e1,e1'),(e2,e2'),(e3,e3')) -> (E_vector_update (e1,e2,e3), E_vector_update (e1',e2',e3'))) - ; e_vector_update_subrange = (fun ((e1,e1'),(e2,e2'),(e3,e3'),(e4,e4')) -> (E_vector_update_subrange (e1,e2,e3,e4), E_vector_update_subrange (e1',e2',e3',e4'))) - ; e_vector_append = (fun ((e1,e1'),(e2,e2')) -> (E_vector_append (e1,e2), E_vector_append (e1',e2'))) - ; e_list = (fun es -> let (es, es') = List.split es in (E_list es, E_list es')) - ; e_cons = (fun ((e1,e1'),(e2,e2')) -> (E_cons (e1,e2), E_cons (e1',e2'))) - ; e_record = (fun (fexps, fexps') -> (E_record fexps, E_record fexps')) - ; e_record_update = (fun ((e1,e1'),(fexp,fexp')) -> (E_record_update (e1,fexp), E_record_update (e1',fexp'))) - ; e_field = (fun ((e1,e1'),id) -> (E_field (e1,id), E_field (e1',id))) - ; e_case = (fun ((e1,e1'),pexps) -> let (pexps, pexps') = List.split pexps in (E_case (e1,pexps), E_case (e1',pexps'))) - ; e_let = (fun ((lb,lb'),(e2,e2')) -> (E_let (lb,e2), E_let (lb',e2'))) - ; e_assign = (fun ((lexp,lexp'),(e2,e2')) -> (E_assign (lexp,e2), E_assign (lexp',e2'))) - ; e_sizeof = (fun nexp -> (E_sizeof nexp, E_sizeof nexp)) - ; e_constraint = (fun nc -> (E_constraint nc, E_constraint nc)) - ; e_exit = (fun (e1,e1') -> (E_exit (e1), E_exit (e1'))) - ; e_return = (fun (e1,e1') -> (E_return e1, E_return e1')) - ; e_assert = (fun ((e1,e1'),(e2,e2')) -> (E_assert(e1,e2), E_assert(e1',e2')) ) - ; e_internal_cast = (fun (a,(e1,e1')) -> (E_internal_cast (a,e1), E_internal_cast (a,e1'))) - ; e_internal_exp = (fun a -> (E_internal_exp a, E_internal_exp a)) - ; e_internal_exp_user = (fun (a1,a2) -> (E_internal_exp_user (a1,a2), E_internal_exp_user (a1,a2))) - ; e_comment = (fun c -> (E_comment c, E_comment c)) - ; e_comment_struc = (fun (e,e') -> (E_comment_struc e, E_comment_struc e')) - ; e_internal_let = (fun ((lexp,lexp'), (e2,e2'), (e3,e3')) -> (E_internal_let (lexp,e2,e3), E_internal_let (lexp',e2',e3'))) - ; e_internal_plet = (fun (pat, (e1,e1'), (e2,e2')) -> (E_internal_plet (pat,e1,e2), E_internal_plet (pat,e1',e2'))) - ; e_internal_return = (fun (e,e') -> (E_internal_return e, E_internal_return e')) - ; e_aux = (fun ((e,e'),annot) -> (E_aux (e,annot), E_aux (e',annot))) - ; lEXP_id = (fun id -> (LEXP_id id, LEXP_id id)) - ; lEXP_memory = (fun (id,es) -> let (es, es') = List.split es in (LEXP_memory (id,es), LEXP_memory (id,es'))) - ; lEXP_cast = (fun (typ,id) -> (LEXP_cast (typ,id), LEXP_cast (typ,id))) - ; lEXP_tup = (fun tups -> let (tups,tups') = List.split tups in (LEXP_tup tups, LEXP_tup tups')) - ; lEXP_vector = (fun ((lexp,lexp'),(e2,e2')) -> (LEXP_vector (lexp,e2), LEXP_vector (lexp',e2'))) - ; lEXP_vector_range = (fun ((lexp,lexp'),(e2,e2'),(e3,e3')) -> (LEXP_vector_range (lexp,e2,e3), LEXP_vector_range (lexp',e2',e3'))) - ; lEXP_field = (fun ((lexp,lexp'),id) -> (LEXP_field (lexp,id), LEXP_field (lexp',id))) - ; lEXP_aux = (fun ((lexp,lexp'),annot) -> (LEXP_aux (lexp,annot), LEXP_aux (lexp',annot))) - ; fE_Fexp = (fun (id,(e,e')) -> (FE_Fexp (id,e), FE_Fexp (id,e'))) - ; fE_aux = (fun ((fexp,fexp'),annot) -> (FE_aux (fexp,annot), FE_aux (fexp',annot))) - ; fES_Fexps = (fun (fexps,b) -> let (fexps, fexps') = List.split fexps in (FES_Fexps (fexps,b), FES_Fexps (fexps',b))) - ; fES_aux = (fun ((fexp,fexp'),annot) -> (FES_aux (fexp,annot), FES_aux (fexp',annot))) - ; def_val_empty = (Def_val_empty, Def_val_empty) - ; def_val_dec = (fun (e,e') -> (Def_val_dec e, Def_val_dec e')) - ; def_val_aux = (fun ((defval,defval'),aux) -> (Def_val_aux (defval,aux), Def_val_aux (defval',aux))) - ; pat_exp = (fun (pat,(e,e')) -> (Pat_exp (pat,e), Pat_exp (pat,e'))) - ; pat_when = (fun (pat,(e1,e1'),(e2,e2')) -> (Pat_when (pat,e1,e2), Pat_when (pat,e1',e2'))) - ; pat_aux = (fun ((pexp,pexp'),a) -> (Pat_aux (pexp,a), Pat_aux (pexp',a))) - ; lB_val = (fun (pat,(e,e')) -> (LB_val (pat,e), LB_val (pat,e'))) - ; lB_aux = (fun ((lb,lb'),annot) -> (LB_aux (lb,annot), LB_aux (lb',annot))) - ; pat_alg = id_pat_alg - } in - - let rewrite_sizeof_fun params_map - (FD_aux (FD_function (rec_opt,tannot,eff,funcls),((l,_) as annot))) = - let rewrite_funcl_body (FCL_aux (FCL_Funcl (id,pat,exp), annot)) (funcls,nvars) = - let body_env = env_of exp in - let body_typ = typ_of exp in - let nmap = nexps_from_params pat in - (* first rewrite calls to other functions... *) - let exp' = fst (fold_exp { copy_exp_alg with e_aux = e_app_aux params_map } exp) in - (* ... then rewrite sizeof expressions in current function body *) - let exp'' = fold_exp { id_exp_alg with e_sizeof = e_sizeof nmap } exp' in - (FCL_aux (FCL_Funcl (id,pat,exp''), annot) :: funcls, - KidSet.union nvars (sizeof_frees exp'')) in - let (funcls, nvars) = List.fold_right rewrite_funcl_body funcls ([], KidSet.empty) in - (* Add a parameter for each remaining free type-level variable in a - sizeof expression *) - let kid_typ kid = atom_typ (nvar kid) in - let kid_annot kid = simple_annot l (kid_typ kid) in - let kid_pat kid = - P_aux (P_typ (kid_typ kid, - P_aux (P_id (Id_aux (Id (string_of_id (id_of_kid kid) ^ "__tv"), l)), - kid_annot kid)), kid_annot kid) in - let kid_eaux kid = E_id (Id_aux (Id (string_of_id (id_of_kid kid) ^ "__tv"), l)) in - let kid_typs = List.map kid_typ (KidSet.elements nvars) in - let kid_pats = List.map kid_pat (KidSet.elements nvars) in - let kid_nmap = List.map (fun kid -> (nvar kid, kid_eaux kid)) (KidSet.elements nvars) in - let rewrite_funcl_params (FCL_aux (FCL_Funcl (id, pat, exp), annot) as funcl) = - let rec rewrite_pat (P_aux (pat, ((l, _) as pannot)) as paux) = - let penv = env_of_annot pannot in - let peff = effect_of_annot (snd pannot) in - if KidSet.is_empty nvars then paux else - match pat_typ_of paux with - | Typ_aux (Typ_tup typs, _) -> - let ptyp' = Typ_aux (Typ_tup (kid_typs @ typs), l) in - (match pat with - | P_tup pats -> - P_aux (P_tup (kid_pats @ pats), (l, Some (penv, ptyp', peff))) - | P_wild -> P_aux (pat, (l, Some (penv, ptyp', peff))) - | P_typ (Typ_aux (Typ_tup typs, l), pat) -> - P_aux (P_typ (Typ_aux (Typ_tup (kid_typs @ typs), l), - rewrite_pat pat), (l, Some (penv, ptyp', peff))) - | P_as (_, id) | P_id id -> - (* adding parameters here would change the type of id; - we should remove the P_as/P_id here and add a let-binding to the body *) - raise (Reporting_basic.err_todo l - "rewriting as- or id-patterns for sizeof expressions not yet implemented") - | _ -> - raise (Reporting_basic.err_unreachable l - "unexpected pattern while rewriting function parameters for sizeof expressions")) - | ptyp -> - let ptyp' = Typ_aux (Typ_tup (kid_typs @ [ptyp]), l) in - P_aux (P_tup (kid_pats @ [paux]), (l, Some (penv, ptyp', peff))) in - let exp' = fold_exp { id_exp_alg with e_sizeof = e_sizeof kid_nmap } exp in - FCL_aux (FCL_Funcl (id, rewrite_pat pat, exp'), annot) in - let funcls = List.map rewrite_funcl_params funcls in - let fd = FD_aux (FD_function (rec_opt,tannot,eff,funcls),annot) in - let params_map = - if KidSet.is_empty nvars then params_map else - Bindings.add (id_of_fundef fd) nvars params_map in - (params_map, FD_aux (FD_function (rec_opt,tannot,eff,funcls),annot)) in - - let rewrite_sizeof_def (params_map, defs) = function - | DEF_fundef fd -> - let (params_map', fd') = rewrite_sizeof_fun params_map fd in - (params_map', defs @ [DEF_fundef fd']) - | DEF_internal_mutrec fds -> - let rewrite_fd (params_map, fds) fd = - let (params_map', fd') = rewrite_sizeof_fun params_map fd in - (params_map', fds @ [fd']) in - (* TODO Split rewrite_sizeof_fun into an analysis and a rewrite pass, - so that we can call the analysis until a fixpoint is reached and then - rewrite the mutually recursive functions *) - let (params_map', fds') = List.fold_left rewrite_fd (params_map, []) fds in - (params_map', defs @ [DEF_internal_mutrec fds']) - | DEF_val (LB_aux (lb, annot)) -> - begin - let lb' = match lb with - | LB_val (pat, exp) -> - let exp' = fst (fold_exp { copy_exp_alg with e_aux = e_app_aux params_map } exp) in - LB_val (pat, exp') in - (params_map, defs @ [DEF_val (LB_aux (lb', annot))]) - end - | def -> - (params_map, defs @ [def]) in - - let rewrite_sizeof_valspec params_map def = - let rewrite_typschm (TypSchm_aux (TypSchm_ts (tq, typ), l) as ts) id = - if Bindings.mem id params_map then - let kid_typs = List.map (fun kid -> atom_typ (nvar kid)) - (KidSet.elements (Bindings.find id params_map)) in - let typ' = match typ with - | Typ_aux (Typ_fn (vtyp_arg, vtyp_ret, declared_eff), vl) -> - let vtyp_arg' = begin - match vtyp_arg with - | Typ_aux (Typ_tup typs, vl) -> - Typ_aux (Typ_tup (kid_typs @ typs), vl) - | _ -> Typ_aux (Typ_tup (kid_typs @ [vtyp_arg]), vl) - end in - Typ_aux (Typ_fn (vtyp_arg', vtyp_ret, declared_eff), vl) - | _ -> - raise (Reporting_basic.err_typ l "val spec with non-function type") in - TypSchm_aux (TypSchm_ts (tq, typ'), l) - else ts in - match def with - | DEF_spec (VS_aux (VS_val_spec (typschm, id, ext, is_cast), a)) -> - DEF_spec (VS_aux (VS_val_spec (rewrite_typschm typschm id, id, ext, is_cast), a)) - | def -> def - in - - let (params_map, defs) = List.fold_left rewrite_sizeof_def - (Bindings.empty, []) defs in - let defs = List.map (rewrite_sizeof_valspec params_map) defs in - fst (check initial_env (Defs defs)) - -let rewrite_defs_remove_assert defs = - let e_assert ((E_aux (eaux, (l, _)) as exp), str) = match eaux with - | E_constraint _ -> - E_assert (exp, str) - | _ -> - E_assert (E_aux (E_lit (mk_lit L_true), simple_annot l bool_typ), str) in - rewrite_defs_base - { rewriters_base with - rewrite_exp = (fun _ -> fold_exp { id_exp_alg with e_assert = e_assert}) } - defs - -let remove_vector_concat_pat pat = - - (* ivc: bool that indicates whether the exp is in a vector_concat pattern *) - let remove_typed_patterns = - fold_pat { id_pat_alg with - p_aux = (function - | (P_typ (_,P_aux (p,_)),annot) - | (p,annot) -> - P_aux (p,annot) - ) - } in - - (* let pat = remove_typed_patterns pat in *) - - let fresh_id_v = fresh_id "v__" in - - (* expects that P_typ elements have been removed from AST, - that the length of all vectors involved is known, - that we don't have indexed vectors *) - - (* introduce names for all patterns of form P_vector_concat *) - let name_vector_concat_roots = - { p_lit = (fun lit -> P_lit lit) - ; p_typ = (fun (typ,p) -> P_typ (typ,p false)) (* cannot happen *) - ; p_wild = P_wild - ; p_as = (fun (pat,id) -> P_as (pat true,id)) - ; p_id = (fun id -> P_id id) - ; p_var = (fun (pat,kid) -> P_var (pat true,kid)) - ; p_app = (fun (id,ps) -> P_app (id, List.map (fun p -> p false) ps)) - ; p_record = (fun (fpats,b) -> P_record (fpats, b)) - ; p_vector = (fun ps -> P_vector (List.map (fun p -> p false) ps)) - ; p_vector_concat = (fun ps -> P_vector_concat (List.map (fun p -> p false) ps)) - ; p_tup = (fun ps -> P_tup (List.map (fun p -> p false) ps)) - ; p_list = (fun ps -> P_list (List.map (fun p -> p false) ps)) - ; p_cons = (fun (p,ps) -> P_cons (p false, ps false)) - ; p_aux = - (fun (pat,((l,_) as annot)) contained_in_p_as -> - match pat with - | P_vector_concat pats -> - (if contained_in_p_as - then P_aux (pat,annot) - else P_aux (P_as (P_aux (pat,annot),fresh_id_v l),annot)) - | _ -> P_aux (pat,annot) - ) - ; fP_aux = (fun (fpat,annot) -> FP_aux (fpat,annot)) - ; fP_Fpat = (fun (id,p) -> FP_Fpat (id,p false)) - } in - - let pat = (fold_pat name_vector_concat_roots pat) false in - - (* introduce names for all unnamed child nodes of P_vector_concat *) - let name_vector_concat_elements = - let p_vector_concat pats = - let rec aux ((P_aux (p,((l,_) as a))) as pat) = match p with - | P_vector _ -> P_aux (P_as (pat,fresh_id_v l),a) - | P_id id -> P_aux (P_id id,a) - | P_as (p,id) -> P_aux (P_as (p,id),a) - | P_typ (typ, pat) -> P_aux (P_typ (typ, aux pat),a) - | P_wild -> P_aux (P_wild,a) - | _ -> - raise - (Reporting_basic.err_unreachable - l "name_vector_concat_elements: Non-vector in vector-concat pattern") in - P_vector_concat (List.map aux pats) in - {id_pat_alg with p_vector_concat = p_vector_concat} in - - let pat = fold_pat name_vector_concat_elements pat in - - - - let rec tag_last = function - | x :: xs -> let is_last = xs = [] in (x,is_last) :: tag_last xs - | _ -> [] in - - (* remove names from vectors in vector_concat patterns and collect them as declarations for the - function body or expression *) - let unname_vector_concat_elements = (* : - ('a, - 'a pat * ((tannot exp -> tannot exp) list), - 'a pat_aux * ((tannot exp -> tannot exp) list), - 'a fpat * ((tannot exp -> tannot exp) list), - 'a fpat_aux * ((tannot exp -> tannot exp) list)) - pat_alg = *) - - (* build a let-expression of the form "let child = root[i..j] in body" *) - let letbind_vec typ_opt (rootid,rannot) (child,cannot) (i,j) = - let (l,_) = cannot in - let env = env_of_annot rannot in - let rootname = string_of_id rootid in - let childname = string_of_id child in - - let root = E_aux (E_id rootid, rannot) in - let index_i = simple_num l i in - let index_j = simple_num l j in - - (* FIXME *) - let subv = fix_eff_exp (E_aux (E_vector_subrange (root, index_i, index_j), cannot)) in - (* let (_, _, ord, _) = vector_typ_args_of (Env.base_typ_of (env_of root) (typ_of root)) in - let subrange_id = if is_order_inc ord then "bitvector_subrange_inc" else "bitvector_subrange_dec" in - let subv = fix_eff_exp (E_aux (E_app (mk_id subrange_id, [root; index_i; index_j]), cannot)) in *) - - let id_pat = - match typ_opt with - | Some typ -> P_aux (P_typ (typ, P_aux (P_id child,cannot)), cannot) - | None -> P_aux (P_id child,cannot) in - let letbind = fix_eff_lb (LB_aux (LB_val (id_pat,subv),cannot)) in - (letbind, - (fun body -> fix_eff_exp (annot_exp (E_let (letbind,body)) l env (typ_of body))), - (rootname,childname)) in - - let p_aux = function - | ((P_as (P_aux (P_vector_concat pats,rannot'),rootid),decls),rannot) -> - let rtyp = Env.base_typ_of (env_of_annot rannot') (typ_of_annot rannot') in - let (start,last_idx) = (match vector_typ_args_of rtyp with - | (Nexp_aux (Nexp_constant start,_), Nexp_aux (Nexp_constant length,_), ord, _) -> - (start, if is_order_inc ord - then sub_big_int (add_big_int start length) unit_big_int - else add_big_int (sub_big_int start length) unit_big_int) - | _ -> - raise (Reporting_basic.err_unreachable (fst rannot') - ("unname_vector_concat_elements: vector of unspecified length in vector-concat pattern"))) in - let rec aux typ_opt (pos,pat_acc,decl_acc) (P_aux (p,cannot),is_last) = - let ctyp = Env.base_typ_of (env_of_annot cannot) (typ_of_annot cannot) in - let (_,length,ord,_) = vector_typ_args_of ctyp in - let (pos',index_j) = match length with - | Nexp_aux (Nexp_constant i,_) -> - if is_order_inc ord - then (add_big_int pos i, sub_big_int (add_big_int pos i) unit_big_int) - else (sub_big_int pos i, add_big_int (sub_big_int pos i) unit_big_int) - | Nexp_aux (_,l) -> - if is_last then (pos,last_idx) - else - raise - (Reporting_basic.err_unreachable - l ("unname_vector_concat_elements: vector of unspecified length in vector-concat pattern")) in - (match p with - (* if we see a named vector pattern, remove the name and remember to - declare it later *) - | P_as (P_aux (p,cannot),cname) -> - let (lb,decl,info) = letbind_vec typ_opt (rootid,rannot) (cname,cannot) (pos,index_j) in - (pos', pat_acc @ [P_aux (p,cannot)], decl_acc @ [((lb,decl),info)]) - (* if we see a P_id variable, remember to declare it later *) - | P_id cname -> - let (lb,decl,info) = letbind_vec typ_opt (rootid,rannot) (cname,cannot) (pos,index_j) in - (pos', pat_acc @ [P_aux (P_id cname,cannot)], decl_acc @ [((lb,decl),info)]) - | P_typ (typ, pat) -> aux (Some typ) (pos,pat_acc,decl_acc) (pat, is_last) - (* normal vector patterns are fine *) - | _ -> (pos', pat_acc @ [P_aux (p,cannot)],decl_acc)) in - let pats_tagged = tag_last pats in - let (_,pats',decls') = List.fold_left (aux None) (start,[],[]) pats_tagged in - - (* abuse P_vector_concat as a P_vector_const pattern: it has the of - patterns as an argument but they're meant to be consed together *) - (P_aux (P_as (P_aux (P_vector_concat pats',rannot'),rootid),rannot), decls @ decls') - | ((p,decls),annot) -> (P_aux (p,annot),decls) in - - { p_lit = (fun lit -> (P_lit lit,[])) - ; p_wild = (P_wild,[]) - ; p_as = (fun ((pat,decls),id) -> (P_as (pat,id),decls)) - ; p_typ = (fun (typ,(pat,decls)) -> (P_typ (typ,pat),decls)) - ; p_id = (fun id -> (P_id id,[])) - ; p_var = (fun ((pat,decls),kid) -> (P_var (pat,kid),decls)) - ; p_app = (fun (id,ps) -> let (ps,decls) = List.split ps in - (P_app (id,ps),List.flatten decls)) - ; p_record = (fun (ps,b) -> let (ps,decls) = List.split ps in - (P_record (ps,b),List.flatten decls)) - ; p_vector = (fun ps -> let (ps,decls) = List.split ps in - (P_vector ps,List.flatten decls)) - ; p_vector_concat = (fun ps -> let (ps,decls) = List.split ps in - (P_vector_concat ps,List.flatten decls)) - ; p_tup = (fun ps -> let (ps,decls) = List.split ps in - (P_tup ps,List.flatten decls)) - ; p_list = (fun ps -> let (ps,decls) = List.split ps in - (P_list ps,List.flatten decls)) - ; p_cons = (fun ((p,decls),(p',decls')) -> (P_cons (p,p'), decls @ decls')) - ; p_aux = (fun ((pat,decls),annot) -> p_aux ((pat,decls),annot)) - ; fP_aux = (fun ((fpat,decls),annot) -> (FP_aux (fpat,annot),decls)) - ; fP_Fpat = (fun (id,(pat,decls)) -> (FP_Fpat (id,pat),decls)) - } in - - let (pat,decls) = fold_pat unname_vector_concat_elements pat in - - let decls = - let module S = Set.Make(String) in - - let roots_needed = - List.fold_right - (fun (_,(rootid,childid)) roots_needed -> - if S.mem childid roots_needed then - (* let _ = print_endline rootid in *) - S.add rootid roots_needed - else if String.length childid >= 3 && String.sub childid 0 2 = String.sub "v__" 0 2 then - roots_needed - else - S.add rootid roots_needed - ) decls S.empty in - List.filter - (fun (_,(_,childid)) -> - S.mem childid roots_needed || - String.length childid < 3 || - not (String.sub childid 0 2 = String.sub "v__" 0 2)) - decls in - - let (letbinds,decls) = - let (decls,_) = List.split decls in - List.split decls in - - let decls = List.fold_left (fun f g x -> f (g x)) (fun b -> b) decls in - - - (* at this point shouldn't have P_as patterns in P_vector_concat patterns any more, - all P_as and P_id vectors should have their declarations in decls. - Now flatten all vector_concat patterns *) - - let flatten = - let p_vector_concat ps = - let aux p acc = match p with - | (P_aux (P_vector_concat pats,_)) -> pats @ acc - | pat -> pat :: acc in - P_vector_concat (List.fold_right aux ps []) in - {id_pat_alg with p_vector_concat = p_vector_concat} in - - let pat = fold_pat flatten pat in - - (* at this point pat should be a flat pattern: no vector_concat patterns - with vector_concats patterns as direct child-nodes anymore *) - - let range a b = - let rec aux a b = if gt_big_int a b then [] else a :: aux (add_big_int a unit_big_int) b in - if gt_big_int a b then List.rev (aux b a) else aux a b in - - let remove_vector_concats = - let p_vector_concat ps = - let aux acc (P_aux (p,annot),is_last) = - let env = env_of_annot annot in - let typ = Env.base_typ_of env (typ_of_annot annot) in - let eff = effect_of_annot (snd annot) in - let (l,_) = annot in - let wild _ = P_aux (P_wild,(gen_loc l, Some (env, bit_typ, eff))) in - if is_vector_typ typ then - match p, vector_typ_args_of typ with - | P_vector ps,_ -> acc @ ps - | _, (_,Nexp_aux (Nexp_constant length,_),_,_) -> - acc @ (List.map wild (range zero_big_int (sub_big_int length unit_big_int))) - | _, _ -> - (*if is_last then*) acc @ [wild zero_big_int] - else raise - (Reporting_basic.err_unreachable l - ("remove_vector_concats: Non-vector in vector-concat pattern " ^ - string_of_typ (typ_of_annot annot))) in - - let has_length (P_aux (p,annot)) = - let typ = Env.base_typ_of (env_of_annot annot) (typ_of_annot annot) in - match vector_typ_args_of typ with - | (_,Nexp_aux (Nexp_constant length,_),_,_) -> true - | _ -> false in - - let ps_tagged = tag_last ps in - let ps' = List.fold_left aux [] ps_tagged in - let last_has_length ps = List.exists (fun (p,b) -> b && has_length p) ps_tagged in - - if last_has_length ps then - P_vector ps' - else - (* If the last vector pattern in the vector_concat pattern has unknown - length we misuse the P_vector_concat constructor's argument to place in - the following way: P_vector_concat [x;y; ... ;z] should be mapped to the - pattern-match x :: y :: .. z, i.e. if x : 'a, then z : vector 'a. *) - P_vector_concat ps' in - - {id_pat_alg with p_vector_concat = p_vector_concat} in - - let pat = fold_pat remove_vector_concats pat in - - (pat,letbinds,decls) - -(* assumes there are no more E_internal expressions *) -let rewrite_exp_remove_vector_concat_pat rewriters (E_aux (exp,(l,annot)) as full_exp) = - let rewrap e = E_aux (e,(l,annot)) in - let rewrite_rec = rewriters.rewrite_exp rewriters in - let rewrite_base = rewrite_exp rewriters in - match exp with - | E_case (e,ps) -> - let aux = function - | (Pat_aux (Pat_exp (pat,body),annot')) -> - let (pat,_,decls) = remove_vector_concat_pat pat in - Pat_aux (Pat_exp (pat, decls (rewrite_rec body)),annot') - | (Pat_aux (Pat_when (pat,guard,body),annot')) -> - let (pat,_,decls) = remove_vector_concat_pat pat in - Pat_aux (Pat_when (pat, decls (rewrite_rec guard), decls (rewrite_rec body)),annot') in - rewrap (E_case (rewrite_rec e, List.map aux ps)) - | E_let (LB_aux (LB_val (pat,v),annot'),body) -> - let (pat,_,decls) = remove_vector_concat_pat pat in - rewrap (E_let (LB_aux (LB_val (pat,rewrite_rec v),annot'), - decls (rewrite_rec body))) - | exp -> rewrite_base full_exp - -let rewrite_fun_remove_vector_concat_pat - rewriters (FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),(l,fdannot))) = - let rewrite_funcl (FCL_aux (FCL_Funcl(id,pat,exp),(l,annot))) = - let (pat',_,decls) = remove_vector_concat_pat pat in - let exp' = decls (rewriters.rewrite_exp rewriters exp) in - (FCL_aux (FCL_Funcl (id,pat',exp'),(l,annot))) - in FD_aux (FD_function(recopt,tannotopt,effectopt,List.map rewrite_funcl funcls),(l,fdannot)) - -let rewrite_defs_remove_vector_concat (Defs defs) = - let rewriters = - {rewrite_exp = rewrite_exp_remove_vector_concat_pat; - rewrite_pat = rewrite_pat; - rewrite_let = rewrite_let; - rewrite_lexp = rewrite_lexp; - rewrite_fun = rewrite_fun_remove_vector_concat_pat; - rewrite_def = rewrite_def; - rewrite_defs = rewrite_defs_base} in - let rewrite_def d = - let d = rewriters.rewrite_def rewriters d in - match d with - | DEF_val (LB_aux (LB_val (pat,exp),a)) -> - let (pat,letbinds,_) = remove_vector_concat_pat pat in - let defvals = List.map (fun lb -> DEF_val lb) letbinds in - [DEF_val (LB_aux (LB_val (pat,exp),a))] @ defvals - | d -> [d] in - Defs (List.flatten (List.map rewrite_def defs)) - -(* A few helper functions for rewriting guarded pattern clauses. - Used both by the rewriting of P_when and separately by the rewriting of - bitvectors in parameter patterns of function clauses *) - -let remove_wildcards pre (P_aux (_,(l,_)) as pat) = - fold_pat - {id_pat_alg with - p_aux = function - | (P_wild,(l,annot)) -> P_aux (P_id (fresh_id pre l),(l,annot)) - | (p,annot) -> P_aux (p,annot) } - pat - -(* Check if one pattern subsumes the other, and if so, calculate a - substitution of variables that are used in the same position. - TODO: Check somewhere that there are no variable clashes (the same variable - name used in different positions of the patterns) - *) -let rec subsumes_pat (P_aux (p1,annot1) as pat1) (P_aux (p2,annot2) as pat2) = - let rewrap p = P_aux (p,annot1) in - let subsumes_list s pats1 pats2 = - if List.length pats1 = List.length pats2 - then - let subs = List.map2 s pats1 pats2 in - List.fold_right - (fun p acc -> match p, acc with - | Some subst, Some substs -> Some (subst @ substs) - | _ -> None) - subs (Some []) - else None in - match p1, p2 with - | P_lit (L_aux (lit1,_)), P_lit (L_aux (lit2,_)) -> - if lit1 = lit2 then Some [] else None - | P_as (pat1,_), _ -> subsumes_pat pat1 pat2 - | _, P_as (pat2,_) -> subsumes_pat pat1 pat2 - | P_typ (_,pat1), _ -> subsumes_pat pat1 pat2 - | _, P_typ (_,pat2) -> subsumes_pat pat1 pat2 - | P_id (Id_aux (id1,_) as aid1), P_id (Id_aux (id2,_) as aid2) -> - if id1 = id2 then Some [] - else if Env.lookup_id aid1 (env_of_annot annot1) = Unbound && - Env.lookup_id aid2 (env_of_annot annot2) = Unbound - then Some [(id2,id1)] else None - | P_id id1, _ -> - if Env.lookup_id id1 (env_of_annot annot1) = Unbound then Some [] else None - | P_wild, _ -> Some [] - | P_app (Id_aux (id1,l1),args1), P_app (Id_aux (id2,_),args2) -> - if id1 = id2 then subsumes_list subsumes_pat args1 args2 else None - | P_record (fps1,b1), P_record (fps2,b2) -> - if b1 = b2 then subsumes_list subsumes_fpat fps1 fps2 else None - | P_vector pats1, P_vector pats2 - | P_vector_concat pats1, P_vector_concat pats2 - | P_tup pats1, P_tup pats2 - | P_list pats1, P_list pats2 -> - subsumes_list subsumes_pat pats1 pats2 - | P_list (pat1 :: pats1), P_cons _ -> - subsumes_pat (rewrap (P_cons (pat1, rewrap (P_list pats1)))) pat2 - | P_cons _, P_list (pat2 :: pats2)-> - subsumes_pat pat1 (rewrap (P_cons (pat2, rewrap (P_list pats2)))) - | P_cons (pat1, pats1), P_cons (pat2, pats2) -> - (match subsumes_pat pat1 pat2, subsumes_pat pats1 pats2 with - | Some substs1, Some substs2 -> Some (substs1 @ substs2) - | _ -> None) - | _ -> None -and subsumes_fpat (FP_aux (FP_Fpat (id1,pat1),_)) (FP_aux (FP_Fpat (id2,pat2),_)) = - if id1 = id2 then subsumes_pat pat1 pat2 else None - -let equiv_pats pat1 pat2 = - match subsumes_pat pat1 pat2, subsumes_pat pat2 pat1 with - | Some _, Some _ -> true - | _, _ -> false - -let subst_id_pat pat (id1,id2) = - let p_id (Id_aux (id,l)) = (if id = id1 then P_id (Id_aux (id2,l)) else P_id (Id_aux (id,l))) in - fold_pat {id_pat_alg with p_id = p_id} pat - -let subst_id_exp exp (id1,id2) = - (* TODO Don't substitute bound occurrences inside let expressions etc *) - let e_id (Id_aux (id,l)) = (if id = id1 then E_id (Id_aux (id2,l)) else E_id (Id_aux (id,l))) in - fold_exp {id_exp_alg with e_id = e_id} exp - -let rec pat_to_exp (P_aux (pat,(l,annot))) = - let rewrap e = E_aux (e,(l,annot)) in - match pat with - | P_lit lit -> rewrap (E_lit lit) - | P_wild -> raise (Reporting_basic.err_unreachable l - "pat_to_exp given wildcard pattern") - | P_as (pat,id) -> rewrap (E_id id) - | P_typ (_,pat) -> pat_to_exp pat - | P_id id -> rewrap (E_id id) - | P_app (id,pats) -> rewrap (E_app (id, List.map pat_to_exp pats)) - | P_record (fpats,b) -> - rewrap (E_record (FES_aux (FES_Fexps (List.map fpat_to_fexp fpats,b),(l,annot)))) - | P_vector pats -> rewrap (E_vector (List.map pat_to_exp pats)) - | P_vector_concat pats -> raise (Reporting_basic.err_unreachable l - "pat_to_exp not implemented for P_vector_concat") - (* We assume that vector concatenation patterns have been transformed - away already *) - | P_tup pats -> rewrap (E_tuple (List.map pat_to_exp pats)) - | P_list pats -> rewrap (E_list (List.map pat_to_exp pats)) - | P_cons (p,ps) -> rewrap (E_cons (pat_to_exp p, pat_to_exp ps)) -and fpat_to_fexp (FP_aux (FP_Fpat (id,pat),(l,annot))) = - FE_aux (FE_Fexp (id, pat_to_exp pat),(l,annot)) - -let case_exp e t cs = - let l = get_loc_exp e in - let env = env_of e in - let annot = (get_loc_exp e, Some (env_of e, t, no_effect)) in - match cs with - | [(P_aux (P_id id, pannot) as pat, body, _)] -> - fix_eff_exp (annot_exp (E_let (LB_aux (LB_val (pat, e), pannot), body)) l env t) - | _ -> - let pexp (pat,body,annot) = Pat_aux (Pat_exp (pat,body),annot) in - let ps = List.map pexp cs in - (* let efr = union_effs (List.map effect_of_pexp ps) in *) - fix_eff_exp (annot_exp (E_case (e,ps)) l env t) - -let rewrite_guarded_clauses l cs = - let rec group clauses = - let add_clause (pat,cls,annot) c = (pat,cls @ [c],annot) in - let rec group_aux current acc = (function - | ((pat,guard,body,annot) as c) :: cs -> - let (current_pat,_,_) = current in - (match subsumes_pat current_pat pat with - | Some substs -> - let pat' = List.fold_left subst_id_pat pat substs in - let guard' = (match guard with - | Some exp -> Some (List.fold_left subst_id_exp exp substs) - | None -> None) in - let body' = List.fold_left subst_id_exp body substs in - let c' = (pat',guard',body',annot) in - group_aux (add_clause current c') acc cs - | None -> - let pat = remove_wildcards "g__" pat in - group_aux (pat,[c],annot) (acc @ [current]) cs) - | [] -> acc @ [current]) in - let groups = match clauses with - | ((pat,guard,body,annot) as c) :: cs -> - group_aux (remove_wildcards "g__" pat, [c], annot) [] cs - | _ -> - raise (Reporting_basic.err_unreachable l - "group given empty list in rewrite_guarded_clauses") in - List.map (fun cs -> if_pexp cs) groups - and if_pexp (pat,cs,annot) = (match cs with - | c :: _ -> - (* fix_eff_pexp (pexp *) - let body = if_exp pat cs in - let pexp = fix_eff_pexp (Pat_aux (Pat_exp (pat,body),annot)) in - let (Pat_aux (_,annot)) = pexp in - (pat, body, annot) - | [] -> - raise (Reporting_basic.err_unreachable l - "if_pexp given empty list in rewrite_guarded_clauses")) - and if_exp current_pat = (function - | (pat,guard,body,annot) :: ((pat',guard',body',annot') as c') :: cs -> - (match guard with - | Some exp -> - let else_exp = - if equiv_pats current_pat pat' - then if_exp current_pat (c' :: cs) - else case_exp (pat_to_exp current_pat) (typ_of body') (group (c' :: cs)) in - fix_eff_exp (annot_exp (E_if (exp,body,else_exp)) (fst annot) (env_of exp) (typ_of body)) - | None -> body) - | [(pat,guard,body,annot)] -> body - | [] -> - raise (Reporting_basic.err_unreachable l - "if_exp given empty list in rewrite_guarded_clauses")) in - group cs - -let bitwise_and_exp exp1 exp2 = - let (E_aux (_,(l,_))) = exp1 in - let andid = Id_aux (Id "and_bool", gen_loc l) in - annot_exp (E_app(andid,[exp1;exp2])) l (env_of exp1) bool_typ - -let rec contains_bitvector_pat (P_aux (pat,annot)) = match pat with -| P_lit _ | P_wild | P_id _ -> false -| P_as (pat,_) | P_typ (_,pat) -> contains_bitvector_pat pat -| P_vector _ | P_vector_concat _ -> - let typ = Env.base_typ_of (env_of_annot annot) (typ_of_annot annot) in - is_bitvector_typ typ -| P_app (_,pats) | P_tup pats | P_list pats -> - List.exists contains_bitvector_pat pats -| P_cons (p,ps) -> contains_bitvector_pat p || contains_bitvector_pat ps -| P_record (fpats,_) -> - List.exists (fun (FP_aux (FP_Fpat (_,pat),_)) -> contains_bitvector_pat pat) fpats - -let contains_bitvector_pexp = function -| Pat_aux (Pat_exp (pat,_),_) | Pat_aux (Pat_when (pat,_,_),_) -> - contains_bitvector_pat pat - -(* Rewrite bitvector patterns to guarded patterns *) - -let remove_bitvector_pat (P_aux (_, (l, _)) as pat) = - - let env = try pat_env_of pat with _ -> Env.empty in - - (* first introduce names for bitvector patterns *) - let name_bitvector_roots = - { p_lit = (fun lit -> P_lit lit) - ; p_typ = (fun (typ,p) -> P_typ (typ,p false)) - ; p_wild = P_wild - ; p_as = (fun (pat,id) -> P_as (pat true,id)) - ; p_id = (fun id -> P_id id) - ; p_var = (fun (pat,kid) -> P_var (pat true,kid)) - ; p_app = (fun (id,ps) -> P_app (id, List.map (fun p -> p false) ps)) - ; p_record = (fun (fpats,b) -> P_record (fpats, b)) - ; p_vector = (fun ps -> P_vector (List.map (fun p -> p false) ps)) - ; p_vector_concat = (fun ps -> P_vector_concat (List.map (fun p -> p false) ps)) - ; p_tup = (fun ps -> P_tup (List.map (fun p -> p false) ps)) - ; p_list = (fun ps -> P_list (List.map (fun p -> p false) ps)) - ; p_cons = (fun (p,ps) -> P_cons (p false, ps false)) - ; p_aux = - (fun (pat,annot) contained_in_p_as -> - let env = env_of_annot annot in - let t = Env.base_typ_of env (typ_of_annot annot) in - let (l,_) = annot in - match pat, is_bitvector_typ t, contained_in_p_as with - | P_vector _, true, false -> - P_aux (P_as (P_aux (pat,annot),fresh_id "b__" l), annot) - | _ -> P_aux (pat,annot) - ) - ; fP_aux = (fun (fpat,annot) -> FP_aux (fpat,annot)) - ; fP_Fpat = (fun (id,p) -> FP_Fpat (id,p false)) - } in - let pat, env = bind_pat env - (strip_pat ((fold_pat name_bitvector_roots pat) false)) - (pat_typ_of pat) in - - (* Then collect guard expressions testing whether the literal bits of a - bitvector pattern match those of a given bitvector, and collect let - bindings for the bits bound by P_id or P_as patterns *) - - (* Helper functions for generating guard expressions *) - let mk_exp e_aux = E_aux (e_aux, (l, ())) in - let mk_num_exp i = mk_lit_exp (L_num i) in - let check_eq_exp l r = - let exp = mk_exp (E_app_infix (l, Id_aux (DeIid "==", Parse_ast.Unknown), r)) in - check_exp env exp bool_typ in - - let access_bit_exp rootid l typ idx = - let access_aux = E_vector_access (mk_exp (E_id rootid), mk_num_exp idx) in - check_exp env (mk_exp access_aux) bit_typ in - - let test_bit_exp rootid l typ idx exp = - let elem = access_bit_exp rootid l typ idx in - Some (check_eq_exp (strip_exp elem) (strip_exp exp)) in - - let test_subvec_exp rootid l typ i j lits = - let (start, length, ord, _) = vector_typ_args_of typ in - let subvec_exp = - match start, length with - | Nexp_aux (Nexp_constant s, _), Nexp_aux (Nexp_constant l, _) - when eq_big_int s i && eq_big_int l (big_int_of_int (List.length lits)) -> - mk_exp (E_id rootid) - | _ -> - mk_exp (E_vector_subrange (mk_exp (E_id rootid), mk_num_exp i, mk_num_exp j)) in - check_eq_exp subvec_exp (mk_exp (E_vector (List.map strip_exp lits))) in - - let letbind_bit_exp rootid l typ idx id = - let rannot = simple_annot l typ in - let elem = access_bit_exp rootid l typ idx in - let e = annot_pat (P_id id) l env bit_typ in - let letbind = LB_aux (LB_val (e,elem), (l, Some (env, bit_typ, no_effect))) in - let letexp = (fun body -> - let (E_aux (_,(_,bannot))) = body in - annot_exp (E_let (letbind,body)) l env (typ_of body)) in - (letexp, letbind) in - - let compose_guards guards = - let conj g1 g2 = match g1, g2 with - | Some g1, Some g2 -> Some (bitwise_and_exp g1 g2) - | Some g1, None -> Some g1 - | None, Some g2 -> Some g2 - | None, None -> None in - List.fold_right conj guards None in - - let flatten_guards_decls gd = - let (guards,decls,letbinds) = Util.split3 gd in - (compose_guards guards, (List.fold_right (@@) decls), List.flatten letbinds) in - - (* Collect guards and let bindings *) - let guard_bitvector_pat = - let collect_guards_decls ps rootid t = - let (start,_,ord,_) = vector_typ_args_of t in - let rec collect current (guards,dls) idx ps = - let idx' = if is_order_inc ord then add_big_int idx unit_big_int else sub_big_int idx unit_big_int in - (match ps with - | pat :: ps' -> - (match pat with - | P_aux (P_lit lit, (l,annot)) -> - let e = E_aux (E_lit lit, (gen_loc l, annot)) in - let current' = (match current with - | Some (l,i,j,lits) -> Some (l,i,idx,lits @ [e]) - | None -> Some (l,idx,idx,[e])) in - collect current' (guards, dls) idx' ps' - | P_aux (P_as (pat',id), (l,annot)) -> - let dl = letbind_bit_exp rootid l t idx id in - collect current (guards, dls @ [dl]) idx (pat' :: ps') - | _ -> - let dls' = (match pat with - | P_aux (P_id id, (l,annot)) -> - dls @ [letbind_bit_exp rootid l t idx id] - | _ -> dls) in - let guards' = (match current with - | Some (l,i,j,lits) -> - guards @ [Some (test_subvec_exp rootid l t i j lits)] - | None -> guards) in - collect None (guards', dls') idx' ps') - | [] -> - let guards' = (match current with - | Some (l,i,j,lits) -> - guards @ [Some (test_subvec_exp rootid l t i j lits)] - | None -> guards) in - (guards',dls)) in - let (guards,dls) = match start with - | Nexp_aux (Nexp_constant s, _) -> - collect None ([],[]) s ps - | _ -> - let (P_aux (_, (l,_))) = pat in - raise (Reporting_basic.err_unreachable l - "guard_bitvector_pat called on pattern with non-constant start index") in - let (decls,letbinds) = List.split dls in - (compose_guards guards, List.fold_right (@@) decls, letbinds) in - - let collect_guards_decls_indexed ips rootid t = - let rec guard_decl (idx,pat) = (match pat with - | P_aux (P_lit lit, (l,annot)) -> - let exp = E_aux (E_lit lit, (l,annot)) in - (test_bit_exp rootid l t idx exp, (fun b -> b), []) - | P_aux (P_as (pat',id), (l,annot)) -> - let (guard,decls,letbinds) = guard_decl (idx,pat') in - let (letexp,letbind) = letbind_bit_exp rootid l t idx id in - (guard, decls >> letexp, letbind :: letbinds) - | P_aux (P_id id, (l,annot)) -> - let (letexp,letbind) = letbind_bit_exp rootid l t idx id in - (None, letexp, [letbind]) - | _ -> (None, (fun b -> b), [])) in - let (guards,decls,letbinds) = Util.split3 (List.map guard_decl ips) in - (compose_guards guards, List.fold_right (@@) decls, List.flatten letbinds) in - - { p_lit = (fun lit -> (P_lit lit, (None, (fun b -> b), []))) - ; p_wild = (P_wild, (None, (fun b -> b), [])) - ; p_as = (fun ((pat,gdls),id) -> (P_as (pat,id), gdls)) - ; p_typ = (fun (typ,(pat,gdls)) -> (P_typ (typ,pat), gdls)) - ; p_id = (fun id -> (P_id id, (None, (fun b -> b), []))) - ; p_var = (fun ((pat,gdls),kid) -> (P_var (pat,kid), gdls)) - ; p_app = (fun (id,ps) -> let (ps,gdls) = List.split ps in - (P_app (id,ps), flatten_guards_decls gdls)) - ; p_record = (fun (ps,b) -> let (ps,gdls) = List.split ps in - (P_record (ps,b), flatten_guards_decls gdls)) - ; p_vector = (fun ps -> let (ps,gdls) = List.split ps in - (P_vector ps, flatten_guards_decls gdls)) - ; p_vector_concat = (fun ps -> let (ps,gdls) = List.split ps in - (P_vector_concat ps, flatten_guards_decls gdls)) - ; p_tup = (fun ps -> let (ps,gdls) = List.split ps in - (P_tup ps, flatten_guards_decls gdls)) - ; p_list = (fun ps -> let (ps,gdls) = List.split ps in - (P_list ps, flatten_guards_decls gdls)) - ; p_cons = (fun ((p,gdls),(p',gdls')) -> - (P_cons (p,p'), flatten_guards_decls [gdls;gdls'])) - ; p_aux = (fun ((pat,gdls),annot) -> - let env = env_of_annot annot in - let t = Env.base_typ_of env (typ_of_annot annot) in - (match pat, is_bitvector_typ t with - | P_as (P_aux (P_vector ps, _), id), true -> - (P_aux (P_id id, annot), collect_guards_decls ps id t) - | _, _ -> (P_aux (pat,annot), gdls))) - ; fP_aux = (fun ((fpat,gdls),annot) -> (FP_aux (fpat,annot), gdls)) - ; fP_Fpat = (fun (id,(pat,gdls)) -> (FP_Fpat (id,pat), gdls)) - } in - fold_pat guard_bitvector_pat pat - -let rewrite_exp_remove_bitvector_pat rewriters (E_aux (exp,(l,annot)) as full_exp) = - let rewrap e = E_aux (e,(l,annot)) in - let rewrite_rec = rewriters.rewrite_exp rewriters in - let rewrite_base = rewrite_exp rewriters in - match exp with - | E_case (e,ps) - when List.exists contains_bitvector_pexp ps -> - let rewrite_pexp = function - | Pat_aux (Pat_exp (pat,body),annot') -> - let (pat',(guard',decls,_)) = remove_bitvector_pat pat in - let body' = decls (rewrite_rec body) in - (match guard' with - | Some guard' -> Pat_aux (Pat_when (pat', guard', body'), annot') - | None -> Pat_aux (Pat_exp (pat', body'), annot')) - | Pat_aux (Pat_when (pat,guard,body),annot') -> - let (pat',(guard',decls,_)) = remove_bitvector_pat pat in - let body' = decls (rewrite_rec body) in - (match guard' with - | Some guard' -> Pat_aux (Pat_when (pat', bitwise_and_exp guard guard', body'), annot') - | None -> Pat_aux (Pat_when (pat', guard, body'), annot')) in - rewrap (E_case (e, List.map rewrite_pexp ps)) - | E_let (LB_aux (LB_val (pat,v),annot'),body) -> - let (pat,(_,decls,_)) = remove_bitvector_pat pat in - rewrap (E_let (LB_aux (LB_val (pat,rewrite_rec v),annot'), - decls (rewrite_rec body))) - | _ -> rewrite_base full_exp - -let rewrite_fun_remove_bitvector_pat - rewriters (FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),(l,fdannot))) = - let _ = reset_fresh_name_counter () in - let funcls = match funcls with - | (FCL_aux (FCL_Funcl(id,_,_),_) :: _) -> - let clause (FCL_aux (FCL_Funcl(_,pat,exp),annot)) = - let (pat,(guard,decls,_)) = remove_bitvector_pat pat in - let exp = decls (rewriters.rewrite_exp rewriters exp) in - (pat,guard,exp,annot) in - let cs = rewrite_guarded_clauses l (List.map clause funcls) in - List.map (fun (pat,exp,annot) -> FCL_aux (FCL_Funcl(id,pat,exp),annot)) cs - | _ -> funcls in - FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),(l,fdannot)) - -let rewrite_defs_remove_bitvector_pats (Defs defs) = - let rewriters = - {rewrite_exp = rewrite_exp_remove_bitvector_pat; - rewrite_pat = rewrite_pat; - rewrite_let = rewrite_let; - rewrite_lexp = rewrite_lexp; - rewrite_fun = rewrite_fun_remove_bitvector_pat; - rewrite_def = rewrite_def; - rewrite_defs = rewrite_defs_base } in - let rewrite_def d = - let d = rewriters.rewrite_def rewriters d in - match d with - | DEF_val (LB_aux (LB_val (pat,exp),a)) -> - let (pat',(_,_,letbinds)) = remove_bitvector_pat pat in - let defvals = List.map (fun lb -> DEF_val lb) letbinds in - [DEF_val (LB_aux (LB_val (pat',exp),a))] @ defvals - | d -> [d] in - (* FIXME See above in rewrite_sizeof *) - (* fst (check initial_env ( *) - Defs (List.flatten (List.map rewrite_def defs)) - (* )) *) - - -(* Remove pattern guards by rewriting them to if-expressions within the - pattern expression. Shares code with the rewriting of bitvector patterns. *) -let rewrite_exp_guarded_pats rewriters (E_aux (exp,(l,annot)) as full_exp) = - let rewrap e = E_aux (e,(l,annot)) in - let rewrite_rec = rewriters.rewrite_exp rewriters in - let rewrite_base = rewrite_exp rewriters in - let is_guarded_pexp = function - | Pat_aux (Pat_when (_,_,_),_) -> true - | _ -> false in - match exp with - | E_case (e,ps) - when List.exists is_guarded_pexp ps -> - let clause = function - | Pat_aux (Pat_exp (pat, body), annot) -> - (pat, None, rewrite_rec body, annot) - | Pat_aux (Pat_when (pat, guard, body), annot) -> - (pat, Some guard, rewrite_rec body, annot) in - let clauses = rewrite_guarded_clauses l (List.map clause ps) in - if (effectful e) then - let e = rewrite_rec e in - let (E_aux (_,(el,eannot))) = e in - let pat_e' = fresh_id_pat "p__" (el, Some (env_of e, typ_of e, no_effect)) in - let exp_e' = pat_to_exp pat_e' in - let letbind_e = LB_aux (LB_val (pat_e',e), (el,eannot)) in - let exp' = case_exp exp_e' (typ_of full_exp) clauses in - rewrap (E_let (letbind_e, exp')) - else case_exp e (typ_of full_exp) clauses - | _ -> rewrite_base full_exp - -let rewrite_defs_guarded_pats = - rewrite_defs_base { rewriters_base with rewrite_exp = rewrite_exp_guarded_pats } - - -let id_is_local_var id env = match Env.lookup_id id env with - | Local _ -> true - | _ -> false - -let id_is_unbound id env = match Env.lookup_id id env with - | Unbound -> true - | _ -> false - -let rec lexp_is_local (LEXP_aux (lexp, _)) env = match lexp with - | LEXP_memory _ -> false - | LEXP_id id - | LEXP_cast (_, id) -> id_is_local_var id env - | LEXP_tup lexps -> List.for_all (fun lexp -> lexp_is_local lexp env) lexps - | LEXP_vector (lexp,_) - | LEXP_vector_range (lexp,_,_) - | LEXP_field (lexp,_) -> lexp_is_local lexp env - -let rec lexp_is_local_intro (LEXP_aux (lexp, _)) env = match lexp with - | LEXP_memory _ -> false - | LEXP_id id - | LEXP_cast (_, id) -> id_is_unbound id env - | LEXP_tup lexps -> List.for_all (fun lexp -> lexp_is_local_intro lexp env) lexps - | LEXP_vector (lexp,_) - | LEXP_vector_range (lexp,_,_) - | LEXP_field (lexp,_) -> lexp_is_local_intro lexp env - -let lexp_is_effectful (LEXP_aux (_, (_, annot))) = match annot with - | Some (_, _, eff) -> effectful_effs eff - | _ -> false - -let rec rewrite_lexp_to_rhs (do_rewrite : tannot lexp -> bool) ((LEXP_aux(lexp,((l,_) as annot))) as le) = - if do_rewrite le then - match lexp with - | LEXP_id _ | LEXP_cast (_, _) | LEXP_tup _ -> (le, (fun exp -> exp)) - | LEXP_vector (lexp, e) -> - let (lhs, rhs) = rewrite_lexp_to_rhs do_rewrite lexp in - (lhs, (fun exp -> rhs (E_aux (E_vector_update (lexp_to_exp lexp, e, exp), annot)))) - | LEXP_vector_range (lexp, e1, e2) -> - let (lhs, rhs) = rewrite_lexp_to_rhs do_rewrite lexp in - (lhs, (fun exp -> rhs (E_aux (E_vector_update_subrange (lexp_to_exp lexp, e1, e2, exp), annot)))) - | LEXP_field (lexp, id) -> - begin - let (lhs, rhs) = rewrite_lexp_to_rhs do_rewrite lexp in - let (LEXP_aux (_, lannot)) = lexp in - let env = env_of_annot lannot in - match Env.expand_synonyms env (typ_of_annot lannot) with - | Typ_aux (Typ_app (Id_aux (Id "register", _), [Typ_arg_aux (Typ_arg_typ (Typ_aux (Typ_id regtyp_id, _)), _)]), _) - | Typ_aux (Typ_id regtyp_id, _) when Env.is_regtyp regtyp_id env -> - let base, top, ranges = Env.get_regtyp regtyp_id env in - let range, _ = - try List.find (fun (_, fid) -> Id.compare fid id = 0) ranges with - | Not_found -> - raise (Reporting_basic.err_typ l ("Field " ^ string_of_id id ^ " doesn't exist for register type " ^ string_of_id regtyp_id)) - in - let lexp_exp = E_aux (E_app (mk_id ("cast_" ^ string_of_id regtyp_id), [lexp_to_exp lexp]), (l, None)) in - let n, m = match range with - | BF_aux (BF_single n, _) -> n, n - | BF_aux (BF_range (n, m), _) -> n, m - | _ -> raise (Reporting_basic.err_unreachable l ("Unsupported lexp: " ^ string_of_lexp le)) in - let rhs' exp = rhs (E_aux (E_vector_update_subrange (lexp_exp, simple_num l n, simple_num l m, exp), lannot)) in - (lhs, rhs') - | Typ_aux (Typ_id rectyp_id, _) | Typ_aux (Typ_app (rectyp_id, _), _) when Env.is_record rectyp_id env -> - let field_update exp = FES_aux (FES_Fexps ([FE_aux (FE_Fexp (id, exp), annot)], false), annot) in - (lhs, (fun exp -> rhs (E_aux (E_record_update (lexp_to_exp lexp, field_update exp), lannot)))) - | _ -> raise (Reporting_basic.err_unreachable l ("Unsupported lexp: " ^ string_of_lexp le)) - end - | _ -> raise (Reporting_basic.err_unreachable l ("Unsupported lexp: " ^ string_of_lexp le)) - else (le, (fun exp -> exp)) - -let updates_vars exp = - let e_assign ((_, lexp), (u, exp)) = - (u || lexp_is_local lexp (env_of exp), E_assign (lexp, exp)) in - fst (fold_exp { (compute_exp_alg false (||)) with e_assign = e_assign } exp) - -(*Expects to be called after rewrite_defs; thus the following should not appear: - internal_exp of any form - lit vectors in patterns or expressions - *) -let rewrite_exp_lift_assign_intro rewriters ((E_aux (exp,((l,_) as annot))) as full_exp) = - let rewrap e = E_aux (e,annot) in - let rewrap_effects e eff = - E_aux (e, (l,Some (env_of_annot annot, typ_of_annot annot, eff))) in - let rewrite_rec = rewriters.rewrite_exp rewriters in - let rewrite_base = rewrite_exp rewriters in - match exp with - | E_block exps -> - let rec walker exps = match exps with - | [] -> [] - | (E_aux(E_assign(le,e), ((l, Some (env,typ,eff)) as annot)) as exp)::exps - when lexp_is_local_intro le env && not (lexp_is_effectful le) -> - let (le', re') = rewrite_lexp_to_rhs (fun _ -> true) le in - let e' = re' (rewrite_base e) in - let exps' = walker exps in - let effects = union_eff_exps exps' in - let block = E_aux (E_block exps', (l, Some (env, unit_typ, effects))) in - [fix_eff_exp (E_aux (E_internal_let(le', e', block), annot))] - (*| ((E_aux(E_if(c,t,e),(l,annot))) as exp)::exps -> - let vars_t = introduced_variables t in - let vars_e = introduced_variables e in - let new_vars = Envmap.intersect vars_t vars_e in - if Envmap.is_empty new_vars - then (rewrite_base exp)::walker exps - else - let new_nmap = match nmap with - | None -> Some(Nexpmap.empty,new_vars) - | Some(nm,s) -> Some(nm, Envmap.union new_vars s) in - let c' = rewrite_base c in - let t' = rewriters.rewrite_exp rewriters new_nmap t in - let e' = rewriters.rewrite_exp rewriters new_nmap e in - let exps' = walker exps in - fst ((Envmap.fold - (fun (res,effects) i (t,e) -> - let bitlit = E_aux (E_lit (L_aux(L_zero, Parse_ast.Generated l)), - (Parse_ast.Generated l, simple_annot bit_t)) in - let rangelit = E_aux (E_lit (L_aux (L_num 0, Parse_ast.Generated l)), - (Parse_ast.Generated l, simple_annot nat_t)) in - let set_exp = - match t.t with - | Tid "bit" | Tabbrev(_,{t=Tid "bit"}) -> bitlit - | Tapp("range", _) | Tapp("atom", _) -> rangelit - | Tapp("vector", [_;_;_;TA_typ ( {t=Tid "bit"} | {t=Tabbrev(_,{t=Tid "bit"})})]) - | Tapp(("reg"|"register"),[TA_typ ({t = Tapp("vector", - [_;_;_;TA_typ ( {t=Tid "bit"} - | {t=Tabbrev(_,{t=Tid "bit"})})])})]) - | Tabbrev(_,{t = Tapp("vector", - [_;_;_;TA_typ ( {t=Tid "bit"} - | {t=Tabbrev(_,{t=Tid "bit"})})])}) -> - E_aux (E_vector_indexed([], Def_val_aux(Def_val_dec bitlit, - (Parse_ast.Generated l,simple_annot bit_t))), - (Parse_ast.Generated l, simple_annot t)) - | _ -> e in - let unioneffs = union_effects effects (get_effsum_exp set_exp) in - ([E_aux (E_internal_let (LEXP_aux (LEXP_id (Id_aux (Id i, Parse_ast.Generated l)), - (Parse_ast.Generated l, (tag_annot t Emp_intro))), - set_exp, - E_aux (E_block res, (Parse_ast.Generated l, (simple_annot_efr unit_t effects)))), - (Parse_ast.Generated l, simple_annot_efr unit_t unioneffs))],unioneffs))) - (E_aux(E_if(c',t',e'),(Parse_ast.Generated l, annot))::exps',eff_union_exps (c'::t'::e'::exps')) new_vars)*) - | e::exps -> (rewrite_rec e)::(walker exps) - in - check_exp (env_of full_exp) - (E_aux (E_block (List.map strip_exp (walker exps)), (l, ()))) (typ_of full_exp) - | E_assign(le,e) - when lexp_is_local_intro le (env_of full_exp) && not (lexp_is_effectful le) -> - let (le', re') = rewrite_lexp_to_rhs (fun _ -> true) le in - let e' = re' (rewrite_base e) in - let block = annot_exp (E_block []) l (env_of full_exp) unit_typ in - check_exp (env_of full_exp) - (strip_exp (E_aux (E_internal_let(le', e', block), annot))) (typ_of full_exp) - | _ -> rewrite_base full_exp - -let rewrite_lexp_lift_assign_intro rewriters ((LEXP_aux(lexp,annot)) as le) = - let rewrap le = LEXP_aux(le,annot) in - let rewrite_base = rewrite_lexp rewriters in - match lexp, annot with - | (LEXP_id id | LEXP_cast (_,id)), (l, Some (env, typ, eff)) -> - (match Env.lookup_id id env with - | Unbound | Local _ -> - LEXP_aux (lexp, (l, Some (env, typ, union_effects eff (mk_effect [BE_lset])))) - | _ -> rewrap lexp) - | _ -> rewrite_base le - - -let rewrite_defs_exp_lift_assign defs = rewrite_defs_base - {rewrite_exp = rewrite_exp_lift_assign_intro; - rewrite_pat = rewrite_pat; - rewrite_let = rewrite_let; - rewrite_lexp = rewrite_lexp_lift_assign_intro; - rewrite_fun = rewrite_fun; - rewrite_def = rewrite_def; - rewrite_defs = rewrite_defs_base} defs - - -(* Rewrite assignments to register references into calls to a builtin function - "write_reg_ref" (in the Lem shallow embedding). For example, if GPR is a - vector of register references, then - GPR[i] := exp; - becomes - write_reg_ref (vector_access (GPR, i)) exp - *) -let rewrite_register_ref_writes (Defs defs) = - let (Defs write_reg_spec) = fst (check Env.empty (Defs (List.map gen_vs - [("write_reg_ref", "forall ('a : Type). (register('a), 'a) -> unit effect {wreg}")]))) in - let lexp_ref_exp (LEXP_aux (_, annot) as lexp) = - try - let exp = infer_exp (env_of_annot annot) (strip_exp (lexp_to_exp lexp)) in - if is_reftyp (typ_of exp) then Some exp else None - with | _ -> None in - let e_assign (lexp, exp) = - let (lhs, rhs) = rewrite_lexp_to_rhs (fun le -> lexp_ref_exp le = None) lexp in - match lexp_ref_exp lhs with - | Some (E_aux (_, annot) as lhs_exp) -> - let lhs = LEXP_aux (LEXP_memory (mk_id "write_reg_ref", [lhs_exp]), annot) in - E_assign (lhs, rhs exp) - | None -> E_assign (lexp, exp) in - let rewrite_exp _ = fold_exp { id_exp_alg with e_assign = e_assign } in - - let generate_field_accessors l env id n1 n2 fields = - let i1, i2 = match n1, n2 with - | Nexp_aux(Nexp_constant i1, _),Nexp_aux(Nexp_constant i2, _) -> i1, i2 - | _ -> raise (Reporting_basic.err_typ l - ("Non-constant indices in register type " ^ string_of_id id)) in - let dir_b = i1 < i2 in - let dir = (if dir_b then "true" else "false") in - let ord = Ord_aux ((if dir_b then Ord_inc else Ord_dec), Parse_ast.Unknown) in - let size = if dir_b then succ_big_int (sub_big_int i2 i1) else succ_big_int (sub_big_int i1 i2) in - let rtyp = mk_id_typ id in - let vtyp = vector_typ (nconstant i1) (nconstant size) ord bit_typ in - let accessors (fr, fid) = - let i, j = match fr with - | BF_aux (BF_single i, _) -> (i, i) - | BF_aux (BF_range (i, j), _) -> (i, j) - | _ -> raise (Reporting_basic.err_unreachable l "unsupported field type") in - let mk_num_exp i = mk_lit_exp (L_num i) in - let reg_pat, reg_env = bind_pat env (mk_pat (P_typ (rtyp, mk_pat (P_id (mk_id "reg"))))) rtyp in - let inferred_get = infer_exp reg_env (mk_exp (E_vector_subrange - (mk_exp (E_id (mk_id "reg")), mk_num_exp i, mk_num_exp j))) in - let ftyp = typ_of inferred_get in - let v_pat, v_env = bind_pat reg_env (mk_pat (P_typ (ftyp, mk_pat (P_id (mk_id "v"))))) ftyp in - let inferred_set = infer_exp v_env (mk_exp (E_vector_update_subrange - (mk_exp (E_id (mk_id "reg")), mk_num_exp i, mk_num_exp j, mk_exp (E_id (mk_id "v"))))) in - let set_args = P_aux (P_tup [reg_pat; v_pat], (l, Some (env, tuple_typ [rtyp; ftyp], no_effect))) in - let fsuffix = "_" ^ string_of_id id ^ "_" ^ string_of_id fid in - let rec_opt = Rec_aux (Rec_nonrec, l) in - let tannot ret_typ = Typ_annot_opt_aux (Typ_annot_opt_some (TypQ_aux (TypQ_tq [], l), ret_typ), l) in - let eff_opt = Effect_opt_aux (Effect_opt_pure, l) in - let mk_funcl id pat exp = FCL_aux (FCL_Funcl (mk_id id, pat, exp), (l, None)) in - let mk_fundef id pat exp ret_typ = DEF_fundef (FD_aux (FD_function (rec_opt, tannot ret_typ, eff_opt, [mk_funcl id pat exp]), (l, None))) in - [mk_fundef ("get" ^ fsuffix) reg_pat inferred_get ftyp; - mk_fundef ("set" ^ fsuffix) set_args inferred_set (typ_of inferred_set)] in - List.concat (List.map accessors fields) in - - let rewriters = { rewriters_base with rewrite_exp = rewrite_exp } in - let rec rewrite ds = match ds with - | (DEF_type (TD_aux (TD_register (id, n1, n2, fields), (l, Some (env, _, _)))) as d) :: ds -> - let (Defs d), env = check env (Defs [d]) in - d @ (generate_field_accessors l env id n1 n2 fields) @ rewrite ds - | d::ds -> (rewriters.rewrite_def rewriters d)::(rewrite ds) - | [] -> [] in - Defs (rewrite (write_reg_spec @ defs)) - - (* rewrite_defs_base { rewriters_base with rewrite_exp = rewrite_exp } - (Defs (write_reg_spec @ defs)) *) - - -(*let rewrite_exp_separate_ints rewriters ((E_aux (exp,((l,_) as annot))) as full_exp) = - (*let tparms,t,tag,nexps,eff,cum_eff,bounds = match annot with - | Base((tparms,t),tag,nexps,eff,cum_eff,bounds) -> tparms,t,tag,nexps,eff,cum_eff,bounds - | _ -> [],unit_t,Emp_local,[],pure_e,pure_e,nob in*) - let rewrap e = E_aux (e,annot) in - (*let rewrap_effects e effsum = - E_aux (e,(l,Base ((tparms,t),tag,nexps,eff,effsum,bounds))) in*) - let rewrite_rec = rewriters.rewrite_exp rewriters in - let rewrite_base = rewrite_exp rewriters in - match exp with - | E_lit (L_aux (((L_num _) as lit),_)) -> - (match (is_within_machine64 t nexps) with - | Yes -> let _ = Printf.eprintf "Rewriter of num_const, within 64bit int yes\n" in rewrite_base full_exp - | Maybe -> let _ = Printf.eprintf "Rewriter of num_const, within 64bit int maybe\n" in rewrite_base full_exp - | No -> let _ = Printf.eprintf "Rewriter of num_const, within 64bit int no\n" in E_aux(E_app(Id_aux (Id "integer_of_int",l),[rewrite_base full_exp]), - (l, Base((tparms,t),External(None),nexps,eff,cum_eff,bounds)))) - | E_cast (typ, exp) -> rewrap (E_cast (typ, rewrite_rec exp)) - | E_app (id,exps) -> rewrap (E_app (id,List.map rewrite_rec exps)) - | E_app_infix(el,id,er) -> rewrap (E_app_infix(rewrite_rec el,id,rewrite_rec er)) - | E_for (id, e1, e2, e3, o, body) -> - rewrap (E_for (id, rewrite_rec e1, rewrite_rec e2, rewrite_rec e3, o, rewrite_rec body)) - | E_vector_access (vec,index) -> rewrap (E_vector_access (rewrite_rec vec,rewrite_rec index)) - | E_vector_subrange (vec,i1,i2) -> - rewrap (E_vector_subrange (rewrite_rec vec,rewrite_rec i1,rewrite_rec i2)) - | E_vector_update (vec,index,new_v) -> - rewrap (E_vector_update (rewrite_rec vec,rewrite_rec index,rewrite_rec new_v)) - | E_vector_update_subrange (vec,i1,i2,new_v) -> - rewrap (E_vector_update_subrange (rewrite_rec vec,rewrite_rec i1,rewrite_rec i2,rewrite_rec new_v)) - | E_case (exp ,pexps) -> - rewrap (E_case (rewrite_rec exp, - (List.map - (fun (Pat_aux (Pat_exp(p,e),pannot)) -> - Pat_aux (Pat_exp(rewriters.rewrite_pat rewriters nmap p,rewrite_rec e),pannot)) pexps))) - | E_let (letbind,body) -> rewrap (E_let(rewriters.rewrite_let rewriters nmap letbind,rewrite_rec body)) - | E_internal_let (lexp,exp,body) -> - rewrap (E_internal_let (rewriters.rewrite_lexp rewriters nmap lexp, rewrite_rec exp, rewrite_rec body)) - | _ -> rewrite_base full_exp - -let rewrite_defs_separate_numbs defs = rewrite_defs_base - {rewrite_exp = rewrite_exp_separate_ints; - rewrite_pat = rewrite_pat; - rewrite_let = rewrite_let; (*will likely need a new one?*) - rewrite_lexp = rewrite_lexp; (*will likely need a new one?*) - rewrite_fun = rewrite_fun; - rewrite_def = rewrite_def; - rewrite_defs = rewrite_defs_base} defs*) - -(* Remove redundant return statements, and translate remaining ones into an - (effectful) call to builtin function "early_return" (in the Lem shallow - embedding). - - TODO: Maybe separate generic removal of redundant returns, and Lem-specific - rewriting of early returns - *) -let rewrite_defs_early_return (Defs defs) = - let is_return (E_aux (exp, _)) = match exp with - | E_return _ -> true - | _ -> false in - - let get_return (E_aux (e, (l, _)) as exp) = match e with - | E_return e -> e - | _ -> exp in - - let e_block es = - match es with - | [E_aux (e, _)] -> e - | _ :: _ when is_return (Util.last es) -> - let (E_aux (_, annot) as e) = get_return (Util.last es) in - E_return (E_aux (E_block (Util.butlast es @ [get_return e]), annot)) - | _ -> E_block es in - - let e_if (e1, e2, e3) = - if is_return e2 && is_return e3 then - let (E_aux (_, annot)) = get_return e2 in - E_return (E_aux (E_if (e1, get_return e2, get_return e3), annot)) - else E_if (e1, e2, e3) in - - let e_case (e, pes) = - let is_return_pexp (Pat_aux (pexp, _)) = match pexp with - | Pat_exp (_, e) | Pat_when (_, _, e) -> is_return e in - let get_return_pexp (Pat_aux (pexp, a)) = match pexp with - | Pat_exp (p, e) -> Pat_aux (Pat_exp (p, get_return e), a) - | Pat_when (p, g, e) -> Pat_aux (Pat_when (p, g, get_return e), a) in - let annot = match List.map get_return_pexp pes with - | Pat_aux (Pat_exp (_, E_aux (_, annot)), _) :: _ -> annot - | Pat_aux (Pat_when (_, _, E_aux (_, annot)), _) :: _ -> annot - | [] -> (Parse_ast.Unknown, None) in - if List.for_all is_return_pexp pes - then E_return (E_aux (E_case (e, List.map get_return_pexp pes), annot)) - else E_case (e, pes) in - - let e_aux (exp, (l, annot)) = - let full_exp = propagate_exp_effect (E_aux (exp, (l, annot))) in - let env = env_of full_exp in - match full_exp with - | E_aux (E_return exp, (l, Some (env, typ, eff))) -> - (* Add escape effect annotation, since we use the exception mechanism - of the state monad to implement early return in the Lem backend *) - let annot' = Some (env, typ, union_effects eff (mk_effect [BE_escape])) in - let exp' = annot_exp (E_cast (typ_of exp, exp)) l env (typ_of exp) in - E_aux (E_app (mk_id "early_return", [exp']), (l, annot')) - | _ -> full_exp in - - let rewrite_funcl_early_return _ (FCL_aux (FCL_Funcl (id, pat, exp), a)) = - let exp = - exp - (* Pull early returns out as far as possible *) - |> fold_exp { id_exp_alg with e_block = e_block; e_if = e_if; e_case = e_case } - (* Remove singleton E_return *) - |> get_return - (* Fix effect annotations *) - |> fold_exp { id_exp_alg with e_aux = e_aux } in - let a = match a with - | (l, Some (env, typ, eff)) -> - (l, Some (env, typ, union_effects eff (effect_of exp))) - | _ -> a in - FCL_aux (FCL_Funcl (id, pat, exp), a) in - - let rewrite_fun_early_return rewriters - (FD_aux (FD_function (rec_opt, tannot_opt, effect_opt, funcls), a)) = - FD_aux (FD_function (rec_opt, tannot_opt, effect_opt, - List.map (rewrite_funcl_early_return rewriters) funcls), a) in - - let (Defs early_ret_spec) = fst (check Env.empty (Defs [gen_vs - ("early_return", "forall ('a : Type) ('b : Type). 'a -> 'b effect {escape}")])) in - - rewrite_defs_base - { rewriters_base with rewrite_fun = rewrite_fun_early_return } - (Defs (early_ret_spec @ defs)) - -(* Propagate effects of functions, if effect checking and propagation - have not been performed already by the type checker. *) -let rewrite_fix_val_specs (Defs defs) = - let find_vs env val_specs id = - try Bindings.find id val_specs with - | Not_found -> - begin - try Env.get_val_spec id env with - | _ -> - raise (Reporting_basic.err_unreachable (Parse_ast.Unknown) - ("No val spec found for " ^ string_of_id id)) - end - in - - let add_eff_to_vs eff = function - | (tq, Typ_aux (Typ_fn (args_t, ret_t, eff'), a)) -> - (tq, Typ_aux (Typ_fn (args_t, ret_t, union_effects eff eff'), a)) - | vs -> vs - in - - let eff_of_vs = function - | (tq, Typ_aux (Typ_fn (args_t, ret_t, eff), a)) -> eff - | _ -> no_effect - in - - let e_aux val_specs (exp, (l, annot)) = - match fix_eff_exp (E_aux (exp, (l, annot))) with - | E_aux (E_app_infix (_, f, _) as exp, (l, Some (env, typ, eff))) - | E_aux (E_app (f, _) as exp, (l, Some (env, typ, eff))) -> - let vs = find_vs env val_specs f in - let env = Env.update_val_spec f vs env in - E_aux (exp, (l, Some (env, typ, union_effects eff (eff_of_vs vs)))) - | e_aux -> e_aux - in - - let rewrite_exp val_specs = fold_exp { id_exp_alg with e_aux = e_aux val_specs } in - - let rewrite_funcl (val_specs, funcls) (FCL_aux (FCL_Funcl (id, pat, exp), (l, annot))) = - let exp = propagate_exp_effect (rewrite_exp val_specs exp) in - let vs, eff = match find_vs (env_of_annot (l, annot)) val_specs id with - | (tq, Typ_aux (Typ_fn (args_t, ret_t, eff), a)) -> - let eff' = union_effects eff (effect_of exp) in - let args_t' = rewrite_typ_nexp_ids (env_of exp) (pat_typ_of pat) in - let ret_t' = rewrite_typ_nexp_ids (env_of exp) (typ_of exp) in - (tq, Typ_aux (Typ_fn (args_t', ret_t', eff'), a)), eff' - in - let annot = add_effect_annot annot eff in - (Bindings.add id vs val_specs, - funcls @ [FCL_aux (FCL_Funcl (id, pat, exp), (l, annot))]) - in - - let rewrite_fundef (val_specs, FD_aux (FD_function (recopt, tannotopt, effopt, funcls), a)) = - let (val_specs, funcls) = List.fold_left rewrite_funcl (val_specs, []) funcls in - (* Repeat once to cross-propagate effects between clauses *) - let (val_specs, funcls) = List.fold_left rewrite_funcl (val_specs, []) funcls in - let is_funcl_rec (FCL_aux (FCL_Funcl (id, _, exp), _)) = - fst (fold_exp - { (compute_exp_alg false (||) ) with - e_app = (fun (f, es) -> - let (rs, es) = List.split es in - (List.fold_left (||) (string_of_id f = string_of_id id) rs, - E_app (f, es))); - e_app_infix = (fun ((r1,e1), f, (r2,e2)) -> - (r1 || r2 || (string_of_id f = string_of_id id), - E_app_infix (e1, f, e2))) } - exp) - in - let recopt = - if List.exists is_funcl_rec funcls then - Rec_aux (Rec_rec, Parse_ast.Unknown) - else recopt - in - let tannotopt = match tannotopt, funcls with - | Typ_annot_opt_aux (Typ_annot_opt_some (typq, typ), l), - FCL_aux (FCL_Funcl (_, _, exp), _) :: _ -> - Typ_annot_opt_aux (Typ_annot_opt_some (typq, rewrite_typ_nexp_ids (env_of exp) typ), l) - | _ -> tannotopt in - (val_specs, FD_aux (FD_function (recopt, tannotopt, effopt, funcls), a)) in - - let rec rewrite_fundefs (val_specs, fundefs) = - match fundefs with - | fundef :: fundefs -> - let (val_specs, fundef) = rewrite_fundef (val_specs, fundef) in - let (val_specs, fundefs) = rewrite_fundefs (val_specs, fundefs) in - (val_specs, fundef :: fundefs) - | [] -> (val_specs, []) in - - let rewrite_def (val_specs, defs) = function - | DEF_fundef fundef -> - let (val_specs, fundef) = rewrite_fundef (val_specs, fundef) in - (val_specs, defs @ [DEF_fundef fundef]) - | DEF_internal_mutrec fundefs -> - let (val_specs, fundefs) = rewrite_fundefs (val_specs, fundefs) in - (val_specs, defs @ [DEF_internal_mutrec fundefs]) - | DEF_val (LB_aux (LB_val (pat, exp), a)) -> - (val_specs, defs @ [DEF_val (LB_aux (LB_val (pat, rewrite_exp val_specs exp), a))]) - | DEF_spec (VS_aux (VS_val_spec (typschm, id, ext_opt, is_cast), a)) -> - let typschm, val_specs = - if Bindings.mem id val_specs then begin - let (tq, typ) = Bindings.find id val_specs in - TypSchm_aux (TypSchm_ts (tq, typ), Parse_ast.Unknown), val_specs - end else begin - let (TypSchm_aux (TypSchm_ts (tq, typ), _)) = typschm in - typschm, Bindings.add id (tq, typ) val_specs - end - in - (val_specs, defs @ [DEF_spec (VS_aux (VS_val_spec (typschm, id, ext_opt, is_cast), a))]) - | def -> (val_specs, defs @ [def]) - in - - let rewrite_val_specs val_specs = function - | DEF_spec (VS_aux (VS_val_spec (typschm, id, ext_opt, is_cast), a)) - when Bindings.mem id val_specs -> - let typschm = match typschm with - | TypSchm_aux (TypSchm_ts (tq, typ), l) -> - let (tq, typ) = Bindings.find id val_specs in - TypSchm_aux (TypSchm_ts (tq, typ), l) - in - DEF_spec (VS_aux (VS_val_spec (typschm, id, ext_opt, is_cast), a)) - | def -> def - in - - let (val_specs, defs) = List.fold_left rewrite_def (Bindings.empty, []) defs in - let defs = List.map (rewrite_val_specs val_specs) defs in - - (* if !Type_check.opt_no_effects - then *) - Defs defs - (* else Defs defs *) - -(* Turn constraints into numeric expressions with sizeof *) -let rewrite_constraint = - let rec rewrite_nc (NC_aux (nc_aux, l)) = mk_exp (rewrite_nc_aux nc_aux) - and rewrite_nc_aux = function - | NC_bounded_ge (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id ">=", mk_exp (E_sizeof n2)) - | NC_bounded_le (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id "<=", mk_exp (E_sizeof n2)) - | NC_equal (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id "==", mk_exp (E_sizeof n2)) - | NC_not_equal (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id "!=", mk_exp (E_sizeof n2)) - | NC_and (nc1, nc2) -> E_app_infix (rewrite_nc nc1, mk_id "&", rewrite_nc nc2) - | NC_or (nc1, nc2) -> E_app_infix (rewrite_nc nc1, mk_id "|", rewrite_nc nc2) - | NC_false -> E_lit (mk_lit L_false) - | NC_true -> E_lit (mk_lit L_true) - | NC_set (kid, ints) -> - unaux_exp (rewrite_nc (List.fold_left (fun nc int -> nc_or nc (nc_eq (nvar kid) (nconstant int))) nc_true ints)) - in - let rewrite_e_aux (E_aux (e_aux, _) as exp) = - match e_aux with - | E_constraint nc -> - check_exp (env_of exp) (rewrite_nc nc) bool_typ - | _ -> exp - in - - let rewrite_e_constraint = { id_exp_alg with e_aux = (fun (exp, annot) -> rewrite_e_aux (E_aux (exp, annot))) } in - - rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp rewrite_e_constraint) } - -let rewrite_type_union_typs rw_typ (Tu_aux (tu, annot)) = - match tu with - | Tu_id id -> Tu_aux (Tu_id id, annot) - | Tu_ty_id (typ, id) -> Tu_aux (Tu_ty_id (rw_typ typ, id), annot) - -let rewrite_type_def_typs rw_typ rw_typquant rw_typschm (TD_aux (td, annot)) = - match td with - | TD_abbrev (id, nso, typschm) -> TD_aux (TD_abbrev (id, nso, rw_typschm typschm), annot) - | TD_record (id, nso, typq, typ_ids, flag) -> - TD_aux (TD_record (id, nso, rw_typquant typq, List.map (fun (typ, id) -> (rw_typ typ, id)) typ_ids, flag), annot) - | TD_variant (id, nso, typq, tus, flag) -> - TD_aux (TD_variant (id, nso, rw_typquant typq, List.map (rewrite_type_union_typs rw_typ) tus, flag), annot) - | TD_enum (id, nso, ids, flag) -> TD_aux (TD_enum (id, nso, ids, flag), annot) - | TD_register (id, n1, n2, ranges) -> TD_aux (TD_register (id, n1, n2, ranges), annot) - -(* FIXME: other reg_dec types *) -let rewrite_dec_spec_typs rw_typ (DEC_aux (ds, annot)) = - match ds with - | DEC_reg (typ, id) -> DEC_aux (DEC_reg (rw_typ typ, id), annot) - | _ -> assert false - -(* Remove overload definitions and cast val specs from the - specification because the interpreter doesn't know about them.*) -let rewrite_overload_cast (Defs defs) = - let remove_cast_vs (VS_aux (vs_aux, annot)) = - match vs_aux with - | VS_val_spec (typschm, id, ext, _) -> VS_aux (VS_val_spec (typschm, id, ext, false), annot) - in - let simple_def = function - | DEF_spec vs -> DEF_spec (remove_cast_vs vs) - | def -> def - in - let is_overload = function - | DEF_overload _ -> true - | _ -> false - in - let defs = List.map simple_def defs in - Defs (List.filter (fun def -> not (is_overload def)) defs) - - -let rewrite_undefined mwords = - let rewrite_e_aux (E_aux (e_aux, _) as exp) = - match e_aux with - | E_lit (L_aux (L_undef, l)) -> - check_exp (env_of exp) (undefined_of_typ mwords l (fun _ -> ()) (Env.expand_synonyms (env_of exp) (typ_of exp))) (typ_of exp) - | _ -> exp - in - let rewrite_exp_undefined = { id_exp_alg with e_aux = (fun (exp, annot) -> rewrite_e_aux (E_aux (exp, annot))) } in - rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp rewrite_exp_undefined) } - -let rec simple_typ (Typ_aux (typ_aux, l) as typ) = Typ_aux (simple_typ_aux typ_aux, l) -and simple_typ_aux = function - | Typ_id id -> Typ_id id - | Typ_app (id, [_; _; _; Typ_arg_aux (Typ_arg_typ typ, l)]) when Id.compare id (mk_id "vector") = 0 -> - Typ_app (mk_id "list", [Typ_arg_aux (Typ_arg_typ (simple_typ typ), l)]) - | Typ_app (id, [_]) when Id.compare id (mk_id "atom") = 0 -> - Typ_id (mk_id "int") - | Typ_app (id, [_; _]) when Id.compare id (mk_id "range") = 0 -> - Typ_id (mk_id "int") - | Typ_app (id, args) -> Typ_app (id, List.concat (List.map simple_typ_arg args)) - | Typ_fn (typ1, typ2, effs) -> Typ_fn (simple_typ typ1, simple_typ typ2, effs) - | Typ_tup typs -> Typ_tup (List.map simple_typ typs) - | Typ_exist (_, _, Typ_aux (typ, l)) -> simple_typ_aux typ - | typ_aux -> typ_aux -and simple_typ_arg (Typ_arg_aux (typ_arg_aux, l)) = - match typ_arg_aux with - | Typ_arg_typ typ -> [Typ_arg_aux (Typ_arg_typ (simple_typ typ), l)] - | _ -> [] - -(* This pass aims to remove all the Num quantifiers from the specification. *) -let rewrite_simple_types (Defs defs) = - let is_simple = function - | QI_aux (QI_id kopt, annot) as qi when is_typ_kopt kopt || is_order_kopt kopt -> true - | _ -> false - in - let simple_typquant (TypQ_aux (tq_aux, annot)) = - match tq_aux with - | TypQ_no_forall -> TypQ_aux (TypQ_no_forall, annot) - | TypQ_tq quants -> TypQ_aux (TypQ_tq (List.filter (fun q -> is_simple q) quants), annot) - in - let simple_typschm (TypSchm_aux (TypSchm_ts (typq, typ), annot)) = - TypSchm_aux (TypSchm_ts (simple_typquant typq, simple_typ typ), annot) - in - let simple_vs (VS_aux (vs_aux, annot)) = - match vs_aux with - | VS_val_spec (typschm, id, ext, is_cast) -> VS_aux (VS_val_spec (simple_typschm typschm, id, ext, is_cast), annot) - in - let rec simple_lit (L_aux (lit_aux, l) as lit) = - match lit_aux with - | L_bin _ | L_hex _ -> - E_list (List.map (fun b -> E_aux (E_lit b, simple_annot l bit_typ)) (vector_string_to_bit_list l lit_aux)) - | _ -> E_lit lit - in - let simple_def = function - | DEF_spec vs -> DEF_spec (simple_vs vs) - | DEF_type td -> DEF_type (rewrite_type_def_typs simple_typ simple_typquant simple_typschm td) - | DEF_reg_dec ds -> DEF_reg_dec (rewrite_dec_spec_typs simple_typ ds) - | def -> def - in - let simple_pat = { - id_pat_alg with - p_typ = (fun (typ, pat) -> P_typ (simple_typ typ, pat)); - p_var = (fun (pat, kid) -> unaux_pat pat); - p_vector = (fun pats -> P_list pats) - } in - let simple_exp = { - id_exp_alg with - e_lit = simple_lit; - e_vector = (fun exps -> E_list exps); - e_cast = (fun (typ, exp) -> E_cast (simple_typ typ, exp)); - (* e_assert = (fun (E_aux (_, annot), str) -> E_assert (E_aux (E_lit (mk_lit L_true), annot), str)); *) - lEXP_cast = (fun (typ, lexp) -> LEXP_cast (simple_typ typ, lexp)); - pat_alg = simple_pat - } in - let simple_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp simple_exp); - rewrite_pat = (fun _ -> fold_pat simple_pat) } - in - let defs = Defs (List.map simple_def defs) in - rewrite_defs_base simple_defs defs - -let rewrite_tuple_vector_assignments defs = - let assign_tuple e_aux annot = - let env = env_of_annot annot in - match e_aux with - | E_assign (LEXP_aux (LEXP_tup lexps, lannot), exp) -> - let typ = Env.base_typ_of env (typ_of exp) in - if is_vector_typ typ then - (* let _ = Pretty_print_common.print stderr (Pretty_print_sail.doc_exp (E_aux (e_aux, annot))) in *) - let (start, _, ord, etyp) = vector_typ_args_of typ in - let len (LEXP_aux (le, lannot)) = - let ltyp = Env.base_typ_of env (typ_of_annot lannot) in - if is_vector_typ ltyp then - let (_, len, _, _) = vector_typ_args_of ltyp in - match nexp_simp len with - | Nexp_aux (Nexp_constant len, _) -> len - | _ -> unit_big_int - else unit_big_int in - let next i step = - if is_order_inc ord - then (sub_big_int (add_big_int i step) unit_big_int, add_big_int i step) - else (add_big_int (sub_big_int i step) unit_big_int, sub_big_int i step) in - let i = match nexp_simp start with - | (Nexp_aux (Nexp_constant i, _)) -> i - | _ -> if is_order_inc ord then zero_big_int else big_int_of_int (List.length lexps - 1) in - let l = gen_loc (fst annot) in - let exp' = - if small exp then strip_exp exp - else mk_exp (E_id (mk_id "split_vec")) in - let lexp_to_exp (i, exps) lexp = - let (j, i') = next i (len lexp) in - let i_exp = mk_exp (E_lit (mk_lit (L_num i))) in - let j_exp = mk_exp (E_lit (mk_lit (L_num j))) in - let sub = mk_exp (E_vector_subrange (exp', i_exp, j_exp)) in - (i', exps @ [sub]) in - let (_, exps) = List.fold_left lexp_to_exp (i, []) lexps in - let tup = mk_exp (E_tuple exps) in - let lexp = LEXP_aux (LEXP_tup (List.map strip_lexp lexps), (l, ())) in - let e_aux = - if small exp then mk_exp (E_assign (lexp, tup)) - else mk_exp ( - E_let ( - mk_letbind (mk_pat (P_id (mk_id "split_vec"))) (strip_exp exp), - mk_exp (E_assign (lexp, tup)))) in - begin - try check_exp env e_aux unit_typ with - | Type_error (l, err) -> - raise (Reporting_basic.err_typ l (string_of_type_error err)) - end - else E_aux (e_aux, annot) - | _ -> E_aux (e_aux, annot) - in - let assign_exp = { - id_exp_alg with - e_aux = (fun (e_aux, annot) -> assign_tuple e_aux annot) - } in - let assign_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp assign_exp) } in - rewrite_defs_base assign_defs defs - -let rewrite_tuple_assignments defs = - let assign_tuple e_aux annot = - let env = env_of_annot annot in - match e_aux with - | E_assign (LEXP_aux (LEXP_tup lexps, _), exp) -> - (* let _ = Pretty_print_common.print stderr (Pretty_print_sail.doc_exp (E_aux (e_aux, annot))) in *) - let (_, ids) = List.fold_left (fun (n, ids) _ -> (n + 1, ids @ [mk_id ("tup__" ^ string_of_int n)])) (0, []) lexps in - let block_assign i lexp = mk_exp (E_assign (strip_lexp lexp, mk_exp (E_id (mk_id ("tup__" ^ string_of_int i))))) in - let block = mk_exp (E_block (List.mapi block_assign lexps)) in - let letbind = mk_letbind (mk_pat (P_tup (List.map (fun id -> mk_pat (P_id id)) ids))) (strip_exp exp) in - let let_exp = mk_exp (E_let (letbind, block)) in - begin - try check_exp env let_exp unit_typ with - | Type_error (l, err) -> - raise (Reporting_basic.err_typ l (string_of_type_error err)) - end - | _ -> E_aux (e_aux, annot) - in - let assign_exp = { - id_exp_alg with - e_aux = (fun (e_aux, annot) -> assign_tuple e_aux annot) - } in - let assign_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp assign_exp) } in - rewrite_defs_base assign_defs defs - -let rewrite_simple_assignments defs = - let assign_e_aux e_aux annot = - let env = env_of_annot annot in - match e_aux with - | E_assign (lexp, exp) -> - let (lexp, rhs) = rewrite_lexp_to_rhs (fun _ -> true) lexp in - let assign = mk_exp (E_assign (strip_lexp lexp, strip_exp (rhs exp))) in - check_exp env assign unit_typ - | _ -> E_aux (e_aux, annot) - in - let assign_exp = { - id_exp_alg with - e_aux = (fun (e_aux, annot) -> assign_e_aux e_aux annot) - } in - let assign_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp assign_exp) } in - rewrite_defs_base assign_defs defs - -let rewrite_defs_remove_blocks = - let letbind_wild v body = - let l = get_loc_exp v in - let env = env_of v in - let typ = typ_of v in - let wild = P_typ (typ, annot_pat P_wild l env typ) in - let e_aux = E_let (annot_letbind (wild, v) l env typ, body) in - propagate_exp_effect (annot_exp e_aux l env (typ_of body)) in - - let rec f l = function - | [] -> E_aux (E_lit (L_aux (L_unit,gen_loc l)), (simple_annot l unit_typ)) - | [e] -> e (* check with Kathy if that annotation is fine *) - | e :: es -> letbind_wild e (f l es) in - - let e_aux = function - | (E_block es,(l,_)) -> f l es - | (e,annot) -> E_aux (e,annot) in - - let alg = { id_exp_alg with e_aux = e_aux } in - - rewrite_defs_base - {rewrite_exp = (fun _ -> fold_exp alg) - ; rewrite_pat = rewrite_pat - ; rewrite_let = rewrite_let - ; rewrite_lexp = rewrite_lexp - ; rewrite_fun = rewrite_fun - ; rewrite_def = rewrite_def - ; rewrite_defs = rewrite_defs_base - } - - - -let letbind (v : 'a exp) (body : 'a exp -> 'a exp) : 'a exp = - (* body is a function : E_id variable -> actual body *) - let (E_aux (_,(l,annot))) = v in - match annot with - | Some (env, Typ_aux (Typ_id tid, _), eff) when string_of_id tid = "unit" -> - let body = body (annot_exp (E_lit (mk_lit L_unit)) l env unit_typ) in - let body_typ = try typ_of body with _ -> unit_typ in - let wild = P_typ (typ_of v, annot_pat P_wild l env (typ_of v)) in - let lb = annot_letbind (wild, v) l env unit_typ in - propagate_exp_effect (annot_exp (E_let (lb, body)) l env body_typ) - | Some (env, typ, eff) -> - let id = fresh_id "w__" l in - let pat = P_typ (typ_of v, annot_pat (P_id id) l env (typ_of v)) in - let lb = annot_letbind (pat, v) l env typ in - let body = body (annot_exp (E_id id) l env typ) in - propagate_exp_effect (annot_exp (E_let (lb, body)) l env (typ_of body)) - | None -> - raise (Reporting_basic.err_unreachable l "no type information") - - -let rec mapCont (f : 'b -> ('b -> 'a exp) -> 'a exp) (l : 'b list) (k : 'b list -> 'a exp) : 'a exp = - match l with - | [] -> k [] - | exp :: exps -> f exp (fun exp -> mapCont f exps (fun exps -> k (exp :: exps))) - -let rewrite_defs_letbind_effects = - - let rec value ((E_aux (exp_aux,_)) as exp) = - not (effectful exp || updates_vars exp) - and value_optdefault (Def_val_aux (o,_)) = match o with - | Def_val_empty -> true - | Def_val_dec e -> value e - and value_fexps (FES_aux (FES_Fexps (fexps,_),_)) = - List.fold_left (fun b (FE_aux (FE_Fexp (_,e),_)) -> b && value e) true fexps in - - - let rec n_exp_name (exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp = - n_exp exp (fun exp -> if value exp then k exp else letbind exp k) - - and n_exp_pure (exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp = - n_exp exp (fun exp -> if value exp then k exp else letbind exp k) - - and n_exp_nameL (exps : 'a exp list) (k : 'a exp list -> 'a exp) : 'a exp = - mapCont n_exp_name exps k - - and n_fexp (fexp : 'a fexp) (k : 'a fexp -> 'a exp) : 'a exp = - let (FE_aux (FE_Fexp (id,exp),annot)) = fexp in - n_exp_name exp (fun exp -> - k (fix_eff_fexp (FE_aux (FE_Fexp (id,exp),annot)))) - - and n_fexpL (fexps : 'a fexp list) (k : 'a fexp list -> 'a exp) : 'a exp = - mapCont n_fexp fexps k - - and n_pexp (newreturn : bool) (pexp : 'a pexp) (k : 'a pexp -> 'a exp) : 'a exp = - match pexp with - | Pat_aux (Pat_exp (pat,exp),annot) -> - k (fix_eff_pexp (Pat_aux (Pat_exp (pat,n_exp_term newreturn exp), annot))) - | Pat_aux (Pat_when (pat,guard,exp),annot) -> - k (fix_eff_pexp (Pat_aux (Pat_when (pat,n_exp_term newreturn guard,n_exp_term newreturn exp), annot))) - - and n_pexpL (newreturn : bool) (pexps : 'a pexp list) (k : 'a pexp list -> 'a exp) : 'a exp = - mapCont (n_pexp newreturn) pexps k - - and n_fexps (fexps : 'a fexps) (k : 'a fexps -> 'a exp) : 'a exp = - let (FES_aux (FES_Fexps (fexps_aux,b),annot)) = fexps in - n_fexpL fexps_aux (fun fexps_aux -> - k (fix_eff_fexps (FES_aux (FES_Fexps (fexps_aux,b),annot)))) - - and n_opt_default (opt_default : 'a opt_default) (k : 'a opt_default -> 'a exp) : 'a exp = - let (Def_val_aux (opt_default,annot)) = opt_default in - match opt_default with - | Def_val_empty -> k (Def_val_aux (Def_val_empty,annot)) - | Def_val_dec exp -> - n_exp_name exp (fun exp -> - k (fix_eff_opt_default (Def_val_aux (Def_val_dec exp,annot)))) - - and n_lb (lb : 'a letbind) (k : 'a letbind -> 'a exp) : 'a exp = - let (LB_aux (lb,annot)) = lb in - match lb with - | LB_val (pat,exp1) -> - n_exp exp1 (fun exp1 -> - k (fix_eff_lb (LB_aux (LB_val (pat,exp1),annot)))) - - and n_lexp (lexp : 'a lexp) (k : 'a lexp -> 'a exp) : 'a exp = - let (LEXP_aux (lexp_aux,annot)) = lexp in - match lexp_aux with - | LEXP_id _ -> k lexp - | LEXP_memory (id,es) -> - n_exp_nameL es (fun es -> - k (fix_eff_lexp (LEXP_aux (LEXP_memory (id,es),annot)))) - | LEXP_tup es -> - n_lexpL es (fun es -> - k (fix_eff_lexp (LEXP_aux (LEXP_tup es,annot)))) - | LEXP_cast (typ,id) -> - k (fix_eff_lexp (LEXP_aux (LEXP_cast (typ,id),annot))) - | LEXP_vector (lexp,e) -> - n_lexp lexp (fun lexp -> - n_exp_name e (fun e -> - k (fix_eff_lexp (LEXP_aux (LEXP_vector (lexp,e),annot))))) - | LEXP_vector_range (lexp,e1,e2) -> - n_lexp lexp (fun lexp -> - n_exp_name e1 (fun e1 -> - n_exp_name e2 (fun e2 -> - k (fix_eff_lexp (LEXP_aux (LEXP_vector_range (lexp,e1,e2),annot)))))) - | LEXP_field (lexp,id) -> - n_lexp lexp (fun lexp -> - k (fix_eff_lexp (LEXP_aux (LEXP_field (lexp,id),annot)))) - - and n_lexpL (lexps : 'a lexp list) (k : 'a lexp list -> 'a exp) : 'a exp = - mapCont n_lexp lexps k - - and n_exp_term (newreturn : bool) (exp : 'a exp) : 'a exp = - let (E_aux (_,(l,tannot))) = exp in - let exp = - if newreturn then - (* let typ = try typ_of exp with _ -> unit_typ in *) - annot_exp (E_internal_return exp) l (env_of exp) (typ_of exp) - else - exp in - (* n_exp_term forces an expression to be translated into a form - "let .. let .. let .. in EXP" where EXP has no effect and does not update - variables *) - n_exp_pure exp (fun exp -> exp) - - and n_exp (E_aux (exp_aux,annot) as exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp = - - let rewrap e = fix_eff_exp (E_aux (e,annot)) in - - match exp_aux with - | E_block es -> failwith "E_block should have been removed till now" - | E_nondet _ -> failwith "E_nondet not supported" - | E_id id -> k exp - | E_lit _ -> k exp - | E_cast (typ,exp') -> - n_exp_name exp' (fun exp' -> - k (rewrap (E_cast (typ,exp')))) - | E_app (id,exps) -> - n_exp_nameL exps (fun exps -> - k (rewrap (E_app (id,exps)))) - | E_app_infix (exp1,id,exp2) -> - n_exp_name exp1 (fun exp1 -> - n_exp_name exp2 (fun exp2 -> - k (rewrap (E_app_infix (exp1,id,exp2))))) - | E_tuple exps -> - n_exp_nameL exps (fun exps -> - k (rewrap (E_tuple exps))) - | E_if (exp1,exp2,exp3) -> - n_exp_name exp1 (fun exp1 -> - let (E_aux (_,annot2)) = exp2 in - let (E_aux (_,annot3)) = exp3 in - let newreturn = effectful exp2 || effectful exp3 in - let exp2 = n_exp_term newreturn exp2 in - let exp3 = n_exp_term newreturn exp3 in - k (rewrap (E_if (exp1,exp2,exp3)))) - | E_for (id,start,stop,by,dir,body) -> - n_exp_name start (fun start -> - n_exp_name stop (fun stop -> - n_exp_name by (fun by -> - let body = n_exp_term (effectful body) body in - k (rewrap (E_for (id,start,stop,by,dir,body)))))) - | E_loop (loop, cond, body) -> - let cond = n_exp_term (effectful cond) cond in - let body = n_exp_term (effectful body) body in - k (rewrap (E_loop (loop,cond,body))) - | E_vector exps -> - n_exp_nameL exps (fun exps -> - k (rewrap (E_vector exps))) - | E_vector_access (exp1,exp2) -> - n_exp_name exp1 (fun exp1 -> - n_exp_name exp2 (fun exp2 -> - k (rewrap (E_vector_access (exp1,exp2))))) - | E_vector_subrange (exp1,exp2,exp3) -> - n_exp_name exp1 (fun exp1 -> - n_exp_name exp2 (fun exp2 -> - n_exp_name exp3 (fun exp3 -> - k (rewrap (E_vector_subrange (exp1,exp2,exp3)))))) - | E_vector_update (exp1,exp2,exp3) -> - n_exp_name exp1 (fun exp1 -> - n_exp_name exp2 (fun exp2 -> - n_exp_name exp3 (fun exp3 -> - k (rewrap (E_vector_update (exp1,exp2,exp3)))))) - | E_vector_update_subrange (exp1,exp2,exp3,exp4) -> - n_exp_name exp1 (fun exp1 -> - n_exp_name exp2 (fun exp2 -> - n_exp_name exp3 (fun exp3 -> - n_exp_name exp4 (fun exp4 -> - k (rewrap (E_vector_update_subrange (exp1,exp2,exp3,exp4))))))) - | E_vector_append (exp1,exp2) -> - n_exp_name exp1 (fun exp1 -> - n_exp_name exp2 (fun exp2 -> - k (rewrap (E_vector_append (exp1,exp2))))) - | E_list exps -> - n_exp_nameL exps (fun exps -> - k (rewrap (E_list exps))) - | E_cons (exp1,exp2) -> - n_exp_name exp1 (fun exp1 -> - n_exp_name exp2 (fun exp2 -> - k (rewrap (E_cons (exp1,exp2))))) - | E_record fexps -> - n_fexps fexps (fun fexps -> - k (rewrap (E_record fexps))) - | E_record_update (exp1,fexps) -> - n_exp_name exp1 (fun exp1 -> - n_fexps fexps (fun fexps -> - k (rewrap (E_record_update (exp1,fexps))))) - | E_field (exp1,id) -> - n_exp_name exp1 (fun exp1 -> - k (rewrap (E_field (exp1,id)))) - | E_case (exp1,pexps) -> - let newreturn = List.exists effectful_pexp pexps in - n_exp_name exp1 (fun exp1 -> - n_pexpL newreturn pexps (fun pexps -> - k (rewrap (E_case (exp1,pexps))))) - | E_let (lb,body) -> - n_lb lb (fun lb -> - rewrap (E_let (lb,n_exp body k))) - | E_sizeof nexp -> - k (rewrap (E_sizeof nexp)) - | E_constraint nc -> - k (rewrap (E_constraint nc)) - | E_sizeof_internal annot -> - k (rewrap (E_sizeof_internal annot)) - | E_assign (lexp,exp1) -> - n_lexp lexp (fun lexp -> - n_exp_name exp1 (fun exp1 -> - k (rewrap (E_assign (lexp,exp1))))) - | E_exit exp' -> k (E_aux (E_exit (n_exp_term (effectful exp') exp'),annot)) - | E_assert (exp1,exp2) -> - n_exp_name exp1 (fun exp1 -> - n_exp_name exp2 (fun exp2 -> - k (rewrap (E_assert (exp1,exp2))))) - | E_internal_cast (annot',exp') -> - n_exp_name exp' (fun exp' -> - k (rewrap (E_internal_cast (annot',exp')))) - | E_internal_exp _ -> k exp - | E_internal_exp_user _ -> k exp - | E_internal_let (lexp,exp1,exp2) -> - n_lexp lexp (fun lexp -> - n_exp exp1 (fun exp1 -> - rewrap (E_internal_let (lexp,exp1,n_exp exp2 k)))) - | E_internal_return exp1 -> - n_exp_name exp1 (fun exp1 -> - k (rewrap (E_internal_return exp1))) - | E_comment str -> - k (rewrap (E_comment str)) - | E_comment_struc exp' -> - n_exp exp' (fun exp' -> - k (rewrap (E_comment_struc exp'))) - | E_return exp' -> - n_exp_name exp' (fun exp' -> - k (rewrap (E_return exp'))) - | E_internal_plet _ -> failwith "E_internal_plet should not be here yet" in - - let rewrite_fun _ (FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),fdannot)) = - let effectful_funcl (FCL_aux (FCL_Funcl(_, _, exp), _)) = effectful exp in - let newreturn = List.exists effectful_funcl funcls in - let rewrite_funcl (FCL_aux (FCL_Funcl(id,pat,exp),annot)) = - let _ = reset_fresh_name_counter () in - FCL_aux (FCL_Funcl (id,pat,n_exp_term newreturn exp),annot) - in FD_aux (FD_function(recopt,tannotopt,effectopt,List.map rewrite_funcl funcls),fdannot) in - let rewrite_def rewriters def = - (* let _ = Pretty_print_sail.pp_defs stderr (Defs [def]) in *) - match def with - | DEF_val (LB_aux (lb, annot)) -> - let rewrap lb = DEF_val (LB_aux (lb, annot)) in - begin - match lb with - | LB_val (pat, exp) -> - rewrap (LB_val (pat, n_exp_term (effectful exp) exp)) - end - | DEF_fundef fdef -> DEF_fundef (rewrite_fun rewriters fdef) - | DEF_internal_mutrec fdefs -> - DEF_internal_mutrec (List.map (rewrite_fun rewriters) fdefs) - | d -> d in - rewrite_defs_base - {rewrite_exp = rewrite_exp - ; rewrite_pat = rewrite_pat - ; rewrite_let = rewrite_let - ; rewrite_lexp = rewrite_lexp - ; rewrite_fun = rewrite_fun - ; rewrite_def = rewrite_def - ; rewrite_defs = rewrite_defs_base - } - -let rewrite_defs_internal_lets = - - let rec pat_of_local_lexp (LEXP_aux (lexp, ((l, _) as annot))) = match lexp with - | LEXP_id id -> P_aux (P_id id, annot) - | LEXP_cast (typ, id) -> P_aux (P_typ (typ, P_aux (P_id id, annot)), annot) - | LEXP_tup lexps -> P_aux (P_tup (List.map pat_of_local_lexp lexps), annot) - | _ -> raise (Reporting_basic.err_unreachable l "unexpected local lexp") in - - let e_let (lb,body) = - match lb with - | LB_aux (LB_val (P_aux ((P_wild | P_typ (_, P_aux (P_wild, _))), _), - E_aux (E_assign ((LEXP_aux (_, annot) as le), exp), (l, _))), _) - when lexp_is_local le (env_of_annot annot) && not (lexp_is_effectful le) -> - (* Rewrite assignments to local variables into let bindings *) - let (lhs, rhs) = rewrite_lexp_to_rhs (fun _ -> true) le in - let (LEXP_aux (_, lannot)) = lhs in - let ltyp = typ_of_annot lannot in - let rhs = annot_exp (E_cast (ltyp, rhs exp)) l (env_of_annot lannot) ltyp in - E_let (LB_aux (LB_val (pat_of_local_lexp lhs, rhs), annot), body) - | LB_aux (LB_val (pat,exp'),annot') -> - if effectful exp' - then E_internal_plet (pat,exp',body) - else E_let (lb,body) in - - let e_internal_let = fun (lexp,exp1,exp2) -> - let paux, annot = match lexp with - | LEXP_aux (LEXP_id id, annot) -> - (P_id id, annot) - | LEXP_aux (LEXP_cast (typ, id), annot) -> - (P_typ (typ, P_aux (P_id id, annot)), annot) - | _ -> failwith "E_internal_let with unexpected lexp" in - if effectful exp1 then - E_internal_plet (P_aux (paux, annot), exp1, exp2) - else - E_let (LB_aux (LB_val (P_aux (paux, annot), exp1), annot), exp2) in - - let alg = { id_exp_alg with e_let = e_let; e_internal_let = e_internal_let } in - rewrite_defs_base - { rewrite_exp = (fun _ -> fold_exp alg) - ; rewrite_pat = rewrite_pat - ; rewrite_let = rewrite_let - ; rewrite_lexp = rewrite_lexp - ; rewrite_fun = rewrite_fun - ; rewrite_def = rewrite_def - ; rewrite_defs = rewrite_defs_base - } - - -(* Now all expressions have no blocks anymore, any term is a sequence of let-expressions, - * internal let-expressions, or internal plet-expressions ended by a term that does not - * access memory or registers and does not update variables *) - -let dedup eq = - List.fold_left (fun acc e -> if List.exists (eq e) acc then acc else e :: acc) [] - -let eqidtyp (id1,_) (id2,_) = - let name1 = match id1 with Id_aux ((Id name | DeIid name),_) -> name in - let name2 = match id2 with Id_aux ((Id name | DeIid name),_) -> name in - name1 = name2 - -let find_introduced_vars exp = - let lEXP_aux ((ids, lexp), annot) = - let ids = match lexp with - | LEXP_id id | LEXP_cast (_, id) - when id_is_unbound id (env_of_annot annot) -> IdSet.add id ids - | _ -> ids in - (ids, LEXP_aux (lexp, annot)) in - fst (fold_exp - { (compute_exp_alg IdSet.empty IdSet.union) with lEXP_aux = lEXP_aux } exp) - -let find_updated_vars exp = - let intros = find_introduced_vars exp in - let lEXP_aux ((ids, lexp), annot) = - let ids = match lexp with - | LEXP_id id | LEXP_cast (_, id) - when id_is_local_var id (env_of_annot annot) && not (IdSet.mem id intros) -> - (id, annot) :: ids - | _ -> ids in - (ids, LEXP_aux (lexp, annot)) in - dedup eqidtyp (fst (fold_exp - { (compute_exp_alg [] (@)) with lEXP_aux = lEXP_aux } exp)) - -let swaptyp typ (l,tannot) = match tannot with - | Some (env, typ', eff) -> (l, Some (env, typ, eff)) - | _ -> raise (Reporting_basic.err_unreachable l "swaptyp called with empty type annotation") - -type 'a updated_term = - | Added_vars of 'a exp * 'a pat - | Same_vars of 'a exp - -let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) = - - let env = env_of exp in - - let rec add_vars overwrite ((E_aux (expaux,annot)) as exp) vars = - match expaux with - | E_let (lb,exp) -> - let exp = add_vars overwrite exp vars in - E_aux (E_let (lb,exp),swaptyp (typ_of exp) annot) - | E_internal_let (lexp,exp1,exp2) -> - let exp2 = add_vars overwrite exp2 vars in - E_aux (E_internal_let (lexp,exp1,exp2), swaptyp (typ_of exp2) annot) - | E_internal_plet (pat,exp1,exp2) -> - let exp2 = add_vars overwrite exp2 vars in - E_aux (E_internal_plet (pat,exp1,exp2), swaptyp (typ_of exp2) annot) - | E_internal_return exp2 -> - let exp2 = add_vars overwrite exp2 vars in - E_aux (E_internal_return exp2,swaptyp (typ_of exp2) annot) - | _ -> - (* after rewrite_defs_letbind_effects there cannot be terms that have - effects/update local variables in "tail-position": check n_exp_term - and where it is used. *) - if overwrite then - match typ_of exp with - | Typ_aux (Typ_id (Id_aux (Id "unit", _)), _) -> vars - | _ -> raise (Reporting_basic.err_unreachable l - "add_vars: trying to overwrite a non-unit expression in tail-position") - else - let typ' = Typ_aux (Typ_tup [typ_of exp;typ_of vars], gen_loc l) in - E_aux (E_tuple [exp;vars],swaptyp typ' annot) in - - let mk_varstup l es = - let exp_to_pat (E_aux (eaux, annot) as exp) = match eaux with - | E_lit lit -> - P_aux (P_lit lit, annot) - | E_id id -> - annot_pat (P_id id) l (env_of exp) (typ_of exp) - | _ -> raise (Reporting_basic.err_unreachable l - ("Failed to extract pattern from expression " ^ string_of_exp exp)) in - match es with - | [] -> - annot_exp (E_lit (mk_lit L_unit)) (gen_loc l) Env.empty unit_typ, - annot_pat P_wild (gen_loc l) Env.empty unit_typ - | [e] -> - let e = infer_exp (env_of e) (strip_exp e) in - e, annot_pat (P_typ (typ_of e, exp_to_pat e)) l (env_of e) (typ_of e) - | e :: _ -> - let infer_e e = infer_exp (env_of e) (strip_exp e) in - let es = List.map infer_e es in - let pats = List.map exp_to_pat es in - let typ = tuple_typ (List.map typ_of es) in - annot_exp (E_tuple es) l (env_of e) typ, - annot_pat (P_typ (typ, annot_pat (P_tup pats) l (env_of e) typ)) l (env_of e) typ in - - let rewrite (E_aux (expaux,((el,_) as annot)) as full_exp) (P_aux (_,(pl,pannot)) as pat) = - let env = env_of_annot annot in - let overwrite = match typ_of full_exp with - | Typ_aux (Typ_id (Id_aux (Id "unit", _)), _) -> true - | _ -> false in - match expaux with - | E_for(id,exp1,exp2,exp3,order,exp4) -> - (* Translate for loops into calls to one of the foreach combinators. - The loop body becomes a function of the loop variable and any - mutable local variables that are updated inside the loop. - Since the foreach* combinators are higher-order functions, - they cannot be represented faithfully in the AST. The following - code abuses the parameters of an E_app node, embedding the loop body - function as an expression followed by the list of variables it - expects. In (Lem) pretty-printing, this turned into an anonymous - function and passed to foreach*. *) - let vars = List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t))) (find_updated_vars exp4) in - let varstuple, varspat = mk_varstup el vars in - let varstyp = typ_of varstuple in - let exp4 = rewrite_var_updates (add_vars overwrite exp4 varstuple) in - let ord_exp, lower, upper = match destruct_range (typ_of exp1), destruct_range (typ_of exp2) with - | None, _ | _, None -> - raise (Reporting_basic.err_unreachable el "Could not determine loop bounds") - | Some (l1, u1), Some (l2, u2) -> - if is_order_inc order - then (annot_exp (E_lit (mk_lit L_true)) el env bool_typ, l1, u2) - else (annot_exp (E_lit (mk_lit L_false)) el env bool_typ, l2, u1) in - let lvar_kid = mk_kid ("loop_" ^ string_of_id id) in - let lvar_nc = nc_and (nc_lteq lower (nvar lvar_kid)) (nc_lteq (nvar lvar_kid) upper) in - let lvar_typ = mk_typ (Typ_exist ([lvar_kid], lvar_nc, atom_typ (nvar lvar_kid))) in - let lvar_pat = P_typ (lvar_typ, annot_pat (P_var ( - annot_pat (P_id id) el env (atom_typ (nvar lvar_kid)), - lvar_kid)) el env lvar_typ) in - let lb = annot_letbind (lvar_pat, exp1) el env lvar_typ in - let body = annot_exp (E_let (lb, exp4)) el env (typ_of exp4) in - let v = annot_exp (E_app (mk_id "foreach", [exp1; exp2; exp3; ord_exp; varstuple; body])) el env (typ_of body) in - let pat = - if overwrite then varspat - else annot_pat (P_tup [pat; varspat]) pl env (typ_of v) in - Added_vars (v,pat) - | E_loop(loop,cond,body) -> - let vars = List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t))) (find_updated_vars body) in - let varstuple, varspat = mk_varstup el vars in - let varstyp = typ_of varstuple in - (* let cond = rewrite_var_updates (add_vars false cond varstuple) in *) - let body = rewrite_var_updates (add_vars overwrite body varstuple) in - let (E_aux (_,(_,bannot))) = body in - let fname = match loop with - | While -> "while" - | Until -> "until" in - let funcl = Id_aux (Id fname,gen_loc el) in - let v = E_aux (E_app (funcl,[cond;varstuple;body]), (gen_loc el, bannot)) in - let pat = - if overwrite then varspat - else annot_pat (P_tup [pat; varspat]) pl env (typ_of v) in - Added_vars (v,pat) - | E_if (c,e1,e2) -> - let vars = List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t))) - (dedup eqidtyp (find_updated_vars e1 @ find_updated_vars e2)) in - if vars = [] then - (Same_vars (E_aux (E_if (c,rewrite_var_updates e1,rewrite_var_updates e2),annot))) - else - let varstuple, varspat = mk_varstup el vars in - let varstyp = typ_of varstuple in - let e1 = rewrite_var_updates (add_vars overwrite e1 varstuple) in - let e2 = rewrite_var_updates (add_vars overwrite e2 varstuple) in - (* after rewrite_defs_letbind_effects c has no variable updates *) - let env = env_of_annot annot in - let typ = typ_of e1 in - let eff = union_eff_exps [e1;e2] in - let v = E_aux (E_if (c,e1,e2), (gen_loc el, Some (env, typ, eff))) in - let pat = - if overwrite then varspat - else annot_pat (P_tup [pat; varspat]) pl env (typ_of v) in - Added_vars (v,pat) - | E_case (e1,ps) -> - (* after rewrite_defs_letbind_effects e1 needs no rewriting *) - let vars = - let f acc (Pat_aux ((Pat_exp (_,e)|Pat_when (_,_,e)),_)) = - acc @ find_updated_vars e in - List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t))) - (dedup eqidtyp (List.fold_left f [] ps)) in - if vars = [] then - let ps = List.map (function - | Pat_aux (Pat_exp (p,e),a) -> - Pat_aux (Pat_exp (p,rewrite_var_updates e),a) - | Pat_aux (Pat_when (p,g,e),a) -> - Pat_aux (Pat_when (p,g,rewrite_var_updates e),a)) ps in - Same_vars (E_aux (E_case (e1,ps),annot)) - else - let varstuple, varspat = mk_varstup el vars in - let varstyp = typ_of varstuple in - let rewrite_pexp (Pat_aux (pexp, (l, _))) = match pexp with - | Pat_exp (pat, exp) -> - let exp = rewrite_var_updates (add_vars overwrite exp varstuple) in - let pannot = (l, Some (env_of exp, typ_of exp, effect_of exp)) in - Pat_aux (Pat_exp (pat, exp), pannot) - | Pat_when _ -> - raise (Reporting_basic.err_unreachable l - "Guarded patterns should have been rewritten already") in - let typ = match ps with - | Pat_aux ((Pat_exp (_,first)|Pat_when (_,_,first)),_) :: _ -> typ_of first - | _ -> unit_typ in - let v = propagate_exp_effect (annot_exp (E_case (e1, List.map rewrite_pexp ps)) pl env typ) in - let pat = - if overwrite then varspat - else annot_pat (P_tup [pat; varspat]) pl env (typ_of v) in - Added_vars (v,pat) - | E_assign (lexp,vexp) -> - let mk_id_pat id = match Env.lookup_id id env with - | Local (_, typ) -> - annot_pat (P_typ (typ, annot_pat (P_id id) pl env typ)) pl env typ - | _ -> - raise (Reporting_basic.err_unreachable pl - ("Failed to look up type of variable " ^ string_of_id id)) in - if effectful exp then - Same_vars (E_aux (E_assign (lexp,vexp),annot)) - else - (match lexp with - | LEXP_aux (LEXP_id id,annot) -> - let pat = annot_pat (P_id id) pl env (typ_of vexp) in - Added_vars (vexp, mk_id_pat id) - | LEXP_aux (LEXP_cast (typ,id),annot) -> - let pat = annot_pat (P_typ (typ, annot_pat (P_id id) pl env (typ_of vexp))) pl env typ in - Added_vars (vexp,pat) - | LEXP_aux (LEXP_vector (LEXP_aux (LEXP_id id,((l2,_) as annot2)),i),((l1,_) as annot)) -> - let eid = annot_exp (E_id id) l2 env (typ_of_annot annot2) in - let vexp = annot_exp (E_vector_update (eid,i,vexp)) l1 env (typ_of_annot annot) in - let pat = annot_pat (P_id id) pl env (typ_of vexp) in - Added_vars (vexp,pat) - | LEXP_aux (LEXP_vector_range (LEXP_aux (LEXP_id id,((l2,_) as annot2)),i,j), - ((l,_) as annot)) -> - let eid = annot_exp (E_id id) l2 env (typ_of_annot annot2) in - let vexp = annot_exp (E_vector_update_subrange (eid,i,j,vexp)) l env (typ_of_annot annot) in - let pat = annot_pat (P_id id) pl env (typ_of vexp) in - Added_vars (vexp,pat) - | _ -> Same_vars (E_aux (E_assign (lexp,vexp),annot))) - | _ -> - (* after rewrite_defs_letbind_effects this expression is pure and updates - no variables: check n_exp_term and where it's used. *) - Same_vars (E_aux (expaux,annot)) in - - match expaux with - | E_let (lb,body) -> - let body = rewrite_var_updates body in - let (LB_aux (LB_val (pat, v), lbannot)) = lb in - let lb = match rewrite v pat with - | Added_vars (v, P_aux (pat, _)) -> - annot_letbind (pat, v) (get_loc_exp v) env (typ_of v) - | Same_vars v -> LB_aux (LB_val (pat, v),lbannot) in - propagate_exp_effect (annot_exp (E_let (lb, body)) l env (typ_of body)) - | E_internal_let (lexp,v,body) -> - (* Rewrite E_internal_let into E_let and call recursively *) - let paux, typ = match lexp with - | LEXP_aux (LEXP_id id, _) -> - P_id id, typ_of v - | LEXP_aux (LEXP_cast (typ, id), _) -> - P_typ (typ, annot_pat (P_id id) l env (typ_of v)), typ - | _ -> - raise (Reporting_basic.err_unreachable l - "E_internal_let with a lexp that is not a variable") in - let lb = annot_letbind (paux, v) l env typ in - let exp = propagate_exp_effect (annot_exp (E_let (lb, body)) l env (typ_of body)) in - rewrite_var_updates exp - | E_internal_plet (pat,v,body) -> - failwith "rewrite_var_updates: E_internal_plet shouldn't be introduced yet" - (* There are no expressions that have effects or variable updates in - "tail-position": check the definition nexp_term and where it is used. *) - | _ -> exp - -let replace_memwrite_e_assign exp = - let e_aux = fun (expaux,annot) -> - match expaux with - | E_assign (LEXP_aux (LEXP_memory (id,args),_),v) -> E_aux (E_app (id,args @ [v]),annot) - | _ -> E_aux (expaux,annot) in - fold_exp { id_exp_alg with e_aux = e_aux } exp - - - -let remove_reference_types exp = - - let rec rewrite_t (Typ_aux (t_aux,a)) = (Typ_aux (rewrite_t_aux t_aux,a)) - and rewrite_t_aux t_aux = match t_aux with - | Typ_app (Id_aux (Id "reg",_), [Typ_arg_aux (Typ_arg_typ (Typ_aux (t_aux2, _)), _)]) -> - rewrite_t_aux t_aux2 - | Typ_app (name,t_args) -> Typ_app (name,List.map rewrite_t_arg t_args) - | Typ_fn (t1,t2,eff) -> Typ_fn (rewrite_t t1,rewrite_t t2,eff) - | Typ_tup ts -> Typ_tup (List.map rewrite_t ts) - | _ -> t_aux - and rewrite_t_arg t_arg = match t_arg with - | Typ_arg_aux (Typ_arg_typ t, a) -> Typ_arg_aux (Typ_arg_typ (rewrite_t t), a) - | _ -> t_arg in - - let rec rewrite_annot = function - | (l, None) -> (l, None) - | (l, Some (env, typ, eff)) -> (l, Some (env, rewrite_t typ, eff)) in - - map_exp_annot rewrite_annot exp - - - -let rewrite_defs_remove_superfluous_letbinds = - - let e_aux (exp,annot) = match exp with - | E_let (lb,exp2) -> - begin match lb,exp2 with - (* 'let x = EXP1 in x' can be replaced with 'EXP1' *) - | LB_aux (LB_val (P_aux (P_id id, _), exp1), _), - E_aux (E_id id', _) - | LB_aux (LB_val (P_aux (P_id id, _), exp1), _), - E_aux (E_cast (_,E_aux (E_id id', _)), _) - when Id.compare id id' == 0 && id_is_unbound id (env_of_annot annot) -> - exp1 - (* "let x = EXP1 in return x" can be replaced with 'return (EXP1)', at - least when EXP1 is 'small' enough *) - | LB_aux (LB_val (P_aux (P_id id, _), exp1), _), - E_aux (E_internal_return (E_aux (E_id id', _)), _) - when Id.compare id id' == 0 && small exp1 && id_is_unbound id (env_of_annot annot) -> - let (E_aux (_,e1annot)) = exp1 in - E_aux (E_internal_return (exp1),e1annot) - | _ -> E_aux (exp,annot) - end - | _ -> E_aux (exp,annot) in - - let alg = { id_exp_alg with e_aux = e_aux } in - rewrite_defs_base - { rewrite_exp = (fun _ -> fold_exp alg) - ; rewrite_pat = rewrite_pat - ; rewrite_let = rewrite_let - ; rewrite_lexp = rewrite_lexp - ; rewrite_fun = rewrite_fun - ; rewrite_def = rewrite_def - ; rewrite_defs = rewrite_defs_base - } - - -let rewrite_defs_remove_superfluous_returns = - - let has_unittype e = match typ_of e with - | Typ_aux (Typ_id (Id_aux (Id "unit", _)), _) -> true - | _ -> false in - - let untyp_pat = function - | P_aux (P_typ (typ, pat), _) -> pat, Some typ - | pat -> pat, None in - - let uncast_internal_return = function - | E_aux (E_internal_return (E_aux (E_cast (typ, exp), _)), a) -> - E_aux (E_internal_return exp, a), Some typ - | exp -> exp, None in - - let e_aux (exp,annot) = match exp with - | E_let (LB_aux (LB_val (pat, exp1), _), exp2) - | E_internal_plet (pat, exp1, exp2) - when effectful exp1 -> - begin match untyp_pat pat, uncast_internal_return exp2 with - | (P_aux (P_lit (L_aux (lit,_)),_), ptyp), - (E_aux (E_internal_return (E_aux (E_lit (L_aux (lit',_)),_)), a), etyp) - when lit = lit' -> - begin - match ptyp, etyp with - | Some typ, _ | _, Some typ -> E_aux (E_cast (typ, exp1), a) - | None, None -> exp1 - end - | (P_aux (P_wild,pannot), ptyp), - (E_aux (E_internal_return (E_aux (E_lit (L_aux (L_unit,_)),_)), a), etyp) - when has_unittype exp1 -> - begin - match ptyp, etyp with - | Some typ, _ | _, Some typ -> E_aux (E_cast (typ, exp1), a) - | None, None -> exp1 - end - | (P_aux (P_id id,_), ptyp), - (E_aux (E_internal_return (E_aux (E_id id',_)), a), etyp) - when Id.compare id id' == 0 && id_is_unbound id (env_of_annot annot) -> - begin - match ptyp, etyp with - | Some typ, _ | _, Some typ -> E_aux (E_cast (typ, exp1), a) - | None, None -> exp1 - end - | _ -> E_aux (exp,annot) - end - | _ -> E_aux (exp,annot) in - - let alg = { id_exp_alg with e_aux = e_aux } in - rewrite_defs_base - { rewrite_exp = (fun _ -> fold_exp alg) - ; rewrite_pat = rewrite_pat - ; rewrite_let = rewrite_let - ; rewrite_lexp = rewrite_lexp - ; rewrite_fun = rewrite_fun - ; rewrite_def = rewrite_def - ; rewrite_defs = rewrite_defs_base - } - - -let rewrite_defs_remove_e_assign (Defs defs) = - let (Defs loop_specs) = fst (check Env.empty (Defs (List.map gen_vs - [("foreach", "forall ('vars : Type). (int, int, int, bool, 'vars, 'vars) -> 'vars"); - ("while", "forall ('vars : Type). (bool, 'vars, 'vars) -> 'vars"); - ("until", "forall ('vars : Type). (bool, 'vars, 'vars) -> 'vars")]))) in - let rewrite_exp _ e = - replace_memwrite_e_assign (remove_reference_types (rewrite_var_updates e)) in - rewrite_defs_base - { rewrite_exp = rewrite_exp - ; rewrite_pat = rewrite_pat - ; rewrite_let = rewrite_let - ; rewrite_lexp = rewrite_lexp - ; rewrite_fun = rewrite_fun - ; rewrite_def = rewrite_def - ; rewrite_defs = rewrite_defs_base - } (Defs (loop_specs @ defs)) - -let recheck_defs defs = fst (check initial_env defs) - -let rewrite_defs_lem = [ - ("tuple_vector_assignments", rewrite_tuple_vector_assignments); - ("tuple_assignments", rewrite_tuple_assignments); - (* ("simple_assignments", rewrite_simple_assignments); *) - ("remove_vector_concat", rewrite_defs_remove_vector_concat); - ("remove_bitvector_pats", rewrite_defs_remove_bitvector_pats); - ("guarded_pats", rewrite_defs_guarded_pats); - ("exp_lift_assign", rewrite_defs_exp_lift_assign); - ("register_ref_writes", rewrite_register_ref_writes); - ("recheck_defs", recheck_defs); - (* ("constraint", rewrite_constraint); *) - (* ("remove_assert", rewrite_defs_remove_assert); *) - ("top_sort_defs", top_sort_defs); - ("trivial_sizeof", rewrite_trivial_sizeof); - ("sizeof", rewrite_sizeof); - ("early_return", rewrite_defs_early_return); - ("nexp_ids", rewrite_defs_nexp_ids); - ("fix_val_specs", rewrite_fix_val_specs); - ("remove_blocks", rewrite_defs_remove_blocks); - ("letbind_effects", rewrite_defs_letbind_effects); - ("remove_e_assign", rewrite_defs_remove_e_assign); - ("internal_lets", rewrite_defs_internal_lets); - ("remove_superfluous_letbinds", rewrite_defs_remove_superfluous_letbinds); - ("remove_superfluous_returns", rewrite_defs_remove_superfluous_returns); - ("recheck_defs", recheck_defs) - ] - -let rewrite_defs_ocaml = [ - (* ("top_sort_defs", top_sort_defs); *) - (* ("undefined", rewrite_undefined); *) - ("tuple_vector_assignments", rewrite_tuple_vector_assignments); - ("tuple_assignments", rewrite_tuple_assignments); - ("simple_assignments", rewrite_simple_assignments); - ("remove_vector_concat", rewrite_defs_remove_vector_concat); - ("constraint", rewrite_constraint); - ("trivial_sizeof", rewrite_trivial_sizeof); - ("sizeof", rewrite_sizeof); - ("simple_types", rewrite_simple_types); - ("overload_cast", rewrite_overload_cast); - ("exp_lift_assign", rewrite_defs_exp_lift_assign); - (* ("separate_numbs", rewrite_defs_separate_numbs) *) - ] - -let rewrite_check_annot = - let check_annot exp = - try - prerr_endline ("CHECKING: " ^ string_of_exp exp ^ " : " ^ string_of_typ (typ_of exp)); - let _ = check_exp (env_of exp) (strip_exp exp) (typ_of exp) in - exp - with - Type_error (l, err) -> raise (Reporting_basic.err_typ l (string_of_type_error err)) - in - let rewrite_exp = { id_exp_alg with e_aux = (fun (exp, annot) -> check_annot (E_aux (exp, annot))) } in - rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp rewrite_exp) } - -let rewrite_defs_check = [ - ("check_annotations", rewrite_check_annot); - ] diff --git a/src/rewriter.mli b/src/rewriter.mli index c107be25..cd293ca5 100644 --- a/src/rewriter.mli +++ b/src/rewriter.mli @@ -9,7 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) (* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -55,13 +62,23 @@ type 'a rewriters = { rewrite_exp : 'a rewriters -> 'a exp -> 'a exp; } val rewrite_exp : tannot rewriters -> tannot exp -> tannot exp + +val rewriters_base : tannot rewriters + +(* The identity re-writer *) val rewrite_defs : tannot defs -> tannot defs -val rewrite_undefined : bool -> tannot defs -> tannot defs -val rewrite_defs_ocaml : (string * (tannot defs -> tannot defs)) list (*Perform rewrites to exclude AST nodes not supported for ocaml out*) -val rewrite_defs_lem : (string * (tannot defs -> tannot defs)) list (*Perform rewrites to exclude AST nodes not supported for lem out*) -val rewrite_defs_check : (string * (tannot defs -> tannot defs)) list -val simple_typ : typ -> typ +val rewrite_defs_base : tannot rewriters -> tannot defs -> tannot defs + +val rewrite_lexp : tannot rewriters -> tannot lexp -> tannot lexp + +val rewrite_pat : tannot rewriters -> tannot pat -> tannot pat + +val rewrite_let : tannot rewriters -> tannot letbind -> tannot letbind + +val rewrite_def : tannot rewriters -> tannot def -> tannot def + +val rewrite_fun : tannot rewriters -> tannot fundef -> tannot fundef (* the type of interpretations of pattern-matching expressions *) type ('a,'pat,'pat_aux,'fpat,'fpat_aux) pat_alg = @@ -82,10 +99,8 @@ type ('a,'pat,'pat_aux,'fpat,'fpat_aux) pat_alg = ; fP_aux : 'fpat_aux * 'a annot -> 'fpat ; fP_Fpat : id * 'pat -> 'fpat_aux } - (* fold over pat_aux expressions *) - (* the type of interpretations of expressions *) type ('a,'exp,'exp_aux,'lexp,'lexp_aux,'fexp,'fexp_aux,'fexps,'fexps_aux, 'opt_default_aux,'opt_default,'pexp,'pexp_aux,'letbind_aux,'letbind, @@ -118,6 +133,7 @@ type ('a,'exp,'exp_aux,'lexp,'lexp_aux,'fexp,'fexp_aux,'fexps,'fexps_aux, ; e_sizeof : nexp -> 'exp_aux ; e_constraint : n_constraint -> 'exp_aux ; e_exit : 'exp -> 'exp_aux + ; e_throw : 'exp -> 'exp_aux ; e_return : 'exp -> 'exp_aux ; e_assert : 'exp * 'exp -> 'exp_aux ; e_internal_cast : 'a annot * 'exp -> 'exp_aux @@ -177,3 +193,24 @@ val compute_exp_alg : 'b -> ('b -> 'b -> 'b) -> ('b * 'a opt_default_aux),('b * 'a opt_default),('b * 'a pexp),('b * 'a pexp_aux), ('b * 'a letbind_aux),('b * 'a letbind), ('b * 'a pat),('b * 'a pat_aux),('b * 'a fpat),('b * 'a fpat_aux)) exp_alg + +val simple_annot : Parse_ast.l -> typ -> Parse_ast.l * tannot + +val union_eff_exps : (tannot exp) list -> effect + +val fix_eff_exp : tannot exp -> tannot exp + +val fix_eff_lexp : tannot lexp -> tannot lexp + +val fix_eff_lb : tannot letbind -> tannot letbind + +val fix_eff_pexp : tannot pexp -> tannot pexp + +val fix_eff_fexp : tannot fexp -> tannot fexp + +val fix_eff_fexps : tannot fexps -> tannot fexps + +val fix_eff_opt_default : tannot opt_default -> tannot opt_default + +(* AA: How this is used in rewrite_pat seems suspect to me *) +val vector_string_to_bit_list : Parse_ast.l -> lit_aux -> lit list diff --git a/src/rewrites.ml b/src/rewrites.ml new file mode 100644 index 00000000..333f87cb --- /dev/null +++ b/src/rewrites.ml @@ -0,0 +1,2905 @@ +(**************************************************************************) +(* Sail *) +(* *) +(* Copyright (c) 2013-2017 *) +(* 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 *) +(* *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(**************************************************************************) + +open Big_int +open Ast +open Ast_util +open Type_check +open Spec_analysis +open Rewriter + +let (>>) f g = fun x -> g(f(x)) + +let fresh_name_counter = ref 0 + +let fresh_name () = + let current = !fresh_name_counter in + let () = fresh_name_counter := (current + 1) in + current + +let reset_fresh_name_counter () = + fresh_name_counter := 0 + +let fresh_id pre l = + let current = fresh_name () in + Id_aux (Id (pre ^ string_of_int current), gen_loc l) + +let fresh_id_exp pre ((l,annot)) = + let id = fresh_id pre l in + E_aux (E_id id, (gen_loc l, annot)) + +let fresh_id_pat pre ((l,annot)) = + let id = fresh_id pre l in + P_aux (P_id id, (gen_loc l, annot)) + +let get_loc_exp (E_aux (_,(l,_))) = l + +let gen_vs (id, spec) = Initial_check.val_spec_of_string dec_ord (mk_id id) spec + +let annot_exp_effect e_aux l env typ effect = E_aux (e_aux, (l, Some (env, typ, effect))) +let annot_exp e_aux l env typ = annot_exp_effect e_aux l env typ no_effect +let annot_pat p_aux l env typ = P_aux (p_aux, (l, Some (env, typ, no_effect))) +let annot_letbind (p_aux, exp) l env typ = + LB_aux (LB_val (annot_pat p_aux l env typ, exp), (l, Some (env, typ, effect_of exp))) + +let simple_num l n = E_aux ( + E_lit (L_aux (L_num n, gen_loc l)), + simple_annot (gen_loc l) + (atom_typ (Nexp_aux (Nexp_constant n, gen_loc l)))) + +let effectful_effs = function + | Effect_aux (Effect_set effs, _) -> + List.exists + (fun (BE_aux (be,_)) -> + match be with + | BE_nondet | BE_unspec | BE_undef | BE_lset -> false + | _ -> true + ) effs + | _ -> true + +let effectful eaux = effectful_effs (effect_of (propagate_exp_effect eaux)) +let effectful_pexp pexp = effectful_effs (snd (propagate_pexp_effect pexp)) + +let rec small (E_aux (exp,_)) = match exp with + | E_id _ + | E_lit _ -> true + | E_cast (_,e) -> small e + | E_list es -> List.for_all small es + | E_cons (e1,e2) -> small e1 && small e2 + | E_sizeof _ -> true + | _ -> false + +let rec rewrite_nexp_ids env (Nexp_aux (nexp, l) as nexp_aux) = match nexp with +| Nexp_id id -> rewrite_nexp_ids env (Env.get_num_def id env) +| Nexp_times (nexp1, nexp2) -> Nexp_aux (Nexp_times (rewrite_nexp_ids env nexp1, rewrite_nexp_ids env nexp2), l) +| Nexp_sum (nexp1, nexp2) -> Nexp_aux (Nexp_sum (rewrite_nexp_ids env nexp1, rewrite_nexp_ids env nexp2), l) +| Nexp_minus (nexp1, nexp2) -> Nexp_aux (Nexp_minus (rewrite_nexp_ids env nexp1, rewrite_nexp_ids env nexp2), l) +| Nexp_exp nexp -> Nexp_aux (Nexp_exp (rewrite_nexp_ids env nexp), l) +| Nexp_neg nexp -> Nexp_aux (Nexp_neg (rewrite_nexp_ids env nexp), l) +| _ -> nexp_aux + +let rewrite_defs_nexp_ids, rewrite_typ_nexp_ids = + let rec rewrite_typ env (Typ_aux (typ, l) as typ_aux) = match typ with + | Typ_fn (arg_t, ret_t, eff) -> + Typ_aux (Typ_fn (rewrite_typ env arg_t, rewrite_typ env ret_t, eff), l) + | Typ_tup ts -> + Typ_aux (Typ_tup (List.map (rewrite_typ env) ts), l) + | Typ_exist (kids, c, typ) -> + Typ_aux (Typ_exist (kids, c, rewrite_typ env typ), l) + | Typ_app (id, targs) -> + Typ_aux (Typ_app (id, List.map (rewrite_typ_arg env) targs), l) + | _ -> typ_aux + and rewrite_typ_arg env (Typ_arg_aux (targ, l) as targ_aux) = match targ with + | Typ_arg_nexp nexp -> + Typ_arg_aux (Typ_arg_nexp (rewrite_nexp_ids env nexp), l) + | Typ_arg_typ typ -> + Typ_arg_aux (Typ_arg_typ (rewrite_typ env typ), l) + | Typ_arg_order ord -> + Typ_arg_aux (Typ_arg_order ord, l) + in + + let rewrite_annot = function + | (l, Some (env, typ, eff)) -> (l, Some (env, rewrite_typ env typ, eff)) + | (l, None) -> (l, None) + in + + rewrite_defs_base { + rewriters_base with rewrite_exp = (fun _ -> map_exp_annot rewrite_annot) + }, + rewrite_typ + + +(* Re-write trivial sizeof expressions - trivial meaning that the + value of the sizeof can be directly inferred from the type + variables in scope. *) +let rewrite_trivial_sizeof, rewrite_trivial_sizeof_exp = + let extract_typ_var l env nexp (id, (_, typ)) = + let var = E_aux (E_id id, (l, Some (env, typ, no_effect))) in + match destruct_atom_nexp env typ with + | Some size when prove env (nc_eq size nexp) -> Some var + (* AA: This next case is a bit of a hack... is there a more + general way to deal with trivial nexps that are offset by + constants? This will resolve a 'n - 1 sizeof when 'n is in + scope. *) + | Some size when prove env (nc_eq (nsum size (nint 1)) nexp) -> + let one_exp = infer_exp env (mk_lit_exp (L_num unit_big_int)) in + Some (E_aux (E_app (mk_id "add_range", [var; one_exp]), (gen_loc l, Some (env, atom_typ (nsum size (nint 1)), no_effect)))) + | _ -> + begin + match destruct_vector env typ with + | Some (_, len, _, _) when prove env (nc_eq len nexp) -> + Some (E_aux (E_app (mk_id "length", [var]), (l, Some (env, atom_typ len, no_effect)))) + | _ -> None + end + in + let rec split_nexp (Nexp_aux (nexp_aux, l) as nexp) = + match nexp_aux with + | Nexp_sum (n1, n2) -> + mk_exp (E_app (mk_id "add_range", [split_nexp n1; split_nexp n2])) + | Nexp_minus (n1, n2) -> + mk_exp (E_app (mk_id "sub_range", [split_nexp n1; split_nexp n2])) + | Nexp_times (n1, n2) -> + mk_exp (E_app (mk_id "mult_range", [split_nexp n1; split_nexp n2])) + | Nexp_neg nexp -> mk_exp (E_app (mk_id "negate_range", [split_nexp nexp])) + | _ -> mk_exp (E_sizeof nexp) + in + let rec rewrite_e_aux split_sizeof (E_aux (e_aux, (l, _)) as orig_exp) = + let env = env_of orig_exp in + match e_aux with + | E_sizeof (Nexp_aux (Nexp_constant c, _) as nexp) -> + E_aux (E_lit (L_aux (L_num c, l)), (l, Some (env, atom_typ nexp, no_effect))) + | E_sizeof nexp -> + begin + match nexp_simp (rewrite_nexp_ids (env_of orig_exp) nexp) with + | Nexp_aux (Nexp_constant c, _) -> + E_aux (E_lit (L_aux (L_num c, l)), (l, Some (env, atom_typ nexp, no_effect))) + | _ -> + let locals = Env.get_locals env in + let exps = Bindings.bindings locals + |> List.map (extract_typ_var l env nexp) + |> List.map (fun opt -> match opt with Some x -> [x] | None -> []) + |> List.concat + in + match exps with + | (exp :: _) -> check_exp env (strip_exp exp) (typ_of exp) + | [] when split_sizeof -> + fold_exp (rewrite_e_sizeof false) (check_exp env (split_nexp nexp) (typ_of orig_exp)) + | [] -> orig_exp + end + | _ -> orig_exp + and rewrite_e_sizeof split_sizeof = + { id_exp_alg with e_aux = (fun (exp, annot) -> rewrite_e_aux split_sizeof (E_aux (exp, annot))) } + in + rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp (rewrite_e_sizeof true)) }, rewrite_e_aux true + +(* Rewrite sizeof expressions with type-level variables to + term-level expressions + + For each type-level variable used in a sizeof expressions whose value cannot + be directly extracted from existing parameters of the surrounding function, + a further parameter is added; calls to the function are rewritten + accordingly (possibly causing further rewriting in the calling function) *) +let rewrite_sizeof (Defs defs) = + let sizeof_frees exp = + fst (fold_exp + { (compute_exp_alg KidSet.empty KidSet.union) with + e_sizeof = (fun nexp -> (nexp_frees nexp, E_sizeof nexp)) } + exp) in + + (* Collect nexps whose values can be obtained directly from a pattern bind *) + let nexps_from_params pat = + fst (fold_pat + { (compute_pat_alg [] (@)) with + p_aux = (fun ((v,pat),((l,_) as annot)) -> + let v' = match pat with + | P_id id | P_as (_, id) -> + let (Typ_aux (typ,_) as typ_aux) = typ_of_annot annot in + (match typ with + | Typ_app (atom, [Typ_arg_aux (Typ_arg_nexp nexp, _)]) + when string_of_id atom = "atom" -> + [nexp, E_id id] + | Typ_app (vector, _) when string_of_id vector = "vector" -> + let id_length = Id_aux (Id "length", gen_loc l) in + (try + (match Env.get_val_spec id_length (env_of_annot annot) with + | _ -> + let (_,len,_,_) = vector_typ_args_of typ_aux in + let exp = E_app (id_length, [E_aux (E_id id, annot)]) in + [len, exp]) + with + | _ -> []) + | _ -> []) + | _ -> [] in + (v @ v', P_aux (pat,annot)))} pat) in + + (* Substitute collected values in sizeof expressions *) + let rec e_sizeof nmap (Nexp_aux (nexp, l) as nexp_aux) = + try snd (List.find (fun (nexp,_) -> nexp_identical nexp nexp_aux) nmap) + with + | Not_found -> + let binop nexp1 op nexp2 = E_app_infix ( + E_aux (e_sizeof nmap nexp1, simple_annot l (atom_typ nexp1)), + Id_aux (Id op, Parse_ast.Unknown), + E_aux (e_sizeof nmap nexp2, simple_annot l (atom_typ nexp2)) + ) in + let (Nexp_aux (nexp, l) as nexp_aux) = nexp_simp nexp_aux in + (match nexp with + | Nexp_constant i -> E_lit (L_aux (L_num i, l)) + | Nexp_times (nexp1, nexp2) -> binop nexp1 "*" nexp2 + | Nexp_sum (nexp1, nexp2) -> binop nexp1 "+" nexp2 + | Nexp_minus (nexp1, nexp2) -> binop nexp1 "-" nexp2 + | _ -> E_sizeof nexp_aux) in + + let ex_regex = Str.regexp "'ex[0-9]+" in + + (* Rewrite calls to functions which have had parameters added to pass values + of type-level variables; these are added as sizeof expressions first, and + then further rewritten as above. *) + let e_app_aux param_map ((exp, exp_orig), ((l, _) as annot)) = + let env = env_of_annot annot in + let full_exp = E_aux (exp, annot) in + let orig_exp = E_aux (exp_orig, annot) in + match exp with + | E_app (f, args) -> + if Bindings.mem f param_map then + (* Retrieve instantiation of the type variables of the called function + for the given parameters in the original environment *) + let inst = + try instantiation_of orig_exp with + | Type_error (l, err) -> + raise (Reporting_basic.err_typ l (string_of_type_error err)) in + (* Rewrite the inst using orig_kid so that each type variable has it's + original name rather than a mangled typechecker name *) + let inst = KBindings.fold (fun kid uvar b -> KBindings.add (orig_kid kid) uvar b) inst KBindings.empty in + let kid_exp kid = begin + (* We really don't want to see an existential here! *) + assert (not (Str.string_match ex_regex (string_of_kid kid) 0)); + let uvar = try Some (KBindings.find (orig_kid kid) inst) with Not_found -> None in + match uvar with + | Some (U_nexp nexp) -> + let sizeof = E_aux (E_sizeof nexp, (l, Some (env, atom_typ nexp, no_effect))) in + (try rewrite_trivial_sizeof_exp sizeof with + | Type_error (l, err) -> + raise (Reporting_basic.err_typ l (string_of_type_error err))) + (* If the type variable is Not_found then it was probably + introduced by a P_var pattern, so it likely exists as + a variable in scope. It can't be an existential because the assert rules that out. *) + | None -> annot_exp (E_id (id_of_kid (orig_kid kid))) l env (atom_typ (nvar (orig_kid kid))) + | _ -> + raise (Reporting_basic.err_unreachable l + ("failed to infer nexp for type variable " ^ string_of_kid kid ^ + " of function " ^ string_of_id f)) + end in + let kid_exps = List.map kid_exp (KidSet.elements (Bindings.find f param_map)) in + (E_aux (E_app (f, kid_exps @ args), annot), orig_exp) + else (full_exp, orig_exp) + | _ -> (full_exp, orig_exp) in + + (* Plug this into a folding algorithm that also keeps around a copy of the + original expressions, which we use to infer instantiations of type variables + in the original environments *) + let copy_exp_alg = + { e_block = (fun es -> let (es, es') = List.split es in (E_block es, E_block es')) + ; e_nondet = (fun es -> let (es, es') = List.split es in (E_nondet es, E_nondet es')) + ; e_id = (fun id -> (E_id id, E_id id)) + ; e_lit = (fun lit -> (E_lit lit, E_lit lit)) + ; e_cast = (fun (typ,(e,e')) -> (E_cast (typ,e), E_cast (typ,e'))) + ; e_app = (fun (id,es) -> let (es, es') = List.split es in (E_app (id,es), E_app (id,es'))) + ; e_app_infix = (fun ((e1,e1'),id,(e2,e2')) -> (E_app_infix (e1,id,e2), E_app_infix (e1',id,e2'))) + ; e_tuple = (fun es -> let (es, es') = List.split es in (E_tuple es, E_tuple es')) + ; e_if = (fun ((e1,e1'),(e2,e2'),(e3,e3')) -> (E_if (e1,e2,e3), E_if (e1',e2',e3'))) + ; e_for = (fun (id,(e1,e1'),(e2,e2'),(e3,e3'),order,(e4,e4')) -> (E_for (id,e1,e2,e3,order,e4), E_for (id,e1',e2',e3',order,e4'))) + ; e_loop = (fun (lt, (e1, e1'), (e2, e2')) -> (E_loop (lt, e1, e2), E_loop (lt, e1', e2'))) + ; e_vector = (fun es -> let (es, es') = List.split es in (E_vector es, E_vector es')) + ; e_vector_access = (fun ((e1,e1'),(e2,e2')) -> (E_vector_access (e1,e2), E_vector_access (e1',e2'))) + ; e_vector_subrange = (fun ((e1,e1'),(e2,e2'),(e3,e3')) -> (E_vector_subrange (e1,e2,e3), E_vector_subrange (e1',e2',e3'))) + ; e_vector_update = (fun ((e1,e1'),(e2,e2'),(e3,e3')) -> (E_vector_update (e1,e2,e3), E_vector_update (e1',e2',e3'))) + ; e_vector_update_subrange = (fun ((e1,e1'),(e2,e2'),(e3,e3'),(e4,e4')) -> (E_vector_update_subrange (e1,e2,e3,e4), E_vector_update_subrange (e1',e2',e3',e4'))) + ; e_vector_append = (fun ((e1,e1'),(e2,e2')) -> (E_vector_append (e1,e2), E_vector_append (e1',e2'))) + ; e_list = (fun es -> let (es, es') = List.split es in (E_list es, E_list es')) + ; e_cons = (fun ((e1,e1'),(e2,e2')) -> (E_cons (e1,e2), E_cons (e1',e2'))) + ; e_record = (fun (fexps, fexps') -> (E_record fexps, E_record fexps')) + ; e_record_update = (fun ((e1,e1'),(fexp,fexp')) -> (E_record_update (e1,fexp), E_record_update (e1',fexp'))) + ; e_field = (fun ((e1,e1'),id) -> (E_field (e1,id), E_field (e1',id))) + ; e_case = (fun ((e1,e1'),pexps) -> let (pexps, pexps') = List.split pexps in (E_case (e1,pexps), E_case (e1',pexps'))) + ; e_let = (fun ((lb,lb'),(e2,e2')) -> (E_let (lb,e2), E_let (lb',e2'))) + ; e_assign = (fun ((lexp,lexp'),(e2,e2')) -> (E_assign (lexp,e2), E_assign (lexp',e2'))) + ; e_sizeof = (fun nexp -> (E_sizeof nexp, E_sizeof nexp)) + ; e_constraint = (fun nc -> (E_constraint nc, E_constraint nc)) + ; e_exit = (fun (e1,e1') -> (E_exit (e1), E_exit (e1'))) + ; e_throw = (fun (e1,e1') -> (E_throw (e1), E_throw (e1'))) + ; e_return = (fun (e1,e1') -> (E_return e1, E_return e1')) + ; e_assert = (fun ((e1,e1'),(e2,e2')) -> (E_assert(e1,e2), E_assert(e1',e2')) ) + ; e_internal_cast = (fun (a,(e1,e1')) -> (E_internal_cast (a,e1), E_internal_cast (a,e1'))) + ; e_internal_exp = (fun a -> (E_internal_exp a, E_internal_exp a)) + ; e_internal_exp_user = (fun (a1,a2) -> (E_internal_exp_user (a1,a2), E_internal_exp_user (a1,a2))) + ; e_comment = (fun c -> (E_comment c, E_comment c)) + ; e_comment_struc = (fun (e,e') -> (E_comment_struc e, E_comment_struc e')) + ; e_internal_let = (fun ((lexp,lexp'), (e2,e2'), (e3,e3')) -> (E_internal_let (lexp,e2,e3), E_internal_let (lexp',e2',e3'))) + ; e_internal_plet = (fun (pat, (e1,e1'), (e2,e2')) -> (E_internal_plet (pat,e1,e2), E_internal_plet (pat,e1',e2'))) + ; e_internal_return = (fun (e,e') -> (E_internal_return e, E_internal_return e')) + ; e_aux = (fun ((e,e'),annot) -> (E_aux (e,annot), E_aux (e',annot))) + ; lEXP_id = (fun id -> (LEXP_id id, LEXP_id id)) + ; lEXP_memory = (fun (id,es) -> let (es, es') = List.split es in (LEXP_memory (id,es), LEXP_memory (id,es'))) + ; lEXP_cast = (fun (typ,id) -> (LEXP_cast (typ,id), LEXP_cast (typ,id))) + ; lEXP_tup = (fun tups -> let (tups,tups') = List.split tups in (LEXP_tup tups, LEXP_tup tups')) + ; lEXP_vector = (fun ((lexp,lexp'),(e2,e2')) -> (LEXP_vector (lexp,e2), LEXP_vector (lexp',e2'))) + ; lEXP_vector_range = (fun ((lexp,lexp'),(e2,e2'),(e3,e3')) -> (LEXP_vector_range (lexp,e2,e3), LEXP_vector_range (lexp',e2',e3'))) + ; lEXP_field = (fun ((lexp,lexp'),id) -> (LEXP_field (lexp,id), LEXP_field (lexp',id))) + ; lEXP_aux = (fun ((lexp,lexp'),annot) -> (LEXP_aux (lexp,annot), LEXP_aux (lexp',annot))) + ; fE_Fexp = (fun (id,(e,e')) -> (FE_Fexp (id,e), FE_Fexp (id,e'))) + ; fE_aux = (fun ((fexp,fexp'),annot) -> (FE_aux (fexp,annot), FE_aux (fexp',annot))) + ; fES_Fexps = (fun (fexps,b) -> let (fexps, fexps') = List.split fexps in (FES_Fexps (fexps,b), FES_Fexps (fexps',b))) + ; fES_aux = (fun ((fexp,fexp'),annot) -> (FES_aux (fexp,annot), FES_aux (fexp',annot))) + ; def_val_empty = (Def_val_empty, Def_val_empty) + ; def_val_dec = (fun (e,e') -> (Def_val_dec e, Def_val_dec e')) + ; def_val_aux = (fun ((defval,defval'),aux) -> (Def_val_aux (defval,aux), Def_val_aux (defval',aux))) + ; pat_exp = (fun (pat,(e,e')) -> (Pat_exp (pat,e), Pat_exp (pat,e'))) + ; pat_when = (fun (pat,(e1,e1'),(e2,e2')) -> (Pat_when (pat,e1,e2), Pat_when (pat,e1',e2'))) + ; pat_aux = (fun ((pexp,pexp'),a) -> (Pat_aux (pexp,a), Pat_aux (pexp',a))) + ; lB_val = (fun (pat,(e,e')) -> (LB_val (pat,e), LB_val (pat,e'))) + ; lB_aux = (fun ((lb,lb'),annot) -> (LB_aux (lb,annot), LB_aux (lb',annot))) + ; pat_alg = id_pat_alg + } in + + let rewrite_sizeof_fun params_map + (FD_aux (FD_function (rec_opt,tannot,eff,funcls),((l,_) as annot))) = + let rewrite_funcl_body (FCL_aux (FCL_Funcl (id,pat,exp), annot)) (funcls,nvars) = + let body_env = env_of exp in + let body_typ = typ_of exp in + let nmap = nexps_from_params pat in + (* first rewrite calls to other functions... *) + let exp' = fst (fold_exp { copy_exp_alg with e_aux = e_app_aux params_map } exp) in + (* ... then rewrite sizeof expressions in current function body *) + let exp'' = fold_exp { id_exp_alg with e_sizeof = e_sizeof nmap } exp' in + (FCL_aux (FCL_Funcl (id,pat,exp''), annot) :: funcls, + KidSet.union nvars (sizeof_frees exp'')) in + let (funcls, nvars) = List.fold_right rewrite_funcl_body funcls ([], KidSet.empty) in + (* Add a parameter for each remaining free type-level variable in a + sizeof expression *) + let kid_typ kid = atom_typ (nvar kid) in + let kid_annot kid = simple_annot l (kid_typ kid) in + let kid_pat kid = + P_aux (P_typ (kid_typ kid, + P_aux (P_id (Id_aux (Id (string_of_id (id_of_kid kid) ^ "__tv"), l)), + kid_annot kid)), kid_annot kid) in + let kid_eaux kid = E_id (Id_aux (Id (string_of_id (id_of_kid kid) ^ "__tv"), l)) in + let kid_typs = List.map kid_typ (KidSet.elements nvars) in + let kid_pats = List.map kid_pat (KidSet.elements nvars) in + let kid_nmap = List.map (fun kid -> (nvar kid, kid_eaux kid)) (KidSet.elements nvars) in + let rewrite_funcl_params (FCL_aux (FCL_Funcl (id, pat, exp), annot) as funcl) = + let rec rewrite_pat (P_aux (pat, ((l, _) as pannot)) as paux) = + let penv = env_of_annot pannot in + let peff = effect_of_annot (snd pannot) in + if KidSet.is_empty nvars then paux else + match pat_typ_of paux with + | Typ_aux (Typ_tup typs, _) -> + let ptyp' = Typ_aux (Typ_tup (kid_typs @ typs), l) in + (match pat with + | P_tup pats -> + P_aux (P_tup (kid_pats @ pats), (l, Some (penv, ptyp', peff))) + | P_wild -> P_aux (pat, (l, Some (penv, ptyp', peff))) + | P_typ (Typ_aux (Typ_tup typs, l), pat) -> + P_aux (P_typ (Typ_aux (Typ_tup (kid_typs @ typs), l), + rewrite_pat pat), (l, Some (penv, ptyp', peff))) + | P_as (_, id) | P_id id -> + (* adding parameters here would change the type of id; + we should remove the P_as/P_id here and add a let-binding to the body *) + raise (Reporting_basic.err_todo l + "rewriting as- or id-patterns for sizeof expressions not yet implemented") + | _ -> + raise (Reporting_basic.err_unreachable l + "unexpected pattern while rewriting function parameters for sizeof expressions")) + | ptyp -> + let ptyp' = Typ_aux (Typ_tup (kid_typs @ [ptyp]), l) in + P_aux (P_tup (kid_pats @ [paux]), (l, Some (penv, ptyp', peff))) in + let exp' = fold_exp { id_exp_alg with e_sizeof = e_sizeof kid_nmap } exp in + FCL_aux (FCL_Funcl (id, rewrite_pat pat, exp'), annot) in + let funcls = List.map rewrite_funcl_params funcls in + let fd = FD_aux (FD_function (rec_opt,tannot,eff,funcls),annot) in + let params_map = + if KidSet.is_empty nvars then params_map else + Bindings.add (id_of_fundef fd) nvars params_map in + (params_map, FD_aux (FD_function (rec_opt,tannot,eff,funcls),annot)) in + + let rewrite_sizeof_def (params_map, defs) = function + | DEF_fundef fd -> + let (params_map', fd') = rewrite_sizeof_fun params_map fd in + (params_map', defs @ [DEF_fundef fd']) + | DEF_internal_mutrec fds -> + let rewrite_fd (params_map, fds) fd = + let (params_map', fd') = rewrite_sizeof_fun params_map fd in + (params_map', fds @ [fd']) in + (* TODO Split rewrite_sizeof_fun into an analysis and a rewrite pass, + so that we can call the analysis until a fixpoint is reached and then + rewrite the mutually recursive functions *) + let (params_map', fds') = List.fold_left rewrite_fd (params_map, []) fds in + (params_map', defs @ [DEF_internal_mutrec fds']) + | DEF_val (LB_aux (lb, annot)) -> + begin + let lb' = match lb with + | LB_val (pat, exp) -> + let exp' = fst (fold_exp { copy_exp_alg with e_aux = e_app_aux params_map } exp) in + LB_val (pat, exp') in + (params_map, defs @ [DEF_val (LB_aux (lb', annot))]) + end + | def -> + (params_map, defs @ [def]) in + + let rewrite_sizeof_valspec params_map def = + let rewrite_typschm (TypSchm_aux (TypSchm_ts (tq, typ), l) as ts) id = + if Bindings.mem id params_map then + let kid_typs = List.map (fun kid -> atom_typ (nvar kid)) + (KidSet.elements (Bindings.find id params_map)) in + let typ' = match typ with + | Typ_aux (Typ_fn (vtyp_arg, vtyp_ret, declared_eff), vl) -> + let vtyp_arg' = begin + match vtyp_arg with + | Typ_aux (Typ_tup typs, vl) -> + Typ_aux (Typ_tup (kid_typs @ typs), vl) + | _ -> Typ_aux (Typ_tup (kid_typs @ [vtyp_arg]), vl) + end in + Typ_aux (Typ_fn (vtyp_arg', vtyp_ret, declared_eff), vl) + | _ -> + raise (Reporting_basic.err_typ l "val spec with non-function type") in + TypSchm_aux (TypSchm_ts (tq, typ'), l) + else ts in + match def with + | DEF_spec (VS_aux (VS_val_spec (typschm, id, ext, is_cast), a)) -> + DEF_spec (VS_aux (VS_val_spec (rewrite_typschm typschm id, id, ext, is_cast), a)) + | def -> def + in + + let (params_map, defs) = List.fold_left rewrite_sizeof_def + (Bindings.empty, []) defs in + let defs = List.map (rewrite_sizeof_valspec params_map) defs in + fst (check initial_env (Defs defs)) + +let rewrite_defs_remove_assert defs = + let e_assert ((E_aux (eaux, (l, _)) as exp), str) = match eaux with + | E_constraint _ -> + E_assert (exp, str) + | _ -> + E_assert (E_aux (E_lit (mk_lit L_true), simple_annot l bool_typ), str) in + rewrite_defs_base + { rewriters_base with + rewrite_exp = (fun _ -> fold_exp { id_exp_alg with e_assert = e_assert}) } + defs + +let remove_vector_concat_pat pat = + + (* ivc: bool that indicates whether the exp is in a vector_concat pattern *) + let remove_typed_patterns = + fold_pat { id_pat_alg with + p_aux = (function + | (P_typ (_,P_aux (p,_)),annot) + | (p,annot) -> + P_aux (p,annot) + ) + } in + + (* let pat = remove_typed_patterns pat in *) + + let fresh_id_v = fresh_id "v__" in + + (* expects that P_typ elements have been removed from AST, + that the length of all vectors involved is known, + that we don't have indexed vectors *) + + (* introduce names for all patterns of form P_vector_concat *) + let name_vector_concat_roots = + { p_lit = (fun lit -> P_lit lit) + ; p_typ = (fun (typ,p) -> P_typ (typ,p false)) (* cannot happen *) + ; p_wild = P_wild + ; p_as = (fun (pat,id) -> P_as (pat true,id)) + ; p_id = (fun id -> P_id id) + ; p_var = (fun (pat,kid) -> P_var (pat true,kid)) + ; p_app = (fun (id,ps) -> P_app (id, List.map (fun p -> p false) ps)) + ; p_record = (fun (fpats,b) -> P_record (fpats, b)) + ; p_vector = (fun ps -> P_vector (List.map (fun p -> p false) ps)) + ; p_vector_concat = (fun ps -> P_vector_concat (List.map (fun p -> p false) ps)) + ; p_tup = (fun ps -> P_tup (List.map (fun p -> p false) ps)) + ; p_list = (fun ps -> P_list (List.map (fun p -> p false) ps)) + ; p_cons = (fun (p,ps) -> P_cons (p false, ps false)) + ; p_aux = + (fun (pat,((l,_) as annot)) contained_in_p_as -> + match pat with + | P_vector_concat pats -> + (if contained_in_p_as + then P_aux (pat,annot) + else P_aux (P_as (P_aux (pat,annot),fresh_id_v l),annot)) + | _ -> P_aux (pat,annot) + ) + ; fP_aux = (fun (fpat,annot) -> FP_aux (fpat,annot)) + ; fP_Fpat = (fun (id,p) -> FP_Fpat (id,p false)) + } in + + let pat = (fold_pat name_vector_concat_roots pat) false in + + (* introduce names for all unnamed child nodes of P_vector_concat *) + let name_vector_concat_elements = + let p_vector_concat pats = + let rec aux ((P_aux (p,((l,_) as a))) as pat) = match p with + | P_vector _ -> P_aux (P_as (pat,fresh_id_v l),a) + | P_id id -> P_aux (P_id id,a) + | P_as (p,id) -> P_aux (P_as (p,id),a) + | P_typ (typ, pat) -> P_aux (P_typ (typ, aux pat),a) + | P_wild -> P_aux (P_wild,a) + | _ -> + raise + (Reporting_basic.err_unreachable + l "name_vector_concat_elements: Non-vector in vector-concat pattern") in + P_vector_concat (List.map aux pats) in + {id_pat_alg with p_vector_concat = p_vector_concat} in + + let pat = fold_pat name_vector_concat_elements pat in + + + + let rec tag_last = function + | x :: xs -> let is_last = xs = [] in (x,is_last) :: tag_last xs + | _ -> [] in + + (* remove names from vectors in vector_concat patterns and collect them as declarations for the + function body or expression *) + let unname_vector_concat_elements = (* : + ('a, + 'a pat * ((tannot exp -> tannot exp) list), + 'a pat_aux * ((tannot exp -> tannot exp) list), + 'a fpat * ((tannot exp -> tannot exp) list), + 'a fpat_aux * ((tannot exp -> tannot exp) list)) + pat_alg = *) + + (* build a let-expression of the form "let child = root[i..j] in body" *) + let letbind_vec typ_opt (rootid,rannot) (child,cannot) (i,j) = + let (l,_) = cannot in + let env = env_of_annot rannot in + let rootname = string_of_id rootid in + let childname = string_of_id child in + + let root = E_aux (E_id rootid, rannot) in + let index_i = simple_num l i in + let index_j = simple_num l j in + + (* FIXME *) + let subv = fix_eff_exp (E_aux (E_vector_subrange (root, index_i, index_j), cannot)) in + (* let (_, _, ord, _) = vector_typ_args_of (Env.base_typ_of (env_of root) (typ_of root)) in + let subrange_id = if is_order_inc ord then "bitvector_subrange_inc" else "bitvector_subrange_dec" in + let subv = fix_eff_exp (E_aux (E_app (mk_id subrange_id, [root; index_i; index_j]), cannot)) in *) + + let id_pat = + match typ_opt with + | Some typ -> P_aux (P_typ (typ, P_aux (P_id child,cannot)), cannot) + | None -> P_aux (P_id child,cannot) in + let letbind = fix_eff_lb (LB_aux (LB_val (id_pat,subv),cannot)) in + (letbind, + (fun body -> fix_eff_exp (annot_exp (E_let (letbind,body)) l env (typ_of body))), + (rootname,childname)) in + + let p_aux = function + | ((P_as (P_aux (P_vector_concat pats,rannot'),rootid),decls),rannot) -> + let rtyp = Env.base_typ_of (env_of_annot rannot') (typ_of_annot rannot') in + let (start,last_idx) = (match vector_typ_args_of rtyp with + | (Nexp_aux (Nexp_constant start,_), Nexp_aux (Nexp_constant length,_), ord, _) -> + (start, if is_order_inc ord + then sub_big_int (add_big_int start length) unit_big_int + else add_big_int (sub_big_int start length) unit_big_int) + | _ -> + raise (Reporting_basic.err_unreachable (fst rannot') + ("unname_vector_concat_elements: vector of unspecified length in vector-concat pattern"))) in + let rec aux typ_opt (pos,pat_acc,decl_acc) (P_aux (p,cannot),is_last) = + let ctyp = Env.base_typ_of (env_of_annot cannot) (typ_of_annot cannot) in + let (_,length,ord,_) = vector_typ_args_of ctyp in + let (pos',index_j) = match length with + | Nexp_aux (Nexp_constant i,_) -> + if is_order_inc ord + then (add_big_int pos i, sub_big_int (add_big_int pos i) unit_big_int) + else (sub_big_int pos i, add_big_int (sub_big_int pos i) unit_big_int) + | Nexp_aux (_,l) -> + if is_last then (pos,last_idx) + else + raise + (Reporting_basic.err_unreachable + l ("unname_vector_concat_elements: vector of unspecified length in vector-concat pattern")) in + (match p with + (* if we see a named vector pattern, remove the name and remember to + declare it later *) + | P_as (P_aux (p,cannot),cname) -> + let (lb,decl,info) = letbind_vec typ_opt (rootid,rannot) (cname,cannot) (pos,index_j) in + (pos', pat_acc @ [P_aux (p,cannot)], decl_acc @ [((lb,decl),info)]) + (* if we see a P_id variable, remember to declare it later *) + | P_id cname -> + let (lb,decl,info) = letbind_vec typ_opt (rootid,rannot) (cname,cannot) (pos,index_j) in + (pos', pat_acc @ [P_aux (P_id cname,cannot)], decl_acc @ [((lb,decl),info)]) + | P_typ (typ, pat) -> aux (Some typ) (pos,pat_acc,decl_acc) (pat, is_last) + (* normal vector patterns are fine *) + | _ -> (pos', pat_acc @ [P_aux (p,cannot)],decl_acc)) in + let pats_tagged = tag_last pats in + let (_,pats',decls') = List.fold_left (aux None) (start,[],[]) pats_tagged in + + (* abuse P_vector_concat as a P_vector_const pattern: it has the of + patterns as an argument but they're meant to be consed together *) + (P_aux (P_as (P_aux (P_vector_concat pats',rannot'),rootid),rannot), decls @ decls') + | ((p,decls),annot) -> (P_aux (p,annot),decls) in + + { p_lit = (fun lit -> (P_lit lit,[])) + ; p_wild = (P_wild,[]) + ; p_as = (fun ((pat,decls),id) -> (P_as (pat,id),decls)) + ; p_typ = (fun (typ,(pat,decls)) -> (P_typ (typ,pat),decls)) + ; p_id = (fun id -> (P_id id,[])) + ; p_var = (fun ((pat,decls),kid) -> (P_var (pat,kid),decls)) + ; p_app = (fun (id,ps) -> let (ps,decls) = List.split ps in + (P_app (id,ps),List.flatten decls)) + ; p_record = (fun (ps,b) -> let (ps,decls) = List.split ps in + (P_record (ps,b),List.flatten decls)) + ; p_vector = (fun ps -> let (ps,decls) = List.split ps in + (P_vector ps,List.flatten decls)) + ; p_vector_concat = (fun ps -> let (ps,decls) = List.split ps in + (P_vector_concat ps,List.flatten decls)) + ; p_tup = (fun ps -> let (ps,decls) = List.split ps in + (P_tup ps,List.flatten decls)) + ; p_list = (fun ps -> let (ps,decls) = List.split ps in + (P_list ps,List.flatten decls)) + ; p_cons = (fun ((p,decls),(p',decls')) -> (P_cons (p,p'), decls @ decls')) + ; p_aux = (fun ((pat,decls),annot) -> p_aux ((pat,decls),annot)) + ; fP_aux = (fun ((fpat,decls),annot) -> (FP_aux (fpat,annot),decls)) + ; fP_Fpat = (fun (id,(pat,decls)) -> (FP_Fpat (id,pat),decls)) + } in + + let (pat,decls) = fold_pat unname_vector_concat_elements pat in + + let decls = + let module S = Set.Make(String) in + + let roots_needed = + List.fold_right + (fun (_,(rootid,childid)) roots_needed -> + if S.mem childid roots_needed then + (* let _ = print_endline rootid in *) + S.add rootid roots_needed + else if String.length childid >= 3 && String.sub childid 0 2 = String.sub "v__" 0 2 then + roots_needed + else + S.add rootid roots_needed + ) decls S.empty in + List.filter + (fun (_,(_,childid)) -> + S.mem childid roots_needed || + String.length childid < 3 || + not (String.sub childid 0 2 = String.sub "v__" 0 2)) + decls in + + let (letbinds,decls) = + let (decls,_) = List.split decls in + List.split decls in + + let decls = List.fold_left (fun f g x -> f (g x)) (fun b -> b) decls in + + + (* at this point shouldn't have P_as patterns in P_vector_concat patterns any more, + all P_as and P_id vectors should have their declarations in decls. + Now flatten all vector_concat patterns *) + + let flatten = + let p_vector_concat ps = + let aux p acc = match p with + | (P_aux (P_vector_concat pats,_)) -> pats @ acc + | pat -> pat :: acc in + P_vector_concat (List.fold_right aux ps []) in + {id_pat_alg with p_vector_concat = p_vector_concat} in + + let pat = fold_pat flatten pat in + + (* at this point pat should be a flat pattern: no vector_concat patterns + with vector_concats patterns as direct child-nodes anymore *) + + let range a b = + let rec aux a b = if gt_big_int a b then [] else a :: aux (add_big_int a unit_big_int) b in + if gt_big_int a b then List.rev (aux b a) else aux a b in + + let remove_vector_concats = + let p_vector_concat ps = + let aux acc (P_aux (p,annot),is_last) = + let env = env_of_annot annot in + let typ = Env.base_typ_of env (typ_of_annot annot) in + let eff = effect_of_annot (snd annot) in + let (l,_) = annot in + let wild _ = P_aux (P_wild,(gen_loc l, Some (env, bit_typ, eff))) in + if is_vector_typ typ then + match p, vector_typ_args_of typ with + | P_vector ps,_ -> acc @ ps + | _, (_,Nexp_aux (Nexp_constant length,_),_,_) -> + acc @ (List.map wild (range zero_big_int (sub_big_int length unit_big_int))) + | _, _ -> + (*if is_last then*) acc @ [wild zero_big_int] + else raise + (Reporting_basic.err_unreachable l + ("remove_vector_concats: Non-vector in vector-concat pattern " ^ + string_of_typ (typ_of_annot annot))) in + + let has_length (P_aux (p,annot)) = + let typ = Env.base_typ_of (env_of_annot annot) (typ_of_annot annot) in + match vector_typ_args_of typ with + | (_,Nexp_aux (Nexp_constant length,_),_,_) -> true + | _ -> false in + + let ps_tagged = tag_last ps in + let ps' = List.fold_left aux [] ps_tagged in + let last_has_length ps = List.exists (fun (p,b) -> b && has_length p) ps_tagged in + + if last_has_length ps then + P_vector ps' + else + (* If the last vector pattern in the vector_concat pattern has unknown + length we misuse the P_vector_concat constructor's argument to place in + the following way: P_vector_concat [x;y; ... ;z] should be mapped to the + pattern-match x :: y :: .. z, i.e. if x : 'a, then z : vector 'a. *) + P_vector_concat ps' in + + {id_pat_alg with p_vector_concat = p_vector_concat} in + + let pat = fold_pat remove_vector_concats pat in + + (pat,letbinds,decls) + +(* assumes there are no more E_internal expressions *) +let rewrite_exp_remove_vector_concat_pat rewriters (E_aux (exp,(l,annot)) as full_exp) = + let rewrap e = E_aux (e,(l,annot)) in + let rewrite_rec = rewriters.rewrite_exp rewriters in + let rewrite_base = rewrite_exp rewriters in + match exp with + | E_case (e,ps) -> + let aux = function + | (Pat_aux (Pat_exp (pat,body),annot')) -> + let (pat,_,decls) = remove_vector_concat_pat pat in + Pat_aux (Pat_exp (pat, decls (rewrite_rec body)),annot') + | (Pat_aux (Pat_when (pat,guard,body),annot')) -> + let (pat,_,decls) = remove_vector_concat_pat pat in + Pat_aux (Pat_when (pat, decls (rewrite_rec guard), decls (rewrite_rec body)),annot') in + rewrap (E_case (rewrite_rec e, List.map aux ps)) + | E_let (LB_aux (LB_val (pat,v),annot'),body) -> + let (pat,_,decls) = remove_vector_concat_pat pat in + rewrap (E_let (LB_aux (LB_val (pat,rewrite_rec v),annot'), + decls (rewrite_rec body))) + | exp -> rewrite_base full_exp + +let rewrite_fun_remove_vector_concat_pat + rewriters (FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),(l,fdannot))) = + let rewrite_funcl (FCL_aux (FCL_Funcl(id,pat,exp),(l,annot))) = + let (pat',_,decls) = remove_vector_concat_pat pat in + let exp' = decls (rewriters.rewrite_exp rewriters exp) in + (FCL_aux (FCL_Funcl (id,pat',exp'),(l,annot))) + in FD_aux (FD_function(recopt,tannotopt,effectopt,List.map rewrite_funcl funcls),(l,fdannot)) + +let rewrite_defs_remove_vector_concat (Defs defs) = + let rewriters = + {rewrite_exp = rewrite_exp_remove_vector_concat_pat; + rewrite_pat = rewrite_pat; + rewrite_let = rewrite_let; + rewrite_lexp = rewrite_lexp; + rewrite_fun = rewrite_fun_remove_vector_concat_pat; + rewrite_def = rewrite_def; + rewrite_defs = rewrite_defs_base} in + let rewrite_def d = + let d = rewriters.rewrite_def rewriters d in + match d with + | DEF_val (LB_aux (LB_val (pat,exp),a)) -> + let (pat,letbinds,_) = remove_vector_concat_pat pat in + let defvals = List.map (fun lb -> DEF_val lb) letbinds in + [DEF_val (LB_aux (LB_val (pat,exp),a))] @ defvals + | d -> [d] in + Defs (List.flatten (List.map rewrite_def defs)) + +(* A few helper functions for rewriting guarded pattern clauses. + Used both by the rewriting of P_when and separately by the rewriting of + bitvectors in parameter patterns of function clauses *) + +let remove_wildcards pre (P_aux (_,(l,_)) as pat) = + fold_pat + {id_pat_alg with + p_aux = function + | (P_wild,(l,annot)) -> P_aux (P_id (fresh_id pre l),(l,annot)) + | (p,annot) -> P_aux (p,annot) } + pat + +(* Check if one pattern subsumes the other, and if so, calculate a + substitution of variables that are used in the same position. + TODO: Check somewhere that there are no variable clashes (the same variable + name used in different positions of the patterns) + *) +let rec subsumes_pat (P_aux (p1,annot1) as pat1) (P_aux (p2,annot2) as pat2) = + let rewrap p = P_aux (p,annot1) in + let subsumes_list s pats1 pats2 = + if List.length pats1 = List.length pats2 + then + let subs = List.map2 s pats1 pats2 in + List.fold_right + (fun p acc -> match p, acc with + | Some subst, Some substs -> Some (subst @ substs) + | _ -> None) + subs (Some []) + else None in + match p1, p2 with + | P_lit (L_aux (lit1,_)), P_lit (L_aux (lit2,_)) -> + if lit1 = lit2 then Some [] else None + | P_as (pat1,_), _ -> subsumes_pat pat1 pat2 + | _, P_as (pat2,_) -> subsumes_pat pat1 pat2 + | P_typ (_,pat1), _ -> subsumes_pat pat1 pat2 + | _, P_typ (_,pat2) -> subsumes_pat pat1 pat2 + | P_id (Id_aux (id1,_) as aid1), P_id (Id_aux (id2,_) as aid2) -> + if id1 = id2 then Some [] + else if Env.lookup_id aid1 (env_of_annot annot1) = Unbound && + Env.lookup_id aid2 (env_of_annot annot2) = Unbound + then Some [(id2,id1)] else None + | P_id id1, _ -> + if Env.lookup_id id1 (env_of_annot annot1) = Unbound then Some [] else None + | P_wild, _ -> Some [] + | P_app (Id_aux (id1,l1),args1), P_app (Id_aux (id2,_),args2) -> + if id1 = id2 then subsumes_list subsumes_pat args1 args2 else None + | P_record (fps1,b1), P_record (fps2,b2) -> + if b1 = b2 then subsumes_list subsumes_fpat fps1 fps2 else None + | P_vector pats1, P_vector pats2 + | P_vector_concat pats1, P_vector_concat pats2 + | P_tup pats1, P_tup pats2 + | P_list pats1, P_list pats2 -> + subsumes_list subsumes_pat pats1 pats2 + | P_list (pat1 :: pats1), P_cons _ -> + subsumes_pat (rewrap (P_cons (pat1, rewrap (P_list pats1)))) pat2 + | P_cons _, P_list (pat2 :: pats2)-> + subsumes_pat pat1 (rewrap (P_cons (pat2, rewrap (P_list pats2)))) + | P_cons (pat1, pats1), P_cons (pat2, pats2) -> + (match subsumes_pat pat1 pat2, subsumes_pat pats1 pats2 with + | Some substs1, Some substs2 -> Some (substs1 @ substs2) + | _ -> None) + | _ -> None +and subsumes_fpat (FP_aux (FP_Fpat (id1,pat1),_)) (FP_aux (FP_Fpat (id2,pat2),_)) = + if id1 = id2 then subsumes_pat pat1 pat2 else None + +let equiv_pats pat1 pat2 = + match subsumes_pat pat1 pat2, subsumes_pat pat2 pat1 with + | Some _, Some _ -> true + | _, _ -> false + +let subst_id_pat pat (id1,id2) = + let p_id (Id_aux (id,l)) = (if id = id1 then P_id (Id_aux (id2,l)) else P_id (Id_aux (id,l))) in + fold_pat {id_pat_alg with p_id = p_id} pat + +let subst_id_exp exp (id1,id2) = + (* TODO Don't substitute bound occurrences inside let expressions etc *) + let e_id (Id_aux (id,l)) = (if id = id1 then E_id (Id_aux (id2,l)) else E_id (Id_aux (id,l))) in + fold_exp {id_exp_alg with e_id = e_id} exp + +let rec pat_to_exp (P_aux (pat,(l,annot))) = + let rewrap e = E_aux (e,(l,annot)) in + match pat with + | P_lit lit -> rewrap (E_lit lit) + | P_wild -> raise (Reporting_basic.err_unreachable l + "pat_to_exp given wildcard pattern") + | P_as (pat,id) -> rewrap (E_id id) + | P_typ (_,pat) -> pat_to_exp pat + | P_id id -> rewrap (E_id id) + | P_app (id,pats) -> rewrap (E_app (id, List.map pat_to_exp pats)) + | P_record (fpats,b) -> + rewrap (E_record (FES_aux (FES_Fexps (List.map fpat_to_fexp fpats,b),(l,annot)))) + | P_vector pats -> rewrap (E_vector (List.map pat_to_exp pats)) + | P_vector_concat pats -> raise (Reporting_basic.err_unreachable l + "pat_to_exp not implemented for P_vector_concat") + (* We assume that vector concatenation patterns have been transformed + away already *) + | P_tup pats -> rewrap (E_tuple (List.map pat_to_exp pats)) + | P_list pats -> rewrap (E_list (List.map pat_to_exp pats)) + | P_cons (p,ps) -> rewrap (E_cons (pat_to_exp p, pat_to_exp ps)) +and fpat_to_fexp (FP_aux (FP_Fpat (id,pat),(l,annot))) = + FE_aux (FE_Fexp (id, pat_to_exp pat),(l,annot)) + +let case_exp e t cs = + let l = get_loc_exp e in + let env = env_of e in + let annot = (get_loc_exp e, Some (env_of e, t, no_effect)) in + match cs with + | [(P_aux (P_id id, pannot) as pat, body, _)] -> + fix_eff_exp (annot_exp (E_let (LB_aux (LB_val (pat, e), pannot), body)) l env t) + | _ -> + let pexp (pat,body,annot) = Pat_aux (Pat_exp (pat,body),annot) in + let ps = List.map pexp cs in + (* let efr = union_effs (List.map effect_of_pexp ps) in *) + fix_eff_exp (annot_exp (E_case (e,ps)) l env t) + +let rewrite_guarded_clauses l cs = + let rec group clauses = + let add_clause (pat,cls,annot) c = (pat,cls @ [c],annot) in + let rec group_aux current acc = (function + | ((pat,guard,body,annot) as c) :: cs -> + let (current_pat,_,_) = current in + (match subsumes_pat current_pat pat with + | Some substs -> + let pat' = List.fold_left subst_id_pat pat substs in + let guard' = (match guard with + | Some exp -> Some (List.fold_left subst_id_exp exp substs) + | None -> None) in + let body' = List.fold_left subst_id_exp body substs in + let c' = (pat',guard',body',annot) in + group_aux (add_clause current c') acc cs + | None -> + let pat = remove_wildcards "g__" pat in + group_aux (pat,[c],annot) (acc @ [current]) cs) + | [] -> acc @ [current]) in + let groups = match clauses with + | ((pat,guard,body,annot) as c) :: cs -> + group_aux (remove_wildcards "g__" pat, [c], annot) [] cs + | _ -> + raise (Reporting_basic.err_unreachable l + "group given empty list in rewrite_guarded_clauses") in + List.map (fun cs -> if_pexp cs) groups + and if_pexp (pat,cs,annot) = (match cs with + | c :: _ -> + (* fix_eff_pexp (pexp *) + let body = if_exp pat cs in + let pexp = fix_eff_pexp (Pat_aux (Pat_exp (pat,body),annot)) in + let (Pat_aux (_,annot)) = pexp in + (pat, body, annot) + | [] -> + raise (Reporting_basic.err_unreachable l + "if_pexp given empty list in rewrite_guarded_clauses")) + and if_exp current_pat = (function + | (pat,guard,body,annot) :: ((pat',guard',body',annot') as c') :: cs -> + (match guard with + | Some exp -> + let else_exp = + if equiv_pats current_pat pat' + then if_exp current_pat (c' :: cs) + else case_exp (pat_to_exp current_pat) (typ_of body') (group (c' :: cs)) in + fix_eff_exp (annot_exp (E_if (exp,body,else_exp)) (fst annot) (env_of exp) (typ_of body)) + | None -> body) + | [(pat,guard,body,annot)] -> body + | [] -> + raise (Reporting_basic.err_unreachable l + "if_exp given empty list in rewrite_guarded_clauses")) in + group cs + +let bitwise_and_exp exp1 exp2 = + let (E_aux (_,(l,_))) = exp1 in + let andid = Id_aux (Id "and_bool", gen_loc l) in + annot_exp (E_app(andid,[exp1;exp2])) l (env_of exp1) bool_typ + +let rec contains_bitvector_pat (P_aux (pat,annot)) = match pat with +| P_lit _ | P_wild | P_id _ -> false +| P_as (pat,_) | P_typ (_,pat) -> contains_bitvector_pat pat +| P_vector _ | P_vector_concat _ -> + let typ = Env.base_typ_of (env_of_annot annot) (typ_of_annot annot) in + is_bitvector_typ typ +| P_app (_,pats) | P_tup pats | P_list pats -> + List.exists contains_bitvector_pat pats +| P_cons (p,ps) -> contains_bitvector_pat p || contains_bitvector_pat ps +| P_record (fpats,_) -> + List.exists (fun (FP_aux (FP_Fpat (_,pat),_)) -> contains_bitvector_pat pat) fpats + +let contains_bitvector_pexp = function +| Pat_aux (Pat_exp (pat,_),_) | Pat_aux (Pat_when (pat,_,_),_) -> + contains_bitvector_pat pat + +(* Rewrite bitvector patterns to guarded patterns *) + +let remove_bitvector_pat (P_aux (_, (l, _)) as pat) = + + let env = try pat_env_of pat with _ -> Env.empty in + + (* first introduce names for bitvector patterns *) + let name_bitvector_roots = + { p_lit = (fun lit -> P_lit lit) + ; p_typ = (fun (typ,p) -> P_typ (typ,p false)) + ; p_wild = P_wild + ; p_as = (fun (pat,id) -> P_as (pat true,id)) + ; p_id = (fun id -> P_id id) + ; p_var = (fun (pat,kid) -> P_var (pat true,kid)) + ; p_app = (fun (id,ps) -> P_app (id, List.map (fun p -> p false) ps)) + ; p_record = (fun (fpats,b) -> P_record (fpats, b)) + ; p_vector = (fun ps -> P_vector (List.map (fun p -> p false) ps)) + ; p_vector_concat = (fun ps -> P_vector_concat (List.map (fun p -> p false) ps)) + ; p_tup = (fun ps -> P_tup (List.map (fun p -> p false) ps)) + ; p_list = (fun ps -> P_list (List.map (fun p -> p false) ps)) + ; p_cons = (fun (p,ps) -> P_cons (p false, ps false)) + ; p_aux = + (fun (pat,annot) contained_in_p_as -> + let env = env_of_annot annot in + let t = Env.base_typ_of env (typ_of_annot annot) in + let (l,_) = annot in + match pat, is_bitvector_typ t, contained_in_p_as with + | P_vector _, true, false -> + P_aux (P_as (P_aux (pat,annot),fresh_id "b__" l), annot) + | _ -> P_aux (pat,annot) + ) + ; fP_aux = (fun (fpat,annot) -> FP_aux (fpat,annot)) + ; fP_Fpat = (fun (id,p) -> FP_Fpat (id,p false)) + } in + let pat, env = bind_pat env + (strip_pat ((fold_pat name_bitvector_roots pat) false)) + (pat_typ_of pat) in + + (* Then collect guard expressions testing whether the literal bits of a + bitvector pattern match those of a given bitvector, and collect let + bindings for the bits bound by P_id or P_as patterns *) + + (* Helper functions for generating guard expressions *) + let mk_exp e_aux = E_aux (e_aux, (l, ())) in + let mk_num_exp i = mk_lit_exp (L_num i) in + let check_eq_exp l r = + let exp = mk_exp (E_app_infix (l, Id_aux (DeIid "==", Parse_ast.Unknown), r)) in + check_exp env exp bool_typ in + + let access_bit_exp rootid l typ idx = + let access_aux = E_vector_access (mk_exp (E_id rootid), mk_num_exp idx) in + check_exp env (mk_exp access_aux) bit_typ in + + let test_bit_exp rootid l typ idx exp = + let elem = access_bit_exp rootid l typ idx in + Some (check_eq_exp (strip_exp elem) (strip_exp exp)) in + + let test_subvec_exp rootid l typ i j lits = + let (start, length, ord, _) = vector_typ_args_of typ in + let subvec_exp = + match start, length with + | Nexp_aux (Nexp_constant s, _), Nexp_aux (Nexp_constant l, _) + when eq_big_int s i && eq_big_int l (big_int_of_int (List.length lits)) -> + mk_exp (E_id rootid) + | _ -> + mk_exp (E_vector_subrange (mk_exp (E_id rootid), mk_num_exp i, mk_num_exp j)) in + check_eq_exp subvec_exp (mk_exp (E_vector (List.map strip_exp lits))) in + + let letbind_bit_exp rootid l typ idx id = + let rannot = simple_annot l typ in + let elem = access_bit_exp rootid l typ idx in + let e = annot_pat (P_id id) l env bit_typ in + let letbind = LB_aux (LB_val (e,elem), (l, Some (env, bit_typ, no_effect))) in + let letexp = (fun body -> + let (E_aux (_,(_,bannot))) = body in + annot_exp (E_let (letbind,body)) l env (typ_of body)) in + (letexp, letbind) in + + let compose_guards guards = + let conj g1 g2 = match g1, g2 with + | Some g1, Some g2 -> Some (bitwise_and_exp g1 g2) + | Some g1, None -> Some g1 + | None, Some g2 -> Some g2 + | None, None -> None in + List.fold_right conj guards None in + + let flatten_guards_decls gd = + let (guards,decls,letbinds) = Util.split3 gd in + (compose_guards guards, (List.fold_right (@@) decls), List.flatten letbinds) in + + (* Collect guards and let bindings *) + let guard_bitvector_pat = + let collect_guards_decls ps rootid t = + let (start,_,ord,_) = vector_typ_args_of t in + let rec collect current (guards,dls) idx ps = + let idx' = if is_order_inc ord then add_big_int idx unit_big_int else sub_big_int idx unit_big_int in + (match ps with + | pat :: ps' -> + (match pat with + | P_aux (P_lit lit, (l,annot)) -> + let e = E_aux (E_lit lit, (gen_loc l, annot)) in + let current' = (match current with + | Some (l,i,j,lits) -> Some (l,i,idx,lits @ [e]) + | None -> Some (l,idx,idx,[e])) in + collect current' (guards, dls) idx' ps' + | P_aux (P_as (pat',id), (l,annot)) -> + let dl = letbind_bit_exp rootid l t idx id in + collect current (guards, dls @ [dl]) idx (pat' :: ps') + | _ -> + let dls' = (match pat with + | P_aux (P_id id, (l,annot)) -> + dls @ [letbind_bit_exp rootid l t idx id] + | _ -> dls) in + let guards' = (match current with + | Some (l,i,j,lits) -> + guards @ [Some (test_subvec_exp rootid l t i j lits)] + | None -> guards) in + collect None (guards', dls') idx' ps') + | [] -> + let guards' = (match current with + | Some (l,i,j,lits) -> + guards @ [Some (test_subvec_exp rootid l t i j lits)] + | None -> guards) in + (guards',dls)) in + let (guards,dls) = match start with + | Nexp_aux (Nexp_constant s, _) -> + collect None ([],[]) s ps + | _ -> + let (P_aux (_, (l,_))) = pat in + raise (Reporting_basic.err_unreachable l + "guard_bitvector_pat called on pattern with non-constant start index") in + let (decls,letbinds) = List.split dls in + (compose_guards guards, List.fold_right (@@) decls, letbinds) in + + let collect_guards_decls_indexed ips rootid t = + let rec guard_decl (idx,pat) = (match pat with + | P_aux (P_lit lit, (l,annot)) -> + let exp = E_aux (E_lit lit, (l,annot)) in + (test_bit_exp rootid l t idx exp, (fun b -> b), []) + | P_aux (P_as (pat',id), (l,annot)) -> + let (guard,decls,letbinds) = guard_decl (idx,pat') in + let (letexp,letbind) = letbind_bit_exp rootid l t idx id in + (guard, decls >> letexp, letbind :: letbinds) + | P_aux (P_id id, (l,annot)) -> + let (letexp,letbind) = letbind_bit_exp rootid l t idx id in + (None, letexp, [letbind]) + | _ -> (None, (fun b -> b), [])) in + let (guards,decls,letbinds) = Util.split3 (List.map guard_decl ips) in + (compose_guards guards, List.fold_right (@@) decls, List.flatten letbinds) in + + { p_lit = (fun lit -> (P_lit lit, (None, (fun b -> b), []))) + ; p_wild = (P_wild, (None, (fun b -> b), [])) + ; p_as = (fun ((pat,gdls),id) -> (P_as (pat,id), gdls)) + ; p_typ = (fun (typ,(pat,gdls)) -> (P_typ (typ,pat), gdls)) + ; p_id = (fun id -> (P_id id, (None, (fun b -> b), []))) + ; p_var = (fun ((pat,gdls),kid) -> (P_var (pat,kid), gdls)) + ; p_app = (fun (id,ps) -> let (ps,gdls) = List.split ps in + (P_app (id,ps), flatten_guards_decls gdls)) + ; p_record = (fun (ps,b) -> let (ps,gdls) = List.split ps in + (P_record (ps,b), flatten_guards_decls gdls)) + ; p_vector = (fun ps -> let (ps,gdls) = List.split ps in + (P_vector ps, flatten_guards_decls gdls)) + ; p_vector_concat = (fun ps -> let (ps,gdls) = List.split ps in + (P_vector_concat ps, flatten_guards_decls gdls)) + ; p_tup = (fun ps -> let (ps,gdls) = List.split ps in + (P_tup ps, flatten_guards_decls gdls)) + ; p_list = (fun ps -> let (ps,gdls) = List.split ps in + (P_list ps, flatten_guards_decls gdls)) + ; p_cons = (fun ((p,gdls),(p',gdls')) -> + (P_cons (p,p'), flatten_guards_decls [gdls;gdls'])) + ; p_aux = (fun ((pat,gdls),annot) -> + let env = env_of_annot annot in + let t = Env.base_typ_of env (typ_of_annot annot) in + (match pat, is_bitvector_typ t with + | P_as (P_aux (P_vector ps, _), id), true -> + (P_aux (P_id id, annot), collect_guards_decls ps id t) + | _, _ -> (P_aux (pat,annot), gdls))) + ; fP_aux = (fun ((fpat,gdls),annot) -> (FP_aux (fpat,annot), gdls)) + ; fP_Fpat = (fun (id,(pat,gdls)) -> (FP_Fpat (id,pat), gdls)) + } in + fold_pat guard_bitvector_pat pat + +let rewrite_exp_remove_bitvector_pat rewriters (E_aux (exp,(l,annot)) as full_exp) = + let rewrap e = E_aux (e,(l,annot)) in + let rewrite_rec = rewriters.rewrite_exp rewriters in + let rewrite_base = rewrite_exp rewriters in + match exp with + | E_case (e,ps) + when List.exists contains_bitvector_pexp ps -> + let rewrite_pexp = function + | Pat_aux (Pat_exp (pat,body),annot') -> + let (pat',(guard',decls,_)) = remove_bitvector_pat pat in + let body' = decls (rewrite_rec body) in + (match guard' with + | Some guard' -> Pat_aux (Pat_when (pat', guard', body'), annot') + | None -> Pat_aux (Pat_exp (pat', body'), annot')) + | Pat_aux (Pat_when (pat,guard,body),annot') -> + let (pat',(guard',decls,_)) = remove_bitvector_pat pat in + let body' = decls (rewrite_rec body) in + (match guard' with + | Some guard' -> Pat_aux (Pat_when (pat', bitwise_and_exp guard guard', body'), annot') + | None -> Pat_aux (Pat_when (pat', guard, body'), annot')) in + rewrap (E_case (e, List.map rewrite_pexp ps)) + | E_let (LB_aux (LB_val (pat,v),annot'),body) -> + let (pat,(_,decls,_)) = remove_bitvector_pat pat in + rewrap (E_let (LB_aux (LB_val (pat,rewrite_rec v),annot'), + decls (rewrite_rec body))) + | _ -> rewrite_base full_exp + +let rewrite_fun_remove_bitvector_pat + rewriters (FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),(l,fdannot))) = + let _ = reset_fresh_name_counter () in + let funcls = match funcls with + | (FCL_aux (FCL_Funcl(id,_,_),_) :: _) -> + let clause (FCL_aux (FCL_Funcl(_,pat,exp),annot)) = + let (pat,(guard,decls,_)) = remove_bitvector_pat pat in + let exp = decls (rewriters.rewrite_exp rewriters exp) in + (pat,guard,exp,annot) in + let cs = rewrite_guarded_clauses l (List.map clause funcls) in + List.map (fun (pat,exp,annot) -> FCL_aux (FCL_Funcl(id,pat,exp),annot)) cs + | _ -> funcls in + FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),(l,fdannot)) + +let rewrite_defs_remove_bitvector_pats (Defs defs) = + let rewriters = + {rewrite_exp = rewrite_exp_remove_bitvector_pat; + rewrite_pat = rewrite_pat; + rewrite_let = rewrite_let; + rewrite_lexp = rewrite_lexp; + rewrite_fun = rewrite_fun_remove_bitvector_pat; + rewrite_def = rewrite_def; + rewrite_defs = rewrite_defs_base } in + let rewrite_def d = + let d = rewriters.rewrite_def rewriters d in + match d with + | DEF_val (LB_aux (LB_val (pat,exp),a)) -> + let (pat',(_,_,letbinds)) = remove_bitvector_pat pat in + let defvals = List.map (fun lb -> DEF_val lb) letbinds in + [DEF_val (LB_aux (LB_val (pat',exp),a))] @ defvals + | d -> [d] in + (* FIXME See above in rewrite_sizeof *) + (* fst (check initial_env ( *) + Defs (List.flatten (List.map rewrite_def defs)) + (* )) *) + + +(* Remove pattern guards by rewriting them to if-expressions within the + pattern expression. Shares code with the rewriting of bitvector patterns. *) +let rewrite_exp_guarded_pats rewriters (E_aux (exp,(l,annot)) as full_exp) = + let rewrap e = E_aux (e,(l,annot)) in + let rewrite_rec = rewriters.rewrite_exp rewriters in + let rewrite_base = rewrite_exp rewriters in + let is_guarded_pexp = function + | Pat_aux (Pat_when (_,_,_),_) -> true + | _ -> false in + match exp with + | E_case (e,ps) + when List.exists is_guarded_pexp ps -> + let clause = function + | Pat_aux (Pat_exp (pat, body), annot) -> + (pat, None, rewrite_rec body, annot) + | Pat_aux (Pat_when (pat, guard, body), annot) -> + (pat, Some guard, rewrite_rec body, annot) in + let clauses = rewrite_guarded_clauses l (List.map clause ps) in + if (effectful e) then + let e = rewrite_rec e in + let (E_aux (_,(el,eannot))) = e in + let pat_e' = fresh_id_pat "p__" (el, Some (env_of e, typ_of e, no_effect)) in + let exp_e' = pat_to_exp pat_e' in + let letbind_e = LB_aux (LB_val (pat_e',e), (el,eannot)) in + let exp' = case_exp exp_e' (typ_of full_exp) clauses in + rewrap (E_let (letbind_e, exp')) + else case_exp e (typ_of full_exp) clauses + | _ -> rewrite_base full_exp + +let rewrite_defs_guarded_pats = + rewrite_defs_base { rewriters_base with rewrite_exp = rewrite_exp_guarded_pats } + + +let id_is_local_var id env = match Env.lookup_id id env with + | Local _ -> true + | _ -> false + +let id_is_unbound id env = match Env.lookup_id id env with + | Unbound -> true + | _ -> false + +let rec lexp_is_local (LEXP_aux (lexp, _)) env = match lexp with + | LEXP_memory _ -> false + | LEXP_id id + | LEXP_cast (_, id) -> id_is_local_var id env + | LEXP_tup lexps -> List.for_all (fun lexp -> lexp_is_local lexp env) lexps + | LEXP_vector (lexp,_) + | LEXP_vector_range (lexp,_,_) + | LEXP_field (lexp,_) -> lexp_is_local lexp env + +let rec lexp_is_local_intro (LEXP_aux (lexp, _)) env = match lexp with + | LEXP_memory _ -> false + | LEXP_id id + | LEXP_cast (_, id) -> id_is_unbound id env + | LEXP_tup lexps -> List.for_all (fun lexp -> lexp_is_local_intro lexp env) lexps + | LEXP_vector (lexp,_) + | LEXP_vector_range (lexp,_,_) + | LEXP_field (lexp,_) -> lexp_is_local_intro lexp env + +let lexp_is_effectful (LEXP_aux (_, (_, annot))) = match annot with + | Some (_, _, eff) -> effectful_effs eff + | _ -> false + +let rec rewrite_lexp_to_rhs (do_rewrite : tannot lexp -> bool) ((LEXP_aux(lexp,((l,_) as annot))) as le) = + if do_rewrite le then + match lexp with + | LEXP_id _ | LEXP_cast (_, _) | LEXP_tup _ -> (le, (fun exp -> exp)) + | LEXP_vector (lexp, e) -> + let (lhs, rhs) = rewrite_lexp_to_rhs do_rewrite lexp in + (lhs, (fun exp -> rhs (E_aux (E_vector_update (lexp_to_exp lexp, e, exp), annot)))) + | LEXP_vector_range (lexp, e1, e2) -> + let (lhs, rhs) = rewrite_lexp_to_rhs do_rewrite lexp in + (lhs, (fun exp -> rhs (E_aux (E_vector_update_subrange (lexp_to_exp lexp, e1, e2, exp), annot)))) + | LEXP_field (lexp, id) -> + begin + let (lhs, rhs) = rewrite_lexp_to_rhs do_rewrite lexp in + let (LEXP_aux (_, lannot)) = lexp in + let env = env_of_annot lannot in + match Env.expand_synonyms env (typ_of_annot lannot) with + | Typ_aux (Typ_app (Id_aux (Id "register", _), [Typ_arg_aux (Typ_arg_typ (Typ_aux (Typ_id regtyp_id, _)), _)]), _) + | Typ_aux (Typ_id regtyp_id, _) when Env.is_regtyp regtyp_id env -> + let base, top, ranges = Env.get_regtyp regtyp_id env in + let range, _ = + try List.find (fun (_, fid) -> Id.compare fid id = 0) ranges with + | Not_found -> + raise (Reporting_basic.err_typ l ("Field " ^ string_of_id id ^ " doesn't exist for register type " ^ string_of_id regtyp_id)) + in + let lexp_exp = E_aux (E_app (mk_id ("cast_" ^ string_of_id regtyp_id), [lexp_to_exp lexp]), (l, None)) in + let n, m = match range with + | BF_aux (BF_single n, _) -> n, n + | BF_aux (BF_range (n, m), _) -> n, m + | _ -> raise (Reporting_basic.err_unreachable l ("Unsupported lexp: " ^ string_of_lexp le)) in + let rhs' exp = rhs (E_aux (E_vector_update_subrange (lexp_exp, simple_num l n, simple_num l m, exp), lannot)) in + (lhs, rhs') + | Typ_aux (Typ_id rectyp_id, _) | Typ_aux (Typ_app (rectyp_id, _), _) when Env.is_record rectyp_id env -> + let field_update exp = FES_aux (FES_Fexps ([FE_aux (FE_Fexp (id, exp), annot)], false), annot) in + (lhs, (fun exp -> rhs (E_aux (E_record_update (lexp_to_exp lexp, field_update exp), lannot)))) + | _ -> raise (Reporting_basic.err_unreachable l ("Unsupported lexp: " ^ string_of_lexp le)) + end + | _ -> raise (Reporting_basic.err_unreachable l ("Unsupported lexp: " ^ string_of_lexp le)) + else (le, (fun exp -> exp)) + +let updates_vars exp = + let e_assign ((_, lexp), (u, exp)) = + (u || lexp_is_local lexp (env_of exp), E_assign (lexp, exp)) in + fst (fold_exp { (compute_exp_alg false (||)) with e_assign = e_assign } exp) + +(*Expects to be called after rewrite_defs; thus the following should not appear: + internal_exp of any form + lit vectors in patterns or expressions + *) +let rewrite_exp_lift_assign_intro rewriters ((E_aux (exp,((l,_) as annot))) as full_exp) = + let rewrap e = E_aux (e,annot) in + let rewrap_effects e eff = + E_aux (e, (l,Some (env_of_annot annot, typ_of_annot annot, eff))) in + let rewrite_rec = rewriters.rewrite_exp rewriters in + let rewrite_base = rewrite_exp rewriters in + match exp with + | E_block exps -> + let rec walker exps = match exps with + | [] -> [] + | (E_aux(E_assign(le,e), ((l, Some (env,typ,eff)) as annot)) as exp)::exps + when lexp_is_local_intro le env && not (lexp_is_effectful le) -> + let (le', re') = rewrite_lexp_to_rhs (fun _ -> true) le in + let e' = re' (rewrite_base e) in + let exps' = walker exps in + let effects = union_eff_exps exps' in + let block = E_aux (E_block exps', (l, Some (env, unit_typ, effects))) in + [fix_eff_exp (E_aux (E_internal_let(le', e', block), annot))] + (*| ((E_aux(E_if(c,t,e),(l,annot))) as exp)::exps -> + let vars_t = introduced_variables t in + let vars_e = introduced_variables e in + let new_vars = Envmap.intersect vars_t vars_e in + if Envmap.is_empty new_vars + then (rewrite_base exp)::walker exps + else + let new_nmap = match nmap with + | None -> Some(Nexpmap.empty,new_vars) + | Some(nm,s) -> Some(nm, Envmap.union new_vars s) in + let c' = rewrite_base c in + let t' = rewriters.rewrite_exp rewriters new_nmap t in + let e' = rewriters.rewrite_exp rewriters new_nmap e in + let exps' = walker exps in + fst ((Envmap.fold + (fun (res,effects) i (t,e) -> + let bitlit = E_aux (E_lit (L_aux(L_zero, Parse_ast.Generated l)), + (Parse_ast.Generated l, simple_annot bit_t)) in + let rangelit = E_aux (E_lit (L_aux (L_num 0, Parse_ast.Generated l)), + (Parse_ast.Generated l, simple_annot nat_t)) in + let set_exp = + match t.t with + | Tid "bit" | Tabbrev(_,{t=Tid "bit"}) -> bitlit + | Tapp("range", _) | Tapp("atom", _) -> rangelit + | Tapp("vector", [_;_;_;TA_typ ( {t=Tid "bit"} | {t=Tabbrev(_,{t=Tid "bit"})})]) + | Tapp(("reg"|"register"),[TA_typ ({t = Tapp("vector", + [_;_;_;TA_typ ( {t=Tid "bit"} + | {t=Tabbrev(_,{t=Tid "bit"})})])})]) + | Tabbrev(_,{t = Tapp("vector", + [_;_;_;TA_typ ( {t=Tid "bit"} + | {t=Tabbrev(_,{t=Tid "bit"})})])}) -> + E_aux (E_vector_indexed([], Def_val_aux(Def_val_dec bitlit, + (Parse_ast.Generated l,simple_annot bit_t))), + (Parse_ast.Generated l, simple_annot t)) + | _ -> e in + let unioneffs = union_effects effects (get_effsum_exp set_exp) in + ([E_aux (E_internal_let (LEXP_aux (LEXP_id (Id_aux (Id i, Parse_ast.Generated l)), + (Parse_ast.Generated l, (tag_annot t Emp_intro))), + set_exp, + E_aux (E_block res, (Parse_ast.Generated l, (simple_annot_efr unit_t effects)))), + (Parse_ast.Generated l, simple_annot_efr unit_t unioneffs))],unioneffs))) + (E_aux(E_if(c',t',e'),(Parse_ast.Generated l, annot))::exps',eff_union_exps (c'::t'::e'::exps')) new_vars)*) + | e::exps -> (rewrite_rec e)::(walker exps) + in + check_exp (env_of full_exp) + (E_aux (E_block (List.map strip_exp (walker exps)), (l, ()))) (typ_of full_exp) + | E_assign(le,e) + when lexp_is_local_intro le (env_of full_exp) && not (lexp_is_effectful le) -> + let (le', re') = rewrite_lexp_to_rhs (fun _ -> true) le in + let e' = re' (rewrite_base e) in + let block = annot_exp (E_block []) l (env_of full_exp) unit_typ in + check_exp (env_of full_exp) + (strip_exp (E_aux (E_internal_let(le', e', block), annot))) (typ_of full_exp) + | _ -> rewrite_base full_exp + +let rewrite_lexp_lift_assign_intro rewriters ((LEXP_aux(lexp,annot)) as le) = + let rewrap le = LEXP_aux(le,annot) in + let rewrite_base = rewrite_lexp rewriters in + match lexp, annot with + | (LEXP_id id | LEXP_cast (_,id)), (l, Some (env, typ, eff)) -> + (match Env.lookup_id id env with + | Unbound | Local _ -> + LEXP_aux (lexp, (l, Some (env, typ, union_effects eff (mk_effect [BE_lset])))) + | _ -> rewrap lexp) + | _ -> rewrite_base le + + +let rewrite_defs_exp_lift_assign defs = rewrite_defs_base + {rewrite_exp = rewrite_exp_lift_assign_intro; + rewrite_pat = rewrite_pat; + rewrite_let = rewrite_let; + rewrite_lexp = rewrite_lexp_lift_assign_intro; + rewrite_fun = rewrite_fun; + rewrite_def = rewrite_def; + rewrite_defs = rewrite_defs_base} defs + + +(* Rewrite assignments to register references into calls to a builtin function + "write_reg_ref" (in the Lem shallow embedding). For example, if GPR is a + vector of register references, then + GPR[i] := exp; + becomes + write_reg_ref (vector_access (GPR, i)) exp + *) +let rewrite_register_ref_writes (Defs defs) = + let (Defs write_reg_spec) = fst (check Env.empty (Defs (List.map gen_vs + [("write_reg_ref", "forall ('a : Type). (register('a), 'a) -> unit effect {wreg}")]))) in + let lexp_ref_exp (LEXP_aux (_, annot) as lexp) = + try + let exp = infer_exp (env_of_annot annot) (strip_exp (lexp_to_exp lexp)) in + if is_reftyp (typ_of exp) then Some exp else None + with | _ -> None in + let e_assign (lexp, exp) = + let (lhs, rhs) = rewrite_lexp_to_rhs (fun le -> lexp_ref_exp le = None) lexp in + match lexp_ref_exp lhs with + | Some (E_aux (_, annot) as lhs_exp) -> + let lhs = LEXP_aux (LEXP_memory (mk_id "write_reg_ref", [lhs_exp]), annot) in + E_assign (lhs, rhs exp) + | None -> E_assign (lexp, exp) in + let rewrite_exp _ = fold_exp { id_exp_alg with e_assign = e_assign } in + + let generate_field_accessors l env id n1 n2 fields = + let i1, i2 = match n1, n2 with + | Nexp_aux(Nexp_constant i1, _),Nexp_aux(Nexp_constant i2, _) -> i1, i2 + | _ -> raise (Reporting_basic.err_typ l + ("Non-constant indices in register type " ^ string_of_id id)) in + let dir_b = i1 < i2 in + let dir = (if dir_b then "true" else "false") in + let ord = Ord_aux ((if dir_b then Ord_inc else Ord_dec), Parse_ast.Unknown) in + let size = if dir_b then succ_big_int (sub_big_int i2 i1) else succ_big_int (sub_big_int i1 i2) in + let rtyp = mk_id_typ id in + let vtyp = vector_typ (nconstant i1) (nconstant size) ord bit_typ in + let accessors (fr, fid) = + let i, j = match fr with + | BF_aux (BF_single i, _) -> (i, i) + | BF_aux (BF_range (i, j), _) -> (i, j) + | _ -> raise (Reporting_basic.err_unreachable l "unsupported field type") in + let mk_num_exp i = mk_lit_exp (L_num i) in + let reg_pat, reg_env = bind_pat env (mk_pat (P_typ (rtyp, mk_pat (P_id (mk_id "reg"))))) rtyp in + let inferred_get = infer_exp reg_env (mk_exp (E_vector_subrange + (mk_exp (E_id (mk_id "reg")), mk_num_exp i, mk_num_exp j))) in + let ftyp = typ_of inferred_get in + let v_pat, v_env = bind_pat reg_env (mk_pat (P_typ (ftyp, mk_pat (P_id (mk_id "v"))))) ftyp in + let inferred_set = infer_exp v_env (mk_exp (E_vector_update_subrange + (mk_exp (E_id (mk_id "reg")), mk_num_exp i, mk_num_exp j, mk_exp (E_id (mk_id "v"))))) in + let set_args = P_aux (P_tup [reg_pat; v_pat], (l, Some (env, tuple_typ [rtyp; ftyp], no_effect))) in + let fsuffix = "_" ^ string_of_id id ^ "_" ^ string_of_id fid in + let rec_opt = Rec_aux (Rec_nonrec, l) in + let tannot ret_typ = Typ_annot_opt_aux (Typ_annot_opt_some (TypQ_aux (TypQ_tq [], l), ret_typ), l) in + let eff_opt = Effect_opt_aux (Effect_opt_pure, l) in + let mk_funcl id pat exp = FCL_aux (FCL_Funcl (mk_id id, pat, exp), (l, None)) in + let mk_fundef id pat exp ret_typ = DEF_fundef (FD_aux (FD_function (rec_opt, tannot ret_typ, eff_opt, [mk_funcl id pat exp]), (l, None))) in + [mk_fundef ("get" ^ fsuffix) reg_pat inferred_get ftyp; + mk_fundef ("set" ^ fsuffix) set_args inferred_set (typ_of inferred_set)] in + List.concat (List.map accessors fields) in + + let rewriters = { rewriters_base with rewrite_exp = rewrite_exp } in + let rec rewrite ds = match ds with + | (DEF_type (TD_aux (TD_register (id, n1, n2, fields), (l, Some (env, _, _)))) as d) :: ds -> + let (Defs d), env = check env (Defs [d]) in + d @ (generate_field_accessors l env id n1 n2 fields) @ rewrite ds + | d::ds -> (rewriters.rewrite_def rewriters d)::(rewrite ds) + | [] -> [] in + Defs (rewrite (write_reg_spec @ defs)) + + (* rewrite_defs_base { rewriters_base with rewrite_exp = rewrite_exp } + (Defs (write_reg_spec @ defs)) *) + + +(*let rewrite_exp_separate_ints rewriters ((E_aux (exp,((l,_) as annot))) as full_exp) = + (*let tparms,t,tag,nexps,eff,cum_eff,bounds = match annot with + | Base((tparms,t),tag,nexps,eff,cum_eff,bounds) -> tparms,t,tag,nexps,eff,cum_eff,bounds + | _ -> [],unit_t,Emp_local,[],pure_e,pure_e,nob in*) + let rewrap e = E_aux (e,annot) in + (*let rewrap_effects e effsum = + E_aux (e,(l,Base ((tparms,t),tag,nexps,eff,effsum,bounds))) in*) + let rewrite_rec = rewriters.rewrite_exp rewriters in + let rewrite_base = rewrite_exp rewriters in + match exp with + | E_lit (L_aux (((L_num _) as lit),_)) -> + (match (is_within_machine64 t nexps) with + | Yes -> let _ = Printf.eprintf "Rewriter of num_const, within 64bit int yes\n" in rewrite_base full_exp + | Maybe -> let _ = Printf.eprintf "Rewriter of num_const, within 64bit int maybe\n" in rewrite_base full_exp + | No -> let _ = Printf.eprintf "Rewriter of num_const, within 64bit int no\n" in E_aux(E_app(Id_aux (Id "integer_of_int",l),[rewrite_base full_exp]), + (l, Base((tparms,t),External(None),nexps,eff,cum_eff,bounds)))) + | E_cast (typ, exp) -> rewrap (E_cast (typ, rewrite_rec exp)) + | E_app (id,exps) -> rewrap (E_app (id,List.map rewrite_rec exps)) + | E_app_infix(el,id,er) -> rewrap (E_app_infix(rewrite_rec el,id,rewrite_rec er)) + | E_for (id, e1, e2, e3, o, body) -> + rewrap (E_for (id, rewrite_rec e1, rewrite_rec e2, rewrite_rec e3, o, rewrite_rec body)) + | E_vector_access (vec,index) -> rewrap (E_vector_access (rewrite_rec vec,rewrite_rec index)) + | E_vector_subrange (vec,i1,i2) -> + rewrap (E_vector_subrange (rewrite_rec vec,rewrite_rec i1,rewrite_rec i2)) + | E_vector_update (vec,index,new_v) -> + rewrap (E_vector_update (rewrite_rec vec,rewrite_rec index,rewrite_rec new_v)) + | E_vector_update_subrange (vec,i1,i2,new_v) -> + rewrap (E_vector_update_subrange (rewrite_rec vec,rewrite_rec i1,rewrite_rec i2,rewrite_rec new_v)) + | E_case (exp ,pexps) -> + rewrap (E_case (rewrite_rec exp, + (List.map + (fun (Pat_aux (Pat_exp(p,e),pannot)) -> + Pat_aux (Pat_exp(rewriters.rewrite_pat rewriters nmap p,rewrite_rec e),pannot)) pexps))) + | E_let (letbind,body) -> rewrap (E_let(rewriters.rewrite_let rewriters nmap letbind,rewrite_rec body)) + | E_internal_let (lexp,exp,body) -> + rewrap (E_internal_let (rewriters.rewrite_lexp rewriters nmap lexp, rewrite_rec exp, rewrite_rec body)) + | _ -> rewrite_base full_exp + +let rewrite_defs_separate_numbs defs = rewrite_defs_base + {rewrite_exp = rewrite_exp_separate_ints; + rewrite_pat = rewrite_pat; + rewrite_let = rewrite_let; (*will likely need a new one?*) + rewrite_lexp = rewrite_lexp; (*will likely need a new one?*) + rewrite_fun = rewrite_fun; + rewrite_def = rewrite_def; + rewrite_defs = rewrite_defs_base} defs*) + +(* Remove redundant return statements, and translate remaining ones into an + (effectful) call to builtin function "early_return" (in the Lem shallow + embedding). + + TODO: Maybe separate generic removal of redundant returns, and Lem-specific + rewriting of early returns + *) +let rewrite_defs_early_return (Defs defs) = + let is_return (E_aux (exp, _)) = match exp with + | E_return _ -> true + | _ -> false in + + let get_return (E_aux (e, (l, _)) as exp) = match e with + | E_return e -> e + | _ -> exp in + + let e_block es = + match es with + | [E_aux (e, _)] -> e + | _ :: _ when is_return (Util.last es) -> + let (E_aux (_, annot) as e) = get_return (Util.last es) in + E_return (E_aux (E_block (Util.butlast es @ [get_return e]), annot)) + | _ -> E_block es in + + let e_if (e1, e2, e3) = + if is_return e2 && is_return e3 then + let (E_aux (_, annot)) = get_return e2 in + E_return (E_aux (E_if (e1, get_return e2, get_return e3), annot)) + else E_if (e1, e2, e3) in + + let e_case (e, pes) = + let is_return_pexp (Pat_aux (pexp, _)) = match pexp with + | Pat_exp (_, e) | Pat_when (_, _, e) -> is_return e in + let get_return_pexp (Pat_aux (pexp, a)) = match pexp with + | Pat_exp (p, e) -> Pat_aux (Pat_exp (p, get_return e), a) + | Pat_when (p, g, e) -> Pat_aux (Pat_when (p, g, get_return e), a) in + let annot = match List.map get_return_pexp pes with + | Pat_aux (Pat_exp (_, E_aux (_, annot)), _) :: _ -> annot + | Pat_aux (Pat_when (_, _, E_aux (_, annot)), _) :: _ -> annot + | [] -> (Parse_ast.Unknown, None) in + if List.for_all is_return_pexp pes + then E_return (E_aux (E_case (e, List.map get_return_pexp pes), annot)) + else E_case (e, pes) in + + let e_aux (exp, (l, annot)) = + let full_exp = propagate_exp_effect (E_aux (exp, (l, annot))) in + let env = env_of full_exp in + match full_exp with + | E_aux (E_return exp, (l, Some (env, typ, eff))) -> + (* Add escape effect annotation, since we use the exception mechanism + of the state monad to implement early return in the Lem backend *) + let annot' = Some (env, typ, union_effects eff (mk_effect [BE_escape])) in + let exp' = annot_exp (E_cast (typ_of exp, exp)) l env (typ_of exp) in + E_aux (E_app (mk_id "early_return", [exp']), (l, annot')) + | _ -> full_exp in + + let rewrite_funcl_early_return _ (FCL_aux (FCL_Funcl (id, pat, exp), a)) = + let exp = + exp + (* Pull early returns out as far as possible *) + |> fold_exp { id_exp_alg with e_block = e_block; e_if = e_if; e_case = e_case } + (* Remove singleton E_return *) + |> get_return + (* Fix effect annotations *) + |> fold_exp { id_exp_alg with e_aux = e_aux } in + let a = match a with + | (l, Some (env, typ, eff)) -> + (l, Some (env, typ, union_effects eff (effect_of exp))) + | _ -> a in + FCL_aux (FCL_Funcl (id, pat, exp), a) in + + let rewrite_fun_early_return rewriters + (FD_aux (FD_function (rec_opt, tannot_opt, effect_opt, funcls), a)) = + FD_aux (FD_function (rec_opt, tannot_opt, effect_opt, + List.map (rewrite_funcl_early_return rewriters) funcls), a) in + + let (Defs early_ret_spec) = fst (check Env.empty (Defs [gen_vs + ("early_return", "forall ('a : Type) ('b : Type). 'a -> 'b effect {escape}")])) in + + rewrite_defs_base + { rewriters_base with rewrite_fun = rewrite_fun_early_return } + (Defs (early_ret_spec @ defs)) + +(* Propagate effects of functions, if effect checking and propagation + have not been performed already by the type checker. *) +let rewrite_fix_val_specs (Defs defs) = + let find_vs env val_specs id = + try Bindings.find id val_specs with + | Not_found -> + begin + try Env.get_val_spec id env with + | _ -> + raise (Reporting_basic.err_unreachable (Parse_ast.Unknown) + ("No val spec found for " ^ string_of_id id)) + end + in + + let add_eff_to_vs eff = function + | (tq, Typ_aux (Typ_fn (args_t, ret_t, eff'), a)) -> + (tq, Typ_aux (Typ_fn (args_t, ret_t, union_effects eff eff'), a)) + | vs -> vs + in + + let eff_of_vs = function + | (tq, Typ_aux (Typ_fn (args_t, ret_t, eff), a)) -> eff + | _ -> no_effect + in + + let e_aux val_specs (exp, (l, annot)) = + match fix_eff_exp (E_aux (exp, (l, annot))) with + | E_aux (E_app_infix (_, f, _) as exp, (l, Some (env, typ, eff))) + | E_aux (E_app (f, _) as exp, (l, Some (env, typ, eff))) -> + let vs = find_vs env val_specs f in + let env = Env.update_val_spec f vs env in + E_aux (exp, (l, Some (env, typ, union_effects eff (eff_of_vs vs)))) + | e_aux -> e_aux + in + + let rewrite_exp val_specs = fold_exp { id_exp_alg with e_aux = e_aux val_specs } in + + let rewrite_funcl (val_specs, funcls) (FCL_aux (FCL_Funcl (id, pat, exp), (l, annot))) = + let exp = propagate_exp_effect (rewrite_exp val_specs exp) in + let vs, eff = match find_vs (env_of_annot (l, annot)) val_specs id with + | (tq, Typ_aux (Typ_fn (args_t, ret_t, eff), a)) -> + let eff' = union_effects eff (effect_of exp) in + let args_t' = rewrite_typ_nexp_ids (env_of exp) (pat_typ_of pat) in + let ret_t' = rewrite_typ_nexp_ids (env_of exp) (typ_of exp) in + (tq, Typ_aux (Typ_fn (args_t', ret_t', eff'), a)), eff' + in + let annot = add_effect_annot annot eff in + (Bindings.add id vs val_specs, + funcls @ [FCL_aux (FCL_Funcl (id, pat, exp), (l, annot))]) + in + + let rewrite_fundef (val_specs, FD_aux (FD_function (recopt, tannotopt, effopt, funcls), a)) = + let (val_specs, funcls) = List.fold_left rewrite_funcl (val_specs, []) funcls in + (* Repeat once to cross-propagate effects between clauses *) + let (val_specs, funcls) = List.fold_left rewrite_funcl (val_specs, []) funcls in + let is_funcl_rec (FCL_aux (FCL_Funcl (id, _, exp), _)) = + fst (fold_exp + { (compute_exp_alg false (||) ) with + e_app = (fun (f, es) -> + let (rs, es) = List.split es in + (List.fold_left (||) (string_of_id f = string_of_id id) rs, + E_app (f, es))); + e_app_infix = (fun ((r1,e1), f, (r2,e2)) -> + (r1 || r2 || (string_of_id f = string_of_id id), + E_app_infix (e1, f, e2))) } + exp) + in + let recopt = + if List.exists is_funcl_rec funcls then + Rec_aux (Rec_rec, Parse_ast.Unknown) + else recopt + in + let tannotopt = match tannotopt, funcls with + | Typ_annot_opt_aux (Typ_annot_opt_some (typq, typ), l), + FCL_aux (FCL_Funcl (_, _, exp), _) :: _ -> + Typ_annot_opt_aux (Typ_annot_opt_some (typq, rewrite_typ_nexp_ids (env_of exp) typ), l) + | _ -> tannotopt in + (val_specs, FD_aux (FD_function (recopt, tannotopt, effopt, funcls), a)) in + + let rec rewrite_fundefs (val_specs, fundefs) = + match fundefs with + | fundef :: fundefs -> + let (val_specs, fundef) = rewrite_fundef (val_specs, fundef) in + let (val_specs, fundefs) = rewrite_fundefs (val_specs, fundefs) in + (val_specs, fundef :: fundefs) + | [] -> (val_specs, []) in + + let rewrite_def (val_specs, defs) = function + | DEF_fundef fundef -> + let (val_specs, fundef) = rewrite_fundef (val_specs, fundef) in + (val_specs, defs @ [DEF_fundef fundef]) + | DEF_internal_mutrec fundefs -> + let (val_specs, fundefs) = rewrite_fundefs (val_specs, fundefs) in + (val_specs, defs @ [DEF_internal_mutrec fundefs]) + | DEF_val (LB_aux (LB_val (pat, exp), a)) -> + (val_specs, defs @ [DEF_val (LB_aux (LB_val (pat, rewrite_exp val_specs exp), a))]) + | DEF_spec (VS_aux (VS_val_spec (typschm, id, ext_opt, is_cast), a)) -> + let typschm, val_specs = + if Bindings.mem id val_specs then begin + let (tq, typ) = Bindings.find id val_specs in + TypSchm_aux (TypSchm_ts (tq, typ), Parse_ast.Unknown), val_specs + end else begin + let (TypSchm_aux (TypSchm_ts (tq, typ), _)) = typschm in + typschm, Bindings.add id (tq, typ) val_specs + end + in + (val_specs, defs @ [DEF_spec (VS_aux (VS_val_spec (typschm, id, ext_opt, is_cast), a))]) + | def -> (val_specs, defs @ [def]) + in + + let rewrite_val_specs val_specs = function + | DEF_spec (VS_aux (VS_val_spec (typschm, id, ext_opt, is_cast), a)) + when Bindings.mem id val_specs -> + let typschm = match typschm with + | TypSchm_aux (TypSchm_ts (tq, typ), l) -> + let (tq, typ) = Bindings.find id val_specs in + TypSchm_aux (TypSchm_ts (tq, typ), l) + in + DEF_spec (VS_aux (VS_val_spec (typschm, id, ext_opt, is_cast), a)) + | def -> def + in + + let (val_specs, defs) = List.fold_left rewrite_def (Bindings.empty, []) defs in + let defs = List.map (rewrite_val_specs val_specs) defs in + + (* if !Type_check.opt_no_effects + then *) + Defs defs + (* else Defs defs *) + +(* Turn constraints into numeric expressions with sizeof *) +let rewrite_constraint = + let rec rewrite_nc (NC_aux (nc_aux, l)) = mk_exp (rewrite_nc_aux nc_aux) + and rewrite_nc_aux = function + | NC_bounded_ge (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id ">=", mk_exp (E_sizeof n2)) + | NC_bounded_le (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id "<=", mk_exp (E_sizeof n2)) + | NC_equal (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id "==", mk_exp (E_sizeof n2)) + | NC_not_equal (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id "!=", mk_exp (E_sizeof n2)) + | NC_and (nc1, nc2) -> E_app_infix (rewrite_nc nc1, mk_id "&", rewrite_nc nc2) + | NC_or (nc1, nc2) -> E_app_infix (rewrite_nc nc1, mk_id "|", rewrite_nc nc2) + | NC_false -> E_lit (mk_lit L_false) + | NC_true -> E_lit (mk_lit L_true) + | NC_set (kid, ints) -> + unaux_exp (rewrite_nc (List.fold_left (fun nc int -> nc_or nc (nc_eq (nvar kid) (nconstant int))) nc_true ints)) + in + let rewrite_e_aux (E_aux (e_aux, _) as exp) = + match e_aux with + | E_constraint nc -> + check_exp (env_of exp) (rewrite_nc nc) bool_typ + | _ -> exp + in + + let rewrite_e_constraint = { id_exp_alg with e_aux = (fun (exp, annot) -> rewrite_e_aux (E_aux (exp, annot))) } in + + rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp rewrite_e_constraint) } + +let rewrite_type_union_typs rw_typ (Tu_aux (tu, annot)) = + match tu with + | Tu_id id -> Tu_aux (Tu_id id, annot) + | Tu_ty_id (typ, id) -> Tu_aux (Tu_ty_id (rw_typ typ, id), annot) + +let rewrite_type_def_typs rw_typ rw_typquant rw_typschm (TD_aux (td, annot)) = + match td with + | TD_abbrev (id, nso, typschm) -> TD_aux (TD_abbrev (id, nso, rw_typschm typschm), annot) + | TD_record (id, nso, typq, typ_ids, flag) -> + TD_aux (TD_record (id, nso, rw_typquant typq, List.map (fun (typ, id) -> (rw_typ typ, id)) typ_ids, flag), annot) + | TD_variant (id, nso, typq, tus, flag) -> + TD_aux (TD_variant (id, nso, rw_typquant typq, List.map (rewrite_type_union_typs rw_typ) tus, flag), annot) + | TD_enum (id, nso, ids, flag) -> TD_aux (TD_enum (id, nso, ids, flag), annot) + | TD_register (id, n1, n2, ranges) -> TD_aux (TD_register (id, n1, n2, ranges), annot) + +(* FIXME: other reg_dec types *) +let rewrite_dec_spec_typs rw_typ (DEC_aux (ds, annot)) = + match ds with + | DEC_reg (typ, id) -> DEC_aux (DEC_reg (rw_typ typ, id), annot) + | _ -> assert false + +(* Remove overload definitions and cast val specs from the + specification because the interpreter doesn't know about them.*) +let rewrite_overload_cast (Defs defs) = + let remove_cast_vs (VS_aux (vs_aux, annot)) = + match vs_aux with + | VS_val_spec (typschm, id, ext, _) -> VS_aux (VS_val_spec (typschm, id, ext, false), annot) + in + let simple_def = function + | DEF_spec vs -> DEF_spec (remove_cast_vs vs) + | def -> def + in + let is_overload = function + | DEF_overload _ -> true + | _ -> false + in + let defs = List.map simple_def defs in + Defs (List.filter (fun def -> not (is_overload def)) defs) + + +let rewrite_undefined mwords = + let rewrite_e_aux (E_aux (e_aux, _) as exp) = + match e_aux with + | E_lit (L_aux (L_undef, l)) -> + check_exp (env_of exp) (undefined_of_typ mwords l (fun _ -> ()) (Env.expand_synonyms (env_of exp) (typ_of exp))) (typ_of exp) + | _ -> exp + in + let rewrite_exp_undefined = { id_exp_alg with e_aux = (fun (exp, annot) -> rewrite_e_aux (E_aux (exp, annot))) } in + rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp rewrite_exp_undefined) } + +let rec simple_typ (Typ_aux (typ_aux, l) as typ) = Typ_aux (simple_typ_aux typ_aux, l) +and simple_typ_aux = function + | Typ_id id -> Typ_id id + | Typ_app (id, [_; _; _; Typ_arg_aux (Typ_arg_typ typ, l)]) when Id.compare id (mk_id "vector") = 0 -> + Typ_app (mk_id "list", [Typ_arg_aux (Typ_arg_typ (simple_typ typ), l)]) + | Typ_app (id, [_]) when Id.compare id (mk_id "atom") = 0 -> + Typ_id (mk_id "int") + | Typ_app (id, [_; _]) when Id.compare id (mk_id "range") = 0 -> + Typ_id (mk_id "int") + | Typ_app (id, args) -> Typ_app (id, List.concat (List.map simple_typ_arg args)) + | Typ_fn (typ1, typ2, effs) -> Typ_fn (simple_typ typ1, simple_typ typ2, effs) + | Typ_tup typs -> Typ_tup (List.map simple_typ typs) + | Typ_exist (_, _, Typ_aux (typ, l)) -> simple_typ_aux typ + | typ_aux -> typ_aux +and simple_typ_arg (Typ_arg_aux (typ_arg_aux, l)) = + match typ_arg_aux with + | Typ_arg_typ typ -> [Typ_arg_aux (Typ_arg_typ (simple_typ typ), l)] + | _ -> [] + +(* This pass aims to remove all the Num quantifiers from the specification. *) +let rewrite_simple_types (Defs defs) = + let is_simple = function + | QI_aux (QI_id kopt, annot) as qi when is_typ_kopt kopt || is_order_kopt kopt -> true + | _ -> false + in + let simple_typquant (TypQ_aux (tq_aux, annot)) = + match tq_aux with + | TypQ_no_forall -> TypQ_aux (TypQ_no_forall, annot) + | TypQ_tq quants -> TypQ_aux (TypQ_tq (List.filter (fun q -> is_simple q) quants), annot) + in + let simple_typschm (TypSchm_aux (TypSchm_ts (typq, typ), annot)) = + TypSchm_aux (TypSchm_ts (simple_typquant typq, simple_typ typ), annot) + in + let simple_vs (VS_aux (vs_aux, annot)) = + match vs_aux with + | VS_val_spec (typschm, id, ext, is_cast) -> VS_aux (VS_val_spec (simple_typschm typschm, id, ext, is_cast), annot) + in + let rec simple_lit (L_aux (lit_aux, l) as lit) = + match lit_aux with + | L_bin _ | L_hex _ -> + E_list (List.map (fun b -> E_aux (E_lit b, simple_annot l bit_typ)) (vector_string_to_bit_list l lit_aux)) + | _ -> E_lit lit + in + let simple_def = function + | DEF_spec vs -> DEF_spec (simple_vs vs) + | DEF_type td -> DEF_type (rewrite_type_def_typs simple_typ simple_typquant simple_typschm td) + | DEF_reg_dec ds -> DEF_reg_dec (rewrite_dec_spec_typs simple_typ ds) + | def -> def + in + let simple_pat = { + id_pat_alg with + p_typ = (fun (typ, pat) -> P_typ (simple_typ typ, pat)); + p_var = (fun (pat, kid) -> unaux_pat pat); + p_vector = (fun pats -> P_list pats) + } in + let simple_exp = { + id_exp_alg with + e_lit = simple_lit; + e_vector = (fun exps -> E_list exps); + e_cast = (fun (typ, exp) -> E_cast (simple_typ typ, exp)); + (* e_assert = (fun (E_aux (_, annot), str) -> E_assert (E_aux (E_lit (mk_lit L_true), annot), str)); *) + lEXP_cast = (fun (typ, lexp) -> LEXP_cast (simple_typ typ, lexp)); + pat_alg = simple_pat + } in + let simple_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp simple_exp); + rewrite_pat = (fun _ -> fold_pat simple_pat) } + in + let defs = Defs (List.map simple_def defs) in + rewrite_defs_base simple_defs defs + +let rewrite_tuple_vector_assignments defs = + let assign_tuple e_aux annot = + let env = env_of_annot annot in + match e_aux with + | E_assign (LEXP_aux (LEXP_tup lexps, lannot), exp) -> + let typ = Env.base_typ_of env (typ_of exp) in + if is_vector_typ typ then + (* let _ = Pretty_print_common.print stderr (Pretty_print_sail.doc_exp (E_aux (e_aux, annot))) in *) + let (start, _, ord, etyp) = vector_typ_args_of typ in + let len (LEXP_aux (le, lannot)) = + let ltyp = Env.base_typ_of env (typ_of_annot lannot) in + if is_vector_typ ltyp then + let (_, len, _, _) = vector_typ_args_of ltyp in + match nexp_simp len with + | Nexp_aux (Nexp_constant len, _) -> len + | _ -> unit_big_int + else unit_big_int in + let next i step = + if is_order_inc ord + then (sub_big_int (add_big_int i step) unit_big_int, add_big_int i step) + else (add_big_int (sub_big_int i step) unit_big_int, sub_big_int i step) in + let i = match nexp_simp start with + | (Nexp_aux (Nexp_constant i, _)) -> i + | _ -> if is_order_inc ord then zero_big_int else big_int_of_int (List.length lexps - 1) in + let l = gen_loc (fst annot) in + let exp' = + if small exp then strip_exp exp + else mk_exp (E_id (mk_id "split_vec")) in + let lexp_to_exp (i, exps) lexp = + let (j, i') = next i (len lexp) in + let i_exp = mk_exp (E_lit (mk_lit (L_num i))) in + let j_exp = mk_exp (E_lit (mk_lit (L_num j))) in + let sub = mk_exp (E_vector_subrange (exp', i_exp, j_exp)) in + (i', exps @ [sub]) in + let (_, exps) = List.fold_left lexp_to_exp (i, []) lexps in + let tup = mk_exp (E_tuple exps) in + let lexp = LEXP_aux (LEXP_tup (List.map strip_lexp lexps), (l, ())) in + let e_aux = + if small exp then mk_exp (E_assign (lexp, tup)) + else mk_exp ( + E_let ( + mk_letbind (mk_pat (P_id (mk_id "split_vec"))) (strip_exp exp), + mk_exp (E_assign (lexp, tup)))) in + begin + try check_exp env e_aux unit_typ with + | Type_error (l, err) -> + raise (Reporting_basic.err_typ l (string_of_type_error err)) + end + else E_aux (e_aux, annot) + | _ -> E_aux (e_aux, annot) + in + let assign_exp = { + id_exp_alg with + e_aux = (fun (e_aux, annot) -> assign_tuple e_aux annot) + } in + let assign_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp assign_exp) } in + rewrite_defs_base assign_defs defs + +let rewrite_tuple_assignments defs = + let assign_tuple e_aux annot = + let env = env_of_annot annot in + match e_aux with + | E_assign (LEXP_aux (LEXP_tup lexps, _), exp) -> + (* let _ = Pretty_print_common.print stderr (Pretty_print_sail.doc_exp (E_aux (e_aux, annot))) in *) + let (_, ids) = List.fold_left (fun (n, ids) _ -> (n + 1, ids @ [mk_id ("tup__" ^ string_of_int n)])) (0, []) lexps in + let block_assign i lexp = mk_exp (E_assign (strip_lexp lexp, mk_exp (E_id (mk_id ("tup__" ^ string_of_int i))))) in + let block = mk_exp (E_block (List.mapi block_assign lexps)) in + let letbind = mk_letbind (mk_pat (P_tup (List.map (fun id -> mk_pat (P_id id)) ids))) (strip_exp exp) in + let let_exp = mk_exp (E_let (letbind, block)) in + begin + try check_exp env let_exp unit_typ with + | Type_error (l, err) -> + raise (Reporting_basic.err_typ l (string_of_type_error err)) + end + | _ -> E_aux (e_aux, annot) + in + let assign_exp = { + id_exp_alg with + e_aux = (fun (e_aux, annot) -> assign_tuple e_aux annot) + } in + let assign_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp assign_exp) } in + rewrite_defs_base assign_defs defs + +let rewrite_simple_assignments defs = + let assign_e_aux e_aux annot = + let env = env_of_annot annot in + match e_aux with + | E_assign (lexp, exp) -> + let (lexp, rhs) = rewrite_lexp_to_rhs (fun _ -> true) lexp in + let assign = mk_exp (E_assign (strip_lexp lexp, strip_exp (rhs exp))) in + check_exp env assign unit_typ + | _ -> E_aux (e_aux, annot) + in + let assign_exp = { + id_exp_alg with + e_aux = (fun (e_aux, annot) -> assign_e_aux e_aux annot) + } in + let assign_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp assign_exp) } in + rewrite_defs_base assign_defs defs + +let rewrite_defs_remove_blocks = + let letbind_wild v body = + let l = get_loc_exp v in + let env = env_of v in + let typ = typ_of v in + let wild = P_typ (typ, annot_pat P_wild l env typ) in + let e_aux = E_let (annot_letbind (wild, v) l env typ, body) in + propagate_exp_effect (annot_exp e_aux l env (typ_of body)) in + + let rec f l = function + | [] -> E_aux (E_lit (L_aux (L_unit,gen_loc l)), (simple_annot l unit_typ)) + | [e] -> e (* check with Kathy if that annotation is fine *) + | e :: es -> letbind_wild e (f l es) in + + let e_aux = function + | (E_block es,(l,_)) -> f l es + | (e,annot) -> E_aux (e,annot) in + + let alg = { id_exp_alg with e_aux = e_aux } in + + rewrite_defs_base + {rewrite_exp = (fun _ -> fold_exp alg) + ; rewrite_pat = rewrite_pat + ; rewrite_let = rewrite_let + ; rewrite_lexp = rewrite_lexp + ; rewrite_fun = rewrite_fun + ; rewrite_def = rewrite_def + ; rewrite_defs = rewrite_defs_base + } + + + +let letbind (v : 'a exp) (body : 'a exp -> 'a exp) : 'a exp = + (* body is a function : E_id variable -> actual body *) + let (E_aux (_,(l,annot))) = v in + match annot with + | Some (env, Typ_aux (Typ_id tid, _), eff) when string_of_id tid = "unit" -> + let body = body (annot_exp (E_lit (mk_lit L_unit)) l env unit_typ) in + let body_typ = try typ_of body with _ -> unit_typ in + let wild = P_typ (typ_of v, annot_pat P_wild l env (typ_of v)) in + let lb = annot_letbind (wild, v) l env unit_typ in + propagate_exp_effect (annot_exp (E_let (lb, body)) l env body_typ) + | Some (env, typ, eff) -> + let id = fresh_id "w__" l in + let pat = P_typ (typ_of v, annot_pat (P_id id) l env (typ_of v)) in + let lb = annot_letbind (pat, v) l env typ in + let body = body (annot_exp (E_id id) l env typ) in + propagate_exp_effect (annot_exp (E_let (lb, body)) l env (typ_of body)) + | None -> + raise (Reporting_basic.err_unreachable l "no type information") + + +let rec mapCont (f : 'b -> ('b -> 'a exp) -> 'a exp) (l : 'b list) (k : 'b list -> 'a exp) : 'a exp = + match l with + | [] -> k [] + | exp :: exps -> f exp (fun exp -> mapCont f exps (fun exps -> k (exp :: exps))) + +let rewrite_defs_letbind_effects = + + let rec value ((E_aux (exp_aux,_)) as exp) = + not (effectful exp || updates_vars exp) + and value_optdefault (Def_val_aux (o,_)) = match o with + | Def_val_empty -> true + | Def_val_dec e -> value e + and value_fexps (FES_aux (FES_Fexps (fexps,_),_)) = + List.fold_left (fun b (FE_aux (FE_Fexp (_,e),_)) -> b && value e) true fexps in + + + let rec n_exp_name (exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp = + n_exp exp (fun exp -> if value exp then k exp else letbind exp k) + + and n_exp_pure (exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp = + n_exp exp (fun exp -> if value exp then k exp else letbind exp k) + + and n_exp_nameL (exps : 'a exp list) (k : 'a exp list -> 'a exp) : 'a exp = + mapCont n_exp_name exps k + + and n_fexp (fexp : 'a fexp) (k : 'a fexp -> 'a exp) : 'a exp = + let (FE_aux (FE_Fexp (id,exp),annot)) = fexp in + n_exp_name exp (fun exp -> + k (fix_eff_fexp (FE_aux (FE_Fexp (id,exp),annot)))) + + and n_fexpL (fexps : 'a fexp list) (k : 'a fexp list -> 'a exp) : 'a exp = + mapCont n_fexp fexps k + + and n_pexp (newreturn : bool) (pexp : 'a pexp) (k : 'a pexp -> 'a exp) : 'a exp = + match pexp with + | Pat_aux (Pat_exp (pat,exp),annot) -> + k (fix_eff_pexp (Pat_aux (Pat_exp (pat,n_exp_term newreturn exp), annot))) + | Pat_aux (Pat_when (pat,guard,exp),annot) -> + k (fix_eff_pexp (Pat_aux (Pat_when (pat,n_exp_term newreturn guard,n_exp_term newreturn exp), annot))) + + and n_pexpL (newreturn : bool) (pexps : 'a pexp list) (k : 'a pexp list -> 'a exp) : 'a exp = + mapCont (n_pexp newreturn) pexps k + + and n_fexps (fexps : 'a fexps) (k : 'a fexps -> 'a exp) : 'a exp = + let (FES_aux (FES_Fexps (fexps_aux,b),annot)) = fexps in + n_fexpL fexps_aux (fun fexps_aux -> + k (fix_eff_fexps (FES_aux (FES_Fexps (fexps_aux,b),annot)))) + + and n_opt_default (opt_default : 'a opt_default) (k : 'a opt_default -> 'a exp) : 'a exp = + let (Def_val_aux (opt_default,annot)) = opt_default in + match opt_default with + | Def_val_empty -> k (Def_val_aux (Def_val_empty,annot)) + | Def_val_dec exp -> + n_exp_name exp (fun exp -> + k (fix_eff_opt_default (Def_val_aux (Def_val_dec exp,annot)))) + + and n_lb (lb : 'a letbind) (k : 'a letbind -> 'a exp) : 'a exp = + let (LB_aux (lb,annot)) = lb in + match lb with + | LB_val (pat,exp1) -> + n_exp exp1 (fun exp1 -> + k (fix_eff_lb (LB_aux (LB_val (pat,exp1),annot)))) + + and n_lexp (lexp : 'a lexp) (k : 'a lexp -> 'a exp) : 'a exp = + let (LEXP_aux (lexp_aux,annot)) = lexp in + match lexp_aux with + | LEXP_id _ -> k lexp + | LEXP_memory (id,es) -> + n_exp_nameL es (fun es -> + k (fix_eff_lexp (LEXP_aux (LEXP_memory (id,es),annot)))) + | LEXP_tup es -> + n_lexpL es (fun es -> + k (fix_eff_lexp (LEXP_aux (LEXP_tup es,annot)))) + | LEXP_cast (typ,id) -> + k (fix_eff_lexp (LEXP_aux (LEXP_cast (typ,id),annot))) + | LEXP_vector (lexp,e) -> + n_lexp lexp (fun lexp -> + n_exp_name e (fun e -> + k (fix_eff_lexp (LEXP_aux (LEXP_vector (lexp,e),annot))))) + | LEXP_vector_range (lexp,e1,e2) -> + n_lexp lexp (fun lexp -> + n_exp_name e1 (fun e1 -> + n_exp_name e2 (fun e2 -> + k (fix_eff_lexp (LEXP_aux (LEXP_vector_range (lexp,e1,e2),annot)))))) + | LEXP_field (lexp,id) -> + n_lexp lexp (fun lexp -> + k (fix_eff_lexp (LEXP_aux (LEXP_field (lexp,id),annot)))) + + and n_lexpL (lexps : 'a lexp list) (k : 'a lexp list -> 'a exp) : 'a exp = + mapCont n_lexp lexps k + + and n_exp_term (newreturn : bool) (exp : 'a exp) : 'a exp = + let (E_aux (_,(l,tannot))) = exp in + let exp = + if newreturn then + (* let typ = try typ_of exp with _ -> unit_typ in *) + annot_exp (E_internal_return exp) l (env_of exp) (typ_of exp) + else + exp in + (* n_exp_term forces an expression to be translated into a form + "let .. let .. let .. in EXP" where EXP has no effect and does not update + variables *) + n_exp_pure exp (fun exp -> exp) + + and n_exp (E_aux (exp_aux,annot) as exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp = + + let rewrap e = fix_eff_exp (E_aux (e,annot)) in + + match exp_aux with + | E_block es -> failwith "E_block should have been removed till now" + | E_nondet _ -> failwith "E_nondet not supported" + | E_id id -> k exp + | E_lit _ -> k exp + | E_cast (typ,exp') -> + n_exp_name exp' (fun exp' -> + k (rewrap (E_cast (typ,exp')))) + | E_app (id,exps) -> + n_exp_nameL exps (fun exps -> + k (rewrap (E_app (id,exps)))) + | E_app_infix (exp1,id,exp2) -> + n_exp_name exp1 (fun exp1 -> + n_exp_name exp2 (fun exp2 -> + k (rewrap (E_app_infix (exp1,id,exp2))))) + | E_tuple exps -> + n_exp_nameL exps (fun exps -> + k (rewrap (E_tuple exps))) + | E_if (exp1,exp2,exp3) -> + n_exp_name exp1 (fun exp1 -> + let (E_aux (_,annot2)) = exp2 in + let (E_aux (_,annot3)) = exp3 in + let newreturn = effectful exp2 || effectful exp3 in + let exp2 = n_exp_term newreturn exp2 in + let exp3 = n_exp_term newreturn exp3 in + k (rewrap (E_if (exp1,exp2,exp3)))) + | E_for (id,start,stop,by,dir,body) -> + n_exp_name start (fun start -> + n_exp_name stop (fun stop -> + n_exp_name by (fun by -> + let body = n_exp_term (effectful body) body in + k (rewrap (E_for (id,start,stop,by,dir,body)))))) + | E_loop (loop, cond, body) -> + let cond = n_exp_term (effectful cond) cond in + let body = n_exp_term (effectful body) body in + k (rewrap (E_loop (loop,cond,body))) + | E_vector exps -> + n_exp_nameL exps (fun exps -> + k (rewrap (E_vector exps))) + | E_vector_access (exp1,exp2) -> + n_exp_name exp1 (fun exp1 -> + n_exp_name exp2 (fun exp2 -> + k (rewrap (E_vector_access (exp1,exp2))))) + | E_vector_subrange (exp1,exp2,exp3) -> + n_exp_name exp1 (fun exp1 -> + n_exp_name exp2 (fun exp2 -> + n_exp_name exp3 (fun exp3 -> + k (rewrap (E_vector_subrange (exp1,exp2,exp3)))))) + | E_vector_update (exp1,exp2,exp3) -> + n_exp_name exp1 (fun exp1 -> + n_exp_name exp2 (fun exp2 -> + n_exp_name exp3 (fun exp3 -> + k (rewrap (E_vector_update (exp1,exp2,exp3)))))) + | E_vector_update_subrange (exp1,exp2,exp3,exp4) -> + n_exp_name exp1 (fun exp1 -> + n_exp_name exp2 (fun exp2 -> + n_exp_name exp3 (fun exp3 -> + n_exp_name exp4 (fun exp4 -> + k (rewrap (E_vector_update_subrange (exp1,exp2,exp3,exp4))))))) + | E_vector_append (exp1,exp2) -> + n_exp_name exp1 (fun exp1 -> + n_exp_name exp2 (fun exp2 -> + k (rewrap (E_vector_append (exp1,exp2))))) + | E_list exps -> + n_exp_nameL exps (fun exps -> + k (rewrap (E_list exps))) + | E_cons (exp1,exp2) -> + n_exp_name exp1 (fun exp1 -> + n_exp_name exp2 (fun exp2 -> + k (rewrap (E_cons (exp1,exp2))))) + | E_record fexps -> + n_fexps fexps (fun fexps -> + k (rewrap (E_record fexps))) + | E_record_update (exp1,fexps) -> + n_exp_name exp1 (fun exp1 -> + n_fexps fexps (fun fexps -> + k (rewrap (E_record_update (exp1,fexps))))) + | E_field (exp1,id) -> + n_exp_name exp1 (fun exp1 -> + k (rewrap (E_field (exp1,id)))) + | E_case (exp1,pexps) -> + let newreturn = List.exists effectful_pexp pexps in + n_exp_name exp1 (fun exp1 -> + n_pexpL newreturn pexps (fun pexps -> + k (rewrap (E_case (exp1,pexps))))) + | E_let (lb,body) -> + n_lb lb (fun lb -> + rewrap (E_let (lb,n_exp body k))) + | E_sizeof nexp -> + k (rewrap (E_sizeof nexp)) + | E_constraint nc -> + k (rewrap (E_constraint nc)) + | E_sizeof_internal annot -> + k (rewrap (E_sizeof_internal annot)) + | E_assign (lexp,exp1) -> + n_lexp lexp (fun lexp -> + n_exp_name exp1 (fun exp1 -> + k (rewrap (E_assign (lexp,exp1))))) + | E_exit exp' -> k (E_aux (E_exit (n_exp_term (effectful exp') exp'),annot)) + | E_assert (exp1,exp2) -> + n_exp_name exp1 (fun exp1 -> + n_exp_name exp2 (fun exp2 -> + k (rewrap (E_assert (exp1,exp2))))) + | E_internal_cast (annot',exp') -> + n_exp_name exp' (fun exp' -> + k (rewrap (E_internal_cast (annot',exp')))) + | E_internal_exp _ -> k exp + | E_internal_exp_user _ -> k exp + | E_internal_let (lexp,exp1,exp2) -> + n_lexp lexp (fun lexp -> + n_exp exp1 (fun exp1 -> + rewrap (E_internal_let (lexp,exp1,n_exp exp2 k)))) + | E_internal_return exp1 -> + n_exp_name exp1 (fun exp1 -> + k (rewrap (E_internal_return exp1))) + | E_comment str -> + k (rewrap (E_comment str)) + | E_comment_struc exp' -> + n_exp exp' (fun exp' -> + k (rewrap (E_comment_struc exp'))) + | E_return exp' -> + n_exp_name exp' (fun exp' -> + k (rewrap (E_return exp'))) + | E_internal_plet _ -> failwith "E_internal_plet should not be here yet" in + + let rewrite_fun _ (FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),fdannot)) = + let effectful_funcl (FCL_aux (FCL_Funcl(_, _, exp), _)) = effectful exp in + let newreturn = List.exists effectful_funcl funcls in + let rewrite_funcl (FCL_aux (FCL_Funcl(id,pat,exp),annot)) = + let _ = reset_fresh_name_counter () in + FCL_aux (FCL_Funcl (id,pat,n_exp_term newreturn exp),annot) + in FD_aux (FD_function(recopt,tannotopt,effectopt,List.map rewrite_funcl funcls),fdannot) in + let rewrite_def rewriters def = + (* let _ = Pretty_print_sail.pp_defs stderr (Defs [def]) in *) + match def with + | DEF_val (LB_aux (lb, annot)) -> + let rewrap lb = DEF_val (LB_aux (lb, annot)) in + begin + match lb with + | LB_val (pat, exp) -> + rewrap (LB_val (pat, n_exp_term (effectful exp) exp)) + end + | DEF_fundef fdef -> DEF_fundef (rewrite_fun rewriters fdef) + | DEF_internal_mutrec fdefs -> + DEF_internal_mutrec (List.map (rewrite_fun rewriters) fdefs) + | d -> d in + rewrite_defs_base + {rewrite_exp = rewrite_exp + ; rewrite_pat = rewrite_pat + ; rewrite_let = rewrite_let + ; rewrite_lexp = rewrite_lexp + ; rewrite_fun = rewrite_fun + ; rewrite_def = rewrite_def + ; rewrite_defs = rewrite_defs_base + } + +let rewrite_defs_internal_lets = + + let rec pat_of_local_lexp (LEXP_aux (lexp, ((l, _) as annot))) = match lexp with + | LEXP_id id -> P_aux (P_id id, annot) + | LEXP_cast (typ, id) -> P_aux (P_typ (typ, P_aux (P_id id, annot)), annot) + | LEXP_tup lexps -> P_aux (P_tup (List.map pat_of_local_lexp lexps), annot) + | _ -> raise (Reporting_basic.err_unreachable l "unexpected local lexp") in + + let e_let (lb,body) = + match lb with + | LB_aux (LB_val (P_aux ((P_wild | P_typ (_, P_aux (P_wild, _))), _), + E_aux (E_assign ((LEXP_aux (_, annot) as le), exp), (l, _))), _) + when lexp_is_local le (env_of_annot annot) && not (lexp_is_effectful le) -> + (* Rewrite assignments to local variables into let bindings *) + let (lhs, rhs) = rewrite_lexp_to_rhs (fun _ -> true) le in + let (LEXP_aux (_, lannot)) = lhs in + let ltyp = typ_of_annot lannot in + let rhs = annot_exp (E_cast (ltyp, rhs exp)) l (env_of_annot lannot) ltyp in + E_let (LB_aux (LB_val (pat_of_local_lexp lhs, rhs), annot), body) + | LB_aux (LB_val (pat,exp'),annot') -> + if effectful exp' + then E_internal_plet (pat,exp',body) + else E_let (lb,body) in + + let e_internal_let = fun (lexp,exp1,exp2) -> + let paux, annot = match lexp with + | LEXP_aux (LEXP_id id, annot) -> + (P_id id, annot) + | LEXP_aux (LEXP_cast (typ, id), annot) -> + (P_typ (typ, P_aux (P_id id, annot)), annot) + | _ -> failwith "E_internal_let with unexpected lexp" in + if effectful exp1 then + E_internal_plet (P_aux (paux, annot), exp1, exp2) + else + E_let (LB_aux (LB_val (P_aux (paux, annot), exp1), annot), exp2) in + + let alg = { id_exp_alg with e_let = e_let; e_internal_let = e_internal_let } in + rewrite_defs_base + { rewrite_exp = (fun _ -> fold_exp alg) + ; rewrite_pat = rewrite_pat + ; rewrite_let = rewrite_let + ; rewrite_lexp = rewrite_lexp + ; rewrite_fun = rewrite_fun + ; rewrite_def = rewrite_def + ; rewrite_defs = rewrite_defs_base + } + + +(* Now all expressions have no blocks anymore, any term is a sequence of let-expressions, + * internal let-expressions, or internal plet-expressions ended by a term that does not + * access memory or registers and does not update variables *) + +let dedup eq = + List.fold_left (fun acc e -> if List.exists (eq e) acc then acc else e :: acc) [] + +let eqidtyp (id1,_) (id2,_) = + let name1 = match id1 with Id_aux ((Id name | DeIid name),_) -> name in + let name2 = match id2 with Id_aux ((Id name | DeIid name),_) -> name in + name1 = name2 + +let find_introduced_vars exp = + let lEXP_aux ((ids, lexp), annot) = + let ids = match lexp with + | LEXP_id id | LEXP_cast (_, id) + when id_is_unbound id (env_of_annot annot) -> IdSet.add id ids + | _ -> ids in + (ids, LEXP_aux (lexp, annot)) in + fst (fold_exp + { (compute_exp_alg IdSet.empty IdSet.union) with lEXP_aux = lEXP_aux } exp) + +let find_updated_vars exp = + let intros = find_introduced_vars exp in + let lEXP_aux ((ids, lexp), annot) = + let ids = match lexp with + | LEXP_id id | LEXP_cast (_, id) + when id_is_local_var id (env_of_annot annot) && not (IdSet.mem id intros) -> + (id, annot) :: ids + | _ -> ids in + (ids, LEXP_aux (lexp, annot)) in + dedup eqidtyp (fst (fold_exp + { (compute_exp_alg [] (@)) with lEXP_aux = lEXP_aux } exp)) + +let swaptyp typ (l,tannot) = match tannot with + | Some (env, typ', eff) -> (l, Some (env, typ, eff)) + | _ -> raise (Reporting_basic.err_unreachable l "swaptyp called with empty type annotation") + +type 'a updated_term = + | Added_vars of 'a exp * 'a pat + | Same_vars of 'a exp + +let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) = + + let env = env_of exp in + + let rec add_vars overwrite ((E_aux (expaux,annot)) as exp) vars = + match expaux with + | E_let (lb,exp) -> + let exp = add_vars overwrite exp vars in + E_aux (E_let (lb,exp),swaptyp (typ_of exp) annot) + | E_internal_let (lexp,exp1,exp2) -> + let exp2 = add_vars overwrite exp2 vars in + E_aux (E_internal_let (lexp,exp1,exp2), swaptyp (typ_of exp2) annot) + | E_internal_plet (pat,exp1,exp2) -> + let exp2 = add_vars overwrite exp2 vars in + E_aux (E_internal_plet (pat,exp1,exp2), swaptyp (typ_of exp2) annot) + | E_internal_return exp2 -> + let exp2 = add_vars overwrite exp2 vars in + E_aux (E_internal_return exp2,swaptyp (typ_of exp2) annot) + | _ -> + (* after rewrite_defs_letbind_effects there cannot be terms that have + effects/update local variables in "tail-position": check n_exp_term + and where it is used. *) + if overwrite then + match typ_of exp with + | Typ_aux (Typ_id (Id_aux (Id "unit", _)), _) -> vars + | _ -> raise (Reporting_basic.err_unreachable l + "add_vars: trying to overwrite a non-unit expression in tail-position") + else + let typ' = Typ_aux (Typ_tup [typ_of exp;typ_of vars], gen_loc l) in + E_aux (E_tuple [exp;vars],swaptyp typ' annot) in + + let mk_varstup l es = + let exp_to_pat (E_aux (eaux, annot) as exp) = match eaux with + | E_lit lit -> + P_aux (P_lit lit, annot) + | E_id id -> + annot_pat (P_id id) l (env_of exp) (typ_of exp) + | _ -> raise (Reporting_basic.err_unreachable l + ("Failed to extract pattern from expression " ^ string_of_exp exp)) in + match es with + | [] -> + annot_exp (E_lit (mk_lit L_unit)) (gen_loc l) Env.empty unit_typ, + annot_pat P_wild (gen_loc l) Env.empty unit_typ + | [e] -> + let e = infer_exp (env_of e) (strip_exp e) in + e, annot_pat (P_typ (typ_of e, exp_to_pat e)) l (env_of e) (typ_of e) + | e :: _ -> + let infer_e e = infer_exp (env_of e) (strip_exp e) in + let es = List.map infer_e es in + let pats = List.map exp_to_pat es in + let typ = tuple_typ (List.map typ_of es) in + annot_exp (E_tuple es) l (env_of e) typ, + annot_pat (P_typ (typ, annot_pat (P_tup pats) l (env_of e) typ)) l (env_of e) typ in + + let rewrite (E_aux (expaux,((el,_) as annot)) as full_exp) (P_aux (_,(pl,pannot)) as pat) = + let env = env_of_annot annot in + let overwrite = match typ_of full_exp with + | Typ_aux (Typ_id (Id_aux (Id "unit", _)), _) -> true + | _ -> false in + match expaux with + | E_for(id,exp1,exp2,exp3,order,exp4) -> + (* Translate for loops into calls to one of the foreach combinators. + The loop body becomes a function of the loop variable and any + mutable local variables that are updated inside the loop. + Since the foreach* combinators are higher-order functions, + they cannot be represented faithfully in the AST. The following + code abuses the parameters of an E_app node, embedding the loop body + function as an expression followed by the list of variables it + expects. In (Lem) pretty-printing, this turned into an anonymous + function and passed to foreach*. *) + let vars = List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t))) (find_updated_vars exp4) in + let varstuple, varspat = mk_varstup el vars in + let varstyp = typ_of varstuple in + let exp4 = rewrite_var_updates (add_vars overwrite exp4 varstuple) in + let ord_exp, lower, upper = match destruct_range (typ_of exp1), destruct_range (typ_of exp2) with + | None, _ | _, None -> + raise (Reporting_basic.err_unreachable el "Could not determine loop bounds") + | Some (l1, u1), Some (l2, u2) -> + if is_order_inc order + then (annot_exp (E_lit (mk_lit L_true)) el env bool_typ, l1, u2) + else (annot_exp (E_lit (mk_lit L_false)) el env bool_typ, l2, u1) in + let lvar_kid = mk_kid ("loop_" ^ string_of_id id) in + let lvar_nc = nc_and (nc_lteq lower (nvar lvar_kid)) (nc_lteq (nvar lvar_kid) upper) in + let lvar_typ = mk_typ (Typ_exist ([lvar_kid], lvar_nc, atom_typ (nvar lvar_kid))) in + let lvar_pat = P_typ (lvar_typ, annot_pat (P_var ( + annot_pat (P_id id) el env (atom_typ (nvar lvar_kid)), + lvar_kid)) el env lvar_typ) in + let lb = annot_letbind (lvar_pat, exp1) el env lvar_typ in + let body = annot_exp (E_let (lb, exp4)) el env (typ_of exp4) in + let v = annot_exp (E_app (mk_id "foreach", [exp1; exp2; exp3; ord_exp; varstuple; body])) el env (typ_of body) in + let pat = + if overwrite then varspat + else annot_pat (P_tup [pat; varspat]) pl env (typ_of v) in + Added_vars (v,pat) + | E_loop(loop,cond,body) -> + let vars = List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t))) (find_updated_vars body) in + let varstuple, varspat = mk_varstup el vars in + let varstyp = typ_of varstuple in + (* let cond = rewrite_var_updates (add_vars false cond varstuple) in *) + let body = rewrite_var_updates (add_vars overwrite body varstuple) in + let (E_aux (_,(_,bannot))) = body in + let fname = match loop with + | While -> "while" + | Until -> "until" in + let funcl = Id_aux (Id fname,gen_loc el) in + let v = E_aux (E_app (funcl,[cond;varstuple;body]), (gen_loc el, bannot)) in + let pat = + if overwrite then varspat + else annot_pat (P_tup [pat; varspat]) pl env (typ_of v) in + Added_vars (v,pat) + | E_if (c,e1,e2) -> + let vars = List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t))) + (dedup eqidtyp (find_updated_vars e1 @ find_updated_vars e2)) in + if vars = [] then + (Same_vars (E_aux (E_if (c,rewrite_var_updates e1,rewrite_var_updates e2),annot))) + else + let varstuple, varspat = mk_varstup el vars in + let varstyp = typ_of varstuple in + let e1 = rewrite_var_updates (add_vars overwrite e1 varstuple) in + let e2 = rewrite_var_updates (add_vars overwrite e2 varstuple) in + (* after rewrite_defs_letbind_effects c has no variable updates *) + let env = env_of_annot annot in + let typ = typ_of e1 in + let eff = union_eff_exps [e1;e2] in + let v = E_aux (E_if (c,e1,e2), (gen_loc el, Some (env, typ, eff))) in + let pat = + if overwrite then varspat + else annot_pat (P_tup [pat; varspat]) pl env (typ_of v) in + Added_vars (v,pat) + | E_case (e1,ps) -> + (* after rewrite_defs_letbind_effects e1 needs no rewriting *) + let vars = + let f acc (Pat_aux ((Pat_exp (_,e)|Pat_when (_,_,e)),_)) = + acc @ find_updated_vars e in + List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t))) + (dedup eqidtyp (List.fold_left f [] ps)) in + if vars = [] then + let ps = List.map (function + | Pat_aux (Pat_exp (p,e),a) -> + Pat_aux (Pat_exp (p,rewrite_var_updates e),a) + | Pat_aux (Pat_when (p,g,e),a) -> + Pat_aux (Pat_when (p,g,rewrite_var_updates e),a)) ps in + Same_vars (E_aux (E_case (e1,ps),annot)) + else + let varstuple, varspat = mk_varstup el vars in + let varstyp = typ_of varstuple in + let rewrite_pexp (Pat_aux (pexp, (l, _))) = match pexp with + | Pat_exp (pat, exp) -> + let exp = rewrite_var_updates (add_vars overwrite exp varstuple) in + let pannot = (l, Some (env_of exp, typ_of exp, effect_of exp)) in + Pat_aux (Pat_exp (pat, exp), pannot) + | Pat_when _ -> + raise (Reporting_basic.err_unreachable l + "Guarded patterns should have been rewritten already") in + let typ = match ps with + | Pat_aux ((Pat_exp (_,first)|Pat_when (_,_,first)),_) :: _ -> typ_of first + | _ -> unit_typ in + let v = propagate_exp_effect (annot_exp (E_case (e1, List.map rewrite_pexp ps)) pl env typ) in + let pat = + if overwrite then varspat + else annot_pat (P_tup [pat; varspat]) pl env (typ_of v) in + Added_vars (v,pat) + | E_assign (lexp,vexp) -> + let mk_id_pat id = match Env.lookup_id id env with + | Local (_, typ) -> + annot_pat (P_typ (typ, annot_pat (P_id id) pl env typ)) pl env typ + | _ -> + raise (Reporting_basic.err_unreachable pl + ("Failed to look up type of variable " ^ string_of_id id)) in + if effectful exp then + Same_vars (E_aux (E_assign (lexp,vexp),annot)) + else + (match lexp with + | LEXP_aux (LEXP_id id,annot) -> + let pat = annot_pat (P_id id) pl env (typ_of vexp) in + Added_vars (vexp, mk_id_pat id) + | LEXP_aux (LEXP_cast (typ,id),annot) -> + let pat = annot_pat (P_typ (typ, annot_pat (P_id id) pl env (typ_of vexp))) pl env typ in + Added_vars (vexp,pat) + | LEXP_aux (LEXP_vector (LEXP_aux (LEXP_id id,((l2,_) as annot2)),i),((l1,_) as annot)) -> + let eid = annot_exp (E_id id) l2 env (typ_of_annot annot2) in + let vexp = annot_exp (E_vector_update (eid,i,vexp)) l1 env (typ_of_annot annot) in + let pat = annot_pat (P_id id) pl env (typ_of vexp) in + Added_vars (vexp,pat) + | LEXP_aux (LEXP_vector_range (LEXP_aux (LEXP_id id,((l2,_) as annot2)),i,j), + ((l,_) as annot)) -> + let eid = annot_exp (E_id id) l2 env (typ_of_annot annot2) in + let vexp = annot_exp (E_vector_update_subrange (eid,i,j,vexp)) l env (typ_of_annot annot) in + let pat = annot_pat (P_id id) pl env (typ_of vexp) in + Added_vars (vexp,pat) + | _ -> Same_vars (E_aux (E_assign (lexp,vexp),annot))) + | _ -> + (* after rewrite_defs_letbind_effects this expression is pure and updates + no variables: check n_exp_term and where it's used. *) + Same_vars (E_aux (expaux,annot)) in + + match expaux with + | E_let (lb,body) -> + let body = rewrite_var_updates body in + let (LB_aux (LB_val (pat, v), lbannot)) = lb in + let lb = match rewrite v pat with + | Added_vars (v, P_aux (pat, _)) -> + annot_letbind (pat, v) (get_loc_exp v) env (typ_of v) + | Same_vars v -> LB_aux (LB_val (pat, v),lbannot) in + propagate_exp_effect (annot_exp (E_let (lb, body)) l env (typ_of body)) + | E_internal_let (lexp,v,body) -> + (* Rewrite E_internal_let into E_let and call recursively *) + let paux, typ = match lexp with + | LEXP_aux (LEXP_id id, _) -> + P_id id, typ_of v + | LEXP_aux (LEXP_cast (typ, id), _) -> + P_typ (typ, annot_pat (P_id id) l env (typ_of v)), typ + | _ -> + raise (Reporting_basic.err_unreachable l + "E_internal_let with a lexp that is not a variable") in + let lb = annot_letbind (paux, v) l env typ in + let exp = propagate_exp_effect (annot_exp (E_let (lb, body)) l env (typ_of body)) in + rewrite_var_updates exp + | E_internal_plet (pat,v,body) -> + failwith "rewrite_var_updates: E_internal_plet shouldn't be introduced yet" + (* There are no expressions that have effects or variable updates in + "tail-position": check the definition nexp_term and where it is used. *) + | _ -> exp + +let replace_memwrite_e_assign exp = + let e_aux = fun (expaux,annot) -> + match expaux with + | E_assign (LEXP_aux (LEXP_memory (id,args),_),v) -> E_aux (E_app (id,args @ [v]),annot) + | _ -> E_aux (expaux,annot) in + fold_exp { id_exp_alg with e_aux = e_aux } exp + + + +let remove_reference_types exp = + + let rec rewrite_t (Typ_aux (t_aux,a)) = (Typ_aux (rewrite_t_aux t_aux,a)) + and rewrite_t_aux t_aux = match t_aux with + | Typ_app (Id_aux (Id "reg",_), [Typ_arg_aux (Typ_arg_typ (Typ_aux (t_aux2, _)), _)]) -> + rewrite_t_aux t_aux2 + | Typ_app (name,t_args) -> Typ_app (name,List.map rewrite_t_arg t_args) + | Typ_fn (t1,t2,eff) -> Typ_fn (rewrite_t t1,rewrite_t t2,eff) + | Typ_tup ts -> Typ_tup (List.map rewrite_t ts) + | _ -> t_aux + and rewrite_t_arg t_arg = match t_arg with + | Typ_arg_aux (Typ_arg_typ t, a) -> Typ_arg_aux (Typ_arg_typ (rewrite_t t), a) + | _ -> t_arg in + + let rec rewrite_annot = function + | (l, None) -> (l, None) + | (l, Some (env, typ, eff)) -> (l, Some (env, rewrite_t typ, eff)) in + + map_exp_annot rewrite_annot exp + + + +let rewrite_defs_remove_superfluous_letbinds = + + let e_aux (exp,annot) = match exp with + | E_let (lb,exp2) -> + begin match lb,exp2 with + (* 'let x = EXP1 in x' can be replaced with 'EXP1' *) + | LB_aux (LB_val (P_aux (P_id id, _), exp1), _), + E_aux (E_id id', _) + | LB_aux (LB_val (P_aux (P_id id, _), exp1), _), + E_aux (E_cast (_,E_aux (E_id id', _)), _) + when Id.compare id id' == 0 && id_is_unbound id (env_of_annot annot) -> + exp1 + (* "let x = EXP1 in return x" can be replaced with 'return (EXP1)', at + least when EXP1 is 'small' enough *) + | LB_aux (LB_val (P_aux (P_id id, _), exp1), _), + E_aux (E_internal_return (E_aux (E_id id', _)), _) + when Id.compare id id' == 0 && small exp1 && id_is_unbound id (env_of_annot annot) -> + let (E_aux (_,e1annot)) = exp1 in + E_aux (E_internal_return (exp1),e1annot) + | _ -> E_aux (exp,annot) + end + | _ -> E_aux (exp,annot) in + + let alg = { id_exp_alg with e_aux = e_aux } in + rewrite_defs_base + { rewrite_exp = (fun _ -> fold_exp alg) + ; rewrite_pat = rewrite_pat + ; rewrite_let = rewrite_let + ; rewrite_lexp = rewrite_lexp + ; rewrite_fun = rewrite_fun + ; rewrite_def = rewrite_def + ; rewrite_defs = rewrite_defs_base + } + + +let rewrite_defs_remove_superfluous_returns = + + let has_unittype e = match typ_of e with + | Typ_aux (Typ_id (Id_aux (Id "unit", _)), _) -> true + | _ -> false in + + let untyp_pat = function + | P_aux (P_typ (typ, pat), _) -> pat, Some typ + | pat -> pat, None in + + let uncast_internal_return = function + | E_aux (E_internal_return (E_aux (E_cast (typ, exp), _)), a) -> + E_aux (E_internal_return exp, a), Some typ + | exp -> exp, None in + + let e_aux (exp,annot) = match exp with + | E_let (LB_aux (LB_val (pat, exp1), _), exp2) + | E_internal_plet (pat, exp1, exp2) + when effectful exp1 -> + begin match untyp_pat pat, uncast_internal_return exp2 with + | (P_aux (P_lit (L_aux (lit,_)),_), ptyp), + (E_aux (E_internal_return (E_aux (E_lit (L_aux (lit',_)),_)), a), etyp) + when lit = lit' -> + begin + match ptyp, etyp with + | Some typ, _ | _, Some typ -> E_aux (E_cast (typ, exp1), a) + | None, None -> exp1 + end + | (P_aux (P_wild,pannot), ptyp), + (E_aux (E_internal_return (E_aux (E_lit (L_aux (L_unit,_)),_)), a), etyp) + when has_unittype exp1 -> + begin + match ptyp, etyp with + | Some typ, _ | _, Some typ -> E_aux (E_cast (typ, exp1), a) + | None, None -> exp1 + end + | (P_aux (P_id id,_), ptyp), + (E_aux (E_internal_return (E_aux (E_id id',_)), a), etyp) + when Id.compare id id' == 0 && id_is_unbound id (env_of_annot annot) -> + begin + match ptyp, etyp with + | Some typ, _ | _, Some typ -> E_aux (E_cast (typ, exp1), a) + | None, None -> exp1 + end + | _ -> E_aux (exp,annot) + end + | _ -> E_aux (exp,annot) in + + let alg = { id_exp_alg with e_aux = e_aux } in + rewrite_defs_base + { rewrite_exp = (fun _ -> fold_exp alg) + ; rewrite_pat = rewrite_pat + ; rewrite_let = rewrite_let + ; rewrite_lexp = rewrite_lexp + ; rewrite_fun = rewrite_fun + ; rewrite_def = rewrite_def + ; rewrite_defs = rewrite_defs_base + } + + +let rewrite_defs_remove_e_assign (Defs defs) = + let (Defs loop_specs) = fst (check Env.empty (Defs (List.map gen_vs + [("foreach", "forall ('vars : Type). (int, int, int, bool, 'vars, 'vars) -> 'vars"); + ("while", "forall ('vars : Type). (bool, 'vars, 'vars) -> 'vars"); + ("until", "forall ('vars : Type). (bool, 'vars, 'vars) -> 'vars")]))) in + let rewrite_exp _ e = + replace_memwrite_e_assign (remove_reference_types (rewrite_var_updates e)) in + rewrite_defs_base + { rewrite_exp = rewrite_exp + ; rewrite_pat = rewrite_pat + ; rewrite_let = rewrite_let + ; rewrite_lexp = rewrite_lexp + ; rewrite_fun = rewrite_fun + ; rewrite_def = rewrite_def + ; rewrite_defs = rewrite_defs_base + } (Defs (loop_specs @ defs)) + +let recheck_defs defs = fst (check initial_env defs) + +let rewrite_defs_lem = [ + ("tuple_vector_assignments", rewrite_tuple_vector_assignments); + ("tuple_assignments", rewrite_tuple_assignments); + (* ("simple_assignments", rewrite_simple_assignments); *) + ("remove_vector_concat", rewrite_defs_remove_vector_concat); + ("remove_bitvector_pats", rewrite_defs_remove_bitvector_pats); + ("guarded_pats", rewrite_defs_guarded_pats); + ("exp_lift_assign", rewrite_defs_exp_lift_assign); + ("register_ref_writes", rewrite_register_ref_writes); + ("recheck_defs", recheck_defs); + (* ("constraint", rewrite_constraint); *) + (* ("remove_assert", rewrite_defs_remove_assert); *) + ("top_sort_defs", top_sort_defs); + ("trivial_sizeof", rewrite_trivial_sizeof); + ("sizeof", rewrite_sizeof); + ("early_return", rewrite_defs_early_return); + ("nexp_ids", rewrite_defs_nexp_ids); + ("fix_val_specs", rewrite_fix_val_specs); + ("remove_blocks", rewrite_defs_remove_blocks); + ("letbind_effects", rewrite_defs_letbind_effects); + ("remove_e_assign", rewrite_defs_remove_e_assign); + ("internal_lets", rewrite_defs_internal_lets); + ("remove_superfluous_letbinds", rewrite_defs_remove_superfluous_letbinds); + ("remove_superfluous_returns", rewrite_defs_remove_superfluous_returns); + ("recheck_defs", recheck_defs) + ] + +let rewrite_defs_ocaml = [ + (* ("top_sort_defs", top_sort_defs); *) + (* ("undefined", rewrite_undefined); *) + ("tuple_vector_assignments", rewrite_tuple_vector_assignments); + ("tuple_assignments", rewrite_tuple_assignments); + ("simple_assignments", rewrite_simple_assignments); + ("remove_vector_concat", rewrite_defs_remove_vector_concat); + ("constraint", rewrite_constraint); + ("trivial_sizeof", rewrite_trivial_sizeof); + ("sizeof", rewrite_sizeof); + ("simple_types", rewrite_simple_types); + ("overload_cast", rewrite_overload_cast); + ("exp_lift_assign", rewrite_defs_exp_lift_assign); + (* ("separate_numbs", rewrite_defs_separate_numbs) *) + ] + +let rewrite_defs_sil = [ + ("top_sort_defs", top_sort_defs); + ("tuple_vector_assignments", rewrite_tuple_vector_assignments); + ("tuple_assignments", rewrite_tuple_assignments); + ("simple_assignments", rewrite_simple_assignments); + ("constraint", rewrite_constraint); + ("trivial_sizeof", rewrite_trivial_sizeof); + ("sizeof", rewrite_sizeof); + ("remove_vector_concat", rewrite_defs_remove_vector_concat); + ("remove_bitvector_pats", rewrite_defs_remove_bitvector_pats); + ] + +let rewrite_check_annot = + let check_annot exp = + try + prerr_endline ("CHECKING: " ^ string_of_exp exp ^ " : " ^ string_of_typ (typ_of exp)); + let _ = check_exp (env_of exp) (strip_exp exp) (typ_of exp) in + (if not (alpha_equivalent (env_of exp) (typ_of exp) (Env.expand_synonyms (env_of exp) (typ_of exp))) + then raise (Reporting_basic.err_typ Parse_ast.Unknown "Found synonym in annotation") + else ()); + exp + with + Type_error (l, err) -> raise (Reporting_basic.err_typ l (string_of_type_error err)) + in + let rewrite_exp = { id_exp_alg with e_aux = (fun (exp, annot) -> check_annot (E_aux (exp, annot))) } in + rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp rewrite_exp) } + +let rewrite_defs_check = [ + ("check_annotations", rewrite_check_annot); + ] diff --git a/src/rewrites.mli b/src/rewrites.mli new file mode 100644 index 00000000..ce24a4c4 --- /dev/null +++ b/src/rewrites.mli @@ -0,0 +1,70 @@ +(**************************************************************************) +(* Sail *) +(* *) +(* Copyright (c) 2013-2017 *) +(* 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 *) +(* *) +(* All rights reserved. *) +(* *) +(* This software was developed by the University of Cambridge Computer *) +(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *) +(* (REMS) project, funded by EPSRC grant EP/K008528/1. *) +(* *) +(* 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. *) +(**************************************************************************) + +open Ast +open Type_check + +(* Re-write undefined to functions created by -undefined_gen flag *) +val rewrite_undefined : bool -> tannot defs -> tannot defs + +(* Perform rewrites to exclude AST nodes not supported for ocaml out*) +val rewrite_defs_ocaml : (string * (tannot defs -> tannot defs)) list + +(* Perform rewrites to exclude AST nodes not supported for lem out*) +val rewrite_defs_lem : (string * (tannot defs -> tannot defs)) list + +(* Perform rewrites to sail intermediate language *) +val rewrite_defs_sil : (string * (tannot defs -> tannot defs)) list + +(* This is a special rewriter pass that checks AST invariants without + actually doing any re-writing *) +val rewrite_defs_check : (string * (tannot defs -> tannot defs)) list + +val simple_typ : typ -> typ diff --git a/src/sail.ml b/src/sail.ml index e7e965ba..aecbcbec 100644 --- a/src/sail.ml +++ b/src/sail.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -49,6 +57,7 @@ let opt_print_initial_env = ref false let opt_print_verbose = ref false let opt_print_lem_ast = ref false let opt_print_lem = ref false +let opt_print_sil = ref false let opt_print_ocaml = ref false let opt_convert = ref false let opt_memo_z3 = ref false @@ -74,6 +83,9 @@ let options = Arg.align ([ ( "-lem_ast", Arg.Set opt_print_lem_ast, " output a Lem AST representation of the input"); + ( "-sil", + Arg.Tuple [Arg.Set opt_print_sil; Arg.Set Initial_check.opt_undefined_gen], + " output a SIL translated version of the input"); ( "-lem", Arg.Set opt_print_lem, " output a Lem translated version of the input"); @@ -138,6 +150,9 @@ let options = Arg.align ([ ( "-dsanity", Arg.Set opt_sanity, " (debug) sanity check the AST (slow)"); + ( "-dmagic_hash", + Arg.Set Initial_check.opt_magic_hash, + " (debug) allow special character # in identifiers"); ( "-v", Arg.Set opt_print_version, " print version"); @@ -204,6 +219,11 @@ let main() = (if !(opt_print_lem_ast) then output "" Lem_ast_out [out_name,ast] else ()); + (if !(opt_print_sil) + then + let ast = rewrite_ast_sil ast in + Pretty_print_sail2.pp_defs stdout ast + else ()); (if !(opt_print_ocaml) then let ast_ocaml = rewrite_ast_ocaml ast in diff --git a/src/spec_analysis.ml b/src/spec_analysis.ml index 424481b5..078fc647 100644 --- a/src/spec_analysis.ml +++ b/src/spec_analysis.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/spec_analysis.mli b/src/spec_analysis.mli index 6295a7ec..f13dd596 100644 --- a/src/spec_analysis.mli +++ b/src/spec_analysis.mli @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/type_check.ml b/src/type_check.ml index 1782a11b..2cfba5fd 100644 --- a/src/type_check.ml +++ b/src/type_check.ml @@ -10,6 +10,13 @@ (* Christopher Pulte *) (* Peter Sewell *) (* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -371,7 +378,7 @@ end = struct default_order : order option; ret_typ : typ option; poly_undefineds : bool; - prove : t -> n_constraint -> bool + prove : t -> n_constraint -> bool; } let empty = @@ -397,7 +404,7 @@ end = struct default_order = None; ret_typ = None; poly_undefineds = false; - prove = (fun _ _ -> false) + prove = (fun _ _ -> false); } let add_prover f env = { env with prove = f } @@ -928,7 +935,6 @@ end = struct { env with poly_undefineds = true } let polymorphic_undefineds env = env.poly_undefineds - end @@ -1982,7 +1988,10 @@ let rec check_exp env (E_aux (exp_aux, (l, ())) as exp : unit exp) (Typ_aux (typ match (exp_aux, typ_aux) with | E_block exps, _ -> begin - let rec check_block l env exps typ = match exps with + let rec check_block l env exps typ = + let annot_exp_effect exp typ eff = E_aux (exp, (l, Some (env, typ, eff))) in + let annot_exp exp typ = annot_exp_effect exp typ no_effect in + match exps with | [] -> typ_equality l env typ unit_typ; [] | [exp] -> [crule check_exp env exp typ] | (E_aux (E_assign (lexp, bind), _) :: exps) -> diff --git a/src/type_check.mli b/src/type_check.mli index 5ed55843..a4537750 100644 --- a/src/type_check.mli +++ b/src/type_check.mli @@ -10,6 +10,13 @@ (* Christopher Pulte *) (* Peter Sewell *) (* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) @@ -233,6 +240,8 @@ val string_of_uvar : uvar -> string val unify : l -> Env.t -> typ -> typ -> uvar KBindings.t * kid list * n_constraint option +val alpha_equivalent : Env.t -> typ -> typ -> bool + (* Throws Invalid_argument if the argument is not a E_app expression *) val instantiation_of : tannot exp -> uvar KBindings.t diff --git a/src/util.ml b/src/util.ml index 4f7878c7..6f7d6a95 100644 --- a/src/util.ml +++ b/src/util.ml @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/src/util.mli b/src/util.mli index ac87cab8..73dbd30b 100644 --- a/src/util.mli +++ b/src/util.mli @@ -9,6 +9,14 @@ (* Robert Norton-Wright *) (* Christopher Pulte *) (* Peter Sewell *) +(* Alasdair Armstrong *) +(* Brian Campbell *) +(* Thomas Bauereiss *) +(* Anthony Fox *) +(* Jon French *) +(* Dominic Mulligan *) +(* Stephen Kell *) +(* Mark Wassell *) (* *) (* All rights reserved. *) (* *) diff --git a/test/ocaml/short_circuit/expect b/test/ocaml/short_circuit/expect new file mode 100644 index 00000000..9766475a --- /dev/null +++ b/test/ocaml/short_circuit/expect @@ -0,0 +1 @@ +ok diff --git a/test/ocaml/short_circuit/sc.sail b/test/ocaml/short_circuit/sc.sail new file mode 100644 index 00000000..a0f4941d --- /dev/null +++ b/test/ocaml/short_circuit/sc.sail @@ -0,0 +1,15 @@ + +val fail : unit -> bool effect {escape} + +function fail () = { + assert(false); + true +} + +val main : unit -> unit effect {escape} + +function main () = { + assert(~(false & fail())); + assert(true | fail()); + print("ok") +}
\ No newline at end of file diff --git a/test/typecheck/run_tests.sh b/test/typecheck/run_tests.sh index 48cf070b..a2567d21 100755 --- a/test/typecheck/run_tests.sh +++ b/test/typecheck/run_tests.sh @@ -62,7 +62,7 @@ for i in `ls $DIR/pass/`; do if $SAILDIR/sail -ddump_tc_ast -dsanity $DIR/pass/$i 2> /dev/null 1> $DIR/rtpass/$i; then - if $SAILDIR/sail -ddump_tc_ast -dno_cast -dsanity $DIR/rtpass/$i 2> /dev/null 1> $DIR/rtpass2/$i; + if $SAILDIR/sail -ddump_tc_ast -dmagic_hash -dno_cast -dsanity $DIR/rtpass/$i 2> /dev/null 1> $DIR/rtpass2/$i; then if diff $DIR/rtpass/$i $DIR/rtpass2/$i; then @@ -86,7 +86,7 @@ do then red "tested $i expecting fail" "pass" else - if $SAILDIR/sail -dno_cast -just_check $DIR/rtfail/$i 2> /dev/null; + if $SAILDIR/sail -dno_cast -dmagic_hash -just_check $DIR/rtfail/$i 2> /dev/null; then yellow "tested $i expecting fail" "passed re-check" else diff --git a/x86/Makefile b/x86/Makefile new file mode 100644 index 00000000..6863714d --- /dev/null +++ b/x86/Makefile @@ -0,0 +1,20 @@ +SAIL=../src/sail.native +LEM:=../../lem/lem + +SOURCES=../etc/regfp.sail x64.sail + +all: x86.lem x86.ml x86_embed.lem + +x86.lem: + $(SAIL) -lem_ast -o x86 $(SOURCES) + +x86.ml: x86.lem ../src/lem_interp/interp_ast.lem + $(LEM) -ocaml -lib ../src/lem_interp/ $< + +x86_embed.lem: $(SOURCES) +# also generates x86_embed_sequential.lem, x86_embed_types.lem, x86_toFromInterp.lem + $(SAIL) -lem -lem_lib X86_extras_embed -o x86 $(SOURCES) + +clean: + rm -f x86.lem x86.ml + rm -f x86_embed*.lem x86_toFromInterp.lem diff --git a/x86/gen/ast.hgen b/x86/gen/ast.hgen new file mode 100644 index 00000000..83488eda --- /dev/null +++ b/x86/gen/ast.hgen @@ -0,0 +1,26 @@ +| `X86BINOP of bool * x86Binop * x86Size * x86Dest_src +| `X86BITOP of bool * x86Bitop * x86Size * x86Bit_offset +| `X86CALL of x86Imm_rm +| `X86CLC +| `X86CMC +| `X86CMPXCHG of bool * x86Size * x86Rm * reg +| `X86DIV of x86Size * x86Rm +| `X86JCC of x86Cond * bit64 +| `X86JMP of x86Rm +| `X86LEA of x86Size * x86Dest_src +| `X86LEAVE +| `X86LOOP of x86Cond * bit64 +| `X86MFENCE +| `X86MONOP of bool * x86Monop * x86Size * x86Rm +| `X86MOV of x86Cond * x86Size * x86Dest_src +| `X86MOVSX of x86Size * x86Dest_src * x86Size +| `X86MOVZX of x86Size * x86Dest_src * x86Size +| `X86MUL of x86Size * x86Rm +| `X86NOP +| `X86POP of x86Rm +| `X86PUSH of x86Imm_rm +| `X86RET of bit64 +| `X86SET of x86Cond * bool * x86Rm +| `X86STC +| `X86XADD of bool * x86Size * x86Rm * reg +| `X86XCHG of bool * x86Size * x86Rm * reg diff --git a/x86/gen/fold.hgen b/x86/gen/fold.hgen new file mode 100644 index 00000000..df546a13 --- /dev/null +++ b/x86/gen/fold.hgen @@ -0,0 +1,26 @@ +| `X86BINOP (_, _, _, ds) -> fold_dest_src ds c +| `X86BITOP (_, _, _, bo) -> fold_bit_offset bo c +| `X86CALL irm -> fold_imm_rm irm c +| `X86CLC -> c +| `X86CMC -> c +| `X86CMPXCHG (_, _, rm, r) -> fold_rm rm (fold_reg r c) +| `X86DIV (_, rm) -> fold_rm rm c +| `X86JCC _ -> c +| `X86JMP rm -> fold_rm rm c +| `X86LEA (_, ds) -> fold_dest_src ds c +| `X86LEAVE -> c +| `X86LOOP _ -> c +| `X86MFENCE -> c +| `X86MONOP (_, _, _, rm) -> fold_rm rm c +| `X86MOV (_, _, ds) -> fold_dest_src ds c +| `X86MOVSX (_, ds, _) -> fold_dest_src ds c +| `X86MOVZX (_, ds, _) -> fold_dest_src ds c +| `X86MUL (_, rm) -> fold_rm rm c +| `X86NOP -> c +| `X86POP rm -> fold_rm rm c +| `X86PUSH irm -> fold_imm_rm irm c +| `X86RET _ -> c +| `X86SET (_, _, rm) -> fold_rm rm c +| `X86STC -> c +| `X86XADD (_, _, rm, r) -> fold_rm rm (fold_reg r c) +| `X86XCHG (_, _, rm, r) -> fold_rm rm (fold_reg r c) diff --git a/x86/gen/herdtools_ast_to_shallow_ast.hgen b/x86/gen/herdtools_ast_to_shallow_ast.hgen new file mode 100644 index 00000000..c709ee6c --- /dev/null +++ b/x86/gen/herdtools_ast_to_shallow_ast.hgen @@ -0,0 +1,28 @@ +| `X86BINOP(locked, binop, sz, dest_src) -> Binop (translate_bool locked, translate_binop binop, translate_size sz, translate_dest_src dest_src) +| `X86BITOP(locked, op, sz, bo) -> Bitop (translate_bool locked, translate_bitop op, translate_size sz, translate_bitoffset bo) +| `X86CALL (imm_rm) -> CALL (translate_imm_rm imm_rm) +| `X86CLC -> CLC +| `X86CMC -> CMC +| `X86CMPXCHG (locked, sz, rm , reg) -> CMPXCHG (translate_bool locked, translate_size sz, translate_rm rm, translate_reg reg) +| `X86DIV (sz, rm) -> X86_DIV (translate_size sz, translate_rm rm) +| `X86StopFetching -> HLT +| `X86JCC (cond, imm64) -> Jcc (translate_cond cond, translate_imm64 imm64) +| `X86JMP (rm) -> JMP (translate_rm rm) +| `X86LEA (sz, dest_src) -> LEA (translate_size sz, translate_dest_src dest_src) +| `X86LEAVE -> LEAVE +| `X86LOOP (cond, imm64) -> LOOP (translate_cond cond, translate_imm64 imm64) +| `X86MFENCE -> MFENCE +| `X86MONOP (locked, monop, sz, rm) -> Monop (translate_bool locked, translate_monop monop, translate_size sz, translate_rm rm) +| `X86MOV (cond, sz, dest_src) -> MOV (translate_cond cond, translate_size sz, translate_dest_src dest_src) +| `X86MOVSX (sz1, dest_src, sz2) -> MOVSX (translate_size sz1, translate_dest_src dest_src, translate_size sz2) +| `X86MOVZX (sz1, dest_src, sz2) -> MOVZX (translate_size sz1, translate_dest_src dest_src, translate_size sz2) +| `X86MUL (sz, rm) -> X86_MUL (translate_size sz, translate_rm rm) +| `X86NOP -> NOP (Nat_big_num.of_int 0) +| `X86POP (rm) -> POP (translate_rm rm) +| `X86PUSH (imm_rm) -> PUSH (translate_imm_rm imm_rm) +| `X86RET (imm64) -> RET (translate_imm64 imm64) +| `X86SET (cond, b, rm) -> SET (translate_cond cond, translate_bool b, translate_rm rm) +| `X86STC -> STC +| `X86XADD (locked, sz, rm, reg) -> XADD (translate_bool locked, translate_size sz, translate_rm rm, translate_reg reg) +| `X86XCHG (locked, sz, rm, reg) -> XCHG (translate_bool locked, translate_size sz, translate_rm rm, translate_reg reg) + diff --git a/x86/gen/herdtools_types_to_shallow_types.hgen b/x86/gen/herdtools_types_to_shallow_types.hgen new file mode 100644 index 00000000..44e16991 --- /dev/null +++ b/x86/gen/herdtools_types_to_shallow_types.hgen @@ -0,0 +1,93 @@ +let is_inc = false + +let translate_bool = function + | true -> Sail_values.B1 + | false -> Sail_values.B0 + +let translate_binop = function + | X86ADD -> X86_Add + | X86OR -> X86_Or + | X86ADC -> X86_Adc + | X86SBB -> X86_Sbb + | X86AND -> X86_And + | X86SUB -> X86_Sub + | X86XOR -> X86_Xor + | X86CMP -> X86_Cmp + | X86ROL -> X86_Rol + | X86ROR -> X86_Ror + | X86RCL -> X86_Rcl + | X86RCR -> X86_Rcr + | X86SHL -> X86_Shl + | X86SHR -> X86_Shr + | X86TEST -> X86_Test + | X86SAR -> X86_Sar + +let translate_bitop = function + | X86Btc -> Btc + | X86Bts -> Bts + | X86Btr -> Btr + +let translate_size = function + | X86S8(high) -> Sz8 (translate_bool high) + | X86S16 -> Sz16 + | X86S32 -> Sz32 + | X86S64 -> Sz64 + +let translate_reg r = Nat_big_num.of_int (reg_to_int r) + +let translate_scale s = + Sail_values.to_vec0 is_inc (Nat_big_num.of_int 2, Nat_big_num.of_int s) + +let translate_imm64 i = Sail_values.to_vec0 is_inc (Nat_big_num.of_int 64, i) + +let translate_msi = function + | Some (scale, reg) -> Some (translate_scale scale, translate_reg reg) + | None -> None + +let translate_base = function + | X86HGenBase.NoBase -> X86_embed_types.NoBase + | X86HGenBase.RegBase(r) -> X86_embed_types.RegBase (translate_reg r) + | X86HGenBase.RipBase -> X86_embed_types.RipBase + +let translate_rm = function + | X86HGenBase.Reg (r) -> X86_embed_types.X86_Reg (translate_reg r) + | X86HGenBase.Mem (m_si, base, imm) -> X86_embed_types.Mem (translate_msi m_si, translate_base base, translate_imm64 imm) + | X86HGenBase.Sym (s) -> X86_embed_types.Mem (None, X86_embed_types.NoBase, translate_imm64 Nat_big_num.zero) + +let translate_dest_src = function + | X86HGenBase.R_rm (reg, rm) -> X86_embed_types.R_rm (translate_reg reg, translate_rm rm) + | X86HGenBase.Rm_i (rm, imm64) -> X86_embed_types.Rm_i (translate_rm rm, translate_imm64 imm64) + | X86HGenBase.Rm_r (rm, reg) -> X86_embed_types.Rm_r (translate_rm rm, translate_reg reg) + +let translate_imm_rm = function + | X86HGenBase.Imm (imm) -> X86_embed_types.Imm (translate_imm64 imm) + | X86HGenBase.Rm (rm) -> X86_embed_types.Rm (translate_rm rm) + +let translate_bitoffset = function + | X86HGenBase.Bit_rm_imm (rm, imm) -> Bit_rm_imm (translate_rm rm, translate_imm64 (Nat_big_num.of_int imm)) + | X86HGenBase.Bit_rm_r (rm, r) -> Bit_rm_r (translate_rm rm, translate_reg r) + +let translate_cond = function + | X86O -> X86_O + | X86NO -> X86_NO + | X86B -> X86_B + | X86NB -> X86_NB + | X86E -> X86_E + | X86NE -> X86_NE + | X86NA -> X86_NA + | X86A -> X86_A + | X86S -> X86_S + | X86NS -> X86_NS + | X86P -> X86_P + | X86NP -> X86_NP + | X86L -> X86_L + | X86NL -> X86_NL + | X86NG -> X86_NG + | X86G -> X86_G + | X86ALWAYS -> X86_ALWAYS + +let translate_monop = function + | X86DEC -> X86_Dec + | X86INC -> X86_Inc + | X86NOT -> X86_Not + | X86NEG -> X86_Neg diff --git a/x86/gen/lexer.hgen b/x86/gen/lexer.hgen new file mode 100644 index 00000000..56944e6d --- /dev/null +++ b/x86/gen/lexer.hgen @@ -0,0 +1,399 @@ +"addb" , BINOP { txt = "ADDB"; op = X86ADD; sz = X86BYTE }; +"orb" , BINOP { txt = "ORB"; op = X86OR; sz = X86BYTE }; +"adcb" , BINOP { txt = "ADCB"; op = X86ADC; sz = X86BYTE }; +"sbbb" , BINOP { txt = "SBBB"; op = X86SBB; sz = X86BYTE }; +"andb" , BINOP { txt = "ANDB"; op = X86AND; sz = X86BYTE }; +"subb" , BINOP { txt = "SUBB"; op = X86SUB; sz = X86BYTE }; +"xorb" , BINOP { txt = "XORB"; op = X86XOR; sz = X86BYTE }; +"cmpb" , BINOP { txt = "CMPB"; op = X86CMP; sz = X86BYTE }; +"rolb" , BINOP { txt = "ROLB"; op = X86ROL; sz = X86BYTE }; +"rorb" , BINOP { txt = "RORB"; op = X86ROR; sz = X86BYTE }; +"shlb" , BINOP { txt = "SHLB"; op = X86SHL; sz = X86BYTE }; +"shrb" , BINOP { txt = "SHRB"; op = X86SHR; sz = X86BYTE }; +"testb" , BINOP { txt = "TESTB"; op = X86TEST; sz = X86BYTE }; +"sarb" , BINOP { txt = "SARB"; op = X86SAR; sz = X86BYTE }; +"addw" , BINOP { txt = "ADDW"; op = X86ADD; sz = X86WORD }; +"orw" , BINOP { txt = "ORW"; op = X86OR; sz = X86WORD }; +"adcw" , BINOP { txt = "ADCW"; op = X86ADC; sz = X86WORD }; +"sbbw" , BINOP { txt = "SBBW"; op = X86SBB; sz = X86WORD }; +"andw" , BINOP { txt = "ANDW"; op = X86AND; sz = X86WORD }; +"subw" , BINOP { txt = "SUBW"; op = X86SUB; sz = X86WORD }; +"xorw" , BINOP { txt = "XORW"; op = X86XOR; sz = X86WORD }; +"cmpw" , BINOP { txt = "CMPW"; op = X86CMP; sz = X86WORD }; +"rolw" , BINOP { txt = "ROLW"; op = X86ROL; sz = X86WORD }; +"rorw" , BINOP { txt = "RORW"; op = X86ROR; sz = X86WORD }; +"shlw" , BINOP { txt = "SHLW"; op = X86SHL; sz = X86WORD }; +"shrw" , BINOP { txt = "SHRW"; op = X86SHR; sz = X86WORD }; +"testw" , BINOP { txt = "TESTW"; op = X86TEST; sz = X86WORD }; +"sarw" , BINOP { txt = "SARW"; op = X86SAR; sz = X86WORD }; +"addl" , BINOP { txt = "ADDL"; op = X86ADD; sz = X86LONG }; +"orl" , BINOP { txt = "ORL"; op = X86OR; sz = X86LONG }; +"adcl" , BINOP { txt = "ADCL"; op = X86ADC; sz = X86LONG }; +"sbbl" , BINOP { txt = "SBBL"; op = X86SBB; sz = X86LONG }; +"andl" , BINOP { txt = "ANDL"; op = X86AND; sz = X86LONG }; +"subl" , BINOP { txt = "SUBL"; op = X86SUB; sz = X86LONG }; +"xorl" , BINOP { txt = "XORL"; op = X86XOR; sz = X86LONG }; +"cmpl" , BINOP { txt = "CMPL"; op = X86CMP; sz = X86LONG }; +"roll" , BINOP { txt = "ROLL"; op = X86ROL; sz = X86LONG }; +"rorl" , BINOP { txt = "RORL"; op = X86ROR; sz = X86LONG }; +"shll" , BINOP { txt = "SHLL"; op = X86SHL; sz = X86LONG }; +"shrl" , BINOP { txt = "SHRL"; op = X86SHR; sz = X86LONG }; +"testl" , BINOP { txt = "TESTL"; op = X86TEST; sz = X86LONG }; +"sarl" , BINOP { txt = "SARL"; op = X86SAR; sz = X86LONG }; +"addq" , BINOP { txt = "ADDQ"; op = X86ADD; sz = X86QUAD }; +"orq" , BINOP { txt = "ORQ"; op = X86OR; sz = X86QUAD }; +"adcq" , BINOP { txt = "ADCQ"; op = X86ADC; sz = X86QUAD }; +"sbbq" , BINOP { txt = "SBBQ"; op = X86SBB; sz = X86QUAD }; +"andq" , BINOP { txt = "ANDQ"; op = X86AND; sz = X86QUAD }; +"subq" , BINOP { txt = "SUBQ"; op = X86SUB; sz = X86QUAD }; +"xorq" , BINOP { txt = "XORQ"; op = X86XOR; sz = X86QUAD }; +"cmpq" , BINOP { txt = "CMPQ"; op = X86CMP; sz = X86QUAD }; +"rolq" , BINOP { txt = "ROLQ"; op = X86ROL; sz = X86QUAD }; +"rorq" , BINOP { txt = "RORQ"; op = X86ROR; sz = X86QUAD }; +"shlq" , BINOP { txt = "SHLQ"; op = X86SHL; sz = X86QUAD }; +"shrq" , BINOP { txt = "SHRQ"; op = X86SHR; sz = X86QUAD }; +"testq" , BINOP { txt = "TESTQ"; op = X86TEST; sz = X86QUAD }; +"sarq" , BINOP { txt = "SARQ"; op = X86SAR; sz = X86QUAD }; +"add" , BINOP { txt = "ADDQ"; op = X86ADD; sz = X86NONE }; +"or" , BINOP { txt = "OR"; op = X86OR; sz = X86NONE }; +"adc" , BINOP { txt = "ADC"; op = X86ADC; sz = X86NONE }; +"sbb" , BINOP { txt = "SBB"; op = X86SBB; sz = X86NONE }; +"and" , BINOP { txt = "AND"; op = X86AND; sz = X86NONE }; +"sub" , BINOP { txt = "SUB"; op = X86SUB; sz = X86NONE }; +"xor" , BINOP { txt = "XOR"; op = X86XOR; sz = X86NONE }; +"cmp" , BINOP { txt = "CMP"; op = X86CMP; sz = X86NONE }; +"rol" , BINOP { txt = "ROL"; op = X86ROL; sz = X86NONE }; +"ror" , BINOP { txt = "ROR"; op = X86ROR; sz = X86NONE }; +"shl" , BINOP { txt = "SHL"; op = X86SHL; sz = X86NONE }; +"shr" , BINOP { txt = "SHR"; op = X86SHR; sz = X86NONE }; +"test" , BINOP { txt = "TEST"; op = X86TEST; sz = X86NONE }; +"sar" , BINOP { txt = "SAR"; op = X86SAR; sz = X86NONE }; +"btcw" , BITOP { txt = "BTSW"; op = X86Btc; sz = X86WORD }; +"btsw" , BITOP { txt = "BTCW"; op = X86Bts; sz = X86WORD }; +"btrw" , BITOP { txt = "BTRW"; op = X86Btr; sz = X86WORD }; +"btcl" , BITOP { txt = "BTSL"; op = X86Btc; sz = X86LONG }; +"btsl" , BITOP { txt = "BTCL"; op = X86Bts; sz = X86LONG }; +"btrl" , BITOP { txt = "BTRL"; op = X86Btr; sz = X86LONG }; +"btcq" , BITOP { txt = "BTSQ"; op = X86Btc; sz = X86QUAD }; +"btsq" , BITOP { txt = "BTCQ"; op = X86Bts; sz = X86QUAD }; +"btrq" , BITOP { txt = "BTRQ"; op = X86Btr; sz = X86QUAD }; +"btc" , BITOP { txt = "BTS"; op = X86Btc; sz = X86NONE }; +"bts" , BITOP { txt = "BTC"; op = X86Bts; sz = X86NONE }; +"btr" , BITOP { txt = "BTR"; op = X86Btr; sz = X86NONE }; +"call" , CALL { txt = "CALL" }; +"clc" , CLC { txt = "CLC" }; +"cmc" , CMC { txt = "CMC" }; +"cmpxchgb" , CMPXCHG { txt = "CMPXCHGB"; sz = X86BYTE }; +"cmpxchgw" , CMPXCHG { txt = "CMPXCHGW"; sz = X86WORD }; +"cmpxchgl" , CMPXCHG { txt = "CMPXCHGL"; sz = X86LONG }; +"cmpxchgq" , CMPXCHG { txt = "CMPXCHGQ"; sz = X86QUAD }; +"cmpxchg" , CMPXCHG { txt = "CMPXCHG"; sz = X86NONE }; +"divb" , DIV { txt = "DIVB"; sz = X86BYTE }; +"divw" , DIV { txt = "DIVW"; sz = X86WORD }; +"divl" , DIV { txt = "DIVL"; sz = X86LONG }; +"divq" , DIV { txt = "DIVQ"; sz = X86QUAD }; +"div" , DIV { txt = "DIV"; sz = X86NONE }; +"jo" , JCC { txt = "JO"; cond = X86O }; +"jb" , JCC { txt = "JB"; cond = X86B }; +"jc" , JCC { txt = "JC"; cond = X86B }; +"jnae" , JCC { txt = "JNAE"; cond = X86B }; +"je" , JCC { txt = "JE"; cond = X86E }; +"jz" , JCC { txt = "JZ"; cond = X86E }; +"ja" , JCC { txt = "JA"; cond = X86A }; +"jnbe" , JCC { txt = "JNBE"; cond = X86A }; +"js" , JCC { txt = "JS"; cond = X86S }; +"jp" , JCC { txt = "JP"; cond = X86P }; +"jpe" , JCC { txt = "JPE"; cond = X86P }; +"jl" , JCC { txt = "JL"; cond = X86L }; +"jnge" , JCC { txt = "JNGE"; cond = X86L }; +"jg" , JCC { txt = "JG"; cond = X86G }; +"jnle" , JCC { txt = "JNLE"; cond = X86G }; +"jno" , JCC { txt = "JNO"; cond = X86NO }; +"jnb" , JCC { txt = "JNB"; cond = X86NB }; +"jnc" , JCC { txt = "JNC"; cond = X86NB }; +"jae" , JCC { txt = "JAE"; cond = X86NB }; +"jne" , JCC { txt = "JNE"; cond = X86NE }; +"jnz" , JCC { txt = "JNZ"; cond = X86NE }; +"jna" , JCC { txt = "JNA"; cond = X86NA }; +"jbe" , JCC { txt = "JBE"; cond = X86NA }; +"jns" , JCC { txt = "JNS"; cond = X86NS }; +"jnp" , JCC { txt = "JNP"; cond = X86NP }; +"jpo" , JCC { txt = "JPO"; cond = X86NP }; +"jnl" , JCC { txt = "JNL"; cond = X86NL }; +"jge" , JCC { txt = "JGE"; cond = X86NL }; +"jng" , JCC { txt = "JNG"; cond = X86NG }; +"jle" , JCC { txt = "JLE"; cond = X86NG }; +"jmp" , JMP { txt = "JMP" }; +"leaw" , LEA { txt = "LEAW"; sz = X86BYTE }; +"leal" , LEA { txt = "LEAL"; sz = X86LONG }; +"leaq" , LEA { txt = "LEAQ"; sz = X86QUAD }; +"lea" , LEA { txt = "LEA"; sz = X86NONE }; +"leave" , LEAVE { txt = "LEAVE" }; +"loopo" , LOOP { txt = "LOOPO"; cond = X86O }; +"loopb" , LOOP { txt = "LOOPB"; cond = X86B }; +"loopc" , LOOP { txt = "LOOPC"; cond = X86B }; +"loopnae" , LOOP { txt = "LOOPNAE"; cond = X86B }; +"loope" , LOOP { txt = "LOOPE"; cond = X86E }; +"loopz" , LOOP { txt = "LOOPZ"; cond = X86E }; +"loopa" , LOOP { txt = "LOOPA"; cond = X86A }; +"loopnbe" , LOOP { txt = "LOOPNBE"; cond = X86A }; +"loops" , LOOP { txt = "LOOPS"; cond = X86S }; +"loopp" , LOOP { txt = "LOOPP"; cond = X86P }; +"looppe" , LOOP { txt = "LOOPPE"; cond = X86P }; +"loopl" , LOOP { txt = "LOOPL"; cond = X86L }; +"loopnge" , LOOP { txt = "LOOPNGE"; cond = X86L }; +"loopg" , LOOP { txt = "LOOPG"; cond = X86G }; +"loopnle" , LOOP { txt = "LOOPNLE"; cond = X86G }; +"loopno" , LOOP { txt = "LOOPNO"; cond = X86NO }; +"loopnb" , LOOP { txt = "LOOPNB"; cond = X86NB }; +"loopnc" , LOOP { txt = "LOOPNC"; cond = X86NB }; +"loopae" , LOOP { txt = "LOOPAE"; cond = X86NB }; +"loopne" , LOOP { txt = "LOOPNE"; cond = X86NE }; +"loopnz" , LOOP { txt = "LOOPNZ"; cond = X86NE }; +"loopna" , LOOP { txt = "LOOPNA"; cond = X86NA }; +"loopbe" , LOOP { txt = "LOOPBE"; cond = X86NA }; +"loopns" , LOOP { txt = "LOOPNS"; cond = X86NS }; +"loopnp" , LOOP { txt = "LOOPNP"; cond = X86NP }; +"looppo" , LOOP { txt = "LOOPPO"; cond = X86NP }; +"loopnl" , LOOP { txt = "LOOPNL"; cond = X86NL }; +"loopge" , LOOP { txt = "LOOPGE"; cond = X86NL }; +"loopng" , LOOP { txt = "LOOPNG"; cond = X86NG }; +"loople" , LOOP { txt = "LOOPLE"; cond = X86NG }; +"mfence" , MFENCE { txt = "MFENCE" }; +"decb" , MONOP { txt = "DECB"; op = X86DEC; sz = X86BYTE }; +"incb" , MONOP { txt = "INCB"; op = X86INC; sz = X86BYTE }; +"notb" , MONOP { txt = "NOTB"; op = X86NOT; sz = X86BYTE }; +"negb" , MONOP { txt = "NEGB"; op = X86NEG; sz = X86BYTE }; +"decw" , MONOP { txt = "DECW"; op = X86DEC; sz = X86WORD }; +"incw" , MONOP { txt = "INCW"; op = X86INC; sz = X86WORD }; +"notw" , MONOP { txt = "NOTW"; op = X86NOT; sz = X86WORD }; +"negw" , MONOP { txt = "NEGW"; op = X86NEG; sz = X86WORD }; +"decl" , MONOP { txt = "DECL"; op = X86DEC; sz = X86LONG }; +"incl" , MONOP { txt = "INCL"; op = X86INC; sz = X86LONG }; +"notl" , MONOP { txt = "NOTL"; op = X86NOT; sz = X86LONG }; +"negl" , MONOP { txt = "NEGL"; op = X86NEG; sz = X86LONG }; +"decq" , MONOP { txt = "DECQ"; op = X86DEC; sz = X86QUAD }; +"incq" , MONOP { txt = "INCQ"; op = X86INC; sz = X86QUAD }; +"notq" , MONOP { txt = "NOTQ"; op = X86NOT; sz = X86QUAD }; +"negq" , MONOP { txt = "NEGQ"; op = X86NEG; sz = X86QUAD }; +"dec" , MONOP { txt = "DEC"; op = X86DEC; sz = X86NONE }; +"inc" , MONOP { txt = "INC"; op = X86INC; sz = X86NONE }; +"not" , MONOP { txt = "NOT"; op = X86NOT; sz = X86NONE }; +"neg" , MONOP { txt = "NEG"; op = X86NEG; sz = X86NONE }; +"cmovow" , CMOV { txt = "CMOVOW"; cond = X86O; sz = X86WORD }; +"cmovbw" , CMOV { txt = "CMOVBW"; cond = X86B; sz = X86WORD }; +"cmovcw" , CMOV { txt = "CMOVCW"; cond = X86B; sz = X86WORD }; +"cmovnaew" , CMOV { txt = "CMOVNAEW"; cond = X86B; sz = X86WORD }; +"cmovew" , CMOV { txt = "CMOVEW"; cond = X86E; sz = X86WORD }; +"cmovzw" , CMOV { txt = "CMOVZW"; cond = X86E; sz = X86WORD }; +"cmovaw" , CMOV { txt = "CMOVAW"; cond = X86A; sz = X86WORD }; +"cmovnbew" , CMOV { txt = "CMOVNBEW"; cond = X86A; sz = X86WORD }; +"cmovsw" , CMOV { txt = "CMOVSW"; cond = X86S; sz = X86WORD }; +"cmovpw" , CMOV { txt = "CMOVPW"; cond = X86P; sz = X86WORD }; +"cmovpew" , CMOV { txt = "CMOVPEW"; cond = X86P; sz = X86WORD }; +"cmovlw" , CMOV { txt = "CMOVLW"; cond = X86L; sz = X86WORD }; +"cmovngew" , CMOV { txt = "CMOVNGEW"; cond = X86L; sz = X86WORD }; +"cmovgw" , CMOV { txt = "CMOVGW"; cond = X86G; sz = X86WORD }; +"cmovnlew" , CMOV { txt = "CMOVNLEW"; cond = X86G; sz = X86WORD }; +"cmovnow" , CMOV { txt = "CMOVNOW"; cond = X86NO; sz = X86WORD }; +"cmovnbw" , CMOV { txt = "CMOVNBW"; cond = X86NB; sz = X86WORD }; +"cmovncw" , CMOV { txt = "CMOVNCW"; cond = X86NB; sz = X86WORD }; +"cmovaew" , CMOV { txt = "CMOVAEW"; cond = X86NB; sz = X86WORD }; +"cmovnew" , CMOV { txt = "CMOVNEW"; cond = X86NE; sz = X86WORD }; +"cmovnzw" , CMOV { txt = "CMOVNZW"; cond = X86NE; sz = X86WORD }; +"cmovnaw" , CMOV { txt = "CMOVNAW"; cond = X86NA; sz = X86WORD }; +"cmovbew" , CMOV { txt = "CMOVBEW"; cond = X86NA; sz = X86WORD }; +"cmovnsw" , CMOV { txt = "CMOVNSW"; cond = X86NS; sz = X86WORD }; +"cmovnpw" , CMOV { txt = "CMOVNPW"; cond = X86NP; sz = X86WORD }; +"cmovpow" , CMOV { txt = "CMOVPOW"; cond = X86NP; sz = X86WORD }; +"cmovnlw" , CMOV { txt = "CMOVNLW"; cond = X86NL; sz = X86WORD }; +"cmovgew" , CMOV { txt = "CMOVGEW"; cond = X86NL; sz = X86WORD }; +"cmovngw" , CMOV { txt = "CMOVNGW"; cond = X86NG; sz = X86WORD }; +"cmovlew" , CMOV { txt = "CMOVLEW"; cond = X86NG; sz = X86WORD }; +"cmovol" , CMOV { txt = "CMOVOL"; cond = X86O; sz = X86LONG }; +"cmovbl" , CMOV { txt = "CMOVBL"; cond = X86B; sz = X86LONG }; +"cmovcl" , CMOV { txt = "CMOVCL"; cond = X86B; sz = X86LONG }; +"cmovnael" , CMOV { txt = "CMOVNAEL"; cond = X86B; sz = X86LONG }; +"cmovel" , CMOV { txt = "CMOVEL"; cond = X86E; sz = X86LONG }; +"cmovzl" , CMOV { txt = "CMOVZL"; cond = X86E; sz = X86LONG }; +"cmoval" , CMOV { txt = "CMOVAL"; cond = X86A; sz = X86LONG }; +"cmovnbel" , CMOV { txt = "CMOVNBEL"; cond = X86A; sz = X86LONG }; +"cmovsl" , CMOV { txt = "CMOVSL"; cond = X86S; sz = X86LONG }; +"cmovpl" , CMOV { txt = "CMOVPL"; cond = X86P; sz = X86LONG }; +"cmovpel" , CMOV { txt = "CMOVPEL"; cond = X86P; sz = X86LONG }; +"cmovll" , CMOV { txt = "CMOVLL"; cond = X86L; sz = X86LONG }; +"cmovngel" , CMOV { txt = "CMOVNGEL"; cond = X86L; sz = X86LONG }; +"cmovgl" , CMOV { txt = "CMOVGL"; cond = X86G; sz = X86LONG }; +"cmovnlel" , CMOV { txt = "CMOVNLEL"; cond = X86G; sz = X86LONG }; +"cmovnol" , CMOV { txt = "CMOVNOL"; cond = X86NO; sz = X86LONG }; +"cmovnbl" , CMOV { txt = "CMOVNBL"; cond = X86NB; sz = X86LONG }; +"cmovncl" , CMOV { txt = "CMOVNCL"; cond = X86NB; sz = X86LONG }; +"cmovael" , CMOV { txt = "CMOVAEL"; cond = X86NB; sz = X86LONG }; +"cmovnel" , CMOV { txt = "CMOVNEL"; cond = X86NE; sz = X86LONG }; +"cmovnzl" , CMOV { txt = "CMOVNZL"; cond = X86NE; sz = X86LONG }; +"cmovnal" , CMOV { txt = "CMOVNAL"; cond = X86NA; sz = X86LONG }; +"cmovbel" , CMOV { txt = "CMOVBEL"; cond = X86NA; sz = X86LONG }; +"cmovnsl" , CMOV { txt = "CMOVNSL"; cond = X86NS; sz = X86LONG }; +"cmovnpl" , CMOV { txt = "CMOVNPL"; cond = X86NP; sz = X86LONG }; +"cmovpol" , CMOV { txt = "CMOVPOL"; cond = X86NP; sz = X86LONG }; +"cmovnll" , CMOV { txt = "CMOVNLL"; cond = X86NL; sz = X86LONG }; +"cmovgel" , CMOV { txt = "CMOVGEL"; cond = X86NL; sz = X86LONG }; +"cmovngl" , CMOV { txt = "CMOVNGL"; cond = X86NG; sz = X86LONG }; +"cmovlel" , CMOV { txt = "CMOVLEL"; cond = X86NG; sz = X86LONG }; +"cmovoq" , CMOV { txt = "CMOVOQ"; cond = X86O; sz = X86QUAD }; +"cmovbq" , CMOV { txt = "CMOVBQ"; cond = X86B; sz = X86QUAD }; +"cmovcq" , CMOV { txt = "CMOVCQ"; cond = X86B; sz = X86QUAD }; +"cmovnaeq" , CMOV { txt = "CMOVNAEQ"; cond = X86B; sz = X86QUAD }; +"cmoveq" , CMOV { txt = "CMOVEQ"; cond = X86E; sz = X86QUAD }; +"cmovzq" , CMOV { txt = "CMOVZQ"; cond = X86E; sz = X86QUAD }; +"cmovaq" , CMOV { txt = "CMOVAQ"; cond = X86A; sz = X86QUAD }; +"cmovnbeq" , CMOV { txt = "CMOVNBEQ"; cond = X86A; sz = X86QUAD }; +"cmovsq" , CMOV { txt = "CMOVSQ"; cond = X86S; sz = X86QUAD }; +"cmovpq" , CMOV { txt = "CMOVPQ"; cond = X86P; sz = X86QUAD }; +"cmovpeq" , CMOV { txt = "CMOVPEQ"; cond = X86P; sz = X86QUAD }; +"cmovlq" , CMOV { txt = "CMOVLQ"; cond = X86L; sz = X86QUAD }; +"cmovngeq" , CMOV { txt = "CMOVNGEQ"; cond = X86L; sz = X86QUAD }; +"cmovgq" , CMOV { txt = "CMOVGQ"; cond = X86G; sz = X86QUAD }; +"cmovnleq" , CMOV { txt = "CMOVNLEQ"; cond = X86G; sz = X86QUAD }; +"cmovnoq" , CMOV { txt = "CMOVNOQ"; cond = X86NO; sz = X86QUAD }; +"cmovnbq" , CMOV { txt = "CMOVNBQ"; cond = X86NB; sz = X86QUAD }; +"cmovncq" , CMOV { txt = "CMOVNCQ"; cond = X86NB; sz = X86QUAD }; +"cmovaeq" , CMOV { txt = "CMOVAEQ"; cond = X86NB; sz = X86QUAD }; +"cmovneq" , CMOV { txt = "CMOVNEQ"; cond = X86NE; sz = X86QUAD }; +"cmovnzq" , CMOV { txt = "CMOVNZQ"; cond = X86NE; sz = X86QUAD }; +"cmovnaq" , CMOV { txt = "CMOVNAQ"; cond = X86NA; sz = X86QUAD }; +"cmovbeq" , CMOV { txt = "CMOVBEQ"; cond = X86NA; sz = X86QUAD }; +"cmovnsq" , CMOV { txt = "CMOVNSQ"; cond = X86NS; sz = X86QUAD }; +"cmovnpq" , CMOV { txt = "CMOVNPQ"; cond = X86NP; sz = X86QUAD }; +"cmovpoq" , CMOV { txt = "CMOVPOQ"; cond = X86NP; sz = X86QUAD }; +"cmovnlq" , CMOV { txt = "CMOVNLQ"; cond = X86NL; sz = X86QUAD }; +"cmovgeq" , CMOV { txt = "CMOVGEQ"; cond = X86NL; sz = X86QUAD }; +"cmovngq" , CMOV { txt = "CMOVNGQ"; cond = X86NG; sz = X86QUAD }; +"cmovleq" , CMOV { txt = "CMOVLEQ"; cond = X86NG; sz = X86QUAD }; +"cmovo" , CMOV { txt = "CMOVO"; cond = X86O; sz = X86NONE }; +"cmovb" , CMOV { txt = "CMOVB"; cond = X86B; sz = X86NONE }; +"cmovc" , CMOV { txt = "CMOVC"; cond = X86B; sz = X86NONE }; +"cmovnae" , CMOV { txt = "CMOVNAE"; cond = X86B; sz = X86NONE }; +"cmove" , CMOV { txt = "CMOVE"; cond = X86E; sz = X86NONE }; +"cmovz" , CMOV { txt = "CMOVZ"; cond = X86E; sz = X86NONE }; +"cmova" , CMOV { txt = "CMOVA"; cond = X86A; sz = X86NONE }; +"cmovnbe" , CMOV { txt = "CMOVNBE"; cond = X86A; sz = X86NONE }; +"cmovs" , CMOV { txt = "CMOVS"; cond = X86S; sz = X86NONE }; +"cmovp" , CMOV { txt = "CMOVP"; cond = X86P; sz = X86NONE }; +"cmovpe" , CMOV { txt = "CMOVPE"; cond = X86P; sz = X86NONE }; +"cmovl" , CMOV { txt = "CMOVL"; cond = X86L; sz = X86NONE }; +"cmovnge" , CMOV { txt = "CMOVNGE"; cond = X86L; sz = X86NONE }; +"cmovg" , CMOV { txt = "CMOVG"; cond = X86G; sz = X86NONE }; +"cmovnle" , CMOV { txt = "CMOVNLE"; cond = X86G; sz = X86NONE }; +"cmovno" , CMOV { txt = "CMOVNO"; cond = X86NO; sz = X86NONE }; +"cmovnb" , CMOV { txt = "CMOVNB"; cond = X86NB; sz = X86NONE }; +"cmovnc" , CMOV { txt = "CMOVNC"; cond = X86NB; sz = X86NONE }; +"cmovae" , CMOV { txt = "CMOVAE"; cond = X86NB; sz = X86NONE }; +"cmovne" , CMOV { txt = "CMOVNE"; cond = X86NE; sz = X86NONE }; +"cmovnz" , CMOV { txt = "CMOVNZ"; cond = X86NE; sz = X86NONE }; +"cmovna" , CMOV { txt = "CMOVNA"; cond = X86NA; sz = X86NONE }; +"cmovbe" , CMOV { txt = "CMOVBE"; cond = X86NA; sz = X86NONE }; +"cmovns" , CMOV { txt = "CMOVNS"; cond = X86NS; sz = X86NONE }; +"cmovnp" , CMOV { txt = "CMOVNP"; cond = X86NP; sz = X86NONE }; +"cmovpo" , CMOV { txt = "CMOVPO"; cond = X86NP; sz = X86NONE }; +"cmovnl" , CMOV { txt = "CMOVNL"; cond = X86NL; sz = X86NONE }; +"cmovge" , CMOV { txt = "CMOVGE"; cond = X86NL; sz = X86NONE }; +"cmovng" , CMOV { txt = "CMOVNG"; cond = X86NG; sz = X86NONE }; +"cmovle" , CMOV { txt = "CMOVLE"; cond = X86NG; sz = X86NONE }; +"movb" , MOV { txt = "MOVB"; sz = X86BYTE }; +"movw" , MOV { txt = "MOVW"; sz = X86WORD }; +"movl" , MOV { txt = "MOVL"; sz = X86LONG }; +"movq" , MOV { txt = "MOVQ"; sz = X86QUAD }; +"mov" , MOV { txt = "MOV"; sz = X86NONE }; +"movabs" , MOV { txt = "MOVABS"; sz = X86QUAD }; +"movsbw" , MOVSX { txt = "MOVSBW"; sz1 = X86BYTE; sz2 = X86WORD }; +"movsbl" , MOVSX { txt = "MOVSBL"; sz1 = X86BYTE; sz2 = X86LONG }; +"movsbq" , MOVSX { txt = "MOVSBQ"; sz1 = X86BYTE; sz2 = X86QUAD }; +"movswl" , MOVSX { txt = "MOVSWL"; sz1 = X86WORD; sz2 = X86LONG }; +"movswq" , MOVSX { txt = "MOVSWQ"; sz1 = X86WORD; sz2 = X86QUAD }; +"movslq" , MOVSX { txt = "MOVSWQ"; sz1 = X86LONG; sz2 = X86QUAD }; +"movzbw" , MOVZX { txt = "MOVZBW"; sz1 = X86BYTE; sz2 = X86WORD }; +"movzbl" , MOVZX { txt = "MOVZBL"; sz1 = X86BYTE; sz2 = X86LONG }; +"movzbq" , MOVZX { txt = "MOVZBQ"; sz1 = X86BYTE; sz2 = X86QUAD }; +"movzwl" , MOVZX { txt = "MOVZWL"; sz1 = X86WORD; sz2 = X86LONG }; +"movzwq" , MOVZX { txt = "MOVZWQ"; sz1 = X86WORD; sz2 = X86QUAD }; +"mulb" , MUL { txt = "MULB"; sz = X86BYTE }; +"mulw" , MUL { txt = "MULW"; sz = X86WORD }; +"mull" , MUL { txt = "MULL"; sz = X86LONG }; +"mulq" , MUL { txt = "MULQ"; sz = X86QUAD }; +"mul" , MUL { txt = "MUL"; sz = X86NONE }; +"nop" , NOP { txt = "NOP" }; +"pop" , POP { txt = "POP" }; +"push" , PUSH { txt = "PUSH" }; +"ret" , PUSH { txt = "RET" }; +"setob" , SET { txt = "SETOB"; cond = X86O }; +"setbb" , SET { txt = "SETBB"; cond = X86B }; +"setcb" , SET { txt = "SETCB"; cond = X86B }; +"setnaeb" , SET { txt = "SETNAEB"; cond = X86B }; +"seteb" , SET { txt = "SETEB"; cond = X86E }; +"setzb" , SET { txt = "SETZB"; cond = X86E }; +"setab" , SET { txt = "SETAB"; cond = X86A }; +"setnbeb" , SET { txt = "SETNBEB"; cond = X86A }; +"setsb" , SET { txt = "SETSB"; cond = X86S }; +"setpb" , SET { txt = "SETPB"; cond = X86P }; +"setpeb" , SET { txt = "SETPEB"; cond = X86P }; +"setlb" , SET { txt = "SETLB"; cond = X86L }; +"setngeb" , SET { txt = "SETNGEB"; cond = X86L }; +"setgb" , SET { txt = "SETGB"; cond = X86G }; +"setnleb" , SET { txt = "SETNLEB"; cond = X86G }; +"setnob" , SET { txt = "SETNOB"; cond = X86NO }; +"setnbb" , SET { txt = "SETNBB"; cond = X86NB }; +"setncb" , SET { txt = "SETNCB"; cond = X86NB }; +"setaeb" , SET { txt = "SETAEB"; cond = X86NB }; +"setneb" , SET { txt = "SETNEB"; cond = X86NE }; +"setnzb" , SET { txt = "SETNZB"; cond = X86NE }; +"setnab" , SET { txt = "SETNAB"; cond = X86NA }; +"setbeb" , SET { txt = "SETBEB"; cond = X86NA }; +"setnsb" , SET { txt = "SETNSB"; cond = X86NS }; +"setnpb" , SET { txt = "SETNPB"; cond = X86NP }; +"setpob" , SET { txt = "SETPOB"; cond = X86NP }; +"setnlb" , SET { txt = "SETNLB"; cond = X86NL }; +"setgeb" , SET { txt = "SETGEB"; cond = X86NL }; +"setngb" , SET { txt = "SETNGB"; cond = X86NG }; +"setleb" , SET { txt = "SETLEB"; cond = X86NG }; +"seto" , SET { txt = "SETO"; cond = X86O }; +"setb" , SET { txt = "SETB"; cond = X86B }; +"setc" , SET { txt = "SETC"; cond = X86B }; +"setnae" , SET { txt = "SETNAE"; cond = X86B }; +"sete" , SET { txt = "SETE"; cond = X86E }; +"setz" , SET { txt = "SETZ"; cond = X86E }; +"seta" , SET { txt = "SETA"; cond = X86A }; +"setnbe" , SET { txt = "SETNBE"; cond = X86A }; +"sets" , SET { txt = "SETS"; cond = X86S }; +"setp" , SET { txt = "SETP"; cond = X86P }; +"setpe" , SET { txt = "SETPE"; cond = X86P }; +"setl" , SET { txt = "SETL"; cond = X86L }; +"setnge" , SET { txt = "SETNGE"; cond = X86L }; +"setg" , SET { txt = "SETG"; cond = X86G }; +"setnle" , SET { txt = "SETNLE"; cond = X86G }; +"setno" , SET { txt = "SETNO"; cond = X86NO }; +"setnb" , SET { txt = "SETNB"; cond = X86NB }; +"setnc" , SET { txt = "SETNC"; cond = X86NB }; +"setae" , SET { txt = "SETAE"; cond = X86NB }; +"setne" , SET { txt = "SETNE"; cond = X86NE }; +"setnz" , SET { txt = "SETNZ"; cond = X86NE }; +"setna" , SET { txt = "SETNA"; cond = X86NA }; +"setbe" , SET { txt = "SETBE"; cond = X86NA }; +"setns" , SET { txt = "SETNS"; cond = X86NS }; +"setnp" , SET { txt = "SETNP"; cond = X86NP }; +"setpo" , SET { txt = "SETPO"; cond = X86NP }; +"setnl" , SET { txt = "SETNL"; cond = X86NL }; +"setge" , SET { txt = "SETGE"; cond = X86NL }; +"setng" , SET { txt = "SETNG"; cond = X86NG }; +"setle" , SET { txt = "SETLE"; cond = X86NG }; +"stc" , STC { txt = "STC" }; +"xaddb" , XADD { txt = "XADDB"; sz = X86BYTE }; +"xaddw" , XADD { txt = "XADDW"; sz = X86WORD }; +"xaddl" , XADD { txt = "XADDL"; sz = X86LONG }; +"xaddq" , XADD { txt = "XADDQ"; sz = X86QUAD }; +"xadd" , XADD { txt = "XADD"; sz = X86NONE }; +"xchgb" , XCHG { txt = "XCHGB"; sz = X86BYTE }; +"xchgw" , XCHG { txt = "XCHGW"; sz = X86WORD }; +"xchgl" , XCHG { txt = "XCHGL"; sz = X86LONG }; +"xchgq" , XCHG { txt = "XCHGQ"; sz = X86QUAD }; +"xchg" , XCHG { txt = "XCHG"; sz = X86NONE }; diff --git a/x86/gen/lexer_intel.hgen b/x86/gen/lexer_intel.hgen new file mode 100644 index 00000000..e1854a14 --- /dev/null +++ b/x86/gen/lexer_intel.hgen @@ -0,0 +1,161 @@ +"add" , BINOP { txt = "ADDQ"; op = X86ADD; sz = X86NONE }; +"or" , BINOP { txt = "OR"; op = X86OR; sz = X86NONE }; +"adc" , BINOP { txt = "ADC"; op = X86ADC; sz = X86NONE }; +"sbb" , BINOP { txt = "SBB"; op = X86SBB; sz = X86NONE }; +"and" , BINOP { txt = "AND"; op = X86AND; sz = X86NONE }; +"sub" , BINOP { txt = "SUB"; op = X86SUB; sz = X86NONE }; +"xor" , BINOP { txt = "XOR"; op = X86XOR; sz = X86NONE }; +"cmp" , BINOP { txt = "CMP"; op = X86CMP; sz = X86NONE }; +"rol" , BINOP { txt = "ROL"; op = X86ROL; sz = X86NONE }; +"ror" , BINOP { txt = "ROR"; op = X86ROR; sz = X86NONE }; +"shl" , BINOP { txt = "SHL"; op = X86SHL; sz = X86NONE }; +"shr" , BINOP { txt = "SHR"; op = X86SHR; sz = X86NONE }; +"test" , BINOP { txt = "TEST"; op = X86TEST; sz = X86NONE }; +"sar" , BINOP { txt = "SAR"; op = X86SAR; sz = X86NONE }; +"btc" , BITOP { txt = "BTS"; op = X86Btc; sz = X86NONE }; +"bts" , BITOP { txt = "BTC"; op = X86Bts; sz = X86NONE }; +"btr" , BITOP { txt = "BTR"; op = X86Btr; sz = X86NONE }; +"call" , CALL { txt = "CALL" }; +"clc" , CLC { txt = "CLC" }; +"cmc" , CMC { txt = "CMC" }; +"cmpxchg" , CMPXCHG { txt = "CMPXCHG"; sz = X86NONE }; +"div" , DIV { txt = "DIV"; sz = X86NONE }; +"jo" , JCC { txt = "JO"; cond = X86O }; +"jb" , JCC { txt = "JB"; cond = X86B }; +"jc" , JCC { txt = "JC"; cond = X86B }; +"jnae" , JCC { txt = "JNAE"; cond = X86B }; +"je" , JCC { txt = "JE"; cond = X86E }; +"jz" , JCC { txt = "JZ"; cond = X86E }; +"ja" , JCC { txt = "JA"; cond = X86A }; +"jnbe" , JCC { txt = "JNBE"; cond = X86A }; +"js" , JCC { txt = "JS"; cond = X86S }; +"jp" , JCC { txt = "JP"; cond = X86P }; +"jpe" , JCC { txt = "JPE"; cond = X86P }; +"jl" , JCC { txt = "JL"; cond = X86L }; +"jnge" , JCC { txt = "JNGE"; cond = X86L }; +"jg" , JCC { txt = "JG"; cond = X86G }; +"jnle" , JCC { txt = "JNLE"; cond = X86G }; +"jno" , JCC { txt = "JNO"; cond = X86NO }; +"jnb" , JCC { txt = "JNB"; cond = X86NB }; +"jnc" , JCC { txt = "JNC"; cond = X86NB }; +"jae" , JCC { txt = "JAE"; cond = X86NB }; +"jne" , JCC { txt = "JNE"; cond = X86NE }; +"jnz" , JCC { txt = "JNZ"; cond = X86NE }; +"jna" , JCC { txt = "JNA"; cond = X86NA }; +"jbe" , JCC { txt = "JBE"; cond = X86NA }; +"jns" , JCC { txt = "JNS"; cond = X86NS }; +"jnp" , JCC { txt = "JNP"; cond = X86NP }; +"jpo" , JCC { txt = "JPO"; cond = X86NP }; +"jnl" , JCC { txt = "JNL"; cond = X86NL }; +"jge" , JCC { txt = "JGE"; cond = X86NL }; +"jng" , JCC { txt = "JNG"; cond = X86NG }; +"jle" , JCC { txt = "JLE"; cond = X86NG }; +"jmp" , JMP { txt = "JMP" }; +"lea" , LEA { txt = "LEA"; sz = X86NONE }; +"leave" , LEAVE { txt = "LEAVE" }; +"loopo" , LOOP { txt = "LOOPO"; cond = X86O }; +"loopb" , LOOP { txt = "LOOPB"; cond = X86B }; +"loopc" , LOOP { txt = "LOOPC"; cond = X86B }; +"loopnae" , LOOP { txt = "LOOPNAE"; cond = X86B }; +"loope" , LOOP { txt = "LOOPE"; cond = X86E }; +"loopz" , LOOP { txt = "LOOPZ"; cond = X86E }; +"loopa" , LOOP { txt = "LOOPA"; cond = X86A }; +"loopnbe" , LOOP { txt = "LOOPNBE"; cond = X86A }; +"loops" , LOOP { txt = "LOOPS"; cond = X86S }; +"loopp" , LOOP { txt = "LOOPP"; cond = X86P }; +"looppe" , LOOP { txt = "LOOPPE"; cond = X86P }; +"loopl" , LOOP { txt = "LOOPL"; cond = X86L }; +"loopnge" , LOOP { txt = "LOOPNGE"; cond = X86L }; +"loopg" , LOOP { txt = "LOOPG"; cond = X86G }; +"loopnle" , LOOP { txt = "LOOPNLE"; cond = X86G }; +"loopno" , LOOP { txt = "LOOPNO"; cond = X86NO }; +"loopnb" , LOOP { txt = "LOOPNB"; cond = X86NB }; +"loopnc" , LOOP { txt = "LOOPNC"; cond = X86NB }; +"loopae" , LOOP { txt = "LOOPAE"; cond = X86NB }; +"loopne" , LOOP { txt = "LOOPNE"; cond = X86NE }; +"loopnz" , LOOP { txt = "LOOPNZ"; cond = X86NE }; +"loopna" , LOOP { txt = "LOOPNA"; cond = X86NA }; +"loopbe" , LOOP { txt = "LOOPBE"; cond = X86NA }; +"loopns" , LOOP { txt = "LOOPNS"; cond = X86NS }; +"loopnp" , LOOP { txt = "LOOPNP"; cond = X86NP }; +"looppo" , LOOP { txt = "LOOPPO"; cond = X86NP }; +"loopnl" , LOOP { txt = "LOOPNL"; cond = X86NL }; +"loopge" , LOOP { txt = "LOOPGE"; cond = X86NL }; +"loopng" , LOOP { txt = "LOOPNG"; cond = X86NG }; +"loople" , LOOP { txt = "LOOPLE"; cond = X86NG }; +"mfence" , MFENCE { txt = "MFENCE" }; +"dec" , MONOP { txt = "DEC"; op = X86DEC; sz = X86NONE }; +"inc" , MONOP { txt = "INC"; op = X86INC; sz = X86NONE }; +"not" , MONOP { txt = "NOT"; op = X86NOT; sz = X86NONE }; +"neg" , MONOP { txt = "NEG"; op = X86NEG; sz = X86NONE }; +"cmovo" , CMOV { txt = "CMOVO"; cond = X86O; sz = X86NONE }; +"cmovb" , CMOV { txt = "CMOVB"; cond = X86B; sz = X86NONE }; +"cmovc" , CMOV { txt = "CMOVC"; cond = X86B; sz = X86NONE }; +"cmovnae" , CMOV { txt = "CMOVNAE"; cond = X86B; sz = X86NONE }; +"cmove" , CMOV { txt = "CMOVE"; cond = X86E; sz = X86NONE }; +"cmovz" , CMOV { txt = "CMOVZ"; cond = X86E; sz = X86NONE }; +"cmova" , CMOV { txt = "CMOVA"; cond = X86A; sz = X86NONE }; +"cmovnbe" , CMOV { txt = "CMOVNBE"; cond = X86A; sz = X86NONE }; +"cmovs" , CMOV { txt = "CMOVS"; cond = X86S; sz = X86NONE }; +"cmovp" , CMOV { txt = "CMOVP"; cond = X86P; sz = X86NONE }; +"cmovpe" , CMOV { txt = "CMOVPE"; cond = X86P; sz = X86NONE }; +"cmovl" , CMOV { txt = "CMOVL"; cond = X86L; sz = X86NONE }; +"cmovnge" , CMOV { txt = "CMOVNGE"; cond = X86L; sz = X86NONE }; +"cmovg" , CMOV { txt = "CMOVG"; cond = X86G; sz = X86NONE }; +"cmovnle" , CMOV { txt = "CMOVNLE"; cond = X86G; sz = X86NONE }; +"cmovno" , CMOV { txt = "CMOVNO"; cond = X86NO; sz = X86NONE }; +"cmovnb" , CMOV { txt = "CMOVNB"; cond = X86NB; sz = X86NONE }; +"cmovnc" , CMOV { txt = "CMOVNC"; cond = X86NB; sz = X86NONE }; +"cmovae" , CMOV { txt = "CMOVAE"; cond = X86NB; sz = X86NONE }; +"cmovne" , CMOV { txt = "CMOVNE"; cond = X86NE; sz = X86NONE }; +"cmovnz" , CMOV { txt = "CMOVNZ"; cond = X86NE; sz = X86NONE }; +"cmovna" , CMOV { txt = "CMOVNA"; cond = X86NA; sz = X86NONE }; +"cmovbe" , CMOV { txt = "CMOVBE"; cond = X86NA; sz = X86NONE }; +"cmovns" , CMOV { txt = "CMOVNS"; cond = X86NS; sz = X86NONE }; +"cmovnp" , CMOV { txt = "CMOVNP"; cond = X86NP; sz = X86NONE }; +"cmovpo" , CMOV { txt = "CMOVPO"; cond = X86NP; sz = X86NONE }; +"cmovnl" , CMOV { txt = "CMOVNL"; cond = X86NL; sz = X86NONE }; +"cmovge" , CMOV { txt = "CMOVGE"; cond = X86NL; sz = X86NONE }; +"cmovng" , CMOV { txt = "CMOVNG"; cond = X86NG; sz = X86NONE }; +"cmovle" , CMOV { txt = "CMOVLE"; cond = X86NG; sz = X86NONE }; +"mov" , MOV { txt = "MOV"; sz = X86NONE }; +"movsx" , MOVSX { txt = "MOVSBW"; sz1 = X86NONE; sz2 = X86NONE }; +"movzx" , MOVZX { txt = "MOVZBW"; sz1 = X86NONE; sz2 = X86NONE }; +"mul" , MUL { txt = "MUL"; sz = X86NONE }; +"nop" , NOP { txt = "NOP" }; +"pop" , POP { txt = "POP" }; +"push" , PUSH { txt = "PUSH" }; +"ret" , PUSH { txt = "RET" }; +"seto" , SET { txt = "SETO"; cond = X86O }; +"setb" , SET { txt = "SETB"; cond = X86B }; +"setc" , SET { txt = "SETC"; cond = X86B }; +"setnae" , SET { txt = "SETNAE"; cond = X86B }; +"sete" , SET { txt = "SETE"; cond = X86E }; +"setz" , SET { txt = "SETZ"; cond = X86E }; +"seta" , SET { txt = "SETA"; cond = X86A }; +"setnbe" , SET { txt = "SETNBE"; cond = X86A }; +"sets" , SET { txt = "SETS"; cond = X86S }; +"setp" , SET { txt = "SETP"; cond = X86P }; +"setpe" , SET { txt = "SETPE"; cond = X86P }; +"setl" , SET { txt = "SETL"; cond = X86L }; +"setnge" , SET { txt = "SETNGE"; cond = X86L }; +"setg" , SET { txt = "SETG"; cond = X86G }; +"setnle" , SET { txt = "SETNLE"; cond = X86G }; +"setno" , SET { txt = "SETNO"; cond = X86NO }; +"setnb" , SET { txt = "SETNB"; cond = X86NB }; +"setnc" , SET { txt = "SETNC"; cond = X86NB }; +"setae" , SET { txt = "SETAE"; cond = X86NB }; +"setne" , SET { txt = "SETNE"; cond = X86NE }; +"setnz" , SET { txt = "SETNZ"; cond = X86NE }; +"setna" , SET { txt = "SETNA"; cond = X86NA }; +"setbe" , SET { txt = "SETBE"; cond = X86NA }; +"setns" , SET { txt = "SETNS"; cond = X86NS }; +"setnp" , SET { txt = "SETNP"; cond = X86NP }; +"setpo" , SET { txt = "SETPO"; cond = X86NP }; +"setnl" , SET { txt = "SETNL"; cond = X86NL }; +"setge" , SET { txt = "SETGE"; cond = X86NL }; +"setng" , SET { txt = "SETNG"; cond = X86NG }; +"setle" , SET { txt = "SETLE"; cond = X86NG }; +"stc" , STC { txt = "STC" }; +"xadd" , XADD { txt = "XADD"; sz = X86NONE }; +"xchg" , XCHG { txt = "XCHG"; sz = X86NONE }; diff --git a/x86/gen/map.hgen b/x86/gen/map.hgen new file mode 100644 index 00000000..843e8832 --- /dev/null +++ b/x86/gen/map.hgen @@ -0,0 +1,26 @@ +| `X86BINOP (locked, bop, sz, ds) -> `X86BINOP (locked, bop, sz, map_dest_src ds) +| `X86BITOP (locked, bop, sz, bo) -> `X86BITOP (locked, bop, sz, map_bit_offset bo) +| `X86CALL irm -> `X86CALL (map_imm_rm irm) +| `X86CLC -> `X86CLC +| `X86CMC -> `X86CMC +| `X86CMPXCHG (locked, sz, rm, r) -> `X86CMPXCHG (locked, sz, map_rm rm, map_reg r) +| `X86DIV (sz, rm) -> `X86DIV (sz, map_rm rm) +| `X86JCC x -> `X86JCC x +| `X86JMP rm -> `X86JMP (map_rm rm) +| `X86LEA (sz, ds) -> `X86LEA (sz, map_dest_src ds) +| `X86LEAVE -> `X86LEAVE +| `X86LOOP x -> `X86LOOP x +| `X86MFENCE -> `X86MFENCE +| `X86MONOP (locked, mop, sz, rm) -> `X86MONOP (locked, mop, sz, map_rm rm) +| `X86MOV (cnd, sz, ds) -> `X86MOV (cnd, sz, map_dest_src ds) +| `X86MOVSX (sz1, ds, sz2) -> `X86MOVSX (sz1, map_dest_src ds, sz2) +| `X86MOVZX (sz1, ds, sz2) -> `X86MOVZX (sz1, map_dest_src ds, sz2) +| `X86MUL (sz, rm) -> `X86MUL (sz, map_rm rm) +| `X86NOP -> `X86NOP +| `X86POP rm -> `X86POP (map_rm rm) +| `X86PUSH irm -> `X86PUSH (map_imm_rm irm) +| `X86RET i -> `X86RET i +| `X86SET (cnd, b, rm) -> `X86SET (cnd, b, map_rm rm) +| `X86STC -> `X86STC +| `X86XADD (locked, sz, rm, r) -> `X86XADD (locked, sz, map_rm rm, map_reg r) +| `X86XCHG (locked, sz, rm, r) -> `X86XCHG (locked, sz, map_rm rm, map_reg r) diff --git a/x86/gen/parser.hgen b/x86/gen/parser.hgen new file mode 100644 index 00000000..b3c9dc72 --- /dev/null +++ b/x86/gen/parser.hgen @@ -0,0 +1,600 @@ +| BINOP imm COMMA addr + { `X86BINOP (false, $1.op, suffix_size $1.sz, Rm_i ($4, bit64_of_int $2)) } +| LOCK BINOP imm COMMA addr + { check_binop_lockable $2.op + ; `X86BINOP (true, $2.op, suffix_size $2.sz, Rm_i ($5, bit64_of_int $3)) } +| BINOP imm COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($4.high), Rm_i (Reg (IReg ($4.reg)), bit64_of_int $2)) + } +| BINOP breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86BINOP (false, $1.op, X86S8 ($4.high), Rm_r (Reg (IReg ($4.reg)), IReg ($2.reg))) + } +| BINOP addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($4.high), R_rm (IReg ($4.reg), $2)) + } +| BINOP breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($2.high), Rm_r ($4, IReg ($2.reg))) + } +| LOCK BINOP breg COMMA addr + { check_binop_lockable $2.op + ; check_size ($2.sz, X86BYTE) + ; `X86BINOP (true, $2.op, X86S8 ($3.high), Rm_r ($5, IReg ($3.reg))) + } +| BINOP imm COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_i (Reg $4, bit64_of_int $2)) + } +| BINOP wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_r (Reg $4, $2)) + } +| BINOP addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, R_rm ($4, $2)) + } +| BINOP wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_r ($4, $2)) + } +| LOCK BINOP wreg COMMA addr + { check_binop_lockable $2.op + ; check_size ($2.sz, X86WORD) + ; `X86BINOP (true, $2.op, X86S16, Rm_r ($5, $3)) + } +| BINOP imm COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_i (Reg $4, bit64_of_int $2)) + } +| BINOP lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_r (Reg $4, $2)) + } +| BINOP addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, R_rm ($4, $2)) + } +| BINOP lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_r ($4, $2)) + } +| LOCK BINOP lreg COMMA addr + { check_binop_lockable $2.op + ; check_size ($2.sz, X86LONG) + ; `X86BINOP (true, $2.op, X86S32, Rm_r ($5, $3)) + } +| BINOP imm COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_i (Reg $4, bit64_of_int $2)) + } +| BINOP qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_r (Reg $4, $2)) + } +| BINOP addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, R_rm ($4, $2)) + } +| BINOP qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_r ($4, $2)) + } +| LOCK BINOP qreg COMMA addr + { check_binop_lockable $2.op + ; check_size ($2.sz, X86QUAD) + ; `X86BINOP (true, $2.op, X86S64, Rm_r ($5, $3)) + } +| BITOP imm COMMA addr + { `X86BITOP (false, $1.op, suffix_size $1.sz, Bit_rm_imm ($4, $2)) + } +| LOCK BITOP imm COMMA addr + { `X86BITOP (true, $2.op, suffix_size $2.sz, Bit_rm_imm ($5, $3)) + } +| BITOP imm COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BITOP (false, $1.op, X86S16, Bit_rm_imm (Reg $4, $2)) + } +| LOCK BITOP imm COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86BITOP (true, $2.op, X86S16, Bit_rm_imm (Reg $5, $3)) + } +| BITOP wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BITOP (true, $1.op, X86S16, Bit_rm_r (Reg $4, $2)) + } +| LOCK BITOP wreg COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86BITOP (false, $2.op, X86S16, Bit_rm_r (Reg $5, $3)) + } +| BITOP wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86BITOP (false, $1.op, X86S16, Bit_rm_r ($4, $2)) + } +| LOCK BITOP wreg COMMA addr + { check_size ($2.sz, X86WORD) + ; `X86BITOP (true, $2.op, X86S16, Bit_rm_r ($5, $3)) + } +| BITOP imm COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_imm (Reg $4, $2)) + } +| LOCK BITOP imm COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_imm (Reg $5, $3)) + } +| BITOP lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_r (Reg $4, $2)) + } +| LOCK BITOP lreg COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_r (Reg $5, $3)) + } +| BITOP lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_r ($4, $2)) + } +| LOCK BITOP lreg COMMA addr + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_r ($5, $3)) + } +| BITOP imm COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_imm (Reg $4, $2)) + } +| LOCK BITOP imm COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_imm (Reg $5, $3)) + } +| BITOP qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_r (Reg $4, $2)) + } +| LOCK BITOP qreg COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_r (Reg $5, $3)) + } +| BITOP qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_r ($4, $2)) + } +| LOCK BITOP qreg COMMA addr + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_r ($5, $3)) + } +| CALL big_imm + { `X86CALL (Imm $2) } +| CALL addr + { `X86CALL (Rm $2) } +| CALL qreg + { `X86CALL (Rm (Reg $2)) } +| CLC + { `X86CLC } +| CMC + { `X86CMC } +| CMOV addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV ($1.cond, X86S16, R_rm ($4, $2)) + } +| CMOV addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV ($1.cond, X86S32, R_rm ($4, $2)) + } +| CMOV addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86MOV ($1.cond, X86S64, R_rm ($4, $2)) + } +| CMOV wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV ($1.cond, X86S16, R_rm ($4, Reg $2)) + } +| CMOV lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV ($1.cond, X86S32, R_rm ($4, Reg $2)) + } +| CMOV qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86MOV ($1.cond, X86S64, R_rm ($4, Reg $2)) + } +| CMPXCHG breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86CMPXCHG (false, X86S8 ($2.high), Reg (IReg ($4.reg)), IReg ($2.reg)) + } +| CMPXCHG breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86CMPXCHG (false, X86S8 ($2.high), $4, IReg ($2.reg)) + } +| LOCK CMPXCHG breg COMMA addr + { check_size ($2.sz, X86BYTE) + ; `X86CMPXCHG (true, X86S8 ($3.high), $5, IReg ($3.reg)) + } +| CMPXCHG wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86CMPXCHG (false, X86S16, Reg $4, $2) + } +| CMPXCHG wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86CMPXCHG (false, X86S16, $4, $2) + } +| LOCK CMPXCHG wreg COMMA addr + { check_size ($2.sz, X86WORD) + ; `X86CMPXCHG (true, X86S16, $5, $3) + } +| CMPXCHG lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86CMPXCHG (false, X86S32, Reg $4, $2) + } +| CMPXCHG lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86CMPXCHG (false, X86S32, $4, $2) + } +| LOCK CMPXCHG lreg COMMA addr + { check_size ($2.sz, X86LONG) + ; `X86CMPXCHG (true, X86S32, $5, $3) + } +| CMPXCHG qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86CMPXCHG (false, X86S64, Reg $4, $2) + } +| CMPXCHG qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86CMPXCHG (false, X86S64, $4, $2) + } +| LOCK CMPXCHG qreg COMMA addr + { check_size ($2.sz, X86QUAD) + ; `X86CMPXCHG (true, X86S64, $5, $3) + } +| DIV addr + { `X86DIV (suffix_size $1.sz, $2) } +| DIV breg + { check_size ($1.sz, X86BYTE) + ; `X86DIV (X86S8 ($2.high), Reg (IReg ($2.reg))) + } +| DIV wreg + { check_size ($1.sz, X86WORD) + ; `X86DIV (X86S16, Reg $2) + } +| DIV lreg + { check_size ($1.sz, X86LONG) + ; `X86DIV (X86S32, Reg $2) + } +| DIV qreg + { check_size ($1.sz, X86QUAD) + ; `X86DIV (X86S64, Reg $2) + } +| JCC big_num + { `X86JCC ($1.cond, $2) } +| JMP big_num + { `X86JCC (X86ALWAYS, $2) } +| JMP addr + { `X86JMP $2 } +| JMP qreg + { `X86JMP (Reg $2) } +| LEA addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86LEA (X86S16, R_rm ($4, $2)) + } +| LEA addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86LEA (X86S32, R_rm ($4, $2)) + } +| LEA addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86LEA (X86S64, R_rm ($4, $2)) + } +| LEAVE + { `X86LEAVE } +| LOOP big_num + { `X86LOOP ($1.cond, $2) } +| MFENCE + { `X86MFENCE } +| MONOP addr + { `X86MONOP (false, $1.op, suffix_size $1.sz, $2) } +| LOCK MONOP addr + { `X86MONOP (true, $2.op, suffix_size $2.sz, $3) } +| MONOP breg + { check_size ($1.sz, X86BYTE) + ; `X86MONOP (false, $1.op, X86S8 ($2.high), Reg (IReg $2.reg)) + } +| MONOP wreg + { check_size ($1.sz, X86WORD) + ; `X86MONOP (false, $1.op, X86S16, Reg $2) + } +| MONOP lreg + { check_size ($1.sz, X86LONG) + ; `X86MONOP (false, $1.op, X86S32, Reg $2) + } +| MONOP qreg + { check_size ($1.sz, X86QUAD) + ; `X86MONOP (false, $1.op, X86S64, Reg $2) + } +| MOV big_imm COMMA addr + { `X86MOV (X86ALWAYS, suffix_size $1.sz, Rm_i ($4, $2)) } +| MOV imm COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($4.high), Rm_i (Reg (IReg $4.reg), bit64_of_int $2)) + } +| MOV breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86MOV (X86ALWAYS, X86S8 ($4.high), Rm_r (Reg (IReg $4.reg), (IReg $2.reg))) + } +| MOV addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($4.high), R_rm (IReg $4.reg, $2)) + } +| MOV breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($2.high), Rm_r ($4, IReg $2.reg)) + } +| MOV imm COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_i (Reg $4, bit64_of_int $2)) + } +| MOV wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_r (Reg $4, $2)) + } +| MOV addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, R_rm ($4, $2)) + } +| MOV wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_r ($4, $2)) + } +| MOV imm COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_i (Reg $4, bit64_of_int $2)) + } +| MOV lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_r (Reg $4, $2)) + } +| MOV addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, R_rm ($4, $2)) + } +| MOV lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_r ($4, $2)) + } +| MOV big_imm COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86MOV (X86ALWAYS, X86S64, Rm_i (Reg $4, $2)) + } +| MOV qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects and immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, Rm_r (Reg $4, $2)) + } +| MOV addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects and immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, R_rm ($4, $2)) + } +| MOV qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects and immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, Rm_r ($4, $2)) + } +| MOVSX breg COMMA wreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86WORD) + ; `X86MOVSX (X86S16, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVSX breg COMMA lreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVSX breg COMMA qreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVSX wreg COMMA lreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($4, Reg $2), X86S16) + } +| MOVSX wreg COMMA qreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($4, Reg $2), X86S16) + } +| MOVSX lreg COMMA qreg + { check_size ($1.sz1, X86LONG) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($4, Reg $2), X86S32) + } +| MOVSX addr COMMA wreg + { check_size ($1.sz2, X86WORD) + ; `X86MOVSX (X86S16, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVSX addr COMMA lreg + { check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVSX addr COMMA qreg + { check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVZX breg COMMA wreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86WORD) + ; `X86MOVZX (X86S16, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVZX breg COMMA lreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVZX breg COMMA qreg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($4, Reg (IReg $2.reg)), X86S8 $2.high) + } +| MOVZX wreg COMMA lreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($4, Reg $2), X86S16) + } +| MOVZX wreg COMMA qreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($4, Reg $2), X86S16) + } +| MOVZX addr COMMA wreg + { check_size ($1.sz2, X86WORD) + ; `X86MOVZX (X86S16, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVZX addr COMMA lreg + { check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($4, $2), suffix_size $1.sz1) + } +| MOVZX addr COMMA qreg + { check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($4, $2), suffix_size $1.sz1) + } +| MUL addr + { `X86MUL (suffix_size $1.sz, $2) } +| MUL breg + { check_size ($1.sz, X86BYTE) + ; `X86MUL (X86S8 ($2.high), Reg (IReg $2.reg)) + } +| MUL wreg + { check_size ($1.sz, X86WORD) + ; `X86MUL (X86S16, Reg $2) + } +| MUL lreg + { check_size ($1.sz, X86LONG) + ; `X86MUL (X86S32, Reg $2) + } +| MUL qreg + { check_size ($1.sz, X86QUAD) + ; `X86MUL (X86S64, Reg $2) + } +| NOP + { `X86NOP } +| POP qreg + { `X86POP (Reg $2) } +| POP addr + { `X86POP $2 } +| PUSH big_imm + { `X86PUSH (Imm $2) } +| PUSH addr + { `X86PUSH (Rm $2) } +| PUSH qreg + { `X86PUSH (Rm (Reg $2)) } +| RET big_imm + { `X86RET $2 } +| SET breg + { `X86SET ($1.cond, $2.high, Reg (IReg $2.reg)) } +| SET addr + { `X86SET ($1.cond, false, $2) } +| STC + { `X86STC } +| XADD breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86XADD (false, X86S8 ($2.high), Reg (IReg $4.reg), (IReg $2.reg)) + } +| XADD breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86XADD (false, X86S8 ($2.high), $4, (IReg $2.reg)) + } +| LOCK XADD breg COMMA addr + { check_size ($2.sz, X86BYTE) + ; `X86XADD (true, X86S8 ($3.high), $5, (IReg $3.reg)) + } +| XADD wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XADD (false, X86S16, Reg $4, $2) + } +| XADD wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86XADD (false, X86S16, $4, $2) + } +| LOCK XADD wreg COMMA addr + { check_size ($2.sz, X86WORD) + ; `X86XADD (true, X86S16, $5, $3) + } +| XADD lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XADD (false, X86S32, Reg $4, $2) + } +| XADD lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86XADD (false, X86S32, $4, $2) + } +| LOCK XADD lreg COMMA addr + { check_size ($2.sz, X86LONG) + ; `X86XADD (true, X86S32, $5, $3) + } +| XADD qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XADD (false, X86S64, Reg $4, $2) + } +| XADD qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86XADD (false, X86S64, $4, $2) + } +| LOCK XADD qreg COMMA addr + { check_size ($2.sz, X86QUAD) + ; `X86XADD (true, X86S64, $5, $3) + } +| XCHG breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86XCHG (false, X86S8 ($2.high), Reg (IReg $4.reg), IReg $2.reg) + } +| XCHG breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86XCHG (false, X86S8 ($2.high), $4, (IReg $2.reg)) + } +| LOCK XCHG breg COMMA addr + { check_size ($2.sz, X86BYTE) + ; `X86XCHG (true, X86S8 ($3.high), $5, (IReg $3.reg)) + } +| XCHG wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XCHG (false, X86S16, Reg $4, $2) + } +| XCHG wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86XCHG (false, X86S16, $4, $2) + } +| LOCK XCHG wreg COMMA addr + { check_size ($2.sz, X86WORD) + ; `X86XCHG (true, X86S16, $5, $3) + } +| XCHG lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XCHG (false, X86S32, Reg $4, $2) + } +| XCHG lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86XCHG (false, X86S32, $4, $2) + } +| LOCK XCHG lreg COMMA addr + { check_size ($2.sz, X86LONG) + ; `X86XCHG (true, X86S32, $5, $3) + } +| XCHG qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XCHG (false, X86S64, Reg $4, $2) + } +| XCHG qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86XCHG (false, X86S64, $4, $2) + } +| LOCK XCHG qreg COMMA addr + { check_size ($2.sz, X86QUAD) + ; `X86XCHG (true, X86S64, $5, $3) + } diff --git a/x86/gen/parser_intel.hgen b/x86/gen/parser_intel.hgen new file mode 100644 index 00000000..72fa0ede --- /dev/null +++ b/x86/gen/parser_intel.hgen @@ -0,0 +1,601 @@ +| BINOP addr COMMA imm + { `X86BINOP (false, $1.op, suffix_size $1.sz, Rm_i ($2, bit64_of_int $4)) + (* XXX size is ambigious -- should require anotation *) } +| LOCK BINOP addr COMMA imm + { check_binop_lockable $2.op + ; `X86BINOP (true, $2.op, suffix_size $2.sz, Rm_i ($3, bit64_of_int $5)) } +| BINOP breg COMMA imm + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($2.high), Rm_i (Reg (IReg ($2.reg)), bit64_of_int $4)) + } +| BINOP breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86BINOP (false, $1.op, X86S8 ($2.high), Rm_r (Reg (IReg ($2.reg)), IReg ($4.reg))) + } +| BINOP addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($4.high), Rm_r ($2, IReg ($4.reg))) + } +| LOCK BINOP addr COMMA breg + { check_binop_lockable $2.op; + check_size ($2.sz, X86BYTE) + ; `X86BINOP (true, $2.op, X86S8 ($5.high), Rm_r ($3, IReg ($5.reg))) + } +| BINOP breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86BINOP (false, $1.op, X86S8 ($2.high), R_rm (IReg ($2.reg), $4)) + } +| BINOP wreg COMMA imm + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_i (Reg $2, bit64_of_int $4)) + } +| BINOP wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_r (Reg $2, $4)) + } +| BINOP addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, Rm_r ($2, $4)) + } +| LOCK BINOP addr COMMA wreg + { check_binop_lockable $2.op; + check_size ($2.sz, X86WORD) + ; `X86BINOP (true, $2.op, X86S16, Rm_r ($3, $5)) + } +| BINOP wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86BINOP (false, $1.op, X86S16, R_rm ($2, $4)) + } +| BINOP lreg COMMA imm + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_i (Reg $2, bit64_of_int $4)) + } +| BINOP lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_r (Reg $2, $4)) + } +| BINOP addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, Rm_r ($2, $4)) + } +| LOCK BINOP addr COMMA lreg + { check_binop_lockable $2.op; + check_size ($2.sz, X86LONG) + ; `X86BINOP (true, $2.op, X86S32, Rm_r ($3, $5)) + } +| BINOP lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86BINOP (false, $1.op, X86S32, R_rm ($2, $4)) + } +| BINOP qreg COMMA imm + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_i (Reg $2, bit64_of_int $4)) + } +| BINOP qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_r (Reg $2, $4)) + } +| BINOP addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, Rm_r ($2, $4)) + } +| LOCK BINOP addr COMMA qreg + { check_binop_lockable $2.op; + check_size ($2.sz, X86QUAD) + ; `X86BINOP (true, $2.op, X86S64, Rm_r ($3, $5)) + } +| BINOP qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86BINOP (false, $1.op, X86S64, R_rm ($2, $4)) + } +| BITOP addr COMMA imm + { `X86BITOP (false, $1.op, suffix_size $1.sz, Bit_rm_imm ($2, $4)) + } +| LOCK BITOP addr COMMA imm + { `X86BITOP (true, $2.op, suffix_size $2.sz, Bit_rm_imm ($3, $5)) + } +| BITOP wreg COMMA imm + { check_size ($1.sz, X86WORD) + ; `X86BITOP (false, $1.op, X86S16, Bit_rm_imm (Reg $2, $4)) + } +| LOCK BITOP wreg COMMA imm + { check_size ($2.sz, X86WORD) + ; `X86BITOP (true, $2.op, X86S16, Bit_rm_imm (Reg $3, $5)) + } +| BITOP wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BITOP (true, $1.op, X86S16, Bit_rm_r (Reg $2, $4)) + } +| LOCK BITOP wreg COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86BITOP (false, $2.op, X86S16, Bit_rm_r (Reg $3, $5)) + } +| BITOP addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86BITOP (false, $1.op, X86S16, Bit_rm_r ($2, $4)) + } +| LOCK BITOP addr COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86BITOP (true, $2.op, X86S16, Bit_rm_r ($3, $5)) + } +| BITOP lreg COMMA imm + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_imm (Reg $2, $4)) + } +| LOCK BITOP lreg COMMA imm + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_imm (Reg $3, $5)) + } +| BITOP lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_r (Reg $2, $4)) + } +| LOCK BITOP lreg COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_r (Reg $3, $5)) + } +| BITOP addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86BITOP (false, $1.op, X86S32, Bit_rm_r ($2, $4)) + } +| LOCK BITOP addr COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86BITOP (true, $2.op, X86S32, Bit_rm_r ($3, $5)) + } +| BITOP qreg COMMA imm + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_imm (Reg $2, $4)) + } +| LOCK BITOP qreg COMMA imm + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_imm (Reg $3, $5)) + } +| BITOP qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_r (Reg $2, $4)) + } +| LOCK BITOP qreg COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_r (Reg $3, $5)) + } +| BITOP addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86BITOP (false, $1.op, X86S64, Bit_rm_r ($2, $4)) + } +| LOCK BITOP addr COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86BITOP (true, $2.op, X86S64, Bit_rm_r ($3, $5)) + } +| CALL big_imm + { `X86CALL (Imm $2) } +| CALL addr + { `X86CALL (Rm $2) } +| CALL qreg + { `X86CALL (Rm (Reg $2)) } +| CLC + { `X86CLC } +| CMC + { `X86CMC } +| CMOV wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86MOV ($1.cond, X86S16, R_rm ($2, $4)) + } +| CMOV lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86MOV ($1.cond, X86S32, R_rm ($2, $4)) + } +| CMOV qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86MOV ($1.cond, X86S64, R_rm ($2, $4)) + } +| CMOV wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV ($1.cond, X86S16, R_rm ($2, Reg $4)) + } +| CMOV lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV ($1.cond, X86S32, R_rm ($2, Reg $4)) + } +| CMOV qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86MOV ($1.cond, X86S64, R_rm ($2, Reg $4)) + } +| CMPXCHG breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86CMPXCHG (false, X86S8 ($2.high), Reg (IReg ($2.reg)), IReg ($4.reg)) + } +| CMPXCHG addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86CMPXCHG (false, X86S8 ($4.high), $2, IReg ($4.reg)) + } +| LOCK CMPXCHG addr COMMA breg + { check_size ($2.sz, X86BYTE) + ; `X86CMPXCHG (true, X86S8 ($5.high), $3, IReg ($5.reg)) + } +| CMPXCHG wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86CMPXCHG (false, X86S16, Reg $2, $4) + } +| CMPXCHG addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86CMPXCHG (false, X86S16, $2, $4) + } +| LOCK CMPXCHG addr COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86CMPXCHG (true, X86S16, $3, $5) + } +| CMPXCHG lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86CMPXCHG (false, X86S32, Reg $2, $4) + } +| CMPXCHG addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86CMPXCHG (false, X86S32, $2, $4) + } +| LOCK CMPXCHG addr COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86CMPXCHG (true, X86S32, $3, $5) + } +| CMPXCHG qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86CMPXCHG (false, X86S64, Reg $2, $4) + } +| CMPXCHG addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86CMPXCHG (false, X86S64, $2, $4) + } +| LOCK CMPXCHG addr COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86CMPXCHG (true, X86S64, $3, $5) + } +| DIV addr + { `X86DIV (suffix_size $1.sz, $2) } +| DIV breg + { check_size ($1.sz, X86BYTE) + ; `X86DIV (X86S8 ($2.high), Reg (IReg ($2.reg))) + } +| DIV wreg + { check_size ($1.sz, X86WORD) + ; `X86DIV (X86S16, Reg $2) + } +| DIV lreg + { check_size ($1.sz, X86LONG) + ; `X86DIV (X86S32, Reg $2) + } +| DIV qreg + { check_size ($1.sz, X86QUAD) + ; `X86DIV (X86S64, Reg $2) + } +| JCC big_num + { `X86JCC ($1.cond, $2) } +| JMP big_num + { `X86JCC (X86ALWAYS, $2) } +| JMP addr + { `X86JMP $2 } +| JMP qreg + { `X86JMP (Reg $2) } +| LEA wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86LEA (X86S16, R_rm ($2, $4)) + } +| LEA lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86LEA (X86S32, R_rm ($2, $4)) + } +| LEA qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; `X86LEA (X86S64, R_rm ($2, $4)) + } +| LEAVE + { `X86LEAVE } +| LOOP big_num + { `X86LOOP ($1.cond, $2) } +| MFENCE + { `X86MFENCE } +| MONOP addr + { `X86MONOP (false, $1.op, suffix_size $1.sz, $2) } +| LOCK MONOP addr + { `X86MONOP (true, $2.op, suffix_size $2.sz, $3) } +| MONOP breg + { check_size ($1.sz, X86BYTE) + ; `X86MONOP (false, $1.op, X86S8 ($2.high), Reg (IReg $2.reg)) + } +| MONOP wreg + { check_size ($1.sz, X86WORD) + ; `X86MONOP (false, $1.op, X86S16, Reg $2) + } +| MONOP lreg + { check_size ($1.sz, X86LONG) + ; `X86MONOP (false, $1.op, X86S32, Reg $2) + } +| MONOP qreg + { check_size ($1.sz, X86QUAD) + ; `X86MONOP (false, $1.op, X86S64, Reg $2) + } +| MOV addr COMMA big_imm + { `X86MOV (X86ALWAYS, suffix_size $1.sz, Rm_i ($2, $4)) } +| MOV breg COMMA imm + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($2.high), Rm_i (Reg (IReg $2.reg), bit64_of_int $4)) + } +| MOV breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86MOV (X86ALWAYS, X86S8 ($2.high), Rm_r (Reg (IReg $2.reg), (IReg $4.reg))) + } +| MOV addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($4.high), Rm_r ($2, IReg $4.reg)) + } +| MOV breg COMMA addr + { check_size ($1.sz, X86BYTE) + ; `X86MOV (X86ALWAYS, X86S8 ($2.high), R_rm (IReg $2.reg, $4)) + } +| MOV wreg COMMA imm + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_i (Reg $2, bit64_of_int $4)) + } +| MOV wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_r (Reg $2, $4)) + } +| MOV addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, Rm_r ($2, $4)) + } +| MOV wreg COMMA addr + { check_size ($1.sz, X86WORD) + ; `X86MOV (X86ALWAYS, X86S16, R_rm ($2, $4)) + } +| MOV lreg COMMA imm + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_i (Reg $2, bit64_of_int $4)) + } +| MOV lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_r (Reg $2, $4)) + } +| MOV addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, Rm_r ($2, $4)) + } +| MOV lreg COMMA addr + { check_size ($1.sz, X86LONG) + ; `X86MOV (X86ALWAYS, X86S32, R_rm ($2, $4)) + } +| MOV qreg COMMA big_imm + { check_size ($1.sz, X86QUAD) + ; `X86MOV (X86ALWAYS, X86S64, Rm_i (Reg $2, $4)) + } +| MOV qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects an immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, Rm_r (Reg $2, $4)) + } +| MOV addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects an immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, Rm_r ($2, $4)) + } +| MOV qreg COMMA addr + { check_size ($1.sz, X86QUAD) + ; if $1.txt = "MOVABS" then failwith "movabs expects an immediate" else () + ; `X86MOV (X86ALWAYS, X86S64, R_rm ($2, $4)) + } +| MOVSX wreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86WORD) + ; `X86MOVSX (X86S16, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVSX lreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVSX qreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVSX lreg COMMA wreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($2, Reg $4), X86S16) + } +| MOVSX qreg COMMA wreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($2, Reg $4), X86S16) + } +| MOVSX qreg COMMA lreg + { check_size ($1.sz1, X86LONG) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($2, Reg $4), X86S32) + } +| MOVSX wreg COMMA addr + { check_size ($1.sz2, X86WORD) + ; `X86MOVSX (X86S16, R_rm ($2, $4), suffix_size $1.sz1) (* XXX size *) + } +| MOVSX lreg COMMA addr + { check_size ($1.sz2, X86LONG) + ; `X86MOVSX (X86S32, R_rm ($2, $4), suffix_size $1.sz1) + } +| MOVSX qreg COMMA addr + { check_size ($1.sz2, X86QUAD) + ; `X86MOVSX (X86S64, R_rm ($2, $4), suffix_size $1.sz1) + } +| MOVZX wreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86WORD) + ; `X86MOVZX (X86S16, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVZX lreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVZX qreg COMMA breg + { check_size ($1.sz1, X86BYTE) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($2, Reg (IReg $4.reg)), X86S8 $4.high) + } +| MOVZX lreg COMMA wreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($2, Reg $4), X86S16) + } +| MOVZX qreg COMMA wreg + { check_size ($1.sz1, X86WORD) + ; check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($2, Reg $4), X86S16) + } +| MOVZX wreg COMMA addr + { check_size ($1.sz2, X86WORD) + ; `X86MOVZX (X86S16, R_rm ($2, $4), suffix_size $1.sz1) (* XXX size *) + } +| MOVZX lreg COMMA addr + { check_size ($1.sz2, X86LONG) + ; `X86MOVZX (X86S32, R_rm ($2, $4), suffix_size $1.sz1) + } +| MOVZX qreg COMMA addr + { check_size ($1.sz2, X86QUAD) + ; `X86MOVZX (X86S64, R_rm ($2, $4), suffix_size $1.sz1) + } +| MUL addr + { `X86MUL (suffix_size $1.sz, $2) } +| MUL breg + { check_size ($1.sz, X86BYTE) + ; `X86MUL (X86S8 ($2.high), Reg (IReg $2.reg)) + } +| MUL wreg + { check_size ($1.sz, X86WORD) + ; `X86MUL (X86S16, Reg $2) + } +| MUL lreg + { check_size ($1.sz, X86LONG) + ; `X86MUL (X86S32, Reg $2) + } +| MUL qreg + { check_size ($1.sz, X86QUAD) + ; `X86MUL (X86S64, Reg $2) + } +| NOP + { `X86NOP } +| POP qreg + { `X86POP (Reg $2) } +| POP addr + { `X86POP $2 } +| PUSH big_imm + { `X86PUSH (Imm $2) } +| PUSH addr + { `X86PUSH (Rm $2) } +| PUSH qreg + { `X86PUSH (Rm (Reg $2)) } +| RET big_imm + { `X86RET $2 } +| SET breg + { `X86SET ($1.cond, $2.high, Reg (IReg $2.reg)) } +| SET addr + { `X86SET ($1.cond, false, $2) } +| STC + { `X86STC } +| XADD breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86XADD (false, X86S8 ($2.high), Reg (IReg $2.reg), (IReg $4.reg)) + } +| XADD addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86XADD (false, X86S8 ($4.high), $2, (IReg $4.reg)) + } +| LOCK XADD addr COMMA breg + { check_size ($2.sz, X86BYTE) + ; `X86XADD (true, X86S8 ($5.high), $3, (IReg $5.reg)) + } +| XADD wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XADD (false, X86S16, Reg $2, $4) + } +| XADD addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XADD (false, X86S16, $2, $4) + } +| LOCK XADD addr COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86XADD (true, X86S16, $3, $5) + } +| XADD lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XADD (false, X86S32, Reg $2, $4) + } +| XADD addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XADD (false, X86S32, $2, $4) + } +| LOCK XADD addr COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86XADD (true, X86S32, $3, $5) + } +| XADD qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XADD (false, X86S64, Reg $2, $4) + } +| XADD addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XADD (false, X86S64, $2, $4) + } +| LOCK XADD addr COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86XADD (true, X86S64, $3, $5) + } +| XCHG breg COMMA breg + { check_size ($1.sz, X86BYTE) + ; check_byte_regs ($2, $4) + ; `X86XCHG (false, X86S8 ($2.high), Reg (IReg $2.reg), IReg $4.reg) + } +| XCHG addr COMMA breg + { check_size ($1.sz, X86BYTE) + ; `X86XCHG (false, X86S8 ($4.high), $2, (IReg $4.reg)) + } +| LOCK XCHG addr COMMA breg + { check_size ($2.sz, X86BYTE) + ; `X86XCHG (true, X86S8 ($5.high), $3, (IReg $5.reg)) + } +| XCHG wreg COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XCHG (false, X86S16, Reg $2, $4) + } +| XCHG addr COMMA wreg + { check_size ($1.sz, X86WORD) + ; `X86XCHG (false, X86S16, $2, $4) + } +| LOCK XCHG addr COMMA wreg + { check_size ($2.sz, X86WORD) + ; `X86XCHG (true, X86S16, $3, $5) + } +| XCHG lreg COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XCHG (false, X86S32, Reg $2, $4) + } +| XCHG addr COMMA lreg + { check_size ($1.sz, X86LONG) + ; `X86XCHG (false, X86S32, $2, $4) + } +| LOCK XCHG addr COMMA lreg + { check_size ($2.sz, X86LONG) + ; `X86XCHG (true, X86S32, $3, $5) + } +| XCHG qreg COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XCHG (false, X86S64, Reg $2, $4) + } +| XCHG addr COMMA qreg + { check_size ($1.sz, X86QUAD) + ; `X86XCHG (false, X86S64, $2, $4) + } +| LOCK XCHG addr COMMA qreg + { check_size ($2.sz, X86QUAD) + ; `X86XCHG (true, X86S64, $3, $5) + } diff --git a/x86/gen/pretty.hgen b/x86/gen/pretty.hgen new file mode 100644 index 00000000..fc0c59d4 --- /dev/null +++ b/x86/gen/pretty.hgen @@ -0,0 +1,50 @@ +| `X86BINOP (locked, bop, sz, dst_src) -> + pp_locked locked ^ pp_x86Binop bop ^ pp_x86Size sz ^ " " ^ pp_x86Dest_src (sz, dst_src) +| `X86BITOP (locked, bop, sz, bo) -> + pp_locked locked ^ pp_x86Bitop bop ^ pp_x86Size sz ^ " " ^ pp_x86Bit_offset (sz, bo) +| `X86CALL (Imm i) -> "call " ^ " $" ^ bit64_to_string i +| `X86CALL (Rm rm) -> "call " ^ pp_x86Rm (X86S64, rm) +| `X86CLC -> "clc" +| `X86CMC -> "cmc" +| `X86CMPXCHG (locked, sz, rm, r) -> + sprintf "%scmpxchg%s %s, %s" + (pp_locked locked) (pp_x86Size sz) (pp_size_reg sz r) (pp_x86Rm (sz, rm)) +| `X86DIV (sz, rm) -> "div" ^ pp_x86Size sz ^ " " ^ pp_x86Rm (sz, rm) +| `X86JCC (X86ALWAYS, i) -> "jmp " ^ bit64_to_string i +| `X86JCC (cnd, i) -> "j" ^ pp_x86Cond cnd ^ " " ^ bit64_to_string i +| `X86JMP (rm) -> "jmp " ^ pp_x86Rm(X86S64, rm) +| `X86LEA (sz, dst_src) -> + "lea" ^ (pp_x86Size sz) ^ " " ^ pp_x86Dest_src (sz, dst_src) +| `X86LEAVE -> "leave" +| `X86LOOP (cnd, i) -> "loop" ^ pp_x86Cond cnd ^ " " ^ bit64_to_string i +| `X86MFENCE -> "mfence" +| `X86MONOP (locked, mop, sz, rm) -> + pp_x86Monop mop ^ pp_x86Size sz ^ " " ^ pp_x86Rm (sz, rm) +| `X86MOV (X86ALWAYS, sz, dst_src) -> + "mov" ^ pp_x86Size sz ^ " " ^ pp_x86Dest_src (sz, dst_src) +| `X86MOV (cnd, sz, dst_src) -> + "cmov" ^ pp_x86Cond cnd ^ pp_x86Size sz ^ " " ^ pp_x86Dest_src (sz, dst_src) +| `X86MOVSX (sz1, R_rm (r, rm), sz2) -> + "movs" ^ pp_x86Size sz1 ^ pp_x86Size sz2 ^ " " ^ pp_x86Rm (sz1, rm) ^ + ", " ^ pp_size_reg sz2 r +| `X86MOVSX (sz1, _, sz2) -> failwith "bad movsx instruction" +| `X86MOVZX (sz1, R_rm (r, rm), sz2) -> + "movz" ^ pp_x86Size sz1 ^ pp_x86Size sz2 ^ " " ^ pp_x86Rm (sz1, rm) ^ + ", " ^ pp_size_reg sz2 r +| `X86MOVZX (sz1, _, sz2) -> failwith "bad movzx instruction" +| `X86MUL (sz, rm) -> "mul" ^ pp_x86Size sz ^ " " ^ pp_x86Rm (sz, rm) +| `X86NOP -> "nop" +| `X86POP rm -> "pop " ^ (pp_x86Rm (X86S64, rm)) +| `X86PUSH (Imm i) -> "push $" ^ bit64_to_string i +| `X86PUSH (Rm rm) -> "push " ^ pp_x86Rm (X86S64, rm) +| `X86RET i -> "ret " ^ bit64_to_string i +| `X86SET (cnd, b, rm) -> "set" ^ pp_x86Cond cnd ^ " " ^ pp_x86Rm (X86S8 b, rm) +| `X86STC -> "stc" +| `X86XADD (locked, sz, rm, r) -> + sprintf "%s xadd%s %s, %s" + (pp_locked locked) (pp_x86Size sz) (pp_size_reg sz r) (pp_x86Rm (sz, rm)) +| `X86XCHG (locked, sz, rm, r) -> + sprintf "%sxchg%s %s, %s" + (pp_locked locked) (pp_x86Size sz) (pp_size_reg sz r) (pp_x86Rm (sz, rm)) +| `X86ThreadStart -> "start" +| `X86StopFetching -> "hlt" diff --git a/x86/gen/sail_trans_out.hgen b/x86/gen/sail_trans_out.hgen new file mode 100644 index 00000000..948db8fa --- /dev/null +++ b/x86/gen/sail_trans_out.hgen @@ -0,0 +1 @@ +(* *) diff --git a/x86/gen/shallow_ast_to_herdtools_ast.hgen b/x86/gen/shallow_ast_to_herdtools_ast.hgen new file mode 100644 index 00000000..ed5d6680 --- /dev/null +++ b/x86/gen/shallow_ast_to_herdtools_ast.hgen @@ -0,0 +1,27 @@ +| Binop (locked, binop, sz, dest_src) -> `X86BINOP (translate_out_bool locked, translate_out_binop binop, translate_out_size sz, translate_out_dest_src dest_src) +| Bitop (locked, bitop, sz, bo) -> `X86BITOP (translate_out_bool locked, translate_out_bitop bitop, translate_out_size sz, translate_out_bitoffset bo) +| CALL (imm_rm) -> `X86CALL (translate_out_imm_rm imm_rm) +| CLC -> `X86CLC +| CMC -> `X86CMC +| CMPXCHG (locked, sz, rm , reg) -> `X86CMPXCHG (translate_out_bool locked, translate_out_size sz, translate_out_rm rm, translate_out_reg reg) +| X86_DIV (sz, rm) -> `X86DIV (translate_out_size sz, translate_out_rm rm) +| HLT -> `X86StopFetching +| Jcc (cond, imm64) -> `X86JCC (translate_out_cond cond, translate_out_imm64 imm64) +| JMP (rm) -> `X86JMP (translate_out_rm rm) +| LEA (sz, dest_src) -> `X86LEA (translate_out_size sz, translate_out_dest_src dest_src) +| LEAVE -> `X86LEAVE +| LOOP (cond, imm64) -> `X86LOOP (translate_out_cond cond, translate_out_imm64 imm64) +| MFENCE -> `X86MFENCE +| Monop (locked, monop, sz, rm) -> `X86MONOP (translate_out_bool locked, translate_out_monop monop, translate_out_size sz, translate_out_rm rm) +| MOV (cond, sz, dest_src) -> `X86MOV (translate_out_cond cond, translate_out_size sz, translate_out_dest_src dest_src) +| MOVSX (sz1, dest_src, sz2) -> `X86MOVSX (translate_out_size sz1, translate_out_dest_src dest_src, translate_out_size sz2) +| MOVZX (sz1, dest_src, sz2) -> `X86MOVZX (translate_out_size sz1, translate_out_dest_src dest_src, translate_out_size sz2) +| X86_MUL (sz, rm) -> `X86MUL (translate_out_size sz, translate_out_rm rm) +| NOP (_) -> `X86NOP +| POP (rm) -> `X86POP (translate_out_rm rm) +| PUSH (imm_rm) -> `X86PUSH (translate_out_imm_rm imm_rm) +| RET (imm64) -> `X86RET (translate_out_imm64 imm64) +| SET (cond, b, rm) -> `X86SET (translate_out_cond cond, translate_out_bool b, translate_out_rm rm) +| STC -> `X86STC +| XADD (locked, sz, rm, reg) -> `X86XADD (translate_out_bool locked, translate_out_size sz, translate_out_rm rm, translate_out_reg reg) +| XCHG (locked, sz, rm, reg) -> `X86XCHG (translate_out_bool locked, translate_out_size sz, translate_out_rm rm, translate_out_reg reg) diff --git a/x86/gen/shallow_types_to_herdtools_types.hgen b/x86/gen/shallow_types_to_herdtools_types.hgen new file mode 100644 index 00000000..ba4eccaa --- /dev/null +++ b/x86/gen/shallow_types_to_herdtools_types.hgen @@ -0,0 +1,97 @@ +let is_inc = false + +let translate_out_bool = function + | Sail_values.B1 -> true + | Sail_values.B0 -> false + | _ -> failwith "translate_out_bool Undef" + +let translate_out_binop = function + | X86_Add -> X86ADD + | X86_Or -> X86OR + | X86_Adc -> X86ADC + | X86_Sbb -> X86SBB + | X86_And -> X86AND + | X86_Sub -> X86SUB + | X86_Xor -> X86XOR + | X86_Cmp -> X86CMP + | X86_Rol -> X86ROL + | X86_Ror -> X86ROR + | X86_Rcl -> X86RCL + | X86_Rcr -> X86RCR + | X86_Shl -> X86SHL + | X86_Shr -> X86SHR + | X86_Test -> X86TEST + | X86_Sar -> X86SAR + +let translate_out_bitop = function + | Btc -> X86Btc + | Bts -> X86Bts + | Btr -> X86Btr + +let translate_out_size = function + | Sz8 (high) -> X86S8 (translate_out_bool high) + | Sz16 -> X86S16 + | Sz32 -> X86S32 + | Sz64 -> X86S64 + +let translate_out_big_bit = Sail_values.unsigned + +let translate_out_int inst = (Nat_big_num.to_int (translate_out_big_bit inst)) + +let translate_out_reg r = IReg (int_to_ireg (Nat_big_num.to_int r)) + +let translate_out_scale = translate_out_int + +let translate_out_imm64 i = translate_out_big_bit i + +let translate_out_msi = function + | Some (scale, reg) -> Some (translate_out_scale scale, translate_out_reg reg) + | None -> None + +let translate_out_base = function + | X86_embed_types.NoBase -> X86HGenBase.NoBase + | X86_embed_types.RegBase(r) -> X86HGenBase.RegBase (translate_out_reg r) + | X86_embed_types.RipBase -> X86HGenBase.RipBase + +let translate_out_rm = function + | X86_embed_types.X86_Reg (r) -> X86HGenBase.Reg (translate_out_reg r) + | X86_embed_types.Mem (m_si, base, imm) -> X86HGenBase.Mem (translate_out_msi m_si, translate_out_base base, translate_out_imm64 imm) + +let translate_out_dest_src = function + | X86_embed_types.R_rm (reg, rm) -> X86HGenBase.R_rm (translate_out_reg reg, translate_out_rm rm) + | X86_embed_types.Rm_i (rm, imm64) -> X86HGenBase.Rm_i (translate_out_rm rm, translate_out_imm64 imm64) + | X86_embed_types.Rm_r (rm, reg) -> X86HGenBase.Rm_r (translate_out_rm rm, translate_out_reg reg) + +let translate_out_imm_rm = function + | X86_embed_types.Imm (imm) -> X86HGenBase.Imm (translate_out_imm64 imm) + | X86_embed_types.Rm (rm) -> X86HGenBase.Rm (translate_out_rm rm) + +let translate_out_bitoffset = function + | Bit_rm_imm (rm, imm) -> X86HGenBase.Bit_rm_imm (translate_out_rm rm, Nat_big_num.to_int (translate_out_imm64 imm)) + | Bit_rm_r (rm, r) -> X86HGenBase.Bit_rm_r (translate_out_rm rm, translate_out_reg r) + +let translate_out_cond = function + | X86_O -> X86O + | X86_NO -> X86NO + | X86_B -> X86B + | X86_NB -> X86NB + | X86_E -> X86E + | X86_NE -> X86NE + | X86_NA -> X86NA + | X86_A -> X86A + | X86_S -> X86S + | X86_NS -> X86NS + | X86_P -> X86P + | X86_NP -> X86NP + | X86_L -> X86L + | X86_NL -> X86NL + | X86_NG -> X86NG + | X86_G -> X86G + | X86_ALWAYS -> X86ALWAYS + +let translate_out_monop = function + | X86_Dec -> X86DEC + | X86_Inc -> X86INC + | X86_Not -> X86NOT + | X86_Neg -> X86NEG + diff --git a/x86/gen/token_types.hgen b/x86/gen/token_types.hgen new file mode 100644 index 00000000..9485e544 --- /dev/null +++ b/x86/gen/token_types.hgen @@ -0,0 +1,29 @@ +type token_BINOP = { txt : string; op : x86Binop; sz : x86Suffix } +type token_BITOP = { txt : string; op : x86Bitop; sz : x86Suffix } +type token_CALL = { txt : string } +type token_CLC = { txt : string } +type token_CMC = { txt : string } +type token_CMOV = { txt : string; cond : x86Cond; sz : x86Suffix } +type token_CMPXCHG = { txt : string; sz : x86Suffix } +type token_DIV = { txt : string; sz : x86Suffix } +type token_JCC = { txt : string; cond : x86Cond } +type token_JMP = { txt : string } +type token_LEA = { txt : string; sz : x86Suffix } +type token_LEAVE = { txt : string } +type token_LOOP = { txt : string; cond : x86Cond } +type token_MFENCE = { txt : string; } +type token_MONOP = { txt : string; op : x86Monop; sz : x86Suffix } +type token_MOV = { txt : string; sz : x86Suffix } +type token_MOVABS = { txt : string } +type token_MOVSX = { txt : string; sz1 : x86Suffix; sz2 : x86Suffix } +type token_MOVZX = { txt : string; sz1 : x86Suffix; sz2 : x86Suffix } +type token_MUL = { txt : string; sz : x86Suffix } +type token_NOP = { txt : string } +type token_POP = { txt : string } +type token_PUSH = { txt : string } +type token_RET = { txt : string } +type token_SET = { txt : string; cond : x86Cond } +type token_STC = { txt : string } +type token_XADD = { txt : string; sz : x86Suffix } +type token_XCHG = { txt : string; sz : x86Suffix } + diff --git a/x86/gen/tokens.hgen b/x86/gen/tokens.hgen new file mode 100644 index 00000000..7aa5256f --- /dev/null +++ b/x86/gen/tokens.hgen @@ -0,0 +1,28 @@ +%token <X86HGenBase.token_BINOP> BINOP +%token <X86HGenBase.token_BITOP> BITOP +%token <X86HGenBase.token_CALL> CALL +%token <X86HGenBase.token_CLC> CLC +%token <X86HGenBase.token_CMC> CMC +%token <X86HGenBase.token_CMPXCHG> CMPXCHG +%token <X86HGenBase.token_DIV> DIV +%token <X86HGenBase.token_JCC> JCC +%token <X86HGenBase.token_JMP> JMP +%token <X86HGenBase.token_LEA> LEA +%token <X86HGenBase.token_LEAVE> LEAVE +%token <X86HGenBase.token_LOOP> LOOP +%token <X86HGenBase.token_MFENCE> MFENCE +%token <X86HGenBase.token_MONOP> MONOP +%token <X86HGenBase.token_CMOV> CMOV +%token <X86HGenBase.token_MOV> MOV +%token <X86HGenBase.token_MOVABS> MOVABS +%token <X86HGenBase.token_MOVSX> MOVSX +%token <X86HGenBase.token_MOVZX> MOVZX +%token <X86HGenBase.token_MUL> MUL +%token <X86HGenBase.token_NOP> NOP +%token <X86HGenBase.token_POP> POP +%token <X86HGenBase.token_PUSH> PUSH +%token <X86HGenBase.token_RET> RET +%token <X86HGenBase.token_SET> SET +%token <X86HGenBase.token_STC> STC +%token <X86HGenBase.token_XADD> XADD +%token <X86HGenBase.token_XCHG> XCHG diff --git a/x86/gen/trans_sail.hgen b/x86/gen/trans_sail.hgen new file mode 100644 index 00000000..0fdfc803 --- /dev/null +++ b/x86/gen/trans_sail.hgen @@ -0,0 +1,28 @@ +(*| `X86BINOP(binop, sz, dest_src) -> ("Binop", [translate_binop binop; translate_size sz; translate_dest_src dest_src], []) +| `X86CALL (imm_rm) -> ("CALL", [translate_imm_rm imm_rm], []) +| `X86CLC -> ("CLC", [], []) +| `X86CMC -> ("CMC", [], []) +| `X86CMPXCHG (sz, rm , reg) -> ("CMPXCHG", [translate_size sz; translate_rm rm; translate_reg reg], []) +| `X86DIV (sz, rm) -> ("DIV", [translate_size sz; translate_rm rm], []) +| `X86StopFetching -> ("HLT", [], []) +| `X86JCC (cond, imm64) -> ("Jcc", [translate_cond cond; translate_imm64 imm64], []) +| `X86JMP (rm) -> ("JMP", [translate_rm rm], []) +| `X86LEA (sz, dest_src) -> ("LEA", [translate_size sz; translate_dest_src dest_src], []) +| `X86LEAVE -> ("LEAVE", [], []) +| `X86LOOP (cond, imm64) -> ("LOOP", [translate_cond cond; translate_imm64 imm64], []) +| `X86MFENCE -> ("MFENCE", [], []) +| `X86MONOP (monop, sz, rm) -> ("Monop", [translate_monop monop; translate_size sz; translate_rm rm], []) +| `X86MOV (cond, sz, dest_src) -> ("MOV", [translate_cond cond; translate_size sz; translate_dest_src dest_src], []) +| `X86MOVSX (sz1, dest_src, sz2) -> ("MOVSX", [translate_size sz1; translate_dest_src dest_src; translate_size sz2], []) +| `X86MOVZX (sz1, dest_src, sz2) -> ("MOVZX", [translate_size sz1; translate_dest_src dest_src; translate_size sz2], []) +| `X86MUL (sz, rm) -> ("MUL", [translate_size sz; translate_rm rm], []) +| `X86NOP -> ("NOP", [Nat_big_num.of_int 0], []) +| `X86POP (rm) -> ("POP", [translate_rm rm], []) +| `X86PUSH (imm_rm) -> ("PUSH", [translate_imm_rm imm_rm], []) +| `X86RET (imm64) -> ("RET", [translate_imm64 imm64], []) +| `X86SET (cond, b, rm) -> ("SET", [translate_cond cond; translate_bool b; translate_rm rm], []) +| `X86STC -> ("STC", [], []) +| `X86XADD (sz, rm, reg) -> ("XADD", [translate_size sz; translate_rm rm; translate_reg reg], []) +| `X86XCHG (sz, rm, reg) -> ("XCHG", [translate_size sz; translate_rm rm; translate_reg reg], []) + +*)
\ No newline at end of file diff --git a/x86/gen/types.hgen b/x86/gen/types.hgen new file mode 100644 index 00000000..117f0f4d --- /dev/null +++ b/x86/gen/types.hgen @@ -0,0 +1,134 @@ +type bit2 = int +type bit64 = Nat_big_num.num +let bit64_of_int = Nat_big_num.of_int +let bit64_to_int = Nat_big_num.to_int +let bit64_to_string = Nat_big_num.to_string +let eq_bit64 = Nat_big_num.equal + +type x86Binop = +| X86ADD +| X86OR +| X86ADC +| X86SBB +| X86AND +| X86SUB +| X86XOR +| X86CMP +| X86ROL +| X86ROR +| X86RCL +| X86RCR +| X86SHL +| X86SHR +| X86TEST +| X86SAR + +let pp_x86Binop = function +| X86ADD -> "add" +| X86OR -> "or" +| X86ADC -> "adc" +| X86SBB -> "sbb" +| X86AND -> "and" +| X86SUB -> "sub" +| X86XOR -> "xor" +| X86CMP -> "cmp" +| X86ROL -> "rol" +| X86ROR -> "ror" +| X86RCL -> "rcl" +| X86RCR -> "rcr" +| X86SHL -> "shl" +| X86SHR -> "shr" +| X86TEST -> "test" +| X86SAR -> "sar" + +type x86Bitop = X86Bts | X86Btc | X86Btr + +let pp_x86Bitop = function +| X86Bts -> "bts" +| X86Btc -> "btc" +| X86Btr -> "btr" + +type x86Monop = +| X86DEC +| X86INC +| X86NOT +| X86NEG + +let pp_x86Monop = function +| X86DEC -> "dec" +| X86INC -> "inc" +| X86NOT -> "not" +| X86NEG -> "neg" + +type x86Cond = +| X86O +| X86NO +| X86B +| X86NB +| X86E +| X86NE +| X86NA +| X86A +| X86S +| X86NS +| X86P +| X86NP +| X86L +| X86NL +| X86NG +| X86G +| X86ALWAYS + +let pp_x86Cond = function +| X86O -> "o" +| X86NO -> "no" +| X86B -> "b" +| X86NB -> "nb" +| X86E -> "e" +| X86NE -> "ne" +| X86NA -> "na" +| X86A -> "a" +| X86S -> "s" +| X86NS -> "ns" +| X86P -> "p" +| X86NP -> "np" +| X86L -> "l" +| X86NL -> "nl" +| X86NG -> "ng" +| X86G -> "g" +| X86ALWAYS -> "" + +type x86Suffix = +| X86BYTE +| X86WORD +| X86LONG +| X86QUAD +| X86NONE + +let pp_x86Suffix = function +| X86BYTE -> "byte" +| X86WORD -> "word" +| X86LONG -> "long" +| X86QUAD -> "quad" +| X86NONE -> "" + +type x86Size = +| X86S8 of bool +| X86S16 +| X86S32 +| X86S64 + +let pp_x86Size = function +| X86S8(_) -> "b" +| X86S16 -> "w" +| X86S32 -> "l" +| X86S64 -> "q" + +let pp_locked l = if l then "lock " else "" + +let suffix_size = function +| X86BYTE -> X86S8 false +| X86WORD -> X86S16 +| X86LONG -> X86S32 +| X86QUAD -> X86S64 +| X86NONE -> X86S64 diff --git a/x86/gen/types_sail_trans_out.hgen b/x86/gen/types_sail_trans_out.hgen new file mode 100644 index 00000000..948db8fa --- /dev/null +++ b/x86/gen/types_sail_trans_out.hgen @@ -0,0 +1 @@ +(* *) diff --git a/x86/gen/types_trans_sail.hgen b/x86/gen/types_trans_sail.hgen new file mode 100644 index 00000000..f088db39 --- /dev/null +++ b/x86/gen/types_trans_sail.hgen @@ -0,0 +1,61 @@ +(*let translate_enum enum_values name value = + let rec bit_count n = + if n = 0 then 0 + else 1 + (bit_count (n lsr 1)) in + let rec find_index element = function + | h::tail -> if h = element then 0 else 1 + (find_index element tail) + | _ -> failwith "translate_enum could not find value" + in + let size = bit_count (List.length enum_values) in + let index = find_index value enum_values in + (name, Range0 (Some size), IInt.bit_list_of_integer size (Nat_big_num.of_int index)) + +let translate_binop = translate_enum [X86ADD ; X86OR ; X86ADC ; X86SBB ; X86AND ; X86SUB ; X86XOR ; X86CMP ; X86ROL ; X86ROR ; X86RCL ; X86RCR ; X86SHL ; X86SHR ; X86TEST; X86SAR] + +let translate_cond = translate_enum [X86O ; X86NO ; X86B ; X86NB ; X86E ; X86NE ; X86NA ; X86A ; X86S ; X86NS ; X86P ; X86NP ; X86L ; X86NL ; X86NG ; X86G ; X86ALWAYS ] + +let translate_monop = translate_enum [X86DEC; X86INC; X86NOT; X86NEG] + +let translate_bool value = + ("bool", Bit, [if value then Bitc_one else Bitc_zero]) + +let translate_size = function + | X86S8(high) -> ("Sz8", [translate_bool high], []) + | X86S16 -> ("Sz16", [], []) + | X86S32 -> ("Sz32", [], []) + | X86S64 -> ("Sz64", [], []) + +let translate_bits bits value = + ("bits", Bvector (Some bits), IInt.bit_list_of_integer bits (Nat_big_num.of_int value)) + +let translate_bits_big bits value = + ("bits", Bvector (Some bits), IInt.bit_list_of_integer bits value) + +let translate_reg r = translate_bits 4 (reg_to_int r) + +let translate_scale s = translate_bits 2 s + +let translate_imm64 i = translate_bits_big 64 i + +let translate_msi = function + | Some (scale, reg) -> ("Some", [translate_scale scale; translate_reg reg], []) + | None -> ("None", [], []) + +let translate_base = function + | X86HGenBase.NoBase -> ("NoBase", [], []) + | X86HGenBase.RegBase(r) -> ("RegBase", [translate_reg r], []) + | X86HGenBase.RipBase -> ("RipBase", [], []) + +let translate_rm = function + | X86HGenBase.Reg (r) -> ("Reg", [translate_reg r], []) + | X86HGenBase.Mem (m_si, base, imm) -> ("Mem", [translate_msi m_si; translate_base base; translate_imm64 imm], []) + +let translate_dest_src = function + | X86HGenBase.R_rm (reg, rm) -> ("R_rm", [translate_reg reg; translate_rm rm], []) + | X86HGenBase.Rm_i (rm, imm64) -> ("Rm_i", [translate_rm rm; translate_imm64 imm64], []) + | X86HGenBase.Rm_r (rm, reg) -> ("Rm_r", [translate_rm rm; translate_reg reg], []) + +let translate_imm_rm = function + | X86HGenBase.Imm (imm) -> ("Imm", [translate_imm64 imm], []) + | X86HGenBase.Rm (rm) -> ("Rm", [translate_rm rm], []) + *) diff --git a/x86/x64.sail b/x86/x64.sail index 3b25802f..9fa0b838 100644 --- a/x86/x64.sail +++ b/x86/x64.sail @@ -32,14 +32,26 @@ default Order dec val extern forall Type 'a. ('a, list<'a>) -> bool effect pure ismember val extern forall Type 'a. list<'a> -> nat effect pure listlength -val extern forall Nat 'n. (bit['n],[|'n|]) -> bit['n] effect pure ASR -val extern forall Nat 'n. (bit['n],[|'n|]) -> bit['n] effect pure LSR -val extern forall Nat 'n. (bit['n],[|'n|]) -> bit['n] effect pure ROR -val extern forall Nat 'n. (bit['n],[|'n|]) -> bit['n] effect pure ROL -val cast bool -> bit effect pure cast_bool_bit -val cast bit -> int effect pure cast_bit_int -val extern forall Num 'n. int -> bit['n] effect pure cast_int_vec -val extern forall 'n, 'm, 'o, 'n <= 0, 'm <= 'o. [|'n:'m|] -> [|0:'o|] effect pure negative_to_zero + +function (bit[8 ]) ASR8 ((bit[8 ]) v, ([|8 |]) shift) = let v2 = ((bit[16 ]) (EXTS(v))) in (bit[8 ]) (mask(v2 >> shift)) +function (bit[16]) ASR16 ((bit[16]) v, ([|16|]) shift) = let v2 = ((bit[32 ]) (EXTS(v))) in (bit[16]) (mask(v2 >> shift)) +function (bit[32]) ASR32 ((bit[32]) v, ([|32|]) shift) = let v2 = ((bit[64 ]) (EXTS(v))) in (bit[32]) (mask(v2 >> shift)) +function (bit[64]) ASR64 ((bit[64]) v, ([|64|]) shift) = let v2 = ((bit[128]) (EXTS(v))) in (bit[64]) (mask(v2 >> shift)) + +function (bit[8 ]) ROR8 ((bit[8 ]) v, ([|8 |]) shift) = let v2 = ((bit[16 ]) (v:v)) in (bit[8 ]) (mask(v2 >> shift)) +function (bit[16]) ROR16 ((bit[16]) v, ([|16|]) shift) = let v2 = ((bit[32 ]) (v:v)) in (bit[16]) (mask(v2 >> shift)) +function (bit[32]) ROR32 ((bit[32]) v, ([|32|]) shift) = let v2 = ((bit[64 ]) (v:v)) in (bit[32]) (mask(v2 >> shift)) +function (bit[64]) ROR64 ((bit[64]) v, ([|64|]) shift) = let v2 = ((bit[128]) (v:v)) in (bit[64]) (mask(v2 >> shift)) + +function (bit[8 ]) ROL8 ((bit[8 ]) v, ([|8 |]) shift) = let v2 = ((bit[16 ]) (v:v)) in (bit[8 ]) (mask(v2 << shift)) +function (bit[16]) ROL16 ((bit[16]) v, ([|16|]) shift) = let v2 = ((bit[32 ]) (v:v)) in (bit[16]) (mask(v2 << shift)) +function (bit[32]) ROL32 ((bit[32]) v, ([|32|]) shift) = let v2 = ((bit[64 ]) (v:v)) in (bit[32]) (mask(v2 << shift)) +function (bit[64]) ROL64 ((bit[64]) v, ([|64|]) shift) = let v2 = ((bit[128]) (v:v)) in (bit[64]) (mask(v2 << shift)) + +(*val cast bool -> bit effect pure cast_bool_bit +val cast bit -> int effect pure cast_bit_int *) +function forall Nat 'n, Nat 'm, Nat 'o, 'n <= 0, 'm <= 'o. ([|0:'o|]) negative_to_zero (([|'n:'m|]) x) = + if x < 0 then 0 else x typedef byte = bit[8] typedef qword = bit[64] @@ -79,20 +91,31 @@ let (vector<0,16,inc,(register<qword>)>) REG = (* Flags *) -register bit CF -register bit PF -register bit AF -register bit ZF -register bit SF -register bit OF +register bit[1] CF +register bit[1] PF +register bit[1] AF +register bit[1] ZF +register bit[1] SF +register bit[1] OF (* -------------------------------------------------------------------------- Memory -------------------------------------------------------------------------- *) -val extern forall Nat 'n. (qword, [|'n|]) -> (bit[8 * 'n]) effect { rmem } MEM +val extern forall Nat 'n. (qword, [|'n|]) -> (bit[8 * 'n]) effect { rmem } rMEM +val extern forall Nat 'n. (qword, [|'n|]) -> (bit[8 * 'n]) effect { rmem } rMEM_locked +function forall Nat 'n. (bit[8 * 'n]) effect { rmem } rMEMl ((bool) locked, (qword) addr, ([|'n|]) size) = + if locked then rMEM_locked(addr, size) else rMEM(addr, size) + +val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea +val extern forall Nat 'n. ( bit[64] , [|'n|]) -> unit effect { eamem } MEMea_locked +val extern forall Nat 'n. ( bit[64] , [|'n|] , bit[8*'n]) -> unit effect { wmv } MEMval +val extern unit -> unit effect { barr } X86_MFENCE -val extern forall Nat 'n. (qword, [|'n|], bit[8 * 'n]) -> unit effect { wmem } wMEM +function forall Nat 'n. unit effect {eamem, wmv} wMEM ((bool) locked, (qword) addr, ([|'n|]) len, (bit[8 * 'n]) data) = { + if locked then MEMea_locked(addr, len) else MEMea(addr, len); + MEMval(addr, len, data); +} (* -------------------------------------------------------------------------- Helper functions @@ -100,13 +123,21 @@ val extern forall Nat 'n. (qword, [|'n|], bit[8 * 'n]) -> unit effect { wmem } w (* Instruction addressing modes *) -typedef size = const union { +typedef wsize = const union { bool Sz8; unit Sz16; unit Sz32; unit Sz64; } +function ([|8:64|]) size_to_int((wsize) s) = + switch(s) { + case (Sz8(_)) -> 8 + case Sz16 -> 16 + case Sz32 -> 32 + case Sz64 -> 64 + } + typedef base = const union { unit NoBase; unit RipBase; @@ -116,7 +147,7 @@ typedef base = const union { typedef scale_index = (bit[2],regn) typedef rm = const union { - regn Reg; + regn X86_Reg; (option<scale_index>,base,qword) Mem; } @@ -131,64 +162,73 @@ typedef imm_rm = const union { qword Imm; } -typedef monop_name = enumerate { Dec; Inc; Not; Neg } +typedef bit_offset = const union { + (rm, qword) Bit_rm_imm; + (rm, regn) Bit_rm_r; +} + +typedef monop_name = enumerate { X86_Dec; X86_Inc; X86_Not; X86_Neg } typedef binop_name = enumerate { - Add; Or; Adc; Sbb; And; Sub; Xor; Cmp; Rol; Ror; Rcl; Rcr; Shl; Shr; Test; Sar + X86_Add; X86_Or; X86_Adc; X86_Sbb; X86_And; X86_Sub; X86_Xor; X86_Cmp; + X86_Rol; X86_Ror; X86_Rcl; X86_Rcr; X86_Shl; X86_Shr; X86_Test; X86_Sar; } +typedef bitop_name = enumerate { Bts; Btc; Btr } + function binop_name opc_to_binop_name ((bit[4]) opc) = switch opc { - case 0x0 -> Add - case 0x1 -> Or - case 0x2 -> Adc - case 0x3 -> Sbb - case 0x4 -> And - case 0x5 -> Sub - case 0x6 -> Xor - case 0x7 -> Cmp - case 0x8 -> Rol - case 0x9 -> Ror - case 0xa -> Rcl - case 0xb -> Rcr - case 0xc -> Shl - case 0xd -> Shr - case 0xe -> Test - case 0xf -> Sar + case 0x0 -> X86_Add + case 0x1 -> X86_Or + case 0x2 -> X86_Adc + case 0x3 -> X86_Sbb + case 0x4 -> X86_And + case 0x5 -> X86_Sub + case 0x6 -> X86_Xor + case 0x7 -> X86_Cmp + case 0x8 -> X86_Rol + case 0x9 -> X86_Ror + case 0xa -> X86_Rcl + case 0xb -> X86_Rcr + case 0xc -> X86_Shl + case 0xd -> X86_Shr + case 0xe -> X86_Test + case 0xf -> X86_Sar } typedef cond = enumerate { - O; NO; B; NB; E; NE; NA; A; S; NS; P; NP; L; NL; NG; G; ALWAYS + X86_O; X86_NO; X86_B; X86_NB; X86_E; X86_NE; X86_NA; X86_A; X86_S; + X86_NS; X86_P; X86_NP; X86_L; X86_NL; X86_NG; X86_G; X86_ALWAYS; } function cond bv_to_cond ((bit[4]) v) = switch v { - case 0x0 -> O - case 0x1 -> NO - case 0x2 -> B - case 0x3 -> NB - case 0x4 -> E - case 0x5 -> NE - case 0x6 -> NA - case 0x7 -> A - case 0x8 -> S - case 0x9 -> NS - case 0xa -> P - case 0xb -> NP - case 0xc -> L - case 0xd -> NL - case 0xe -> NG - case 0xf -> G + case 0x0 -> X86_O + case 0x1 -> X86_NO + case 0x2 -> X86_B + case 0x3 -> X86_NB + case 0x4 -> X86_E + case 0x5 -> X86_NE + case 0x6 -> X86_NA + case 0x7 -> X86_A + case 0x8 -> X86_S + case 0x9 -> X86_NS + case 0xa -> X86_P + case 0xb -> X86_NP + case 0xc -> X86_L + case 0xd -> X86_NL + case 0xe -> X86_NG + case 0xf -> X86_G } (* Effective addresses *) typedef ea = const union { - (size,qword) Ea_i; - (size,regn) Ea_r; - (size,qword) Ea_m; + (wsize,qword) Ea_i; + (wsize,regn) Ea_r; + (wsize,qword) Ea_m; } function qword ea_index ((option<scale_index>) index) = @@ -208,20 +248,20 @@ function qword ea_base ((base) b) = case (RegBase(b)) -> REG[b] } -function ea ea_rm ((size) sz, (rm) r) = +function ea ea_rm ((wsize) sz, (rm) r) = switch r { - case (Reg(n)) -> Ea_r (sz, n) + case (X86_Reg(n)) -> Ea_r (sz, n) case (Mem(idx, b, d)) -> Ea_m (sz, ea_index(idx) + (qword) (ea_base(b) + d)) } -function ea ea_dest ((size) sz, (dest_src) ds) = +function ea ea_dest ((wsize) sz, (dest_src) ds) = switch ds { case (Rm_i (v, _)) -> ea_rm (sz, v) case (Rm_r (v, _)) -> ea_rm (sz, v) case (R_rm (v, _)) -> Ea_r (sz, v) } -function ea ea_src ((size) sz, (dest_src) ds) = +function ea ea_src ((wsize) sz, (dest_src) ds) = switch ds { case (Rm_i (_, v)) -> Ea_i (sz, v) case (Rm_r (_, v)) -> Ea_r (sz, v) @@ -234,7 +274,7 @@ function ea ea_imm_rm ((imm_rm) i_rm) = case (Imm (v)) -> Ea_i (Sz64, v) } -function qword restrict_size ((size) sz, (qword) imm) = +function qword restrict_size ((wsize) sz, (qword) imm) = switch sz { case (Sz8(_)) -> imm & 0x00000000000000FF case Sz16 -> imm & 0x000000000000FFFF @@ -244,7 +284,7 @@ function qword restrict_size ((size) sz, (qword) imm) = function regn sub4 ((regn) r) = negative_to_zero (r - 4) -function qword effect { rreg, rmem } EA ((ea) e) = +function qword effect { rreg, rmem } EA ((bool) locked, (ea) e) = switch e { case (Ea_i(sz,i)) -> restrict_size(sz,i) case (Ea_r((Sz8(have_rex)),r)) -> @@ -253,62 +293,67 @@ function qword effect { rreg, rmem } EA ((ea) e) = else (REG[sub4 (r)] >> 8) & 0x00000000000000FF case (Ea_r(sz,r)) -> restrict_size(sz, REG[r]) - case (Ea_m((Sz8(_)),a)) -> EXTZ (MEM(a, 1)) - case (Ea_m(Sz16,a)) -> EXTZ (MEM(a, 2)) - case (Ea_m(Sz32,a)) -> EXTZ (MEM(a, 4)) - case (Ea_m(Sz64,a)) -> MEM(a, 8) + case (Ea_m((Sz8(_)),a)) -> EXTZ (rMEMl(locked, a, 1)) + case (Ea_m(Sz16,a)) -> EXTZ (rMEMl(locked, a, 2)) + case (Ea_m(Sz32,a)) -> EXTZ (rMEMl(locked, a, 4)) + case (Ea_m(Sz64,a)) -> rMEMl(locked, a, 8) } -function unit effect { wmem, wreg, escape } wEA ((ea) e, (qword) w) = +function unit effect { wmem, wreg, escape } wEA ((bool) locked, (ea) e, (qword) w) = switch e { case (Ea_i(_,_)) -> exit () case (Ea_r((Sz8(have_rex)),r)) -> if have_rex | r < 4 (* RSP *) | r > 7 (* RDI *) then - { - (qword) regr := REG[r]; - regr[7 .. 0] := w[7 .. 0]; - REG[r] := regr - } + (REG[r])[7 .. 0] := w[7 .. 0] else - { - (qword) regr := REG[sub4(r)]; - regr[15 .. 8] := (vector<15,8,dec,bit>) (adjust_dec(w[7 .. 0])); - REG[sub4(r)] := regr - } - case (Ea_r(Sz16,r)) -> - { - (qword) regr := REG[r]; - regr[15 .. 8] := w[15 .. 8]; - REG[r] := regr - } + (REG[sub4(r)])[15 .. 8] := (vector<15,8,dec,bit>) (w[7 .. 0]) + case (Ea_r(Sz16,r)) ->(REG[r])[15 .. 0] := w[15 .. 0] case (Ea_r(Sz32,r)) -> REG[r] := (qword) (EXTZ (w[31 .. 0])) case (Ea_r(Sz64,r)) -> REG[r] := w - case (Ea_m((Sz8(_)),a)) -> wMEM(a, 1, w[7 .. 0]) - case (Ea_m(Sz16,a)) -> wMEM(a, 2, w[15 .. 0]) - case (Ea_m(Sz32,a)) -> wMEM(a, 4, w[31 .. 0]) - case (Ea_m(Sz64,a)) -> wMEM(a, 8, w) + case (Ea_m((Sz8(_)),a)) -> wMEM(locked, a, 1, w[7 .. 0]) + case (Ea_m(Sz16,a)) -> wMEM(locked, a, 2, w[15 .. 0]) + case (Ea_m(Sz32,a)) -> wMEM(locked, a, 4, w[31 .. 0]) + case (Ea_m(Sz64,a)) -> wMEM(locked, a, 8, w) } -function (ea, qword, qword) read_dest_src_ea ((size) sz, (dest_src) ds) = +function (ea, qword, qword) read_dest_src_ea ((bool) locked, (wsize) sz, (dest_src) ds) = let e = ea_dest (sz, ds) in - (e, EA(e), EA(ea_src(sz, ds))) + (e, EA(locked, e), EA(locked, ea_src(sz, ds))) function qword call_dest_from_ea ((ea) e) = switch e { case (Ea_i(_, i)) -> RIP + i case (Ea_r(_, r)) -> REG[r] - case (Ea_m(_, a)) -> MEM(a, 8) + case (Ea_m(_, a)) -> rMEM(a, 8) } function qword get_ea_address ((ea) e) = switch e { case (Ea_i(_, i)) -> 0x0000000000000000 case (Ea_r(_, r)) -> 0x0000000000000000 - case (Ea_m(_, a)) -> 0x0000000000000000 + case (Ea_m(_, a)) -> a } function unit jump_to_ea ((ea) e) = RIP := call_dest_from_ea(e) +function (ea, nat) bit_offset_ea ((wsize) sz, (bit_offset) bo) = + let s = size_to_int (sz) in + switch bo { + case (Bit_rm_imm (r_m, imm)) -> + let base_ea = ea_rm (sz, r_m) in + switch (base_ea) { + case (Ea_r(_, r)) -> (Ea_r(sz, r), imm mod s) + case (Ea_m(_, a)) -> (Ea_m(sz, a), imm mod s) + } + case (Bit_rm_r (r_m, r)) -> + let base_ea = ea_rm (sz, r_m) in + let offset = REG[r] in + switch (base_ea) { + case (Ea_r(_, r)) -> (Ea_r(sz, r), offset mod s) + case (Ea_m(_, a)) -> (Ea_m(Sz64, a + (offset div 8)), offset mod 64) + } + } + (* EFLAG updates *) function bit byte_parity ((byte) b) = @@ -318,7 +363,7 @@ function bit byte_parity ((byte) b) = (bit) (acc mod 2 == 0) } -function [|64|] size_width ((size) sz) = +function [|64|] size_width ((wsize) sz) = switch sz { case (Sz8(_)) -> 8 case Sz16 -> 16 @@ -326,7 +371,7 @@ function [|64|] size_width ((size) sz) = case Sz64 -> 64 } -function [|63|] size_width_sub1 ((size) sz) = +function [|63|] size_width_sub1 ((wsize) sz) = switch sz { case (Sz8(_)) -> 7 case Sz16 -> 15 @@ -335,16 +380,16 @@ function [|63|] size_width_sub1 ((size) sz) = } (* XXXXX -function bit word_size_msb ((size) sz, (qword) w) = w[size_width(sz) - 1] +function bit word_size_msb ((wsize) sz, (qword) w) = w[size_width(sz) - 1] *) -function bit word_size_msb ((size) sz, (qword) w) = w[size_width_sub1(sz)] +function bit word_size_msb ((wsize) sz, (qword) w) = w[size_width_sub1(sz)] function unit write_PF ((qword) w) = PF := byte_parity (w[7 .. 0]) -function unit write_SF ((size) sz, (qword) w) = SF := word_size_msb (sz, w) +function unit write_SF ((wsize) sz, (qword) w) = SF := word_size_msb (sz, w) -function unit write_ZF ((size) sz, (qword) w) = +function unit write_ZF ((wsize) sz, (qword) w) = ZF := (bit) (switch sz { case (Sz8(_)) -> w[7 .. 0] == 0x00 @@ -353,7 +398,7 @@ function unit write_ZF ((size) sz, (qword) w) = case Sz64 -> w == 0x0000000000000000 }) -function unit write_arith_eflags_except_CF_OF ((size) sz, (qword) w) = +function unit write_arith_eflags_except_CF_OF ((wsize) sz, (qword) w) = { AF := undefined; write_PF(w); @@ -361,14 +406,14 @@ function unit write_arith_eflags_except_CF_OF ((size) sz, (qword) w) = write_ZF(sz, w); } -function unit write_arith_eflags ((size) sz, (qword) w, (bit) c, (bit) x) = +function unit write_arith_eflags ((wsize) sz, (qword) w, (bit) c, (bit) x) = { CF := c; OF := x; write_arith_eflags_except_CF_OF (sz, w) } -function unit write_logical_eflags ((size) sz, (qword) w) = +function unit write_logical_eflags ((wsize) sz, (qword) w) = write_arith_eflags (sz, w, bitzero, bitzero) function unit erase_eflags () = @@ -381,51 +426,48 @@ function unit erase_eflags () = ZF := undefined; } -(* XXXXX *) -function nat power ((nat) x, ([|64|]) y) = undefined +function nat value_width ((wsize) sz) = 2 ** size_width(sz) -function nat value_width ((size) sz) = power (2, size_width(sz)) - -function bit word_signed_overflow_add ((size) sz, (qword) a, (qword) b) = +function bit word_signed_overflow_add ((wsize) sz, (qword) a, (qword) b) = (bit) (word_size_msb (sz, a) == word_size_msb (sz, b) & word_size_msb (sz, a + b) != word_size_msb (sz, a)) -function bit word_signed_overflow_sub ((size) sz, (qword) a, (qword) b) = +function bit word_signed_overflow_sub ((wsize) sz, (qword) a, (qword) b) = (bit) (word_size_msb (sz, a) != word_size_msb (sz, b) & word_size_msb (sz, a - b) != word_size_msb (sz, a)) -function (qword, bit, bit) add_with_carry_out ((size) sz, (qword) a, (qword) b) = +function (qword, bit, bit) add_with_carry_out ((wsize) sz, (qword) a, (qword) b) = (a + b, (bit) ((int) (value_width (sz)) <= unsigned(a) + unsigned(b)), word_signed_overflow_add (sz, a, b)) -function (qword, bit, bit) sub_with_borrow ((size) sz, (qword) a, (qword) b) = +function (qword, bit, bit) sub_with_borrow ((wsize) sz, (qword) a, (qword) b) = (a - b, (bit) (a < b), word_signed_overflow_sub (sz, a, b)) -function unit write_arith_result ((size) sz, (qword) w, (bit) c, (bit) x, (ea) e) = +function unit write_arith_result ((bool) locked, (wsize) sz, (qword) w, (bit) c, (bit) x, (ea) e) = { write_arith_eflags (sz, w, c, x); - wEA (e) := w; + wEA (locked, e) := w; } -function unit write_arith_result_no_CF_OF ((size) sz, (qword) w, (ea) e) = +function unit write_arith_result_no_CF_OF ((bool) locked, (wsize) sz, (qword) w, (ea) e) = { write_arith_eflags_except_CF_OF (sz, w); - wEA (e) := w; + wEA (locked, e) := w; } -function unit write_logical_result ((size) sz, (qword) w, (ea) e) = +function unit write_logical_result ((bool) locked, (wsize) sz, (qword) w, (ea) e) = { write_arith_eflags_except_CF_OF (sz, w); - wEA (e) := w; + wEA (locked, e) := w; } -function unit write_result_erase_eflags ((qword) w, (ea) e) = +function unit write_result_erase_eflags ((bool) locked, (qword) w, (ea) e) = { erase_eflags (); - wEA (e) := w; + wEA (locked, e) := w; } -function qword effect { escape } sign_extension ((qword) w, (size) size1, (size) size2) = +function qword effect { escape } sign_extension ((qword) w, (wsize) size1, (wsize) size2) = { (qword) x := w; switch (size1, size2) { @@ -440,106 +482,106 @@ function qword effect { escape } sign_extension ((qword) w, (size) size1, (size) x; } -function [|64|] mask_shift ((size) sz, (qword) w) = +function [|64|] mask_shift ((wsize) sz, (qword) w) = if sz == Sz64 then w[5 .. 0] else w[4 .. 0] -function qword rol ((size) sz, (qword) a, (qword) b) = +function qword rol ((wsize) sz, (qword) a, (qword) b) = switch sz { - case (Sz8(_)) -> EXTZ (ROL (a[7 .. 0], b[2 .. 0])) - case Sz16 -> EXTZ (ROL (a[15 .. 0], b[3 .. 0])) - case Sz32 -> EXTZ (ROL (a[31 .. 0], b[4 .. 0])) - case Sz64 -> ROL (a, b[5 .. 0]) + case (Sz8(_)) -> EXTZ (ROL8 (a[7 .. 0], b[2 .. 0])) + case Sz16 -> EXTZ (ROL16 (a[15 .. 0], b[3 .. 0])) + case Sz32 -> EXTZ (ROL32 (a[31 .. 0], b[4 .. 0])) + case Sz64 -> ROL64 (a, b[5 .. 0]) } -function qword ror ((size) sz, (qword) a, (qword) b) = +function qword ror ((wsize) sz, (qword) a, (qword) b) = switch sz { - case (Sz8(_)) -> EXTZ (ROR (a[7 .. 0], b[2 .. 0])) - case Sz16 -> EXTZ (ROR (a[15 .. 0], b[3 .. 0])) - case Sz32 -> EXTZ (ROR (a[31 .. 0], b[4 .. 0])) - case Sz64 -> ROR (a, b[5 .. 0]) + case (Sz8(_)) -> EXTZ (ROR8 (a[7 .. 0], b[2 .. 0])) + case Sz16 -> EXTZ (ROR16 (a[15 .. 0], b[3 .. 0])) + case Sz32 -> EXTZ (ROR32 (a[31 .. 0], b[4 .. 0])) + case Sz64 -> ROR64 (a, b[5 .. 0]) } -function qword sar ((size) sz, (qword) a, (qword) b) = +function qword sar ((wsize) sz, (qword) a, (qword) b) = switch sz { - case (Sz8(_)) -> EXTZ (ASR (a[7 .. 0], b[2 .. 0])) - case Sz16 -> EXTZ (ASR (a[15 .. 0], b[3 .. 0])) - case Sz32 -> EXTZ (ASR (a[31 .. 0], b[4 .. 0])) - case Sz64 -> ASR (a, b[5 .. 0]) + case (Sz8(_)) -> EXTZ (ASR8 (a[7 .. 0], b[2 .. 0])) + case Sz16 -> EXTZ (ASR16 (a[15 .. 0], b[3 .. 0])) + case Sz32 -> EXTZ (ASR32 (a[31 .. 0], b[4 .. 0])) + case Sz64 -> ASR64 (a, b[5 .. 0]) } -function unit write_binop ((size) sz, (binop_name) bop, (qword) a, (qword) b, (ea) e) = +function unit write_binop ((bool) locked, (wsize) sz, (binop_name) bop, (qword) a, (qword) b, (ea) e) = switch bop { - case Add -> let (w,c,x) = add_with_carry_out (sz, a, b) in - write_arith_result (sz, w, c, x, e) - case Sub -> let (w,c,x) = sub_with_borrow (sz, a, b) in - write_arith_result (sz, w, c, x, e) - case Cmp -> let (w,c,x) = sub_with_borrow (sz, a, b) in + case X86_Add -> let (w,c,x) = add_with_carry_out (sz, a, b) in + write_arith_result (locked, sz, w, c, x, e) + case X86_Sub -> let (w,c,x) = sub_with_borrow (sz, a, b) in + write_arith_result (locked, sz, w, c, x, e) + case X86_Cmp -> let (w,c,x) = sub_with_borrow (sz, a, b) in write_arith_eflags (sz, w, c, x) - case Test -> write_logical_eflags (sz, a & b) - case And -> write_logical_result (sz, a & b, e) - case Xor -> write_logical_result (sz, a ^ b, e) - case Or -> write_logical_result (sz, a | b, e) - case Rol -> write_result_erase_eflags (rol (sz, a, b), e) - case Ror -> write_result_erase_eflags (ror (sz, a, b), e) - case Sar -> write_result_erase_eflags (sar (sz, a, b), e) - case Shl -> write_result_erase_eflags (a << mask_shift (sz, b), e) - case Shr -> write_result_erase_eflags (a >> mask_shift (sz, b), e) - case Adc -> + case X86_Test -> write_logical_eflags (sz, a & b) + case X86_And -> write_logical_result (locked, sz, a & b, e) (* XXX rmn30 wrong flags? *) + case X86_Xor -> write_logical_result (locked, sz, a ^ b, e) + case X86_Or -> write_logical_result (locked, sz, a | b, e) + case X86_Rol -> write_result_erase_eflags (locked, rol (sz, a, b), e) + case X86_Ror -> write_result_erase_eflags (locked, ror (sz, a, b), e) + case X86_Sar -> write_result_erase_eflags (locked, sar (sz, a, b), e) + case X86_Shl -> write_result_erase_eflags (locked, a << mask_shift (sz, b), e) + case X86_Shr -> write_result_erase_eflags (locked, a >> mask_shift (sz, b), e) + case X86_Adc -> { - let carry = CF in + let carry = (bit) CF in let (qword) result = a + (qword) (b + carry) in { CF := (bit) ((int) (value_width (sz)) <= unsigned(a) + unsigned(b)); OF := undefined; - write_arith_result_no_CF_OF (sz, result, e); + write_arith_result_no_CF_OF (locked, sz, result, e); } } - case Sbb -> + case X86_Sbb -> { - let carry = CF in + let carry = (bit) CF in let (qword) result = a - (qword) (b + carry) in { CF := (bit) (unsigned(a) < unsigned(b) + (int) carry); OF := undefined; - write_arith_result_no_CF_OF (sz, result, e); + write_arith_result_no_CF_OF (locked, sz, result, e); } } case _ -> exit () } -function unit write_monop ((size) sz, (monop_name) mop, (qword) a, (ea) e) = +function unit write_monop ((bool) locked, (wsize) sz, (monop_name) mop, (qword) a, (ea) e) = switch mop { - case Not -> wEA(e) := ~(a) - case Dec -> write_arith_result_no_CF_OF (sz, a - 1, e) - case Inc -> write_arith_result_no_CF_OF (sz, a + 1, e) - case Neg -> { write_arith_result_no_CF_OF (sz, 0 - a, e); - CF := undefined; - } + case X86_Not -> wEA(locked, e) := ~(a) + case X86_Dec -> write_arith_result_no_CF_OF (locked, sz, a - 1, e) + case X86_Inc -> write_arith_result_no_CF_OF (locked, sz, a + 1, e)(* XXX rmn30 should set OF *) + case X86_Neg -> { write_arith_result_no_CF_OF (locked, sz, 0 - a, e); + CF := undefined; + } } function bool read_cond ((cond) c) = switch c { - case A -> ~(CF) & ~(ZF) - case NB -> ~(CF) - case B -> CF - case NA -> CF | (bit) ZF - case E -> ZF - case G -> ~(ZF) & (SF == OF) - case NL -> SF == OF - case L -> SF != OF - case NG -> ZF | SF != OF - case NE -> ~(ZF) - case NO -> ~(OF) - case NP -> ~(PF) - case NS -> ~(SF) - case O -> OF - case P -> PF - case S -> SF - case ALWAYS -> true + case X86_A -> ~(CF) & ~(ZF) + case X86_NB -> ~(CF) + case X86_B -> CF + case X86_NA -> CF | (bit) ZF + case X86_E -> ZF + case X86_G -> ~(ZF) & (SF == OF) + case X86_NL -> SF == OF + case X86_L -> SF != OF + case X86_NG -> ZF | SF != OF + case X86_NE -> ~(ZF) + case X86_NO -> ~(OF) + case X86_NP -> ~(PF) + case X86_NS -> ~(SF) + case X86_O -> OF + case X86_P -> PF + case X86_S -> SF + case X86_ALWAYS -> true } function qword pop_aux () = - let top = MEM(RSP, 8) in + let top = rMEM(RSP, 8) in { RSP := RSP + 8; top; @@ -548,12 +590,12 @@ function qword pop_aux () = function unit push_aux ((qword) w) = { RSP := RSP - 8; - wMEM(RSP, 8) := w; + wMEM(false, RSP, 8) := w; } -function unit pop ((rm) r) = wEA (ea_rm (Sz64,r)) := pop_aux() +function unit pop ((rm) r) = wEA (false, ea_rm (Sz64,r)) := pop_aux() function unit pop_rip () = RIP := pop_aux() -function unit push ((imm_rm) i) = push_aux (EA (ea_imm_rm (i))) +function unit push ((imm_rm) i) = push_aux (EA (false, ea_imm_rm (i))) function unit push_rip () = push_aux (RIP) function unit drop ((qword) i) = if i[7 ..0] != 0 then () else RSP := RSP + i @@ -565,17 +607,36 @@ function unit drop ((qword) i) = if i[7 ..0] != 0 then () else RSP := RSP + i scattered function unit execute scattered typedef ast = const union -val ast -> unit effect {escape, rmem, rreg, undef, wmem, wreg} execute +val ast -> unit effect {escape, rmem, rreg, undef, eamem, wmv, wreg, barr} execute (* ========================================================================== Binop ========================================================================== *) -union ast member (binop_name,size,dest_src) Binop +union ast member (bool,binop_name,wsize,dest_src) Binop + +function clause execute (Binop (locked,bop,sz,ds)) = + let (e, val_dst, val_src) = read_dest_src_ea (locked, sz, ds) in + write_binop (locked, sz, bop, val_dst, val_src, e) + +(* ========================================================================== + Bitop + ========================================================================== *) -function clause execute (Binop (bop,sz,ds)) = - let (e, val_dst, val_src) = read_dest_src_ea (sz, ds) in - write_binop (sz, bop, val_dst, val_src, e) +union ast member (bool,bitop_name,wsize,bit_offset) Bitop + +function clause execute (Bitop (locked,bop,sz,boffset)) = + let (base_ea, offset) = bit_offset_ea (sz, boffset) in { + word := EA(locked, base_ea); + bitval := word[offset]; + word[offset] := switch(bop) { + case Bts -> bitone + case Btc -> (~ (bitval)) + case Btr -> bitzero + }; + CF := bitval; + wEA(locked, base_ea) := word; + } (* ========================================================================== CALL @@ -609,45 +670,58 @@ function clause execute CMC = CF := ~(CF) CMPXCHG ========================================================================== *) -union ast member (size,rm,regn) CMPXCHG +union ast member (bool, wsize,rm,regn) CMPXCHG -function clause execute (CMPXCHG (sz,r,n)) = +function clause execute (CMPXCHG (locked, sz,r,n)) = let src = Ea_r(sz, n) in let acc = Ea_r(sz, 0) in (* RAX *) let dst = ea_rm(sz, r) in - let val_dst = EA(dst) in - let val_acc = EA(src) in + let val_dst = EA(locked, dst) in + let val_acc = EA(false, acc) in { - write_binop (sz, Cmp, val_acc, val_dst, src); + write_binop (locked, sz, X86_Cmp, val_acc, val_dst, src); if val_acc == val_dst then - wEA(dst) := EA (src) - else - wEA(acc) := val_dst; + wEA(locked, dst) := EA (false, src) + else { + wEA(false, acc) := val_dst; + (* write back the original value in dst so that we always + perform locked write after locked read *) + wEA(locked, dst) := val_dst; + } } (* ========================================================================== DIV ========================================================================== *) -union ast member (size,rm) DIV +union ast member (wsize,rm) X86_DIV -function clause execute (DIV (sz,r)) = +function clause execute (X86_DIV (sz,r)) = let w = (int) (value_width(sz)) in let eax = Ea_r(sz, 0) in (* RAX *) let edx = Ea_r(sz, 2) in (* RDX *) - let n = unsigned(EA(edx)) * w + unsigned(EA(eax)) in - let d = unsigned(EA(ea_rm(sz, r))) in + let n = unsigned(EA(false, edx)) * w + unsigned(EA(false, eax)) in + let d = unsigned(EA(false, ea_rm(sz, r))) in let q = n quot d in let m = n mod d in if d == 0 | w < q then exit () else { - wEA(eax) := cast_int_vec(q); - wEA(edx) := cast_int_vec(m); + wEA(false, eax) := (qword) q; + wEA(false, edx) := (qword) m; erase_eflags(); } (* ========================================================================== + HLT -- halt instruction used to end test in RMEM + ========================================================================== *) + +union ast member unit HLT + +function clause execute (HLT) = () + + +(* ========================================================================== Jcc ========================================================================== *) @@ -662,18 +736,18 @@ function clause execute (Jcc (c,i)) = union ast member rm JMP -function clause execute (JMP (r)) = RIP := EA (ea_rm (Sz64, r)) +function clause execute (JMP (r)) = RIP := EA (false, ea_rm (Sz64, r)) (* ========================================================================== LEA ========================================================================== *) -union ast member (size,dest_src) LEA +union ast member (wsize,dest_src) LEA function clause execute (LEA (sz,ds)) = let src = ea_src (sz, ds) in let dst = ea_dest (sz, ds) in - wEA(dst) := get_ea_address (src) + wEA(false, dst) := get_ea_address (src) (* ========================================================================== LEAVE @@ -684,7 +758,7 @@ union ast member unit LEAVE function clause execute LEAVE = { RSP := RBP; - pop (Reg (5)); (* RBP *) + pop (X86_Reg (5)); (* RBP *) } (* ========================================================================== @@ -700,67 +774,76 @@ function clause execute (LOOP (c,i)) = } (* ========================================================================== + MFENCE + ========================================================================== *) + +union ast member unit MFENCE + +function clause execute (MFENCE) = + X86_MFENCE () + +(* ========================================================================== Monop ========================================================================== *) -union ast member (monop_name,size,rm) Monop +union ast member (bool,monop_name,wsize,rm) Monop -function clause execute (Monop (mop,sz,r)) = - let e = ea_rm (sz, r) in write_monop (sz, mop, EA(e), e) +function clause execute (Monop (locked,mop,sz,r)) = + let e = ea_rm (sz, r) in write_monop (locked, sz, mop, EA(locked, e), e) (* ========================================================================== MOV ========================================================================== *) -union ast member (cond,size,dest_src) MOV +union ast member (cond,wsize,dest_src) MOV function clause execute (MOV (c,sz,ds)) = if read_cond (c) then let src = ea_src (sz, ds) in let dst = ea_dest (sz, ds) in - wEA(dst) := EA(src) + wEA(false, dst) := EA(false, src) else () (* ========================================================================== MOVSX ========================================================================== *) -union ast member (size,dest_src,size) MOVSX +union ast member (wsize,dest_src,wsize) MOVSX function clause execute (MOVSX (sz1,ds,sz2)) = let src = ea_src (sz1, ds) in let dst = ea_dest (sz2, ds) in - wEA(dst) := sign_extension (EA(src), sz1, sz2) + wEA(false, dst) := sign_extension (EA(false, src), sz1, sz2) (* ========================================================================== MOVZX ========================================================================== *) -union ast member (size,dest_src,size) MOVZX +union ast member (wsize,dest_src,wsize) MOVZX function clause execute (MOVZX (sz1,ds,sz2)) = let src = ea_src (sz1, ds) in let dst = ea_dest (sz2, ds) in - wEA(dst) := EA(src) + wEA(false, dst) := EA(false, src) (* ========================================================================== MUL ========================================================================== *) -union ast member (size,rm) MUL +union ast member (wsize,rm) X86_MUL -function clause execute (MUL (sz,r)) = +function clause execute (X86_MUL (sz,r)) = let eax = Ea_r (sz, 0) in (* RAX *) - let val_eax = EA(eax) in - let val_src = EA(ea_rm (sz, r)) in + let val_eax = EA(false, eax) in + let val_src = EA(false, ea_rm (sz, r)) in switch sz { - case (Sz8(_)) -> wEA(Ea_r(Sz16,0)) := (val_eax * val_src)[63 .. 0] + case (Sz8(_)) -> wEA(false, Ea_r(Sz16,0)) := (val_eax * val_src)[63 .. 0] case _ -> let m = val_eax * val_src in let edx = Ea_r (sz, 2) in (* RDX *) { - wEA(eax) := m[63 .. 0]; - wEA(edx) := (LSR (m, size_width(sz)))[63 .. 0] + wEA(false, eax) := m[63 .. 0]; + wEA(false, edx) := (m >> size_width(sz))[63 .. 0] } } @@ -807,7 +890,7 @@ function clause execute (RET (i)) = union ast member (cond,bool,rm) SET function clause execute (SET (c,b,r)) = - wEA(ea_rm(Sz8(b),r)) := if read_cond (c) then 1 else 0 + wEA(false, ea_rm(Sz8(b),r)) := if read_cond (c) then 1 else 0 (* ========================================================================== STC @@ -821,32 +904,32 @@ function clause execute STC = CF := true XADD ========================================================================== *) -union ast member (size,rm,regn) XADD +union ast member (bool, wsize,rm,regn) XADD -function clause execute (XADD (sz,r,n)) = +function clause execute (XADD (locked,sz,r,n)) = let src = Ea_r (sz, n) in let dst = ea_rm (sz, r) in - let val_src = EA(src) in - let val_dst = EA(dst) in + let val_src = EA(false, src) in + let val_dst = EA(locked, dst) in { - wEA(src) := val_dst; - write_binop (sz, Add, val_src, val_dst, dst); + wEA(false, src) := val_dst; + write_binop (locked, sz, X86_Add, val_src, val_dst, dst); } (* ========================================================================== XCHG ========================================================================== *) -union ast member (size,rm,regn) XCHG +union ast member (bool,wsize,rm,regn) XCHG -function clause execute (XCHG (sz,r,n)) = +function clause execute (XCHG (locked,sz,r,n)) = let src = Ea_r (sz, n) in let dst = ea_rm (sz, r) in - let val_src = EA(src) in - let val_dst = EA(dst) in + let val_src = EA(false, src) in + let val_dst = EA(locked, dst) in { - wEA(src) := val_dst; - wEA(dst) := val_src; + wEA(false, src) := val_dst; + wEA(locked, dst) := val_src; } end ast @@ -855,7 +938,7 @@ end execute (* -------------------------------------------------------------------------- Decoding -------------------------------------------------------------------------- *) - +(* function (qword,ostream) oimmediate8 ((ostream) strm) = switch strm { case (Some (b :: t)) -> ((qword) (EXTS(b)), Some (t)) @@ -885,20 +968,20 @@ function (qword,ostream) immediate64 ((byte_stream) strm) = case _ -> ((qword) undefined, (ostream) None) } -function (qword, ostream) immediate ((size) sz, (byte_stream) strm) = +function (qword, ostream) immediate ((wsize) sz, (byte_stream) strm) = switch sz { case (Sz8 (_)) -> immediate8 (strm) case Sz16 -> immediate16 (strm) case _ -> immediate32 (strm) } -function (qword, ostream) oimmediate ((size) sz, (ostream) strm) = +function (qword, ostream) oimmediate ((wsize) sz, (ostream) strm) = switch strm { case (Some (s)) -> immediate (sz, s) case None -> ((qword) undefined, (ostream) None) } -function (qword, ostream) full_immediate ((size) sz, (byte_stream) strm) = +function (qword, ostream) full_immediate ((wsize) sz, (byte_stream) strm) = if sz == Sz64 then immediate64 (strm) else immediate (sz, strm) (* - Parse ModR/M and SIB bytes --------------------------------------------- *) @@ -1010,7 +1093,7 @@ function rec option<atuple> read_prefix function option<atuple> read_prefixes ((byte_stream) strm) = read_prefix ([||||], [||||], strm) -function size op_size ((bool) have_rex, (bit[1]) w, (bit[1]) v, (bool) override) = +function wsize op_size ((bool) have_rex, (bit[1]) w, (bit[1]) v, (bool) override) = if v == 1 then Sz8 (have_rex) else if w == 1 then @@ -1225,3 +1308,306 @@ function (byte_stream, ast, nat) decode ((byte_stream) strm) = case _ -> exit () } } + *) + +let (vector <0, 16, inc, string >) GPRstr = + ["RAX","RCX","RDX","RBX","RSP","RBP","RSI","RDI","R8","R9","R10","R11","R12","R13","R14","R15"] + +function (regfps) regfp_base ((base) b) = + switch b { + case NoBase -> [|| ||] + case RipBase -> [|| RFull("RIP") ||] + case (RegBase(b)) -> [|| RFull(GPRstr[b]) ||] + } + +function (regfps) regfp_idx ((option<scale_index>) idx) = + switch idx { + case (None) -> [|| ||] + case (Some(scale, idx)) -> [|| RFull(GPRstr[idx]) ||] + } + +function (bool, regfps, regfps) regfp_rm ((rm) r) = + switch r { + case (X86_Reg(n)) -> + (false, [|| RFull(GPRstr[n]) ||], [|| ||]) + case (Mem(idx, b, d)) -> { + (true, [|| ||], append(regfp_idx(idx), regfp_base(b))) + } + } + +function (instruction_kind, regfps, regfps, regfps) regfp_dest_src ((dest_src) ds) = + switch ds { + case (Rm_i (r_m, i)) -> + let (m,rd,ars) = regfp_rm(r_m) in + (if m then IK_mem_write(Write_plain) else IK_simple, ars, rd, ars) + case (Rm_r (r_m, r)) -> + let (m,rd,ars) = regfp_rm(r_m) in + (if m then IK_mem_write(Write_plain) else IK_simple, RFull(GPRstr[r]) :: ars, rd, ars) + case (R_rm (r, r_m)) -> + let (m,rs,ars) = regfp_rm(r_m) in + (if m then IK_mem_read(Read_plain) else IK_simple, append(rs, ars), [|| RFull(GPRstr[r]) ||], ars) + } + +(* as above but where destination is also a source operand *) +function (instruction_kind, regfps, regfps, regfps) regfp_dest_src_rmw (locked, (dest_src) ds) = + let rk = if locked then Read_X86_locked else Read_plain in + let wk = if locked then Write_X86_locked else Write_plain in + switch ds { + case (Rm_i (r_m, i)) -> + let (m,rds, ars) = regfp_rm(r_m) in + (if m then IK_mem_rmw(rk, wk) else IK_simple, append(rds, ars), rds, ars) + case (Rm_r (r_m, r)) -> + let (m,rds, ars) = regfp_rm(r_m) in + (if m then IK_mem_rmw(rk, wk) else IK_simple, RFull(GPRstr[r]) :: append(rds, ars), rds, ars) + case (R_rm (r, r_m)) -> + let rds = [|| RFull(GPRstr[r]) ||] in + let (m,rs,ars) = regfp_rm(r_m) in + (if m then IK_mem_read(Read_plain) else IK_simple, append(rds, ars), rds, ars) + } + +function (bool, regfps, regfps) regfp_imm_rm ((imm_rm) i_rm) = + switch i_rm { + case (Rm (v)) -> regfp_rm (v) + case (Imm (v)) -> (false, [|| ||], [|| ||]) + } + +let all_flags_but_cf_of = [|| RFull("AF"), RFull("PF"), RFull("SF"), RFull("ZF") ||] +let all_flags = append([|| RFull("CF"), RFull("OF") ||], all_flags_but_cf_of) + +function (regfps) regfp_binop_flags ((binop_name) op) = + switch (op) { + case X86_Add -> all_flags + case X86_Sub -> all_flags + case X86_Cmp -> all_flags + case X86_Test -> all_flags_but_cf_of + case X86_And -> all_flags_but_cf_of + case X86_Xor -> all_flags_but_cf_of + case X86_Or -> all_flags_but_cf_of + case X86_Rol -> all_flags + case X86_Ror -> all_flags + case X86_Sar -> all_flags + case X86_Shl -> all_flags + case X86_Shr -> all_flags + case X86_Adc -> all_flags + case X86_Sbb -> all_flags + } +function (regfps) regfp_cond ((cond) c) = + switch c { + case X86_A -> [|| RFull("CF"), RFull("ZF") ||] + case X86_NB -> [|| RFull("CF") ||] + case X86_B -> [|| RFull("CF") ||] + case X86_NA -> [|| RFull("CF"), RFull("ZF") ||] + case X86_E -> [|| RFull("ZF") ||] + case X86_G -> [|| RFull("ZF"), RFull("SF"), RFull("OF") ||] + case X86_NL -> [|| RFull("SF"), RFull("OF") ||] + case X86_L -> [|| RFull("SF"), RFull("OF") ||] + case X86_NG -> [|| RFull("ZF"), RFull("SF"), RFull("OF") ||] + case X86_NE -> [|| RFull("ZF") ||] + case X86_NO -> [|| RFull("OF") ||] + case X86_NP -> [|| RFull("PF") ||] + case X86_NS -> [|| RFull("SF") ||] + case X86_O -> [|| RFull("OF") ||] + case X86_P -> [|| RFull("PF") ||] + case X86_S -> [|| RFull("SF") ||] + case X86_ALWAYS -> [|| ||] + } + +function (regfps,regfps,regfps,niafps,diafp,instruction_kind) initial_analysis (instr) = { + iR := [|| ||]; + oR := [|| ||]; + aR := [|| ||]; + ik := IK_simple; + Nias := [|| NIAFP_successor ||]; + Dia := DIAFP_none; + switch instr { + case(Binop (locked, binop, sz, ds)) -> { + let flags = regfp_binop_flags (binop) in + let (ik', iRs, oRs, aRs) = regfp_dest_src_rmw(locked, ds) in { + ik := ik'; + iR := append(iRs, iR); + oR := append(flags, append(oRs, oR)); + aR := append(aRs, aR); + } + } + case(Bitop (locked, bitop, sz, bitoff)) -> { + let rk = if locked then Read_X86_locked else Read_plain in + let wk = if locked then Write_X86_locked else Write_plain in + let (ik', iRs, oRs, aRs) = switch(bitoff) { + case (Bit_rm_imm (r_m, imm)) -> + let (m, rs, ars) = regfp_rm(r_m) in + (if m then IK_mem_rmw(rk, wk) else IK_simple, + append(rs, ars), rs, ars) + case (Bit_rm_r (r_m, r)) -> + let rfp = RFull(GPRstr[r]) in + let (m, rs, ars) = regfp_rm(r_m) in + (if m then IK_mem_rmw(rk, wk) else IK_simple, + rfp::append(rs, ars), rs, + if m then (rfp::ars) else ars) (* in memory case r is a third input to address! *) + } in { + ik := ik'; + iR := append(iRs, iR); + oR := RFull("CF")::append(oRs, oR); + aR := append(aRs, aR); + } + } + case(CALL (irm) ) -> + let (m, rs, ars) = regfp_imm_rm (irm) in { + ik := if m then IK_mem_rmw(Read_plain, Write_plain) else IK_mem_write(Write_plain); + iR := RFull("RIP") :: RFull("RSP") :: rs; + oR := RFull("RSP") :: oR; + aR := ars; + Nias := switch irm { + (* XXX register name is not important here -- just indicates we don't know the destination yet. *) + case (Rm (v)) -> NIAFP_register(RFull("RAX")) + case (Imm (v)) -> NIAFP_concrete_address(RIP + v) + } :: Nias; + } + case(CLC ) -> oR := RFull("CF") :: oR + case(CMC ) -> { + iR := RFull("CF") :: iR; + oR := RFull("CF") :: oR; + } + case(CMPXCHG (locked, sz, r_m, reg) ) -> + let rk = if locked then Read_X86_locked else Read_plain in + let wk = if locked then Write_X86_locked else Write_plain in + let (m, rs, aRs) = regfp_rm (r_m) in { + ik := if m then IK_mem_rmw (rk, wk) else IK_simple; + iR := RFull("RAX") :: RFull(GPRstr[reg]) :: append(rs, aRs); + oR := RFull("RAX") :: append(regfp_binop_flags(X86_Cmp), rs); + aR := aRs; + } + case(X86_DIV (sz, r_m) ) -> + let (m, rs, ars) = regfp_rm (r_m) in { + ik := if m then IK_mem_read (Read_plain) else IK_simple; + iR := RFull("RAX") :: RFull("RDX") :: append(rs, ars); + oR := RFull("RAX") :: RFull("RDX") :: append(oR, all_flags); + aR := ars; + } + case(HLT ) -> () + case(Jcc (c, imm64) ) -> + let flags = regfp_cond(c) in { + ik := IK_cond_branch; + iR := RFull("RIP") :: flags; + Nias := NIAFP_concrete_address(RIP + imm64) :: Nias; + } + case(JMP (r_m) ) -> + let (m, rs, ars) = regfp_rm (r_m) in { + ik := if m then IK_mem_read(Read_plain) else IK_simple; + iR := RFull("RIP")::append(rs, ars); + aR := ars; + (* XXX register name is not important here -- just indicates we don't know the destination yet. *) + Nias := NIAFP_register(RFull("RAX")) :: Nias; + } + case(LEA (sz, ds) ) -> + let (_, irs, ors, ars) = regfp_dest_src (ds) in { + iR := irs; + oR := ors; + aR := ars; + } + case(LEAVE ) -> { + ik := IK_mem_read(Read_plain); + iR := RFull("RBP") :: iR; + oR := RFull("RBP") :: RFull("RSP") :: oR; + aR := RFull("RBP") :: aR; + } + case(LOOP (c, imm64) ) -> + let flags = regfp_cond(c) in { + ik := IK_cond_branch; + iR := RFull("RCX") :: flags; + oR := RFull("RCX") :: oR; + Nias := NIAFP_concrete_address(RIP + imm64) :: Nias; + } + case(MFENCE ) -> + ik := IK_barrier (Barrier_x86_MFENCE) + case(Monop (locked, monop, sz, r_m) ) -> + let rk = if locked then Read_X86_locked else Read_plain in + let wk = if locked then Write_X86_locked else Write_plain in + let (m, rds, ars) = regfp_rm(r_m) in { + ik := if m then IK_mem_rmw(rk, wk) else IK_simple; + iR := append(rds, ars); + oR := append(all_flags_but_cf_of, rds); (* XXX fix flags *) + aR := ars; + } + case(MOV (c, sz, ds) ) -> + let (ik', irs, ors, ars) = regfp_dest_src (ds) in + let flags = regfp_cond(c) in + { + ik := ik'; + iR := append(irs, flags); + oR := ors; + aR := ars; + } + case(MOVSX (sz1, ds, sz2) ) -> + let (ik', irs, ors, ars) = regfp_dest_src (ds) in { + ik := ik'; + iR := irs; + oR := ors; + aR := ars; + } + case(MOVZX (sz1, ds, sz2) ) -> + let (ik', irs, ors, ars) = regfp_dest_src (ds) in { + ik := ik'; + iR := irs; + oR := ors; + aR := ars; + } + case(X86_MUL (sz, r_m) ) -> + let (m, rs, ars) = regfp_rm (r_m) in { + ik := if m then IK_mem_read (Read_plain) else IK_simple; + iR := RFull("RAX") :: append(rs, ars); + oR := RFull("RAX") :: RFull("RDX") :: append(oR, all_flags); + aR := ars; + } + case(NOP (_) ) -> () + case(POP (r_m) ) -> + let (m, rd, ars) = regfp_rm (r_m) in { + ik := if m then IK_mem_rmw(Read_plain, Write_plain) else IK_mem_write(Write_plain); + iR := RFull("RSP") :: ars; + oR := RFull("RSP") :: rd; + aR := RFull("RSP") :: ars; + } + case(PUSH (irm) ) -> + let (m, rs, ars) = regfp_imm_rm (irm) in { + ik := if m then IK_mem_rmw(Read_plain, Write_plain) else IK_mem_write(Write_plain); + iR := RFull("RSP") :: append(rs, ars); + oR := RFull("RSP") :: oR; + aR := RFull("RSP") :: ars; + } + case(RET (imm64) ) -> { + ik := IK_mem_read(Read_plain); + iR := RFull("RSP") :: iR; + oR := RFull("RSP") :: oR; + aR := RFull("RSP") :: aR; + (* XXX register name is not important here -- just indicates we don't know the destination yet. *) + Nias := NIAFP_register(RFull("RAX")) :: Nias; + } + case(SET (c, b, r_m) ) -> + let flags = regfp_cond(c) in + let (m, rs, ars) = regfp_rm(r_m) in { + ik := if m then IK_mem_write(Write_plain) else IK_simple; + iR := append(flags, ars); + oR := rs; + aR := ars; + } + case(STC ) -> oR := [|| RFull("CF") ||] + case(XADD (locked, sz, r_m, reg) ) -> + let rk = if locked then Read_X86_locked else Read_plain in + let wk = if locked then Write_X86_locked else Write_plain in + let (m, rs, ars) = regfp_rm(r_m) in { + ik := if m then IK_mem_rmw(rk, wk) else IK_simple; + iR := RFull(GPRstr[reg]) :: append(rs, ars); + oR := RFull(GPRstr[reg]) :: append(rs, all_flags); + aR := ars; + } + case(XCHG (locked, sz, r_m, reg) ) -> + let rk = if locked then Read_X86_locked else Read_plain in + let wk = if locked then Write_X86_locked else Write_plain in + let (m, rs, ars) = regfp_rm(r_m) in { + ik := if m then IK_mem_rmw(rk, wk) else IK_simple; + iR := RFull(GPRstr[reg]) :: append(rs, ars); + oR := RFull(GPRstr[reg]) :: rs; + aR := ars; + } + }; + (iR,oR,aR,Nias,Dia,ik) +} diff --git a/x86/x86_extras.lem b/x86/x86_extras.lem new file mode 100644 index 00000000..d6498d87 --- /dev/null +++ b/x86/x86_extras.lem @@ -0,0 +1,53 @@ +open import Pervasives +open import Interp_ast +open import Interp_interface +open import Sail_impl_base +open import Interp_inter_imp +import Set_extra + +let memory_parameter_transformer mode v = + match v with + | Interp_ast.V_tuple [location;length] -> + let (v,loc_regs) = extern_with_track mode extern_vector_value location in + + match length with + | Interp_ast.V_lit (L_aux (L_num len) _) -> + (v,(natFromInteger len),loc_regs) + | Interp_ast.V_track (Interp_ast.V_lit (L_aux (L_num len) _)) size_regs -> + match loc_regs with + | Nothing -> (v,(natFromInteger len),Just (List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs))) + | Just loc_regs -> (v,(natFromInteger len),Just (loc_regs++(List.map (fun r -> extern_reg r Nothing) (Set_extra.toList size_regs)))) + end + | _ -> Assert_extra.failwith "expected 'V_lit (L_aux (L_num _) _)' or 'V_track (V_lit (L_aux (L_num len) _)) _'" + end + | _ -> Assert_extra.failwith ("memory_parameter_transformer: expected 'V_tuple [_;_]' given " ^ (Interp.string_of_value v)) + end + +let memory_parameter_transformer_option_address _mode v = + match v with + | Interp_ast.V_tuple [location;_] -> + Just (extern_vector_value location) + | _ -> Assert_extra.failwith ("memory_parameter_transformer_option_address: expected 'V_tuple [_;_]' given " ^ (Interp.string_of_value v)) + end + +let x86_read_memory_functions : memory_reads = + [ ("rMEM", (MR Read_plain memory_parameter_transformer)); + ("rMEM_locked", (MR Read_X86_locked memory_parameter_transformer)); + ] + +let x86_memory_writes : memory_writes = + [] + +let x86_memory_eas : memory_write_eas = + [ ("MEMea", (MEA Write_plain memory_parameter_transformer)); + ("MEMea_locked", (MEA Write_X86_locked memory_parameter_transformer)); + ] + +let x86_memory_vals : memory_write_vals = + [ ("MEMval", (MV memory_parameter_transformer_option_address Nothing)); + ] + +let x86_barrier_functions = + [ + ("X86_MFENCE", Barrier_x86_MFENCE); + ] diff --git a/x86/x86_extras_embed.lem b/x86/x86_extras_embed.lem new file mode 100644 index 00000000..f5130995 --- /dev/null +++ b/x86/x86_extras_embed.lem @@ -0,0 +1,24 @@ +open import Pervasives +open import Pervasives_extra +open import Sail_impl_base +open import Sail_values +open import Prompt + +val rMEM : (vector bitU * integer) -> M (vector bitU) +val rMEM_locked : (vector bitU * integer) -> M (vector bitU) + +let rMEM (addr,size) = read_mem false Read_plain addr size +let rMEM_locked (addr,size) = read_mem false Read_X86_locked addr size + +val MEMea : (vector bitU * integer) -> M unit +val MEMea_locked : (vector bitU * integer) -> M unit + +let MEMea (addr,size) = write_mem_ea Write_plain addr size +let MEMea_locked (addr,size) = write_mem_ea Write_X86_locked addr size + +val MEMval : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional : (vector bitU * integer * vector bitU) -> M bitU + +let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return () + +let X86_MFENCE () = barrier Barrier_x86_MFENCE diff --git a/x86/x86_extras_embed_sequential.lem b/x86/x86_extras_embed_sequential.lem new file mode 100644 index 00000000..2703b6c4 --- /dev/null +++ b/x86/x86_extras_embed_sequential.lem @@ -0,0 +1,24 @@ +open import Pervasives +open import Pervasives_extra +open import Sail_impl_base +open import Sail_values +open import State + +val rMEM : (vector bitU * integer) -> M (vector bitU) +val rMEM_locked : (vector bitU * integer) -> M (vector bitU) + +let rMEM (addr,size) = read_mem false Read_plain addr size +let rMEM_locked (addr,size) = read_mem false Read_X86_locked addr size + +val MEMea : (vector bitU * integer) -> M unit +val MEMea_locked : (vector bitU * integer) -> M unit + +let MEMea (addr,size) = write_mem_ea Write_plain addr size +let MEMea_locked (addr,size) = write_mem_ea Write_X86_locked addr size + +val MEMval : (vector bitU * integer * vector bitU) -> M unit +val MEMval_conditional : (vector bitU * integer * vector bitU) -> M bitU + +let MEMval (_,_,v) = write_mem_val v >>= fun _ -> return () + +let X86_MFENCE () = barrier Barrier_x86_MFENCE |
