summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bauereiss2017-12-06 17:18:36 +0000
committerThomas Bauereiss2017-12-06 17:18:36 +0000
commit2bc281428a3a1d608d56f69e71b50056a25e3da0 (patch)
treedfd8e8a13702696fd9daef64315952b9652f95e8
parentc3c3c40a1d4f81448d8356317e88be2b04363df7 (diff)
parent44e9396fa90ab68ee4c8d9674c6bbad6fc851c6d (diff)
Merge remote branch 'experiments' into experiments
-rw-r--r--arm/Makefile59
-rw-r--r--arm/aarch64_regfp.sail598
-rw-r--r--arm/armV8.h.sail24
-rw-r--r--arm/armV8.sail157
-rw-r--r--arm/armV8_A64_lib.sail18
-rw-r--r--arm/armV8_A64_sys_regs.sail200
-rw-r--r--arm/armV8_common_lib.sail10
-rw-r--r--arm/armV8_extras.lem77
-rw-r--r--arm/armV8_extras_embed.lem59
-rw-r--r--arm/armV8_extras_embed_sequential.lem59
-rw-r--r--arm/armV8_lib.h.sail5
-rw-r--r--arm/gen/ast.hgen44
-rw-r--r--arm/gen/fold.hgen44
-rw-r--r--arm/gen/herdtools_ast_to_shallow_ast.hgen335
-rw-r--r--arm/gen/herdtools_types_to_shallow_types.hgen153
-rw-r--r--arm/gen/lexer.hgen309
-rw-r--r--arm/gen/map.hgen44
-rw-r--r--arm/gen/parser.hgen1396
-rw-r--r--arm/gen/pretty.hgen393
-rw-r--r--arm/gen/regs_out_in.hgen155
-rw-r--r--arm/gen/sail_trans_out.hgen326
-rw-r--r--arm/gen/shallow_ast_to_herdtools_ast.hgen326
-rw-r--r--arm/gen/shallow_types_to_herdtools_types.hgen154
-rw-r--r--arm/gen/token_types.hgen85
-rw-r--r--arm/gen/tokens.hgen78
-rw-r--r--arm/gen/trans_sail.hgen379
-rw-r--r--arm/gen/types.hgen90
-rw-r--r--arm/gen/types_sail_trans_out.hgen189
-rw-r--r--arm/gen/types_trans_sail.hgen119
-rw-r--r--cheri/cheri_insts.sail344
-rw-r--r--cheri/cheri_prelude_128.sail28
-rw-r--r--cheri/cheri_prelude_256.sail18
-rw-r--r--cheri/cheri_prelude_common.sail12
-rw-r--r--editors/sail2-mode.el2
-rw-r--r--etc/power_header31
-rw-r--r--etc/regfp.sail24
-rw-r--r--lib/ocaml_rts/sail_lib.ml3
-rw-r--r--mips/Makefile23
-rw-r--r--mips/gen/ast.hgen (renamed from mips/hgen/ast.hgen)0
-rw-r--r--mips/gen/fold.hgen (renamed from mips/hgen/fold.hgen)0
-rw-r--r--mips/gen/herdtools_ast_to_shallow_ast.hgen (renamed from mips/hgen/herdtools_ast_to_shallow_ast.hgen)0
-rw-r--r--mips/gen/herdtools_types_to_shallow_types.hgen (renamed from mips/hgen/herdtools_types_to_shallow_types.hgen)0
-rw-r--r--mips/gen/lexer.hgen (renamed from mips/hgen/lexer.hgen)0
-rw-r--r--mips/gen/map.hgen (renamed from mips/hgen/map.hgen)0
-rw-r--r--mips/gen/parser.hgen (renamed from mips/hgen/parser.hgen)0
-rw-r--r--mips/gen/pretty.hgen (renamed from mips/hgen/pretty.hgen)0
-rw-r--r--mips/gen/sail_trans_out.hgen (renamed from mips/hgen/sail_trans_out.hgen)0
-rw-r--r--mips/gen/shallow_ast_to_herdtools_ast.hgen (renamed from mips/hgen/shallow_ast_to_herdtools_ast.hgen)0
-rw-r--r--mips/gen/shallow_types_to_herdtools_types.hgen (renamed from mips/hgen/shallow_types_to_herdtools_types.hgen)0
-rw-r--r--mips/gen/token_types.hgen (renamed from mips/hgen/token_types.hgen)0
-rw-r--r--mips/gen/tokens.hgen (renamed from mips/hgen/tokens.hgen)0
-rw-r--r--mips/gen/trans_sail.hgen (renamed from mips/hgen/trans_sail.hgen)0
-rw-r--r--mips/gen/types.hgen (renamed from mips/hgen/types.hgen)0
-rw-r--r--mips/gen/types_sail_trans_out.hgen (renamed from mips/hgen/types_sail_trans_out.hgen)0
-rw-r--r--mips/gen/types_trans_sail.hgen (renamed from mips/hgen/types_trans_sail.hgen)0
-rw-r--r--mips/mips_extras.lem14
-rw-r--r--mips/mips_prelude.sail7
-rw-r--r--mips/mips_tlb.sail2
-rw-r--r--mips/run_embed.ml12
-rw-r--r--power/Makefile49
-rw-r--r--power/gen/ast.gen202
-rw-r--r--power/gen/compile.gen2257
-rw-r--r--power/gen/fold.gen368
-rw-r--r--power/gen/herdtools_ast_to_shallow_ast.gen1312
-rw-r--r--power/gen/lexer.gen368
-rw-r--r--power/gen/map.gen368
-rw-r--r--power/gen/parser.gen736
-rw-r--r--power/gen/pretty.gen368
-rw-r--r--power/gen/sail_trans_out.gen1112
-rw-r--r--power/gen/sail_trans_out_types.hgen146
-rw-r--r--power/gen/shallow_ast_to_herdtools_ast.gen1112
-rw-r--r--power/gen/shallow_types_to_herdtools_types.hgen150
-rw-r--r--power/gen/tokens.gen368
-rw-r--r--power/gen/trans_sail.gen1516
-rw-r--r--power/gen/trans_sail_types.hgen61
-rw-r--r--power/power.sail4607
-rw-r--r--power/power_embed.lem.fixed6743
-rw-r--r--power/power_embed_sequential.lem.fixed6743
-rw-r--r--power/power_extras.lem96
-rw-r--r--power/power_extras_embed.lem50
-rw-r--r--power/power_extras_embed_sequential.lem50
-rw-r--r--power/power_regfp.sail1483
-rw-r--r--risc-v/Makefile25
-rw-r--r--risc-v/gen/ast.hgen (renamed from risc-v/hgen/ast.hgen)8
-rw-r--r--risc-v/gen/fold.hgen16
-rw-r--r--risc-v/gen/herdtools_ast_to_shallow_ast.hgen (renamed from risc-v/hgen/herdtools_ast_to_shallow_ast.hgen)42
-rw-r--r--risc-v/gen/herdtools_types_to_shallow_types.hgen (renamed from risc-v/hgen/herdtools_types_to_shallow_types.hgen)75
-rw-r--r--risc-v/gen/lexer.hgen190
-rw-r--r--risc-v/gen/map.hgen15
-rw-r--r--risc-v/gen/parser.hgen74
-rw-r--r--risc-v/gen/pretty.hgen (renamed from risc-v/hgen/pretty.hgen)19
-rw-r--r--risc-v/gen/pretty_xml.hgen137
-rw-r--r--risc-v/gen/sail_trans_out.hgen (renamed from risc-v/hgen/sail_trans_out.hgen)13
-rw-r--r--risc-v/gen/shallow_ast_to_herdtools_ast.hgen (renamed from risc-v/hgen/shallow_ast_to_herdtools_ast.hgen)17
-rw-r--r--risc-v/gen/shallow_types_to_herdtools_types.hgen (renamed from risc-v/hgen/shallow_types_to_herdtools_types.hgen)75
-rw-r--r--risc-v/gen/token_types.hgen (renamed from risc-v/hgen/token_types.hgen)12
-rw-r--r--risc-v/gen/tokens.hgen (renamed from risc-v/hgen/tokens.hgen)5
-rw-r--r--risc-v/gen/trans_sail.hgen (renamed from risc-v/hgen/trans_sail.hgen)45
-rw-r--r--risc-v/gen/types.hgen (renamed from risc-v/hgen/types.hgen)81
-rw-r--r--risc-v/gen/types_sail_trans_out.hgen (renamed from risc-v/hgen/types_sail_trans_out.hgen)12
-rw-r--r--risc-v/gen/types_trans_sail.hgen (renamed from risc-v/hgen/types_trans_sail.hgen)18
-rw-r--r--risc-v/hgen/fold.hgen13
-rw-r--r--risc-v/hgen/lexer.hgen64
-rw-r--r--risc-v/hgen/map.hgen12
-rw-r--r--risc-v/hgen/parser.hgen36
-rw-r--r--risc-v/riscv.sail497
-rw-r--r--risc-v/riscv_extras.lem53
-rw-r--r--risc-v/riscv_extras_embed.lem59
-rw-r--r--risc-v/riscv_extras_embed_sequential.lem58
-rw-r--r--risc-v/riscv_regfp.sail77
-rw-r--r--risc-v/riscv_types.sail166
-rw-r--r--src/LICENCE10
-rw-r--r--src/Makefile16
-rw-r--r--src/Makefile-non-opam8
-rw-r--r--src/ast_util.ml19
-rw-r--r--src/ast_util.mli8
-rw-r--r--src/constraint.ml50
-rw-r--r--src/constraint.mli50
-rw-r--r--src/finite_map.ml8
-rw-r--r--src/gen_lib/deep_shallow_convert.lem163
-rw-r--r--src/gen_lib/sail_values.ml27
-rw-r--r--src/gen_lib/state.lem39
-rw-r--r--src/initial_check.ml41
-rw-r--r--src/initial_check.mli9
-rw-r--r--src/lem_interp/instruction_extractor.lem13
-rw-r--r--src/lem_interp/interp.lem12
-rw-r--r--src/lem_interp/interp_inter_imp.lem279
-rw-r--r--src/lem_interp/interp_interface.lem18
-rw-r--r--src/lem_interp/interp_lib.lem8
-rw-r--r--src/lem_interp/interp_utilities.lem8
-rw-r--r--src/lem_interp/pretty_interp.ml8
-rw-r--r--src/lem_interp/printing_functions.ml8
-rw-r--r--src/lem_interp/run_interp.ml8
-rw-r--r--src/lem_interp/run_interp_model.ml16
-rw-r--r--src/lem_interp/run_with_elf.ml18
-rw-r--r--src/lem_interp/run_with_elf_cheri.ml583
-rw-r--r--src/lem_interp/run_with_elf_cheri128.ml587
-rw-r--r--src/lem_interp/sail_impl_base.lem141
-rw-r--r--src/lexer.mll10
-rw-r--r--src/lexer2.mll14
-rw-r--r--src/monomorphise.ml50
-rw-r--r--src/myocamlbuild.ml8
-rw-r--r--src/ocaml_backend.ml71
-rw-r--r--src/parse_ast.ml11
-rw-r--r--src/parser.mly8
-rw-r--r--src/parser2.mly38
-rw-r--r--src/pp.ml8
-rw-r--r--src/pp.mli8
-rw-r--r--src/pre_lexer.mll10
-rw-r--r--src/pre_parser.mly8
-rw-r--r--src/pretty_print.ml8
-rw-r--r--src/pretty_print.mli8
-rw-r--r--src/pretty_print_common.ml8
-rw-r--r--src/pretty_print_lem.ml8
-rw-r--r--src/pretty_print_lem_ast.ml63
-rw-r--r--src/pretty_print_sail.ml8
-rw-r--r--src/pretty_print_sail2.ml158
-rw-r--r--src/process_file.ml19
-rw-r--r--src/process_file.mli9
-rw-r--r--src/reporting_basic.ml8
-rw-r--r--src/reporting_basic.mli8
-rw-r--r--src/rewriter.ml3001
-rw-r--r--src/rewriter.mli51
-rw-r--r--src/rewrites.ml2905
-rw-r--r--src/rewrites.mli70
-rw-r--r--src/sail.ml20
-rw-r--r--src/spec_analysis.ml8
-rw-r--r--src/spec_analysis.mli8
-rw-r--r--src/type_check.ml17
-rw-r--r--src/type_check.mli9
-rw-r--r--src/util.ml8
-rw-r--r--src/util.mli8
-rw-r--r--test/ocaml/short_circuit/expect1
-rw-r--r--test/ocaml/short_circuit/sc.sail15
-rwxr-xr-xtest/typecheck/run_tests.sh4
-rw-r--r--x86/Makefile20
-rw-r--r--x86/gen/ast.hgen26
-rw-r--r--x86/gen/fold.hgen26
-rw-r--r--x86/gen/herdtools_ast_to_shallow_ast.hgen28
-rw-r--r--x86/gen/herdtools_types_to_shallow_types.hgen93
-rw-r--r--x86/gen/lexer.hgen399
-rw-r--r--x86/gen/lexer_intel.hgen161
-rw-r--r--x86/gen/map.hgen26
-rw-r--r--x86/gen/parser.hgen600
-rw-r--r--x86/gen/parser_intel.hgen601
-rw-r--r--x86/gen/pretty.hgen50
-rw-r--r--x86/gen/sail_trans_out.hgen1
-rw-r--r--x86/gen/shallow_ast_to_herdtools_ast.hgen27
-rw-r--r--x86/gen/shallow_types_to_herdtools_types.hgen97
-rw-r--r--x86/gen/token_types.hgen29
-rw-r--r--x86/gen/tokens.hgen28
-rw-r--r--x86/gen/trans_sail.hgen28
-rw-r--r--x86/gen/types.hgen134
-rw-r--r--x86/gen/types_sail_trans_out.hgen1
-rw-r--r--x86/gen/types_trans_sail.hgen61
-rw-r--r--x86/x64.sail864
-rw-r--r--x86/x86_extras.lem53
-rw-r--r--x86/x86_extras_embed.lem24
-rw-r--r--x86/x86_extras_embed_sequential.lem24
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
diff --git a/src/pp.ml b/src/pp.ml
index 7da8aad3..b3eaf1fc 100644
--- a/src/pp.ml
+++ b/src/pp.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/pp.mli b/src/pp.mli
index 0613e433..5cfb3d88 100644
--- a/src/pp.mli
+++ b/src/pp.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/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