From c941eb027c817ace7d1c0e214c0b62cc7f7c751f Mon Sep 17 00:00:00 2001
From: emteere <47253321+emteere@users.noreply.github.com>
Date: Wed, 28 Aug 2024 14:52:30 -0400
Subject: [PATCH] GP-4879 Initial M16C commit
---
Ghidra/Processors/M16C/Module.manifest | 1 +
Ghidra/Processors/M16C/build.gradle | 23 +
Ghidra/Processors/M16C/certification.manifest | 12 +
.../M16C/data/languages/M16C_60.cspec | 40 +
.../M16C/data/languages/M16C_60.ldefs | 20 +
.../M16C/data/languages/M16C_60.pspec | 169 +
.../M16C/data/languages/M16C_60.slaspec | 3627 ++++++++++++
.../M16C/data/languages/M16C_80.cspec | 31 +
.../M16C/data/languages/M16C_80.ldefs | 20 +
.../M16C/data/languages/M16C_80.pspec | 296 +
.../M16C/data/languages/M16C_80.slaspec | 5050 +++++++++++++++++
.../Processors/M16C/data/manuals/M16C_60.idx | 95 +
.../Processors/M16C/data/manuals/M16C_80.idx | 110 +
13 files changed, 9494 insertions(+)
create mode 100644 Ghidra/Processors/M16C/Module.manifest
create mode 100644 Ghidra/Processors/M16C/build.gradle
create mode 100644 Ghidra/Processors/M16C/certification.manifest
create mode 100644 Ghidra/Processors/M16C/data/languages/M16C_60.cspec
create mode 100644 Ghidra/Processors/M16C/data/languages/M16C_60.ldefs
create mode 100644 Ghidra/Processors/M16C/data/languages/M16C_60.pspec
create mode 100644 Ghidra/Processors/M16C/data/languages/M16C_60.slaspec
create mode 100644 Ghidra/Processors/M16C/data/languages/M16C_80.cspec
create mode 100644 Ghidra/Processors/M16C/data/languages/M16C_80.ldefs
create mode 100644 Ghidra/Processors/M16C/data/languages/M16C_80.pspec
create mode 100644 Ghidra/Processors/M16C/data/languages/M16C_80.slaspec
create mode 100644 Ghidra/Processors/M16C/data/manuals/M16C_60.idx
create mode 100644 Ghidra/Processors/M16C/data/manuals/M16C_80.idx
diff --git a/Ghidra/Processors/M16C/Module.manifest b/Ghidra/Processors/M16C/Module.manifest
new file mode 100644
index 0000000000..f394b55cb6
--- /dev/null
+++ b/Ghidra/Processors/M16C/Module.manifest
@@ -0,0 +1 @@
+MODULE DEPENDENCY: Ghidra/Framework/SoftwareModeling
\ No newline at end of file
diff --git a/Ghidra/Processors/M16C/build.gradle b/Ghidra/Processors/M16C/build.gradle
new file mode 100644
index 0000000000..64451b65c1
--- /dev/null
+++ b/Ghidra/Processors/M16C/build.gradle
@@ -0,0 +1,23 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
+apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
+apply plugin: 'eclipse'
+eclipse.project.name = 'Processors M16C'
+
+sleighCompileOptions = [
+ '-l'
+]
diff --git a/Ghidra/Processors/M16C/certification.manifest b/Ghidra/Processors/M16C/certification.manifest
new file mode 100644
index 0000000000..06f5f2e280
--- /dev/null
+++ b/Ghidra/Processors/M16C/certification.manifest
@@ -0,0 +1,12 @@
+##VERSION: 2.0
+Module.manifest||GHIDRA||||END|
+data/languages/M16C_60.cspec||GHIDRA||||END|
+data/languages/M16C_60.ldefs||GHIDRA||||END|
+data/languages/M16C_60.pspec||GHIDRA||||END|
+data/languages/M16C_60.slaspec||GHIDRA||||END|
+data/languages/M16C_80.cspec||GHIDRA||||END|
+data/languages/M16C_80.ldefs||GHIDRA||||END|
+data/languages/M16C_80.pspec||GHIDRA||||END|
+data/languages/M16C_80.slaspec||GHIDRA||||END|
+data/manuals/M16C_60.idx||GHIDRA||||END|
+data/manuals/M16C_80.idx||GHIDRA||||END|
diff --git a/Ghidra/Processors/M16C/data/languages/M16C_60.cspec b/Ghidra/Processors/M16C/data/languages/M16C_60.cspec
new file mode 100644
index 0000000000..3949c2a7fc
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/languages/M16C_60.cspec
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/M16C/data/languages/M16C_60.ldefs b/Ghidra/Processors/M16C/data/languages/M16C_60.ldefs
new file mode 100644
index 0000000000..18014c05e0
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/languages/M16C_60.ldefs
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Renesas M16C/60 16-Bit MicroComputer
+
+
+
+
diff --git a/Ghidra/Processors/M16C/data/languages/M16C_60.pspec b/Ghidra/Processors/M16C/data/languages/M16C_60.pspec
new file mode 100644
index 0000000000..a1e280dda3
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/languages/M16C_60.pspec
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Ghidra/Processors/M16C/data/languages/M16C_60.slaspec b/Ghidra/Processors/M16C/data/languages/M16C_60.slaspec
new file mode 100644
index 0000000000..e6046afac7
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/languages/M16C_60.slaspec
@@ -0,0 +1,3627 @@
+# Renesas M16C/60 16-Bit MicroComputer
+
+#
+# Memory Architecture
+#
+define endian=little;
+
+define alignment=1;
+
+define space RAM type=ram_space size=3 default;
+define space register type=register_space size=2;
+
+#
+# General Registers
+#
+define register offset=0x0000 size=2 [
+ R1 R3 R0 R2 A0 A1
+];
+
+define register offset=0x0000 size=1 [
+ R1L R1H _ _ R0L R0H
+];
+
+define register offset=0x0000 size=4 [
+ R3R1 R2R0 A1A0
+];
+
+define register offset=0x1000 size=3 [
+ PC # Program Counter
+];
+
+define register offset=0x2000 size=3 [
+ INTB # Interrupt Table Register
+];
+
+define register offset=0x2000 size=2 [
+ INTBL INTBH
+];
+
+define register offset=0x3000 size=2 [
+ SP # Current Stack Pointer (Represents active stack pointer: ISP or USP)
+ FB # Frame Base Register
+ SB # Static Base Register
+ FLG # Flag Register
+ ISP # Interrupt Stack Pointer
+];
+
+# Flag Register Contents (FLG)
+#
+# b15 - Reserved area
+# b14:b12 - Processor interrupt priority level
+# b11:b8 - Reserved area
+# b7 - (U) Stack pointer select flag
+# b6 - (I) Interrupt enable flag
+# b5 - (O) Overflow flag
+# b4 - (B) Register bank select flag
+# b3 - (S) Sign flag
+# b2 - (Z) Zero flag
+# b1 - (D) Debug flag
+# b0 - (C) Carry flag
+@define CARRY "FLG[0,1]"
+@define DEBUG "FLG[1,1]"
+@define ZERO "FLG[2,1]"
+@define SIGN "FLG[3,1]"
+@define REG_BANK "FLG[4,1]"
+@define OVERFLOW "FLG[5,1]"
+@define INTERRUPT "FLG[6,1]"
+@define STACK_SEL "FLG[7,1]"
+@define IPL "FLG[12,3]"
+
+# Define context bits
+define register offset=0xA000 size=4 contextreg;
+
+define context contextreg
+ dstFollowsSrc = (0,1) # =1 destination add-on data follows 4-bit encoded source add-on data
+ # =2 destination add-on data follows 8-bit data
+;
+
+define token b0(8)
+ b0_0007 = (0,7)
+;
+
+define token b1(8)
+ b1_d2 = (0,1)
+ b1_d3 = (0,2)
+ b1_d3_2 = (2,2)
+ b1_2_reg8 = (2,2)
+ b1_2_regAx = (2,2)
+ b1_3_regAx = (3,3)
+ b1_3_reg8 = (3,3)
+ b1_size_0 = (0,0)
+ b1_0407 = (4,7)
+ b1_0307 = (3,7)
+ b1_0107 = (1,7)
+ b1_0007 = (0,7)
+ b1_0002 = (0,2)
+ b1_bit = (0,2)
+;
+
+define token b2(8)
+ b2_d4_reg8 = (0,1)
+ b2_s4_reg8 = (4,5)
+ b2_d4_reg16 = (0,1)
+ b2_s4_reg16 = (4,5)
+ b2_d4_reg32 = (0,0)
+ b2_s4_reg32 = (4,4)
+ b2_reg32 = (4,4)
+ b2_d4_regAxSF = (0,1) # selects A0, A1, SB or FB
+ b2_s4_regAxSF = (4,5) # selects A0, A1, SB or FB
+ b2_d4_regAx = (0,0)
+ b2_s4_regAx = (4,4)
+ b2_reg16 = (4,6)
+ b2_creg16 = (4,6)
+ b2_d4 = (0,3)
+ b2_d4_3 = (3,3)
+ b2_d4_23 = (2,3)
+ b2_d4_13 = (1,3)
+ b2_s4 = (4,7)
+ b2_s4_23 = (6,7)
+ b2_s4_13 = (5,7)
+ b2_shiftSign_7 = (7,7)
+ b2_shiftSign_3 = (3,3)
+ b2_0707 = (7,7)
+ b2_0607 = (6,7)
+ b2_0507 = (5,7)
+ b2_0407 = (4,7)
+ b2_0406 = (4,6)
+ b2_0307 = (3,7)
+ b2_0303 = (3,3)
+ b2_0007 = (0,7)
+ b2_0003 = (0,3)
+ b2_0002 = (0,2)
+ b2_simm4_0407 = (4,7) signed
+ b2_simm4_0003 = (0,3) signed
+;
+
+define token b3(8)
+ b3_0407 = (4,7)
+ b3_0007 = (0,7)
+ b3_0003 = (0,3)
+;
+
+define token b4(8)
+ b4_0007 = (0,7)
+;
+
+define token b5(8)
+ b5_0007 = (0,7)
+;
+
+define token b6(8)
+ b6_0007 = (0,7)
+;
+
+define token imm8(8)
+ simm8_dat = (0,7) signed
+ imm8_dat = (0,7)
+ imm8_base = (3,7) # bit,base byte displacement
+ imm8_bit = (0,2) # bit,base bit number
+ simm8_base = (3,7) signed # bit,base signed byte displacement
+ simm8_bit = (0,2) # bit,base signed bit number
+ imm6_dat = (0,5) # int number
+ cnd8_dat = (0,7)
+ imm8_0607 = (6,7)
+ imm8_0407 = (4,7)
+ imm8_0003 = (0,3)
+ regBit7 = (7,7)
+ regBit6 = (6,6)
+ regBit5 = (5,5)
+ regBit4 = (4,4)
+ regBit3 = (3,3)
+ regBit2 = (2,2)
+ regBit1 = (1,1)
+ regBit0 = (0,0)
+;
+
+define token imm16(16)
+ simm16_dat = (0,15) signed
+ imm16_dat = (0,15)
+ imm16_base = (3,15) # bit,base byte displacement
+ imm16_bit = (0, 2) # bit,base bit number
+;
+
+define token imm24(24)
+ simm24_dat = (0,23) signed
+ imm24_dat = (0,23)
+ simm20_dat = (0,19)
+ imm20_dat = (0,19)
+;
+
+define token imm32(32)
+ simm32_dat = (0,31) signed
+ imm32_dat = (0,31)
+;
+
+attach variables [ b2_s4_reg16 b2_d4_reg16 ] [ R0 R1 R2 R3 ];
+attach variables [ b2_s4_reg8 b2_d4_reg8 ] [ R0L R0H R1L R1H ];
+attach variables [ b1_2_reg8 b1_3_reg8 ] [ R0L R0H ];
+attach variables [ b2_s4_regAx b2_d4_regAx b1_3_regAx b1_2_regAx ] [ A0 A1 ];
+attach variables [ b2_s4_regAxSF b2_d4_regAxSF ] [ A0 A1 SB FB ];
+attach variables [ b2_reg16 ] [ R0 R1 R2 R3 A0 A1 _ _ ];
+attach variables [ b2_creg16 ] [ _ INTBL INTBH FLG ISP SP SB FB ];
+attach variables [ b2_reg32 b2_d4_reg32 ] [ R2R0 R3R1 ];
+
+#
+# PCode Op
+#
+define pcodeop Break; # BRK
+define pcodeop DecimalAdd; # DADD
+define pcodeop DecimalAddWithCarry; # DADC
+define pcodeop DecimalSubtractWithBorrow; # DSBB
+define pcodeop DecimalSubtract; # DSUB
+define pcodeop Wait; # WAIT
+
+#
+# FLAG MACROS...
+#
+# Set zero and sign flags from result
+macro setResultFlags(result) {
+ $(SIGN) = (result s< 0x0);
+ $(ZERO) = (result == 0x0);
+}
+
+# Set carry and overflow flags for addition
+macro setAdd3Flags(v1, v2, v3) {
+ local add13 = v1 + v3;
+ $(CARRY) = carry(v1,v3) || carry(v2,add13);
+ $(OVERFLOW) = scarry(v1,v3) || scarry(v2,add13);
+}
+
+# Set carry and overflow flags for addition
+macro setAddFlags(v1, v2) {
+ $(CARRY) = carry(v1, v2);
+ $(OVERFLOW) = scarry(v1, v2);
+}
+
+# Set overflow flags for subtraction of op3,op2 from op1 (op1-op2-op3)
+macro setSubtract3Flags(v1, v2, v3) {
+ local add12 = v1 - v2;
+ $(CARRY) = (v1 >= v2) || (add12 >= v3);
+ $(OVERFLOW) = sborrow(v1, v2) || sborrow(add12, v3);
+}
+
+# Set overflow flags for subtraction of op2 from op1 (op1-op2)
+macro setSubtractFlags(v1, v2) {
+ $(CARRY) = (v1 s>= v2);
+ $(OVERFLOW) = sborrow(v1, v2);
+}
+
+macro push1(val) {
+ SP = SP - 1;
+ ptr:3 = zext(SP);
+ *:1 ptr = val;
+}
+
+macro push2(val) {
+ SP = SP - 2;
+ ptr:3 = zext(SP);
+ *:2 ptr = val;
+}
+
+macro push3(val) {
+ SP = SP - 3;
+ ptr:3 = zext(SP);
+ *:3 ptr = val;
+}
+
+macro push4(val) {
+ SP = SP - 4;
+ ptr:3 = zext(SP);
+ *:4 ptr = val;
+}
+
+macro pop1(val) {
+ ptr:3 = zext(SP);
+ val = *:1 ptr;
+ SP = SP + 1;
+}
+
+macro pop2(val) {
+ ptr:3 = zext(SP);
+ val = *:2 ptr;
+ SP = SP + 2;
+}
+
+macro pop3(val) {
+ ptr:3 = zext(SP);
+ val = *:3 ptr;
+ SP = SP + 3;
+}
+
+macro pop4(val) {
+ ptr:3 = zext(SP);
+ val = *:4 ptr;
+ SP = SP + 4;
+}
+
+#
+# Source operand location data
+#
+# Obtain base offset displacement for [AX | SB | FB] - AX and SB uses unsigned displacements, FB uses signed displacement
+src4dsp8: imm8_dat^":8" is b1_0007; b2_s4; imm8_dat { export *[const]:2 imm8_dat; }
+src4dsp8: simm8_dat^":8" is b1_0007; b2_s4=0xb; simm8_dat { export *[const]:2 simm8_dat; }
+src4dsp16: imm16_dat^":16" is b1_0007; b2_s4; imm16_dat { export *[const]:2 imm16_dat; }
+
+# src4... Handle 4-bit encoded Source specified by b2_s4(4-bits)
+# Variable length pattern starting at instruction byte b1
+# associated src4 add-on data immediately follows instruction byte b2
+# abs16 cases are broken out differently to facilitate export of constant addresses in certain cases
+# 1-Byte source value/location specified by 4-bit encoding (b2_d4)
+src4B: b2_s4_reg8 is b1_0007; b2_s4_23=0x0 & b2_s4_reg8 { export b2_s4_reg8; } # Rx
+src4B: b2_s4_regAx is b1_0007; b2_s4_13=0x2 & b2_s4_regAx { tmp:1 = b2_s4_regAx:1; export tmp; } # Ax
+src4B: [b2_s4_regAx] is b1_0007; b2_s4_13=0x3 & b2_s4_regAx { ptr:3 = zext(b2_s4_regAx); export *:1 ptr; } # [Ax]
+src4B: src4dsp8^[b2_s4_regAxSF] is (b1_0007; b2_s4_23=0x2 & b2_s4_regAxSF) ... & src4dsp8 { ptr:3 = zext(b2_s4_regAxSF + src4dsp8); export *:1 ptr; } # dsp:8[Ax|SB|FB]
+src4B: src4dsp16^[b2_s4_regAxSF] is (b1_0007; b2_s4_23=0x3 & b2_s4_regAxSF) ... & src4dsp16 { ptr:3 = zext(b2_s4_regAxSF + src4dsp16); export *:1 ptr; } # dsp:16[Ax|SB|FB]
+src4B: imm16_dat is b1_0007; b2_s4=0xf; imm16_dat { export *:1 imm16_dat; } # abs16 (special constant address case)
+
+# 2-Byte source value/location specified by 2-bit encoding (b2_d4)
+src4W: b2_s4_reg16 is b1_0007; b2_s4_23=0x0 & b2_s4_reg16 { export b2_s4_reg16; } # Rx
+src4W: b2_s4_regAx is b1_0007; b2_s4_13=0x2 & b2_s4_regAx { export b2_s4_regAx; } # Ax
+src4W: [b2_s4_regAx] is b1_0007; b2_s4_13=0x3 & b2_s4_regAx { ptr:3 = zext(b2_s4_regAx); export *:2 ptr; } # [Ax]
+src4W: src4dsp8^[b2_s4_regAxSF] is (b1_0007; b2_s4_23=0x2 & b2_s4_regAxSF) ... & src4dsp8 { ptr:3 = zext(b2_s4_regAxSF + src4dsp8); export *:2 ptr; } # dsp:8[Ax|SB|FB]
+src4W: src4dsp16^[b2_s4_regAxSF] is (b1_0007; b2_s4_23=0x3 & b2_s4_regAxSF) ... & src4dsp16 { ptr:3 = zext(b2_s4_regAxSF + src4dsp16); export *:2 ptr; } # dsp:16[Ax|SB|FB]
+src4W: imm16_dat is b1_0007; b2_s4=0xf; imm16_dat { export *:2 imm16_dat; } # abs16 (special constant address case)
+
+#
+# Destination operand location data (may also be used as a source in certain cases)
+#
+# Skip instruction and source add-on bytes which occur before destination add-on bytes
+# Starting position is at b1
+skipBytesBeforeDst4: is b1_0007; b2_s4 { }
+skipBytesBeforeDst4: is dstFollowsSrc=1 & b1_0007; b2_s4_23=0x2; imm8_dat { } # src4: dsp8
+skipBytesBeforeDst4: is dstFollowsSrc=1 & b1_0007; b2_s4_23=0x3; imm16_dat { } # src4: dsp16/abs16
+skipBytesBeforeDst4: is dstFollowsSrc=2 & b1_0007; b2_d4; imm8_dat { } # dsp8
+
+# Obtain base offset displacement for [AX | SB | FB] - AX and SB uses unsigned displacements, FB uses signed displacement
+dst4dsp8: imm8_dat^":8" is (skipBytesBeforeDst4; imm8_dat) { export *[const]:2 imm8_dat; }
+dst4dsp8: simm8_dat^":8" is (b1_0007; b2_d4=0xb) ... & (skipBytesBeforeDst4; simm8_dat) { export *[const]:2 simm8_dat; }
+dst4dsp16: imm16_dat^":16" is (skipBytesBeforeDst4; imm16_dat) { export *[const]:2 imm16_dat; }
+
+# dst4... Handle 4-bit encoded Destination specified by b2_d4(4-bits)
+# Ax direct case is read-only! Instruction must use dst4Ax for write/update case
+# Variable length pattern starting at instruction byte b1
+# abs16 cases are broken out differently to facilitate export of constant addresses in certain cases
+# 1-Byte destination value/location specified by 4-bit encoding (b2_d4)
+dst4B: b2_d4_reg8 is b1_0007; b2_d4_23=0x0 & b2_d4_reg8 { export b2_d4_reg8; } # Rx
+dst4B: b2_d4_regAx is b1_0007; b2_d4_13=0x2 & b2_d4_regAx { tmp:1 = b2_d4_regAx:1; export tmp; } # Ax - read-only use !
+dst4B: [b2_d4_regAx] is b1_0007; b2_d4_13=0x3 & b2_d4_regAx { ptr:3 = zext(b2_d4_regAx); export *:1 ptr; } # [Ax]
+dst4B: dst4dsp8^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x2 & b2_d4_regAxSF) ... & dst4dsp8 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp8); export *:1 ptr; } # dsp:8[Ax|SB|FB]
+dst4B: dst4dsp16^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x3 & b2_d4_regAxSF) ... & dst4dsp16 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp16); export *:1 ptr; } # dsp:16[Ax|SB]
+dst4B: imm16_dat is (b1_0007; b2_d4=0xf) ... & (skipBytesBeforeDst4; imm16_dat) { export *:1 imm16_dat; } # abs16 (special constant address case)
+
+# 2-Byte destination value/location specified by 4-bit encoding (b2_d4)
+dst4W: b2_d4_reg16 is b1_0007; b2_d4_23=0x0 & b2_d4_reg16 { export b2_d4_reg16; } # Rx
+dst4W: b2_d4_regAx is b1_0007; b2_d4_13=0x2 & b2_d4_regAx { export b2_d4_regAx; } # Ax
+dst4W: [b2_d4_regAx] is b1_0007; b2_d4_13=0x3 & b2_d4_regAx { ptr:3 = zext(b2_d4_regAx); export *:2 ptr; } # [Ax]
+dst4W: dst4dsp8^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x2 & b2_d4_regAxSF) ... & dst4dsp8 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp8); export *:2 ptr; } # dsp:8[Ax|SB|FB]
+dst4W: dst4dsp16^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x3 & b2_d4_regAxSF) ... & dst4dsp16 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp16); export *:2 ptr; } # dsp:16[Ax|SB]
+dst4W: imm16_dat is (b1_0007; b2_d4=0xf) ... & (skipBytesBeforeDst4; imm16_dat) { export *:2 imm16_dat; } # abs16 (special constant address case)
+
+# 4-Byte destination value/location specified by 4-bit encoding (b2_d4)
+dst4L: b2_d4_reg32 is b1_0007; b2_d4_13=0x0 & b2_d4_reg32 { export b2_d4_reg32; } # Rx
+dst4L: A1A0 is A1A0 & b1_0007; b2_d4=0x4 { export A1A0; } # A1A0
+dst4L: [b2_d4_regAx] is b1_0007; b2_d4_13=0x3 & b2_d4_regAx { ptr:3 = zext(b2_d4_regAx); export *:4 ptr; } # [Ax]
+dst4L: dst4dsp8^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x2 & b2_d4_regAxSF) ... & dst4dsp8 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp8); export *:4 ptr; } # dsp:8[Ax|SB|FB]
+dst4L: dst4dsp16^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x3 & b2_d4_regAxSF) ... & dst4dsp16 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp16); export *:4 ptr; } # dsp:16[Ax|SB]
+dst4L: imm16_dat is (b1_0007; b2_d4=0xf) ... & (skipBytesBeforeDst4; imm16_dat) { export *:4 imm16_dat; } # abs16 (special constant address case)
+
+# 3-Byte destination value/location specified by 4-bit encoding (b2_d4) - use DST4L to constrain, and dst4L for register Ax/Rx non-memory cases
+dst4T: [b2_d4_regAx] is b1_0007; b2_d4_13=0x3 & b2_d4_regAx { ptr:3 = zext(b2_d4_regAx); export *:3 ptr; } # [Ax]
+dst4T: dst4dsp8^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x2 & b2_d4_regAxSF) ... & dst4dsp8 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp8); export *:3 ptr; } # dsp:8[Ax|SB|FB]
+dst4T: dst4dsp16^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x3 & b2_d4_regAxSF) ... & dst4dsp16 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp16); export *:3 ptr; } # dsp:16[Ax|SB]
+dst4T: imm16_dat is (b1_0007; b2_d4=0xf) ... & (skipBytesBeforeDst4; imm16_dat) { export *:3 imm16_dat; } # abs16 (special constant address case)
+
+# 3-Byte effective address specified by 4-bit encoding (b2_d4)
+dst4A: dst4dsp8^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x2 & b2_d4_regAxSF) ... & dst4dsp8 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp8); export ptr; } # dsp:8[Ax|SB|FB]
+dst4A: dst4dsp16^[b2_d4_regAxSF] is (b1_0007; b2_d4_23=0x3 & b2_d4_regAxSF) ... & dst4dsp16 { ptr:3 = zext(b2_d4_regAxSF + dst4dsp16); export ptr; } # dsp:16[Ax|SB]
+dst4A: imm16_dat is (b1_0007; b2_d4=0xf) ... & (skipBytesBeforeDst4; imm16_dat) { export *[const]:3 imm16_dat; } # abs16 (special constant address case)
+
+# Ax destination specified by 4-bit encoding (b2_d4)
+# NOTE! Ax destination is special case and must be handled separately by each instruction
+# Starting position is at instruction b1
+dst4Ax: b2_d4_regAx is b1_0007; b2_d4_regAx { export b2_d4_regAx; }
+
+# 1/2-Byte destination value/location specified by 4-bit encoding (b2_d4)
+# This handles the case for dst4B, dst4W and dst4L where 5-bit encoded Source (src4) add-on bytes may exist before Destination add-on bytes
+# Variable length pattern starting at instruction byte b1
+dst4B_afterSrc4: dst4B is dst4B [ dstFollowsSrc=1; ] { export dst4B; }
+
+dst4W_afterSrc4: dst4W is dst4W [ dstFollowsSrc=1; ] { export dst4W; }
+
+dst4L_afterSrc4: dst4L is dst4L [ dstFollowsSrc=1; ] { export dst4L; }
+
+#
+# The following macros are used to constrain bit patterns when using dst4
+# These should be used by constructor pattern matching instead of the corresponding dst4 sub-constructor
+#
+@define DST4AX "((b1_0007; b2_d4_13=0x2) & dst4Ax)"
+@define DST4A "((b1_0007; b2_d4_3=1) ... & dst4A)"
+@define DST4T "((b1_0007; (b2_d4_3=1 | b2_d4_13=3)) ... & dst4T)"
+
+# Skip instruction and source add-on bytes which occur before destination add-on bytes
+# Starting position is at b1
+skipBytesBeforeDst2: is b1_d2 { }
+skipBytesBeforeDst2: is dstFollowsSrc=2 & b1_d2; imm8_dat { } # dsp8
+
+#
+# destination value/location specified by 2/3-bit encoding, R0H/R0L choice controlled by destination-bit (b1_0002)
+#
+dst2B: R0L is (R0L & b1_d3=0x4) { export R0L; }
+dst2B: R0H is (R0H & b1_d3=0x0) { export R0H; }
+dst2B: imm8_dat^[SB] is (SB & b1_d2=0x1) ... & (skipBytesBeforeDst2; imm8_dat) { ptr:3 = zext(SB + imm8_dat); export *:1 ptr; }
+dst2B: simm8_dat^[FB] is (FB & b1_d2=0x2) ... & (skipBytesBeforeDst2; simm8_dat) { ptr:3 = zext(FB + simm8_dat); export *:1 ptr; }
+dst2B: imm16_dat is (b1_d2=0x3) ... & (skipBytesBeforeDst2; imm16_dat) { export *:1 imm16_dat; }
+
+#
+# destination value/location specified by 3-bit encoding (must be constrained by DST3B or DST3B_AFTER_DSP8)
+#
+dst3B: R0L is (R0L & b1_d3=0x4) { export R0L; }
+dst3B: R0H is (R0H & b1_d3=0x3) { export R0H; }
+dst3B: imm8_dat^[SB] is (SB & b1_d3=0x5) ... & (skipBytesBeforeDst2; imm8_dat) { ptr:3 = zext(SB + imm8_dat); export *:1 ptr; }
+dst3B: simm8_dat^[FB] is (FB & b1_d3=0x6) ... & (skipBytesBeforeDst2; simm8_dat) { ptr:3 = zext(FB + simm8_dat); export *:1 ptr; }
+dst3B: imm16_dat is (b1_d3=0x7) ... & (skipBytesBeforeDst2; imm16_dat) { export *:1 imm16_dat; }
+
+# 1-Byte destination value/location specified by 3-bit encoding (b2_d3)
+# This handles the case for dst3B where Dsp8 add-on bytes always exist before Destination add-on bytes
+# Variable length pattern starting at instruction byte b1
+dst3B_afterDsp8: dst3B is dst3B [ dstFollowsSrc=2; ] { export dst3B; }
+
+#
+# The following macros are used to constrain bit patterns when using dst2 for a 3-bit src/dest
+# These should be used by constructor pattern matching instead of the corresponding dst4 sub-constructor
+#
+@define DST3B "((b1_d3=3 | b1_d3_2=1) ... & dst3B)"
+@define DST3B_AFTER_DSP8 "((b1_d3=3 | b1_d3_2=1) ... & dst3B_afterDsp8)"
+
+# Special dsp8[SP] source/destination - starting point is on dsp8 data
+dsp8spB: simm8_dat^":8"^[SP] is simm8_dat & SP { ptr:3 = zext(SP + simm8_dat); export *:1 ptr; }
+
+dsp8spW: simm8_dat^":8"^[SP] is simm8_dat & SP { ptr:3 = zext(SP + simm8_dat); export *:2 ptr; }
+
+# Special dsp20[A0] source/destination - starting point is on dsp20 data
+dsp20A0B: simm20_dat^":20["^A0^"]" is A0 & simm20_dat { ptr:3 = zext(A0 + simm20_dat); export *:1 ptr; }
+
+dsp20A0W: simm20_dat^":20["^A0^"]" is A0 & simm20_dat { ptr:3 = zext(A0 + simm20_dat); export *:2 ptr; }
+
+#
+# Bit base - associated add-on data immediately follows instruction byte b2
+# There are three cases which must be broken-out by instruction (regBase, memBaseAx, memBase)
+#
+# bit-base is bit,byte specified by [Ax] (constrain instruction pattern using b2_d4_13=0x3) - contexts of Ax are exported
+memBaseAx: [b2_d4_regAx] is b1_0007; b2_d4_13=0x3 & b2_d4_regAx { export b2_d4_regAx; } # [Ax] (special case! bit operand does not appear)
+
+# bit-base is 16-bit register: Rx or Ax (constrain instruction pattern using b2_d4_3=0)
+regBase: b2_d4_reg16 is b1_0007; b2_d4_23=0x0 & b2_d4_reg16 { export b2_d4_reg16; } # Rx
+regBase: b2_d4_regAx is b1_0007; b2_d4_13=0x2 & b2_d4_regAx { export b2_d4_regAx; } # Ax
+
+# bit-base is byte location within memory
+memBase: imm8_base^":8"^[b2_d4_regAxSF] is b1_0007; b2_d4_23=0x2 & b2_d4_regAxSF; imm8_base { ptr:3 = zext(b2_d4_regAxSF + imm8_base); export *:1 ptr; } # dsp:8[Ax|SB]
+memBase: simm8_base^":8"^[FB] is b1_0007; b2_d4_23=0x2 & b2_d4=0xb & FB; simm8_base { ptr:3 = zext(FB + simm8_base); export *:1 ptr; } # dsp:8[FB]
+memBase: imm16_base^":16"^[b2_d4_regAxSF] is b1_0007; b2_d4_23=0x3 & b2_d4_regAxSF; imm16_base { ptr:3 = zext(b2_d4_regAxSF + imm16_base); export *:1 ptr; } # dsp:16[Ax|SB]
+memBase: imm16_base^":16" is b1_0007; b2_d4=0xf; imm16_base { export *:1 imm16_base; } # abs16 (special constant address case)
+
+memBase11: imm8_dat^":11"^[SB] is SB & b1_0007; imm8_dat { ptr:3 = zext(SB + imm8_dat); export *:1 ptr; } # dsp:11[SB]
+
+# Bit operand associated with regBase operand
+# TODO: imm8_0407=0 constraint removed due to sleigh compiler issue
+regBit: imm8_0003 is b1_0007; b2_d4; imm8_0003 { export *[const]:1 imm8_0003; } # Rx, Ax
+
+# Bit operand associated with memBase operand
+memBit: imm8_bit is b1_0007; b2_d4; imm8_bit { export *[const]:1 imm8_bit; } # dsp:8[Ax|SB|FB]
+memBit: imm16_bit is b1_0007; b2_d4_23=3; imm16_bit { export *[const]:1 imm16_bit; } # dsp:16[Ax|SB], base:16
+
+#
+# Immediate data operand
+# Fixed length - current position is at start of immediate data
+#
+srcImm3: "#"^b2_0002 is b2_0002 { export *[const]:1 b2_0002; }
+srcImm8: "#"^imm8_dat is imm8_dat { export *[const]:1 imm8_dat; }
+srcImm16: "#"^imm16_dat is imm16_dat { export *[const]:2 imm16_dat; }
+
+srcSimm8: "#"^simm8_dat is simm8_dat { export *[const]:1 simm8_dat; }
+srcSimm16: "#"^simm16_dat is simm16_dat { export *[const]:2 simm16_dat; }
+
+# Signed immediate data from 4-bit value: -8 <= value <= 7
+# NOTE! There are two different cases based upon the bits used from b2
+srcSimm4_0407: "#"^b2_simm4_0407 is b2_simm4_0407 { export *[const]:1 b2_simm4_0407; }
+srcSimm4_0003: "#"^b2_simm4_0003 is b2_simm4_0003 { export *[const]:1 b2_simm4_0003; }
+
+# Signed immediate shift amount from 4-bit value: -8 <= value <= -1 || 1 <= value <= 8
+# NOTE! There are two different cases based upon the bits used from b2
+srcSimm4Shift_0407: "#"^val is b2_shiftSign_7=0 & b2_0406 [ val = b2_0406 + 1; ] { export *[const]:1 val; }
+srcSimm4Shift_0407: "#"^val is b2_shiftSign_7=1 & b2_0406 [ val = -(b2_0406 + 1); ] { export *[const]:1 val; }
+srcSimm4Shift_0003: "#"^val is b2_shiftSign_3=0 & b2_0002 [ val = b2_0002 + 1; ] { export *[const]:1 val; }
+srcSimm4Shift_0003: "#"^val is b2_shiftSign_3=1 & b2_0002 [ val = -(b2_0002 + 1); ] { export *[const]:1 val; }
+
+srcZero8: "#0" is b1_0007 { export 0:1; }
+
+# special 6-bit immediate for INT number
+srcIntNum: "#"^imm6_dat is imm6_dat { export *[const]:1 imm6_dat; }
+
+#
+# Offset label operand
+#
+abs20offset: imm20_dat is imm20_dat { export *:1 imm20_dat; }
+
+abs20offsetW: imm20_dat is imm20_dat { export *:2 imm20_dat; }
+
+abs16offset: imm16_dat is imm16_dat { export *:1 imm16_dat; }
+
+# Relative address offsets
+rel16offset1: offs is simm16_dat [ offs = inst_start + 1 + simm16_dat; ] { export *:1 offs; }
+
+rel8offset1: offs is simm8_dat [ offs = inst_start + 1 + simm8_dat; ] { export *:1 offs; }
+rel8offset2: offs is simm8_dat [ offs = inst_start + 2 + simm8_dat; ] { export *:1 offs; }
+
+rel3offset2: offs is b1_0002 [ offs = inst_start + 2 + b1_0002; ] { export *:1 offs; }
+
+reloffset_dst4W: dst4W is dst4W { local reladdr = inst_start + dst4W; export *:3 reladdr; }
+
+reloffset_dst4L: dst4L is dst4L { local reladdr = inst_start + dst4L; export *:3 reladdr; }
+
+reloffset_dst4T: dst4T is $(DST4T) { local reladdr = inst_start + dst4T; export *:3 reladdr; }
+
+#
+# Conditionals
+#
+cnd8: "GEU" is cnd8_dat=0x00 { tstCnd:1 = ($(CARRY) == 1); export tstCnd; } # Equal to or greater than (<=), C flag is 1
+cnd8: "GTU" is cnd8_dat=0x01 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 1); export tstCnd; } # Greater than (<)
+cnd8: "EQ" is cnd8_dat=0x02 { tstCnd:1 = ($(ZERO) == 1); export tstCnd; } # Equal to (=), Z flag is 1
+cnd8: "N" is cnd8_dat=0x03 { tstCnd:1 = ($(SIGN) == 1); export tstCnd; } # Negative (0>)
+cnd8: "LE" is cnd8_dat=0x04 { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 1); export tstCnd; } # Equal to or less than (signed value) (>=)
+cnd8: "O" is cnd8_dat=0x05 { tstCnd:1 = ($(OVERFLOW) == 1); export tstCnd; } # O flag is 1
+cnd8: "GE" is cnd8_dat=0x06 { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 0); export tstCnd; } # Equal to or greater than (signed value) (<=)
+cnd8: "LTU" is cnd8_dat=0xf8 { tstCnd:1 = ($(CARRY) == 0); export tstCnd; } # less than (>), C flag is 0
+cnd8: "LEU" is cnd8_dat=0xf9 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 0); export tstCnd; } # Equal to or less than (>=)
+cnd8: "NE" is cnd8_dat=0xfa { tstCnd:1 = ($(ZERO) == 0); export tstCnd; } # Not Equal to (=), Z flag is 0
+cnd8: "PZ" is cnd8_dat=0xfb { tstCnd:1 = ($(SIGN) == 0); export tstCnd; } # Positive or zero (0<=)
+cnd8: "GT" is cnd8_dat=0xfc { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 0); export tstCnd; } # Greater than (signed value) (<)
+cnd8: "NO" is cnd8_dat=0xfd { tstCnd:1 = ($(OVERFLOW) == 0); export tstCnd; } # O flag is 0
+cnd8: "LT" is cnd8_dat=0xfe { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 1); export tstCnd; } # less than (signed value) (<=)
+
+b2cnd4: "GEU" is b2_0003=0x0 { tstCnd:1 = ($(CARRY) == 1); export tstCnd; } # Equal to or greater than (<=), C flag is 1
+b2cnd4: "GTU" is b2_0003=0x1 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 1); export tstCnd; } # Greater than (<)
+b2cnd4: "EQ" is b2_0003=0x2 { tstCnd:1 = ($(ZERO) == 1); export tstCnd; } # Equal to (=), Z flag is 1
+b2cnd4: "N" is b2_0003=0x3 { tstCnd:1 = ($(SIGN) == 1); export tstCnd; } # Negative (0>)
+b2cnd4: "LTU" is b2_0003=0x4 { tstCnd:1 = ($(CARRY) == 0); export tstCnd; } # less than (>), C flag is 0
+b2cnd4: "LEU" is b2_0003=0x5 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 0); export tstCnd; } # Equal to or less than (>=)
+b2cnd4: "NE" is b2_0003=0x6 { tstCnd:1 = ($(ZERO) == 0); export tstCnd; } # Not Equal to (=), Z flag is 0
+b2cnd4: "PZ" is b2_0003=0x7 { tstCnd:1 = ($(SIGN) == 0); export tstCnd; } # Positive or zero (0<=)
+b2cnd4: "LE" is b2_0003=0x8 { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 1); export tstCnd; } # Equal to or less than (signed value) (>=)
+b2cnd4: "O" is b2_0003=0x9 { tstCnd:1 = ($(OVERFLOW) == 1); export tstCnd; } # O flag is 1
+b2cnd4: "GE" is b2_0003=0xa { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 0); export tstCnd; } # Equal to or greater than (signed value) (<=)
+b2cnd4: "GT" is b2_0003=0xc { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 0); export tstCnd; } # Greater than (signed value) (<)
+b2cnd4: "NO" is b2_0003=0xd { tstCnd:1 = ($(OVERFLOW) == 0); export tstCnd; } # O flag is 0
+b2cnd4: "LT" is b2_0003=0xe { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 1); export tstCnd; } # less than (signed value) (<=)
+
+# Special case of b2cnd4 where b2_0003=1 (see JCnd)
+b2cnd3: "LE" is b2_0002=0x0 { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 1); export tstCnd; } # Equal to or less than (signed value) (>=)
+b2cnd3: "O" is b2_0002=0x1 { tstCnd:1 = ($(OVERFLOW) == 1); export tstCnd; } # O flag is 1
+b2cnd3: "GE" is b2_0002=0x2 { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 0); export tstCnd; } # Equal to or greater than (signed value) (<=)
+b2cnd3: "GT" is b2_0002=0x4 { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 0); export tstCnd; } # Greater than (signed value) (<)
+b2cnd3: "NO" is b2_0002=0x5 { tstCnd:1 = ($(OVERFLOW) == 0); export tstCnd; } # O flag is 0
+b2cnd3: "LT" is b2_0002=0x6 { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 1); export tstCnd; } # less than (signed value) (<=)
+
+b1cnd3: "LTU" is b1_0002=4 { tstCnd:1 = ($(CARRY) == 0); export tstCnd; } # less than (>), C flag is 0
+b1cnd3: "LEU" is b1_0002=5 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 0); export tstCnd; } # Equal to or less than (>=)
+b1cnd3: "NE" is b1_0002=6 { tstCnd:1 = ($(ZERO) == 0); export tstCnd; } # Not Equal to (=), Z flag is 0
+b1cnd3: "PZ" is b1_0002=7 { tstCnd:1 = ($(SIGN) == 0); export tstCnd; } # Positive or zero (0<=)
+b1cnd3: "GEU" is b1_0002=0 { tstCnd:1 = ($(CARRY) == 1); export tstCnd; } # Equal to or greater than (<=), C flag is 1
+b1cnd3: "GTU" is b1_0002=1 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 1); export tstCnd; } # Greater than (<)
+b1cnd3: "EQ" is b1_0002=2 { tstCnd:1 = ($(ZERO) == 1); export tstCnd; } # Equal to (=), Z flag is 1
+b1cnd3: "N" is b1_0002=3 { tstCnd:1 = ($(SIGN) == 1); export tstCnd; } # Negative (0>)
+
+#
+# Flag bit operand
+#
+flagBit: "C" is b2_0406=0 { export 0:2; }
+flagBit: "D" is b2_0406=1 { export 1:2; }
+flagBit: "Z" is b2_0406=2 { export 2:2; }
+flagBit: "S" is b2_0406=3 { export 3:2; }
+flagBit: "B" is b2_0406=4 { export 4:2; }
+flagBit: "O" is b2_0406=5 { export 5:2; }
+flagBit: "I" is b2_0406=6 { export 6:2; }
+flagBit: "U" is b2_0406=7 { export 7:2; }
+
+#
+# Instruction Constructors
+#
+### ABS ###
+:ABS.B dst4B is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xf) ... & dst4B {
+ local tmp = dst4B;
+ $(OVERFLOW) = (tmp == 0x80);
+ local ztst = (tmp s< 0);
+ tmp = (zext(ztst) * -tmp) + (zext(!ztst) * tmp);
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# 0111 0110 1111 0100 ABS.B A0
+# 0111 0110 1111 0001 ABS.B R0H
+:ABS.B dst4Ax is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xf) & $(DST4AX) {
+ local tmp = dst4Ax:1;
+ $(OVERFLOW) = (tmp == 0x80);
+ local ztst = (tmp s< 0);
+ tmp = (zext(ztst) * -tmp) + (zext(!ztst) * tmp);
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+:ABS.W dst4W is (b1_0107=0x3b & b1_size_0=1; b2_0407=0xf) ... & dst4W {
+ local tmp = dst4W;
+ $(OVERFLOW) = (tmp == 0x8000);
+ local ztst = (tmp s< 0);
+ tmp = (zext(ztst) * -tmp) + (zext(!ztst) * tmp);
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+### ADC ###
+
+# (1) ADC.B #simm, dst
+:ADC.B srcSimm8, dst4B is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x6) ... & dst4B); srcSimm8 {
+ tmp:1 = dst4B;
+ c:1 = $(CARRY);
+ setAdd3Flags(tmp, srcSimm8, c);
+ tmp = tmp + srcSimm8 + c;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ADC.B #simm, Ax
+:ADC.B srcSimm8, dst4Ax is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x6) & $(DST4AX)); srcSimm8 {
+ tmp:1 = dst4Ax:1;
+ c:1 = $(CARRY);
+ setAdd3Flags(tmp, srcSimm8, c);
+ tmp = tmp + srcSimm8 + c;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ADC.W #simm, dst
+:ADC.W srcSimm16, dst4W is ((b1_0107=0x3b & b1_size_0=1; b2_0407=0x6) ... & dst4W); srcSimm16 {
+ tmp:2 = dst4W;
+ c:2 = zext($(CARRY));
+ setAdd3Flags(tmp, srcSimm16, c);
+ tmp = tmp + srcSimm16 + c;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ADC.B src, dst
+:ADC.B src4B, dst4B_afterSrc4 is (b1_0107=0x58 & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ tmp:1 = dst4B_afterSrc4;
+ src:1 = src4B;
+ c:1 = $(CARRY);
+ setAdd3Flags(tmp, src, c);
+ tmp = tmp + src + c;
+ dst4B_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ADC.B src, Ax
+:ADC.B src4B, dst4Ax is (b1_0107=0x58 & b1_size_0=0) ... & src4B & $(DST4AX) ... {
+ tmp:1 = dst4Ax:1;
+ src:1 = src4B;
+ c:1 = $(CARRY);
+ setAdd3Flags(tmp, src, c);
+ tmp = tmp + src + c;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) ADC.W src, dst
+:ADC.W src4W, dst4W_afterSrc4 is (b1_0107=0x58 & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ tmp:2 = dst4W_afterSrc4;
+ src:2 = src4W;
+ c:2 = zext($(CARRY));
+ setAdd3Flags(tmp, src, c);
+ tmp = tmp + src + c;
+ dst4W_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+
+### ADCF ###
+
+:ADCF.B dst4B is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xe) ... & dst4B {
+ tmp:1 = dst4B;
+ c:1 = $(CARRY);
+ setAddFlags(tmp, c);
+ tmp = tmp + c;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+:ADCF.B dst4Ax is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xe) & $(DST4AX) {
+ tmp:1 = dst4Ax:1;
+ c:1 = $(CARRY);
+ setAddFlags(tmp, c);
+ tmp = tmp + c;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+:ADCF.W dst4W is (b1_0107=0x3b & b1_size_0=1; b2_0407=0xe) ... & dst4W {
+ tmp:2 = dst4W;
+ c:2 = zext($(CARRY));
+ setAddFlags(tmp, c);
+ tmp = tmp + c;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+### ADD ###
+
+# (1) ADD.B:G #simm, dst
+:ADD^".B:G" srcSimm8, dst4B is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x4) ... & dst4B); srcSimm8 {
+ tmp:1 = dst4B;
+ setAddFlags(tmp, srcSimm8);
+ tmp = tmp + srcSimm8;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ADD.B:G #simm, Ax
+:ADD^".B:G" srcSimm8, dst4Ax is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x4) & $(DST4AX)); srcSimm8 {
+ tmp:1 = dst4Ax:1;
+ setAddFlags(tmp, srcSimm8);
+ tmp = tmp + srcSimm8;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ADD.W:G #simm, dst
+:ADD^".W:G" srcSimm16, dst4W is ((b1_0107=0x3b & b1_size_0=1; b2_0407=0x4) ... & dst4W); srcSimm16 {
+ tmp:2 = dst4W;
+ setAddFlags(tmp, srcSimm16);
+ tmp = tmp + srcSimm16;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ADD.B:Q #simm4, dst
+:ADD^".B:Q" srcSimm4_0407, dst4B is (b1_0107=0x64 & b1_size_0=0; srcSimm4_0407) ... & dst4B {
+ tmp:1 = dst4B;
+ setAddFlags(tmp, srcSimm4_0407);
+ tmp = tmp + srcSimm4_0407;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ADD.B:Q #simm4, Ax
+:ADD^".B:Q" srcSimm4_0407, dst4Ax is (b1_0107=0x64 & b1_size_0=0; srcSimm4_0407) & $(DST4AX) {
+ tmp:1 = dst4Ax:1;
+ setAddFlags(tmp, srcSimm4_0407);
+ tmp = tmp + srcSimm4_0407;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) ADD.W:Q #simm4, dst
+:ADD^".W:Q" srcSimm4_0407, dst4W is (b1_0107=0x64 & b1_size_0=1; srcSimm4_0407) ... & dst4W {
+ tmp:2 = dst4W;
+ imm:2 = sext(srcSimm4_0407);
+ setAddFlags(tmp, imm);
+ tmp = tmp + imm;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) ADD.B:S #imm, dst
+:ADD^".B:S" srcSimm8, dst3B_afterDsp8 is (b1_0307=0x10; srcSimm8) ... & $(DST3B_AFTER_DSP8) {
+ tmp:1 = dst3B_afterDsp8;
+ setAddFlags(tmp, srcSimm8);
+ tmp = tmp + srcSimm8;
+ dst3B_afterDsp8 = tmp;
+ setResultFlags(tmp);
+}
+
+# (4) ADD.B:G src, dst
+:ADD^".B:G" src4B, dst4B_afterSrc4 is (b1_0107=0x50 & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ tmp:1 = dst4B_afterSrc4;
+ src:1 = src4B;
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst4B_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (4) ADD.B:G src, Ax
+:ADD^".B:G" src4B, dst4Ax is (b1_0107=0x50 & b1_size_0=0) ... & src4B & $(DST4AX) ... {
+ tmp:1 = dst4Ax:1;
+ src:1 = src4B;
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (4) ADD.W:G src, dst
+:ADD^".W:G" src4W, dst4W_afterSrc4 is (b1_0107=0x50 & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ tmp:2 = dst4W_afterSrc4;
+ src:2 = src4W;
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst4W_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (5) ADD.B:S src, R0H/R0L
+:ADD^".B:S" dst2B, b1_2_reg8 is (b1_0307=0x4 & b1_2_reg8) ... & dst2B {
+ src:1 = dst2B;
+ setAddFlags(b1_2_reg8, src);
+ b1_2_reg8 = b1_2_reg8 + src;
+ setResultFlags(b1_2_reg8);
+}
+
+# (6) ADD.B:G #simm, SP
+:ADD^".B:G" srcSimm8, SP is SP & b1_0107=0x3e & b1_size_0=0; b2_0007=0xeb; srcSimm8 {
+ imm:2 = sext(srcSimm8);
+ setAddFlags(SP, imm);
+ SP = SP + imm;
+ setResultFlags(SP);
+}
+
+# (6) ADD.W:G #simm, SP
+:ADD^".W:G" srcSimm16, SP is SP & b1_0107=0x3e & b1_size_0=1; b2_0007=0xeb; srcSimm16 {
+ setAddFlags(SP, srcSimm16);
+ SP = SP + srcSimm16;
+ setResultFlags(SP);
+}
+
+# (7) ADD.W:Q #simm, SP
+:ADD^".B:Q" srcSimm4_0003, SP is SP & b1_0007=0x7d; b2_0407=0xb & srcSimm4_0003 {
+ imm:2 = sext(srcSimm4_0003);
+ setAddFlags(SP, imm);
+ SP = SP + imm;
+ setResultFlags(SP);
+}
+
+### ADJNZ ###
+
+:ADJNZ.B srcSimm4_0407, dst4B is ((b1_0107=0x7c & b1_size_0=0; srcSimm4_0407) ... & dst4B); rel8offset2 {
+ tmp:1 = dst4B + srcSimm4_0407;
+ dst4B = tmp;
+ if (tmp != 0) goto rel8offset2;
+}
+
+:ADJNZ.B srcSimm4_0407, dst4Ax is ((b1_0107=0x7c & b1_size_0=0; srcSimm4_0407) & $(DST4AX)); rel8offset2 {
+ tmp:1 = dst4Ax:1 + srcSimm4_0407;
+ dst4Ax = zext(tmp);
+ if (tmp != 0) goto rel8offset2;
+}
+
+:ADJNZ.W srcSimm4_0407, dst4W is ((b1_0107=0x7c & b1_size_0=1; srcSimm4_0407) ... & dst4W); rel8offset2 {
+ tmp:2 = dst4W + sext(srcSimm4_0407);
+ dst4W = tmp;
+ if (tmp != 0) goto rel8offset2;
+}
+
+### AND ###
+
+# (1) AND.B:G #imm, dst
+:AND^".B:G" srcImm8, dst4B is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x2) ... & dst4B); srcImm8 {
+ tmp:1 = dst4B & srcImm8;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) AND.B:G #imm, Ax
+:AND^".B:G" srcImm8, dst4Ax is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x2) & $(DST4AX)); srcImm8 {
+ tmp:1 = dst4Ax:1 & srcImm8;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) AND.W:G #imm, dst
+:AND^".W:G" srcImm16, dst4W is ((b1_0107=0x3b & b1_size_0=1; b2_0407=0x2) ... & dst4W); srcImm16 {
+ tmp:2 = dst4W & srcImm16;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) AND.B:S #imm, dst
+:AND^".B:S" srcImm8, dst3B_afterDsp8 is (b1_0307=0x12; srcImm8) ... & $(DST3B_AFTER_DSP8) {
+ tmp:1 = dst3B_afterDsp8 & srcImm8;
+ dst3B_afterDsp8 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) AND.B:G src, dst
+:AND^".B:G" src4B, dst4B_afterSrc4 is (b1_0107=0x48 & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ tmp:1 = dst4B_afterSrc4 & src4B;
+ dst4B_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) AND.B:G src, Ax
+:AND^".B:G" src4B, dst4Ax is (b1_0107=0x48 & b1_size_0=0) ... & src4B & $(DST4AX) ... {
+ tmp:1 = dst4Ax:1 & src4B;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (3) AND.W:G src, dst
+:AND^".W:G" src4W, dst4W_afterSrc4 is (b1_0107=0x48 & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ tmp:2 = dst4W_afterSrc4 & src4W;
+ dst4W_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (4) AND.B:S src, R0L/R0H
+:AND^".B:S" dst2B, b1_2_reg8 is (b1_0307=0x2 & b1_2_reg8) ... & dst2B {
+ tmp:1 = dst2B & b1_2_reg8;
+ b1_2_reg8 = tmp;
+ setResultFlags(tmp);
+}
+
+### BAND ###
+
+# BAND bit,Rx/Ax
+:BAND regBit, regBase is (b1_0007=0x7e; b2_0407=0x4 & b2_d4_3=0) ... & regBase ... & regBit {
+ bitValue:2 = (regBase >> regBit) & 1;
+ $(CARRY) = $(CARRY) & bitValue:1;
+}
+
+# BAND [Ax]
+:BAND memBaseAx is (b1_0007=0x7e; b2_0407=0x4 & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ bitValue:1 = (val >> bit) & 1;
+ $(CARRY) = $(CARRY) & bitValue;
+}
+
+# BAND bit,base
+:BAND memBit, memBase is (b1_0007=0x7e; b2_0407=0x4) ... & memBase & memBit {
+ bitValue:1 = (memBase >> memBit) & 1;
+ $(CARRY) = $(CARRY) & bitValue;
+}
+
+
+### BCLR ###
+
+# (1) BCLR:G bit,Rx/Ax
+:BCLR^":G" regBit, regBase is (b1_0007=0x7e; b2_0407=0x8 & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = ~(1 << regBit);
+ regBase = regBase & mask;
+}
+
+# (1) BCLR:G [Ax]
+:BCLR^":G" memBaseAx is (b1_0007=0x7e; b2_0407=0x8 & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = ~(1 << bit);
+ *:1 ptr = val & mask;
+}
+
+# (1) BCLR:G bit,base
+:BCLR^":G" memBit, memBase is (b1_0007=0x7e; b2_0407=0x8) ... & memBase & memBit {
+ mask:1 = ~(1 << memBit);
+ memBase = memBase & mask;
+}
+
+# (2) BCLR:S bit,base:11[SB]
+:BCLR^":S" b1_bit, memBase11 is (b1_0307=0x08 & b1_bit) ... & memBase11 {
+ mask:1 = ~(1 << b1_bit);
+ memBase11 = memBase11 & mask;
+}
+
+### BMcnd ###
+
+# (1) BMcnd bit,Rx/Ax
+:BM^cnd8 regBit, regBase is ((b1_0007=0x7e; b2_0407=0x2 & b2_d4_3=0) ... & regBase ... & regBit); cnd8 {
+ mask:2 = ~(1 << regBit);
+ regBase = ((zext(cnd8) << regBit) | (regBase & mask));
+}
+
+# (1) BMcnd [Ax]
+:BM^cnd8 memBaseAx is ((b1_0007=0x7e; b2_0407=0x2 & b2_d4_13=0x3) & memBaseAx); cnd8 {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = ~(1 << bit);
+ *:1 ptr = ((cnd8 << bit) | (val & mask));
+}
+
+# (1) BMcnd bit,base
+:BM^cnd8 memBit, memBase is ((b1_0007=0x7e; b2_0407=0x2) ... & memBase & memBit); cnd8 {
+ mask:1 = ~(1 << memBit);
+ memBase = ((cnd8 << memBit) | (memBase & mask));
+}
+
+# (2) BMcnd C
+:BM^b2cnd4 "C" is b1_0007=0x7d; b2_0407=0xd & b2cnd4 {
+ $(CARRY) = b2cnd4;
+}
+
+### BNAND ###
+
+# BNAND bit,Rx/Ax
+:BNAND regBit, regBase is (b1_0007=0x7e; b2_0407=0x5 & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (regBase & mask);
+ $(CARRY) = $(CARRY) && (bitValue == 0);
+}
+
+# BNAND [Ax]
+:BNAND memBaseAx is (b1_0007=0x7e; b2_0407=0x5 & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (val & mask);
+ $(CARRY) = $(CARRY) && (bitValue == 0);
+}
+
+# BNAND bit,base
+:BNAND memBit, memBase is (b1_0007=0x7e; b2_0407=0x5) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ bitValue:1 = (memBase & mask);
+ $(CARRY) = $(CARRY) && (bitValue == 0);
+}
+
+### BNOR ###
+
+# BNOR bit,Rx/Ax
+:BNOR regBit, regBase is (b1_0007=0x7e; b2_0407=0x7 & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (regBase & mask);
+ $(CARRY) = $(CARRY) || (bitValue == 0);
+}
+
+# BNOR [Ax]
+:BNOR memBaseAx is (b1_0007=0x7e; b2_0407=0x7 & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (val & mask);
+ $(CARRY) = $(CARRY) || (bitValue == 0);
+}
+
+# BNOR bit,base
+:BNOR memBit, memBase is (b1_0007=0x7e; b2_0407=0x7) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ bitValue:1 = (memBase & mask);
+ $(CARRY) = $(CARRY) || (bitValue == 0);
+}
+
+### BNOT ###
+
+# (1) BNOT:G bit,Rx/Ax
+:BNOT^":G" regBit, regBase is (b1_0007=0x7e; b2_0407=0xa & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (~regBase & mask);
+ regBase = (regBase & ~mask) | bitValue;
+}
+
+# (1) BNOT:G [Ax]
+:BNOT^":G" memBaseAx is (b1_0007=0x7e; b2_0407=0xa & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (~val & mask);
+ *:1 ptr = (val & ~mask) | bitValue;
+}
+
+# (1) BNOT:G bit,base
+:BNOT^":G" memBit, memBase is (b1_0007=0x7e; b2_0407=0xa) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ val:1 = memBase;
+ bitValue:1 = (~val & mask);
+ memBase = (val & ~mask) | bitValue;
+}
+
+# (2) BNOT:S bit,base:11[SB]
+:BNOT^":S" b1_bit, memBase11 is (b1_0307=0x0a & b1_bit) ... & memBase11 {
+ mask:1 = (1 << b1_bit);
+ val:1 = memBase11;
+ bitValue:1 = (~val & mask);
+ memBase11 = (val & ~mask) | bitValue;
+}
+
+### BNTST ###
+
+# BNTST bit,Rx/Ax
+:BNTST regBit, regBase is (b1_0007=0x7e; b2_0407=0x3 & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (regBase & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = z;
+ $(ZERO) = z;
+}
+
+# BNTST [Ax]
+:BNTST memBaseAx is (b1_0007=0x7e; b2_0407=0x3 & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (val & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = z;
+ $(ZERO) = z;
+}
+
+# BNTST bit,base
+:BNTST memBit, memBase is (b1_0007=0x7e; b2_0407=0x3) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ bitValue:1 = (memBase & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = z;
+ $(ZERO) = z;
+}
+
+### BNXOR ###
+
+# BNXOR bit,Rx/Ax
+:BNXOR regBit, regBase is (b1_0007=0x7e; b2_0407=0xd & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (regBase & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue == 0);
+}
+
+# BNXOR [Ax]
+:BNXOR memBaseAx is (b1_0007=0x7e; b2_0407=0xd & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (val & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue == 0);
+}
+
+# BNXOR bit,base
+:BNXOR memBit, memBase is (b1_0007=0x7e; b2_0407=0xd) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ bitValue:1 = (memBase & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue == 0);
+}
+
+### BOR ###
+
+# BOR bit,Rx/Ax
+:BOR regBit, regBase is (b1_0007=0x7e; b2_0407=0x6 & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (regBase & mask);
+ $(CARRY) = $(CARRY) || (bitValue != 0);
+}
+
+# BOR [Ax]
+:BOR memBaseAx is (b1_0007=0x7e; b2_0407=0x6 & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (val & mask);
+ $(CARRY) = $(CARRY) || (bitValue != 0);
+}
+
+# BOR bit,base
+:BOR memBit, memBase is (b1_0007=0x7e; b2_0407=0x6) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ bitValue:1 = (memBase & mask);
+ $(CARRY) = $(CARRY) || (bitValue != 0);
+}
+
+### BRK ###
+
+:BRK is b1_0007=0x0 {
+ # most likely not necessary to model break behavior
+ Break();
+}
+
+### BSET ###
+
+# (1) BSET:G bit,Rx/Ax
+:BSET^":G" regBit, regBase is (b1_0007=0x7e; b2_0407=0x9 & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ regBase = regBase | mask;
+}
+
+# (1) BSET:G [Ax]
+:BSET^":G" memBaseAx is (b1_0007=0x7e; b2_0407=0x9 & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ *:1 ptr = val | mask;
+}
+
+# (1) BSET:G bit,base
+:BSET^":G" memBit, memBase is (b1_0007=0x7e; b2_0407=0x9) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ memBase = memBase | mask;
+}
+
+# (2) BSET:S bit,base:11[SB]
+:BSET^":S" b1_bit, memBase11 is (b1_0307=0x09 & b1_bit) ... & memBase11 {
+ mask:1 = (1 << b1_bit);
+ memBase11 = memBase11 | mask;
+}
+
+### BTST ###
+
+# (1) BTST:G bit,Rx/Ax
+:BTST^":G" regBit, regBase is (b1_0007=0x7e; b2_0407=0xb & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (regBase & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+}
+
+# (1) BTST:G [Ax]
+:BTST^":G" memBaseAx is (b1_0007=0x7e; b2_0407=0xb & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (val & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+}
+
+# (1) BTST:G bit,base
+:BTST^":G" memBit, memBase is (b1_0007=0x7e; b2_0407=0xb) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ bitValue:1 = (memBase & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+}
+
+# (2) BTST:S bit,base:11[SB]
+:BTST^":S" b1_bit, memBase11 is (b1_0307=0x0b & b1_bit) ... & memBase11 {
+ mask:1 = (1 << b1_bit);
+ bitValue:1 = (memBase11 & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+}
+
+### BTSTC ###
+
+# BTSTC bit,Rx/Ax
+:BTSTC regBit, regBase is (b1_0007=0x7e; b2_0407=0x0 & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (regBase & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ regBase = regBase & ~mask;
+}
+
+# BTSTC [Ax]
+:BTSTC memBaseAx is (b1_0007=0x7e; b2_0407=0x0 & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (val & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ *:1 ptr = val & ~mask;
+}
+
+# BTSTC bit,base
+:BTSTC memBit, memBase is (b1_0007=0x7e; b2_0407=0x0) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ val:1 = memBase;
+ bitValue:1 = (val & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ memBase = val & ~mask;
+}
+
+### BTSTS ###
+
+# BTSTS bit,Rx/Ax
+:BTSTS regBit, regBase is (b1_0007=0x7e; b2_0407=0x1 & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (regBase & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ regBase = regBase | mask;
+}
+
+# BTSTS [Ax]
+:BTSTS memBaseAx is (b1_0007=0x7e; b2_0407=0x1 & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (val & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ *:1 ptr = val | mask;
+}
+
+# BTSTS bit,base
+:BTSTS memBit, memBase is (b1_0007=0x7e; b2_0407=0x1) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ val:1 = memBase;
+ bitValue:1 = (val & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ memBase = val | mask;
+}
+
+### BXOR ###
+
+# BXOR bit,Rx/Ax
+:BXOR regBit, regBase is (b1_0007=0x7e; b2_0407=0xc & b2_d4_3=0) ... & regBase ... & regBit {
+ mask:2 = (1 << regBit);
+ bitValue:2 = (regBase & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue != 0);
+}
+
+# BXOR [Ax]
+:BXOR memBaseAx is (b1_0007=0x7e; b2_0407=0xc & b2_d4_13=0x3) & memBaseAx {
+ ptr:3 = zext(memBaseAx >> 3);
+ bit:1 = memBaseAx:1 & 0x7;
+ val:1 = *:1 ptr;
+ mask:1 = (1 << bit);
+ bitValue:1 = (val & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue != 0);
+}
+
+# BXOR bit,base
+:BXOR memBit, memBase is (b1_0007=0x7e; b2_0407=0xc) ... & memBase & memBit {
+ mask:1 = (1 << memBit);
+ bitValue:1 = (memBase & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue != 0);
+}
+
+### CMP ###
+
+# (1) CMP.B:G #simm, dst
+:CMP^".B:G" srcSimm8, dst4B is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x8) ... & dst4B); srcSimm8 {
+ tmp:1 = dst4B;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ setResultFlags(tmp);
+}
+
+# (1) CMP.B:G #simm, Ax
+:CMP^".B:G" srcSimm8, dst4Ax is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x8) & $(DST4AX)); srcSimm8 {
+ tmp:1 = dst4Ax:1;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ setResultFlags(tmp);
+}
+
+# (1) CMP.W:G #simm, dst
+:CMP^".W:G" srcSimm16, dst4W is ((b1_0107=0x3b & b1_size_0=1; b2_0407=0x8) ... & dst4W); srcSimm16 {
+ tmp:2 = dst4W;
+ setSubtractFlags(tmp, srcSimm16);
+ tmp = tmp - srcSimm16;
+ setResultFlags(tmp);
+}
+
+# (2) CMP.B:Q #simm4, dst
+:CMP^".B:Q" srcSimm4_0407, dst4B is (b1_0107=0x68 & b1_size_0=0; srcSimm4_0407) ... & dst4B {
+ tmp:1 = dst4B;
+ setSubtractFlags(tmp, srcSimm4_0407);
+ tmp = tmp - srcSimm4_0407;
+ setResultFlags(tmp);
+}
+
+# (2) CMP.B:Q #simm4, Ax
+:CMP^".B:Q" srcSimm4_0407, dst4Ax is (b1_0107=0x68 & b1_size_0=0; srcSimm4_0407) & $(DST4AX) {
+ tmp:1 = dst4Ax:1;
+ setSubtractFlags(tmp, srcSimm4_0407);
+ tmp = tmp - srcSimm4_0407;
+ setResultFlags(tmp);
+}
+
+# (2) CMP.W:Q #simm4, dst
+:CMP^".W:Q" srcSimm4_0407, dst4W is (b1_0107=0x68 & b1_size_0=1; srcSimm4_0407) ... & dst4W {
+ tmp:2 = dst4W;
+ imm:2 = sext(srcSimm4_0407);
+ setSubtractFlags(tmp, imm);
+ tmp = tmp - imm;
+ setResultFlags(tmp);
+}
+
+# (3) CMP.B:S #imm, dst
+:CMP^".B:S" srcSimm8, dst3B_afterDsp8 is (b1_0307=0x1c; srcSimm8) ... & $(DST3B_AFTER_DSP8) {
+ tmp:1 = dst3B_afterDsp8;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ setResultFlags(tmp);
+}
+
+# (4) CMP.B:G src, dst
+:CMP^".B:G" src4B, dst4B_afterSrc4 is (b1_0107=0x60 & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ tmp:1 = dst4B_afterSrc4;
+ src:1 = src4B;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ setResultFlags(tmp);
+}
+
+# (4) CMP.B:G src, Ax
+:CMP^".B:G" src4B, dst4Ax is (b1_0107=0x60 & b1_size_0=0) ... & src4B & $(DST4AX) ... {
+ tmp:1 = dst4Ax:1;
+ src:1 = src4B;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ setResultFlags(tmp);
+}
+
+# (4) CMP.W:G src, dst
+:CMP^".W:G" src4W, dst4W_afterSrc4 is (b1_0107=0x60 & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ tmp:2 = dst4W_afterSrc4;
+ src:2 = src4W;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ setResultFlags(tmp);
+}
+
+# (5) CMP.B:S src, R0H/R0L
+:CMP^".B:S" dst2B, b1_2_reg8 is (b1_0307=0x7 & b1_2_reg8) ... & dst2B {
+ src:1 = dst2B;
+ setSubtractFlags(b1_2_reg8, src);
+ b1_2_reg8 = b1_2_reg8 - src;
+ setResultFlags(b1_2_reg8);
+}
+
+### DADC ###
+
+# (1) DADC.B #imm, R0L
+:DADC.B srcImm8, R0L is R0L & b1_0007=0x7c; b2_0007=0xee; srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(R0L);
+ tmp:2 = DecimalAddWithCarry(src, dst);
+ R0L = tmp:1;
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (2) DADC.W #imm, R0
+:DADC.W srcImm16, R0 is R0 & b1_0007=0x7d; b2_0007=0xee; srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(R0);
+ tmp:4 = DecimalAddWithCarry(src, dst);
+ R0 = tmp:2;
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+# (3) DADC.B R0H, R0L
+:DADC.B R0H, R0L is R0H & R0L & b1_0007=0x7c; b2_0007=0xe6 {
+ src:2 = zext(R0H);
+ dst:2 = zext(R0L);
+ tmp:2 = DecimalAddWithCarry(src, dst);
+ R0L = tmp:1;
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (4) DADC.W R1, R0
+:DADC.W R1, R0 is R1 & R0 & b1_0007=0x7d; b2_0007=0xe6 {
+ src:4 = zext(R1);
+ dst:4 = zext(R0);
+ tmp:4 = DecimalAddWithCarry(src, dst);
+ R0 = tmp:2;
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+### DADD ###
+
+# (1) DADD.B #imm, R0L
+:DADD.B srcImm8, R0L is R0L & b1_0007=0x7c; b2_0007=0xec; srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(R0L);
+ tmp:2 = DecimalAdd(src, dst);
+ R0L = tmp:1;
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (2) DADD.W #imm, R0
+:DADD.W srcImm16, R0 is R0 & b1_0007=0x7d; b2_0007=0xec; srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(R0);
+ tmp:4 = DecimalAdd(src, dst);
+ R0 = tmp:2;
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+# (3) DADD.B R0H, R0L
+:DADD.B R0H, R0L is R0H & R0L & b1_0007=0x7c; b2_0007=0xe4 {
+ src:2 = zext(R0H);
+ dst:2 = zext(R0L);
+ tmp:2 = DecimalAdd(src, dst);
+ R0L = tmp:1;
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (4) DADD.W R1, R0
+:DADD.W R1, R0 is R1 & R0 & b1_0007=0x7d; b2_0007=0xe4 {
+ src:4 = zext(R1);
+ dst:4 = zext(R0);
+ tmp:4 = DecimalAdd(src, dst);
+ R0 = tmp:2;
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+### DEC ###
+
+# (1) DEC.B dst
+:DEC.B dst3B is b1_0307=0x15 ... & $(DST3B) {
+ dst:1 = dst3B;
+ setSubtractFlags(dst, 1);
+ dst = dst - 1;
+ dst3B = dst;
+ setResultFlags(dst);
+}
+
+# (2) DEC.W dst
+:DEC.W b1_3_regAx is b1_0407=0xf & b1_0002=0x2 & b1_3_regAx {
+ dst:2 = b1_3_regAx;
+ setSubtractFlags(dst, 1);
+ dst = dst - 1;
+ b1_3_regAx = dst;
+ setResultFlags(dst);
+}
+
+### DIV ###
+
+# (1) DIV.B #imm
+:DIV.B srcSimm8 is b1_0107=0x3e & b1_size_0=0; b2_0007=0xe1; srcSimm8 {
+ d:2 = sext(srcSimm8);
+ q:2 = R0 s/ d;
+ r:2 = R0 s% d; # remainder has same sign as R0 (dividend)
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (1) DIV.W #imm
+:DIV.W srcSimm16 is b1_0107=0x3e & b1_size_0=1; b2_0007=0xe1; srcSimm16 {
+ d:4 = sext(srcSimm16);
+ q:4 = R2R0 s/ d;
+ r:4 = R2R0 s% d; # remainder has same sign as R0 (dividend)
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIV.B src
+:DIV.B dst4B is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xd) ... & dst4B {
+ d:2 = sext(dst4B);
+ q:2 = R0 s/ d;
+ r:2 = R0 s% d; # remainder has same sign as R0 (dividend)
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIV.W src
+:DIV.W dst4W is (b1_0107=0x3b & b1_size_0=1; b2_0407=0xd) ... & dst4W {
+ d:4 = sext(dst4W);
+ q:4 = R2R0 s/ d;
+ r:4 = R2R0 s% d; # remainder has same sign as R0 (dividend)
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+### DIVU ###
+
+# (1) DIVU.B #imm
+:DIVU.B srcImm8 is b1_0107=0x3e & b1_size_0=0; b2_0007=0xe0; srcImm8 {
+ d:2 = zext(srcImm8);
+ q:2 = R0 / d;
+ r:2 = R0 % d;
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (1) DIVU.W #imm
+:DIVU.W srcImm16 is b1_0107=0x3e & b1_size_0=1; b2_0007=0xe0; srcImm16 {
+ d:4 = zext(srcImm16);
+ q:4 = R2R0 / d;
+ r:4 = R2R0 % d;
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIVU.B src
+:DIVU.B dst4B is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xc) ... & dst4B {
+ d:2 = zext(dst4B);
+ q:2 = R0 / d;
+ r:2 = R0 % d;
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIVU.W src
+:DIVU.W dst4W is (b1_0107=0x3b & b1_size_0=1; b2_0407=0xc) ... & dst4W {
+ d:4 = zext(dst4W);
+ q:4 = R2R0 / d;
+ r:4 = R2R0 % d;
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+### DIVX ###
+
+# (1) DIVX.B #imm
+:DIVX.B srcSimm8 is b1_0107=0x3e & b1_size_0=0; b2_0007=0xe3; srcSimm8 {
+ d:2 = sext(srcSimm8);
+ q:2 = R0 s/ d;
+ r:2 = R0 s% d;
+
+ #according to the manual the remainder has the same sign as the quotient
+ differ:1 = (r s< 0) != (d s< 0);
+ r = (zext(differ) * (-r)) + (zext(!differ) * r);
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (1) DIVX.W #imm
+:DIVX.W srcSimm16 is b1_0107=0x3e & b1_size_0=1; b2_0007=0xe3; srcSimm16 {
+ d:4 = sext(srcSimm16);
+ q:4 = R2R0 s/ d;
+ r:4 = R2R0 s% d;
+
+ #according to the manual the remainder has the same sign as the quotient
+ differ:1 = (r s< 0) != (d s< 0);
+ r = (zext(differ) * (-r)) + (zext(!differ) * r);
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIVX.B src
+:DIVX.B dst4B is (b1_0107=0x3b & b1_size_0=0; b2_0407=0x9) ... & dst4B {
+ d:2 = sext(dst4B);
+ q:2 = R0 s/ d;
+ r:2 = R0 s% d;
+
+ #according to the manual the remainder has the same sign as the quotient
+ differ:1 = (r s< 0) != (d s< 0);
+ r = (zext(differ) * (-r)) + (zext(!differ) * r);
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIVX.W src
+:DIVX.W dst4W is (b1_0107=0x3b & b1_size_0=1; b2_0407=0x9) ... & dst4W {
+ d:4 = sext(dst4W);
+ q:4 = R2R0 s/ d;
+ r:4 = R2R0 s% d;
+
+ #according to the manual the remainder has the same sign as the quotient
+ differ:1 = (r s< 0) != (d s< 0);
+ r = (zext(differ) * (-r)) + (zext(!differ) * r);
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+### DSBB ###
+
+# (1) DSBB.B #imm8, R0L
+:DSBB.B srcImm8, R0L is R0L & b1_0007=0x7c; b2_0007=0xef; srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(R0L);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:2 = DecimalSubtractWithBorrow(dst, src);
+ R0L = tmp:1;
+ setResultFlags(tmp:1);
+}
+
+# (2) DSBB.W #imm16, R0
+:DSBB.W srcImm16, R0 is R0 & b1_0007=0x7d; b2_0007=0xef; srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(R0);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:4 = DecimalSubtractWithBorrow(dst, src);
+ R0 = tmp:2;
+ setResultFlags(tmp:2);
+}
+
+# (3) DSBB.B R0H, R0L
+:DSBB.B R0H, R0L is R0H & R0L & b1_0007=0x7c; b2_0007=0xe7 {
+ src:2 = zext(R0H);
+ dst:2 = zext(R0L);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:2 = DecimalSubtractWithBorrow(dst, src);
+ R0L = tmp:1;
+ setResultFlags(tmp:1);
+}
+
+# (4) DSBB.W R1, R0
+:DSBB.W R1, R0 is R0 & R1 & b1_0007=0x7d; b2_0007=0xe7 {
+ src:4 = zext(R1);
+ dst:4 = zext(R0);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:4 = DecimalSubtractWithBorrow(dst, src);
+ R0 = tmp:2;
+ setResultFlags(tmp:2);
+}
+
+### DSUB ###
+
+# (1) DSUB.B #imm8, R0L
+:DSUB.B srcImm8, R0L is R0L & b1_0007=0x7c; b2_0007=0xed; srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(R0L);
+ $(CARRY) = (dst >= src);
+ tmp:2 = DecimalSubtract(dst, src);
+ R0L = tmp:1;
+ setResultFlags(tmp:1);
+}
+
+# (2) DSUB.W #imm16, R0
+:DSUB.W srcImm16, R0 is R0 & b1_0007=0x7d; b2_0007=0xed; srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(R0);
+ $(CARRY) = (dst >= src);
+ tmp:4 = DecimalSubtract(dst, src);
+ R0 = tmp:2;
+ setResultFlags(tmp:2);
+}
+
+# (3) DSUB.B R0H, R0L
+:DSUB.B R0H, R0L is R0H & R0L & b1_0007=0x7c; b2_0007=0xe5 {
+ src:2 = zext(R0H);
+ dst:2 = zext(R0L);
+ $(CARRY) = (dst >= src);
+ tmp:2 = DecimalSubtract(dst, src);
+ R0L = tmp:1;
+ setResultFlags(tmp:1);
+}
+
+# (4) DSUB.W R1, R0
+:DSUB.W R1, R0 is R0 & R1 & b1_0007=0x7d; b2_0007=0xe5 {
+ src:4 = zext(R1);
+ dst:4 = zext(R0);
+ $(CARRY) = (dst >= src);
+ tmp:4 = DecimalSubtract(dst, src);
+ R0 = tmp:2;
+ setResultFlags(tmp:2);
+}
+
+### ENTER ###
+
+:ENTER srcImm8 is b1_0007=0x7c; b2_0007=0xf2; srcImm8 {
+ push2(FB);
+ FB = SP;
+ SP = SP - zext(srcImm8);
+}
+
+### EXITD ###
+
+:EXITD is b1_0007=0x7d; b2_0007=0xf2 {
+ SP = FB;
+ pop2(FB);
+ pc:3 = 0;
+ pop3(pc);
+ return [pc];
+}
+
+### EXTS ###
+
+# (1) EXTS.B dst
+:EXTS.B dst4B is (b1_0007=0x7c; b2_0407=0x6) ... & dst4B & dst4W {
+ tmp:2 = sext(dst4B);
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) EXTS.B Ax
+:EXTS.B dst4Ax is (b1_0007=0x7c; b2_0407=0x6) & $(DST4AX) {
+ tmp:2 = sext(dst4Ax:1);
+ dst4Ax = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) EXTS.W R0
+:EXTS.W R0 is R0 & b1_0007=0x7c; b2_0007=0xf3 {
+ tmp:4 = sext(R0);
+ R2R0 = tmp;
+ setResultFlags(tmp);
+}
+
+### FCLR ###
+
+:FCLR flagBit is b1_0007=0xeb; b2_0707=0 & flagBit & b2_0003=0x5 {
+ mask:2 = ~(1 << flagBit);
+ FLG = FLG & mask;
+}
+
+### FSET ###
+
+:FSET flagBit is b1_0007=0xeb; b2_0707=0 & flagBit & b2_0003=0x4 {
+ mask:2 = (1 << flagBit);
+ FLG = FLG | mask;
+}
+
+### INC ###
+
+# (1) INC.B dst
+:INC.B dst3B is b1_0307=0x14 ... & $(DST3B) {
+ tmp:1 = dst3B + 1;
+ dst3B = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) INC.W dst
+:INC.W b1_3_regAx is b1_0407=0xb & b1_0002=0x2 & b1_3_regAx {
+ tmp:2 = b1_3_regAx + 1;
+ b1_3_regAx = tmp;
+ setResultFlags(tmp);
+}
+
+### INT ###
+
+:INT srcIntNum is b1_0007=0xeb; imm8_0607=3 & srcIntNum {
+ push1(FLG:1);
+ next:3 = inst_next;
+ push3(next);
+ ptr3:3 = (INTB + (zext(srcIntNum) * 0x4));
+ pc:3 = *:3 ptr3;
+ $(STACK_SEL) = ((srcIntNum > 0x1f) * $(STACK_SEL));
+ $(INTERRUPT) = 0x0;
+ $(DEBUG) = 0x0;
+ call [pc];
+}
+
+##### INTO #####
+
+:INTO is b1_0007=0xf6 {
+ if ($(OVERFLOW) == 0) goto inst_next;
+ push1(FLG:1);
+ next:3 = inst_next;
+ push3(next);
+ $(STACK_SEL) = 0;
+ $(INTERRUPT) = 0x0;
+ $(DEBUG) = 0x0;
+ call 0x0fffe0;
+}
+
+### JCnd ###
+
+# (1) JCnd3 dsp8
+:J^b1cnd3 rel8offset1 is b1_0307=0x0d & b1cnd3; rel8offset1 {
+ if (b1cnd3) goto rel8offset1;
+}
+
+# (2) JCnd4 dsp8
+:J^b2cnd3 rel8offset2 is b1_0007=0x7d; b2_0407=0xc & b2_0303=1 & b2cnd3; rel8offset2 {
+ if (b2cnd3) goto rel8offset2;
+}
+
+### JMP ###
+
+# (1) JMP.S dsp3
+:JMP.S rel3offset2 is b1_0307=0x0c & rel3offset2 {
+ goto rel3offset2;
+}
+
+# (2) JMP.B dsp8
+:JMP.B rel8offset1 is b1_0007=0xfe; rel8offset1 {
+ goto rel8offset1;
+}
+
+# (3) JMP.W dsp16
+:JMP.W rel16offset1 is b1_0007=0xf4; rel16offset1 {
+ goto rel16offset1;
+}
+
+# (4) JMP.A abs20
+:JMP.A abs20offset is b1_0007=0xfc; abs20offset {
+ goto abs20offset;
+}
+
+### JMPI ###
+
+# JMPI.W dst
+:JMPI.W reloffset_dst4W is (b1_0007=0x7d; b2_0407=0x2) ... & reloffset_dst4W {
+ goto reloffset_dst4W;
+}
+
+# JMPI.A dst (dst=register)
+:JMPI.A reloffset_dst4L is (b1_0007=0x7d; b2_0407=0x0) ... & reloffset_dst4L {
+ goto reloffset_dst4L;
+}
+
+# JMPI.A dst (dst=memory)
+:JMPI.A reloffset_dst4T is (b1_0007=0x7d; b2_0407=0x0) ... & reloffset_dst4T {
+ goto reloffset_dst4T;
+}
+
+### JMPS ###
+
+:JMPS srcImm8 is b1_0007=0xee; srcImm8 {
+ # 18 <= srcImm8 <= 255 (range restriction not enforced by pattern match)
+ ptr:3 = 0x0ffffe - (zext(srcImm8) << 1);
+ pc:3 = 0x0f0000 | zext(*:2 ptr);
+ goto [pc];
+}
+
+### JSR ###
+
+:JSR.W rel16offset1 is b1_0007=0xf5; rel16offset1 {
+ next:3 = inst_next;
+ push3(next);
+ call rel16offset1;
+}
+
+:JSR.A abs20offset is b1_0007=0xfd; abs20offset {
+ next:3 = inst_next;
+ push3(next);
+ call abs20offset;
+}
+
+### JSRI ###
+
+# JSRI.W dst
+:JSRI.W reloffset_dst4W is (b1_0007=0x7d; b2_0407=0x3) ... & reloffset_dst4W {
+ next:3 = inst_next;
+ push3(next);
+ call reloffset_dst4W;
+}
+
+# JSRI.A dst (dst=register)
+:JSRI.A dst4L is (b1_0007=0x7d; b2_0407=0x1) ... & dst4L {
+ next:3 = inst_next;
+ push3(next);
+ pc:3 = dst4L:3;
+ call [pc];
+}
+
+# JSRI.A dst (dst=memory)
+:JSRI.A dst4T is (b1_0007=0x7d; b2_0407=0x1) ... & $(DST4T) {
+ next:3 = inst_next;
+ push3(next);
+ pc:3 = dst4T;
+ call [pc];
+}
+
+### JSRS ###
+
+:JSRS srcImm8 is b1_0007=0xef; srcImm8 {
+ # 18 <= srcImm8 <= 255 (range restriction not enforced by pattern match)
+ next:3 = inst_next;
+ push3(next);
+ ptr:3 = 0x0ffffe - (zext(srcImm8) << 1);
+ pc:3 = 0x0f0000 | zext(*:2 ptr);
+ call [pc];
+}
+
+### LDC ###
+
+:LDC srcImm16, b2_creg16 is b1_0007=0xeb; b2_0707=0 & b2_creg16 & b2_0003=0x0; srcImm16 {
+ b2_creg16 = srcImm16;
+}
+
+:LDC dst4W, b2_creg16 is (b1_0007=0x7a; b2_0707=1 & b2_creg16) ... & dst4W {
+ b2_creg16 = dst4W;
+}
+
+### LDCTX ###
+
+:LDCTX abs16offset, abs20offset is b1_0007=0x7c; b2_0007=0xf0; abs16offset; imm20_dat & abs20offset {
+
+ taskNum:1 = abs16offset; # load task number stored at abs16
+ ptr:3 = imm20_dat + (zext(taskNum) * 2); # compute table entry address relative to abs20
+ regInfo:1 = *:1 ptr;
+ ptr = ptr + 1;
+ spCorrect:1 = *:1 ptr;
+
+ ptr = zext(SP);
+
+ if ((regInfo & 1) == 0) goto ;
+ R0 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ R1 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ R2 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ R3 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ A0 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ A1 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ SB = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ FB = *:2 ptr;
+ ptr = ptr + 2;
+
+ SP = SP + zext(spCorrect);
+}
+
+### LDE ###
+
+# (1) LDE.B abs20, dst
+:LDE.B abs20offset, dst4B is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0x8) ... & dst4B); abs20offset {
+ tmp:1 = abs20offset;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) LDE.B abs20, Ax
+:LDE.B abs20offset, dst4Ax is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0x8) & $(DST4AX)); abs20offset {
+ tmp:1 = abs20offset;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) LDE.W abs20, dst
+:LDE.W abs20offsetW, dst4W is ((b1_0107=0x3a & b1_size_0=1; b2_0407=0x8) ... & dst4W); abs20offsetW {
+ tmp:2 = abs20offsetW;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) LDE.B dsp20, dst
+:LDE.B dsp20A0B, dst4B is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0x9) ... & dst4B); dsp20A0B {
+ tmp:1 = dsp20A0B;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) LDE.B dsp20, Ax
+:LDE.B dsp20A0B, dst4Ax is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0x9) & $(DST4AX)); dsp20A0B {
+ tmp:1 = dsp20A0B;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) LDE.W dsp20, dst
+:LDE.W dsp20A0W, dst4W is ((b1_0107=0x3a & b1_size_0=1; b2_0407=0x9) ... & dst4W); dsp20A0W {
+ tmp:2 = dsp20A0W;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) LDE.B [A1A0], dst
+:LDE.B [A1A0], dst4B is (A1A0 & b1_0107=0x3a & b1_size_0=0; b2_0407=0xa) ... & dst4B {
+ ptr:3 = A1A0:3;
+ tmp:1 = *:1 ptr;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) LDE.B [A1A0], Ax
+:LDE.B [A1A0], dst4Ax is (A1A0 & b1_0107=0x3a & b1_size_0=0; b2_0407=0xa) & $(DST4AX) {
+ ptr:3 = A1A0:3;
+ tmp:1 = *:1 ptr;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (3) LDE.W [A1A0], dst
+:LDE.W [A1A0], dst4W is (A1A0 & b1_0107=0x3a & b1_size_0=1; b2_0407=0xa) ... & dst4W {
+ ptr:3 = A1A0:3;
+ tmp:2 = *:2 ptr;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+### LDINTB ###
+# LDINTB operand value
+ldIntbVal: "#"^val is b1_0007; b2_0007; b3_0003; b4_0007; b5_0007; b6_0007; imm16_dat [ val = (b3_0003 << 16) + imm16_dat; ] {
+ export *[const]:3 val;
+}
+
+# NOTE: Although this is documented as a macro for two LDE instructions, the encoding is different ??
+:LDINTB ldIntbVal is (b1_0007=0xeb; b2_0007=0x20; b3_0407=0x0; b4_0007=0x0; b5_0007=0xeb; b6_0007=0x10) ... & ldIntbVal {
+ INTB = ldIntbVal;
+}
+
+### LDIPL ###
+
+:LDIPL srcImm3 is b1_0007=0x7d; b2_0307=0x14 & srcImm3 {
+ $(IPL) = srcImm3;
+}
+
+### MOV ###
+
+# (1) MOV.B:G #imm, dst
+:MOV^".B:G" srcImm8, dst4B is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0xc) ... & dst4B); srcImm8 {
+ val:1 = srcImm8;
+ dst4B = val;
+ setResultFlags(val);
+}
+
+# (1) MOV.B:G #imm, Ax
+:MOV^".B:G" srcImm8, dst4Ax is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0xc) & $(DST4AX)); srcImm8 {
+ val:1 = srcImm8;
+ dst4Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (1) MOV.W:G #imm, dst
+:MOV^".W:G" srcImm16, dst4W is ((b1_0107=0x3a & b1_size_0=1; b2_0407=0xc) ... & dst4W); srcImm16 {
+ val:2 = srcImm16;
+ dst4W = val;
+ setResultFlags(val);
+}
+
+# (2) MOV.B:Q #simm4, dst
+:MOV^".B:Q" srcSimm4_0407, dst4B is (b1_0107=0x6c & b1_size_0=0; srcSimm4_0407) ... & dst4B {
+ val:1 = srcSimm4_0407;
+ dst4B = val;
+ setResultFlags(val);
+}
+
+# (2) MOV.B:Q #simm4, Ax
+:MOV^".B:Q" srcSimm4_0407, dst4Ax is (b1_0107=0x6c & b1_size_0=0; srcSimm4_0407) & $(DST4AX) {
+ val:1 = srcSimm4_0407;
+ dst4Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (2) MOV.W:Q #simm4, dst
+:MOV^".W:Q" srcSimm4_0407, dst4W is (b1_0107=0x6c & b1_size_0=1; srcSimm4_0407) ... & dst4W {
+ val:2 = sext(srcSimm4_0407);
+ dst4W = val;
+ setResultFlags(val);
+}
+
+# (3) MOV.B:S #imm, dst
+:MOV^".B:S" srcImm8, dst3B_afterDsp8 is (b1_0307=0x18; srcImm8) ... & $(DST3B_AFTER_DSP8) {
+ val:1 = srcImm8;
+ dst3B_afterDsp8 = val;
+ setResultFlags(val);
+}
+
+# (4) MOV.B:S #imm, dst
+:MOV^".B:S" srcImm8, b1_3_regAx is b1_0407=0xe & b1_3_regAx & b1_0002=0x2; srcImm8 {
+ val:1 = srcImm8;
+ b1_3_regAx = zext(val);
+ setResultFlags(val);
+}
+
+# (4) MOV.W:S #imm, Ax
+:MOV^".W:S" srcImm16, b1_3_regAx is b1_0407=0xa & b1_3_regAx & b1_0002=0x2; srcImm16 {
+ val:2 = srcImm16;
+ b1_3_regAx = val;
+ setResultFlags(val);
+}
+
+# (5) MOV.B:Z #0, dst
+:MOV^".B:Z" srcZero8, dst3B is (srcZero8 & b1_0307=0x16) ... & $(DST3B) {
+ dst3B = 0;
+ $(SIGN) = 0;
+ $(ZERO) = 1;
+}
+
+# (6) MOV.B:G src, dst
+:MOV^".B:G" src4B, dst4B_afterSrc4 is (b1_0107=0x39 & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ val:1 = src4B;
+ dst4B_afterSrc4 = val;
+ setResultFlags(val);
+}
+
+# (6) MOV.B:G src, Ax
+:MOV^".B:G" src4B, dst4Ax is (b1_0107=0x39 & b1_size_0=0) ... & src4B & $(DST4AX) ... {
+ val:1 = src4B;
+ dst4Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (6) MOV.W:G src, dst
+:MOV^".W:G" src4W, dst4W_afterSrc4 is (b1_0107=0x39 & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ val:2 = src4W;
+ dst4W_afterSrc4 = val;
+ setResultFlags(val);
+}
+
+# (7) MOV.B:S src, Ax
+:MOV^".B:S" dst2B, b1_2_regAx is (b1_0307=0x06 & b1_2_regAx) ... & dst2B {
+ val:1 = dst2B;
+ b1_2_regAx = zext(val);
+ setResultFlags(val);
+}
+
+# (8) MOV.B:S R0H/R0L, dst
+# TODO: Is it really necessary to exclude R0H/R0L as valid destination ??
+:MOV^".B:S" b1_2_reg8, dst2B is (b1_0307=0x0 & b1_2_reg8) ... & dst2B {
+ val:1 = b1_2_reg8;
+ dst2B = val;
+ setResultFlags(val);
+}
+
+# (9) MOV.B:S src, R0H/R0L
+:MOV^".B:S" dst2B, b1_2_reg8 is (b1_0307=0x1 & b1_2_reg8) ... & dst2B {
+ val:1 = dst2B;
+ b1_2_reg8 = val;
+ setResultFlags(val);
+}
+
+# (10) MOV.B:G dsp:8[SP], dst
+:MOV^".B:G" dsp8spB, dst4B is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0xb) ... & dst4B); dsp8spB {
+ val:1 = dsp8spB;
+ dst4B = val;
+ setResultFlags(val);
+}
+
+# (10) MOV.B:G dsp:8[SP], Ax
+:MOV^".B:G" dsp8spB, dst4Ax is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0xb) & $(DST4AX)); dsp8spB {
+ val:1 = dsp8spB;
+ dst4Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (10) MOV.W:G dsp:8[SP], dst
+:MOV^".W:G" dsp8spW, dst4W is ((b1_0107=0x3a & b1_size_0=1; b2_0407=0xb) ... & dst4W); dsp8spW {
+ val:2 = dsp8spW;
+ dst4W = val;
+ setResultFlags(val);
+}
+
+# (11) MOV.B:G src, dsp:8[SP]
+:MOV^".B:G" dst4B, dsp8spB is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0x3) ... & dst4B); dsp8spB {
+ val:1 = dst4B;
+ dsp8spB = val;
+ setResultFlags(val);
+}
+
+# (11) MOV.W:G src, dsp:8[SP]
+:MOV^".W:G" dst4W, dsp8spW is ((b1_0107=0x3a & b1_size_0=1; b2_0407=0x3) ... & dst4W); dsp8spW {
+ val:2 = dst4W;
+ dsp8spW = val;
+ setResultFlags(val);
+}
+
+### MOVA ###
+
+:MOVA dst4A, b2_reg16 is (b1_0007=0xeb; b2_0707=0 & b2_reg16) ... & $(DST4A) {
+ b2_reg16 = dst4A:2;
+}
+
+### MOVDir ###
+
+# TODO: dst4B=Ax/R0L cases will parse but are not valid
+
+# (1) MOVDir R0L, dst
+:MOVLL R0L, dst4B is (R0L & b1_0007=0x7c; b2_0407=0x8) ... & dst4B {
+ dst4B = (R0L & 0x0f) | (dst4B & 0xf0);
+}
+:MOVHL R0L, dst4B is (R0L & b1_0007=0x7c; b2_0407=0x9) ... & dst4B {
+ dst4B = ((R0L & 0xf0) >> 4) | (dst4B & 0xf0);
+}
+:MOVLH R0L, dst4B is (R0L & b1_0007=0x7c; b2_0407=0xa) ... & dst4B {
+ dst4B = ((R0L & 0x0f) << 4) | (dst4B & 0x0f);
+}
+:MOVHH R0L, dst4B is (R0L & b1_0007=0x7c; b2_0407=0xb) ... & dst4B {
+ dst4B = (R0L & 0xf0) | (dst4B & 0x0f);
+}
+
+# (1) MOVDir dst, R0L
+:MOVLL dst4B, R0L is (R0L & b1_0007=0x7c; b2_0407=0x0) ... & dst4B {
+ R0L = (dst4B & 0x0f) | (R0L & 0xf0);
+}
+:MOVHL dst4B, R0L is (R0L & b1_0007=0x7c; b2_0407=0x1) ... & dst4B {
+ R0L = ((dst4B & 0xf0) >> 4) | (R0L & 0xf0);
+}
+:MOVLH dst4B, R0L is (R0L & b1_0007=0x7c; b2_0407=0x2) ... & dst4B {
+ R0L = ((dst4B & 0x0f) << 4) | (R0L & 0x0f);
+}
+:MOVHH dst4B, R0L is (R0L & b1_0007=0x7c; b2_0407=0x3) ... & dst4B {
+ R0L = (dst4B & 0xf0) | (R0L & 0x0f);
+}
+
+### MUL ###
+
+# TODO: Illegal MUL destination cases will parse but are not valid (e.g., R0H, R2, R1H, R3)
+
+# (1) MUL.B #imm, dst
+:MUL.B srcSimm8, dst4B is ((b1_0107=0x3e & b1_size_0=0; b2_0407=0x5) ... & dst4B & dst4W); srcSimm8 {
+ dst4W = sext(srcSimm8) * sext(dst4B);
+}
+
+# (1) MUL.W #imm, dst
+:MUL.W srcSimm16, dst4W is ((b1_0107=0x3e & b1_size_0=1; b2_0407=0x5) ... & dst4W & dst4L); srcSimm16 {
+ dst4L = sext(srcSimm16) * sext(dst4W);
+}
+
+# (2) MUL.B src, dst
+:MUL.B src4B, dst4B_afterSrc4 is (b1_0107=0x3c & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... & dst4W_afterSrc4 ... {
+ dst4W_afterSrc4 = sext(src4B) * sext(dst4B_afterSrc4);
+}
+
+# (2) MUL.W src, dst
+:MUL.W src4W, dst4W_afterSrc4 is (b1_0107=0x3c & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... & dst4L_afterSrc4 ... {
+ dst4L_afterSrc4 = sext(src4W) * sext(dst4W_afterSrc4);
+}
+
+### MULU ###
+
+# TODO: Illegal MULU destination cases will parse but are not valid (e.g., R0H, R2, R1H, R3)
+
+# (1) MULU.B #imm, dst
+:MULU.B srcImm8, dst4B is ((b1_0107=0x3e & b1_size_0=0; b2_0407=0x4) ... & dst4B & dst4W); srcImm8 {
+ dst4W = zext(srcImm8) * zext(dst4B);
+}
+
+# (1) MULU.W #imm, dst
+:MULU.W srcImm16, dst4W is ((b1_0107=0x3e & b1_size_0=1; b2_0407=0x4) ... & dst4W & dst4L); srcImm16 {
+ dst4L = zext(srcImm16) * zext(dst4W);
+}
+
+# (2) MULU.B src, dst
+:MULU.B src4B, dst4B_afterSrc4 is (b1_0107=0x38 & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... & dst4W_afterSrc4 ... {
+ dst4W_afterSrc4 = zext(src4B) * zext(dst4B_afterSrc4);
+}
+
+# (2) MULU.W src, dst
+:MULU.W src4W, dst4W_afterSrc4 is (b1_0107=0x38 & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... & dst4L_afterSrc4 ... {
+ dst4L_afterSrc4 = zext(src4W) * zext(dst4W_afterSrc4);
+}
+
+### NEG ###
+
+# (1) NEG.B dst
+:NEG.B dst4B is (b1_0107=0x3a & b1_size_0=0; b2_0407=0x5) ... & dst4B {
+ tmp:1 = dst4B;
+ setSubtractFlags(0:1, tmp);
+ tmp = -tmp;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) NEG.W dst
+:NEG.W dst4W is (b1_0107=0x3a & b1_size_0=1; b2_0407=0x5) ... & dst4W {
+ tmp:2 = dst4W;
+ setSubtractFlags(0:2, tmp);
+ tmp = -tmp;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+### NOP ###
+
+:NOP is b1_0007=0x04 {
+}
+
+### NOT ###
+
+# (1) NOT.B dst
+:NOT.B dst4B is (b1_0107=0x3a & b1_size_0=0; b2_0407=0x7) ... & dst4B {
+ tmp:1 = ~dst4B;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) NOT.W dst
+:NOT.W dst4W is (b1_0107=0x3a & b1_size_0=1; b2_0407=0x7) ... & dst4W {
+ tmp:2 = ~dst4W;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) NOT.B:S dst
+:NOT^".B:S" dst3B is (b1_0307=0x17) ... & $(DST3B) {
+ tmp:1 = ~dst3B;
+ dst3B = tmp;
+ setResultFlags(tmp);
+}
+
+### OR ###
+
+# (1) OR.B:G #imm, dst
+:OR^".B:G" srcImm8, dst4B is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x3) ... & dst4B); srcImm8 {
+ tmp:1 = dst4B | srcImm8;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) OR.B:G #imm, Ax
+:OR^".B:G" srcImm8, dst4Ax is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x3) & $(DST4AX)); srcImm8 {
+ tmp:1 = dst4Ax:1 | srcImm8;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) OR.W:G #imm, dst
+:OR^".W:G" srcImm16, dst4W is ((b1_0107=0x3b & b1_size_0=1; b2_0407=0x3) ... & dst4W); srcImm16 {
+ tmp:2 = dst4W | srcImm16;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) OR.B:S #imm, dst
+:OR^".B:S" srcImm8, dst3B_afterDsp8 is (b1_0307=0x13; srcImm8) ... & $(DST3B_AFTER_DSP8) {
+ tmp:1 = dst3B_afterDsp8 | srcImm8;
+ dst3B_afterDsp8 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) OR.B:G src, dst
+:OR^".B:G" src4B, dst4B_afterSrc4 is (b1_0107=0x4c & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ tmp:1 = dst4B_afterSrc4 | src4B;
+ dst4B_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) OR.B:G src, Ax
+:OR^".B:G" src4B, dst4Ax is (b1_0107=0x4c & b1_size_0=0) ... & src4B & $(DST4AX) ... {
+ tmp:1 = dst4Ax:1 | src4B;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (3) OR.W:G src, dst
+:OR^".W:G" src4W, dst4W_afterSrc4 is (b1_0107=0x4c & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ tmp:2 = dst4W_afterSrc4 | src4W;
+ dst4W_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (4) OR.B:S src, R0L/R0H
+:OR^".B:S" dst2B, b1_2_reg8 is (b1_0307=0x3 & b1_2_reg8) ... & dst2B {
+ tmp:1 = dst2B | b1_2_reg8;
+ b1_2_reg8 = tmp;
+ setResultFlags(tmp);
+}
+
+### POP ###
+
+# (1) POP.B:G dst
+:POP^".B:G" dst4B is (b1_0107=0x3a & b1_size_0=0; b2_0407=0xd) ... & dst4B {
+ pop1(dst4B);
+}
+
+# (1) POP.B:G Ax
+:POP^".B:G" dst4Ax is (b1_0107=0x3a & b1_size_0=0; b2_0407=0xd) & $(DST4AX) {
+ val:1 = 0;
+ pop1(val);
+ dst4Ax = zext(val);
+}
+
+# (1) POP.W:G dst
+:POP^".W:G" dst4W is (b1_0107=0x3a & b1_size_0=1; b2_0407=0xd) ... & dst4W {
+ pop2(dst4W);
+}
+
+# (2) POP.B:S R0L/R0H
+:POP^".B:S" b1_3_reg8 is b1_0407=0x9 & b1_3_reg8 & b1_0002=0x2 {
+ pop1(b1_3_reg8);
+}
+
+# (3) POP.W:S Ax
+:POP^".W:S" b1_3_regAx is b1_0407=0xd & b1_3_regAx & b1_0002=0x2 {
+ pop2(b1_3_regAx);
+}
+
+### POPC ###
+
+:POPC b2_creg16 is b1_0007=0xeb; b2_0707=0 & b2_creg16 & b2_0003=0x3 {
+ pop2(b2_creg16);
+}
+
+### POPM ###
+popRegFB: FB is regBit7=1 & FB { pop2(FB); }
+popRegFB: is regBit7=0 { }
+
+popRegSB: SB popRegFB is regBit6=1 & popRegFB & SB { pop2(SB); build popRegFB; }
+popRegSB: popRegFB is popRegFB { build popRegFB; }
+
+popRegA1: A1 popRegSB is regBit5=1 & popRegSB & A1 { pop2(A1); build popRegSB; }
+popRegA1: popRegSB is popRegSB { build popRegSB; }
+popRegA0: A0 popRegA1 is regBit4=1 & popRegA1 & A0 { pop2(A0); build popRegA1; }
+popRegA0: popRegA1 is popRegA1 { build popRegA1; }
+
+popRegR3: R3 popRegA0 is regBit3=1 & popRegA0 & R3 { pop2(R3); build popRegA0; }
+popRegR3: popRegA0 is popRegA0 { build popRegA0; }
+popRegR2: R2 popRegR3 is regBit2=1 & popRegR3 & R2 { pop2(R2); build popRegR3; }
+popRegR2: popRegR3 is popRegR3 { build popRegR3; }
+popRegR1: R1 popRegR2 is regBit1=1 & popRegR2 & R1 { pop2(R1); build popRegR2; }
+popRegR1: popRegR2 is popRegR2 { build popRegR2; }
+popRegR0: R0 popRegR1 is regBit0=1 & popRegR1 & R0 { pop2(R0); build popRegR1; }
+popRegR0: popRegR1 is popRegR1 { build popRegR1; }
+
+popRegList: "( "^popRegR0^")" is popRegR0 { build popRegR0; }
+
+:POPM popRegList is b1_0007=0xed; popRegList {
+ build popRegList;
+}
+
+### PUSH ###
+
+# (1) PUSH.B:G #imm
+:PUSH^".B:G" srcImm8 is b1_0107=0x3e & b1_size_0=0; b2_0007=0xe2; srcImm8 {
+ push1(srcImm8);
+}
+
+# (1) PUSH.W:G #imm
+:PUSH^".W:G" srcImm16 is b1_0107=0x3e & b1_size_0=1; b2_0007=0xe2; srcImm16 {
+ push2(srcImm16);
+}
+
+# (2) PUSH.B:G src
+:PUSH^".B:G" dst4B is (b1_0107=0x3a & b1_size_0=0; b2_0407=0x4) ... & dst4B {
+ push1(dst4B);
+}
+
+# (2) PUSH.W:G src
+:PUSH^".W:G" dst4W is (b1_0107=0x3a & b1_size_0=1; b2_0407=0x4) ... & dst4W {
+ push2(dst4W);
+}
+
+# (3) PUSH.B:S R0H/R0L
+:PUSH^".B:S" b1_3_reg8 is b1_0407=0x8 & b1_3_reg8 & b1_0002=0x2 {
+ push1(b1_3_reg8);
+}
+
+# (4) PUSH.W:S Ax
+:PUSH^".W:S" b1_3_regAx is b1_0407=0xc & b1_3_regAx & b1_0002=0x2 {
+ push2(b1_3_regAx);
+}
+
+### PUSHA ###
+
+:PUSHA dst4A is (b1_0007=0x7d; b2_0407=0x9) ... & $(DST4A) {
+ push2(dst4A:2);
+}
+
+### PUSHC ###
+
+:PUSHC b2_creg16 is b1_0007=0xeb; b2_0707=0 & b2_creg16 & b2_0003=0x2 {
+ push2(b2_creg16);
+}
+
+### PUSHM ###
+pushRegR0: R0 is regBit7=1 & R0 { push2(R0); }
+pushRegR0: is regBit7=0 { }
+pushRegR1: pushRegR0 R1 is regBit6=1 & pushRegR0 & R1 { push2(R1); build pushRegR0; }
+pushRegR1: pushRegR0 is pushRegR0 { build pushRegR0; }
+pushRegR2: pushRegR1 R2 is regBit5=1 & pushRegR1 & R2 { push2(R2); build pushRegR1; }
+pushRegR2: pushRegR1 is pushRegR1 { build pushRegR1; }
+pushRegR3: pushRegR2 R3 is regBit4=1 & pushRegR2 & R3 { push2(R3); build pushRegR2; }
+pushRegR3: pushRegR2 is pushRegR2 { build pushRegR2; }
+
+pushRegA0: pushRegR3 A0 is regBit3=1 & pushRegR3 & A0 { push3(A0); build pushRegR3; }
+pushRegA0: pushRegR3 is pushRegR3 { build pushRegR3; }
+pushRegA1: pushRegA0 A1 is regBit2=1 & pushRegA0 & A1 { push3(A1); build pushRegA0; }
+pushRegA1: pushRegA0 is pushRegA0 { build pushRegA0; }
+
+pushRegSB: pushRegA1 SB is regBit1=1 & pushRegA1 & SB { push3(SB); build pushRegA1; }
+pushRegSB: pushRegA1 is pushRegA1 { build pushRegA1; }
+
+pushRegFB: pushRegSB FB is regBit0=1 & pushRegSB & FB { push3(FB); build pushRegSB; }
+pushRegFB: pushRegSB is pushRegSB { build pushRegSB; }
+
+pushRegList: "("^pushRegFB^" )" is pushRegFB { build pushRegFB; }
+
+:PUSHM pushRegList is b1_0007=0xec; pushRegList {
+ build pushRegList;
+}
+
+### REIT ###
+
+:REIT is b1_0007=0xfb {
+ pc:3 = 0;
+ pop3(pc);
+ f:1 = 0;
+ pop1(f);
+ FLG = zext(f); # TODO: Not sure what state upper FLG bits should be in ??
+ return [pc];
+}
+
+### RMPA ###
+
+:RMPA.B is b1_0107=0x3e & b1_size_0=0; b2_0007=0xf1 {
+ if (R3 == 0) goto inst_next;
+ ptr0:3 = zext(A0);
+ ptr1:3 = zext(A1);
+ a:1 = *:1 ptr0;
+ b:1 = *:1 ptr1;
+ A0 = A0 + 1;
+ A1 = A1 + 1;
+ prod:2 = sext(a) * sext(b);
+ o:1 = scarry(R0, prod);
+ $(OVERFLOW) = o | $(OVERFLOW);
+ R0 = R0 + prod;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:RMPA.W is b1_0107=0x3e & b1_size_0=1; b2_0007=0xf1 {
+ if (R3 == 0) goto inst_next;
+ ptr0:3 = zext(A0);
+ ptr1:3 = zext(A1);
+ a:2 = *:2 ptr0;
+ b:2 = *:2 ptr1;
+ A0 = A0 + 2;
+ A1 = A1 + 2;
+ prod:4 = sext(a) * sext(b);
+ o:1 = scarry(R2R0, prod);
+ $(OVERFLOW) = o | $(OVERFLOW);
+ R2R0 = R2R0 + prod;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+### ROLC ###
+
+:ROLC.B dst4B is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xa) ... & dst4B {
+ c:1 = $(CARRY);
+ tmp:1 = dst4B;
+ $(CARRY) = tmp s< 0;
+ tmp = (tmp << 1) | c;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+:ROLC.B dst4Ax is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xa) & $(DST4AX) {
+ c:1 = $(CARRY);
+ tmp:1 = dst4Ax:1;
+ $(CARRY) = tmp s< 0;
+ tmp = (tmp << 1) | c;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+:ROLC.W dst4W is (b1_0107=0x3b & b1_size_0=1; b2_0407=0xa) ... & dst4W {
+ c:2 = zext($(CARRY));
+ tmp:2 = dst4W;
+ $(CARRY) = tmp s< 0;
+ tmp = (tmp << 1) | c;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+### RORC ###
+
+:RORC.B dst4B is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xb) ... & dst4B {
+ c:1 = $(CARRY);
+ tmp:1 = dst4B;
+ $(CARRY) = (tmp & 1) == 1;
+ tmp = (tmp >> 1) | (c << 7);
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+:RORC.B dst4Ax is (b1_0107=0x3b & b1_size_0=0; b2_0407=0xb) & $(DST4AX) {
+ c:1 = $(CARRY);
+ tmp:1 = dst4Ax:1;
+ $(CARRY) = (tmp & 1) == 1;
+ tmp = (tmp >> 1) | (c << 7);
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+:RORC.W dst4W is (b1_0107=0x3b & b1_size_0=1; b2_0407=0xb) ... & dst4W {
+ c:2 = zext($(CARRY));
+ tmp:2 = dst4W;
+ $(CARRY) = (tmp & 1) == 1;
+ tmp = (tmp >> 1) | (c << 15);
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+### ROT ###
+
+# (1) ROT.B #imm, dst (right)
+:ROT.B srcSimm4Shift_0407, dst4B is (b1_0107=0x70 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=1) ... & dst4B {
+ rightShift:1 = -srcSimm4Shift_0407;
+ tmp:1 = dst4B;
+ $(CARRY) = (tmp >> (rightShift - 1)) & 1;
+ tmp = (tmp >> rightShift) | (tmp << (8 - rightShift));
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ROT.B #imm, Ax (right)
+:ROT.B srcSimm4Shift_0407, dst4Ax is (b1_0107=0x70 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=1) & $(DST4AX) {
+ rightShift:1 = -srcSimm4Shift_0407;
+ tmp:1 = dst4Ax:1;
+ $(CARRY) = (tmp >> (rightShift - 1)) & 1;
+ tmp = (tmp >> rightShift) | (tmp << (8 - rightShift));
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ROT.W #imm, dst (right)
+:ROT.W srcSimm4Shift_0407, dst4W is (b1_0107=0x70 & b1_size_0=1; srcSimm4Shift_0407 & b2_shiftSign_7=1) ... & dst4W {
+ rightShift:1 = -srcSimm4Shift_0407;
+ tmp:2 = dst4W;
+ c:2 = (tmp >> (rightShift - 1));
+ $(CARRY) = c:1 & 1;
+ tmp = (tmp >> rightShift) | (tmp << (16 - rightShift));
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ROT.B #imm, dst (left)
+:ROT.B srcSimm4Shift_0407, dst4B is (b1_0107=0x70 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=0) ... & dst4B {
+ leftShift:1 = srcSimm4Shift_0407;
+ tmp:1 = dst4B;
+ $(CARRY) = (tmp >> (8 - leftShift)) & 1;
+ tmp = (tmp << leftShift) | (tmp >> (8 - leftShift));
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ROT.B #imm, Ax (left)
+:ROT.B srcSimm4Shift_0407, dst4Ax is (b1_0107=0x70 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=0) & $(DST4AX) {
+ leftShift:1 = srcSimm4Shift_0407;
+ tmp:1 = dst4Ax:1;
+ $(CARRY) = (tmp >> (8 - leftShift)) & 1;
+ tmp = (tmp << leftShift) | (tmp >> (8 - leftShift));
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ROT.W #imm, dst (left)
+:ROT.W srcSimm4Shift_0407, dst4W is (b1_0107=0x70 & b1_size_0=1; srcSimm4Shift_0407 & b2_shiftSign_7=0) ... & dst4W {
+ leftShift:1 = srcSimm4Shift_0407;
+ tmp:2 = dst4W;
+ c:2 = (tmp >> (16 - leftShift));
+ $(CARRY) = c:1 & 1;
+ tmp = (tmp << leftShift) | (tmp >> (16 - leftShift));
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ROT.B R1H, dst
+:ROT.B R1H, dst4B is (R1H & b1_0107=0x3a & b1_size_0=0; b2_0407=0x6) ... & dst4B {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H s% 8;
+ tmp:1 = dst4B;
+ if (shift s>= 0) goto ;
+ shift = -shift;
+ $(CARRY) = (tmp >> (shift - 1)) & 1;
+ tmp = (tmp >> shift) | (tmp << (8 - shift));
+ goto ;
+
+ $(CARRY) = (tmp >> (8 - shift)) & 1;
+ tmp = (tmp << shift) | (tmp >> (8 - shift));
+
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ROT.B R1H, Ax
+:ROT.B R1H, dst4Ax is (R1H & b1_0107=0x3a & b1_size_0=0; b2_0407=0x6) & $(DST4AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H s% 8;
+ tmp:1 = dst4Ax:1;
+ if (shift s>= 0) goto ;
+ shift = -shift;
+ $(CARRY) = (tmp >> (shift - 1)) & 1;
+ tmp = (tmp >> shift) | (tmp << (8 - shift));
+ goto ;
+
+ $(CARRY) = (tmp >> (8 - shift)) & 1;
+ tmp = (tmp << shift) | (tmp >> (8 - shift));
+
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) ROT.W R1H, dst
+:ROT.W R1H, dst4W is (R1H & b1_0107=0x3a & b1_size_0=1; b2_0407=0x6) ... & dst4W {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H s% 16;
+ tmp:2 = dst4W;
+ if (shift s>= 0) goto ;
+ shift = -shift;
+ c:2 = (tmp >> (shift - 1));
+ tmp = (tmp >> shift) | (tmp << (16 - shift));
+ goto ;
+
+ c = (tmp >> (16 - shift));
+ tmp = (tmp << shift) | (tmp >> (16 - shift));
+
+ $(CARRY) = c:1 & 1;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+### RTS ###
+
+:RTS is b1_0007=0xf3 {
+ pc:3 = 0;
+ pop3(pc);
+ return [pc];
+}
+
+### SBB ###
+
+# (1) SBB.B #imm, dst
+:SBB.B srcSimm8, dst4B is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x7) ... & dst4B); srcSimm8 {
+ tmp:1 = dst4B;
+ c:1 = $(CARRY);
+ setSubtract3Flags(tmp, srcSimm8, c);
+ tmp = tmp - srcSimm8 - c;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) SBB.B #imm, Ax
+:SBB.B srcSimm8, dst4Ax is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x7) & $(DST4AX)); srcSimm8 {
+ tmp:1 = dst4Ax:1;
+ c:1 = $(CARRY);
+ setSubtract3Flags(tmp, srcSimm8, c);
+ tmp = tmp - srcSimm8 - c;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) SBB.W #imm, dst
+:SBB.W srcSimm16, dst4W is ((b1_0107=0x3b & b1_size_0=1; b2_0407=0x7) ... & dst4W); srcSimm16 {
+ tmp:2 = dst4W;
+ c:2 = zext($(CARRY));
+ setSubtract3Flags(tmp, srcSimm16, c);
+ tmp = tmp - srcSimm16 - c;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) SBB.B src, dst
+:SBB.B src4B, dst4B_afterSrc4 is (b1_0107=0x5c & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ tmp:1 = dst4B_afterSrc4;
+ s:1 = src4B;
+ c:1 = $(CARRY);
+ setSubtract3Flags(tmp, s, c);
+ tmp = tmp - s - c;
+ dst4B_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) SBB.B src, Ax
+:SBB.B src4B, dst4Ax is (b1_0107=0x5c & b1_size_0=0) ... & src4B & $(DST4AX) ... {
+ tmp:1 = dst4Ax:1;
+ s:1 = src4B;
+ c:1 = $(CARRY);
+ setSubtract3Flags(tmp, s, c);
+ tmp = tmp - s - c;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) SBB.W src, dst
+:SBB.W src4W, dst4W_afterSrc4 is (b1_0107=0x5c & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ tmp:2 = dst4W_afterSrc4;
+ s:2 = src4W;
+ c:2 = zext($(CARRY));
+ setSubtract3Flags(tmp, s, c);
+ tmp = tmp - s - c;
+ dst4W_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+##### SBJNZ - PSUEDO-OP! SAME AS ADJNZ #####
+### SHA ###
+macro SHAsetShiftRightFlags(val,shift,result) {
+ local c = (val >> (shift - 1)) & 1;
+ $(CARRY) = c:1;
+ local mask = ~(-(1 << shift));
+ allOnes:1 = (mask & val) == mask;
+ allZeros:1 = (mask & val) == 0;
+ $(OVERFLOW) = (result s< 0 && allOnes) || (result s>= 0 && allZeros);
+ setResultFlags(result);
+}
+
+macro SHAsetShiftLeftFlags(val,shift,result,sze) {
+ local c = (val >> (sze - shift)) & 1;
+ $(CARRY) = c:1;
+ local mask = -(1 << shift);
+ allOnes:1 = (mask & val) == mask;
+ allZeros:1 = (mask & val) == 0;
+ $(OVERFLOW) = (result s< 0 && allOnes) || (result s>= 0 && allZeros);
+ setResultFlags(result);
+}
+
+# (1) SHA.B #imm4, dst (right)
+:SHA.B srcSimm4Shift_0407, dst4B is (b1_0107=0x78 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=1) ... & dst4B {
+ val:1 = dst4B;
+ shift:1 = -srcSimm4Shift_0407;
+ tmp:1 = val s>> shift;
+ dst4B = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHA.B #imm4, Ax (right)
+:SHA.B srcSimm4Shift_0407, dst4Ax is (b1_0107=0x78 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=1) & $(DST4AX) {
+ val:1 = dst4Ax:1;
+ shift:1 = -srcSimm4Shift_0407;
+ tmp:1 = val s>> shift;
+ dst4Ax = zext(tmp);
+ SHAsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHA.W #imm4, dst (right)
+:SHA.W srcSimm4Shift_0407, dst4W is (b1_0107=0x78 & b1_size_0=1; srcSimm4Shift_0407 & b2_shiftSign_7=1) ... & dst4W {
+ val:2 = dst4W;
+ shift:1 = -srcSimm4Shift_0407;
+ tmp:2 = val s>> shift;
+ dst4W = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHA.B #imm4, dst (left)
+:SHA.B srcSimm4Shift_0407, dst4B is (b1_0107=0x78 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=0) ... & dst4B {
+ val:1 = dst4B;
+ shift:1 = srcSimm4Shift_0407;
+ tmp:1 = val << shift;
+ dst4B = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (1) SHA.B #imm4, Ax (left)
+:SHA.B srcSimm4Shift_0407, dst4Ax is (b1_0107=0x78 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=0) & $(DST4AX) {
+ val:1 = dst4Ax:1;
+ shift:1 = srcSimm4Shift_0407;
+ tmp:1 = val << shift;
+ dst4Ax = zext(tmp);
+ SHAsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (1) SHA.W #imm4, dst (left)
+:SHA.W srcSimm4Shift_0407, dst4W is (b1_0107=0x78 & b1_size_0=1; srcSimm4Shift_0407 & b2_shiftSign_7=0) ... & dst4W {
+ val:2 = dst4W;
+ shift:1 = srcSimm4Shift_0407;
+ tmp:2 = val << shift;
+ dst4W = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (2) SHA.B R1H, dst
+:SHA.B R1H, dst4B is (R1H & b1_0107=0x3a & b1_size_0=0; b2_0407=0xf) ... & dst4B {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:1 = dst4B;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:1 = val s>> shift;
+ dst4B = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst4B = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (2) SHA.B R1H, Ax
+:SHA.B R1H, dst4Ax is (R1H & b1_0107=0x3a & b1_size_0=0; b2_0407=0xf) & $(DST4AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:1 = dst4Ax:1;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:1 = val s>> shift;
+ dst4Ax = zext(tmp);
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst4Ax = zext(tmp);
+ SHAsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (2) SHA.W R1H, dst
+:SHA.W R1H, dst4W is (R1H & b1_0107=0x3a & b1_size_0=1; b2_0407=0xf) ... & dst4W {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:2 = dst4W;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:2 = val s>> shift;
+ dst4W = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst4W = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (3) SHA.L #imm4, R2R0/R3R1 (right)
+:SHA.L srcSimm4Shift_0003, b2_reg32 is b1_0007=0xeb; b2_0507=0x5 & b2_reg32 & srcSimm4Shift_0003 & b2_shiftSign_3=1 {
+ val:4 = b2_reg32;
+ shift:1 = -srcSimm4Shift_0003;
+ tmp:4 = val s>> shift;
+ b2_reg32 = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+}
+
+# (3) SHA.L #imm4, R2R0/R3R1 (left)
+:SHA.L srcSimm4Shift_0003, b2_reg32 is b1_0007=0xeb; b2_0507=0x5 & b2_reg32 & srcSimm4Shift_0003 & b2_shiftSign_3=0 {
+ val:4 = b2_reg32;
+ shift:1 = srcSimm4Shift_0003;
+ tmp:4 = val << shift;
+ b2_reg32 = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 32);
+}
+
+# (4) SHA.L R1H, R2R0/R3R1
+:SHA.L R1H, b2_reg32 is R1H & b1_0007=0xeb; b2_0507=0x1 & b2_reg32 & b2_0003=0x1 {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:4 = b2_reg32;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val s>> shift;
+ b2_reg32 = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ b2_reg32 = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 32);
+}
+
+### SHL ###
+macro SHLsetShiftRightFlags(val,shift,result) {
+ local c = (val >> (shift - 1)) & 1;
+ $(CARRY) = c:1;
+ setResultFlags(result);
+}
+
+macro SHLsetShiftLeftFlags(val,shift,result,sze) {
+ local c = (val >> (sze - shift)) & 1;
+ $(CARRY) = c:1;
+ setResultFlags(result);
+}
+
+# (1) SHL.B #imm4, dst (right)
+:SHL.B srcSimm4Shift_0407, dst4B is (b1_0107=0x74 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=1) ... & dst4B {
+ val:1 = dst4B;
+ shift:1 = -srcSimm4Shift_0407;
+ tmp:1 = val >> shift;
+ dst4B = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHL.B #imm4, Ax (right)
+:SHL.B srcSimm4Shift_0407, dst4Ax is (b1_0107=0x74 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=1) & $(DST4AX) {
+ val:1 = dst4Ax:1;
+ shift:1 = -srcSimm4Shift_0407;
+ tmp:1 = val >> shift;
+ dst4Ax = zext(tmp);
+ SHLsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHL.W #imm4, dst (right)
+:SHL.W srcSimm4Shift_0407, dst4W is (b1_0107=0x74 & b1_size_0=1; srcSimm4Shift_0407 & b2_shiftSign_7=1) ... & dst4W {
+ val:2 = dst4W;
+ shift:1 = -srcSimm4Shift_0407;
+ tmp:2 = val >> shift;
+ dst4W = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHL.B #imm4, dst (left)
+:SHL.B srcSimm4Shift_0407, dst4B is (b1_0107=0x74 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=0) ... & dst4B {
+ val:1 = dst4B;
+ shift:1 = srcSimm4Shift_0407;
+ tmp:1 = val << shift;
+ dst4B = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (1) SHL.B #imm4, Ax (left)
+:SHL.B srcSimm4Shift_0407, dst4Ax is (b1_0107=0x74 & b1_size_0=0; srcSimm4Shift_0407 & b2_shiftSign_7=0) & $(DST4AX) {
+ val:1 = dst4Ax:1;
+ shift:1 = srcSimm4Shift_0407;
+ tmp:1 = val << shift;
+ dst4Ax = zext(tmp);
+ SHLsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (1) SHL.W #imm4, dst (left)
+:SHL.W srcSimm4Shift_0407, dst4W is (b1_0107=0x74 & b1_size_0=1; srcSimm4Shift_0407 & b2_shiftSign_7=0) ... & dst4W {
+ val:2 = dst4W;
+ shift:1 = srcSimm4Shift_0407;
+ tmp:2 = val << shift;
+ dst4W = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (2) SHL.B R1H, dst
+:SHL.B R1H, dst4B is (R1H & b1_0107=0x3a & b1_size_0=0; b2_0407=0xe) ... & dst4B {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:1 = dst4B;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:1 = val >> shift;
+ dst4B = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst4B = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (2) SHL.B R1H, Ax
+:SHL.B R1H, dst4Ax is (R1H & b1_0107=0x3a & b1_size_0=0; b2_0407=0xe) & $(DST4AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:1 = dst4Ax:1;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:1 = val >> shift;
+ dst4Ax = zext(tmp);
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst4Ax = zext(tmp);
+ SHLsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (2) SHL.W R1H, dst
+:SHL.W R1H, dst4W is (R1H & b1_0107=0x3a & b1_size_0=1; b2_0407=0xe) ... & dst4W {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:2 = dst4W;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:2 = val >> shift;
+ dst4W = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst4W = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (3) SHL.L #imm4, R2R0/R3R1 (right)
+:SHL.L srcSimm4Shift_0003, b2_reg32 is b1_0007=0xeb; b2_0507=0x4 & b2_reg32 & srcSimm4Shift_0003 & b2_shiftSign_3=1 {
+ val:4 = b2_reg32;
+ shift:1 = -srcSimm4Shift_0003;
+ tmp:4 = val >> shift;
+ b2_reg32 = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+}
+
+# (3) SHL.L #imm4, R2R0/R3R1 (left)
+:SHL.L srcSimm4Shift_0003, b2_reg32 is b1_0007=0xeb; b2_0507=0x4 & b2_reg32 & srcSimm4Shift_0003 & b2_shiftSign_3=0 {
+ val:4 = b2_reg32;
+ shift:1 = srcSimm4Shift_0003;
+ tmp:4 = val << shift;
+ b2_reg32 = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 32);
+}
+
+# (4) SHL.L R1H, R2R0/R3R1
+:SHL.L R1H, b2_reg32 is R1H & b1_0007=0xeb; b2_0507=0x0 & b2_reg32 & b2_0003=0x1 {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:4 = b2_reg32;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val >> shift;
+ b2_reg32 = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ b2_reg32 = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 32);
+}
+
+### SMOVB ###
+
+:SMOVB.B is b1_0107=0x3e & b1_size_0=0; b2_0007=0xe9 {
+ if (R3 == 0) goto inst_next;
+ ptr0:3 = (zext(R1H) << 16) + zext(A0);
+ ptr1:3 = zext(A1);
+ *:1 ptr1 = *:1 ptr0;
+ A1 = A1 - 1;
+ ptr0 = ptr0 - 1;
+ A0 = ptr0:2;
+ R1H = ptr0(2);
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:SMOVB.W is b1_0107=0x3e & b1_size_0=1; b2_0007=0xe9 {
+ if (R3 == 0) goto inst_next;
+ ptr0:3 = (zext(R1H) << 16) + zext(A0);
+ ptr1:3 = zext(A1);
+ *:2 ptr1 = *:2 ptr0;
+ A1 = A1 - 2;
+ ptr0 = ptr0 - 2;
+ A0 = ptr0:2;
+ R1H = ptr0(2);
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+### SMOVF ###
+
+:SMOVF.B is b1_0107=0x3e & b1_size_0=0; b2_0007=0xe8 {
+ if (R3 == 0) goto inst_next;
+ ptr0:3 = (zext(R1H) << 16) + zext(A0);
+ ptr1:3 = zext(A1);
+ *:1 ptr1 = *:1 ptr0;
+ A1 = A1 + 1;
+ ptr0 = ptr0 + 1;
+ A0 = ptr0:2;
+ R1H = ptr0(2);
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:SMOVF.W is b1_0107=0x3e & b1_size_0=1; b2_0007=0xe8 {
+ if (R3 == 0) goto inst_next;
+ ptr0:3 = (zext(R1H) << 16) + zext(A0);
+ ptr1:3 = zext(A1);
+ *:2 ptr1 = *:2 ptr0;
+ A1 = A1 + 2;
+ ptr0 = ptr0 + 2;
+ A0 = ptr0:2;
+ R1H = ptr0(2);
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+### SSTR ###
+
+:SSTR.B is b1_0107=0x3e & b1_size_0=0; b2_0007=0xea {
+ if (R3 == 0) goto inst_next;
+ ptr1:3 = zext(A1);
+ *:1 ptr1 = R0L;
+ A1 = A1 + 1;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:SSTR.W is b1_0107=0x3e & b1_size_0=1; b2_0007=0xea {
+ if (R3 == 0) goto inst_next;
+ ptr1:3 = zext(A1);
+ *:2 ptr1 = R0;
+ A1 = A1 + 2;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+### STC ###
+
+# (1) STC src, dst
+:STC b2_creg16, dst4W is (b1_0007=0x7b; b2_0707=1 & b2_creg16) ... & dst4W {
+ dst4W = b2_creg16;
+}
+
+# (2) STC PC, dst (dst=register)
+:STC PC, dst4L is (PC & b1_0007=0x7c; b2_0407=0xc) ... & dst4L {
+ dst4L = zext(PC);
+}
+
+# (2) STC PC, dst (dst=memory)
+:STC PC, dst4T is (PC & b1_0007=0x7c; b2_0407=0xc) ... & $(DST4T) {
+ dst4T = inst_next; # PC value refers to next instruction address
+}
+
+### STCTX ###
+
+:STCTX abs16offset, abs20offset is b1_0007=0xb6; b2_0007=0xd3; abs16offset; imm20_dat & abs20offset {
+
+ taskNum:1 = abs16offset; # load task number stored at abs16
+ ptr:3 = imm20_dat + (zext(taskNum) * 2); # compute table entry address relative to abs20
+ regInfo:1 = *:1 ptr;
+ ptr = ptr + 1;
+ spCorrect:1 = *:1 ptr;
+
+ ptr = zext(SP);
+
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = FB;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = SB;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = A1;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = A0;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = R3;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = R2;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = R1;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = R0;
+
+ SP = SP - zext(spCorrect);
+}
+
+### STE ###
+
+# (1) STE.B src, abs20
+:STE.B dst4B, abs20offset is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0) ... & dst4B); abs20offset {
+ val:1 = dst4B;
+ abs20offset = val;
+ setResultFlags(val);
+}
+
+# (1) STE.W src, abs20
+:STE.W dst4W, abs20offsetW is ((b1_0107=0x3a & b1_size_0=1; b2_0407=0) ... & dst4W); abs20offsetW {
+ val:2 = dst4W;
+ abs20offsetW = val;
+ setResultFlags(val);
+}
+
+# (2) STE.B src, dsp:20[A0]
+:STE.B dst4B, dsp20A0B is ((b1_0107=0x3a & b1_size_0=0; b2_0407=0x1) ... & dst4B); dsp20A0B {
+ val:1 = dst4B;
+ dsp20A0B = val;
+ setResultFlags(val);
+}
+
+# (2) STE.W src, dsp:20[A0]
+:STE.W dst4W, dsp20A0W is ((b1_0107=0x3a & b1_size_0=1; b2_0407=0x1) ... & dst4W); dsp20A0W {
+ val:2 = dst4W;
+ dsp20A0W = val;
+ setResultFlags(val);
+}
+
+steA1A0B: "["^A1A0^"]" is A1A0 { ptr:3 = A1A0:3; export *:1 ptr; }
+
+steA1A0W: "["^A1A0^"]" is A1A0 { ptr:3 = A1A0:3; export *:2 ptr; }
+
+# (3) STE.B src, [A1A0]
+:STE.B dst4B, steA1A0B is (steA1A0B & b1_0107=0x3a & b1_size_0=0; b2_0407=0x2) ... & dst4B {
+ val:1 = dst4B;
+ steA1A0B = val;
+ setResultFlags(val);
+}
+
+# (3) STE.W src, [A1A0]
+:STE.W dst4W, steA1A0W is (steA1A0W & b1_0107=0x3a & b1_size_0=1; b2_0407=0x2) ... & dst4W {
+ val:2 = dst4W;
+ steA1A0W = val;
+ setResultFlags(val);
+}
+
+### STNZ ###
+
+:STNZ srcImm8, dst3B_afterDsp8 is (b1_0307=0x1a; srcImm8) ... & $(DST3B_AFTER_DSP8) {
+ if ($(ZERO) != 0) goto inst_next;
+ dst3B_afterDsp8 = srcImm8;
+}
+
+### STZ ###
+
+:STZ srcImm8, dst3B_afterDsp8 is (b1_0307=0x19; srcImm8) ... & $(DST3B_AFTER_DSP8) {
+ if ($(ZERO) == 0) goto inst_next;
+ dst3B_afterDsp8 = srcImm8;
+}
+
+### STZX ###
+skipBytesBeforeImm82: is b1_0007; imm8_dat { } # imm81
+skipBytesBeforeImm82: is b1_d3=0x5; imm16_dat { } # imm81; dsp8
+skipBytesBeforeImm82: is b1_d3=0x6; imm16_dat { } # imm81; dsp8
+skipBytesBeforeImm82: is b1_d3=0x7; imm24_dat { } # imm81; abs16
+
+stzxImm82: "#"^imm8_dat is skipBytesBeforeImm82; imm8_dat { export *[const]:1 imm8_dat; }
+
+:STZX srcImm8, stzxImm82, dst3B_afterDsp8 is (b1_0307=0x1b; srcImm8) ... & $(DST3B_AFTER_DSP8) ... & stzxImm82 {
+ z:1 = $(ZERO);
+ dst3B_afterDsp8 = (z * srcImm8) + (!z * stzxImm82);
+}
+
+### SUB ###
+
+# (1) SUB.B:G #simm, dst
+:SUB^".B:G" srcSimm8, dst4B is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x5) ... & dst4B); srcSimm8 {
+ tmp:1 = dst4B;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) SUB.B:G #simm, Ax
+:SUB^".B:G" srcSimm8, dst4Ax is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x5) & $(DST4AX)); srcSimm8 {
+ tmp:1 = dst4Ax:1;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) SUB.W:G #simm, dst
+:SUB^".W:G" srcSimm16, dst4W is ((b1_0107=0x3b & b1_size_0=1; b2_0407=0x5) ... & dst4W); srcSimm16 {
+ tmp:2 = dst4W;
+ setSubtractFlags(tmp, srcSimm16);
+ tmp = tmp - srcSimm16;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) SUB.B:S #simm, dst
+:SUB^".B:S" srcSimm8, dst3B_afterDsp8 is (b1_0307=0x11; srcSimm8) ... & $(DST3B_AFTER_DSP8) {
+ tmp:1 = dst3B_afterDsp8;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ dst3B_afterDsp8 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) SUB.B:G src, dst
+:SUB^".B:G" src4B, dst4B_afterSrc4 is (b1_0107=0x54 & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ tmp:1 = dst4B_afterSrc4;
+ src:1 = src4B;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst4B_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) SUB.B:G src, Ax
+:SUB^".B:G" src4B, dst4Ax is (b1_0107=0x54 & b1_size_0=0) ... & src4B & $(DST4AX) ... {
+ tmp:1 = dst4Ax:1;
+ src:1 = src4B;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (3) SUB.W:G src, dst
+:SUB^".W:G" src4W, dst4W_afterSrc4 is (b1_0107=0x54 & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ tmp:2 = dst4W_afterSrc4;
+ src:2 = src4W;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst4W_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (4) SUB.B:S src, R0H/R0L
+:SUB^".B:S" dst2B, b1_2_reg8 is (b1_0307=0x5 & b1_2_reg8) ... & dst2B {
+ tmp:1 = b1_2_reg8;
+ src:1 = dst2B;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ b1_2_reg8 = tmp;
+ setResultFlags(tmp);
+}
+
+### TST ###
+
+# (1) TST.B #imm, dst
+:TST.B srcImm8, dst4B is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x0) ... & dst4B); srcImm8 {
+ tmp:1 = dst4B & srcImm8;
+ setResultFlags(tmp);
+}
+
+# (1) TST.W #imm, dst
+:TST.W srcImm16, dst4W is ((b1_0107=0x3b & b1_size_0=1; b2_0407=0x0) ... & dst4W); srcImm16 {
+ tmp:2 = dst4W & srcImm16;
+ setResultFlags(tmp);
+}
+
+# (2) TST.B src, dst
+:TST.B src4B, dst4B_afterSrc4 is (b1_0107=0x40 & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ tmp:1 = dst4B_afterSrc4 & src4B;
+ setResultFlags(tmp);
+}
+
+# (2) TST.W src, dst
+:TST.W src4W, dst4W_afterSrc4 is (b1_0107=0x40 & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ tmp:2 = dst4W_afterSrc4 & src4W;
+ setResultFlags(tmp);
+}
+
+##### UND #####
+# Don't implement this "Undefined" instruction
+# :UND is b1_0007=0xff
+
+### WAIT ###
+
+:WAIT is b1_0007=0x7d; b2_0007=0xf3 {
+ Wait();
+}
+
+### XCHG ###
+
+:XCHG.B b2_s4_reg8, dst4B is (b1_0107=0x3d & b1_size_0=0; b2_0607=0 & b2_s4_reg8) ... & dst4B {
+ tmp:1 = dst4B;
+ dst4B = b2_s4_reg8;
+ b2_s4_reg8 = tmp;
+}
+
+:XCHG.B b2_s4_reg8, dst4Ax is (b1_0107=0x3d & b1_size_0=0; b2_0607=0 & b2_s4_reg8) & $(DST4AX) {
+ tmp:1 = dst4Ax:1;
+ dst4Ax = zext(b2_s4_reg8);
+ b2_s4_reg8 = tmp;
+}
+
+:XCHG.W b2_s4_reg16, dst4W is (b1_0107=0x3d & b1_size_0=1; b2_0607=0 & b2_s4_reg16) ... & dst4W {
+ tmp:2 = dst4W;
+ dst4W = b2_s4_reg16;
+ b2_s4_reg16 = tmp;
+}
+
+### XOR ###
+
+# (1) XOR.B:G #imm, dst
+:XOR^".B:G" srcImm8, dst4B is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x1) ... & dst4B); srcImm8 {
+ tmp:1 = dst4B ^ srcImm8;
+ dst4B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) XOR.B:G #imm, Ax
+:XOR^".B:G" srcImm8, dst4Ax is ((b1_0107=0x3b & b1_size_0=0; b2_0407=0x1) & $(DST4AX)); srcImm8 {
+ tmp:1 = dst4Ax:1 ^ srcImm8;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) XOR.W:G #imm, dst
+:XOR^".W:G" srcImm16, dst4W is ((b1_0107=0x3b & b1_size_0=1; b2_0407=0x1) ... & dst4W); srcImm16 {
+ tmp:2 = dst4W ^ srcImm16;
+ dst4W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) XOR.B:G src, dst
+:XOR^".B:G" src4B, dst4B_afterSrc4 is (b1_0107=0x44 & b1_size_0=0) ... & src4B ... & dst4B_afterSrc4 ... {
+ tmp:1 = dst4B_afterSrc4 ^ src4B;
+ dst4B_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) XOR.B:G src, Ax
+:XOR^".B:G" src4B, dst4Ax is (b1_0107=0x44 & b1_size_0=0) ... & src4B & $(DST4AX) ... {
+ tmp:1 = dst4Ax:1 ^ src4B;
+ dst4Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) XOR.W:G src, dst
+:XOR^".W:G" src4W, dst4W_afterSrc4 is (b1_0107=0x44 & b1_size_0=1) ... & src4W ... & dst4W_afterSrc4 ... {
+ tmp:2 = dst4W_afterSrc4 ^ src4W;
+ dst4W_afterSrc4 = tmp;
+ setResultFlags(tmp);
+}
diff --git a/Ghidra/Processors/M16C/data/languages/M16C_80.cspec b/Ghidra/Processors/M16C/data/languages/M16C_80.cspec
new file mode 100644
index 0000000000..dda14808d1
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/languages/M16C_80.cspec
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/M16C/data/languages/M16C_80.ldefs b/Ghidra/Processors/M16C/data/languages/M16C_80.ldefs
new file mode 100644
index 0000000000..8781217449
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/languages/M16C_80.ldefs
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Renesas M16C/80 16-Bit MicroComputer
+
+
+
+
diff --git a/Ghidra/Processors/M16C/data/languages/M16C_80.pspec b/Ghidra/Processors/M16C/data/languages/M16C_80.pspec
new file mode 100644
index 0000000000..012579c0eb
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/languages/M16C_80.pspec
@@ -0,0 +1,296 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Ghidra/Processors/M16C/data/languages/M16C_80.slaspec b/Ghidra/Processors/M16C/data/languages/M16C_80.slaspec
new file mode 100644
index 0000000000..9acb2b71c4
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/languages/M16C_80.slaspec
@@ -0,0 +1,5050 @@
+#
+# Renesas M16C/80 16-Bit MicroComputer
+#
+
+#
+# Memory Architecture
+#
+define endian=little;
+
+define alignment=1;
+
+define space RAM type=ram_space size=3 default;
+define space register type=register_space size=2;
+
+#
+# General Registers
+#
+define register offset=0x0000 size=2 [
+ R0 R2 R1 R3
+];
+
+define register offset=0x0000 size=1 [
+ R0L R0H _ _ R1L R1H _ _
+];
+
+define register offset=0x0000 size=4 [
+ R2R0 R3R1
+];
+
+define register offset=0x0000 size=6 [
+ R1R2R0
+];
+
+define register offset=0x2000 size=3 [
+ A0 A1
+];
+
+define register offset=0x3000 size=3 [
+ PC # Program Counter
+ SVP # Save PC Register
+ VCT # Vector Register
+ byteIndexOffset # Byte offset for memory (see useByteIndex)
+ bitIndex # Index offset for bit operations (see useBitIndex)
+];
+
+define register offset=0x4000 size=3 [
+ INTB
+];
+
+define register offset=0x4000 size=2 [
+ INTBL INTBH
+];
+
+define register offset=0x5000 size=3 [
+ SP # Stack Pointer (Represents active stack pointer: ISP or USP)
+ FB # Frame Base Register
+ SB # Static Base Register
+ ISP # Interrupt Stack Pointer
+];
+
+define register offset=0x6000 size=2 [
+ FLG # Flag Register
+ SVF # Save Flag Register
+];
+
+@define CARRY "FLG[0,1]"
+@define DEBUG "FLG[1,1]"
+@define ZERO "FLG[2,1]"
+@define SIGN "FLG[3,1]"
+@define REG_BANK "FLG[4,1]"
+@define OVERFLOW "FLG[5,1]"
+@define INTERRUPT "FLG[6,1]"
+@define STACK_SEL "FLG[7,1]"
+@define IPL "FLG[12,3]"
+
+define register offset=0x7000 size=2 [
+ # These are really 1-Byte registers
+ DMD0 # DMA mode register
+ DMD1 # DMA mode register
+];
+
+define register offset=0x8000 size=2 [
+ DCT0 # DMA transfer count register
+ DCT1 # DMA transfer count register
+ DRC0 # DMA transfer count reload register
+ DRC1 # DMA transfer count reload register
+];
+
+define register offset=0x9000 size=3 [
+ DMA0 # DMA memory address register
+ DMA1 # DMA memory address register
+ DSA0 # DMA SFR address register
+ DSA1 # DMA SFR address register
+ DRA0 # DMA memory address reload register
+ DRA1 # DMA memory address reload register
+];
+
+# Define context bits
+define register offset=0xA000 size=4 contextreg;
+
+define context contextreg
+ useBitIndex = (0, 0) noflow # =1 use bitIndex instead of bit specified by instruction
+ useByteIndexOffset = (1, 2) noflow
+ useSrcByteIndexOffset = (1, 1) noflow
+ useDstByteIndexOffset = (2, 2) noflow
+
+ # transient context:
+ phase = (3, 4) # guard for saving off modes before starting instructions
+ indDst = (5, 5) # =1 indirect destination
+ indSrc = (6, 6) # =1 indirect source
+ dstFollowsSrc = (7, 8) # =1 destination add-on data follows 5-bit encoded source add-on data
+ # =2 destination add-on data follows 8-bit data
+;
+
+define token b0(8)
+ b0_0007 = (0,7)
+;
+
+define token b1(8)
+ b1_s5 = (4,6)
+ b1_s5_4 = (6,6)
+ b1_d5 = (1,3)
+ b1_d5_4 = (3,3)
+ b1_d2 = (4,5)
+ b1_d1_regAx = (0,0)
+ b1_size_5 = (5,5)
+ b1_size_4 = (4,4)
+ b1_size_0 = (0,0)
+ b1_0707 = (7,7)
+ b1_0607 = (6,7)
+ b1_0507 = (5,7)
+ b1_0505 = (5,5)
+ b1_0407 = (4,7)
+ b1_0406 = (4,6)
+ b1_0405 = (4,5)
+ b1_0104 = (1,4)
+ b1_0103 = (1,3)
+ b1_0007 = (0,7)
+ b1_0000 = (0,0)
+;
+
+define token b2(8)
+ b2_d5_reg8 = (6,7)
+ b2_s5_reg8 = (4,5)
+ b2_d5_reg16 = (6,7)
+ b2_s5_reg16 = (4,5)
+ b2_d5_reg32 = (6,6) # only d0 used to select double register
+ b2_s5_reg32 = (4,4) # only s0 used to select double register
+ b2_d5_regAxSF = (6,7) # selects A0, A1, SB or FB
+ b2_s5_regAxSF = (4,5) # selects A0, A1, SB or FB
+ b2_d5_regAx = (6,6)
+ b2_s5_regAx = (4,4)
+ b2_d5 = (6,7)
+ b2_s5 = (4,5)
+ b2_d5_1 = (7,7)
+ b2_d5_0 = (6,6)
+ b2_s5_1 = (5,5)
+ b2_s5_0 = (4,4)
+ b2_0707 = (7,7)
+ b2_0606 = (6,6)
+ b2_0405 = (4,5)
+ b2_0307 = (3,7)
+ b2_0305 = (3,5)
+ b2_0105 = (1,5)
+ b2_0102 = (1,2)
+ b2_0101 = (1,1)
+ b2_0007 = (0,7)
+ b2_0005 = (0,5)
+ b2_0003 = (0,3)
+ b2_0002 = (0,2)
+ b2_simm4 = (0,3) signed
+ b2_shiftSign = (3,3)
+ b2_bit = (0,2)
+ b2_reg8 = (0,2)
+ b2_reg16 = (0,2)
+ b2_creg16 = (0,2)
+ b2_creg24 = (0,2)
+ b2_dreg24 = (0,2)
+ b2_reg32 = (0,0)
+ b2_regAx = (0,0)
+;
+
+define token imm8(8)
+ simm8_dat = (0,7) signed
+ imm8_dat = (0,7)
+ imm6_dat = (2,7)
+ cnd_dat = (0,3)
+ imm8_0001 = (0,1)
+ regBit7 = (7,7)
+ regBit6 = (6,6)
+ regBit5 = (5,5)
+ regBit4 = (4,4)
+ regBit3 = (3,3)
+ regBit2 = (2,2)
+ regBit1 = (1,1)
+ regBit0 = (0,0)
+;
+
+define token imm16(16)
+ simm16_dat = (0,15) signed
+ imm16_dat = (0,15)
+;
+
+define token imm24(24)
+ simm24_dat = (0,23) signed
+ imm24_dat = (0,23)
+;
+
+define token imm32(32)
+ simm32_dat = (0,31) signed
+ imm32_dat = (0,31)
+;
+
+attach variables [ b2_s5_reg32 b2_d5_reg32 ] [ R2R0 R3R1 ];
+attach variables [ b2_s5_reg16 b2_d5_reg16 ] [ R2 R3 R0 R1 ];
+attach variables [ b2_s5_reg8 b2_d5_reg8 ] [ R0H R1H R0L R1L ];
+attach variables [ b2_s5_regAx b2_d5_regAx b1_d1_regAx b2_regAx ] [ A0 A1 ];
+attach variables [ b2_s5_regAxSF b2_d5_regAxSF ] [ A0 A1 SB FB ];
+attach variables [ b2_creg16 ] [ DCT0 DCT1 FLG SVF DRC0 DRC1 DMD0 DMD1 ];
+attach variables [ b2_creg24 ] [ INTB SP SB FB SVP VCT _ ISP ];
+attach variables [ b2_dreg24 ] [ _ _ DMA0 DMA1 DRA0 DRA1 DSA0 DSA1 ];
+attach variables [ b2_reg32 ] [ R2R0 R3R1 ];
+
+# XCHG register attach
+attach variables [ b2_reg8 ] [ R0L R1L _ _ R0H R1H _ _ ];
+attach variables [ b2_reg16 ] [ R0 R1 _ _ R2 R3 _ _ ];
+
+#
+# PCode Op
+#
+define pcodeop Break; # BRK
+define pcodeop Break2; # BRK2
+define pcodeop DecimalAdd; # DADD
+define pcodeop DecimalAddWithCarry; # DADC
+define pcodeop DecimalSubtractWithBorrow; # DSBB
+define pcodeop DecimalSubtract; # DSUB
+define pcodeop Wait; # WAIT
+
+#
+# FLAG MACROS...
+#
+# Set zero and sign flags from result
+macro setResultFlags(result) {
+ $(SIGN) = (result s< 0x0);
+ $(ZERO) = (result == 0x0);
+}
+
+# Set carry and overflow flags for addition
+macro setAdd3Flags(v1, v2, v3) {
+ local add13 = v1 + v3;
+ $(CARRY) = carry(v1,v3) || carry(v2,add13);
+ $(OVERFLOW) = scarry(v1,v3) || scarry(v2,add13);
+}
+
+# Set carry and overflow flags for addition
+macro setAddFlags(v1, v2) {
+ $(CARRY) = carry(v1, v2);
+ $(OVERFLOW) = scarry(v1, v2);
+}
+
+# Set overflow flags for subtraction of op3,op2 from op1 (op1-op2-op3)
+macro setSubtract3Flags(v1, v2, v3) {
+ local add12 = v1 - v2;
+ $(CARRY) = (v1 >= v2) || (add12 >= v3);
+ $(OVERFLOW) = sborrow(v1, v2) || sborrow(add12, v3);
+}
+
+# Set overflow flags for subtraction of op2 from op1 (op1-op2)
+macro setSubtractFlags(v1, v2) {
+ $(CARRY) = (v1 s>= v2);
+ $(OVERFLOW) = sborrow(v1, v2);
+}
+
+macro push1(val) {
+ SP = SP - 2;
+ *:1 SP = val;
+}
+
+macro push2(val) {
+ SP = SP - 2;
+ *:2 SP = val;
+}
+
+macro push3(val) {
+ SP = SP - 4;
+ *:3 SP = val;
+}
+
+macro push4(val) {
+ SP = SP - 4;
+ *:4 SP = val;
+}
+
+macro pop1(val) {
+ val = *:1 SP;
+ SP = SP + 2;
+}
+
+macro pop2(val) {
+ val = *:2 SP;
+ SP = SP + 2;
+}
+
+macro pop3(val) {
+ val = *:3 SP;
+ SP = SP + 4;
+}
+
+macro pop4(val) {
+ val = *:4 SP;
+ SP = SP + 4;
+}
+
+:^instruction is phase=0 & b0_0007 & instruction [ phase=1; ] {}
+:^instruction is phase=0 & b0_0007=0x09; instruction [ indDst=1; phase=1; ] {} # indirect destination prefix
+:^instruction is phase=0 & b0_0007=0x41; instruction [ indSrc=1; phase=1; ] {} # indirect source prefix
+:^instruction is phase=0 & b0_0007=0x49; instruction [ indDst=1; indSrc=1; phase=1; ] {} # indirect source and destination prefix
+
+#
+# Source operand location data
+#
+# Obtain additional source byte offset as a result of an INDEX instruction (flagged by useSrcByteIndexOffset context bit)
+srcIndexOffset: is useSrcByteIndexOffset=0 { export 0:3; }
+srcIndexOffset: is useSrcByteIndexOffset=1 { export byteIndexOffset; }
+
+# Obtain base offset displacement for [AX | SB | FB] - AX and SB uses unsigned displacements, FB uses signed displacement
+src5dsp8: imm8_dat^":8" is b1_s5; b2_s5; imm8_dat { export *[const]:3 imm8_dat; }
+src5dsp8: simm8_dat^":8" is b1_s5; b2_s5=0x3; simm8_dat { export *[const]:3 simm8_dat; }
+
+src5dsp16: imm16_dat^":16" is b1_s5; b2_s5; imm16_dat { export *[const]:3 imm16_dat; }
+src5dsp16: simm16_dat^":16" is b1_s5; b2_s5=0x3; simm16_dat { export *[const]:3 simm16_dat; }
+
+src5dsp24: imm24_dat^":24" is b1_s5; b2_s5; imm24_dat { export *[const]:3 imm24_dat; }
+src5dsp24: simm24_dat^":24" is b1_s5; b2_s5=0x3; simm24_dat { export *[const]:3 simm24_dat; }
+
+# src5... Handle 5-bit encoded Source specified by b1_s(3-bits) and b2_s(2-bits)
+# Variable length pattern starting at instruction byte b1
+# associated src5 add-on data immediately follows instruction byte b2
+# abs16 and abs24 cases are broken out differently to facilitate export of constant addresses in certain cases
+# 1-Byte source value/location specified by 5-bit encoding (b1_d5/b2_d5) - supports indirect prefix and byteIndexOffset
+src5B: b2_s5_reg8 is b1_s5=0x4; b2_s5_reg8 { export b2_s5_reg8; } # Rx
+src5B: b2_s5_regAx is b1_s5=0x0; b2_s5_1=1 & b2_s5_regAx { tmp:1 = b2_s5_regAx:1; export tmp; } # Ax
+src5B: [b2_s5_regAx] is indSrc=1 & b1_s5=0x0; b2_s5_1=1 & b2_s5_regAx { ptr:3 = b2_s5_regAx; export *:1 ptr; } # [Ax] - w/ indirect prefix
+src5B: [b2_s5_regAx] is srcIndexOffset & b1_s5=0x0; b2_s5_1=0 & b2_s5_regAx { ptr:3 = b2_s5_regAx + srcIndexOffset; export *:1 ptr; } # [Ax]
+src5B: [[b2_s5_regAx]] is indSrc=1 & srcIndexOffset & b1_s5=0x0; b2_s5_1=0 & b2_s5_regAx { ptr:3 = b2_s5_regAx + srcIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [[Ax]]
+src5B: src5dsp8^[b2_s5_regAxSF] is (srcIndexOffset & b1_s5=0x1; b2_s5_regAxSF) ... & src5dsp8 { ptr:3 = b2_s5_regAxSF + src5dsp8 + srcIndexOffset; export *:1 ptr; } # dsp:8[Ax|SB|FB]
+src5B: [src5dsp8^[b2_s5_regAxSF]] is (indSrc=1 & srcIndexOffset & b1_s5=0x1; b2_s5_regAxSF) ... & src5dsp8 { ptr:3 = b2_s5_regAxSF + src5dsp8 + srcIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [dsp:8[Ax|SB|FB]]
+src5B: src5dsp16^[b2_s5_regAxSF] is (srcIndexOffset & b1_s5=0x2; b2_s5_regAxSF) ... & src5dsp16 { ptr:3 = b2_s5_regAxSF + src5dsp16 + srcIndexOffset; export *:1 ptr; } # dsp:16[Ax|SB|FB]
+src5B: [src5dsp16^[b2_s5_regAxSF]] is (indSrc=1 & srcIndexOffset & b1_s5=0x2; b2_s5_regAxSF) ... & src5dsp16 { ptr:3 = b2_s5_regAxSF + src5dsp16 + srcIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [dsp:16[Ax|SB|FB]]
+src5B: src5dsp24^[b2_s5_regAx] is (srcIndexOffset & b1_s5=0x3; b2_s5_1=0 & b2_s5_regAx) ... & src5dsp24 { ptr:3 = b2_s5_regAx + src5dsp24 + srcIndexOffset; export *:1 ptr; } # dsp:24[Ax]
+src5B: [src5dsp24^[b2_s5_regAx]] is (indSrc=1 & srcIndexOffset & b1_s5=0x3; b2_s5_1=0 & b2_s5_regAx) ... & src5dsp24 { ptr:3 = b2_s5_regAx + src5dsp24 + srcIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [dsp:24[Ax]]
+src5B: imm16_dat is indSrc=0 & useSrcByteIndexOffset=1 & b1_s5=0x3; b2_s5=0x3; imm16_dat { ptr:3 = imm16_dat + byteIndexOffset; export *:1 ptr; } # abs16 (+byteIndexOffset)
+src5B: imm16_dat is indSrc=0 & b1_s5=0x3; b2_s5=0x3; imm16_dat { export *:1 imm16_dat; } # abs16 (special constant address case)
+src5B: [imm16_dat] is indSrc=1 & srcIndexOffset & b1_s5=0x3; b2_s5=0x3; imm16_dat { ptr:3 = imm16_dat + srcIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [abs16]
+src5B: imm24_dat is indSrc=0 & useSrcByteIndexOffset=1 & b1_s5=0x3; b2_s5=0x2; imm24_dat { ptr:3 = imm24_dat + byteIndexOffset; export *:1 ptr; } # abs24 (+byteIndexOffset)
+src5B: imm24_dat is indSrc=0 & b1_s5=0x3; b2_s5=0x2; imm24_dat { export *:1 imm24_dat; } # abs24 (special constant address case)
+src5B: [imm24_dat] is indSrc=1 & srcIndexOffset & b1_s5=0x3; b2_s5=0x2; imm24_dat { ptr:3 = imm24_dat + srcIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [abs24]
+
+# 2-Byte source value/location specified by 5-bit encoding (b1_d5/b2_d5) - supports indirect prefix and byteIndexOffset
+src5W: b2_s5_reg16 is b1_s5=0x4; b2_s5_reg16 { export b2_s5_reg16; } # Rx
+src5W: b2_s5_regAx is b1_s5=0x0; b2_s5_1=1 & b2_s5_regAx { tmp:2 = b2_s5_regAx:2; export tmp; } # Ax
+src5W: [b2_s5_regAx] is indSrc=1 & b1_s5=0x0; b2_s5_1=1 & b2_s5_regAx { ptr:3 = b2_s5_regAx; export *:2 ptr; } # [Ax] - w/ indirect prefix
+src5W: [b2_s5_regAx] is srcIndexOffset & b1_s5=0x0; b2_s5_1=0 & b2_s5_regAx { ptr:3 = b2_s5_regAx + srcIndexOffset; export *:2 ptr; } # [Ax]
+src5W: [[b2_s5_regAx]] is indSrc=1 & srcIndexOffset & b1_s5=0x0; b2_s5_1=0 & b2_s5_regAx { ptr:3 = b2_s5_regAx + srcIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [[Ax]]
+src5W: src5dsp8^[b2_s5_regAxSF] is (srcIndexOffset & b1_s5=0x1; b2_s5_regAxSF) ... & src5dsp8 { ptr:3 = b2_s5_regAxSF + src5dsp8 + srcIndexOffset; export *:2 ptr; } # dsp:8[Ax|SB|FB]
+src5W: [src5dsp8^[b2_s5_regAxSF]] is (indSrc=1 & srcIndexOffset & b1_s5=0x1; b2_s5_regAxSF) ... & src5dsp8 { ptr:3 = b2_s5_regAxSF + src5dsp8 + srcIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [dsp:8[Ax|SB|FB]]
+src5W: src5dsp16^[b2_s5_regAxSF] is (srcIndexOffset & b1_s5=0x2; b2_s5_regAxSF) ... & src5dsp16 { ptr:3 = b2_s5_regAxSF + src5dsp16 + srcIndexOffset; export *:2 ptr; } # dsp:16[Ax|SB|FB]
+src5W: [src5dsp16^[b2_s5_regAxSF]] is (indSrc=1 & srcIndexOffset & b1_s5=0x2; b2_s5_regAxSF) ... & src5dsp16 { ptr:3 = b2_s5_regAxSF + src5dsp16 + srcIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [dsp:16[Ax|SB|FB]]
+src5W: src5dsp24^[b2_s5_regAx] is (srcIndexOffset & b1_s5=0x3; b2_s5_1=0 & b2_s5_regAx) ... & src5dsp24 { ptr:3 = b2_s5_regAx + src5dsp24 + srcIndexOffset; export *:2 ptr; } # dsp:24[Ax]
+src5W: [src5dsp24^[b2_s5_regAx]] is (indSrc=1 & srcIndexOffset & b1_s5=0x3; b2_s5_1=0 & b2_s5_regAx) ... & src5dsp24 { ptr:3 = b2_s5_regAx + src5dsp24 + srcIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [dsp:24[Ax]]
+src5W: imm16_dat is indSrc=0 & useSrcByteIndexOffset=1 & b1_s5=0x3; b2_s5=0x3; imm16_dat { ptr:3 = imm16_dat + byteIndexOffset; export *:2 ptr; } # abs16 (+byteIndexOffset)
+src5W: imm16_dat is indSrc=0 & b1_s5=0x3; b2_s5=0x3; imm16_dat { export *:2 imm16_dat; } # abs16 (special constant address case)
+src5W: [imm16_dat] is indSrc=1 & srcIndexOffset & b1_s5=0x3; b2_s5=0x3; imm16_dat { ptr:3 = imm16_dat + srcIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [abs16]
+src5W: imm24_dat is indSrc=0 & useSrcByteIndexOffset=1 & b1_s5=0x3; b2_s5=0x2; imm24_dat { ptr:3 = imm24_dat + byteIndexOffset; export *:2 ptr; } # abs24 (+byteIndexOffset)
+src5W: imm24_dat is indSrc=0 & b1_s5=0x3; b2_s5=0x2; imm24_dat { export *:2 imm24_dat; } # abs24 (special constant address case)
+src5W: [imm24_dat] is indSrc=1 & srcIndexOffset & b1_s5=0x3; b2_s5=0x2; imm24_dat { ptr:3 = imm24_dat + srcIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [abs24]
+
+# 4-Byte source value/location specified by 5-bit encoding (b1_d5/b2_d5) - supports indirect prefix and byteIndexOffset
+src5L: b2_s5_reg32 is b1_s5=0x4; b2_s5_1=1 & b2_s5_reg32 { export b2_s5_reg32; } # Rx
+src5L: b2_s5_regAx is b1_s5=0x0; b2_s5_1=1 & b2_s5_regAx { tmp:4 = zext(b2_s5_regAx); export tmp; } # Ax
+src5L: [b2_s5_regAx] is indSrc=1 & b1_s5=0x0; b2_s5_1=1 & b2_s5_regAx { ptr:3 = b2_s5_regAx; export *:4 ptr; } # [Ax] - w/ indirect prefix
+src5L: [b2_s5_regAx] is srcIndexOffset & b1_s5=0x0; b2_s5_1=0 & b2_s5_regAx { ptr:3 = b2_s5_regAx + srcIndexOffset; export *:4 ptr; } # [Ax]
+src5L: [[b2_s5_regAx]] is indSrc=1 & srcIndexOffset & b1_s5=0x0; b2_s5_1=0 & b2_s5_regAx { ptr:3 = b2_s5_regAx + srcIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [[Ax]]
+src5L: src5dsp8^[b2_s5_regAxSF] is (srcIndexOffset & b1_s5=0x1; b2_s5_regAxSF) ... & src5dsp8 { ptr:3 = b2_s5_regAxSF + src5dsp8 + srcIndexOffset; export *:4 ptr; } # dsp:8[Ax|SB|FB]
+src5L: [src5dsp8^[b2_s5_regAxSF]] is (indSrc=1 & srcIndexOffset & b1_s5=0x1; b2_s5_regAxSF) ... & src5dsp8 { ptr:3 = b2_s5_regAxSF + src5dsp8 + srcIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [dsp:8[Ax|SB|FB]]
+src5L: src5dsp16^[b2_s5_regAxSF] is (srcIndexOffset & b1_s5=0x2; b2_s5_regAxSF) ... & src5dsp16 { ptr:3 = b2_s5_regAxSF + src5dsp16 + srcIndexOffset; export *:4 ptr; } # dsp:16[Ax|SB|FB]
+src5L: [src5dsp16^[b2_s5_regAxSF]] is (indSrc=1 & srcIndexOffset & b1_s5=0x2; b2_s5_regAxSF) ... & src5dsp16 { ptr:3 = b2_s5_regAxSF + src5dsp16 + srcIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [dsp:16[Ax|SB|FB]]
+src5L: src5dsp24^[b2_s5_regAx] is (srcIndexOffset & b1_s5=0x3; b2_s5_1=0 & b2_s5_regAx) ... & src5dsp24 { ptr:3 = b2_s5_regAx + src5dsp24 + srcIndexOffset; export *:4 ptr; } # dsp:24[Ax]
+src5L: [src5dsp24^[b2_s5_regAx]] is (indSrc=1 & srcIndexOffset & b1_s5=0x3; b2_s5_1=0 & b2_s5_regAx) ... & src5dsp24 { ptr:3 = b2_s5_regAx + src5dsp24 + srcIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [dsp:24[Ax]]
+src5L: imm16_dat is indSrc=0 & useSrcByteIndexOffset=1 & b1_s5=0x3; b2_s5=0x3; imm16_dat { ptr:3 = imm16_dat + byteIndexOffset; export *:4 ptr; } # abs16 (+byteIndexOffset)
+src5L: imm16_dat is indSrc=0 & b1_s5=0x3; b2_s5=0x3; imm16_dat { export *:4 imm16_dat; } # abs16 (special constant address case)
+src5L: [imm16_dat] is indSrc=1 & srcIndexOffset & b1_s5=0x3; b2_s5=0x3; imm16_dat { ptr:3 = imm16_dat + srcIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [abs16]
+src5L: imm24_dat is indSrc=0 & useSrcByteIndexOffset=1 & b1_s5=0x3; b2_s5=0x2; imm24_dat { ptr:3 = imm24_dat + byteIndexOffset; export *:4 ptr; } # abs24 (+byteIndexOffset)
+src5L: imm24_dat is indSrc=0 & b1_s5=0x3; b2_s5=0x2; imm24_dat { export *:4 imm24_dat; } # abs24 (special constant address case)
+src5L: [imm24_dat] is indSrc=1 & srcIndexOffset & b1_s5=0x3; b2_s5=0x2; imm24_dat { ptr:3 = imm24_dat + srcIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [abs24]
+
+#
+# The following macros are used to elliminate illegal bit patterns when using src5
+# These should be used by constructor pattern matching instead of the corresponding src5 subconstructor
+#
+@define SRC5B "((b1_s5=4 | b1_s5_4=0) ... & src5B)"
+@define SRC5W "((b1_s5=4 | b1_s5_4=0) ... & src5W)"
+@define SRC5L "((b1_s5=4 | b1_s5_4=0) ... & src5L)"
+
+#
+# Destination operand location data (may also be used as a source in certain cases)
+#
+# Skip instruction and source add-on bytes which occur before destination add-on bytes
+# Starting position is at b1
+skipBytesBeforeDst5: is b1_s5; b2_s5 { }
+skipBytesBeforeDst5: is dstFollowsSrc=1 & b1_s5=1; b2_s5; imm8_dat { } # src5: dsp8
+skipBytesBeforeDst5: is dstFollowsSrc=1 & b1_s5=2; b2_s5; imm16_dat { } # src5: dsp16
+skipBytesBeforeDst5: is dstFollowsSrc=1 & b1_s5=3; b2_s5; imm24_dat { } # src5: dsp24/abs24
+skipBytesBeforeDst5: is dstFollowsSrc=1 & b1_s5=3; b2_s5=3; imm16_dat { } # src5: abs16
+skipBytesBeforeDst5: is dstFollowsSrc=2 & b1_d5; b2_d5; imm8_dat { } # dsp8
+
+# Obtain additional destination byte offset as a result of an INDEX instruction (flagged by useDstByteIndexOffset context bit)
+dstIndexOffset: is useDstByteIndexOffset=0 { export 0:3; }
+dstIndexOffset: is useDstByteIndexOffset=1 { export byteIndexOffset; }
+
+# Obtain base offset displacement for [AX | SB | FB] - AX and SB uses unsigned displacements, FB uses signed displacement
+dst5dsp8: imm8_dat^":8" is (skipBytesBeforeDst5; imm8_dat) { export *[const]:3 imm8_dat; }
+dst5dsp8: simm8_dat^":8" is (b1_d5; b2_d5=0x3) ... & (skipBytesBeforeDst5; simm8_dat) { export *[const]:3 simm8_dat; }
+dst5dsp16: imm16_dat^":16" is (skipBytesBeforeDst5; imm16_dat) { export *[const]:3 imm16_dat; }
+dst5dsp16: simm16_dat^":16" is (b1_d5; b2_d5=0x3) ... & (skipBytesBeforeDst5; simm16_dat) { export *[const]:3 simm16_dat; }
+dst5dsp24: imm24_dat^":24" is (skipBytesBeforeDst5; imm24_dat) { export *[const]:3 imm24_dat; }
+
+# dst5... Handle 5-bit encoded Destination specified by b1_d5(3-bits) and b2_d5(2-bits)
+# Ax direct case is read-only! Instruction must use dst5Ax for write/update case
+# Variable length pattern starting at instruction byte b1
+# abs16 and abs24 cases are broken out differently to facilitate export of constant addresses in certain cases
+# 1-Byte destination value/location specified by 5-bit encoding (b1_d5/b2_d5) - supports indirect prefix and byteIndexOffset
+dst5B: b2_d5_reg8 is b1_d5=0x4; b2_d5_reg8 { export b2_d5_reg8; } # Rx
+dst5B: b2_d5_regAx is b1_d5=0x0; b2_d5_1=1 & b2_d5_regAx { tmp:1 = b2_d5_regAx:1; export tmp; } # Ax - read-only use !
+dst5B: [b2_d5_regAx] is indDst=1 & b1_d5=0x0; b2_d5_1=1 & b2_d5_regAx { ptr:3 = b2_d5_regAx; export *:1 ptr; } # [Ax] - w/ indirect prefix
+dst5B: [b2_d5_regAx] is dstIndexOffset & b1_d5=0x0; b2_d5_1=0 & b2_d5_regAx { ptr:3 = b2_d5_regAx + dstIndexOffset; export *:1 ptr; } # [Ax]
+dst5B: [[b2_d5_regAx]] is indDst=1 & dstIndexOffset & b1_d5=0x0; b2_d5_1=0 & b2_d5_regAx { ptr:3 = b2_d5_regAx + dstIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [[Ax]]
+dst5B: dst5dsp8^[b2_d5_regAxSF] is (dstIndexOffset & b1_d5=0x1; b2_d5_regAxSF) ... & dst5dsp8 { ptr:3 = b2_d5_regAxSF + dst5dsp8 + dstIndexOffset; export *:1 ptr; } # dsp:8[Ax|SB|FB]
+dst5B: [dst5dsp8^[b2_d5_regAxSF]] is (indDst=1 & dstIndexOffset & b1_d5=0x1; b2_d5_regAxSF) ... & dst5dsp8 { ptr:3 = b2_d5_regAxSF + dst5dsp8 + dstIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [dsp:8[Ax|SB|FB]]
+dst5B: dst5dsp16^[b2_d5_regAxSF] is (dstIndexOffset & b1_d5=0x2; b2_d5_regAxSF) ... & dst5dsp16 { ptr:3 = b2_d5_regAxSF + dst5dsp16 + dstIndexOffset; export *:1 ptr; } # dsp:16[Ax|SB|FB]
+dst5B: [dst5dsp16^[b2_d5_regAxSF]] is (indDst=1 & dstIndexOffset & b1_d5=0x2; b2_d5_regAxSF) ... & dst5dsp16 { ptr:3 = b2_d5_regAxSF + dst5dsp16 + dstIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [dsp:16[Ax|SB|FB]]
+dst5B: dst5dsp24^[b2_d5_regAx] is (dstIndexOffset & b1_d5=0x3; b2_d5_1=0 & b2_d5_regAx) ... & dst5dsp24 { ptr:3 = b2_d5_regAx + dst5dsp24 + dstIndexOffset; export *:1 ptr; } # dsp:24[Ax]
+dst5B: [dst5dsp24^[b2_d5_regAx]] is (indDst=1 & dstIndexOffset & b1_d5=0x3; b2_d5_1=0 & b2_d5_regAx) ... & dst5dsp24 { ptr:3 = b2_d5_regAx + dst5dsp24 + dstIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [dsp:24[Ax]]
+dst5B: imm16_dat is (indDst=0 & useDstByteIndexOffset=1 & b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { ptr:3 = imm16_dat + byteIndexOffset; export *:1 ptr; } # abs16 (+byteIndexOffset)
+dst5B: imm16_dat is (indDst=0 & b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { export *:1 imm16_dat; } # abs16 (special constant address case)
+dst5B: [imm16_dat] is (indDst=1 & dstIndexOffset & b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { ptr:3 = imm16_dat + dstIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [abs16]
+dst5B: imm24_dat is (indDst=0 & useDstByteIndexOffset=1 & b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { ptr:3 = imm24_dat + byteIndexOffset; export *:1 ptr; } # abs24
+dst5B: imm24_dat is (indDst=0 & b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { export *:1 imm24_dat; } # abs24 (special constant address case)
+dst5B: [imm24_dat] is (indDst=1 & dstIndexOffset & b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { ptr:3 = imm24_dat + dstIndexOffset; ptr = *:3 ptr; export *:1 ptr; } # [abs24]
+
+# 2-Byte destination value/location specified by 5-bit encoding (b1_d5/b2_d5) - supports indirect prefix and byteIndexOffset
+dst5W: b2_d5_reg16 is b1_d5=0x4; b2_d5_reg16 { export b2_d5_reg16; } # Rx
+dst5W: b2_d5_regAx is b1_d5=0x0; b2_d5_1=1 & b2_d5_regAx { tmp:2 = b2_d5_regAx:2; export tmp; } # Ax - read-only use !
+dst5W: [b2_d5_regAx] is indDst=1 & b1_d5=0x0; b2_d5_1=1 & b2_d5_regAx { ptr:3 = b2_d5_regAx; export *:2 ptr; } # [Ax] - w/ indirect prefix
+dst5W: [b2_d5_regAx] is dstIndexOffset & b1_d5=0x0; b2_d5_1=0 & b2_d5_regAx { ptr:3 = b2_d5_regAx + dstIndexOffset; export *:2 ptr; } # [Ax]
+dst5W: [[b2_d5_regAx]] is indDst=1 & dstIndexOffset & b1_d5=0x0; b2_d5_1=0 & b2_d5_regAx { ptr:3 = b2_d5_regAx + dstIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [[Ax]]
+dst5W: dst5dsp8^[b2_d5_regAxSF] is (dstIndexOffset & b1_d5=0x1; b2_d5_regAxSF) ... & dst5dsp8 { ptr:3 = b2_d5_regAxSF + dst5dsp8 + dstIndexOffset; export *:2 ptr; } # dsp:8[Ax|SB|FB]
+dst5W: [dst5dsp8^[b2_d5_regAxSF]] is (indDst=1 & dstIndexOffset & b1_d5=0x1; b2_d5_regAxSF) ... & dst5dsp8 { ptr:3 = b2_d5_regAxSF + dst5dsp8 + dstIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [dsp:8[Ax|SB|FB]]
+dst5W: dst5dsp16^[b2_d5_regAxSF] is (dstIndexOffset & b1_d5=0x2; b2_d5_regAxSF) ... & dst5dsp16 { ptr:3 = b2_d5_regAxSF + dst5dsp16 + dstIndexOffset; export *:2 ptr; } # dsp:16[Ax|SB|FB]
+dst5W: [dst5dsp16^[b2_d5_regAxSF]] is (indDst=1 & dstIndexOffset & b1_d5=0x2; b2_d5_regAxSF) ... & dst5dsp16 { ptr:3 = b2_d5_regAxSF + dst5dsp16 + dstIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [dsp:16[Ax|SB|FB]]
+dst5W: dst5dsp24^[b2_d5_regAx] is (dstIndexOffset & b1_d5=0x3; b2_d5_1=0 & b2_d5_regAx) ... & dst5dsp24 { ptr:3 = b2_d5_regAx + dst5dsp24 + dstIndexOffset; export *:2 ptr; } # dsp:24[Ax]
+dst5W: [dst5dsp24^[b2_d5_regAx]] is (indDst=1 & dstIndexOffset & b1_d5=0x3; b2_d5_1=0 & b2_d5_regAx) ... & dst5dsp24 { ptr:3 = b2_d5_regAx + dst5dsp24 + dstIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [dsp:24[Ax]]
+dst5W: imm16_dat is (indDst=0 & useDstByteIndexOffset=1 & b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { ptr:3 = imm16_dat + byteIndexOffset; export *:2 ptr; } # abs16 (+byteIndexOffset)
+dst5W: imm16_dat is (indDst=0 & b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { export *:2 imm16_dat; } # abs16 (special constant address case)
+dst5W: [imm16_dat] is (indDst=1 & dstIndexOffset & b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { ptr:3 = imm16_dat + dstIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [abs16]
+dst5W: imm24_dat is (indDst=0 & useDstByteIndexOffset=1 & b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { ptr:3 = imm24_dat + byteIndexOffset; export *:2 ptr; } # abs24
+dst5W: imm24_dat is (indDst=0 & b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { export *:2 imm24_dat; } # abs24 (special constant address case)
+dst5W: [imm24_dat] is (indDst=1 & dstIndexOffset & b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { ptr:3 = imm24_dat + dstIndexOffset; ptr = *:3 ptr; export *:2 ptr; } # [abs24]
+
+# 4-Byte destination value/location specified by 5-bit encoding (b1_d5/b2_d5) - supports indirect prefix and byteIndexOffset
+dst5L: b2_d5_reg32 is b1_d5=0x4; b2_d5_1=1 & b2_d5_reg32 { export b2_d5_reg32; } # Rx
+dst5L: b2_d5_regAx is b1_d5=0x0; b2_d5_1=1 & b2_d5_regAx { tmp:4 = zext(b2_d5_regAx); export tmp; } # Ax - read-only use !
+dst5L: [b2_d5_regAx] is indDst=1 & b1_d5=0x0; b2_d5_1=1 & b2_d5_regAx { ptr:3 = b2_d5_regAx; export *:4 ptr; } # [Ax] - w/ indirect prefix
+dst5L: [b2_d5_regAx] is dstIndexOffset & b1_d5=0x0; b2_d5_1=0 & b2_d5_regAx { ptr:3 = b2_d5_regAx + dstIndexOffset; export *:4 ptr; } # [Ax]
+dst5L: [[b2_d5_regAx]] is indDst=1 & dstIndexOffset & b1_d5=0x0; b2_d5_1=0 & b2_d5_regAx { ptr:3 = b2_d5_regAx + dstIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [[Ax]]
+dst5L: dst5dsp8^[b2_d5_regAxSF] is (dstIndexOffset & b1_d5=0x1; b2_d5_regAxSF) ... & dst5dsp8 { ptr:3 = b2_d5_regAxSF + dst5dsp8 + dstIndexOffset; export *:4 ptr; } # dsp:8[Ax|SB|FB]
+dst5L: [dst5dsp8^[b2_d5_regAxSF]] is (indDst=1 & dstIndexOffset & b1_d5=0x1; b2_d5_regAxSF) ... & dst5dsp8 { ptr:3 = b2_d5_regAxSF + dst5dsp8 + dstIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [dsp:8[Ax|SB|FB]]
+dst5L: dst5dsp16^[b2_d5_regAxSF] is (dstIndexOffset & b1_d5=0x2; b2_d5_regAxSF) ... & dst5dsp16 { ptr:3 = b2_d5_regAxSF + dst5dsp16 + dstIndexOffset; export *:4 ptr; } # dsp:16[Ax|SB|FB]
+dst5L: [dst5dsp16^[b2_d5_regAxSF]] is (indDst=1 & dstIndexOffset & b1_d5=0x2; b2_d5_regAxSF) ... & dst5dsp16 { ptr:3 = b2_d5_regAxSF + dst5dsp16 + dstIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [dsp:16[Ax|SB|FB]]
+dst5L: dst5dsp24^[b2_d5_regAx] is (dstIndexOffset & b1_d5=0x3; b2_d5_1=0 & b2_d5_regAx) ... & dst5dsp24 { ptr:3 = b2_d5_regAx + dst5dsp24 + dstIndexOffset; export *:4 ptr; } # dsp:24[Ax]
+dst5L: [dst5dsp24^[b2_d5_regAx]] is (indDst=1 & dstIndexOffset & b1_d5=0x3; b2_d5_1=0 & b2_d5_regAx) ... & dst5dsp24 { ptr:3 = b2_d5_regAx + dst5dsp24 + dstIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [dsp:24[Ax]]
+dst5L: imm16_dat is (indDst=0 & useDstByteIndexOffset=1 & b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { ptr:3 = imm16_dat + byteIndexOffset; export *:4 ptr; } # abs16 (+byteIndexOffset)
+dst5L: imm16_dat is (indDst=0 & b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { export *:4 imm16_dat; } # abs16 (special constant address case)
+dst5L: [imm16_dat] is (indDst=1 & dstIndexOffset & b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { ptr:3 = imm16_dat + dstIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [abs16]
+dst5L: imm24_dat is (indDst=0 & useDstByteIndexOffset=1 & b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { ptr:3 = imm24_dat + byteIndexOffset; export *:4 ptr; } # abs24
+dst5L: imm24_dat is (indDst=0 & b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { export *:4 imm24_dat; } # abs24 (special constant address case)
+dst5L: [imm24_dat] is (indDst=1 & dstIndexOffset & b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { ptr:3 = imm24_dat + dstIndexOffset; ptr = *:3 ptr; export *:4 ptr; } # [abs24]
+
+# 3-Byte destination effective address specified by 5-bit encoding (b1_d5/b2_d5)
+dst5A: dst5dsp8^[b2_d5_regAxSF] is (b1_d5=0x1; b2_d5_regAxSF) ... & dst5dsp8 { ptr:3 = b2_d5_regAxSF + dst5dsp8; export ptr; } # dsp:8[Ax|SB|FB]
+dst5A: dst5dsp16^[b2_d5_regAxSF] is (b1_d5=0x2; b2_d5_regAxSF) ... & dst5dsp16 { ptr:3 = b2_d5_regAxSF + dst5dsp16; export ptr; } # dsp:16[Ax|SB|FB]
+dst5A: dst5dsp24^[b2_d5_regAx] is (b1_d5=0x3; b2_d5_1=0 & b2_d5_regAx) ... & dst5dsp24 { ptr:3 = b2_d5_regAx + dst5dsp24; export ptr; } # dsp:24[Ax]
+dst5A: imm16_dat is (b1_d5=0x3; b2_d5=0x3) ... & (skipBytesBeforeDst5; imm16_dat) { export *[const]:3 imm16_dat; } # abs16 (special constant address case)
+dst5A: imm24_dat is (b1_d5=0x3; b2_d5=0x2) ... & (skipBytesBeforeDst5; imm24_dat) { export *[const]:3 imm24_dat; } # abs24 (special constant address case)
+
+# Ax destination specified by 5-bit encoding (b1_d5/b2_d5)
+# NOTE! Ax destination is special case and must be handled seperately by each instruction
+# Starting position is at instruction b1
+dst5Ax: b2_d5_regAx is b1_d5; b2_d5_regAx { export b2_d5_regAx; }
+
+# 1/2/4-Byte destination value/location specified by 5-bit encoding (b1_d5/b2_d5)
+# This handles the case for dst5B, dst5W and dst5L where 5-bit encoded Source (src5) add-on bytes may exist before Destination add-on bytes
+# Variable length pattern starting at instruction byte b1
+dst5B_afterSrc5: dst5B is dst5B [ dstFollowsSrc=1; ] { export dst5B; }
+
+dst5W_afterSrc5: dst5W is dst5W [ dstFollowsSrc=1; ] { export dst5W; }
+
+dst5L_afterSrc5: dst5L is dst5L [ dstFollowsSrc=1; ] { export dst5L; }
+
+# 1/2/4-Byte destination value/location specified by 5-bit encoding (b1_d5/b2_d5)
+# This handles the case for dst5B, dst5W and dst5L where Dsp8 add-on bytes always exist before Destination add-on bytes
+# Variable length pattern starting at instruction byte b1
+dst5B_afterDsp8: dst5B is dst5B [ dstFollowsSrc=2; ] { export dst5B; }
+
+dst5W_afterDsp8: dst5W is dst5W [ dstFollowsSrc=2; ] { export dst5W; }
+
+#
+# The following macros are used to elliminate illegal bit patterns when using dst5
+# These should be used by constructor pattern matching instead of the corresponding dst5 subconstructor
+#
+@define DST5B "((b1_d5=4 | b1_d5_4=0) ... & dst5B)"
+@define DST5W "((b1_d5=4 | b1_d5_4=0) ... & dst5W)"
+@define DST5L "((b1_d5=4 | b1_d5_4=0) ... & dst5L)"
+@define DST5A "((b1_d5_4=0) ... & dst5A)"
+@define DST5AX "((b1_d5=0x0; b2_d5_1=1) & dst5Ax)"
+@define DST5B_AFTER_SRC5 "((b1_d5=4 | b1_d5_4=0) ... & dst5B_afterSrc5)"
+@define DST5W_AFTER_SRC5 "((b1_d5=4 | b1_d5_4=0) ... & dst5W_afterSrc5)"
+@define DST5L_AFTER_SRC5 "((b1_d5=4 | b1_d5_4=0) ... & dst5L_afterSrc5)"
+@define DST5B_AFTER_DSP8 "((b1_d5=4 | b1_d5_4=0) ... & dst5B_afterDsp8)"
+@define DST5W_AFTER_DSP8 "((b1_d5=4 | b1_d5_4=0) ... & dst5W_afterDsp8)"
+@define DST5L_AFTER_DSP8 "((b1_d5=4 | b1_d5_4=0) ... & dst5L_afterDsp8)"
+
+# dst2... Handle 2-bit encoded Destination specified by b1_d2
+# Variable length pattern starting at instruction byte b1
+# TODO? Certain uses of dst2 should exclude the R0 case (b1_d2=0)
+# 1-Byte destination value/location specified by 2-bit encoding (b1_d2)
+dst2B: R0L is b1_d2=0 & R0L { export R0L; }
+dst2B: imm16_dat is b1_d2=1; imm16_dat { export *:1 imm16_dat; }
+dst2B: [imm16_dat] is indDst=1 & b1_d2=1; imm16_dat { ptr:3 = imm16_dat; ptr = *:3 ptr; export *:1 ptr; }
+dst2B: imm8_dat^":8"^[SB] is b1_d2=2 & SB; imm8_dat { ptr:3 = SB + imm8_dat; export *:1 ptr; }
+dst2B: [imm8_dat^":8"^[SB]] is indDst=1 & b1_d2=2 & SB; imm8_dat { ptr:3 = SB + imm8_dat; ptr = *:3 ptr; export *:1 ptr; }
+dst2B: simm8_dat^":8"^[FB] is b1_d2=3 & FB; simm8_dat { ptr:3 = FB + simm8_dat; export *:1 ptr; }
+dst2B: [simm8_dat^":8"^[FB]] is indDst=1 & b1_d2=3 & FB; simm8_dat { ptr:3 = FB + simm8_dat; ptr = *:3 ptr; export *:1 ptr; }
+
+# 2-Byte destination value/location specified by 2-bit encoding (b1_d2)
+dst2W: R0 is b1_d2=0 & R0 { export R0; }
+dst2W: imm16_dat is b1_d2=1; imm16_dat { export *:2 imm16_dat; }
+dst2W: [imm16_dat] is indDst=1 & b1_d2=1; imm16_dat { ptr:3 = imm16_dat; ptr = *:3 ptr; export *:2 ptr; }
+dst2W: imm8_dat^":8"^[SB] is b1_d2=2 & SB; imm8_dat { ptr:3 = SB + imm8_dat; export *:2 ptr; }
+dst2W: [imm8_dat^":8"^[SB]] is indDst=1 & b1_d2=2 & SB; imm8_dat { ptr:3 = SB + imm8_dat; ptr = *:3 ptr; export *:2 ptr; }
+dst2W: simm8_dat^":8"^[FB] is b1_d2=3 & FB; simm8_dat { ptr:3 = FB + simm8_dat; export *:2 ptr; }
+dst2W: [simm8_dat^":8"^[FB]] is indDst=1 & b1_d2=3 & FB; simm8_dat { ptr:3 = FB + simm8_dat; ptr = *:3 ptr; export *:2 ptr; }
+
+# 4-Byte destination value/location specified by 2-bit encoding (b1_d2)
+dst2L: R2R0 is b1_d2=0 & R2R0 { export R2R0; }
+dst2L: imm16_dat is b1_d2=1; imm16_dat { export *:4 imm16_dat; }
+dst2L: [imm16_dat] is indDst=1 & b1_d2=1; imm16_dat { ptr:3 = imm16_dat; ptr = *:3 ptr; export *:4 ptr; }
+dst2L: imm8_dat^":8"^[SB] is b1_d2=2 & SB; imm8_dat { ptr:3 = SB + imm8_dat; export *:4 ptr; }
+dst2L: [imm8_dat^":8"^[SB]] is indDst=1 & b1_d2=2 & SB; imm8_dat { ptr:3 = SB + imm8_dat; ptr = *:3 ptr; export *:4 ptr; }
+dst2L: simm8_dat^":8"^[FB] is b1_d2=3 & FB; simm8_dat { ptr:3 = FB + simm8_dat; export *:4 ptr; }
+dst2L: [simm8_dat^":8"^[FB]] is indDst=1 & b1_d2=3 & FB; simm8_dat { ptr:3 = FB + simm8_dat; ptr = *:3 ptr; export *:4 ptr; }
+
+dsp8spB: simm8_dat^":8"^[SP] is simm8_dat & SP { ptr:3 = SP + simm8_dat; export *:1 ptr; }
+
+dsp8spW: simm8_dat^":8"^[SP] is simm8_dat & SP { ptr:3 = SP + simm8_dat; export *:2 ptr; }
+
+#
+# Bit base - associated add-on data immediately follows instruction byte b2
+# (Ax destination case must be handled seperately)
+#
+# Obtain bitbase offset displacement for [AX | SB | FB] - AX and SB uses unsigned displacements, FB uses signed displacement
+bitbaseDsp8: imm8_dat^":11" is b1_d5; b2_d5; imm8_dat { export *[const]:3 imm8_dat; }
+bitbaseDsp8: simm8_dat^":11" is b1_d5; b2_d5=0x3; simm8_dat { export *[const]:3 simm8_dat; }
+
+bitbaseDsp16: imm16_dat^":19" is b1_d5; b2_d5; imm16_dat { export *[const]:3 imm16_dat; }
+bitbaseDsp16: simm16_dat^":19" is b1_d5; b2_d5=0x3; simm16_dat { export *[const]:3 simm16_dat; }
+
+bitbaseDsp24: imm24_dat^":27" is b1_d5; b2_d5; imm24_dat { export *[const]:3 imm24_dat; }
+bitbaseDsp24: simm24_dat^":27" is b1_d5; b2_d5=0x3; simm24_dat { export *[const]:3 simm24_dat; }
+
+bitbase: b2_d5_reg8 is useBitIndex=0 & b1_d5=0x4; b2_d5_reg8 { export b2_d5_reg8; } # Rx
+bitbase: b2_d5_regAx is useBitIndex=0 & b1_d5=0x0; b2_d5_1=1 & b2_d5_regAx { tmp:1 = b2_d5_regAx:1; export tmp; } # Ax - read-only case
+bitbase: [b2_d5_regAx] is useBitIndex=0 & b1_d5=0x0; b2_d5_1=0 & b2_d5_regAx { ptr:3 = b2_d5_regAx; export *:1 ptr; } # [Ax]
+bitbase: bitbaseDsp8^[b2_d5_regAxSF] is (useBitIndex=0 & b1_d5=0x1; b2_d5_regAxSF) ... & bitbaseDsp8 { ptr:3 = b2_d5_regAxSF + bitbaseDsp8; export *:1 ptr; } # base:11[Ax|SB|FB]
+bitbase: bitbaseDsp16^[b2_d5_regAxSF] is (useBitIndex=0 & b1_d5=0x2; b2_d5_regAxSF) ... & bitbaseDsp16 { ptr:3 = b2_d5_regAxSF + bitbaseDsp16; export *:1 ptr; } # base:19[Ax|SB|FB]
+bitbase: bitbaseDsp24^[b2_d5_regAx] is (useBitIndex=0 & b1_d5=0x3; b2_d5_1=0 & b2_d5_regAx) ... & bitbaseDsp24 { ptr:3 = b2_d5_regAx + bitbaseDsp24; export *:1 ptr; } # base:27[Ax]
+bitbase: imm16_dat^":19" is useBitIndex=0 & b1_d5=0x3; b2_d5=0x3; imm16_dat { export *:1 imm16_dat; } # base:19
+bitbase: imm24_dat^":27" is useBitIndex=0 & b1_d5=0x3; b2_d5=0x2; imm24_dat { export *:1 imm24_dat; } # base:27
+
+bitbase: [b2_d5_regAx] is useBitIndex=1 & b1_d5=0x0; b2_d5_1=0 & b2_d5_regAx { ptr:3 = b2_d5_regAx + (bitIndex / 8); export *:1 ptr; } # [Ax] w/bitIndex
+bitbase: bitbaseDsp8^[b2_d5_regAxSF] is (useBitIndex=1 & b1_d5=0x1; b2_d5_regAxSF) ... & bitbaseDsp8 { ptr:3 = b2_d5_regAxSF + bitbaseDsp8 + (bitIndex / 8); export *:1 ptr; } # base:11[Ax|SB|FB] w/bitIndex
+bitbase: bitbaseDsp16^[b2_d5_regAxSF] is (useBitIndex=1 & b1_d5=0x2; b2_d5_regAxSF) ... & bitbaseDsp16 { ptr:3 = b2_d5_regAxSF + bitbaseDsp16 + (bitIndex / 8); export *:1 ptr; } # base:19[Ax|SB|FB] w/bitIndex
+bitbase: bitbaseDsp24^[b2_d5_regAx] is (useBitIndex=1 & b1_d5=0x3; b2_d5_1=0 & b2_d5_regAx) ... & bitbaseDsp24 { ptr:3 = b2_d5_regAx + bitbaseDsp24 + (bitIndex / 8); export *:1 ptr; } # base:27[Ax] w/bitIndex
+bitbase: imm16_dat^":19" is useBitIndex=1 & b1_d5=0x3; b2_d5=0x3; imm16_dat { ptr:3 = imm16_dat + (bitIndex / 8); export *:1 ptr; } # base:19 w/bitIndex
+bitbase: imm24_dat^":27" is useBitIndex=1 & b1_d5=0x3; b2_d5=0x2; imm24_dat { ptr:3 = imm24_dat + (bitIndex / 8); export *:1 ptr; } # base:27 w/bitIndex
+
+# Ax bitbase destination specified by 5-bit encoding (b1_d5/b2_d5)
+# NOTE! Ax destination is special case and must be handled seperately by each instruction
+# Starting position is at instruction b1
+bitbaseAx: b2_d5_regAx is b1_d5; b2_d5_regAx { export b2_d5_regAx; }
+
+bitbaseAbs16: imm16_dat is imm16_dat { export *:1 imm16_dat; }
+
+#
+# The following macros are used to elliminate illegal bit patterns when using dst5
+# These should be used by constructor pattern matching instead of the corresponding dst5 subconstructor
+#
+@define BITBASE "((b1_d5=4 | b1_d5_4=0) ... & bitbase)"
+@define BITBASE_AX "((b1_d5=0x0; b2_d5_1=1) & bitbaseAx)"
+
+# Bit identifier (may be overriden if useBitIndex has been set by BINDEX instruction
+bit: b2_bit is useBitIndex=0 & b2_bit { export *[const]:1 b2_bit; }
+bit: [bitIndex] is useBitIndex=1 & bitIndex { val:3 = bitIndex % 8; b:1 = val:1; export b; }
+
+#
+# Immediate data operand
+# Fixed length - current position is at start of immediate data
+#
+srcImm3: "#"^b2_0002 is b2_0002 { export *[const]:1 b2_0002; }
+srcImm8: "#"^imm8_dat is imm8_dat { export *[const]:1 imm8_dat; }
+
+srcImm8a: "#"^imm8_dat is imm8_dat { export *[const]:1 imm8_dat; } # used when two imm8 are needed
+
+srcImm16: "#"^imm16_dat is imm16_dat { export *[const]:2 imm16_dat; }
+
+srcImm16a: "#"^imm16_dat is imm16_dat { export *[const]:2 imm16_dat; } # used when two imm16 are needed
+
+srcImm24: "#"^imm24_dat is imm24_dat { export *[const]:3 imm24_dat; }
+srcImm32: "#"^imm32_dat is imm32_dat { export *[const]:4 imm32_dat; }
+
+# Unsigned immediate data from 1-bit value: 1 <= value <= 2 (1 added to unsigned bit value)
+srcImm1p: "#"^val is b1_0505 [ val = b1_0505 + 1; ] { export *[const]:1 val; }
+
+# Unsigned immediate data from 2-bit value: 1 <= value <= 8 (1 added to unsigned bit value)
+srcImm3p: "#"^val is b1_0405 & b1_0000 [ val = (b1_0405 << 1) + b1_0000 + 1; ] { export *[const]:1 val; }
+
+srcSimm8: "#"^simm8_dat is simm8_dat { export *[const]:1 simm8_dat; }
+srcSimm16: "#"^simm16_dat is simm16_dat { export *[const]:2 simm16_dat; }
+srcSimm32: "#"^simm32_dat is simm32_dat { export *[const]:4 simm32_dat; }
+
+# Signed immediate data from signed 4-bit value: -8 <= value <= 7
+srcSimm4: "#"^b2_simm4 is b2_simm4 { export *[const]:1 b2_simm4; }
+
+srcSimm8a: srcSimm8 is srcSimm8 { export srcSimm8; }
+
+srcSimm16a: srcSimm16 is srcSimm16 { export srcSimm16; }
+
+# Signed immediate shift amount from 4-bit value: -8 <= value <= -1 || 1 <= value <= 8
+srcSimm4Shift: "#"^val is b2_shiftSign=0 & b2_0002 [ val = b2_0002 + 1; ] { export *[const]:1 val; }
+srcSimm4Shift: "#"^val is b2_shiftSign=1 & b2_0002 [ val = -(b2_0002 + 1); ] { export *[const]:1 val; }
+
+srcZero8: "#0" is b1_0007 { export 0:1; }
+srcZero16: "#0" is b1_0007 { export 0:2; }
+
+# special 6-bit immediate for INT number
+srcIntNum: "#"^imm6_dat is imm6_dat { export *[const]:1 imm6_dat; }
+
+#
+# Offset label operand
+#
+abs24offset: imm24_dat is imm24_dat { export *:1 imm24_dat; }
+
+abs16offset: imm16_dat is imm16_dat { export *:1 imm16_dat; }
+
+# Relative address offsets
+rel16offset1: offs is simm16_dat [ offs = inst_start + 1 + simm16_dat; ] { export *:1 offs; }
+
+rel8offset1: offs is simm8_dat [ offs = inst_start + 1 + simm8_dat; ] { export *:1 offs; }
+rel8offset2: offs is simm8_dat [ offs = inst_start + 2 + simm8_dat; ] { export *:1 offs; }
+
+rel3offset2: offs is b1_0405 & b1_0000 [ offs = inst_start + 2 + ((b1_0405 << 1) + b1_0000); ] { export *:1 offs; }
+
+reloffset_dst5W: dst5W is $(DST5W) { local reladdr = inst_start + dst5W; export *:3 reladdr; }
+
+reloffset_dst5L: dst5L is $(DST5L) { local reladdr = inst_start + dst5L; export *:3 reladdr; }
+
+reloffset_dst5Ax: dst5Ax is $(DST5AX) { local reladdr = inst_start + dst5Ax; export *:3 reladdr; }
+
+#
+# Conditionals (see BMcnd)
+#
+# TODO!! Need to verify conditional logic pulled from old slaspec
+# TODO: the 'cnd' subconstructor should really constrain the bits 4-7 to 0x0, however this exposes a sleigh compiler problem
+cnd: "LTU" is cnd_dat=0x0 { tstCnd:1 = ($(CARRY) == 0); export tstCnd; } # less than (>), C flag is 0
+cnd: "LEU" is cnd_dat=0x1 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 0); export tstCnd; } # Equal to or less than (>=)
+cnd: "NE" is cnd_dat=0x2 { tstCnd:1 = ($(ZERO) == 0); export tstCnd; } # Not Equal to (=), Z flag is 0
+cnd: "PZ" is cnd_dat=0x3 { tstCnd:1 = ($(SIGN) == 0); export tstCnd; } # Positive or zero (0<=)
+cnd: "NO" is cnd_dat=0x4 { tstCnd:1 = ($(OVERFLOW) == 0); export tstCnd; } # O flag is 0
+cnd: "GT" is cnd_dat=0x5 { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 0); export tstCnd; } # Greater than (signed value) (<)
+cnd: "GE" is cnd_dat=0x6 { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 0); export tstCnd; } # Equal to or greater than (signed value) (<=)
+cnd: "GEU" is cnd_dat=0x8 { tstCnd:1 = ($(CARRY) == 1); export tstCnd; } # Equal to or greater than (<=), C flag is 1
+cnd: "GTU" is cnd_dat=0x9 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 1); export tstCnd; } # Greater than (<)
+cnd: "EQ" is cnd_dat=0xa { tstCnd:1 = ($(ZERO) == 1); export tstCnd; } # Equal to (=), Z flag is 1
+cnd: "N" is cnd_dat=0xb { tstCnd:1 = ($(SIGN) == 1); export tstCnd; } # Negative (0>)
+cnd: "O" is cnd_dat=0xc { tstCnd:1 = ($(OVERFLOW) == 1); export tstCnd; } # O flag is 1
+cnd: "LE" is cnd_dat=0xd { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 1); export tstCnd; } # Equal to or less than (signed value) (>=)
+cnd: "LT" is cnd_dat=0xe { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 1); export tstCnd; } # less than (signed value) (<=)
+
+b2cnd: "LTU" is b2_0606=0 & b2_0002=0 { tstCnd:1 = ($(CARRY) == 0); export tstCnd; } # less than (>), C flag is 0
+b2cnd: "LEU" is b2_0606=0 & b2_0002=1 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 0); export tstCnd; } # Equal to or less than (>=)
+b2cnd: "NE" is b2_0606=0 & b2_0002=2 { tstCnd:1 = ($(ZERO) == 0); export tstCnd; } # Not Equal to (=), Z flag is 0
+b2cnd: "PZ" is b2_0606=0 & b2_0002=3 { tstCnd:1 = ($(SIGN) == 0); export tstCnd; } # Positive or zero (0<=)
+b2cnd: "NO" is b2_0606=0 & b2_0002=4 { tstCnd:1 = ($(OVERFLOW) == 0); export tstCnd; } # O flag is 0
+b2cnd: "GT" is b2_0606=0 & b2_0002=5 { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 0); export tstCnd; } # Greater than (signed value) (<)
+b2cnd: "GE" is b2_0606=0 & b2_0002=6 { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 0); export tstCnd; } # Equal to or greater than (signed value) (<=)
+b2cnd: "GEU" is b2_0606=1 & b2_0002=0 { tstCnd:1 = ($(CARRY) == 1); export tstCnd; } # Equal to or greater than (<=), C flag is 1
+b2cnd: "GTU" is b2_0606=1 & b2_0002=1 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 1); export tstCnd; } # Greater than (<)
+b2cnd: "EQ" is b2_0606=1 & b2_0002=2 { tstCnd:1 = ($(ZERO) == 1); export tstCnd; } # Equal to (=), Z flag is 1
+b2cnd: "N" is b2_0606=1 & b2_0002=3 { tstCnd:1 = ($(SIGN) == 1); export tstCnd; } # Negative (0>)
+b2cnd: "O" is b2_0606=1 & b2_0002=4 { tstCnd:1 = ($(OVERFLOW) == 1); export tstCnd; } # O flag is 1
+b2cnd: "LE" is b2_0606=1 & b2_0002=5 { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 1); export tstCnd; } # Equal to or less than (signed value) (>=)
+b2cnd: "LT" is b2_0606=1 & b2_0002=6 { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 1); export tstCnd; } # less than (signed value) (<=)
+
+b1cnd: "LTU" is b1_0406=0 & b1_0000=0 { tstCnd:1 = ($(CARRY) == 0); export tstCnd; } # less than (>), C flag is 0
+b1cnd: "LEU" is b1_0406=0 & b1_0000=1 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 0); export tstCnd; } # Equal to or less than (>=)
+b1cnd: "NE" is b1_0406=1 & b1_0000=0 { tstCnd:1 = ($(ZERO) == 0); export tstCnd; } # Not Equal to (=), Z flag is 0
+b1cnd: "PZ" is b1_0406=1 & b1_0000=1 { tstCnd:1 = ($(SIGN) == 0); export tstCnd; } # Positive or zero (0<=)
+b1cnd: "NO" is b1_0406=2 & b1_0000=0 { tstCnd:1 = ($(OVERFLOW) == 0); export tstCnd; } # O flag is 0
+b1cnd: "GT" is b1_0406=2 & b1_0000=1 { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 0); export tstCnd; } # Greater than (signed value) (<)
+b1cnd: "GE" is b1_0406=3 & b1_0000=0 { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 0); export tstCnd; } # Equal to or greater than (signed value) (<=)
+b1cnd: "GEU" is b1_0406=4 & b1_0000=0 { tstCnd:1 = ($(CARRY) == 1); export tstCnd; } # Equal to or greater than (<=), C flag is 1
+b1cnd: "GTU" is b1_0406=4 & b1_0000=1 { tstCnd:1 = (($(CARRY) & (!$(ZERO))) == 1); export tstCnd; } # Greater than (<)
+b1cnd: "EQ" is b1_0406=5 & b1_0000=0 { tstCnd:1 = ($(ZERO) == 1); export tstCnd; } # Equal to (=), Z flag is 1
+b1cnd: "N" is b1_0406=5 & b1_0000=1 { tstCnd:1 = ($(SIGN) == 1); export tstCnd; } # Negative (0>)
+b1cnd: "O" is b1_0406=6 & b1_0000=0 { tstCnd:1 = ($(OVERFLOW) == 1); export tstCnd; } # O flag is 1
+b1cnd: "LE" is b1_0406=6 & b1_0000=1 { tstCnd:1 = ((($(SIGN) ^ $(OVERFLOW)) | $(ZERO)) == 1); export tstCnd; } # Equal to or less than (signed value) (>=)
+b1cnd: "LT" is b1_0406=7 & b1_0000=0 { tstCnd:1 = (($(SIGN) ^ $(OVERFLOW)) == 1); export tstCnd; } # less than (signed value) (<=)
+
+#
+# Flag bit operand
+#
+flagBit: "C" is b2_0002=0 { export 0:2; }
+flagBit: "D" is b2_0002=1 { export 1:2; }
+flagBit: "Z" is b2_0002=2 { export 2:2; }
+flagBit: "S" is b2_0002=3 { export 3:2; }
+flagBit: "B" is b2_0002=4 { export 4:2; }
+flagBit: "O" is b2_0002=5 { export 5:2; }
+flagBit: "I" is b2_0002=6 { export 6:2; }
+flagBit: "U" is b2_0002=7 { export 7:2; }
+
+with: phase=1 {
+#
+# Instruction Constructors
+#
+##### ABS #####
+# (1) ABS.B dst
+# 1010 0100 1001 1111 0011 0100 0001 0010 ABS.B 0x1234:16[SB]
+# 0000 1001 1010 0100 1001 1111 0011 0100 0001 0010 ABS.B [0x1234:16[SB]]
+:ABS.B dst5B is (b1_0407=0xa & b1_size_0=0; b2_0005=0x1f) ... & $(DST5B) ... {
+ tmp:1 = dst5B;
+ $(OVERFLOW) = (tmp == 0x80);
+ if (tmp s>= 0) goto ;
+ tmp = -tmp;
+ dst5B = tmp;
+
+ setResultFlags(tmp);
+}
+
+# (1) ABS.B Ax
+:ABS.B dst5Ax is (b1_0407=0xa & b1_size_0=0; b2_0005=0x1f) ... & $(DST5AX) ... {
+ tmp:1 = dst5Ax:1;
+ $(OVERFLOW) = (tmp == 0x80);
+ if (tmp s>= 0) goto ;
+ tmp = -tmp;
+ dst5Ax = zext(tmp);
+
+ setResultFlags(tmp);
+}
+
+# (1) ABS.W dst
+# 1010 0101 1001 1111 0011 0100 0001 0010 ABS.W 0x1234:16[SB]
+# 0000 1001 1010 0101 1001 1111 0011 0100 0001 0010 ABS.W [0x1234:16[SB]]
+:ABS.W dst5W is (b1_0407=0xa & b1_size_0=1; b2_0005=0x1f) ... & $(DST5W) ... {
+ tmp:2 = dst5W;
+ $(OVERFLOW) = (tmp == 0x8000);
+ if (tmp s>= 0) goto ;
+ tmp = -tmp;
+ dst5W = tmp;
+
+ setResultFlags(tmp);
+}
+
+# (1) ABS.W Ax
+:ABS.W dst5Ax is (b1_0407=0xa & b1_size_0=1; b2_0005=0x1f) ... & $(DST5AX) ... {
+ tmp:2 = dst5Ax:2;
+ $(OVERFLOW) = (tmp == 0x8000);
+ if (tmp s>= 0) goto ;
+ tmp = -tmp;
+ dst5Ax = zext(tmp);
+
+ setResultFlags(tmp);
+}
+
+##### ADC #####
+
+# (1) ADC.B #simm, dst
+# 0000 0001 1000 0100 1010 1110 0011 0100 0001 0010 0101 0110 ADC.B 0x56, 0x1234:16[SB]
+# 0000 1001 0000 0001 1000 0100 1010 1110 0011 0100 0001 0010 0101 0110 ABS.B 0x56, [0x1234:16[SB]]
+:ADC.B srcSimm8, dst5B is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x2e) ... & $(DST5B)); srcSimm8 {
+ tmp:1 = dst5B;
+ c:1 = $(CARRY);
+ setAdd3Flags(tmp, srcSimm8, c);
+ tmp = tmp + srcSimm8 + c;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ADC.B #simm, Ax
+:ADC.B srcSimm8, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x2e) & $(DST5AX)); srcSimm8 {
+ tmp:1 = dst5Ax:1;
+ c:1 = $(CARRY);
+ setAdd3Flags(tmp, srcSimm8, c);
+ tmp = tmp + srcSimm8 + c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ADC.W #simm, dst
+:ADC.W srcSimm16, dst5W is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x2e) ... & $(DST5W)); srcSimm16 {
+ tmp:2 = dst5W;
+ c:2 = zext($(CARRY));
+ setAdd3Flags(tmp, srcSimm16, c);
+ tmp = tmp + srcSimm16 + c;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ADC.B #simm, Ax
+:ADC.W srcSimm16, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x2e) & $(DST5AX)); srcSimm16 {
+ tmp:2 = dst5Ax:2;
+ c:2 = zext($(CARRY));
+ setAdd3Flags(tmp, srcSimm16, c);
+ tmp = tmp + srcSimm16 + c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) ADC.B src5, dst5
+:ADC.B src5B, dst5B_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x4) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ...) {
+ tmp:1 = dst5B_afterSrc5;
+ s:1 = src5B;
+ c:1 = $(CARRY);
+ setAdd3Flags(tmp, s, c);
+ tmp = tmp + s + c;
+ dst5B_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ADC.B src5, Ax
+:ADC.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x4) ... & $(SRC5B) & $(DST5AX) ...) {
+ tmp:1 = dst5Ax:1;
+ s:1 = src5B;
+ c:1 = $(CARRY);
+ setAdd3Flags(tmp, s, c);
+ tmp = tmp + s + c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) ADC.W src5, dst5
+:ADC.W src5W, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x4) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ...) {
+ tmp:2 = dst5W_afterSrc5;
+ s:2 = src5W;
+ c:2 = zext($(CARRY));
+ setAdd3Flags(tmp, s, c);
+ tmp = tmp + s + c;
+ dst5W_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ADC.W src5, Ax
+:ADC.W src5W, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x4) ... & $(SRC5W) & $(DST5AX) ...) {
+ tmp:2 = dst5Ax:2;
+ s:2 = src5W;
+ c:2 = zext($(CARRY));
+ setAdd3Flags(tmp, s, c);
+ tmp = tmp + s + c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### ADCF #####
+
+# (1) ADCF.B dst
+:ADCF.B dst5B is (b1_0407=0xb & b1_size_0=0; b2_0005=0x1e) ... & $(DST5B) {
+ tmp:1 = dst5B;
+ c:1 = $(CARRY);
+ setAddFlags(tmp, c);
+ tmp = tmp + c;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ADCF.B Ax
+:ADCF.B dst5Ax is (b1_0407=0xb & b1_size_0=0; b2_0005=0x1e) & $(DST5AX) {
+ tmp:1 = dst5Ax:1;
+ c:1 = $(CARRY);
+ setAddFlags(tmp, c);
+ tmp = tmp + c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ADCF.W dst
+:ADCF.W dst5W is (b1_0407=0xb & b1_size_0=1; b2_0005=0x1e) ... & $(DST5W) {
+ tmp:2 = dst5W;
+ c:2 = zext($(CARRY));
+ setAddFlags(tmp, c);
+ tmp = tmp + c;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ADCF.B Ax
+:ADCF.W dst5Ax is (b1_0407=0xb & b1_size_0=1; b2_0005=0x1e) & $(DST5AX) {
+ tmp:2 = dst5Ax:2;
+ c:2 = zext($(CARRY));
+ setAddFlags(tmp, c);
+ tmp = tmp + c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### ADD #####
+
+# (1) ADD.B:G #simm, dst
+:ADD^".B:G" srcSimm8, dst5B is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x2e) ... & $(DST5B)); srcSimm8 {
+ tmp:1 = dst5B;
+ setAddFlags(tmp, srcSimm8);
+ tmp = tmp + srcSimm8;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ADD.B:G #simm, Ax
+:ADD^".B:G" srcSimm8, dst5Ax is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x2e) & $(DST5AX)); srcSimm8 {
+ tmp:1 = dst5Ax:1;
+ setAddFlags(tmp, srcSimm8);
+ tmp = tmp + srcSimm8;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ADD.W:G #simm, dst
+:ADD^".W:G" srcSimm16, dst5W is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x2e) ... & $(DST5W)); srcSimm16 {
+ tmp:2 = dst5W;
+ setAddFlags(tmp, srcSimm16);
+ tmp = tmp + srcSimm16;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ADD.W:G #simm, Ax
+:ADD^".W:G" srcSimm16, dst5Ax is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x2e) & $(DST5AX)); srcSimm16 {
+ tmp:2 = dst5Ax:2;
+ setAddFlags(tmp, srcSimm16);
+ tmp = tmp + srcSimm16;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) ADD.L:G #simm, dst
+:ADD^".L:G" srcSimm32, dst5L is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x31) ... & $(DST5L)); srcSimm32 {
+ tmp:4 = dst5L;
+ setAddFlags(tmp, srcSimm32);
+ tmp = tmp + srcSimm32;
+ dst5L = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ADD.L:G #simm, Ax
+:ADD^".L:G" srcSimm32, dst5Ax is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x31) & $(DST5AX)); srcSimm32 {
+ tmp:4 = zext(dst5Ax);
+ setAddFlags(tmp, srcSimm32);
+ tmp = tmp + srcSimm32;
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+# (3) ADD.B:G #simm4, dst
+:ADD^".B:G" srcSimm4, dst5B is (b1_0507=0x7 & b1_size_4=0 & b1_size_0=0; b2_0405=3 & srcSimm4) ... & $(DST5B) {
+ tmp:1 = dst5B;
+ setAddFlags(tmp, srcSimm4);
+ tmp = tmp + srcSimm4;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) ADD.B:G #simm4, Ax
+:ADD^".B:G" srcSimm4, dst5Ax is (b1_0507=0x7 & b1_d5=0x0 & b1_size_4=0 & b1_size_0=0; b2_0405=3 & srcSimm4) & $(DST5AX) {
+ tmp:1 = dst5Ax:1;
+ setAddFlags(tmp, srcSimm4);
+ tmp = tmp + srcSimm4;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (3) ADD.W:Q #simm4, dst
+:ADD^".W:Q" srcSimm4, dst5W is (b1_0507=0x7 & b1_size_4=0 & b1_size_0=1; b2_0405=3 & srcSimm4) ... & $(DST5W) {
+ tmp:2 = dst5W;
+ imm:2 = sext(srcSimm4);
+ setAddFlags(tmp, imm);
+ tmp = tmp + imm;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) ADD.W:Q #simm4, Ax
+:ADD^".W:Q" srcSimm4, dst5Ax is (b1_0507=0x7 & b1_d5=0x0 & b1_size_4=0 & b1_size_0=1; b2_0405=3 & srcSimm4) & $(DST5AX) {
+ tmp:2 = dst5Ax:2;
+ imm:2 = sext(srcSimm4);
+ setAddFlags(tmp, imm);
+ tmp = tmp + imm;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (3) ADD.L:Q #simm4, dst
+:ADD^".L:Q" srcSimm4, dst5L is (b1_0507=0x7 & b1_size_4=1 & b1_size_0=0; b2_0405=3 & srcSimm4) ... & $(DST5L) {
+ tmp:4 = dst5L;
+ imm:4 = sext(srcSimm4);
+ setAddFlags(tmp, imm);
+ tmp = tmp + imm;
+ dst5L = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) ADD.L:Q #simm4, Ax
+:ADD^".L:Q" srcSimm4, dst5Ax is (b1_0507=0x7 & b1_d5=0x0 & b1_size_4=1 & b1_size_0=0; b2_0405=3 & srcSimm4) & $(DST5AX) {
+ tmp:4 = sext(dst5Ax);
+ imm:4 = sext(srcSimm4);
+ setAddFlags(tmp, imm);
+ tmp = tmp + imm;
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+# (4) ADD.B:S #simm, dst
+:ADD^".B:S" srcSimm8, dst2B is ((b1_0607=0 & b1_0103=3 & b1_size_0=0) ... & dst2B); srcSimm8 {
+ tmp:1 = dst2B;
+ setAddFlags(tmp, srcSimm8);
+ tmp = tmp + srcSimm8;
+ dst2B = tmp;
+ setResultFlags(tmp);
+}
+
+# (4) ADD.W:S #simm, dst
+# 0010 0111 0101 0110 0011 0100 0001 0010 ADD.W:S #0x1234, 0x56:8[SB]
+:ADD^".W:S" srcSimm16, dst2W is ((b1_0607=0 & b1_0103=3 & b1_size_0=1) ... & dst2W); srcSimm16 {
+ tmp:2 = dst2W;
+ setAddFlags(tmp, srcSimm16);
+ tmp = tmp + srcSimm16;
+ dst2W = tmp;
+ setResultFlags(tmp);
+}
+
+# (5) ADD.L:S #imm1, Ax
+:ADD^".L:S" srcImm1p, b1_d1_regAx is b1_0607=2 & srcImm1p & b1_0104=0x6 & b1_d1_regAx {
+ tmp:4 = sext(b1_d1_regAx);
+ imm:4 = zext(srcImm1p);
+ setAddFlags(tmp, imm);
+ tmp = tmp + imm;
+ b1_d1_regAx = tmp:3;
+ setResultFlags(tmp);
+}
+
+# (6) ADD.B:G src, dst
+# 1011 0110 0001 1000 0101 0110 0011 0100 0001 0010 0011 0011 0010 0010 0001 0001 ADD.B:G 0x123456:24[A0], 112233[A1]
+# 1100 0101 1111 1000 0011 0100 0001 0010 ADD.W:G R1, 0x1234:16[FB]
+:ADD^".B:G" src5B, dst5B_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0x8) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ... {
+ tmp:1 = dst5B_afterSrc5;
+ src:1 = src5B;
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5B_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (6) ADD.B:G src, Ax - Ax destination case
+:ADD^".B:G" src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0x8) ... & $(SRC5B) & $(DST5AX) ... {
+ tmp:1 = dst5Ax:1;
+ src:1 = src5B;
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (6) ADD.W:G src, dst
+:ADD^".W:G" src5W, dst5W_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0x8) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ... {
+ tmp:2 = dst5W_afterSrc5;
+ src:2 = src5W;
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5W_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (6) ADD.W:G src, Ax - Ax destination case
+:ADD^".W:G" src5W, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0x8) ... & $(SRC5W) & $(DST5AX) ... {
+ tmp:2 = dst5Ax:2;
+ src:2 = src5W;
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (7) ADD.L:G src, dst
+:ADD^".L:G" src5L, dst5L_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0x2) ... & $(SRC5L) ... & $(DST5L_AFTER_SRC5) ... {
+ tmp:4 = dst5L_afterSrc5;
+ src:4 = src5L;
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5L_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (7) ADD.L:G src, Ax - Ax destination case
+:ADD^".L:G" src5L, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0x2) ... & $(SRC5L) & $(DST5AX) ... {
+ tmp:4 = zext(dst5Ax);
+ src:4 = src5L;
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+# (8) ADD.l:G #simm16, SP
+:ADD^".L:G" srcSimm16, SP is b1_0007=0xb6 & SP; b2_0007=0x13; srcSimm16 {
+ # not done as 32-bit calculation to simplify stack analysis
+ imm:3 = sext(srcSimm16);
+ setAddFlags(SP, imm);
+ SP = SP + imm;
+ setResultFlags(SP);
+}
+
+# (9) ADD.L:Q #imm3, SP
+:ADD^".L:Q" srcImm3p, SP is b1_0607=1 & srcImm3p & b1_0103=1 & SP {
+ # not done as 32-bit calculation to simplify stack analysis
+ imm:3 = zext(srcImm3p);
+ setAddFlags(SP, imm);
+ SP = SP + imm;
+ setResultFlags(SP);
+}
+
+# (10) ADD.L:S #simm8, SP
+:ADD^".L:S" srcSimm8, SP is b1_0007=0xb6 & SP; b2_0007=0x03; srcSimm8 {
+ # not done as 32-bit calculation to simplify stack analysis
+ imm:3 = sext(srcSimm8);
+ setAddFlags(SP, imm);
+ SP = SP + imm;
+ setResultFlags(SP);
+}
+
+##### ADDX #####
+
+# (1) ADDX #simm, dst5
+:ADDX srcSimm8, dst5L is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x11) ... & $(DST5L)); srcSimm8 {
+ tmp:4 = dst5L;
+ src:4 = sext(srcSimm8);
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5L = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ADDX #simm, Ax
+:ADDX srcSimm8, dst5Ax is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x11) & $(DST5AX)); srcSimm8 {
+ tmp:4 = zext(dst5Ax);
+ src:4 = sext(srcSimm8);
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+# (2) ADDX src5, dst5
+:ADDX src5B, dst5L_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0x2) ... & $(SRC5B) ... & $(DST5L_AFTER_SRC5) ... {
+ tmp:4 = dst5L_afterSrc5;
+ src:4 = sext(src5B);
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5L_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ADDX src5, Ax
+:ADDX src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0x2) ... & $(SRC5B) & $(DST5AX) ... {
+ tmp:4 = zext(dst5Ax);
+ src:4 = sext(src5B);
+ setAddFlags(tmp, src);
+ tmp = tmp + src;
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+##### ADJNZ #####
+
+# ADJNZ.B #simm4, dst, rel8offset2
+# 1111 1000 1001 1111 0000 0110 ADJNZ #-0x1,R0L,
+:ADJNZ.B srcSimm4, dst5B, rel8offset2 is ((b1_0407=0xf & b1_size_0=0; b2_0405=1 & srcSimm4) ... & $(DST5B)); rel8offset2 {
+ tmp:1 = dst5B + srcSimm4;
+ dst5B = tmp;
+ if (tmp != 0) goto rel8offset2;
+}
+
+# ADJNZ.B #simm4, Ax, , rel8offset2
+:ADJNZ.B srcSimm4, dst5Ax, rel8offset2 is ((b1_0407=0xf & b1_size_0=0; b2_0405=1 & srcSimm4) & $(DST5AX)); rel8offset2 {
+ tmp:1 = dst5Ax:1 + srcSimm4;
+ dst5Ax = zext(tmp);
+ if (tmp != 0) goto rel8offset2;
+}
+
+# ADJNZ.W #simm4, dst, rel8offset2
+:ADJNZ.W srcSimm4, dst5W, rel8offset2 is ((b1_0407=0xf & b1_size_0=1; b2_0405=1 & srcSimm4) ... & $(DST5W)); rel8offset2 {
+ tmp:2 = dst5W + sext(srcSimm4);
+ dst5W = tmp;
+ if (tmp != 0) goto rel8offset2;
+}
+
+# ADJNZ.W #simm4, Ax, rel8offset2
+:ADJNZ.W srcSimm4, dst5Ax, rel8offset2 is ((b1_0407=0xf & b1_size_0=1; b2_0405=1 & srcSimm4) & $(DST5AX)); rel8offset2 {
+ tmp:2 = dst5Ax:2 + sext(srcSimm4);
+ dst5Ax = zext(tmp);
+ if (tmp != 0) goto rel8offset2;
+}
+
+##### AND #####
+
+# (1) AND.B:G #imm, dst
+:AND^".B:G" srcImm8, dst5B is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x3f) ... & $(DST5B)); srcImm8 {
+ tmp:1 = dst5B & srcImm8;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) AND.B:G #imm, Ax
+:AND^".B:G" srcImm8, dst5Ax is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x3f) & $(DST5AX)); srcImm8 {
+ tmp:1 = dst5Ax:1 & srcImm8;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) AND.W:G #imm, dst
+:AND^".W:G" srcImm16, dst5W is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x3f) ... & $(DST5W)); srcImm16 {
+ tmp:2 = dst5W & srcImm16;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) AND.W:G #imm, Ax
+:AND^".W:G" srcImm16, dst5Ax is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x3f) & $(DST5AX)); srcImm16 {
+ tmp:2 = dst5Ax:2 & srcImm16;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) AND.B:S #imm, dst
+:AND^".B:S" srcImm8, dst2B is ((b1_0607=1 & b1_0103=6 & b1_size_0=0) ... & dst2B); srcImm8 {
+ tmp:1 = dst2B & srcImm8;
+ dst2B = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) AND.W:S #imm, dst
+:AND^".W:S" srcImm16, dst2W is ((b1_0607=1 & b1_0103=6 & b1_size_0=1) ... & dst2W); srcImm16 {
+ tmp:2 = dst2W & srcImm16;
+ dst2W = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) AND.B:G src5, dst5
+:AND^".B:G" src5B, dst5B_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0xd) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ... {
+ tmp:1 = dst5B_afterSrc5 & src5B;
+ dst5B_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) AND.B:G src5, Ax
+:AND^".B:G" src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0xd) ... & $(SRC5B) & $(DST5AX) ... {
+ tmp:1 = dst5Ax:1 & src5B;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (3) AND.W:G src5, dst5
+:AND^".W:G" src5W, dst5W_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0xd) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ... {
+ tmp:2 = dst5W_afterSrc5 & src5W;
+ dst5W_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) AND.W:G src5, Ax
+:AND^".W:G" src5W, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0xd) ... & $(SRC5W) & $(DST5AX) ... {
+ tmp:2 = dst5Ax:2 & src5W;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### BAND #####
+
+# BAND bit,bitbase
+# 0000 0001 1101 0110 0000 1011 0101 0110 0011 0100 0001 0010 BAND 0x3,0x123456[A0]
+:BAND bit, bitbase is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x1 & bit) ... & $(BITBASE)) {
+ bitValue:1 = (bitbase >> bit) & 1;
+ $(CARRY) = $(CARRY) & bitValue;
+}
+
+##### BCLR #####
+
+# BCLR bit,bitbase
+# 1101 0110 0011 0011 0101 0110 0011 0100 0001 0010 BCLR 0x3,0x123456[A0]
+:BCLR bit, bitbase is (b1_0407=0xd & b1_size_0=0; b2_0305=0x6 & bit) ... & $(BITBASE) {
+ mask:1 = ~(1 << bit);
+ bitbase = bitbase & mask;
+}
+
+# BCLR bit,Ax
+:BCLR b2_bit, bitbaseAx is (b1_0407=0xd & b1_size_0=0; b2_0305=0x6 & b2_bit) & $(BITBASE_AX) {
+ mask:3 = ~(1 << b2_bit);
+ bitbaseAx = bitbaseAx & mask;
+}
+
+##### BITINDEX #####
+
+# BITINDEX.B src -- dst5B used as source
+# 1100 1000 1010 1110 BINDEX.B R0L
+:BITINDEX.B dst5B is (b1_0407=0xc & b1_size_0=0; b2_0005=0x2e) ... & $(DST5B)
+ [ useBitIndex=1; globalset(inst_next,useBitIndex); useBitIndex=0; ] {
+ bitIndex = zext(dst5B);
+}
+
+# BITINDEX.W src -- dst5W used as source
+:BITINDEX.W dst5W is (b1_0407=0xc & b1_size_0=1; b2_0005=0x2e) ... & $(DST5W)
+ [ useBitIndex=1; globalset(inst_next,useBitIndex); useBitIndex=0; ] {
+ bitIndex = zext(dst5W);
+}
+
+##### BMCnd #####
+
+# (1) BMcnd bit, bitbase
+:BM^cnd bit, bitbase is ((b1_0407=0xd & b1_size_0=0; b2_0305=0x2 & bit) ... & $(BITBASE)); cnd {
+ mask:1 = ~(1 << bit);
+ bitbase = ((cnd << bit) | (bitbase & mask));
+}
+
+# (1) BMcnd bit, Ax
+:BM^cnd b2_bit, bitbaseAx is ((b1_0407=0xd & b1_size_0=0; b2_0305=0x2 & b2_bit) & $(BITBASE_AX)); cnd {
+ mask:3 = ~(1 << b2_bit);
+ bitbaseAx = ((zext(cnd) << b2_bit) | (bitbaseAx & mask));
+}
+
+# (2) BMcnd C
+:BM^b2cnd "C" is b1_0007=0xd9; b2_0707=0 & b2_0305=5 & b2cnd {
+ $(CARRY) = b2cnd;
+}
+
+##### BNAND #####
+
+:BNAND bit, bitbase is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x3 & bit) ... & $(BITBASE)) {
+ mask:1 = (1 << bit);
+ bitValue:1 = (bitbase & mask);
+ $(CARRY) = $(CARRY) && (bitValue == 0);
+}
+
+:BNAND b2_bit, bitbaseAx is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x3 & b2_bit) & $(BITBASE_AX)) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (bitbaseAx & mask);
+ $(CARRY) = $(CARRY) && (bitValue == 0);
+}
+
+##### BNOR #####
+
+:BNOR bit, bitbase is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x6 & bit) ... & $(BITBASE)) {
+ mask:1 = (1 << bit);
+ bitValue:1 = (bitbase & mask);
+ $(CARRY) = $(CARRY) || (bitValue == 0);
+}
+
+:BNOR b2_bit, bitbaseAx is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x6 & b2_bit) & $(BITBASE_AX)) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (bitbaseAx & mask);
+ $(CARRY) = $(CARRY) || (bitValue == 0);
+}
+
+##### BNOT #####
+
+# BNOT bit,bitbase
+:BNOT bit, bitbase is (b1_0407=0xd & b1_size_0=0; b2_0305=0x3 & bit) ... & $(BITBASE) {
+ mask:1 = (1 << bit);
+ val:1 = bitbase;
+ bitValue:1 = (~val & mask);
+ bitbase = (val & ~mask) | bitValue;
+}
+
+# BNOT bit,Ax
+:BNOT b2_bit, bitbaseAx is (b1_0407=0xd & b1_size_0=0; b2_0305=0x3 & b2_bit) & $(BITBASE_AX) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (~bitbaseAx & mask);
+ bitbaseAx = (bitbaseAx & ~mask) | bitValue;
+}
+
+##### BNTST #####
+
+:BNTST bit, bitbase is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x0 & bit) ... & $(BITBASE)) {
+ mask:1 = (1 << bit);
+ bitValue:1 = (bitbase & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = z;
+ $(ZERO) = z;
+}
+
+:BNTST b2_bit, bitbaseAx is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x0 & b2_bit) & $(BITBASE_AX)) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (bitbaseAx & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = z;
+ $(ZERO) = z;
+}
+
+##### BNXOR #####
+
+:BNXOR bit, bitbase is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x7 & bit) ... & $(BITBASE)) {
+ mask:1 = (1 << bit);
+ bitValue:1 = (bitbase & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue == 0);
+}
+
+:BNXOR b2_bit, bitbaseAx is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x7 & b2_bit) & $(BITBASE_AX)) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (bitbaseAx & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue == 0);
+}
+
+##### BOR #####
+
+:BOR bit, bitbase is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x4 & bit) ... & $(BITBASE)) {
+ mask:1 = (1 << bit);
+ bitValue:1 = (bitbase & mask);
+ $(CARRY) = $(CARRY) || (bitValue != 0);
+}
+
+:BOR b2_bit, bitbaseAx is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x4 & b2_bit) & $(BITBASE_AX)) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (bitbaseAx & mask);
+ $(CARRY) = $(CARRY) || (bitValue != 0);
+}
+
+##### BRK #####
+
+:BRK is b1_0007=0x0 {
+ # I don't think it is necessary to model break behavior
+ Break();
+}
+
+##### BRK2 #####
+
+:BRK2 is b1_0007=0x8 {
+ # I don't think it is necessary to model break behavior
+ Break2();
+}
+
+##### BSET #####
+
+:BSET bit, bitbase is (b1_0407=0xd & b1_size_0=0; b2_0305=0x7 & bit) ... & $(BITBASE) {
+ mask:1 = (1 << bit);
+ bitbase = bitbase | mask;
+}
+
+:BSET b2_bit, bitbaseAx is (b1_0407=0xd & b1_size_0=0; b2_0305=0x7 & b2_bit) & $(BITBASE_AX) {
+ mask:3 = (1 << b2_bit);
+ bitbaseAx = bitbaseAx | mask;
+}
+
+##### BTST #####
+
+# (1) BTST bit, bitbase
+:BTST bit, bitbase is (b1_0407=0xd & b1_size_0=0; b2_0305=0x0 & bit) ... & $(BITBASE) {
+ mask:1 = (1 << bit);
+ bitValue:1 = (bitbase & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+}
+
+# (1) BTST bit, Ax
+:BTST b2_bit, bitbaseAx is (b1_0407=0xd & b1_size_0=0; b2_0305=0x0 & b2_bit) & $(BITBASE_AX) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (bitbaseAx & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+}
+
+# (2) BTST bit, bitbase
+:BTST b, bitbaseAbs16 is b1_0607=0 & b1_0405 & b1_0103=5 & b1_0000; bitbaseAbs16 [ b = (b1_0405 << 1) + b1_0000; ] {
+ mask:1 = (1 << b);
+ bitValue:1 = (bitbaseAbs16 & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+}
+
+##### BTSTC #####
+
+# (1) BTSTC bit, bitbase
+:BTSTC bit, bitbase is (b1_0407=0xd & b1_size_0=0; b2_0305=0x4 & bit) ... & $(BITBASE) {
+ mask:1 = (1 << bit);
+ val:1 = bitbase;
+ bitValue:1 = (val & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ bitbase = val & ~mask;
+}
+
+# (1) BTSTC bit, Ax
+:BTSTC b2_bit, bitbaseAx is (b1_0407=0xd & b1_size_0=0; b2_0305=0x4 & b2_bit) & $(BITBASE_AX) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (bitbaseAx & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ bitbaseAx = bitbaseAx & ~mask;
+}
+
+##### BTSTS #####
+
+# (1) BTSTS bit, bitbase
+:BTSTS bit, bitbase is (b1_0407=0xd & b1_size_0=0; b2_0305=0x5 & bit) ... & $(BITBASE) {
+ mask:1 = (1 << bit);
+ val:1 = bitbase;
+ bitValue:1 = (val & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ bitbase = val | mask;
+}
+
+# (1) BTSTS bit, Ax
+:BTSTS b2_bit, bitbaseAx is (b1_0407=0xd & b1_size_0=0; b2_0305=0x5 & b2_bit) & $(BITBASE_AX) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (bitbaseAx & mask);
+ z:1 = (bitValue == 0);
+ $(CARRY) = !z;
+ $(ZERO) = z;
+ bitbaseAx = bitbaseAx | mask;
+}
+
+##### BXOR #####
+
+:BXOR bit, bitbase is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x5 & bit) ... & $(BITBASE)) {
+ mask:1 = (1 << bit);
+ bitValue:1 = (bitbase & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue != 0);
+}
+
+:BXOR b2_bit, bitbaseAx is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=0; b2_0305=0x5 & b2_bit) & $(BITBASE_AX)) {
+ mask:3 = (1 << b2_bit);
+ bitValue:3 = (bitbaseAx & mask);
+ $(CARRY) = $(CARRY) ^ (bitValue != 0);
+}
+
+##### CLIP #####
+
+# CLIP.B #simm, #simm, dst5
+:CLIP.B srcSimm8, srcSimm8a, dst5B is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x3e) ... & $(DST5B)); srcSimm8; srcSimm8a {
+ val:1 = dst5B;
+ cmp1:1 = srcSimm8 s> val;
+ cmp2:1 = srcSimm8a s< val;
+ dst5B = (cmp1 * srcSimm8) + (cmp2 * srcSimm8a) + ((!cmp1 * !cmp2) * val);
+}
+
+# CLIP.B #simm, #simm, Ax
+:CLIP.B srcSimm8, srcSimm8a, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x3e) & $(DST5AX)); srcSimm8; srcSimm8a {
+ val:1 = dst5Ax:1;
+ cmp1:1 = srcSimm8 s> val;
+ cmp2:1 = srcSimm8a s< val;
+ dst5Ax = zext((cmp1 * srcSimm8) + (cmp2 * srcSimm8a) + ((!cmp1 * !cmp2) * val));
+}
+
+# CLIP.W #simm, #simm, dst5
+:CLIP.W srcSimm16, srcSimm16a, dst5W is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x3e) ... & $(DST5W)); srcSimm16; srcSimm16a {
+ val:2 = dst5W;
+ cmp1:1 = srcSimm16 s> val;
+ cmp2:1 = srcSimm16a s< val;
+ dst5W = (zext(cmp1) * srcSimm16) + (zext(cmp2) * srcSimm16a) + (zext(!cmp1 * !cmp2) * val);
+}
+
+# CLIP.W #simm, #simm, Ax
+:CLIP.W srcSimm16, srcSimm16a, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x3e) & $(DST5AX)); srcSimm16; srcSimm16a {
+ val:2 = dst5Ax:2;
+ cmp1:1 = srcSimm16 s> val;
+ cmp2:1 = srcSimm16a s< val;
+ dst5Ax = zext((zext(cmp1) * srcSimm16) + (zext(cmp2) * srcSimm16a) + (zext(!cmp1 * !cmp2) * val));
+}
+
+##### CMP #####
+
+# (1) CMP.B:G #simm, dst5
+:CMP^".B:G" srcSimm8, dst5B is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x2e) ... & $(DST5B)); srcSimm8 {
+ tmp:1 = dst5B;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ setResultFlags(tmp);
+}
+
+# (1) CMP.B:G #simm, Ax
+:CMP^".B:G" srcSimm8, dst5Ax is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x2e) & $(DST5AX)); srcSimm8 {
+ tmp:1 = dst5Ax:1;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ setResultFlags(tmp);
+}
+
+# (1) CMP.W:G #simm, dst5
+:CMP^".W:G" srcSimm16, dst5W is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x2e) ... & $(DST5W)); srcSimm16 {
+ tmp:2 = dst5W;
+ setSubtractFlags(tmp, srcSimm16);
+ tmp = tmp - srcSimm16;
+ setResultFlags(tmp);
+}
+
+# (1) CMP.W:G #simm, Ax
+:CMP^".W:G" srcSimm16, dst5Ax is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x2e) & $(DST5AX)); srcSimm16 {
+ tmp:2 = dst5Ax:2;
+ setSubtractFlags(tmp, srcSimm16);
+ tmp = tmp - srcSimm16;
+ setResultFlags(tmp);
+}
+
+# (2) CMP.L:G #simm, dst5
+:CMP^".L:G" srcSimm32, dst5L is ((b1_0407=0xa & b1_size_0=0; b2_0005=0x31) ... & $(DST5L)); srcSimm32 {
+ tmp:4 = dst5L;
+ setSubtractFlags(tmp, srcSimm32);
+ tmp = tmp - srcSimm32;
+ setResultFlags(tmp);
+}
+
+# (2) CMP.L:G #simm, Ax
+:CMP^".L:G" srcSimm32, dst5Ax is ((b1_0407=0xa & b1_size_0=0; b2_0005=0x31) & $(DST5AX)); srcSimm32 {
+ tmp:4 = zext(dst5Ax);
+ setSubtractFlags(tmp, srcSimm32);
+ tmp = tmp - srcSimm32;
+ setResultFlags(tmp);
+}
+
+# (3) CMP.B:Q #simm4, dst5
+:CMP^".B:Q" srcSimm4, dst5B is (b1_0407=0xe & b1_size_0=0; b2_0405=1 & srcSimm4) ... & $(DST5B) {
+ tmp:1 = dst5B;
+ setSubtractFlags(tmp, srcSimm4);
+ tmp = tmp - srcSimm4;
+ setResultFlags(tmp);
+}
+
+# (3) CMP.B:Q #simm4, Ax
+:CMP^".B:Q" srcSimm4, dst5Ax is (b1_0407=0xe & b1_size_0=0; b2_0405=1 & srcSimm4) & $(DST5AX) {
+ tmp:1 = dst5Ax:1;
+ setSubtractFlags(tmp, srcSimm4);
+ tmp = tmp - srcSimm4;
+ setResultFlags(tmp);
+}
+
+# (3) CMP.W:Q #simm4, dst5
+:CMP^".W:Q" srcSimm4, dst5W is (b1_0407=0xe & b1_size_0=1; b2_0405=1 & srcSimm4) ... & $(DST5W) {
+ tmp:2 = dst5W;
+ imm:2 = sext(srcSimm4);
+ setSubtractFlags(tmp, imm);
+ tmp = tmp - imm;
+ setResultFlags(tmp);
+}
+
+# (3) CMP.W:Q #simm4, Ax
+:CMP^".W:Q" srcSimm4, dst5Ax is (b1_0407=0xe & b1_size_0=1; b2_0405=1 & srcSimm4) & $(DST5AX) {
+ tmp:2 = dst5Ax:2;
+ imm:2 = sext(srcSimm4);
+ setSubtractFlags(tmp, imm);
+ tmp = tmp - imm;
+ setResultFlags(tmp);
+}
+
+# (4) CMP.B:S #simm, dst2
+:CMP^".B:S" srcSimm8, dst2B is ((b1_0607=1 & b1_0103=3 & b1_size_0=0) ... & dst2B); srcSimm8 {
+ tmp:1 = dst2B;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ setResultFlags(tmp);
+}
+
+# (4) CMP.W:S #simm, dst2
+:CMP^".W:S" srcSimm16, dst2W is ((b1_0607=1 & b1_0103=3 & b1_size_0=1) ... & dst2W); srcSimm16 {
+ tmp:2 = dst2W;
+ setSubtractFlags(tmp, srcSimm16);
+ tmp = tmp - srcSimm16;
+ setResultFlags(tmp);
+}
+
+# (5) CMP.B:G src5, dst5
+:CMP^".B:G" src5B, dst5B_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0x6) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) {
+ tmp:1 = dst5B_afterSrc5;
+ src:1 = src5B;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ setResultFlags(tmp);
+}
+
+# (5) CMP.B:G src5, Ax
+:CMP^".B:G" src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0x6) ... & $(SRC5B) & $(DST5AX) ... {
+ tmp:1 = dst5Ax:1;
+ src:1 = src5B;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ setResultFlags(tmp);
+}
+
+# (5) CMP.W:G src5, dst5
+:CMP^".W:G" src5W, dst5W_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0x6) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) {
+ tmp:2 = dst5W_afterSrc5;
+ src:2 = src5W;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ setResultFlags(tmp);
+}
+
+# (5) CMP.W:G src5, Ax
+:CMP^".W:G" src5W, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0x6) ... & $(SRC5W) & $(DST5AX) ... {
+ tmp:2 = dst5Ax:2;
+ src:2 = src5W;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ setResultFlags(tmp);
+}
+
+# (6) CMP.L:G src5, dst5
+:CMP^".L:G" src5L, dst5L_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=1) ... & $(SRC5L) ... & $(DST5L_AFTER_SRC5) ... {
+ tmp:4 = dst5L_afterSrc5;
+ src:4 = src5L;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ setResultFlags(tmp);
+}
+
+# (6) CMP.L:G src5, Ax
+:CMP^".L:G" src5L, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=1) ... & $(SRC5L) & $(DST5AX) ... {
+ tmp:4 = zext(dst5Ax);
+ src:4 = src5L;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ setResultFlags(tmp);
+}
+
+# (7) CMP.B:S src2, R0L
+:CMP^".B:S" dst2B, R0L is (b1_0607=1 & b1_0103=0 & b1_size_0=0 & R0L) ... & dst2B {
+ tmp:1 = dst2B;
+ setSubtractFlags(R0L, tmp);
+ tmp = tmp - R0L;
+ setResultFlags(tmp);
+}
+
+# (7) CMP.W:S src2, R0
+:CMP^".W:S" dst2W, R0 is (b1_0607=1 & b1_0103=0 & b1_size_0=1 & R0) ... & dst2W {
+ tmp:2 = dst2W;
+ setSubtractFlags(R0, tmp);
+ tmp = tmp - R0;
+ setResultFlags(tmp);
+}
+
+##### CMPX #####
+
+# CMPX #simm, dst5
+:CMPX srcSimm8, dst5L is ((b1_0407=0xa & b1_size_0=0; b2_0005=0x11) ... & $(DST5L)); srcSimm8 {
+ tmp:4 = dst5L;
+ imm:4 = sext(srcSimm8);
+ setSubtractFlags(tmp, imm);
+ tmp = tmp - imm;
+ setResultFlags(tmp);
+}
+
+# CMPX #simm, Ax
+:CMPX srcSimm8, dst5Ax is ((b1_0407=0xa & b1_size_0=0; b2_0005=0x11) & $(DST5AX)); srcSimm8 {
+ tmp:4 = zext(dst5Ax);
+ imm:4 = sext(srcSimm8);
+ setSubtractFlags(tmp, imm);
+ tmp = tmp - imm;
+ setResultFlags(tmp);
+}
+
+##### DADC #####
+
+# (1) DADC.B #imm, dst5
+:DADC.B srcImm8, dst5B is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x0e) ... & $(DST5B)); srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(dst5B);
+ tmp:2 = DecimalAddWithCarry(src, dst);
+ dst5B = tmp:1;
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (1) DADC.B #imm, Ax
+:DADC.B srcImm8, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x0e) & $(DST5AX)); srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(dst5Ax:1);
+ tmp:2 = DecimalAddWithCarry(src, dst);
+ dst5Ax = zext(tmp:1);
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (1) DADC.W #imm, dst5
+:DADC.W srcImm16, dst5W is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x0e) ... & $(DST5W)); srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(dst5W);
+ tmp:4 = DecimalAddWithCarry(src, dst);
+ dst5W = tmp:2;
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+# (1) DADC.W #imm, Ax
+:DADC.W srcImm16, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x0e) & $(DST5AX)); srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(dst5Ax:2);
+ tmp:4 = DecimalAddWithCarry(src, dst);
+ dst5Ax = zext(tmp:2);
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+# (2) DADC.B src5, dst5
+:DADC.B src5B, dst5B_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x8) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ...) {
+ src:2 = zext(src5B);
+ dst:2 = zext(dst5B_afterSrc5);
+ tmp:2 = DecimalAddWithCarry(src, dst);
+ dst5B_afterSrc5 = tmp:1;
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (2) DADC.B src5, Ax
+:DADC.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x8) ... & $(SRC5B) & $(DST5AX) ...) {
+ src:2 = zext(src5B);
+ dst:2 = zext(dst5Ax:1);
+ tmp:2 = DecimalAddWithCarry(src, dst);
+ dst5Ax = zext(tmp:1);
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (2) DADC.W src5, dst5
+:DADC.W src5W, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x8) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ...) {
+ src:4 = zext(src5W);
+ dst:4 = zext(dst5W_afterSrc5);
+ tmp:4 = DecimalAddWithCarry(src, dst);
+ dst5W_afterSrc5 = tmp:2;
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+# (2) DADC.W src5, Ax
+:DADC.W src5W, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x8) ... & $(SRC5W) & $(DST5AX) ...) {
+ src:4 = zext(src5W);
+ dst:4 = zext(dst5Ax:2);
+ tmp:4 = DecimalAddWithCarry(src, dst);
+ dst5Ax = zext(tmp:2);
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+##### DADD #####
+
+# (1) DADD.B #imm, dst5
+:DADD.B srcImm8, dst5B is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x1e) ... & $(DST5B)); srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(dst5B);
+ tmp:2 = DecimalAdd(src, dst);
+ dst5B = tmp:1;
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (1) DADD.B #imm, Ax
+:DADD.B srcImm8, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x1e) & $(DST5AX)); srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(dst5Ax:1);
+ tmp:2 = DecimalAdd(src, dst);
+ dst5Ax = zext(tmp:1);
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (1) DADD.W #imm, dst5
+:DADD.W srcImm16, dst5W is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x1e) ... & $(DST5W)); srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(dst5W);
+ tmp:4 = DecimalAdd(src, dst);
+ dst5W = tmp:2;
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+# (1) DADD.W #imm, Ax
+:DADD.W srcImm16, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x1e) & $(DST5AX)); srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(dst5Ax:2);
+ tmp:4 = DecimalAdd(src, dst);
+ dst5Ax = zext(tmp:2);
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+# (2) DADD.B src5, dst5
+:DADD.B src5B, dst5B_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x0) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ...) {
+ src:2 = zext(src5B);
+ dst:2 = zext(dst5B_afterSrc5);
+ tmp:2 = DecimalAdd(src, dst);
+ dst5B_afterSrc5 = tmp:1;
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (2) DADD.B src5, Ax
+:DADD.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x0) ... & $(SRC5B) & $(DST5AX) ...) {
+ src:2 = zext(src5B);
+ dst:2 = zext(dst5Ax:1);
+ tmp:2 = DecimalAdd(src, dst);
+ dst5Ax = zext(tmp:1);
+ $(CARRY) = (tmp > 0x99);
+ setResultFlags(tmp:1);
+}
+
+# (2) DADD.W src5, dst5
+:DADD.W src5W, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x0) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ...) {
+ src:4 = zext(src5W);
+ dst:4 = zext(dst5W_afterSrc5);
+ tmp:4 = DecimalAdd(src, dst);
+ dst5W_afterSrc5 = tmp:2;
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+# (2) DADD.W src5, Ax
+:DADD.W src5W, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x0) ... & $(SRC5W) & $(DST5AX) ...) {
+ src:4 = zext(src5W);
+ dst:4 = zext(dst5Ax:2);
+ tmp:4 = DecimalAdd(src, dst);
+ dst5Ax = zext(tmp:2);
+ $(CARRY) = (tmp > 0x9999);
+ setResultFlags(tmp:2);
+}
+
+##### DEC #####
+
+# DEC.B dst5
+:DEC.B dst5B is (b1_0407=0xb & b1_size_0=0; b2_0005=0x0e) ... & $(DST5B) {
+ tmp:1 = dst5B - 1;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# DEC.B Ax
+:DEC.B dst5Ax is (b1_0407=0xb & b1_size_0=0; b2_0005=0x0e) & $(DST5AX) {
+ tmp:1 = dst5Ax:1 - 1;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# DEC.W dst5
+:DEC.W dst5W is (b1_0407=0xb & b1_size_0=1; b2_0005=0x0e) ... & $(DST5W) {
+ tmp:2 = dst5W - 1;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# DEC.W Ax
+:DEC.W dst5Ax is (b1_0407=0xb & b1_size_0=1; b2_0005=0x0e) & $(DST5AX) {
+ tmp:2 = dst5Ax:2 - 1;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### DIV #####
+
+# (1) DIV.B #imm
+:DIV.B srcSimm8 is b1_0007=0xb0; b2_0007=0x43; srcSimm8 {
+ d:2 = sext(srcSimm8);
+ q:2 = R0 s/ d;
+ r:2 = R0 s% d; # remainder has same sign as R0 (dividend)
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (1) DIV.W #imm
+:DIV.W srcSimm16 is b1_0007=0xb0; b2_0007=0x53; srcSimm16 {
+ d:4 = sext(srcSimm16);
+ q:4 = R2R0 s/ d;
+ r:4 = R2R0 s% d; # remainder has same sign as R0 (dividend)
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIV.B src5
+:DIV.B dst5B is (b1_0407=0x8 & b1_size_0=0; b2_0005=0x1e) ... & $(DST5B) {
+ d:2 = sext(dst5B);
+ q:2 = R0 s/ d;
+ r:2 = R0 s% d; # remainder has same sign as R0 (dividend)
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIV.W src5
+:DIV.W dst5W is (b1_0407=0x8 & b1_size_0=1; b2_0005=0x1e) ... & $(DST5W) {
+ d:4 = sext(dst5W);
+ q:4 = R2R0 s/ d;
+ r:4 = R2R0 s% d; # remainder has same sign as R0 (dividend)
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+##### DIVU #####
+
+# (1) DIVU.B #imm
+:DIVU.B srcImm8 is b1_0007=0xb0; b2_0007=0x03; srcImm8 {
+ d:2 = zext(srcImm8);
+ q:2 = R0 / d;
+ r:2 = R0 % d;
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (1) DIVU.W #imm
+:DIVU.W srcImm16 is b1_0007=0xb0; b2_0007=0x13; srcImm16 {
+ d:4 = zext(srcImm16);
+ q:4 = R2R0 / d;
+ r:4 = R2R0 % d;
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIVU.B src5
+:DIVU.B dst5B is (b1_0407=0x8 & b1_size_0=0; b2_0005=0x0e) ... & $(DST5B) {
+ d:2 = zext(dst5B);
+ q:2 = R0 / d;
+ r:2 = R0 % d;
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIVU.W src5
+:DIVU.W dst5W is (b1_0407=0x8 & b1_size_0=1; b2_0005=0x0e) ... & $(DST5W) {
+ d:4 = zext(dst5W);
+ q:4 = R2R0 / d;
+ r:4 = R2R0 % d;
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+##### DIVX #####
+
+# (1) DIVX.B #imm
+:DIVX.B srcSimm8 is b1_0007=0xb2; b2_0007=0x43; srcSimm8 {
+ d:2 = sext(srcSimm8);
+ q:2 = R0 s/ d;
+ r:2 = R0 s% d;
+
+ #according to the manual the remainder has the same sign as the quotient
+ differ:1 = (r s< 0) != (d s< 0);
+ r = (zext(differ) * (-r)) + (zext(!differ) * r);
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (1) DIVX.W #imm
+:DIVX.W srcSimm16 is b1_0007=0xb2; b2_0007=0x53; srcSimm16 {
+ d:4 = sext(srcSimm16);
+ q:4 = R2R0 s/ d;
+ r:4 = R2R0 s% d;
+
+ #according to the manual the remainder has the same sign as the quotient
+ differ:1 = (r s< 0) != (d s< 0);
+ r = (zext(differ) * (-r)) + (zext(!differ) * r);
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIVX.B src5
+:DIVX.B dst5B is (b1_0407=0x9 & b1_size_0=0; b2_0005=0x1e) ... & $(DST5B) {
+ d:2 = sext(dst5B);
+ q:2 = R0 s/ d;
+ r:2 = R0 s% d;
+
+ #according to the manual the remainder has the same sign as the quotient
+ differ:1 = (r s< 0) != (d s< 0);
+ r = (zext(differ) * (-r)) + (zext(!differ) * r);
+ R0L = q:1;
+ R0H = r:1;
+ q = q s>> 8;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+# (2) DIVX.W src5
+:DIVX.W dst5W is (b1_0407=0x9 & b1_size_0=1; b2_0005=0x1e) ... & $(DST5W) {
+ d:4 = sext(dst5W);
+ q:4 = R2R0 s/ d;
+ r:4 = R2R0 s% d;
+
+ #according to the manual the remainder has the same sign as the quotient
+ R0 = q:2;
+ R2 = r:2;
+ q = q s>> 16;
+ $(OVERFLOW) = (d == 0) || ((q != 0) && (q != -1));
+}
+
+##### DSBB #####
+
+# (1) DSBB.B #imm, dst5
+:DSBB.B srcImm8, dst5B is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x0e) ... & $(DST5B)); srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(dst5B);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:2 = DecimalSubtractWithBorrow(dst, src);
+ dst5B = tmp:1;
+ setResultFlags(tmp:1);
+}
+
+# (1) DSBB.B #imm, Ax
+:DSBB.B srcImm8, dst5Ax is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x0e) & $(DST5AX)); srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(dst5Ax:1);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:2 = DecimalSubtractWithBorrow(dst, src);
+ dst5Ax = zext(tmp:1);
+ setResultFlags(tmp:1);
+}
+
+# (1) DSBB.W #imm, dst5
+:DSBB.W srcImm16, dst5W is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x0e) ... & $(DST5W)); srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(dst5W);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:4 = DecimalSubtractWithBorrow(dst, src);
+ dst5W = tmp:2;
+ setResultFlags(tmp:2);
+}
+
+# (1) DSBB.W #imm, Ax
+:DSBB.W srcImm16, dst5Ax is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x0e) & $(DST5AX)); srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(dst5Ax:2);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:4 = DecimalSubtractWithBorrow(dst, src);
+ dst5Ax = zext(tmp:2);
+ setResultFlags(tmp:2);
+}
+
+# (2) DSBB.B src5, dst5
+:DSBB.B src5B, dst5B_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0xa) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ...) {
+ src:2 = zext(src5B);
+ dst:2 = zext(dst5B_afterSrc5);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:2 = DecimalSubtractWithBorrow(dst, src);
+ dst5B_afterSrc5 = tmp:1;
+ setResultFlags(tmp:1);
+}
+
+# (2) DSBB.B src5, Ax
+:DSBB.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0xa) ... & $(SRC5B) & $(DST5AX) ...) {
+ src:2 = zext(src5B);
+ dst:2 = zext(dst5Ax:1);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:2 = DecimalSubtractWithBorrow(dst, src);
+ dst5Ax = zext(tmp:1);
+ setResultFlags(tmp:1);
+}
+
+# (2) DSBB.W src5, dst5
+:DSBB.W src5W, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0xa) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ...) {
+ src:4 = zext(src5W);
+ dst:4 = zext(dst5W_afterSrc5);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:4 = DecimalSubtractWithBorrow(dst, src);
+ dst5W_afterSrc5 = tmp:2;
+ setResultFlags(tmp:2);
+}
+
+# (2) DSBB.W src5, Ax
+:DSBB.W src5W, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0xa) ... & $(SRC5W) & $(DST5AX) ...) {
+ src:4 = zext(src5W);
+ dst:4 = zext(dst5Ax:2);
+ c:1 = $(CARRY);
+ $(CARRY) = (c && (dst > src)) || (!c && (dst >= src));
+ tmp:4 = DecimalSubtractWithBorrow(dst, src);
+ dst5Ax = zext(tmp:2);
+ setResultFlags(tmp:2);
+}
+
+##### DSUB #####
+
+# (1) DSUB.B #imm, dst5
+:DSUB.B srcImm8, dst5B is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x1e) ... & $(DST5B)); srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(dst5B);
+ $(CARRY) = (dst >= src);
+ tmp:2 = DecimalSubtract(dst, src);
+ dst5B = tmp:1;
+ setResultFlags(tmp:1);
+}
+
+# (1) DSUB.B #imm, Ax
+:DSUB.B srcImm8, dst5Ax is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x1e) & $(DST5AX)); srcImm8 {
+ src:2 = zext(srcImm8);
+ dst:2 = zext(dst5Ax:1);
+ $(CARRY) = (dst >= src);
+ tmp:2 = DecimalSubtract(dst, src);
+ dst5Ax = zext(tmp:1);
+ setResultFlags(tmp:1);
+}
+
+# (1) DSUB.W #imm, dst5
+:DSUB.W srcImm16, dst5W is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x1e) ... & $(DST5W)); srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(dst5W);
+ $(CARRY) = (dst >= src);
+ tmp:4 = DecimalSubtract(dst, src);
+ dst5W = tmp:2;
+ setResultFlags(tmp:2);
+}
+
+# (1) DSUB.W #imm, Ax
+:DSUB.W srcImm16, dst5Ax is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x1e) & $(DST5AX)); srcImm16 {
+ src:4 = zext(srcImm16);
+ dst:4 = zext(dst5Ax:2);
+ $(CARRY) = (dst >= src);
+ tmp:4 = DecimalSubtract(dst, src);
+ dst5Ax = zext(tmp:2);
+ setResultFlags(tmp:2);
+}
+
+# (2) DSUB.B src5, dst5
+:DSUB.B src5B, dst5B_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x2) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ...) {
+ src:2 = zext(src5B);
+ dst:2 = zext(dst5B_afterSrc5);
+ $(CARRY) = (dst >= src);
+ tmp:2 = DecimalSubtract(dst, src);
+ dst5B_afterSrc5 = tmp:1;
+ setResultFlags(tmp:1);
+}
+
+# (2) DSUB.B src5, Ax
+:DSUB.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x2) ... & $(SRC5B) & $(DST5AX) ...) {
+ src:2 = zext(src5B);
+ dst:2 = zext(dst5Ax:1);
+ $(CARRY) = (dst >= src);
+ tmp:2 = DecimalSubtract(dst, src);
+ dst5Ax = zext(tmp:1);
+ setResultFlags(tmp:1);
+}
+
+# (2) DSUB.W src5, dst5
+:DSUB.W src5W, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x2) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ...) {
+ src:4 = zext(src5W);
+ dst:4 = zext(dst5W_afterSrc5);
+ $(CARRY) = (dst >= src);
+ tmp:4 = DecimalSubtract(dst, src);
+ dst5W_afterSrc5 = tmp:2;
+ setResultFlags(tmp:2);
+}
+
+# (2) DSUB.W src5, Ax
+:DSUB.W src5W, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x2) ... & $(SRC5W) & $(DST5AX) ...) {
+ src:4 = zext(src5W);
+ dst:4 = zext(dst5Ax:2);
+ $(CARRY) = (dst >= src);
+ tmp:4 = DecimalSubtract(dst, src);
+ dst5Ax = zext(tmp:2);
+ setResultFlags(tmp:2);
+}
+
+##### ENTER #####
+
+:ENTER srcImm8 is b1_0007=0xec; srcImm8 {
+ push3(FB);
+ FB = SP;
+ SP = SP - zext(srcImm8);
+}
+
+##### EXITD #####
+
+:EXITD is b1_0007=0xfc {
+ SP = FB;
+ pop3(FB);
+ pc:3 = 0;
+ pop3(pc);
+ return [pc];
+}
+
+##### EXTS #####
+
+# (1) EXTS.B dst5
+:EXTS.B dst5B is (b1_0407=0xc & b1_size_0=0; b2_0005=0x1e) ... & $(DST5B) & $(DST5W) {
+ tmp:2 = sext(dst5B);
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) EXTS.B Ax
+:EXTS.B dst5Ax is (b1_0407=0xc & b1_size_0=0; b2_0005=0x1e) & $(DST5AX) {
+ tmp:2 = sext(dst5Ax:1);
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) EXTS.W dst5
+:EXTS.W dst5W is (b1_0407=0xc & b1_size_0=1; b2_0005=0x1e) ... & $(DST5W) & $(DST5L) {
+ tmp:4 = sext(dst5W);
+ dst5L = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) EXTS.W Ax
+:EXTS.W dst5Ax is (b1_0407=0xc & b1_size_0=1; b2_0005=0x1e) & $(DST5AX) {
+ tmp:4 = sext(dst5Ax:2);
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+# (2) EXTS.B src5, dst5
+:EXTS.B src5B, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x7) ... & $(SRC5B) ... & $(DST5W_AFTER_SRC5) ...) {
+ tmp:2 = sext(src5B);
+ dst5W_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) EXTS.B src5, Ax
+:EXTS.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x7) ... & $(SRC5B) & $(DST5AX) ...) {
+ tmp:2 = sext(src5B);
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### EXTZ #####
+
+# (1) EXTZ.B src5, dst5
+:EXTZ.B src5B, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0xb) ... & $(SRC5B) ... & $(DST5W_AFTER_SRC5) ...) {
+ tmp:2 = zext(src5B);
+ dst5W_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) EXTZ.B src5, Ax
+:EXTZ.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0xb) ... & $(SRC5B) & $(DST5AX) ...) {
+ tmp:2 = zext(src5B);
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### FCLR #####
+
+:FCLR flagBit is b1_0007=0xd3; b2_0307=0x1d & flagBit {
+ mask:2 = ~(1 << flagBit);
+ FLG = FLG & mask;
+}
+
+##### FREIT #####
+
+:FREIT is b1_0007=0x9f {
+ FLG = SVF;
+ return [SVP];
+}
+
+##### FSET #####
+
+:FSET flagBit is b1_0007=0xd1; b2_0307=0x1d & flagBit {
+ mask:2 = (1 << flagBit);
+ FLG = FLG | mask;
+}
+
+##### INC #####
+
+# INC.B dst5
+:INC.B dst5B is (b1_0407=0xa & b1_size_0=0; b2_0005=0x0e) ... & $(DST5B) {
+ tmp:1 = dst5B + 1;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# INC.B Ax
+:INC.B dst5Ax is (b1_0407=0xa & b1_size_0=0; b2_0005=0x0e) & $(DST5AX) {
+ tmp:1 = dst5Ax:1 + 1;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# INC.W dst5
+:INC.W dst5W is (b1_0407=0xa & b1_size_0=1; b2_0005=0x0e) ... & $(DST5W) {
+ tmp:2 = dst5W + 1;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# INC.W Ax
+:INC.W dst5Ax is (b1_0407=0xa & b1_size_0=1; b2_0005=0x0e) & $(DST5AX) {
+ tmp:2 = dst5Ax:2 + 1;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### INDEXB #####
+
+# 1000 1000 0100 0011 INDEXB.B R1H
+:INDEXB.B dst5B is (b1_0407=0x8 & b1_size_0=0; b2_0005=0x03) ... & $(DST5B)
+ [ useByteIndexOffset=3; globalset(inst_next,useByteIndexOffset); useByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5B);
+}
+
+:INDEXB.W dst5W is (b1_0407=0x8 & b1_size_0=0; b2_0005=0x13) ... & $(DST5W)
+ [ useByteIndexOffset=3; globalset(inst_next,useByteIndexOffset); useByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5W);
+}
+
+##### INDEXBD #####
+
+:INDEXBD.B dst5B is (b1_0407=0xa & b1_size_0=0; b2_0005=0x03) ... & $(DST5B)
+ [ useDstByteIndexOffset=3; globalset(inst_next,useDstByteIndexOffset); useDstByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5B);
+}
+
+:INDEXBD.W dst5W is (b1_0407=0xa & b1_size_0=0; b2_0005=0x13) ... & $(DST5W)
+ [ useDstByteIndexOffset=3; globalset(inst_next,useDstByteIndexOffset); useDstByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5W);
+}
+
+##### INDEXBS #####
+
+:INDEXBS.B dst5B is (b1_0407=0xc & b1_size_0=0; b2_0005=0x03) ... & $(DST5B)
+ [ useSrcByteIndexOffset=3; globalset(inst_next,useSrcByteIndexOffset); useSrcByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5B);
+}
+
+:INDEXBS.W dst5W is (b1_0407=0xc & b1_size_0=0; b2_0005=0x13) ... & $(DST5W)
+ [ useSrcByteIndexOffset=3; globalset(inst_next,useSrcByteIndexOffset); useSrcByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5W);
+}
+
+##### INDEXL #####
+
+:INDEXL.B dst5B is (b1_0407=0x9 & b1_size_0=0; b2_0005=0x23) ... & $(DST5B)
+ [ useByteIndexOffset=3; globalset(inst_next,useByteIndexOffset); useByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5B) * 4;
+}
+
+:INDEXL.W dst5W is (b1_0407=0x9 & b1_size_0=0; b2_0005=0x33) ... & $(DST5W)
+ [ useByteIndexOffset=3; globalset(inst_next,useByteIndexOffset); useByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5W) * 4;
+}
+
+##### INDEXLD #####
+
+:INDEXLD.B dst5B is (b1_0407=0xb & b1_size_0=0; b2_0005=0x23) ... & $(DST5B)
+ [ useDstByteIndexOffset=3; globalset(inst_next,useDstByteIndexOffset); useDstByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5B) * 4;
+}
+
+:INDEXLD.W dst5W is (b1_0407=0xb & b1_size_0=0; b2_0005=0x33) ... & $(DST5W)
+ [ useDstByteIndexOffset=3; globalset(inst_next,useDstByteIndexOffset); useDstByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5W) * 4;
+}
+
+##### INDEXLS #####
+
+:INDEXLS.B dst5B is (b1_0407=0x9 & b1_size_0=0; b2_0005=0x03) ... & $(DST5B)
+ [ useSrcByteIndexOffset=3; globalset(inst_next,useSrcByteIndexOffset); useSrcByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5B) * 4;
+}
+
+:INDEXLS.W dst5W is (b1_0407=0x9 & b1_size_0=0; b2_0005=0x13) ... & $(DST5W)
+ [ useSrcByteIndexOffset=3; globalset(inst_next,useSrcByteIndexOffset); useSrcByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5W) * 4;
+}
+
+##### INDEXW #####
+
+:INDEXW.B dst5B is (b1_0407=0x8 & b1_size_0=0; b2_0005=0x23) ... & $(DST5B)
+ [ useByteIndexOffset=3; globalset(inst_next,useByteIndexOffset); useByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5B) * 2;
+}
+
+:INDEXW.W dst5W is (b1_0407=0x8 & b1_size_0=0; b2_0005=0x33) ... & $(DST5W)
+ [ useByteIndexOffset=3; globalset(inst_next,useByteIndexOffset); useByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5W) * 2;
+}
+
+##### INDEXWD #####
+
+:INDEXWD.B dst5B is (b1_0407=0xa & b1_size_0=0; b2_0005=0x23) ... & $(DST5B)
+ [ useDstByteIndexOffset=3; globalset(inst_next,useDstByteIndexOffset); useDstByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5B) * 2;
+}
+
+:INDEXWD.W dst5W is (b1_0407=0xa & b1_size_0=0; b2_0005=0x33) ... & $(DST5W)
+ [ useDstByteIndexOffset=3; globalset(inst_next,useDstByteIndexOffset); useDstByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5W) * 2;
+}
+
+##### INDEXWS #####
+
+:INDEXWS.B dst5B is (b1_0407=0xc & b1_size_0=0; b2_0005=0x23) ... & $(DST5B)
+ [ useSrcByteIndexOffset=3; globalset(inst_next,useSrcByteIndexOffset); useSrcByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5B) * 2;
+}
+
+:INDEXWS.W dst5W is (b1_0407=0xc & b1_size_0=0; b2_0005=0x33) ... & $(DST5W)
+ [ useSrcByteIndexOffset=3; globalset(inst_next,useSrcByteIndexOffset); useSrcByteIndexOffset=0; ] {
+ byteIndexOffset = zext(dst5W) * 2;
+}
+
+##### INT #####
+
+:INT srcIntNum is b1_0007=0xbe; imm8_0001=0 & srcIntNum {
+ push2(FLG);
+ next:3 = inst_next;
+ push3(next);
+ ptr3:3 = (INTB + (zext(srcIntNum) * 0x4));
+ pc:3 = *:3 ptr3;
+ $(STACK_SEL) = ((srcIntNum > 0x1f) * $(STACK_SEL));
+ $(INTERRUPT) = 0x0;
+ $(DEBUG) = 0x0;
+ call [pc];
+}
+
+##### INTO #####
+
+:INTO is b1_0007=0xbf {
+ if ($(OVERFLOW) == 0) goto inst_next;
+ push2(FLG);
+ next:3 = inst_next;
+ push3(next);
+ $(STACK_SEL) = 0;
+ $(INTERRUPT) = 0x0;
+ $(DEBUG) = 0x0;
+ call 0x0ffffe0;
+}
+
+##### JCnd #####
+
+:J^b1cnd rel8offset1 is b1_0707=1 & b1_0103=5 & b1cnd; rel8offset1 {
+ if (b1cnd) goto rel8offset1;
+}
+
+##### JMP #####
+
+:JMP.S rel3offset2 is b1_0607=1 & b1_0103=5 & rel3offset2 {
+ goto rel3offset2;
+}
+
+:JMP.B rel8offset1 is b1_0007=0xbb; rel8offset1 {
+ goto rel8offset1;
+}
+
+:JMP.W rel16offset1 is b1_0007=0xce; rel16offset1 {
+ goto rel16offset1;
+}
+
+:JMP.A abs24offset is b1_0007=0xcc; abs24offset {
+ goto abs24offset;
+}
+
+##### JMPI #####
+:JMPI.W reloffset_dst5W is (b1_0407=0xc & b1_size_0=1; b2_0005=0x0f) ... & reloffset_dst5W {
+ goto reloffset_dst5W;
+}
+
+:JMPI.A reloffset_dst5L is (b1_0407=0x8 & b1_size_0=0; b2_0005=0x01) ... & reloffset_dst5L {
+ goto reloffset_dst5L;
+}
+
+:JMPI.A reloffset_dst5Ax is (b1_0407=0x8 & b1_size_0=0; b2_0005=0x01) & reloffset_dst5Ax {
+ goto reloffset_dst5Ax;
+}
+
+##### JMPS #####
+
+:JMPS srcImm8 is b1_0007=0xdc; srcImm8 {
+ # 18 <= srcImm8 <= 255 (range restriction not enforced by pattern match)
+ ptr:3 = 0x0fffe - (zext(srcImm8) << 1);
+ pc:3 = 0xff0000 | zext(*:2 ptr);
+ goto [pc];
+}
+
+##### JSR #####
+
+:JSR.W rel16offset1 is b1_0007=0xcf; rel16offset1 {
+ next:3 = inst_next;
+ push3(next);
+ call rel16offset1;
+}
+
+:JSR.A abs24offset is b1_0007=0xcd; abs24offset {
+ next:3 = inst_next;
+ push3(next);
+ call abs24offset;
+}
+
+##### JSRI #####
+
+:JSRI.W reloffset_dst5W is (b1_0407=0xc & b1_size_0=1; b2_0005=0x1f) ... & reloffset_dst5W {
+ next:3 = inst_next;
+ push3(next);
+ call reloffset_dst5W;
+}
+
+:JSRI.A dst5L is (b1_0407=0x9 & b1_size_0=0; b2_0005=0x01) ... & $(DST5L) {
+ next:3 = inst_next;
+ push3(next);
+ pc:3 = dst5L:3;
+ call [pc];
+}
+
+:JSRI.A dst5Ax is (b1_0407=0x9 & b1_size_0=0; b2_0005=0x01) & $(DST5AX) {
+ next:3 = inst_next;
+ push3(next);
+ call [dst5Ax];
+}
+
+##### JSRS #####
+
+:JSRS srcImm8 is b1_0007=0xdd; srcImm8 {
+ # 18 <= srcImm8 <= 255 (range restriction not enforced by pattern match)
+ next:3 = inst_next;
+ push3(next);
+ ptr:3 = 0x0fffe - (zext(srcImm8) << 1);
+ pc:3 = 0xff0000 | zext(*:2 ptr);
+ call [pc];
+}
+
+##### LDC #####
+
+# (1) LDC #imm16, b2_creg16
+:LDC srcImm16, b2_creg16 is b1_0007=0xd5; b2_0307=0x15 & b2_creg16; srcImm16 {
+ b2_creg16 = srcImm16;
+}
+
+# (2) LDC #imm24, b2_creg24
+:LDC srcImm24, b2_creg24 is b1_0007=0xd5; b2_0307=0x05 & b2_creg24; srcImm24 {
+ b2_creg24 = srcImm24;
+}
+
+# (3) LDC #imm24, b2_dreg24
+:LDC srcImm24, b2_dreg24 is b1_0007=0xd5; b2_0307=0x0d & b2_dreg24; srcImm24 {
+ b2_dreg24 = srcImm24;
+}
+
+# (4) LDC dst5, b2_creg16
+:LDC dst5W, b2_creg16 is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=1; b2_0305=1 & b2_creg16) ... & $(DST5W)) {
+ b2_creg16 = dst5W;
+}
+
+# (5) LDC dst5, b2_creg24
+:LDC dst5L, b2_creg24 is (b1_0407=0xd & b1_size_0=1; b2_0305=0 & b2_creg24) ... & $(DST5L) {
+ b2_creg24 = dst5L:3;
+}
+
+# (6) LDC dst5, b2_dreg24
+:LDC dst5L, b2_dreg24 is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=1; b2_0305=0 & b2_dreg24) ... & $(DST5L)) {
+ b2_dreg24 = dst5L:3;
+}
+
+##### LDCTX #####
+
+:LDCTX abs16offset, abs24offset is b1_0007=0xb6; b2_0007=0xc3; abs16offset; imm24_dat & abs24offset {
+
+ taskNum:1 = abs16offset; # load task number stored at abs16
+ ptr:3 = imm24_dat + (zext(taskNum) * 2); # compute table entry address relative to abs24
+ regInfo:1 = *:1 ptr;
+ ptr = ptr + 1;
+ spCorrect:1 = *:1 ptr;
+
+ ptr = SP;
+
+ if ((regInfo & 1) == 0) goto ;
+ R0 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ R1 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ R2 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ R3 = *:2 ptr;
+ ptr = ptr + 2;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ tmp:4 = *:4 ptr;
+ A0 = tmp:3;
+ ptr = ptr + 4;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ tmp = *:4 ptr;
+ A1 = tmp:3;
+ ptr = ptr + 4;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ tmp = *:4 ptr;
+ SB = tmp:3;
+ ptr = ptr + 4;
+
+ regInfo = regInfo >> 1;
+ if ((regInfo & 1) == 0) goto ;
+ tmp = *:4 ptr;
+ FB = tmp:3;
+ ptr = ptr + 4;
+
+ SP = SP + zext(spCorrect);
+}
+
+##### LDIPL #####
+
+:LDIPL srcImm3 is b1_0007=0xd5; b2_0307=0x1d & srcImm3 {
+ $(IPL) = srcImm3;
+}
+
+##### MAX #####
+
+# (1) MAX.B #imm, dst5
+:MAX.B srcSimm8, dst5B is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x3f) ... & $(DST5B)); srcSimm8 {
+ if (srcSimm8 s<= dst5B) goto inst_next;
+ dst5B = srcSimm8;
+}
+
+# (1) MAX.B #imm, Ax
+:MAX.B srcSimm8, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x3f) & $(DST5AX)); srcSimm8 {
+ if (srcSimm8 s<= dst5Ax:1) goto inst_next;
+ dst5Ax = zext(srcSimm8);
+}
+
+# (1) MAX.W #imm, dst5
+:MAX.W srcSimm16, dst5W is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x3f) ... & $(DST5W)); srcSimm16 {
+ if (srcSimm16 s<= dst5W) goto inst_next;
+ dst5W = srcSimm16;
+}
+
+# (1) MAX.W #imm, Ax
+:MAX.W srcSimm16, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x3f) & $(DST5AX)); srcSimm16 {
+ if (srcSimm16 s<= dst5Ax:2) goto inst_next;
+ dst5Ax = zext(srcSimm16);
+}
+
+# (2) MAX.B src5, dst5
+:MAX.B src5B, dst5B_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0xd) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ...) {
+ val:1 = src5B;
+ if (val s<= dst5B_afterSrc5) goto inst_next;
+ dst5B_afterSrc5 = val;
+}
+
+# (2) MAX.B src5, Ax
+:MAX.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0xd) ... & $(SRC5B) & $(DST5AX) ...) {
+ val:1 = src5B;
+ if (val s<= dst5Ax:1) goto inst_next;
+ dst5Ax = zext(val);
+}
+
+# (2) MAX.W src5, dst5
+:MAX.W src5W, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0xd) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ...) {
+ val:2 = src5W;
+ if (val s<= dst5W_afterSrc5) goto inst_next;
+ dst5W_afterSrc5 = val;
+}
+
+# (2) MAX.W src5, Ax
+:MAX.B src5W, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0xd) ... & $(SRC5W) & $(DST5AX) ...) {
+ val:2 = src5W;
+ if (val s<= dst5Ax:2) goto inst_next;
+ dst5Ax = zext(val);
+}
+
+##### MIN #####
+
+# (1) MIN.B #imm, dst5
+:MIN.B srcSimm8, dst5B is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x2f) ... & $(DST5B)); srcSimm8 {
+ if (srcSimm8 s>= dst5B) goto inst_next;
+ dst5B = srcSimm8;
+}
+
+# (1) MIN.B #imm, Ax
+:MIN.B srcSimm8, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x2f) & $(DST5AX)); srcSimm8 {
+ if (srcSimm8 s>= dst5Ax:1) goto inst_next;
+ dst5Ax = zext(srcSimm8);
+}
+
+# (1) MIN.W #imm, dst5
+:MIN.W srcSimm16, dst5W is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x2f) ... & $(DST5W)); srcSimm16 {
+ if (srcSimm16 s>= dst5W) goto inst_next;
+ dst5W = srcSimm16;
+}
+
+# (1) MIN.W #imm, Ax
+:MIN.W srcSimm16, dst5Ax is b0_0007=0x1; ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x2f) & $(DST5AX)); srcSimm16 {
+ if (srcSimm16 s>= dst5Ax:2) goto inst_next;
+ dst5Ax = zext(srcSimm16);
+}
+
+# (2) MIN.B src5, dst5
+:MIN.B src5B, dst5B_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0xc) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ...) {
+ val:1 = src5B;
+ if (val s>= dst5B_afterSrc5) goto inst_next;
+ dst5B_afterSrc5 = val;
+}
+
+# (2) MIN.B src5, Ax
+:MIN.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0xc) ... & $(SRC5B) & $(DST5AX) ...) {
+ val:1 = src5B;
+ if (val s>= dst5Ax:1) goto inst_next;
+ dst5Ax = zext(val);
+}
+
+# (2) MIN.W src5, dst5
+:MIN.W src5W, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0xc) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ...) {
+ val:2 = src5W;
+ if (val s>= dst5W_afterSrc5) goto inst_next;
+ dst5W_afterSrc5 = val;
+}
+
+# (2) MIN.W src5, Ax
+:MIN.B src5W, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0xc) ... & $(SRC5W) & $(DST5AX) ...) {
+ val:2 = src5W;
+ if (val s>= dst5Ax:2) goto inst_next;
+ dst5Ax = zext(val);
+}
+
+##### MOV #####
+
+# (1) MOV.B:G #imm, dst5
+:MOV^".B:G" srcImm8, dst5B is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x2f) ... & $(DST5B)); srcImm8 {
+ val:1 = srcImm8;
+ dst5B = val;
+ setResultFlags(val);
+}
+
+# (1) MOV.B:G #imm, Ax
+:MOV^".B:G" srcImm8, dst5Ax is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x2f) & $(DST5AX)); srcImm8 {
+ val:1 = srcImm8;
+ dst5Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (1) MOV.W:G #imm, dst5
+:MOV^".W:G" srcImm16, dst5W is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x2f) ... & $(DST5W)); srcImm16 {
+ val:2 = srcImm16;
+ dst5W = val;
+ setResultFlags(val);
+}
+
+# (1) MOV.W:G #imm, Ax
+:MOV^".W:G" srcImm16, dst5Ax is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x2f) & $(DST5AX)); srcImm16 {
+ val:2 = srcImm16;
+ dst5Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (2) MOV.L:G #imm, dst5
+:MOV^".L:G" srcImm32, dst5L is ((b1_0407=0xb & b1_size_0=0; b2_0005=0x31) ... & $(DST5L)); srcImm32 {
+ val:4 = srcImm32;
+ dst5L = val;
+ setResultFlags(val);
+}
+
+# (2) MOV.L:G #imm, Ax
+:MOV^".L:G" srcImm32, dst5Ax is ((b1_0407=0xb & b1_size_0=0; b2_0005=0x31) & $(DST5AX)); srcImm32 {
+ val:4 = srcImm32;
+ dst5Ax = val:3;
+ setResultFlags(val);
+}
+
+# (3) MOV.B:Q #imm4, dst5
+:MOV^".B:Q" srcSimm4, dst5B is (b1_0407=0xf & b1_size_0=0; b2_0405=2 & srcSimm4) ... & $(DST5B) {
+ val:1 = srcSimm4;
+ dst5B = val;
+ setResultFlags(val);
+}
+
+# (3) MOV.B:Q #imm4, Ax
+:MOV^".B:Q" srcSimm4, dst5Ax is (b1_0407=0xf & b1_size_0=0; b2_0405=2 & srcSimm4) & $(DST5AX) {
+ val:1 = srcSimm4;
+ dst5Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (3) MOV.W:Q #imm4, dst5
+:MOV^".W:Q" srcSimm4, dst5W is (b1_0407=0xf & b1_size_0=1; b2_0405=2 & srcSimm4) ... & $(DST5W) {
+ val:2 = sext(srcSimm4);
+ dst5W = val;
+ setResultFlags(val);
+}
+
+# (3) MOV.W:Q #imm4, Ax
+:MOV^".W:Q" srcSimm4, dst5Ax is (b1_0407=0xf & b1_size_0=1; b2_0405=2 & srcSimm4) & $(DST5AX) {
+ val:2 = sext(srcSimm4);
+ dst5Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (4) MOV.B:S #imm, dst2
+:MOV^".B:S" srcImm8, dst2B is ((b1_0607=0 & b1_0103=2 & b1_size_0=0) ... & dst2B); srcImm8 {
+ val:1 = srcImm8;
+ dst2B = val;
+ setResultFlags(val);
+}
+
+# (4) MOV.W:S #imm, dst2
+:MOV^".W:S" srcImm16, dst2W is ((b1_0607=0 & b1_0103=2 & b1_size_0=1) ... & dst2W); srcImm16 {
+ val:2 = srcImm16;
+ dst2W = val;
+ setResultFlags(val);
+}
+
+# (5) MOV.W:S #imm16, Ax
+:MOV^".W:S" srcImm16, b1_d1_regAx is b1_0607=2 & b1_size_5=0 & b1_0104=0xe & b1_d1_regAx; srcImm16 {
+ val:2 = srcImm16;
+ b1_d1_regAx = zext(val);
+ setResultFlags(val);
+}
+
+# (5) MOV.L:S #imm24, Ax
+:MOV^".L:S" srcImm24, b1_d1_regAx is b1_0607=2 & b1_size_5=1 & b1_0104=0xe & b1_d1_regAx; srcImm24 {
+ val:3 = srcImm24;
+ b1_d1_regAx = val;
+ setResultFlags(val);
+}
+
+# (6) MOV.B:Z #0, dst2
+:MOV^".B:Z" srcZero8, dst2B is (b1_0607=0 & b1_0103=1 & b1_size_0=0 & srcZero8) ... & dst2B {
+ dst2B = 0;
+ $(SIGN) = 0;
+ $(ZERO) = 1;
+}
+
+# (6) MOV.W:Z #0, dst2
+:MOV^".W:Z" srcZero16, dst2W is (b1_0607=0 & b1_0103=1 & b1_size_0=1 & srcZero16) ... & dst2W {
+ dst2W = 0;
+ $(SIGN) = 0;
+ $(ZERO) = 1;
+}
+
+# (7) MOV.B:G src5, dst5
+:MOV^".B:G" src5B, dst5B_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0xb) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ... {
+ val:1 = src5B;
+ dst5B_afterSrc5 = val;
+ setResultFlags(val);
+}
+
+# (7) MOV.B:G src5, Ax
+:MOV^".B:G" src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0xb) ... & $(SRC5B) & $(DST5AX) ... {
+ val:1 = src5B;
+ dst5Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (7) MOV.W:G src5, dst5
+:MOV^".W:G" src5W, dst5W_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0xb) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ... {
+ val:2 = src5W;
+ dst5W_afterSrc5 = val;
+ setResultFlags(val);
+}
+
+# (7) MOV.W:G src5, Ax
+:MOV^".W:G" src5W, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0xb) ... & $(SRC5W) & $(DST5AX) ... {
+ val:2 = src5W;
+ dst5Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (8) MOV.L:G src5, dst5
+:MOV^".L:G" src5L, dst5L_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0x3) ... & $(SRC5L) ... & $(DST5L_AFTER_SRC5) ... {
+ val:4 = src5L;
+ dst5L_afterSrc5 = val;
+ setResultFlags(val);
+}
+
+# (8) MOV.L:G src5, Ax
+:MOV^".L:G" src5L, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0x3) ... & $(SRC5L) & $(DST5AX) ... {
+ val:4 = src5L;
+ dst5Ax = val:3;
+ setResultFlags(val);
+}
+
+# (9) MOV.B:S src2, R0L
+:MOV^".B:S" dst2B, R0L is (R0L & b1_0607=0 & b1_0103=4 & b1_size_0=0) ... & dst2B {
+ val:1 = dst2B;
+ R0L = val;
+ setResultFlags(val);
+}
+
+# (9) MOV.W:S src2, R0
+:MOV^".W:S" dst2W, R0 is (R0 & b1_0607=0 & b1_0103=4 & b1_size_0=1) ... & dst2W {
+ val:2 = dst2W;
+ R0 = val;
+ setResultFlags(val);
+}
+
+# (10) MOV.B:S src2, R1L
+:MOV^".B:S" dst2B, R1L is (R1L & b1_0607=1 & b1_0103=7 & b1_size_0=0) ... & dst2B {
+ val:1 = dst2B;
+ R1L = val;
+ setResultFlags(val);
+}
+
+# (10) MOV.W:S src2, R1
+:MOV^".W:S" dst2W, R1 is (R1 & b1_0607=1 & b1_0103=7 & b1_size_0=1) ... & dst2W {
+ val:2 = dst2W;
+ R1 = val;
+ setResultFlags(val);
+}
+
+# (11) MOV.B:S R0L, dst2
+:MOV^".B:S" R0L, dst2B is (R0L & b1_0607=0 & b1_0103=0 & b1_size_0=0) ... & dst2B {
+ val:1 = R0L;
+ dst2B = val;
+ setResultFlags(val);
+}
+
+# (11) MOV.W:S R0, dst2
+:MOV^".W:S" R0, dst2W is (R0 & b1_0607=0 & b1_0103=0 & b1_size_0=1) ... & dst2W {
+ val:2 = R0;
+ dst2W = val;
+ setResultFlags(val);
+}
+
+# (12) MOV.L:S src2L, Ax
+:MOV^".L:S" dst2L, b1_d1_regAx is (b1_0607=1 & b1_0103=4 & b1_d1_regAx) ... & dst2L {
+ val:4 = dst2L;
+ b1_d1_regAx = val:3;
+ setResultFlags(val);
+}
+
+# (13) MOV.B:G dsp:8[SP], dst5
+# 1011 0110 1000 1111 0001 0010 1110 1111 1100 1101 1010 1011 MOV.G:G 0x12(SP),0xabcdef
+:MOV^".B:G" dsp8spB, dst5B_afterDsp8 is (b1_0407=0xb & b1_size_0=0; b2_0005=0x0f; dsp8spB) ... & $(DST5B_AFTER_DSP8) {
+ val:1 = dsp8spB;
+ dst5B_afterDsp8 = val;
+ setResultFlags(val);
+}
+
+# (13) MOV.B:G dsp:8[SP], Ax
+:MOV^".B:G" dsp8spB, dst5Ax is (b1_0407=0xb & b1_size_0=0; b2_0005=0x0f; dsp8spB) & $(DST5AX) ... {
+ val:1 = dsp8spB;
+ dst5Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (13) MOV.W:G dsp:8[SP], dst5
+:MOV^".W:G" dsp8spW, dst5W_afterDsp8 is (b1_0407=0xb & b1_size_0=1; b2_0005=0x0f; dsp8spW) ... & $(DST5W_AFTER_DSP8) {
+ val:2 = dsp8spW;
+ dst5W_afterDsp8 = val;
+ setResultFlags(val);
+}
+
+# (13) MOV.W:G dsp:8[SP], Ax
+:MOV^".W:G" dsp8spW, dst5Ax is (b1_0407=0xb & b1_size_0=1; b2_0005=0x0f; dsp8spW) & $(DST5AX) ... {
+ val:2 = dsp8spW;
+ dst5Ax = zext(val);
+ setResultFlags(val);
+}
+
+# (14) MOV.B:G src5, dsp:8[SP]
+:MOV^".B:G" dst5B, dsp8spB is ((b1_0407=0xa & b1_size_0=0; b2_0005=0x0f) ... & $(DST5B)); dsp8spB {
+ val:1 = dst5B;
+ dsp8spB = val;
+ setResultFlags(val);
+}
+
+# (14) MOV.W:G src5, dsp:8[SP]
+:MOV^".W:G" dst5W, dsp8spW is ((b1_0407=0xa & b1_size_0=1; b2_0005=0x0f) ... & $(DST5W)); dsp8spW {
+ val:2 = dst5W;
+ dsp8spW = val;
+ setResultFlags(val);
+}
+
+##### MOVA #####
+
+# MOVA dst5A, RxRx
+:MOVA dst5A, b2_reg32 is (b1_0407=0xd & b1_size_0=1; b2_0105=0xc & b2_reg32) ... & $(DST5A) {
+ b2_reg32 = zext(dst5A);
+}
+
+# MOVA dst5A, Ax
+:MOVA dst5A, b2_regAx is (b1_0407=0xd & b1_size_0=1; b2_0105=0xd & b2_regAx) ... & $(DST5A) {
+ b2_regAx = dst5A;
+}
+
+##### MOVDir #####
+
+# TODO: dst5B=Ax case will parse but is not valid
+
+# (1) MOVDir R0L, dst
+:MOVLL R0L, dst5B is R0L & b0_0007=0x1; ((b1_0407=0xb & b1_size_0=0; b2_0005=0x0e) ... & $(DST5B)) {
+ dst5B = (R0L & 0x0f) | (dst5B & 0xf0);
+}
+:MOVHL R0L, dst5B is R0L & b0_0007=0x1; ((b1_0407=0xb & b1_size_0=0; b2_0005=0x1e) ... & $(DST5B)) {
+ dst5B = ((R0L & 0xf0) >> 4) | (dst5B & 0xf0);
+}
+:MOVLH R0L, dst5B is R0L & b0_0007=0x1; ((b1_0407=0xb & b1_size_0=0; b2_0005=0x2e) ... & $(DST5B)) {
+ dst5B = ((R0L & 0x0f) << 4) | (dst5B & 0x0f);
+}
+:MOVHH R0L, dst5B is R0L & b0_0007=0x1; ((b1_0407=0xb & b1_size_0=0; b2_0005=0x3e) ... & $(DST5B)) {
+ dst5B = (R0L & 0xf0) | (dst5B & 0x0f);
+}
+
+# (2) MOVDir dst, R0L
+:MOVLL dst5B, R0L is R0L & b0_0007=0x1; ((b1_0407=0xa & b1_size_0=0; b2_0005=0x0e) ... & $(DST5B)) {
+ R0L = (dst5B & 0x0f) | (R0L & 0xf0);
+}
+:MOVHL dst5B, R0L is R0L & b0_0007=0x1; ((b1_0407=0xa & b1_size_0=0; b2_0005=0x1e) ... & $(DST5B)) {
+ R0L = ((dst5B & 0xf0) >> 4) | (R0L & 0xf0);
+}
+:MOVLH dst5B, R0L is R0L & b0_0007=0x1; ((b1_0407=0xa & b1_size_0=0; b2_0005=0x2e) ... & $(DST5B)) {
+ R0L = ((dst5B & 0x0f) << 4) | (R0L & 0x0f);
+}
+:MOVHH dst5B, R0L is R0L & b0_0007=0x1; ((b1_0407=0xa & b1_size_0=0; b2_0005=0x3e) ... & $(DST5B)) {
+ R0L = (dst5B & 0xf0) | (R0L & 0x0f);
+}
+
+##### MOVX #####
+
+:MOVX srcSimm8, dst5L is ((b1_0407=0xb & b1_size_0=0; b2_0005=0x11) ... & $(DST5L)); srcSimm8 {
+ val:4 = sext(srcSimm8);
+ dst5L = val;
+ setResultFlags(val);
+}
+
+:MOVX srcSimm8, dst5Ax is ((b1_0407=0xb & b1_size_0=0; b2_0005=0x11) & $(DST5AX)); srcSimm8 {
+ val:3 = sext(srcSimm8);
+ dst5Ax = val;
+ setResultFlags(val);
+}
+
+##### MUL #####
+
+# TODO: Illegal MUL destination cases will parse but are not valid (e.g., R0H/R2, R1H/R3)
+
+# (1) MUL.B #imm, dst5
+:MUL.B srcSimm8, dst5B is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x1f) ... & $(DST5W) & $(DST5B)); srcSimm8 {
+ dst5W = sext(srcSimm8) * sext(dst5B);
+}
+
+# (1) MUL.B #imm, Ax
+:MUL.B srcSimm8, dst5Ax is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x1f) & $(DST5AX)); srcSimm8 {
+ val:2 = sext(srcSimm8) * sext(dst5Ax:1);
+ dst5Ax = zext(val);
+}
+
+# (1) MUL.W #imm, dst5
+:MUL.W srcSimm16, dst5W is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x1f) ... & $(DST5L) & $(DST5W)); srcSimm16 {
+ dst5L = sext(srcSimm16) * sext(dst5W);
+}
+
+# (1) MUL.W #imm, Ax
+:MUL.W srcSimm16, dst5Ax is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x1f) & $(DST5AX)); srcSimm16 {
+ val:4 = sext(srcSimm16) * sext(dst5Ax:2);
+ dst5Ax = val:3;
+}
+
+# (2) MUL.B src5, dst5
+:MUL.B src5B, dst5B_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0xc) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ... & $(DST5W_AFTER_SRC5) ... {
+ dst5W_afterSrc5 = sext(src5B) * sext(dst5B_afterSrc5);
+}
+
+# (2) MUL.B src5, Ax
+:MUL.B src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0xc) ... & $(SRC5B) & $(DST5AX) ... {
+ val:2 = sext(src5B) * sext(dst5Ax:1);
+ dst5Ax = zext(val);
+}
+
+# (2) MUL.W src5, dst5
+:MUL.W src5W, dst5W_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0xc) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ... & $(DST5L_AFTER_SRC5) ... {
+ dst5L_afterSrc5 = sext(src5W) * sext(dst5W_afterSrc5);
+}
+
+# (2) MUL.W src5, Ax
+:MUL.W src5W, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0xc) ... & $(SRC5W) & $(DST5AX) ... {
+ val:4 = sext(src5W) * sext(dst5Ax:2);
+ dst5Ax = val:3;
+}
+
+##### MULEX #####
+
+:MULEX dst5W is (b1_0407=0xc & b1_size_0=1; b2_0005=0x3e) ... & $(DST5W) {
+ R1R2R0 = sext(R2R0) * sext(dst5W);
+}
+
+##### MULU #####
+
+# TODO: Illegal MULU destination cases will parse but are not valid (e.g., R0H/R2, R1H/R3)
+
+# (1) MULU.B #imm, dst5
+:MULU.B srcImm8, dst5B is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x0f) ... & $(DST5B) & $(DST5W)); srcImm8 {
+ dst5W = zext(srcImm8) * zext(dst5B);
+}
+
+# (1) MULU.B #imm, Ax
+:MULU.B srcImm8, dst5Ax is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x0f) & $(DST5AX)); srcImm8 {
+ val:2 = zext(srcImm8) * zext(dst5Ax:1);
+ dst5Ax = zext(val);
+}
+
+# (1) MULU.W #imm, dst5
+:MULU.W srcImm16, dst5W is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x0f) ... & $(DST5W) & $(DST5L)); srcImm16 {
+ dst5L = zext(srcImm16) * zext(dst5W);
+}
+
+# (1) MULU.W #imm, Ax
+:MULU.W srcImm16, dst5Ax is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x0f) & $(DST5AX)); srcImm16 {
+ val:4 = zext(srcImm16) * zext(dst5Ax:2);
+ dst5Ax = val:3;
+}
+
+# (2) MULU.B src5, dst5
+:MULU.B src5B, dst5B_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0x4) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ... & $(DST5W_AFTER_SRC5) ... {
+ dst5W_afterSrc5 = zext(src5B) * zext(dst5B_afterSrc5);
+}
+
+# (2) MULU.B src5, Ax
+:MULU.B src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0x4) ... & $(SRC5B) & $(DST5AX) ... {
+ val:2 = zext(src5B) * zext(dst5Ax:1);
+ dst5Ax = zext(val);
+}
+
+# (2) MULU.W src5, dst5
+:MULU.W src5W, dst5W_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0x4) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ... & $(DST5L_AFTER_SRC5) ... {
+ dst5L_afterSrc5 = zext(src5W) * zext(dst5W_afterSrc5);
+}
+
+# (2) MULU.W src5, Ax
+:MULU.W src5W, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0x4) ... & $(SRC5W) & $(DST5AX) ... {
+ val:4 = zext(src5W) * zext(dst5Ax:2);
+ dst5Ax = val:3;
+}
+
+##### NEG #####
+
+# NEG.B dst5
+:NEG.B dst5B is (b1_0407=0xa & b1_size_0=0; b2_0005=0x2f) ... & $(DST5B) {
+ tmp:1 = dst5B;
+ setSubtractFlags(0:1, tmp);
+ tmp = -tmp;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# NEG.B Ax
+:NEG.B dst5Ax is (b1_0407=0xa & b1_size_0=0; b2_0005=0x2f) & $(DST5AX) {
+ tmp:1 = dst5Ax:1;
+ setSubtractFlags(0:1, tmp);
+ tmp = -tmp;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# NEG.W dst5
+:NEG.W dst5W is (b1_0407=0xa & b1_size_0=1; b2_0005=0x2f) ... & $(DST5W) {
+ tmp:2 = dst5W;
+ setSubtractFlags(0:2, tmp);
+ tmp = -tmp;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# NEG.W Ax
+:NEG.W dst5Ax is (b1_0407=0xa & b1_size_0=1; b2_0005=0x2f) & $(DST5AX) {
+ tmp:2 = dst5Ax:2;
+ setSubtractFlags(0:2, tmp);
+ tmp = -tmp;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### NOP #####
+
+:NOP is b1_0007=0xde {
+}
+
+##### NOT #####
+
+# NOT.B dst5
+:NOT.B dst5B is (b1_0407=0xa & b1_size_0=0; b2_0005=0x1e) ... & $(DST5B) {
+ tmp:1 = ~dst5B;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# NOT.B Ax
+:NOT.B dst5Ax is (b1_0407=0xa & b1_size_0=0; b2_0005=0x1e) & $(DST5AX) {
+ tmp:1 = ~dst5Ax:1;
+ tmp = tmp;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# NOT.W dst5
+:NOT.W dst5W is (b1_0407=0xa & b1_size_0=1; b2_0005=0x1e) ... & $(DST5W) {
+ tmp:2 = ~dst5W;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# NOT.W Ax
+:NOT.W dst5Ax is (b1_0407=0xa & b1_size_0=1; b2_0005=0x1e) & $(DST5AX) {
+ tmp:2 = ~dst5Ax:2;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### OR #####
+
+# (1) OR.B:G #imm, dst
+:OR^".B:G" srcImm8, dst5B is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x2f) ... & $(DST5B)); srcImm8 {
+ tmp:1 = dst5B & srcImm8;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) OR.B:G #imm, Ax
+:OR^".B:G" srcImm8, dst5Ax is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x2f) & $(DST5AX)); srcImm8 {
+ tmp:1 = dst5Ax:1 & srcImm8;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) OR.W:G #imm, dst
+:OR^".W:G" srcImm16, dst5W is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x2f) ... & $(DST5W)); srcImm16 {
+ tmp:2 = dst5W & srcImm16;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) OR.W:G #imm, Ax
+:OR^".W:G" srcImm16, dst5Ax is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x2f) & $(DST5AX)); srcImm16 {
+ tmp:2 = dst5Ax:2 & srcImm16;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) OR.B:S #imm, dst
+:OR^".B:S" srcImm8, dst2B is ((b1_0607=1 & b1_0103=2 & b1_size_0=0) ... & dst2B); srcImm8 {
+ tmp:1 = dst2B & srcImm8;
+ dst2B = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) OR.W:S #imm, dst
+:OR^".W:S" srcImm16, dst2W is ((b1_0607=1 & b1_0103=2 & b1_size_0=1) ... & dst2W); srcImm16 {
+ tmp:2 = dst2W & srcImm16;
+ dst2W = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) OR.B:G src5, dst5
+:OR^".B:G" src5B, dst5B_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0x5) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ... {
+ tmp:1 = dst5B_afterSrc5 & src5B;
+ dst5B_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) OR.B:G src5, Ax
+:OR^".B:G" src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0x5) ... & $(SRC5B) & $(DST5AX) ... {
+ tmp:1 = dst5Ax:1 & src5B;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (3) OR.W:G src5, dst5
+:OR^".W:G" src5W, dst5W_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0x5) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ... {
+ tmp:2 = dst5W_afterSrc5 & src5W;
+ dst5W_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) OR.W:G src5, Ax
+:OR^".W:G" src5W, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0x5) ... & $(SRC5W) & $(DST5AX) ... {
+ tmp:2 = dst5Ax:2 & src5W;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### POP #####
+
+# POP.B dst5
+:POP.B dst5B is (b1_0407=0xb & b1_size_0=0; b2_0005=0x2f) ... & $(DST5B) {
+ pop1(dst5B);
+}
+
+# POP.B Ax
+:POP.B dst5Ax is (b1_0407=0xb & b1_size_0=0; b2_0005=0x2f) & $(DST5AX) {
+ val:1 = 0;
+ pop1(val);
+ dst5Ax = zext(val);
+}
+
+# POP.W dst5
+:POP.W dst5W is (b1_0407=0xb & b1_size_0=1; b2_0005=0x2f) ... & $(DST5W) {
+ pop2(dst5W);
+}
+
+# POP.W Ax
+:POP.W dst5Ax is (b1_0407=0xb & b1_size_0=1; b2_0005=0x2f) & $(DST5AX) {
+ val:2 = 0;
+ pop2(val);
+ dst5Ax = zext(val);
+}
+
+##### POPC #####
+
+# (1) POPC reg16
+:POPC b2_creg16 is b1_0007=0xd3; b2_0307=0x15 & b2_creg16 {
+ pop2(b2_creg16);
+}
+
+# (2) POPC reg24
+:POPC b2_creg24 is b1_0007=0xd3; b2_0307=0x05 & b2_creg24 {
+ pop3(b2_creg24);
+}
+
+##### POPM #####
+popRegFB: FB is regBit7=1 & FB { pop3(FB); }
+popRegFB: is regBit7=0 { }
+
+popRegSB: SB popRegFB is regBit6=1 & popRegFB & SB { pop3(SB); build popRegFB; }
+popRegSB: popRegFB is popRegFB { build popRegFB; }
+
+popRegA1: A1 popRegSB is regBit5=1 & popRegSB & A1 { pop3(A1); build popRegSB; }
+popRegA1: popRegSB is popRegSB { build popRegSB; }
+popRegA0: A0 popRegA1 is regBit4=1 & popRegA1 & A0 { pop3(A0); build popRegA1; }
+popRegA0: popRegA1 is popRegA1 { build popRegA1; }
+
+popRegR3: R3 popRegA0 is regBit3=1 & popRegA0 & R3 { pop2(R3); build popRegA0; }
+popRegR3: popRegA0 is popRegA0 { build popRegA0; }
+popRegR2: R2 popRegR3 is regBit2=1 & popRegR3 & R2 { pop2(R2); build popRegR3; }
+popRegR2: popRegR3 is popRegR3 { build popRegR3; }
+popRegR1: R1 popRegR2 is regBit1=1 & popRegR2 & R1 { pop2(R1); build popRegR2; }
+popRegR1: popRegR2 is popRegR2 { build popRegR2; }
+popRegR0: R0 popRegR1 is regBit0=1 & popRegR1 & R0 { pop2(R0); build popRegR1; }
+popRegR0: popRegR1 is popRegR1 { build popRegR1; }
+
+popRegList: "( "^popRegR0^")" is popRegR0 { build popRegR0; }
+
+:POPM popRegList is b1_0007=0x8e; popRegList {
+ build popRegList;
+}
+
+##### PUSH #####
+
+# (1) PUSH.B #imm
+:PUSH.B srcImm8 is b1_0007=0xae; srcImm8 {
+ push1(srcImm8);
+#tmp:2 = zext(srcImm8); # This differs from what really happens - decompiler tries to resolve source of unknown byte on stack
+#push2(tmp);
+}
+
+# (1) PUSH.W #imm
+:PUSH.B srcImm16 is b1_0007=0xaf; srcImm16 {
+ push2(srcImm16);
+}
+
+# (2) PUSH.B src5
+:PUSH.B dst5B is (b1_0407=0xc & b1_size_0=0; b2_0005=0x0e) ... & $(DST5B) {
+ push1(dst5B);
+#tmp:2 = zext(dst5B); # This differs from what really happens - decompiler tries to resolve source of unknown byte on stack
+#push2(tmp);
+}
+
+# (2) PUSH.W src5
+:PUSH.W dst5W is (b1_0407=0xc & b1_size_0=1; b2_0005=0x0e) ... & $(DST5W) {
+ push2(dst5W);
+}
+
+# (3) PUSH.L #imm
+:PUSH.L srcImm32 is b1_0007=0xb6; b2_0007=0x53; srcImm32 {
+ push4(srcImm32);
+}
+
+# (4) PUSH.L src5
+:PUSH.L dst5L is (b1_0407=0xa & b1_size_0=0; b2_0005=0x01) ... & $(DST5L) {
+ push4(dst5L);
+}
+
+##### PUSHA #####
+
+:PUSHA dst5A is (b1_0407=0xb & b1_size_0=0; b2_0005=0x01) ... & $(DST5A) {
+ push3(dst5A);
+#tmp:4 = zext(dst5A); # This differs from what really happens - decompiler tries to resolve source of unknown byte on stack
+#push4(tmp);
+}
+
+##### PUSHC #####
+
+# (1) PUSHC reg16
+:PUSHC b2_creg16 is b1_0007=0xd1; b2_0307=0x15 & b2_creg16 {
+ push2(b2_creg16);
+}
+
+# (2) PUSHC reg24
+:PUSHC b2_creg24 is b1_0007=0xd1; b2_0307=0x05 & b2_creg24 {
+ push3(b2_creg24);
+#tmp:4 = zext(b2_creg24); # This differs from what really happens - decompiler tries to resolve source of unknown byte on stack
+#push4(tmp);
+}
+
+##### PUSHM #####
+pushRegR0: R0 is regBit7=1 & R0 { push2(R0); }
+pushRegR0: is regBit7=0 { }
+pushRegR1: pushRegR0 R1 is regBit6=1 & pushRegR0 & R1 { push2(R1); build pushRegR0; }
+pushRegR1: pushRegR0 is pushRegR0 { build pushRegR0; }
+pushRegR2: pushRegR1 R2 is regBit5=1 & pushRegR1 & R2 { push2(R2); build pushRegR1; }
+pushRegR2: pushRegR1 is pushRegR1 { build pushRegR1; }
+pushRegR3: pushRegR2 R3 is regBit4=1 & pushRegR2 & R3 { push2(R3); build pushRegR2; }
+pushRegR3: pushRegR2 is pushRegR2 { build pushRegR2; }
+
+pushRegA0: pushRegR3 A0 is regBit3=1 & pushRegR3 & A0 { push3(A0); build pushRegR3; }
+pushRegA0: pushRegR3 is pushRegR3 { build pushRegR3; }
+pushRegA1: pushRegA0 A1 is regBit2=1 & pushRegA0 & A1 { push3(A1); build pushRegA0; }
+pushRegA1: pushRegA0 is pushRegA0 { build pushRegA0; }
+
+pushRegSB: pushRegA1 SB is regBit1=1 & pushRegA1 & SB { push3(SB); build pushRegA1; }
+pushRegSB: pushRegA1 is pushRegA1 { build pushRegA1; }
+
+pushRegFB: pushRegSB FB is regBit0=1 & pushRegSB & FB { push3(FB); build pushRegSB; }
+pushRegFB: pushRegSB is pushRegSB { build pushRegSB; }
+
+pushRegList: "("^pushRegFB^" )" is pushRegFB { build pushRegFB; }
+
+:PUSHM pushRegList is b1_0007=0x8f; pushRegList {
+ build pushRegList;
+}
+
+##### REIT #####
+
+:REIT is b1_0007=0x9e {
+ pc:3 = 0;
+ pop3(pc);
+ pop2(FLG);
+ return [pc];
+}
+
+##### RMPA #####
+
+:RMPA.B is b1_0007=0xb8; b2_0007=0x43 {
+ if (R3 == 0) goto inst_next;
+ a:1 = *:1 A0;
+ b:1 = *:1 A1;
+ A0 = A0 + 1;
+ A1 = A1 + 1;
+ prod:6 = sext(a) * sext(b);
+ o:1 = scarry(R1R2R0, prod);
+ $(OVERFLOW) = o | $(OVERFLOW);
+ R1R2R0 = R1R2R0 + prod;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:RMPA.W is b1_0007=0xb8; b2_0007=0x53 {
+ if (R3 == 0) goto inst_next;
+ a:2 = *:2 A0;
+ b:2 = *:2 A1;
+ A0 = A0 + 2;
+ A1 = A1 + 2;
+ prod:6 = sext(a) * sext(b);
+ o:1 = scarry(R1R2R0, prod);
+ $(OVERFLOW) = o | $(OVERFLOW);
+ R1R2R0 = R1R2R0 + prod;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+##### ROLC #####
+
+:ROLC.B dst5B is (b1_0407=0xb & b1_size_0=0; b2_0005=0x2e) ... & $(DST5B) {
+ c:1 = $(CARRY);
+ tmp:1 = dst5B;
+ $(CARRY) = tmp s< 0;
+ tmp = (tmp << 1) | c;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+:ROLC.B dst5Ax is (b1_0407=0xb & b1_size_0=0; b2_0005=0x2e) & $(DST5AX) {
+ c:1 = $(CARRY);
+ tmp:1 = dst5Ax:1;
+ $(CARRY) = tmp s< 0;
+ tmp = (tmp << 1) | c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+:ROLC.W dst5W is (b1_0407=0xb & b1_size_0=1; b2_0005=0x2e) ... & $(DST5W) {
+ c:2 = zext($(CARRY));
+ tmp:2 = dst5W;
+ $(CARRY) = tmp s< 0;
+ tmp = (tmp << 1) | c;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+:ROLC.W dst5Ax is (b1_0407=0xb & b1_size_0=1; b2_0005=0x2e) & $(DST5AX) {
+ c:2 = zext($(CARRY));
+ tmp:2 = dst5Ax:2;
+ $(CARRY) = tmp s< 0;
+ tmp = (tmp << 1) | c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### RORC #####
+
+:RORC.B dst5B is (b1_0407=0xa & b1_size_0=0; b2_0005=0x2e) ... & $(DST5B) {
+ c:1 = $(CARRY);
+ tmp:1 = dst5B;
+ $(CARRY) = (tmp & 1) == 1;
+ tmp = (tmp >> 1) | (c << 7);
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+:RORC.B dst5Ax is (b1_0407=0xa & b1_size_0=0; b2_0005=0x2e) & $(DST5AX) {
+ c:1 = $(CARRY);
+ tmp:1 = dst5Ax:1;
+ $(CARRY) = (tmp & 1) == 1;
+ tmp = (tmp >> 1) | (c << 7);
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+:RORC.W dst5W is (b1_0407=0xa & b1_size_0=1; b2_0005=0x2e) ... & $(DST5W) {
+ c:2 = zext($(CARRY));
+ tmp:2 = dst5W;
+ $(CARRY) = (tmp & 1) == 1;
+ tmp = (tmp >> 1) | (c << 15);
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+:RORC.W dst5Ax is (b1_0407=0xa & b1_size_0=1; b2_0005=0x2e) & $(DST5AX) {
+ c:2 = zext($(CARRY));
+ tmp:2 = dst5Ax:2;
+ $(CARRY) = (tmp & 1) == 1;
+ tmp = (tmp >> 1) | (c << 15);
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### ROT #####
+
+# (1) ROT.B #imm4, dst5 (right)
+:ROT.B srcSimm4Shift, dst5B is (b1_0407=0xe & b1_size_0=0; b2_0405=2 & b2_shiftSign=1 & srcSimm4Shift) ... & $(DST5B) {
+ rightShift:1 = -srcSimm4Shift;
+ tmp:1 = dst5B;
+ $(CARRY) = (tmp >> (rightShift - 1)) & 1;
+ tmp = (tmp >> rightShift) | (tmp << (8 - rightShift));
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ROT.B #imm4, Ax (right)
+:ROT.B srcSimm4Shift, dst5Ax is (b1_0407=0xe & b1_size_0=0; b2_0405=2 & b2_shiftSign=1 & srcSimm4Shift) & $(DST5AX) {
+ rightShift:1 = -srcSimm4Shift;
+ tmp:1 = dst5Ax:1;
+ $(CARRY) = (tmp >> (rightShift - 1)) & 1;
+ tmp = (tmp >> rightShift) | (tmp << (8 - rightShift));
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ROT.W #imm4, dst5 (right)
+:ROT.W srcSimm4Shift, dst5W is (b1_0407=0xe & b1_size_0=1; b2_0405=2 & b2_shiftSign=1 & srcSimm4Shift) ... & $(DST5W) {
+ rightShift:1 = -srcSimm4Shift;
+ tmp:2 = dst5W;
+ c:2 = (tmp >> (rightShift - 1));
+ $(CARRY) = c:1 & 1;
+ tmp = (tmp >> rightShift) | (tmp << (16 - rightShift));
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ROT.W #imm4, Ax (right)
+:ROT.W srcSimm4Shift, dst5Ax is (b1_0407=0xe & b1_size_0=1; b2_0405=2 & b2_shiftSign=1 & srcSimm4Shift) & $(DST5AX) {
+ rightShift:1 = -srcSimm4Shift;
+ tmp:2 = dst5Ax:2;
+ c:2 = (tmp >> (rightShift - 1));
+ $(CARRY) = c:1 & 1;
+ tmp = (tmp >> rightShift) | (tmp << (16 - rightShift));
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ROT.B #imm4, dst5 (left)
+:ROT.B srcSimm4Shift, dst5B is (b1_0407=0xe & b1_size_0=0; b2_0405=2 & b2_shiftSign=0 & srcSimm4Shift) ... & $(DST5B) {
+ leftShift:1 = srcSimm4Shift;
+ tmp:1 = dst5B;
+ $(CARRY) = (tmp >> (8 - leftShift)) & 1;
+ tmp = (tmp << leftShift) | (tmp >> (8 - leftShift));
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ROT.B #imm4, Ax (left)
+:ROT.B srcSimm4Shift, dst5Ax is (b1_0407=0xe & b1_size_0=0; b2_0405=2 & b2_shiftSign=0 & srcSimm4Shift) & $(DST5AX) {
+ leftShift:1 = srcSimm4Shift;
+ tmp:1 = dst5Ax:1;
+ $(CARRY) = (tmp >> (8 - leftShift)) & 1;
+ tmp = (tmp << leftShift) | (tmp >> (8 - leftShift));
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) ROT.W #imm4, dst5 (left)
+:ROT.W srcSimm4Shift, dst5W is (b1_0407=0xe & b1_size_0=1; b2_0405=2 & b2_shiftSign=0 & srcSimm4Shift) ... & $(DST5W) {
+ leftShift:1 = srcSimm4Shift;
+ tmp:2 = dst5W;
+ c:2 = (tmp >> (16 - leftShift));
+ $(CARRY) = c:1 & 1;
+ tmp = (tmp << leftShift) | (tmp >> (16 - leftShift));
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) ROT.W #imm4, Ax (left)
+:ROT.W srcSimm4Shift, dst5Ax is (b1_0407=0xe & b1_size_0=1; b2_0405=2 & b2_shiftSign=0 & srcSimm4Shift) & $(DST5AX) {
+ leftShift:1 = srcSimm4Shift;
+ tmp:2 = dst5Ax:2;
+ c:2 = (tmp >> (16 - leftShift));
+ $(CARRY) = c:1 & 1;
+ tmp = (tmp << leftShift) | (tmp >> (16 - leftShift));
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) ROT.B R1H, dst5
+:ROT.B R1H, dst5B is (R1H & b1_0407=0xa & b1_size_0=0; b2_0005=0x3f) ... & $(DST5B) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H s% 8;
+ tmp:1 = dst5B;
+ if (shift s>= 0) goto ;
+ shift = -shift;
+ $(CARRY) = (tmp >> (shift - 1)) & 1;
+ tmp = (tmp >> shift) | (tmp << (8 - shift));
+ goto ;
+
+ $(CARRY) = (tmp >> (8 - shift)) & 1;
+ tmp = (tmp << shift) | (tmp >> (8 - shift));
+
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ROT.B R1H, Ax
+:ROT.B R1H, dst5Ax is (R1H & b1_0407=0xa & b1_size_0=0; b2_0005=0x3f) & $(DST5AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H s% 8;
+ tmp:1 = dst5Ax:1;
+ if (shift s>= 0) goto ;
+ shift = -shift;
+ $(CARRY) = (tmp >> (shift - 1)) & 1;
+ tmp = (tmp >> shift) | (tmp << (8 - shift));
+ goto ;
+
+ $(CARRY) = (tmp >> (8 - shift)) & 1;
+ tmp = (tmp << shift) | (tmp >> (8 - shift));
+
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) ROT.W R1H, dst5
+:ROT.W R1H, dst5W is (R1H & b1_0407=0xa & b1_size_0=1; b2_0005=0x3f) ... & $(DST5W) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H s% 16;
+ tmp:2 = dst5W;
+ if (shift s>= 0) goto ;
+ shift = -shift;
+ c:2 = (tmp >> (shift - 1));
+ tmp = (tmp >> shift) | (tmp << (16 - shift));
+ goto ;
+
+ c = (tmp >> (16 - shift));
+ tmp = (tmp << shift) | (tmp >> (16 - shift));
+
+ $(CARRY) = c:1 & 1;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) ROT.W R1H, Ax
+:ROT.W R1H, dst5Ax is (R1H & b1_0407=0xa & b1_size_0=1; b2_0005=0x3f) & $(DST5AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H s% 16;
+ tmp:2 = dst5Ax:2;
+ if (shift s>= 0) goto ;
+ shift = -shift;
+ c:2 = (tmp >> (shift - 1));
+ tmp = (tmp >> shift) | (tmp << (16 - shift));
+ goto ;
+
+ c = (tmp >> (16 - shift));
+ tmp = (tmp << shift) | (tmp >> (16 - shift));
+
+ $(CARRY) = c:1 & 1;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### RTS #####
+
+:RTS is b1_0007=0xdf {
+ pc:3 = 0;
+ pop3(pc);
+ return [pc];
+}
+
+##### SBB #####
+
+# (1) SBB.B #simm, dst
+:SBB.B srcSimm8, dst5B is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x2e) ... & $(DST5B)); srcSimm8 {
+ tmp:1 = dst5B;
+ c:1 = $(CARRY);
+ setSubtract3Flags(tmp, srcSimm8, c);
+ tmp = tmp - srcSimm8 - c;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) SBB.B #simm, Ax
+:SBB.B srcSimm8, dst5Ax is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x2e) & $(DST5AX)); srcSimm8 {
+ tmp:1 = dst5Ax:1;
+ c:1 = $(CARRY);
+ setSubtract3Flags(tmp, srcSimm8, c);
+ tmp = tmp - srcSimm8 - c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) SBB.W #simm, dst
+:SBB.W srcSimm16, dst5W is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x2e) ... & $(DST5W)); srcSimm16 {
+ tmp:2 = dst5W;
+ c:2 = zext($(CARRY));
+ setSubtract3Flags(tmp, srcSimm16, c);
+ tmp = tmp - srcSimm16 - c;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) SBB.B #simm, Ax
+:SBB.W srcSimm16, dst5Ax is b0_0007=0x1; ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x2e) & $(DST5AX)); srcSimm16 {
+ tmp:2 = dst5Ax:2;
+ c:2 = zext($(CARRY));
+ setSubtract3Flags(tmp, srcSimm16, c);
+ tmp = tmp - srcSimm16 - c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) SBB.B src5, dst5
+:SBB.B src5B, dst5B_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x6) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ...) {
+ tmp:1 = dst5B_afterSrc5;
+ s:1 = src5B;
+ c:1 = $(CARRY);
+ setSubtract3Flags(tmp, s, c);
+ tmp = tmp - s - c;
+ dst5B_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) SBB.B src5, Ax
+:SBB.B src5B, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x6) ... & $(SRC5B) & $(DST5AX) ...) {
+ tmp:1 = dst5Ax:1;
+ s:1 = src5B;
+ c:1 = $(CARRY);
+ setSubtract3Flags(tmp, s, c);
+ tmp = tmp - s - c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) SBB.W src5, dst5
+:SBB.W src5W, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x6) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ...) {
+ tmp:2 = dst5W_afterSrc5;
+ s:2 = src5W;
+ c:2 = zext($(CARRY));
+ setSubtract3Flags(tmp, s, c);
+ tmp = tmp - s - c;
+ dst5W_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) SBB.W src5, Ax
+:SBB.W src5W, dst5Ax is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x6) ... & $(SRC5W) & $(DST5AX) ...) {
+ tmp:2 = dst5Ax:2;
+ s:2 = src5W;
+ c:2 = zext($(CARRY));
+ setSubtract3Flags(tmp, s, c);
+ tmp = tmp - s - c;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+##### SBJNZ - PSUEDO-OP! SAME AS ADJNZ #####
+
+##### SCCnd #####
+
+:SC^b2cnd dst5W is (b1_0407=0xd & b1_size_0=1; b2_0405=3 & b2cnd) ... & $(DST5W) {
+ dst5W = zext(b2cnd);
+}
+
+:SC^b2cnd dst5Ax is (b1_0407=0xd & b1_size_0=1; b2_0405=3 & b2cnd) & $(DST5AX) {
+ dst5Ax = zext(b2cnd);
+}
+
+##### SCMPU #####
+
+:SCMPU.B is b1_0007=0xb8; b2_0007=0xc3 {
+ tmp0:1 = *:1 A0;
+ tmp2:1 = *:1 A1;
+ setSubtractFlags(tmp0, tmp2);
+ tmp:1 = tmp0 - tmp2;
+ setResultFlags(tmp);
+ A0 = A0 + 1;
+ A1 = A1 + 1;
+ if ((tmp0 != 0) && (tmp0 == tmp2)) goto inst_start;
+}
+
+:SCMPU.W is b1_0007=0xb8; b2_0007=0xd3 {
+ # TODO: The symantic description looks suspicious - manual may be incorrect ??
+ tmp0:1 = *:1 A0;
+ tmp2:1 = *:1 A1;
+ setSubtractFlags(tmp0, tmp2);
+ setResultFlags(tmp0 - tmp2);
+ A0 = A0 + 1;
+ A1 = A1 + 1;
+ tmp1:1 = *:1 A0;
+ tmp3:1 = *:1 A1;
+ A0 = A0 + 1;
+ A1 = A1 + 1;
+ if (tmp0 == 0 || tmp0 != tmp2) goto ;
+ setSubtractFlags(tmp1, tmp3);
+ setResultFlags(tmp1 - tmp3);
+
+ if ((tmp0 != 0) && (tmp1 != 0) && (tmp0 == tmp2) && (tmp1 == tmp3)) goto inst_start;
+}
+
+##### SHA #####
+macro SHAsetShiftRightFlags(val,shift,result) {
+ local c = (val >> (shift - 1)) & 1;
+ $(CARRY) = c:1;
+ local mask = ~(-(1 << shift));
+ allOnes:1 = (mask & val) == mask;
+ allZeros:1 = (mask & val) == 0;
+ $(OVERFLOW) = (result s< 0 && allOnes) || (result s>= 0 && allZeros);
+ setResultFlags(result);
+}
+
+macro SHAsetShiftLeftFlags(val,shift,result,sze) {
+ local c = (val >> (sze - shift)) & 1;
+ $(CARRY) = c:1;
+ local mask = -(1 << shift);
+ allOnes:1 = (mask & val) == mask;
+ allZeros:1 = (mask & val) == 0;
+ $(OVERFLOW) = (result s< 0 && allOnes) || (result s>= 0 && allZeros);
+ setResultFlags(result);
+}
+
+# (1) SHA.B #imm4, dst5 (right)
+:SHA.B srcSimm4Shift, dst5B is (b1_0407=0xf & b1_size_0=0; b2_0405=0 & b2_shiftSign=1 & srcSimm4Shift) ... & $(DST5B) {
+ val:1 = dst5B;
+ shift:1 = -srcSimm4Shift;
+ tmp:1 = val s>> shift;
+ dst5B = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHA.B #imm4, Ax (right)
+:SHA.B srcSimm4Shift, dst5Ax is (b1_0407=0xf & b1_size_0=0; b2_0405=0 & b2_shiftSign=1 & srcSimm4Shift) & $(DST5AX) {
+ val:1 = dst5Ax:1;
+ shift:1 = -srcSimm4Shift;
+ tmp:1 = val s>> shift;
+ dst5Ax = zext(tmp);
+ SHAsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHA.W #imm4, dst5 (right)
+:SHA.W srcSimm4Shift, dst5W is (b1_0407=0xf & b1_size_0=1; b2_0405=0 & b2_shiftSign=1 & srcSimm4Shift) ... & $(DST5W) {
+ val:2 = dst5W;
+ shift:1 = -srcSimm4Shift;
+ tmp:2 = val s>> shift;
+ dst5W = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHA.W #imm4, Ax (right)
+:SHA.W srcSimm4Shift, dst5Ax is (b1_0407=0xf & b1_size_0=1; b2_0405=0 & b2_shiftSign=1 & srcSimm4Shift) & $(DST5AX) {
+ val:2 = dst5Ax:2;
+ shift:1 = -srcSimm4Shift;
+ tmp:2 = val s>> shift;
+ dst5Ax = zext(tmp);
+ SHAsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHA.B #imm4, dst5 (left)
+:SHA.B srcSimm4Shift, dst5B is (b1_0407=0xf & b1_size_0=0; b2_0405=0 & b2_shiftSign=0 & srcSimm4Shift) ... & $(DST5B) {
+ val:1 = dst5B;
+ shift:1 = srcSimm4Shift;
+ tmp:1 = val << shift;
+ dst5B = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (1) SHA.B #imm4, Ax (left)
+:SHA.B srcSimm4Shift, dst5Ax is (b1_0407=0xf & b1_size_0=0; b2_0405=0 & b2_shiftSign=0 & srcSimm4Shift) & $(DST5AX) {
+ val:1 = dst5Ax:1;
+ shift:1 = srcSimm4Shift;
+ tmp:1 = val << shift;
+ dst5Ax = zext(tmp);
+ SHAsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (1) SHA.W #imm4, dst5 (left)
+:SHA.W srcSimm4Shift, dst5W is (b1_0407=0xf & b1_size_0=1; b2_0405=0 & b2_shiftSign=0 & srcSimm4Shift) ... & $(DST5W) {
+ val:2 = dst5W;
+ shift:1 = srcSimm4Shift;
+ tmp:2 = val << shift;
+ dst5W = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (1) SHA.W #imm4, Ax (left)
+:SHA.W srcSimm4Shift, dst5Ax is (b1_0407=0xf & b1_size_0=1; b2_0405=0 & b2_shiftSign=0 & srcSimm4Shift) & $(DST5AX) {
+ val:2 = dst5Ax:2;
+ shift:1 = srcSimm4Shift;
+ tmp:2 = val << shift;
+ dst5Ax = zext(tmp);
+ SHAsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (2) SHA.L #imm, dst5
+:SHA.L srcSimm8, dst5L is ((b1_0407=0xa & b1_size_0=0; b2_0005=0x21) ... & $(DST5L)); srcSimm8 {
+ # Unable to pattern match on sign bit due to interior ellipses
+ shift:1 = srcSimm8;
+ val:4 = dst5L;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val s>> shift;
+ dst5L = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5L = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 32);
+}
+
+# (2) SHA.L #imm, Ax
+:SHA.L srcSimm8, dst5Ax is ((b1_0407=0xa & b1_size_0=0; b2_0005=0x21) & $(DST5AX)); srcSimm8 {
+ # Unable to pattern match on sign bit due to interior ellipses
+ shift:1 = srcSimm8;
+ val:4 = zext(dst5Ax);
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val s>> shift;
+ dst5Ax = tmp:3;
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5Ax = tmp:3;
+# No flags set
+}
+
+# (3) SHA.B R1H, dst5
+:SHA.B R1H, dst5B is (R1H & b1_0407=0xb & b1_size_0=0; b2_0005=0x3e) ... & $(DST5B) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:1 = dst5B;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:1 = val s>> shift;
+ dst5B = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5B = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (3) SHA.B R1H, Ax
+:SHA.B R1H, dst5Ax is (R1H & b1_0407=0xb & b1_size_0=0; b2_0005=0x3e) & $(DST5AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:1 = dst5Ax:1;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:1 = val s>> shift;
+ dst5Ax = zext(tmp);
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5Ax = zext(tmp);
+ SHAsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (3) SHA.W R1H, dst5
+:SHA.W R1H, dst5W is (R1H & b1_0407=0xb & b1_size_0=1; b2_0005=0x3e) ... & $(DST5W) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:2 = dst5W;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:2 = val s>> shift;
+ dst5W = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5W = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (3) SHA.W R1H, Ax
+:SHA.W R1H, dst5Ax is (R1H & b1_0407=0xb & b1_size_0=1; b2_0005=0x3e) & $(DST5AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:2 = dst5Ax:2;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:2 = val s>> shift;
+ dst5Ax = zext(tmp);
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5Ax = zext(tmp);
+ SHAsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (4) SHA.L R1H, dst5
+:SHA.L R1H, dst5L is (R1H & b1_0407=0xc & b1_size_0=0; b2_0005=0x11) ... & $(DST5L) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:4 = dst5L;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val s>> shift;
+ dst5L = tmp;
+ SHAsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5L = tmp;
+ SHAsetShiftLeftFlags(val, shift, tmp, 32);
+}
+
+# (4) SHA.L R1H, Ax
+:SHA.L R1H, dst5Ax is (R1H & b1_0407=0xc & b1_size_0=0; b2_0005=0x11) & $(DST5AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:4 = zext(dst5Ax);
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val s>> shift;
+ dst5Ax = tmp:3;
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5Ax = tmp:3;
+# No flags set
+}
+
+##### SHL #####
+macro SHLsetShiftRightFlags(val,shift,result) {
+ local c = (val >> (shift - 1)) & 1;
+ $(CARRY) = c:1;
+ setResultFlags(result);
+}
+
+macro SHLsetShiftLeftFlags(val,shift,result,sze) {
+ local c = (val >> (sze - shift)) & 1;
+ $(CARRY) = c:1;
+ setResultFlags(result);
+}
+
+# (1) SHL.B #imm4, dst5 (right)
+:SHL.B srcSimm4Shift, dst5B is (b1_0407=0xe & b1_size_0=0; b2_0405=0 & b2_shiftSign=1 & srcSimm4Shift) ... & $(DST5B) {
+ val:1 = dst5B;
+ shift:1 = -srcSimm4Shift;
+ tmp:1 = val >> shift;
+ dst5B = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHL.B #imm4, Ax (right)
+:SHL.B srcSimm4Shift, dst5Ax is (b1_0407=0xe & b1_size_0=0; b2_0405=0 & b2_shiftSign=1 & srcSimm4Shift) & $(DST5AX) {
+ val:1 = dst5Ax:1;
+ shift:1 = -srcSimm4Shift;
+ tmp:1 = val >> shift;
+ dst5Ax = zext(tmp);
+ SHLsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHL.W #imm4, dst5 (right)
+:SHL.W srcSimm4Shift, dst5W is (b1_0407=0xe & b1_size_0=1; b2_0405=0 & b2_shiftSign=1 & srcSimm4Shift) ... & $(DST5W) {
+ val:2 = dst5W;
+ shift:1 = -srcSimm4Shift;
+ tmp:2 = val >> shift;
+ dst5W = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHL.W #imm4, Ax (right)
+:SHL.W srcSimm4Shift, dst5Ax is (b1_0407=0xe & b1_size_0=1; b2_0405=0 & b2_shiftSign=1 & srcSimm4Shift) & $(DST5AX) {
+ val:2 = dst5Ax:2;
+ shift:1 = -srcSimm4Shift;
+ tmp:2 = val >> shift;
+ dst5Ax = zext(tmp);
+ SHLsetShiftRightFlags(val, shift, tmp);
+}
+
+# (1) SHL.B #imm4, dst5 (left)
+:SHL.B srcSimm4Shift, dst5B is (b1_0407=0xe & b1_size_0=0; b2_0405=0 & b2_shiftSign=0 & srcSimm4Shift) ... & $(DST5B) {
+ val:1 = dst5B;
+ shift:1 = srcSimm4Shift;
+ tmp:1 = val << shift;
+ dst5B = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (1) SHL.B #imm4, Ax (left)
+:SHL.B srcSimm4Shift, dst5Ax is (b1_0407=0xe & b1_size_0=0; b2_0405=0 & b2_shiftSign=0 & srcSimm4Shift) & $(DST5AX) {
+ val:1 = dst5Ax:1;
+ shift:1 = srcSimm4Shift;
+ tmp:1 = val << shift;
+ dst5Ax = zext(tmp);
+ SHLsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (1) SHL.W #imm4, dst5 (left)
+:SHL.W srcSimm4Shift, dst5W is (b1_0407=0xe & b1_size_0=1; b2_0405=0 & b2_shiftSign=0 & srcSimm4Shift) ... & $(DST5W) {
+ val:2 = dst5W;
+ shift:1 = srcSimm4Shift;
+ tmp:2 = val << shift;
+ dst5W = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (1) SHL.W #imm4, Ax (left)
+:SHL.W srcSimm4Shift, dst5Ax is (b1_0407=0xe & b1_size_0=1; b2_0405=0 & b2_shiftSign=0 & srcSimm4Shift) & $(DST5AX) {
+ val:2 = dst5Ax:2;
+ shift:1 = srcSimm4Shift;
+ tmp:2 = val << shift;
+ dst5Ax = zext(tmp);
+ SHLsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (2) SHL.L #imm, dst5
+:SHL.L srcSimm8, dst5L is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x21) ... & $(DST5L)); srcSimm8 {
+ # Unable to pattern match on sign bit due to interior ellipses
+ shift:1 = srcSimm8;
+ val:4 = dst5L;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val >> shift;
+ dst5L = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5L = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 32);
+}
+
+# (2) SHL.L #imm, Ax
+:SHL.L srcSimm8, dst5Ax is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x21) & $(DST5AX)); srcSimm8 {
+ # Unable to pattern match on sign bit due to interior ellipses
+ shift:1 = srcSimm8;
+ val:4 = zext(dst5Ax);
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val >> shift;
+ dst5Ax = tmp:3;
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5Ax = tmp:3;
+# No flags set
+}
+
+# (3) SHL.B R1H, dst5
+:SHL.B R1H, dst5B is (R1H & b1_0407=0xa & b1_size_0=0; b2_0005=0x3e) ... & $(DST5B) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:1 = dst5B;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:1 = val >> shift;
+ dst5B = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5B = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (3) SHL.B R1H, Ax
+:SHL.B R1H, dst5Ax is (R1H & b1_0407=0xa & b1_size_0=0; b2_0005=0x3e) & $(DST5AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:1 = dst5Ax:1;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:1 = val >> shift;
+ dst5Ax = zext(tmp);
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5Ax = zext(tmp);
+ SHLsetShiftLeftFlags(val, shift, tmp, 8);
+}
+
+# (3) SHL.W R1H, dst5
+:SHL.W R1H, dst5W is (R1H & b1_0407=0xa & b1_size_0=1; b2_0005=0x3e) ... & $(DST5W) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:2 = dst5W;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:2 = val >> shift;
+ dst5W = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5W = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (3) SHL.W R1H, Ax
+:SHL.W R1H, dst5Ax is (R1H & b1_0407=0xa & b1_size_0=1; b2_0005=0x3e) & $(DST5AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:2 = dst5Ax:2;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:2 = val >> shift;
+ dst5Ax = zext(tmp);
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5Ax = zext(tmp);
+ SHLsetShiftLeftFlags(val, shift, tmp, 16);
+}
+
+# (4) SHL.L R1H, dst5
+:SHL.L R1H, dst5L is (R1H & b1_0407=0xc & b1_size_0=0; b2_0005=0x01) ... & $(DST5L) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:4 = dst5L;
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val >> shift;
+ dst5L = tmp;
+ SHLsetShiftRightFlags(val, shift, tmp);
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5L = tmp;
+ SHLsetShiftLeftFlags(val, shift, tmp, 32);
+}
+
+# (4) SHL.L R1H, Ax
+:SHL.L R1H, dst5Ax is (R1H & b1_0407=0xc & b1_size_0=0; b2_0005=0x01) & $(DST5AX) {
+ if (R1H == 0) goto inst_next;
+ shift:1 = R1H;
+ val:4 = zext(dst5Ax);
+ if (shift s> 0) goto ;
+ shift = -shift;
+ tmp:4 = val >> shift;
+ dst5Ax = tmp:3;
+ goto inst_next;
+
+ tmp = val << shift;
+ dst5Ax = tmp:3;
+# No flags set
+}
+
+##### SIN #####
+
+:SIN.B is b1_0007=0xb2; b2_0007=0x83 {
+ if (R3 == 0) goto inst_next;
+ *:1 A1 = *:1 A0;
+ A1 = A1 + 1;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:SIN.W is b1_0007=0xb2; b2_0007=0x93 {
+ if (R3 == 0) goto inst_next;
+ *:2 A1 = *:2 A0;
+ A1 = A1 + 2;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+##### SMOVB #####
+
+:SMOVB.B is b1_0007=0xb6; b2_0007=0x83 {
+ if (R3 == 0) goto inst_next;
+ *:1 A1 = *:1 A0;
+ A1 = A1 - 1;
+ A0 = A0 - 1;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:SMOVB.W is b1_0007=0xb6; b2_0007=0x93 {
+ if (R3 == 0) goto inst_next;
+ *:2 A1 = *:2 A0;
+ A1 = A1 - 2;
+ A0 = A0 - 2;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+##### SMOVF #####
+
+:SMOVF.B is b1_0007=0xb0; b2_0007=0x83 {
+ if (R3 == 0) goto inst_next;
+ *:1 A1 = *:1 A0;
+ A1 = A1 + 1;
+ A0 = A0 + 1;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:SMOVF.W is b1_0007=0xb0; b2_0007=0x93 {
+ if (R3 == 0) goto inst_next;
+ *:2 A1 = *:2 A0;
+ A1 = A1 + 2;
+ A0 = A0 + 2;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+##### SMOVU #####
+
+:SMOVU.B is b1_0007=0xb8; b2_0007=0x83 {
+ local tmp:1 = *:1 A0;
+ *:1 A1 = tmp;
+ A0 = A0 + 1;
+ A1 = A1 + 1;
+ if (tmp != 0) goto inst_start;
+}
+
+:SMOVU.W is b1_0007=0xb8; b2_0007=0x93 {
+ local tmp:2 = *:2 A0;
+ *:2 A1 = tmp;
+ A0 = A0 + 2;
+ A1 = A1 + 2;
+ local tmp0:2 = tmp & 0xff;
+ local tmp1:2 = tmp & 0xff00;
+ if ((tmp0 != 0) && (tmp1 != 0)) goto inst_start;
+}
+
+##### SOUT #####
+
+:SOUT.B is b1_0007=0xb4; b2_0007=0x83 {
+ if (R3 == 0) goto inst_next;
+ *:1 A1 = *:1 A0;
+ A0 = A0 + 1;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:SOUT.W is b1_0007=0xb4; b2_0007=0x93 {
+ if (R3 == 0) goto inst_next;
+ *:2 A1 = *:2 A0;
+ A0 = A0 + 2;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+##### SSTR #####
+
+:SSTR.B is b1_0007=0xb8; b2_0007=0x03 {
+ if (R3 == 0) goto inst_next;
+ *:1 A1 = R0L;
+ A1 = A1 + 1;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+:SSTR.W is b1_0007=0xb8; b2_0007=0x13 {
+ if (R3 == 0) goto inst_next;
+ *:2 A1 = R0;
+ A1 = A1 + 2;
+ R3 = R3 - 1;
+ goto inst_start;
+}
+
+##### STC #####
+
+# (1) STC dreg24, dst5
+:STC b2_dreg24, dst5L is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=1; b2_0305=0x2 & b2_dreg24) ... & $(DST5L)) {
+ dst5L = zext(b2_dreg24);
+}
+
+# (1) STC dreg24, Ax
+:STC b2_dreg24, dst5Ax is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=1; b2_0305=0x2 & b2_dreg24) & $(DST5AX)) {
+ dst5Ax = b2_dreg24;
+}
+
+# (2) STC reg16, dst5
+:STC b2_creg16, dst5W is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=1; b2_0305=0x3 & b2_creg16) ... & $(DST5W)) {
+ dst5W = b2_creg16;
+}
+
+# (2) STC reg16, Ax
+:STC b2_creg16, dst5Ax is b0_0007=0x1; ((b1_0407=0xd & b1_size_0=1; b2_0305=0x3 & b2_creg16) & $(DST5AX)) {
+ dst5Ax = zext(b2_creg16);
+}
+
+# (3) STC reg24, dst5L
+:STC b2_creg24, dst5L is (b1_0407=0xd & b1_size_0=1; b2_0305=0x2 & b2_creg24) ... & $(DST5L) {
+ dst5L = zext(b2_creg24);
+}
+
+# (3) STC reg24, Ax
+:STC b2_creg24, dst5Ax is (b1_0407=0xd & b1_size_0=1; b2_0305=0x2 & b2_creg24) & $(DST5AX) {
+ dst5Ax = b2_creg24;
+}
+
+##### STCTX #####
+
+:STCTX abs16offset, abs24offset is b1_0007=0xb6; b2_0007=0xd3; abs16offset; imm24_dat & abs24offset {
+
+ taskNum:1 = abs16offset; # load task number stored at abs16
+ ptr:3 = imm24_dat + (zext(taskNum) * 2); # compute table entry address relative to abs24
+ regInfo:1 = *:1 ptr;
+ ptr = ptr + 1;
+ spCorrect:1 = *:1 ptr;
+
+ ptr = SP;
+
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 4;
+ *:4 ptr = FB;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 4;
+ *:4 ptr = SB;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 4;
+ *:4 ptr = A1;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 4;
+ *:4 ptr = A0;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = R3;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = R2;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = R1;
+
+ regInfo = regInfo << 1;
+ if ((regInfo & 0x80) == 0) goto ;
+ ptr = ptr - 2;
+ *:2 ptr = R0;
+
+ SP = SP - zext(spCorrect);
+}
+
+##### STNZ #####
+
+# (1) STNZ.B #imm, dst5
+:STNZ.B srcImm8, dst5B is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x1f) ... & $(DST5B)); srcImm8 {
+ if ($(ZERO) != 0) goto inst_next;
+ dst5B = srcImm8;
+}
+
+# (1) STNZ.B #imm, Ax
+:STNZ.B srcImm8, dst5Ax is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x1f) & $(DST5AX)); srcImm8 {
+ if ($(ZERO) != 0) goto inst_next;
+ dst5Ax = zext(srcImm8);
+}
+
+# (1) STNZ.W #imm, dst5
+:STNZ.W srcImm16, dst5W is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x1f) ... & $(DST5W)); srcImm16 {
+ if ($(ZERO) != 0) goto inst_next;
+ dst5W = srcImm16;
+}
+
+# (1) STNZ.W #imm, Ax
+:STNZ.W srcImm16, dst5Ax is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x1f) & $(DST5AX)); srcImm16 {
+ if ($(ZERO) != 0) goto inst_next;
+ dst5Ax = zext(srcImm16);
+}
+
+##### STZ #####
+
+# (1) STZ.B #imm, dst5
+:STZ.B srcImm8, dst5B is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x0f) ... & $(DST5B)); srcImm8 {
+ if ($(ZERO) == 0) goto inst_next;
+ dst5B = srcImm8;
+}
+
+# (1) STZ.B #imm, Ax
+:STZ.B srcImm8, dst5Ax is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x0f) & $(DST5AX)); srcImm8 {
+ if ($(ZERO) == 0) goto inst_next;
+ dst5Ax = zext(srcImm8);
+}
+
+# (1) STZ.W #imm, dst5
+:STZ.W srcImm16, dst5W is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x0f) ... & $(DST5W)); srcImm16 {
+ if ($(ZERO) == 0) goto inst_next;
+ dst5W = srcImm16;
+}
+
+# (1) STZ.W #imm, Ax
+:STZ.W srcImm16, dst5Ax is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x0f) & $(DST5AX)); srcImm16 {
+ if ($(ZERO) == 0) goto inst_next;
+ dst5Ax = zext(srcImm16);
+}
+
+##### STZX #####
+
+# STZX.B #imm, #imm, dst5
+:STZX.B srcImm8, srcImm8a, dst5B is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x3f) ... & $(DST5B)); srcImm8; srcImm8a {
+ z:1 = $(ZERO);
+ dst5B = (z * srcImm8) + (!z * srcImm8a);
+}
+
+# STZX.B #imm, #imm, Ax
+:STZX.B srcImm8, srcImm8a, dst5Ax is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x3f) & $(DST5AX)); srcImm8; srcImm8a {
+ z:1 = $(ZERO);
+ dst5Ax = zext((z * srcImm8) + (!z * srcImm8a));
+}
+
+# STZX.W #imm, #imm, dst5
+:STZX.W srcImm16, srcImm16a, dst5W is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x3f) ... & $(DST5W)); srcImm16; srcImm16a {
+ z:1 = $(ZERO);
+ dst5W = (zext(z) * srcImm16) + (zext(!z) * srcImm16a);
+}
+
+# STZX.W #imm, #imm, Ax
+:STZX.W srcImm16, srcImm16a, dst5Ax is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x3f) & $(DST5AX)); srcImm16; srcImm16a {
+ z:1 = $(ZERO);
+ dst5Ax = zext((zext(z) * srcImm16) + (zext(!z) * srcImm16a));
+}
+
+##### SUB #####
+
+# (1) SUB.B:G #simm, dst
+:SUB^".B:G" srcSimm8, dst5B is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x3e) ... & $(DST5B)); srcSimm8 {
+ tmp:1 = dst5B;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) SUB.B:G #simm, Ax
+:SUB^".B:G" srcSimm8, dst5Ax is ((b1_0407=0x8 & b1_size_0=0; b2_0005=0x3e) & $(DST5AX)); srcSimm8 {
+ tmp:1 = dst5Ax:1;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) SUB.W:G #simm, dst
+:SUB^".W:G" srcSimm16, dst5W is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x3e) ... & $(DST5W)); srcSimm16 {
+ tmp:2 = dst5W;
+ setSubtractFlags(tmp, srcSimm16);
+ tmp = tmp - srcSimm16;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) SUB.W:G #simm, Ax
+:SUB^".W:G" srcSimm16, dst5Ax is ((b1_0407=0x8 & b1_size_0=1; b2_0005=0x3e) & $(DST5AX)); srcSimm16 {
+ tmp:2 = dst5Ax:2;
+ setSubtractFlags(tmp, srcSimm16);
+ tmp = tmp - srcSimm16;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) SUB.L:G #simm, dst
+:SUB^".L:G" srcSimm32, dst5L is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x31) ... & $(DST5L)); srcSimm32 {
+ tmp:4 = dst5L;
+ setSubtractFlags(tmp, srcSimm32);
+ tmp = tmp - srcSimm32;
+ dst5L = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) SUB.L:G #simm, Ax
+:SUB^".L:G" srcSimm32, dst5Ax is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x31) & $(DST5AX)); srcSimm32 {
+ tmp:4 = zext(dst5Ax);
+ setSubtractFlags(tmp, srcSimm32);
+ tmp = tmp - srcSimm32;
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+# (3) SUB.B:S #simm, dst
+:SUB^".B:S" srcSimm8, dst2B is ((b1_0607=0 & b1_0103=7 & b1_size_0=0) ... & dst2B); srcSimm8 {
+ tmp:1 = dst2B;
+ setSubtractFlags(tmp, srcSimm8);
+ tmp = tmp - srcSimm8;
+ dst2B = tmp;
+ setResultFlags(tmp);
+}
+
+# (3) SUB.W:S #simm, dst
+:SUB^".W:S" srcSimm16, dst2W is ((b1_0607=0 & b1_0103=7 & b1_size_0=1) ... & dst2W); srcSimm16 {
+ tmp:2 = dst2W;
+ setSubtractFlags(tmp, srcSimm16);
+ tmp = tmp - srcSimm16;
+ dst2W = tmp;
+ setResultFlags(tmp);
+}
+
+# (4) SUB.B:G src, dst
+:SUB^".B:G" src5B, dst5B_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0xa) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ... {
+ tmp:1 = dst5B_afterSrc5;
+ src:1 = src5B;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5B_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (4) SUB.B:G src, Ax - Ax destination case
+:SUB^".B:G" src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0xa) ... & $(SRC5B) & $(DST5AX) ... {
+ tmp:1 = dst5Ax:1;
+ src:1 = src5B;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (4) SUB.W:G src, dst
+:SUB^".W:G" src5W, dst5W_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0xa) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ... {
+ tmp:2 = dst5W_afterSrc5;
+ src:2 = src5W;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5W_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (4) SUB.W:G src, Ax - Ax destination case
+:SUB^".W:G" src5W, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0xa) ... & $(SRC5W) & $(DST5AX) ... {
+ tmp:2 = dst5Ax:2;
+ src:2 = src5W;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (5) SUB.L:G src, dst
+:SUB^".L:G" src5L, dst5L_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0x0) ... & $(SRC5L) ... & $(DST5L_AFTER_SRC5) ... {
+ tmp:4 = dst5L_afterSrc5;
+ src:4 = src5L;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5L_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (5) SUB.L:G src, Ax - Ax destination case
+:SUB^".L:G" src5L, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0x0) ... & $(SRC5L) & $(DST5AX) ... {
+ tmp:4 = zext(dst5Ax);
+ src:4 = src5L;
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+##### SUBX #####
+
+# (1) SUBX #simm, dst5
+:SUBX srcSimm8, dst5L is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x11) ... & $(DST5L)); srcSimm8 {
+ tmp:4 = dst5L;
+ src:4 = sext(srcSimm8);
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5L = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) SUBX #simm, Ax
+:SUBX srcSimm8, dst5Ax is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x11) & $(DST5AX)); srcSimm8 {
+ tmp:4 = zext(dst5Ax);
+ src:4 = sext(srcSimm8);
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+# (2) SUBX src5, dst5
+:SUBX src5B, dst5L_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0x0) ... & $(SRC5B) ... & $(DST5L_AFTER_SRC5) ... {
+ tmp:4 = dst5L_afterSrc5;
+ src:4 = sext(src5B);
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5L_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) SUBX src5, Ax
+:SUBX src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0x0) ... & $(SRC5B) & $(DST5AX) ... {
+ tmp:4 = zext(dst5Ax);
+ src:4 = sext(src5B);
+ setSubtractFlags(tmp, src);
+ tmp = tmp - src;
+ dst5Ax = tmp:3;
+ setResultFlags(tmp);
+}
+
+##### TST #####
+
+# (1) TST.B:G #imm, dst
+:TST^".B:G" srcImm8, dst5B is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x3e) ... & $(DST5B)); srcImm8 {
+ tmp:1 = dst5B & srcImm8;
+ setResultFlags(tmp);
+}
+
+# (1) TST.W:G #imm, dst
+:TST^".W:G" srcImm16, dst5W is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x3e) ... & $(DST5W)); srcImm16 {
+ tmp:2 = dst5W & srcImm16;
+ setResultFlags(tmp);
+}
+
+# (2) TST.B:S #imm, dst
+:TST^".B:S" srcImm8, dst2B is ((b1_0607=0 & b1_0103=6 & b1_size_0=0) ... & dst2B); srcImm8 {
+ tmp:1 = dst2B & srcImm8;
+ setResultFlags(tmp);
+}
+
+# (2) TST.W:S #imm, dst
+:TST^".W:S" srcImm16, dst2W is ((b1_0607=0 & b1_0103=6 & b1_size_0=1) ... & dst2W); srcImm16 {
+ tmp:2 = dst2W & srcImm16;
+ setResultFlags(tmp);
+}
+
+# (3) TST.B:G src5, dst5
+:TST^".B:G" src5B, dst5B_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=0; b2_0003=0x9) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ...) {
+ tmp:1 = dst5B_afterSrc5 & src5B;
+ setResultFlags(tmp);
+}
+
+# (3) TST.W:G src5, dst5
+:TST^".W:G" src5W, dst5W_afterSrc5 is b0_0007=0x1; ((b1_0707=1 & b1_size_0=1; b2_0003=0x9) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ...) {
+ tmp:2 = dst5W_afterSrc5 & src5W;
+ setResultFlags(tmp);
+}
+
+##### UND #####
+# Don't implement this "Undefined" instruction
+# :UND is b1_0007=0xff
+
+##### WAIT #####
+
+:WAIT is b1_0007=0xb2; b2_0007=0x03 {
+ Wait();
+}
+
+##### XCHG #####
+
+# XCHG.B reg8, dst5
+:XCHG.B b2_reg8, dst5B is (b1_0407=0xd & b1_size_0=0; b2_0305=1 & b2_0101=0 & b2_reg8) ... & $(DST5B) {
+ tmp:1 = dst5B;
+ dst5B = b2_reg8;
+ b2_reg8 = tmp;
+}
+
+# XCHG.B Ax, dst5
+:XCHG.B b2_regAx, dst5B is (b1_0407=0xd & b1_size_0=0; b2_0305=1 & b2_0102=1 & b2_regAx) ... & $(DST5B) {
+ tmp:1 = dst5B;
+ dst5B = b2_regAx:1;
+ b2_regAx = zext(tmp);
+}
+
+# XCHG.B reg8, Ax
+:XCHG.B b2_reg8, dst5Ax is (b1_0407=0xd & b1_size_0=0; b2_0305=1 & b2_0101=0 & b2_reg8) & $(DST5AX) {
+ tmp:1 = dst5Ax:1;
+ dst5Ax = zext(b2_reg8);
+ b2_reg8 = tmp;
+}
+
+# XCHG.B Ax, Ax
+:XCHG.B b2_regAx, dst5Ax is (b1_0407=0xd & b1_size_0=0; b2_0305=1 & b2_0102=1 & b2_regAx) & $(DST5AX) {
+ tmp:1 = dst5Ax:1;
+ dst5Ax = zext(b2_regAx:1);
+ b2_regAx = zext(tmp);
+}
+
+# XCHG.W reg16, dst5
+:XCHG.W b2_reg16, dst5W is (b1_0407=0xd & b1_size_0=1; b2_0305=1 & b2_0101=0 & b2_reg16) ... & $(DST5W) {
+ tmp:2 = dst5W;
+ dst5W = b2_reg16;
+ b2_reg16 = tmp;
+}
+
+# XCHG.W Ax, dst5
+:XCHG.W b2_regAx, dst5W is (b1_0407=0xd & b1_size_0=1; b2_0305=1 & b2_0102=1 & b2_regAx) ... & $(DST5W) {
+ tmp:2 = dst5W;
+ dst5W = b2_regAx:2;
+ b2_regAx = zext(tmp);
+}
+
+# XCHG.W reg16, Ax
+:XCHG.W b2_reg16, dst5Ax is (b1_0407=0xd & b1_size_0=1; b2_0305=1 & b2_0101=0 & b2_reg16) & $(DST5AX) {
+ tmp:2 = dst5Ax:2;
+ dst5Ax = zext(b2_reg16);
+ b2_reg16 = tmp;
+}
+
+# XCHG.W Ax, Ax
+:XCHG.W b2_regAx, dst5Ax is (b1_0407=0xd & b1_size_0=1; b2_0305=1 & b2_0102=1 & b2_regAx) & $(DST5AX) {
+ tmp:3 = dst5Ax;
+ dst5Ax = zext(b2_regAx:2); # dest Ax recieves low 16-bits of src Ax zero extended
+ b2_regAx = tmp; # src Ax recieves all 24-bits of dest Ax
+}
+
+##### XOR #####
+
+# (1) XOR.B #imm, dst
+:XOR^".B:G" srcImm8, dst5B is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x0e) ... & $(DST5B)); srcImm8 {
+ tmp:1 = dst5B ^ srcImm8;
+ dst5B = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) XOR.B #imm, Ax
+:XOR^".B:G" srcImm8, dst5Ax is ((b1_0407=0x9 & b1_size_0=0; b2_0005=0x0e) & $(DST5AX)); srcImm8 {
+ tmp:1 = dst5Ax:1 ^ srcImm8;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (1) XOR.W #imm, dst
+:XOR^".W:G" srcImm16, dst5W is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x0e) ... & $(DST5W)); srcImm16 {
+ tmp:2 = dst5W ^ srcImm16;
+ dst5W = tmp;
+ setResultFlags(tmp);
+}
+
+# (1) XOR.W #imm, Ax
+:XOR^".W:G" srcImm16, dst5Ax is ((b1_0407=0x9 & b1_size_0=1; b2_0005=0x0e) & $(DST5AX)); srcImm16 {
+ tmp:2 = dst5Ax:2 ^ srcImm16;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) XOR.B src5, dst5
+:XOR^".B:G" src5B, dst5B_afterSrc5 is (b1_0707=1 & b1_size_0=0; b2_0003=0x9) ... & $(SRC5B) ... & $(DST5B_AFTER_SRC5) ... {
+ tmp:1 = dst5B_afterSrc5 ^ src5B;
+ dst5B_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) XOR.B src5, Ax
+:XOR^".B:G" src5B, dst5Ax is (b1_0707=1 & b1_size_0=0; b2_0003=0x9) ... & $(SRC5B) & $(DST5AX) ... {
+ tmp:1 = dst5Ax:1 ^ src5B;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+# (2) XOR.W src5, dst5
+:XOR^".W:G" src5W, dst5W_afterSrc5 is (b1_0707=1 & b1_size_0=1; b2_0003=0x9) ... & $(SRC5W) ... & $(DST5W_AFTER_SRC5) ... {
+ tmp:2 = dst5W_afterSrc5 ^ src5W;
+ dst5W_afterSrc5 = tmp;
+ setResultFlags(tmp);
+}
+
+# (2) XOR.W src5, Ax
+:XOR^".W:G" src5W, dst5Ax is (b1_0707=1 & b1_size_0=1; b2_0003=0x9) ... & $(SRC5W) & $(DST5AX) ... {
+ tmp:2 = dst5Ax:2 ^ src5W;
+ dst5Ax = zext(tmp);
+ setResultFlags(tmp);
+}
+
+} # end phase=1
+
diff --git a/Ghidra/Processors/M16C/data/manuals/M16C_60.idx b/Ghidra/Processors/M16C/data/manuals/M16C_60.idx
new file mode 100644
index 0000000000..a57d66928f
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/manuals/M16C_60.idx
@@ -0,0 +1,95 @@
+@m16csm.pdf
+ABS, 55
+ADC, 56
+ADCF, 57
+ADD, 58
+ADJNZ, 60
+AND, 61
+BAND, 63
+BCLR, 64
+BM, 65
+BNAND, 66
+BNOR, 67
+BNOT, 68
+BNTST, 69
+BNXOR, 70
+BOR, 71
+BRK, 72
+BSET, 73
+BTST, 74
+BTSTC, 75
+BTSTS, 76
+BXOR, 77
+CMP, 78
+DADC, 80
+DADD, 81
+DEC, 82
+DIV, 83
+DIVU, 84
+DIVX, 85
+DSBB, 86
+DSUB, 87
+ENTER, 88
+EXITD, 89
+EXTS, 90
+FCLR, 91
+FSET, 92
+INC, 93
+INT, 94
+INTO, 95
+J, 96
+JMP, 97
+JMPI, 98
+JMPS, 99
+JSR, 100
+JSRI, 101
+JSRS, 102
+LDC, 103
+LDCTX, 104
+LDE, 105
+LDINTB, 106
+LDIPL, 107
+MOV, 108
+MOVA, 110
+MOVHH, 111
+MOVHL, 111
+MOVLH, 111
+MOVLL, 111
+MUL, 112
+MULU, 113
+NEG, 114
+NOP, 115
+NOT, 116
+OR, 117
+POP, 119
+POPC, 120
+POPM, 121
+PUSH, 122
+PUSHA, 123
+PUSHC, 124
+PUSHM, 125
+REIT, 126
+RMPA, 127
+ROLC, 128
+RORC, 129
+ROT, 130
+RTS, 131
+SBB, 132
+SBJNZ, 133
+SHA, 134
+SHL, 135
+SMOVB, 136
+SMOVF, 137
+SSTR, 138
+STC, 139
+STCTX, 140
+STE, 141
+STNZ, 142
+STZ, 143
+STZX, 144
+SUB, 145
+TST, 147
+UND, 148
+WAIT, 149
+XCHG, 150
+XOR, 151
diff --git a/Ghidra/Processors/M16C/data/manuals/M16C_80.idx b/Ghidra/Processors/M16C/data/manuals/M16C_80.idx
new file mode 100644
index 0000000000..cd2c20f43f
--- /dev/null
+++ b/Ghidra/Processors/M16C/data/manuals/M16C_80.idx
@@ -0,0 +1,110 @@
+@m16c80.pdf
+ABS, 60
+ADC, 61
+ADCF, 62
+ADD, 63
+ADDX, 65
+ADJNZ, 66
+AND, 67
+BAND, 69
+BCLR, 70
+BITINDEX, 71
+BM, 72
+BNAND, 73
+BNOR, 74
+BNOT, 75
+BNTST, 76
+BNXOR, 77
+BOR, 78
+BRK, 79
+BRK2, 80
+BSET, 81
+BTST, 82
+BTSTC, 83
+BTSTS, 84
+BXOR, 85
+CLIP, 86
+CMP, 87
+CMPX, 89
+DADC, 90
+DADD, 91
+DEC, 92
+DIV, 93
+DIVU, 94
+DIVX, 95
+DSBB, 96
+DSUB, 97
+ENTER, 98
+EXITD, 99
+EXTS, 100
+EXTZ, 101
+FLCR, 102
+FREIT, 103
+FSET, 104
+INC, 105
+INDEX, 175
+INT, 107
+INTO, 108
+J, 109
+JMP, 110
+JMPI, 111
+JMPS, 112
+JSR, 113
+JSRI, 114
+JSRS, 115
+LDC, 116
+LDCTX, 117
+LDIPL, 118
+MAX, 119
+MIN, 120
+MOV, 121
+MOVA, 123
+MOVHH, 124
+MOVHL, 124
+MOVLH, 124
+MOVLL, 124
+MOVX, 125
+MUL, 126
+MULEX, 127
+MULU, 128
+NEG, 129
+NOP, 130
+NOT, 131
+OR, 132
+POP, 134
+POPC, 135
+POPM, 136
+PUSH, 137
+PUSHA, 138
+PUSHC, 139
+PUSHM, 140
+REIT, 141
+RMPA, 142
+ROLC, 143
+RORC, 144
+ROT, 145
+RTS, 146
+SBB, 147
+SBJNZ, 148
+SC, 149
+SCMPU, 150
+SHA, 151
+SHL, 153
+SIN, 155
+SMOVB, 156
+SMOVF, 157
+SMOVU, 158
+SOUT, 159
+SSTR, 160
+STC, 161
+STCTX, 162
+STNZ, 163
+STZ, 164
+STZX, 165
+SUB, 166
+SUBX, 168
+TST, 169
+UND, 171
+WAIT, 172
+XCHG, 173
+XOR, 174