diff --git a/Ghidra/Processors/SuperH/LICENSE b/Ghidra/Processors/SuperH/LICENSE
new file mode 100644
index 0000000000..c78c135cd6
--- /dev/null
+++ b/Ghidra/Processors/SuperH/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2019 VGKintsugi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Ghidra/Processors/SuperH/Module.manifest b/Ghidra/Processors/SuperH/Module.manifest
new file mode 100644
index 0000000000..8d1c8b69c3
--- /dev/null
+++ b/Ghidra/Processors/SuperH/Module.manifest
@@ -0,0 +1 @@
+
diff --git a/Ghidra/Processors/SuperH/data/languages/sh-1.slaspec b/Ghidra/Processors/SuperH/data/languages/sh-1.slaspec
new file mode 100644
index 0000000000..b8ca66cbaf
--- /dev/null
+++ b/Ghidra/Processors/SuperH/data/languages/sh-1.slaspec
@@ -0,0 +1,4 @@
+
+@define SH_VERSION "1"
+
+@include "superh.sinc"
diff --git a/Ghidra/Processors/SuperH/data/languages/sh-2.slaspec b/Ghidra/Processors/SuperH/data/languages/sh-2.slaspec
new file mode 100644
index 0000000000..aaa0eeaa3a
--- /dev/null
+++ b/Ghidra/Processors/SuperH/data/languages/sh-2.slaspec
@@ -0,0 +1,3 @@
+@define SH_VERSION "2"
+
+@include "superh.sinc"
diff --git a/Ghidra/Processors/SuperH/data/languages/superh.cspec b/Ghidra/Processors/SuperH/data/languages/superh.cspec
new file mode 100644
index 0000000000..299439d4db
--- /dev/null
+++ b/Ghidra/Processors/SuperH/data/languages/superh.cspec
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Processors/SuperH/data/languages/superh.ldefs b/Ghidra/Processors/SuperH/data/languages/superh.ldefs
new file mode 100644
index 0000000000..877b9461b9
--- /dev/null
+++ b/Ghidra/Processors/SuperH/data/languages/superh.ldefs
@@ -0,0 +1,26 @@
+
+
+
+
+ SuperH SH-2 processor 32-bit big-endian
+
+
+
+ SuperH SH-1 processor 32-bit big-endian
+
+
+
diff --git a/Ghidra/Processors/SuperH/data/languages/superh.pspec b/Ghidra/Processors/SuperH/data/languages/superh.pspec
new file mode 100644
index 0000000000..114b5c47a8
--- /dev/null
+++ b/Ghidra/Processors/SuperH/data/languages/superh.pspec
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Ghidra/Processors/SuperH/data/languages/superh.sinc b/Ghidra/Processors/SuperH/data/languages/superh.sinc
new file mode 100644
index 0000000000..e79aa81e3d
--- /dev/null
+++ b/Ghidra/Processors/SuperH/data/languages/superh.sinc
@@ -0,0 +1,1410 @@
+# All assembly defintions taken from: http://www.shared-ptr.com/sh_insns.html
+
+define endian=big;
+
+define alignment=2;
+
+define space ram type=ram_space size=4 wordsize=1 default;
+define space register type=register_space size=4;
+
+define register offset=0 size=4
+[r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15];
+
+define register offset=0x100 size=4 [sr gbr vbr mach macl pr pc];
+
+# SR Flags
+@define T_FLAG "sr[0,1]"
+@define S_FLAG "sr[1,1]"
+@define I0_FLAG "sr[4,1]"
+@define I1_FLAG "sr[5,1]"
+@define I2_FLAG "sr[6,1]"
+@define I3_FLAG "sr[7,1]"
+@define Q_FLAG "sr[8,1]"
+@define M_FLAG "sr[9,1]"
+
+define token instr(16)
+ disp_00_03 = (0, 3)
+ sdisp_00_03 = (0, 3) signed
+ disp_00_07 = (0, 7)
+ sdisp_00_07 = (0, 7) signed
+ disp_00_11 = (0, 11)
+ sdisp_00_11 = (0, 11) signed
+ imm_00_07 = (0, 7)
+ simm_00_07 = (0, 7) signed
+ opcode_00_03 = (0, 3)
+ opcode_00_07 = (0, 7)
+ opcode_00_15 = (0, 15)
+ opcode_04_07 = (4, 7)
+ opcode_08_11 = (8, 11)
+ opcode_08_15 = (8, 15)
+ opcode_12_15 = (12, 15)
+ rm_04_07 = (4, 7)
+ rm_08_11 = (8, 11)
+ rn_04_07 = (4, 7)
+ rn_08_11 = (8, 11)
+;
+
+attach variables [ rm_04_07 rm_08_11 rn_04_07 rn_08_11 ] [
+ r0 r1 r2 r3 r4 r5 r6 r7
+ r8 r9 r10 r11 r12 r13 r14 r15
+];
+
+# helpers for branch
+target00_07: target is sdisp_00_07 [ target = (sdisp_00_07 << 1) + inst_start + 4; ] {
+ export *:4 target;
+}
+
+target00_11: target is sdisp_00_11 [ target = (sdisp_00_11 << 1) + inst_start + 4; ] {
+ export *:4 target;
+}
+
+#
+# Data Transfer Instructions
+#
+
+:mov rm_04_07, rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b0011
+{
+ rn_08_11 = rm_04_07;
+}
+
+:mov simm_00_07,rn_08_11 is opcode_12_15=0b1110 & rn_08_11 & simm_00_07
+{
+ rn_08_11 = simm_00_07;
+}
+
+:mova @(disp,pc),r0 is r0 & pc & opcode_08_15=0b11000111 & disp_00_07 [disp = (disp_00_07 << 2); ]
+{
+ local temp:4 = inst_start;
+ r0 = disp + (temp & 0xFFFFFFFC) + 4;
+}
+
+:mov.w @(target,pc),rn_08_11 is pc & opcode_12_15=0b1001 & rn_08_11 & disp_00_07 [ target = (disp_00_07 << 1) + 4; ]
+{
+ local temp:4 = inst_start;
+ rn_08_11 = sext(*:2 (temp + target));
+}
+
+:mov.l @(disp,pc),rn_08_11 is pc & opcode_12_15=0b1101 & rn_08_11 & disp_00_07 [disp = (disp_00_07 << 2) + 4; ]
+{
+ local temp:4 = inst_start;
+ rn_08_11 = *:4 ((temp & 0xFFFFFFFC) + disp);
+}
+
+:mov.b @rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b0000
+{
+ rn_08_11 = sext(*:1 rm_04_07);
+}
+
+:mov.w @rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b0001
+{
+ rn_08_11 = sext(*:2 rm_04_07);
+}
+
+:mov.l @rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b0010
+{
+ rn_08_11 = *:4 rm_04_07;
+}
+
+:mov.b rm_04_07,@rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b0000
+{
+ *:1 rn_08_11 = rm_04_07:1;
+}
+
+:mov.w rm_04_07,@rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b0001
+{
+ *:2 rn_08_11 = rm_04_07:2;
+}
+
+:mov.l rm_04_07,@rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b0010
+{
+ *:4 rn_08_11 = rm_04_07;
+}
+
+:mov.b @rm_04_07+,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b0100 & opcode_04_07 & opcode_08_11
+{
+ rn_08_11 = sext(*:1 rm_04_07);
+
+ local m:4 = opcode_04_07;
+ local n:4 = opcode_08_11;
+
+ # Check n != m
+ if(m == n) goto ;
+ rm_04_07 = rm_04_07 + 1;
+
+
+}
+
+:mov.w @rm_04_07+,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b0101 & opcode_04_07 & opcode_08_11
+{
+ rn_08_11 = sext(*:2 rm_04_07);
+
+ local m:4 = opcode_04_07;
+ local n:4 = opcode_08_11;
+
+ # Check n != m
+ if(m == n) goto ;
+ rm_04_07 = rm_04_07 + 2;
+
+
+}
+
+:mov.l @rm_04_07+,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b0110 & opcode_04_07 & opcode_08_11
+{
+ rn_08_11 = *:4 rm_04_07;
+
+ local m:4 = opcode_04_07;
+ local n:4 = opcode_08_11;
+
+ # Check n != m
+ if(m == n) goto ;
+ rm_04_07 = rm_04_07 + 4;
+
+
+}
+
+:mov.b rm_04_07,@-rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b0100
+{
+ rn_08_11 = rn_08_11 -1;
+ *:1 rn_08_11 = rm_04_07;
+}
+
+:mov.w rm_04_07,@-rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b0101
+{
+ rn_08_11 = rn_08_11 -2;
+ *:2 rn_08_11 = rm_04_07;
+}
+
+:mov.l rm_04_07,@-rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b0110
+{
+ rn_08_11 = rn_08_11 -4;
+ *:4 rn_08_11 = rm_04_07;
+}
+
+:mov.b @(disp_00_03,rm_04_07),r0 is r0 & opcode_08_15=0b10000100 & rm_04_07 & disp_00_03
+{
+ r0 = sext(*:1 (disp_00_03 + rm_04_07));
+}
+
+:mov.w @(disp,rm_04_07),r0 is r0 & opcode_08_15=0b10000101 & rm_04_07 & disp_00_03 [ disp = disp_00_03 << 1; ]
+{
+ r0 = sext(*:2 (disp + rm_04_07));
+}
+
+:mov.l @(disp,rm_04_07),rn_08_11 is opcode_12_15=0b0101 & rn_08_11 & rm_04_07 & disp_00_03 [ disp = disp_00_03 << 2; ]
+{
+ rn_08_11 = *:4 (disp + rm_04_07);
+}
+
+:mov.b r0,@(disp_00_03,rn_04_07) is r0 & opcode_08_15=0b10000000 & rn_04_07 & disp_00_03
+{
+ *:1 (rn_04_07 + disp_00_03) = r0:1;
+}
+
+:mov.w r0,@(disp,rn_04_07) is r0 & opcode_08_15=0b10000001 & rn_04_07 & disp_00_03 [ disp = disp_00_03 << 1; ]
+{
+ *:2 (rn_04_07 + disp) = r0:2;
+}
+
+:mov.l rm_04_07,@(disp,rn_08_11) is opcode_12_15=0b0001 & rn_08_11 & rm_04_07 & disp_00_03 [ disp = disp_00_03 << 2; ]
+{
+ *:4 (rn_08_11 + disp) = rm_04_07;
+}
+
+:mov.b @(r0,rm_04_07),rn_08_11 is r0 & opcode_12_15=0b0000 & rn_08_11 & rm_04_07 & opcode_00_03=0b1100
+{
+ rn_08_11 = sext(*:1 (rm_04_07 + r0));
+}
+
+:mov.w @(r0,rm_04_07),rn_08_11 is r0 & opcode_12_15=0b0000 & rn_08_11 & rm_04_07 & opcode_00_03=0b1101
+{
+ rn_08_11 = sext(*:2 (rm_04_07 + r0));
+}
+
+:mov.l @(r0,rm_04_07),rn_08_11 is r0 & opcode_12_15=0b0000 & rn_08_11 & rm_04_07 & opcode_00_03=0b1110
+{
+ rn_08_11 = *:4 (rm_04_07 + r0);
+}
+
+:mov.b rm_04_07,@(r0,rn_08_11) is r0 & opcode_12_15=0b0000 & rn_08_11 & rm_04_07 & opcode_00_03=0b0100
+{
+ *:1 (rn_08_11 + r0) = rm_04_07;
+}
+
+:mov.w rm_04_07,@(r0,rn_08_11) is r0 & opcode_12_15=0b0000 & rn_08_11 & rm_04_07 & opcode_00_03=0b0101
+{
+ *:2 (rn_08_11 + r0) = rm_04_07;
+}
+
+:mov.l rm_04_07,@(r0,rn_08_11) is r0 & opcode_12_15=0b0000 & rn_08_11 & rm_04_07 & opcode_00_03=0b0110
+{
+ *:4 (rn_08_11 + r0) = rm_04_07;
+}
+
+:mov.b @(disp_00_07,gbr),r0 is gbr & r0 & opcode_08_15=0b11000100 & disp_00_07
+{
+ r0 = sext(*:1 (gbr + disp_00_07));
+}
+
+:mov.w @(disp,gbr),r0 is gbr & r0 & opcode_08_15=0b11000101 & disp_00_07 [disp = (disp_00_07 << 1); ]
+{
+ r0 = sext(*:2 (gbr + disp));
+}
+
+:mov.l @(disp,gbr),r0 is gbr & r0 & opcode_08_15=0b11000110 & disp_00_07 [disp = (disp_00_07 << 2); ]
+{
+ r0 = *:4 (gbr + disp);
+}
+
+:mov.b r0,@(disp_00_07,gbr) is r0 & gbr & opcode_08_15=0b11000000 & disp_00_07
+{
+ *:1 (gbr + disp_00_07) = r0;
+}
+
+:mov.w r0,@(disp,gbr) is r0 & gbr & opcode_08_15=0b11000001 & disp_00_07 [disp = (disp_00_07 << 1); ]
+{
+ *:2 (gbr + disp) = r0;
+}
+
+:mov.l r0,@(disp,gbr) is r0 & gbr & opcode_08_15=0b11000010 & disp_00_07 [disp = (disp_00_07 << 2); ]
+{
+ *:4 (gbr + disp) = r0;
+}
+
+:movt rn_08_11 is opcode_12_15=0b0000 & rn_08_11 & opcode_00_07=0b00101001
+{
+ rn_08_11 = zext($(T_FLAG));
+}
+
+:swap.b rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b1000
+{
+ local temp0;
+ local temp1;
+
+ temp0 = rm_04_07 & 0xFFFF0000;
+ temp1 = (rm_04_07 & 0x000000FF) << 8;
+
+ rn_08_11 = (rm_04_07 & 0x0000FF00) >> 8;
+ rn_08_11 = rn_08_11 | temp1 | temp0;
+}
+
+:swap.w rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b1001
+{
+ local temp;
+
+ temp = (rm_04_07 >> 16) & 0x0000FFFF;
+
+ rn_08_11 = rm_04_07 << 16;
+ rn_08_11 = rn_08_11 | temp;
+}
+
+:xtrct rm_04_07,rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b1101
+{
+ local high;
+ local low;
+
+ high = (rm_04_07 << 16) & 0xFFFF0000;
+ low = (rn_08_11 >> 16) & 0x0000FFFF;
+ rn_08_11 = high | low;
+}
+
+#
+# Arithmetic Operation Instructions
+#
+:add rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b1100
+{
+ rn_08_11 = rn_08_11 + rm_04_07;
+}
+
+:add imm_00_07,rn_08_11 is opcode_12_15=0b0111 & rn_08_11 & imm_00_07
+{
+ rn_08_11 = rn_08_11 + sext(imm_00_07:1);
+}
+
+:addc rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b1110
+{
+ local temp0;
+ local temp1;
+
+ temp1 = rn_08_11 + rm_04_07;
+ temp0 = temp1;
+
+ rn_08_11 = temp1 + zext($(T_FLAG));
+
+ $(T_FLAG) = (temp0 > temp1) | (temp1 > rn_08_11);
+}
+
+:addv rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b1111
+{
+ local dest:1;
+ local src:1;
+ local ans:1;
+
+ dest = (rn_08_11 s< 0);
+ src = (rm_04_07 s< 0);
+
+ src = src + dest;
+ rn_08_11 = rn_08_11 + rm_04_07;
+
+ ans = (rn_08_11 s< 0);
+
+ ans = ans + dest;
+
+ $(T_FLAG) = (src == 0 || src == 2) && (ans == 1);
+}
+
+:cmp"/eq" imm_00_07,r0 is r0 & opcode_08_15=0b10001000 & imm_00_07
+{
+ local temp:4 = sext(imm_00_07:1);
+
+ $(T_FLAG) = (r0 == temp);
+}
+
+:cmp"/eq" rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b0000
+{
+ $(T_FLAG) = (rn_08_11 == rm_04_07);
+}
+
+:cmp"/hs" rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b0010
+{
+ $(T_FLAG) = (rn_08_11 >= rm_04_07);
+}
+
+:cmp"/ge" rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b0011
+{
+ $(T_FLAG) = (rn_08_11 s>= rm_04_07);
+}
+
+:cmp"/hi" rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b0110
+{
+ $(T_FLAG) = (rn_08_11 > rm_04_07);
+}
+
+:cmp"/gt" rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b0111
+{
+ $(T_FLAG) = (rn_08_11 s> rm_04_07);
+}
+
+:cmp"/pl" rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00010101
+{
+ $(T_FLAG) = (rn_08_11 s> 0);
+}
+
+:cmp"/pz" rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00010001
+{
+ $(T_FLAG) = (rn_08_11 s>= 0);
+}
+
+:cmp"/str" rm_04_07,rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b1100
+{
+ local temp:4;
+ local HH:4;
+ local HL:4;
+ local LH:4;
+ local LL:4;
+
+ temp = rn_08_11 ^ rm_04_07;
+
+ HH = (temp & 0xFF000000) >> 24;
+ HL = (temp & 0x00FF0000) >> 16;
+ LH = (temp & 0x0000FF00) >> 8;
+ LL = (temp & 0x000000FF);
+
+ $(T_FLAG) = (HH != 0) && (HL != 0) && (LH != 0) && (LL != 0);
+}
+
+:div0s rm_04_07,rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b0111
+{
+ $(Q_FLAG) = !((rn_08_11 & 0x80000000) == 0);
+ $(M_FLAG) = !((rm_04_07 & 0x80000000) == 0);
+
+ $(T_FLAG) = !($(M_FLAG) == $(Q_FLAG));
+}
+
+:div0u is opcode_00_15=0b0000000000011001
+{
+ $(M_FLAG) = 0;
+ $(Q_FLAG) = 0;
+ $(T_FLAG) = 0;
+}
+
+:div1 rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b0100
+{
+ local tmp0:4;
+ local tmp1:1;
+ local tmp2:4;
+ local old_q:1;
+
+ old_q = $(Q_FLAG);
+ $(Q_FLAG) = (0x80000000 & rn_08_11) != 0;
+ tmp2 = rm_04_07;
+ rn_08_11 = rn_08_11 << 1;
+ rn_08_11 = rn_08_11 | zext($(T_FLAG));
+
+ # BUGBUG: cleaner way to do this??
+
+ if(old_q == 0 && $(M_FLAG) == 0 && $(Q_FLAG) == 0) goto ;
+ if(old_q == 0 && $(M_FLAG) == 0 && $(Q_FLAG) == 1) goto ;
+ if(old_q == 0 && $(M_FLAG) == 1 && $(Q_FLAG) == 0) goto ;
+ if(old_q == 0 && $(M_FLAG) == 1 && $(Q_FLAG) == 1) goto ;
+ if(old_q == 1 && $(M_FLAG) == 0 && $(Q_FLAG) == 0) goto ;
+ if(old_q == 1 && $(M_FLAG) == 0 && $(Q_FLAG) == 1) goto ;
+ if(old_q == 1 && $(M_FLAG) == 1 && $(Q_FLAG) == 0) goto ;
+ if(old_q == 1 && $(M_FLAG) == 1 && $(Q_FLAG) == 1) goto ;
+
+
+ tmp0 = rn_08_11;
+ rn_08_11 = rn_08_11 - tmp2;
+ tmp1 = rn_08_11 > tmp0;
+ $(Q_FLAG) = tmp1;
+ goto ;
+
+
+ tmp0 = rn_08_11;
+ rn_08_11 = rn_08_11 - tmp2;
+ tmp1 = rn_08_11 > tmp0;
+ $(Q_FLAG) = tmp1 == 0;
+ goto ;
+
+
+ tmp0 = rn_08_11;
+ rn_08_11 = rn_08_11 + tmp2;
+ tmp1 = rn_08_11 < tmp0;
+ $(Q_FLAG) = tmp1 == 0;
+ goto ;
+
+
+ tmp0 = rn_08_11;
+ rn_08_11 = rn_08_11 + tmp2;
+ tmp1 = rn_08_11 < tmp0;
+ $(Q_FLAG) = tmp1;
+ goto ;
+
+
+ tmp0 = rn_08_11;
+ rn_08_11 = rn_08_11 + tmp2;
+ tmp1 = rn_08_11 < tmp0;
+ $(Q_FLAG) = tmp1;
+ goto ;
+
+
+ tmp0 = rn_08_11;
+ rn_08_11 = rn_08_11 + tmp2;
+ tmp1 = rn_08_11 < tmp0;
+ $(Q_FLAG) = tmp1;
+ goto ;
+
+
+ tmp0 = rn_08_11;
+ rn_08_11 = rn_08_11 - tmp2;
+ tmp1 = rn_08_11 > tmp0;
+ $(Q_FLAG) = tmp1 == 0;
+ goto ;
+
+
+ tmp0 = rn_08_11;
+ rn_08_11 = rn_08_11 - tmp2;
+ tmp1 = rn_08_11 > tmp0;
+ $(Q_FLAG) = tmp1;
+ goto ;
+
+
+ $(T_FLAG) = $(Q_FLAG) == $(M_FLAG);
+}
+
+@if SH_VERSION == "2"
+:dmuls.l rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b1101
+{
+ local a:8 = sext(rn_08_11);
+ local b:8 = sext(rm_04_07);
+ local result:8 = a * b;
+
+ mach = result(4);
+ macl = result:4;
+}
+
+:dmulu.l rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b0101
+{
+ local a:8 = zext(rn_08_11);
+ local b:8 = zext(rm_04_07);
+ local result:8 = a * b;
+
+ mach = result(4);
+ macl = result:4;
+}
+
+:dt rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00010000
+{
+ rn_08_11 = rn_08_11 - 1;
+ $(T_FLAG) = (rn_08_11 == 0);
+}
+@endif
+
+:exts.b rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b1110
+{
+ rn_08_11 = rm_04_07;
+
+ if((rm_04_07 & 0x00000080) == 0) goto ;
+
+ rn_08_11 = rn_08_11 | 0xFFFFFF00;
+ goto ;
+
+
+ rn_08_11 = rn_08_11 & 0x000000FF;
+
+
+}
+
+:exts.w rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b1111
+{
+ rn_08_11 = rm_04_07;
+
+ if((rm_04_07 & 0x00008000) == 0) goto ;
+
+ rn_08_11 = rn_08_11 | 0xFFFF0000;
+ goto ;
+
+
+ rn_08_11 = rn_08_11 & 0x0000FFFF;
+
+
+}
+
+:extu.b rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b1100
+{
+ rn_08_11 = rm_04_07 & 0x000000FF;
+}
+
+:extu.w rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b1101
+{
+ rn_08_11 = rm_04_07 & 0x0000FFFF;
+}
+
+@if SH_VERSION == "2"
+:mac.l @rm_04_07+,@rn_08_11+ is opcode_12_15=0b0000 & rn_08_11 & rm_04_07 & opcode_00_03=0b1111
+{
+ # BUGBUG: review this instruction
+
+ local RnL;
+ local RnH;
+ local RmL;
+ local RmH;
+ local Res0;
+ local Res1:4;
+ local Res2:4;
+
+ local temp0;
+ local temp1:4;
+ local temp2:4;
+ local temp3;
+
+ local tempm:4;
+ local tempn:4;
+ local fnLmL:4;
+
+ tempn = *:4 rn_08_11;
+ rn_08_11 = rn_08_11 + 4;
+ tempm = *:4 rm_04_07;
+ rm_04_07 = rm_04_07 + 4;
+
+ if((tempn ^ tempm) s<0) goto ;
+ fnLmL = 0;
+ goto ;
+
+ fnLmL = -1;
+
+ if( tempn s>= 0) goto ;
+ tempn = 0 - tempn;
+
+
+ if( tempm s>= 0) goto ;
+ tempm = 0 - tempm;
+
+
+
+ temp1 = tempn;
+ temp2 = tempm;
+
+ RnL = temp1 & 0x0000FFFF;
+ RnH = (temp1 >> 16) & 0x0000FFFF;
+ RmL = temp2 & 0x0000FFFF;
+ RmH = (temp2 >> 16) & 0x0000FFFF;
+ temp0 = RmL * RnL;
+ temp1 = RmH * RnL;
+ temp2 = RmL * RnH;
+ temp3 = RmH * RnH;
+
+ Res2 = 0;
+ Res1 = temp1 + temp2;
+
+ if(Res2 >= temp1) goto ;
+ Res2 = Res2 + 0x00010000;
+
+
+ temp1 = (Res1 << 16) & 0xFFFF0000;
+
+ Res0 = temp0 + temp1;
+ Res2 = Res2 + zext(Res0 < temp0);
+
+ Res2 = Res2 + ((Res1 >> 16) & 0x0000FFFF) + temp3;
+
+ if(fnLmL s>= 0) goto ;
+ Res2 = ~Res2;
+
+ if(Res0 == 0) goto ;
+ Res0 = (~Res0) + 1;
+ goto ;
+
+
+ Res2 = Res2 + 1;
+
+
+
+ if($(S_FLAG) != 1) goto ;
+
+ Res0 = macl + Res0;
+ Res2 = Res2 + zext(macl > Res0);
+
+ Res2 = Res2 + (mach & 0x0000FFFF);
+
+ if((Res2 s>= 0) || Res2 >= 0xFFFF8000) goto ;
+ Res2 = 0xFFFF8000;
+ Res0 = 0x00000000;
+
+
+ if((Res2 s<= 0) || Res2 <= 0x00007FFF) goto ;
+ Res2 = 0x00007FFF;
+ Res0 = 0xFFFFFFFF;
+
+
+ mach = (Res2 & 0x0000FFFF) | (mach & 0xFFFF0000);
+ macl = Res0;
+
+ goto ;
+
+
+ Res0 = macl + Res0;
+ Res2 = Res2 + zext(macl > Res0);
+
+ Res2 = Res2 + mach;
+ mach = Res2;
+ macl = Res0;
+
+
+}
+@endif
+
+:mac.w @rm_04_07+,@rn_08_11+ is opcode_12_15=0b0100 & rn_08_11 & rm_04_07 & opcode_00_03=0b1111
+{
+ # BUGBUG: review this instruction
+
+ local tempm:4;
+ local tempn:4;
+ local dest;
+ local src:4;
+ local ans;
+ local templ:4;
+
+ tempn = *:2 rn_08_11;
+ rn_08_11 = rn_08_11 + 2;
+ tempm = *:2 rm_04_07;
+ rm_04_07 = rm_04_07 + 2;
+
+ templ = macl;
+ tempm = sext(tempn:2) * sext(tempm:2);
+
+ dest = (macl s< 0);
+
+ if(tempm s< 0) goto ;
+ src = 0;
+ tempn = 0;
+ goto ;
+
+
+ src = 1;
+ tempn = 0xFFFFFFFF;
+
+
+ src = src + zext(dest);
+ macl = macl + tempm;
+
+ ans = (macl s< 0);
+
+ ans = ans + dest;
+
+ # if (S == 1)
+ if($(S_FLAG) != 1) goto ;
+
+ if(ans != 1) goto ;
+
+@if SH_VERSION == "1"
+ if(src != 0 && src != 2) goto ;
+ mach = mach | 0x00000001;
+
+@endif
+
+ if(src == 0) goto ;
+ if(src == 2) goto ;
+ goto ;
+
+
+ macl = 0x7FFFFFFF;
+ goto ;
+
+
+ macl = 0x80000000;
+ goto ;
+
+ # if (S != 1)
+
+
+ mach = mach + tempn;
+
+ if(templ s<= macl) goto ;
+ macl = macl + 1;
+
+
+@if SH_VERSION == "1"
+ if((mach & 0x00000200) == 0) goto ;
+ mach = mach | 0xFFFFFC00;
+ goto ;
+
+ mach = mach & 0x000003FF;
+@endif
+
+
+}
+
+@if SH_VERSION == "2"
+:mul.l rm_04_07,rn_08_11 is opcode_12_15=0b0000 & rn_08_11 & rm_04_07 & opcode_00_03=0b0111
+{
+ macl = rn_08_11 * rm_04_07;
+}
+@endif
+
+:muls.w rm_04_07,rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b1111
+{
+ macl = sext(rn_08_11:2 & 0xFFFF) * sext(rm_04_07:2 & 0xFFFF);
+}
+
+:mulu.w rm_04_07,rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b1110
+{
+ macl = (rn_08_11 & 0xFFFF) * (rm_04_07 & 0xFFFF);
+}
+
+:neg rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b1011
+{
+ rn_08_11 = 0 - rm_04_07;
+}
+
+:negc rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b1010
+{
+ local temp;
+
+ temp = 0 - rm_04_07;
+ rn_08_11 = temp - zext($(T_FLAG));
+
+ # BUGBUG: should temp be signed or unsigned??
+ # Documentation says if(0 < temp) not 0 != temp
+ $(T_FLAG) = (0 != temp) || (temp < rn_08_11);
+}
+
+:sub rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b1000
+{
+ rn_08_11 = rn_08_11 - rm_04_07;
+}
+
+:subc rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b1010
+{
+ local temp0;
+ local temp1;
+
+ temp1 = rn_08_11 - rm_04_07;
+ temp0 = rn_08_11;
+
+ rn_08_11 = temp1 - zext($(T_FLAG));
+
+ $(T_FLAG) = (temp0 < temp1 || temp1 < rn_08_11);
+}
+
+:subv rm_04_07,rn_08_11 is opcode_12_15=0b0011 & rn_08_11 & rm_04_07 & opcode_00_03=0b1011
+{
+ local dest;
+ local src;
+ local ans;
+
+ dest = !(rn_08_11 s>= 0);
+ src = !(rm_04_07 s>= 0);
+
+ src = src + dest;
+ rn_08_11 = rn_08_11 - rm_04_07;
+
+ ans = (rn_08_11 s>= 0);
+ ans = ans + dest;
+
+ $(T_FLAG) = (src == 1) && (ans == 1);
+}
+
+#
+# Logic Operation Instructions
+#
+:and rm_04_07,rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b1001
+{
+ rn_08_11 = rn_08_11 & rm_04_07;
+}
+
+:and imm_00_07,r0 is r0 & opcode_08_15=0b11001001 & imm_00_07
+{
+ r0 = (r0 & imm_00_07) & 0x000000FF;
+}
+
+:and.b imm_00_07,@(r0,gbr) is r0 & gbr & opcode_08_15=0b11001101 & imm_00_07
+{
+ local temp = *:1 (gbr + r0);
+ temp = (temp & imm_00_07) & 0x000000FF;
+
+ *:1 (gbr + r0) = temp;
+}
+
+:not rm_04_07,rn_08_11 is opcode_12_15=0b0110 & rn_08_11 & rm_04_07 & opcode_00_03=0b0111
+{
+ rn_08_11 = ~rm_04_07;
+}
+
+:or rm_04_07,rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b1011
+{
+ rn_08_11 = rn_08_11 | rm_04_07;
+}
+
+:or imm_00_07,r0 is r0 & opcode_08_15=0b11001011 & imm_00_07
+{
+ r0 = r0 | imm_00_07:4;
+}
+
+:or.b imm_00_07,@(r0,gbr) is r0 & gbr & opcode_08_15=0b11001111 & imm_00_07
+{
+ local temp = *:1 (gbr + r0);
+ temp = (temp & imm_00_07) | 0x000000FF;
+
+ *:1 (gbr + r0) = temp;
+}
+
+:tas.b @rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00011011
+{
+ local temp = *:1 rn_08_11;
+
+ $(T_FLAG) = (temp == 0);
+
+ temp = temp | 0x80;
+
+ *:1 rn_08_11 = temp;
+}
+
+:tst rm_04_07,rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b1000
+{
+ $(T_FLAG) = ((rm_04_07 & rm_04_07) == 0);
+}
+
+:tst imm_00_07,r0 is r0 & opcode_08_15=0b11001000 & imm_00_07
+{
+ local temp = r0 & (imm_00_07 & 0x000000FF);
+
+ $(T_FLAG) = (temp == 0);
+}
+
+:tst.b imm_00_07,@(r0,gbr) is r0 & gbr & opcode_08_15=0b11001100 & imm_00_07
+{
+ local temp = *:1 (gbr + r0);
+ temp = temp & (imm_00_07 & 0x000000FF);
+
+ $(T_FLAG) = (temp == 0);
+}
+
+:xor rm_04_07,rn_08_11 is opcode_12_15=0b0010 & rn_08_11 & rm_04_07 & opcode_00_03=0b1010
+{
+ rn_08_11 = rn_08_11 ^ rm_04_07;
+}
+
+:xor imm_00_07,r0 is r0 & opcode_08_15=0b11001010 & imm_00_07
+{
+ r0 = r0 ^ (imm_00_07 & 0x000000FF);
+}
+
+:xor.b imm_00_07,@(r0,gbr) is r0 & gbr & opcode_08_15=0b11001110 & imm_00_07
+{
+ local temp = *:1 (gbr + r0);
+ temp = temp & (imm_00_07 & 0x000000FF);
+
+ *:1 (gbr + r0) = temp;
+}
+
+#
+#Shift Instructions
+#
+:rotcl rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00100100
+{
+ local temp:1;
+
+ temp = ((rn_08_11 & 0x80000000) != 0);
+
+ rn_08_11 = (rn_08_11 << 1) & 0xFFFFFFFE;
+
+ if($(T_FLAG) == 0) goto ;
+
+ rn_08_11 = rn_08_11 | 0x1;
+
+
+
+ $(T_FLAG) = temp;
+}
+
+:rotcr rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00100101
+{
+ local temp:1;
+
+ temp = !((rn_08_11 & 1) == 0);
+
+ rn_08_11 = (rn_08_11 >> 1) & 0x7FFFFFFF;
+
+ if($(T_FLAG) == 0) goto ;
+
+ rn_08_11 = rn_08_11 | 0x80000000;
+
+
+
+ $(T_FLAG) = temp;
+}
+
+:rotl rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00000100
+{
+ $(T_FLAG) = ((rn_08_11 & 0x80000000) != 0);
+
+ if($(T_FLAG) == 1) goto ;
+
+ rn_08_11 = rn_08_11 & 0xFFFFFFFE;
+ goto ;
+
+
+
+ rn_08_11 = rn_08_11 | 0x00000001;
+
+
+}
+
+:rotr rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00000101
+{
+ $(T_FLAG) = ((rn_08_11 & 0x1) != 0);
+
+ if($(T_FLAG) == 1) goto ;
+
+ rn_08_11 = rn_08_11 & 0x7FFFFFFF;
+ goto ;
+
+
+
+ rn_08_11 = rn_08_11 | 0x80000000;
+
+
+}
+
+:shal rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00100000
+{
+ # clear or set T
+ $(T_FLAG) = ((rn_08_11 & 0x80000000) != 0);
+
+ rn_08_11 = rn_08_11 << 1;
+}
+
+:shar rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00100001
+{
+ $(T_FLAG) = ((rn_08_11 & 1) == 1);
+
+ rn_08_11 = rn_08_11 >> 1;
+
+ if((rn_08_11 & 0x80000000) != 1) goto ;
+
+ rn_08_11 = rn_08_11 & 0x7FFFFFFF;
+ goto ;
+
+
+
+ rn_08_11 = rn_08_11 | 0x80000000;
+
+
+}
+
+:shll rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00000000
+{
+ # clear or set T
+ $(T_FLAG) = ((rn_08_11 & 0x80000000) != 0);
+
+ rn_08_11 = rn_08_11 << 1;
+}
+
+:shll2 rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00001000
+{
+ rn_08_11 = rn_08_11 << 2;
+}
+
+:shll8 rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00011000
+{
+ rn_08_11 = rn_08_11 << 8;
+}
+
+:shll16 rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00101000
+{
+ rn_08_11 = rn_08_11 << 16;
+}
+
+:shlr rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00000001
+{
+ # clear or set T
+ $(T_FLAG) = (rn_08_11 & 1) == 1;
+
+ rn_08_11 = rn_08_11 >> 1;
+ rn_08_11 = rn_08_11 & 0x7FFFFFFF;
+}
+
+:shlr2 rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00001001
+{
+ rn_08_11 = rn_08_11 >> 2;
+ rn_08_11 = rn_08_11 & 0x3FFFFFFF;
+}
+
+:shlr8 rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00011001
+{
+ rn_08_11 = rn_08_11 >> 8;
+ rn_08_11 = rn_08_11 & 0x00FFFFFF;
+}
+
+:shlr16 rn_08_11 is opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00101001
+{
+ rn_08_11 = rn_08_11 >> 16;
+ rn_08_11 = rn_08_11 & 0x0000FFFF;
+}
+
+#
+# Branch Instructions
+#
+:bf target00_07 is opcode_08_15=0b10001011 & target00_07
+{
+ if ($(T_FLAG) == 0) goto target00_07;
+}
+
+@if SH_VERSION == "2"
+:bf"/s" target00_07 is opcode_08_15=0b10001111 & target00_07
+{
+ delayslot(1);
+ if ($(T_FLAG)==0) goto target00_07;
+}
+@endif
+
+:bt target00_07 is opcode_08_15=0b10001001 & target00_07
+{
+ if ($(T_FLAG) == 1) goto target00_07;
+}
+
+@if SH_VERSION == "2"
+:bt"/s" target00_07 is opcode_08_15=0b10001101 & target00_07
+{
+ delayslot(1);
+ if ($(T_FLAG)==1) goto target00_07;
+}
+@endif
+
+:bra target00_11 is opcode_12_15=0b1010 & target00_11
+{
+ delayslot(1);
+ goto target00_11;
+}
+
+@if SH_VERSION == "2"
+:braf rm_08_11 is opcode_12_15=0b0000 & rm_08_11 & opcode_00_07=0b00100011
+{
+ local temp:4 = inst_start + 4 + rm_08_11;
+ delayslot(1);
+ goto [temp];
+}
+@endif
+
+:bsr target00_11 is opcode_12_15=0b1011 & target00_11
+{
+ pr = inst_start + 4;
+ delayslot(1);
+ call target00_11;
+}
+
+@if SH_VERSION == "2"
+:bsrf rm_08_11 is opcode_12_15=0b0000 & rm_08_11 & opcode_00_07=0b00000011
+{
+ pr = inst_start + 4;
+ delayslot(1);
+ call [rm_08_11];
+}
+@endif
+
+:jmp @rm_08_11 is opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00101011
+{
+ delayslot(1);
+ goto [rm_08_11];
+}
+
+:jsr @rm_08_11 is opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00001011
+{
+ pr = inst_start + 4;
+ delayslot(1);
+ call [rm_08_11];
+}
+
+:rts is opcode_00_15=0b0000000000001011
+{
+ delayslot(1);
+ return [pr];
+}
+
+#
+# System Control Instructions
+#
+:clrmac is opcode_00_15=0b0000000000101000
+{
+ mach = 0;
+ macl = 0;
+}
+
+:clrt is opcode_00_15=0b0000000000001000
+{
+ $(T_FLAG) = 0;
+}
+
+:ldc rm_08_11,sr is sr & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00001110
+{
+ sr = rm_08_11 & 0x0FFF0FFF;
+}
+
+:ldc.l @rm_08_11+,sr is sr & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00000111
+{
+ sr = *rm_08_11 & 0x0FFF0FFF;
+ rm_08_11 = rm_08_11 + 4;
+
+}
+
+:ldc rm_08_11,gbr is gbr & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00011110
+{
+ gbr = rm_08_11;
+}
+
+:ldc.l @rm_08_11+,gbr is gbr & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00010111
+{
+ gbr = *rm_08_11;
+ rm_08_11 = rm_08_11 + 4;
+}
+
+:ldc rm_08_11,vbr is vbr & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00101110
+{
+ vbr = rm_08_11;
+}
+
+:ldc.l @rm_08_11+,vbr is vbr & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00100111
+{
+ vbr = *rm_08_11;
+ rm_08_11 = rm_08_11 + 4;
+}
+
+:lds rm_08_11,mach is mach & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00001010
+{
+ mach = rm_08_11;
+
+@if SH_VERSION == "1"
+ if((mach & 0x00000200) == 0) goto ;
+
+ # sign extend
+ mach = mach | 0xFFFFFC00;
+ goto ;
+
+
+ mach = mach & 0x000003FF;
+
+
+@endif
+}
+
+:lds.l @rm_08_11+,mach is mach & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00000110
+{
+ mach = *rm_08_11;
+
+@if SH_VERSION == "1"
+ if((mach & 0x00000200) == 0) goto ;
+
+ # sign extend
+ mach = mach | 0xFFFFFC00;
+ goto ;
+
+
+ mach = mach & 0x000003FF;
+
+
+@endif
+
+ rm_08_11 = rm_08_11 + 4;
+}
+
+:lds rm_08_11,macl is macl & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00011010
+{
+ macl = rm_08_11;
+}
+
+:lds.l @rm_08_11+,macl is macl & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00010110
+{
+ macl = *rm_08_11;
+ rm_08_11 = rm_08_11 + 4;
+}
+
+:lds rm_08_11,pr is pr & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00101010
+{
+ pr = rm_08_11;
+}
+
+:lds.l @rm_08_11+,pr is pr & opcode_12_15=0b0100 & rm_08_11 & opcode_00_07=0b00100110
+{
+ pr = *rm_08_11;
+ rm_08_11 = rm_08_11 + 4;
+}
+
+:nop is opcode_00_15=0b0000000000001001
+{
+ # BUGBUG: intentional nop
+ r0 = r0; # do this to suppress warning
+}
+
+:rte is opcode_00_15=0b0000000000101011
+{
+ _pc:4 = *r15;
+ r15 = r15 + 4;
+
+ _sr:4 = *r15 & 0x000063F3;
+ r15 = r15 + 4;
+
+ delayslot(1);
+
+ pc = _pc;
+ sr = _sr;
+
+ goto [pc];
+}
+
+:sett is opcode_00_15=0b0000000000011000
+{
+ $(T_FLAG) = 1;
+}
+
+:sleep is opcode_00_15=0b0000000000011011
+{
+ # BUGBUG: call sleep();
+ r0 = r0;
+}
+
+:stc sr,rn_08_11 is sr & opcode_12_15=0b0000 & rn_08_11 & opcode_00_07=0b00000010
+{
+ rn_08_11 = sr;
+}
+
+:stc.l sr,@-rn_08_11 is sr & opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00000011
+{
+ rn_08_11 = rn_08_11 -4;
+ *rn_08_11 = sr;
+}
+
+:stc gbr,rn_08_11 is gbr & opcode_12_15=0b0000 & rn_08_11 & opcode_00_07=0b00010010
+{
+ rn_08_11 = gbr;
+}
+
+:stc.l gbr,@-rn_08_11 is gbr & opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00010011
+{
+ rn_08_11 = rn_08_11 -4;
+ *rn_08_11 = gbr;
+}
+
+:stc vbr,rn_08_11 is vbr & opcode_12_15=0b0000 & rn_08_11 & opcode_00_07=0b00100010
+{
+ rn_08_11 = vbr;
+}
+
+:stc.l vbr,@-rn_08_11 is vbr & opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00100011
+{
+ rn_08_11 = rn_08_11 -4;
+ *rn_08_11 = vbr;
+}
+
+:sts mach,rn_08_11 is mach & opcode_12_15=0b0000 & rn_08_11 & opcode_00_07=0b00001010
+{
+ rn_08_11 = mach;
+
+@if SH_VERSION == "1"
+ if((rn_08_11 & 0x00000200) == 0) goto ;
+
+ # sign extend
+ rn_08_11 = rn_08_11 | 0xFFFFFC00;
+ goto ;
+
+
+ rn_08_11 = rn_08_11 & 0x000003FF;
+
+
+@endif
+}
+
+:sts.l mach,@-rn_08_11 is mach & opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00000010
+{
+ rn_08_11 = rn_08_11 - 4;
+
+ local temp = mach;
+
+@if SH_VERSION == "1"
+ if((temp & 0x00000200) == 0) goto ;
+
+ # sign extend
+ temp = temp | 0xFFFFFC00;
+ goto ;
+
+
+ temp = temp & 0x000003FF;
+
+
+@endif
+
+ *rn_08_11 = temp;
+}
+
+:sts macl,rn_08_11 is macl & opcode_12_15=0b0000 & rn_08_11 & opcode_00_07=0b00011010
+{
+ rn_08_11 = macl;
+}
+
+:sts.l macl,@-rn_08_11 is macl & opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00010010
+{
+ rn_08_11 = rn_08_11 -4;
+ *rn_08_11 = macl;
+}
+
+:sts pr,rn_08_11 is pr & opcode_12_15=0b0000 & rn_08_11 & opcode_00_07=0b00101010
+{
+ rn_08_11 = pr;
+}
+
+:sts.l pr,@-rn_08_11 is pr & opcode_12_15=0b0100 & rn_08_11 & opcode_00_07=0b00100010
+{
+ rn_08_11 = rn_08_11 -4;
+ *rn_08_11 = pr;
+}
+
+:trapa imm_00_07 is opcode_08_15=0b11000011 & imm_00_07
+{
+ r15 = r15 -4;
+ *r15 = sr;
+
+ r15 = r15- 4;
+ *r15 = pc + 2;
+
+ pc = *(vbr + (imm_00_07 * 4));
+ goto [pc];
+}