diff --git a/Ghidra/Processors/68000/certification.manifest b/Ghidra/Processors/68000/certification.manifest
index 55d58490e3a..caf51979e76 100644
--- a/Ghidra/Processors/68000/certification.manifest
+++ b/Ghidra/Processors/68000/certification.manifest
@@ -12,6 +12,7 @@ data/languages/68020.slaspec||GHIDRA||reviewed||END|
data/languages/68030.slaspec||GHIDRA||||END|
data/languages/68040.slaspec||GHIDRA||||END|
data/languages/coldfire.slaspec||GHIDRA||||END|
+data/languages/CPU32.slaspec||GHIDRA||||END|
data/manuals/68000.idx||GHIDRA||||END|
data/patterns/68000_patterns.xml||GHIDRA||||END|
data/patterns/patternconstraints.xml||GHIDRA||||END|
diff --git a/Ghidra/Processors/68000/data/languages/68000.ldefs b/Ghidra/Processors/68000/data/languages/68000.ldefs
index 5115f2d878b..4b9135c6867 100644
--- a/Ghidra/Processors/68000/data/languages/68000.ldefs
+++ b/Ghidra/Processors/68000/data/languages/68000.ldefs
@@ -73,4 +73,17 @@
+
+ Motorola 32-bit CPU32
+
+
+
diff --git a/Ghidra/Processors/68000/data/languages/68000.sinc b/Ghidra/Processors/68000/data/languages/68000.sinc
index 9ad6a66119f..97d5f5b5d88 100644
--- a/Ghidra/Processors/68000/data/languages/68000.sinc
+++ b/Ghidra/Processors/68000/data/languages/68000.sinc
@@ -59,6 +59,10 @@ define register offset=0x746 size=10 [ FP7 ];
@define DAT_DIR_CTL_ADDR_MODES2 "(mode2=0 | mode2=2 | mode2=5 | mode2=6 | mode=7)" # Data direct and control addressing modes
@define CTL_ADDR_MODES2 "(mode2=2 | mode2=5 | mode2=6 | mode2=7)" # Control addressing modes
+@ifdef CPU32
+@define TBL_ADDR_MODES "(tbl_mode=2 | tbl_mode=4 | tbl_mode=5 | tbl_mode=6 | tbl_mode=7)" # Addressing modes for tblxx instructions
+@endif
+
# Floating-point condition code bits within FPSR
@define N_FP "FPSR[27,1]"
@define Z_FP "FPSR[26,1]"
@@ -172,9 +176,33 @@ define token extword (16)
reg12x = (12,15)
reg12xwu = (12,15)
reg12xwl = (12,15)
-@endif
+@endif
+@ifdef CPU32 # Data Register Interpolation
+ tbl_dr_size = (6,7)
+ tbl_dr_round = (10,10)
+ tbl_dr_sign = (11,11)
+ tbl_dr_reg = (0,2)
+@endif
;
+@ifdef CPU32
+# The TBLxx instructions are two 16-bit tokens optionally followed by a disp16 token.
+# The presence of the disp16 token is governed by bits in the first token.
+# Sleigh's ... operator follows the second token, but needs the bits from the first.
+# To work around that, a single 32-bit token is used in place of the standard tokens.
+define token tbl_instrA(32)
+ tbl_regan=(16,18)
+ tbl_mode=(19,21)
+ tbl_op37=(19,23)
+ tbl_op67=(22,23)
+ tbl_opbig=(24,31)
+ tbl_size=(6,7)
+ tbl_round=(10,10)
+ tbl_sign=(11,11)
+ tbl_regxdn=(12,14)
+;
+@endif
+
define token extword2 (16)
regda2 = (12,15)
ext2_911 = (9,11)
@@ -305,12 +333,23 @@ define context contextreg
extGUARD = (14,14) # guard for saving off modes before starting instructions
;
+@ifdef CPU32
+attach variables [ regdn regxdn reg9dn regdr regdq regsdn regdu regdc regdu2 regdc2 tbl_regxdn tbl_dr_reg ] [ D0 D1 D2 D3 D4 D5 D6 D7 ];
+@else
attach variables [ regdn regxdn reg9dn regdr regdq regsdn regdu regdc regdu2 regdc2 ] [ D0 D1 D2 D3 D4 D5 D6 D7 ];
+@endif
+
attach variables [ fldoffreg fldwdreg f_reg fcnt fkfacreg fldynreg ] [ D0 D1 D2 D3 D4 D5 D6 D7 ];
attach variables [ regdnw regxdnw reg9dnw regsdnw regduw regdcw regdu2w regdc2w ] [ D0w D1w D2w D3w D4w D5w D6w D7w ];
attach variables [ regdnb reg9dnb regsdnb regdub regdcb ] [ D0b D1b D2b D3b D4b D5b D6b D7b ];
attach variables [ regda regda2 ] [ D0 D1 D2 D3 D4 D5 D6 D7 A0 A1 A2 A3 A4 A5 A6 SP ];
+
+@ifdef CPU32
+attach variables [ regan regxan reg9an regfan regsan aregx tbl_regan ] [ A0 A1 A2 A3 A4 A5 A6 SP ];
+@else
attach variables [ regan regxan reg9an regfan regsan aregx ] [ A0 A1 A2 A3 A4 A5 A6 SP ];
+@endif
+
attach variables [ reganw regxanw regsanw ] [ A0w A1w A2w A3w A4w A5w A6w A7w ];
attach variables [ reganb regsanb ] [ A0b A1b A2b A3b A4b A5b A6b A7b ];
@@ -480,7 +519,7 @@ eab: "#"^d8 is mode=7 & regan=4; d8 { export *[const]:1 d8; }
# Second effective address calculation for mov
-# NB- Extended-precsion are 12 bytes, so we need to increment or decrement the reg by 12 not 4
+# NB- Extended-precision are 12 bytes, so we need to increment or decrement the reg by 12 not 4
#
# size=extend | packed (96-bit)
# The fmovem.x insn needs the movemptr to be set here
@@ -1651,6 +1690,97 @@ skip_addr: skipAddr is op02=3 [skipAddr = inst_next + 4;] { export *[ram]:4 skip
:tpf.l is opbig=0x51 & op37=0x1f & op02=3 & skip_addr { goto skip_addr; } # nop + 2 word
@endif # COLDFIRE
+@ifdef CPU32
+
+#TODO: Finish TBLxx instruction implementation:
+
+tbl_eal: (tbl_regan) is tbl_mode=2 & tbl_regan { export *:4 tbl_regan; }
+tbl_eal: -(tbl_regan) is tbl_mode=4 & tbl_regan { tbl_regan = tbl_regan - 4; export *:4 tbl_regan; }
+tbl_eal: (d16,tbl_regan) is tbl_mode=5 & tbl_regan; d16 { local tmp:4 = tbl_regan + d16; export *:4 tmp; }
+tbl_eal: (extw) is tbl_mode=6 & tbl_regan; extw [ regtfan = tbl_regan; pcmode = 0; ] { build extw; export *:4 extw; }
+tbl_eal: (d16,PC) is PC & tbl_mode=7 & tbl_regan=2; d16 { tmp:4 = inst_start + 2 + d16; export *:4 tmp; }
+tbl_eal: (extw) is tbl_mode=7 & tbl_regan=3; extw [ pcmode=1; ] { build extw; export *:4 extw; }
+tbl_eal: (d16)".w" is tbl_mode=7 & tbl_regan=0; d16 { export *:4 d16; }
+tbl_eal: (d32)".l" is tbl_mode=7 & tbl_regan=1; d32 { export *:4 d32; }
+tbl_eal: "#"^d32 is tbl_mode=7 & tbl_regan=4; d32 { export *[const]:4 d32; }
+
+tbl_eaw: (tbl_regan) is tbl_mode=2 & tbl_regan { export *:2 tbl_regan; }
+# tbl_eaw: -(tbl_regan) is tbl_mode=4 & tbl_regan { tbl_regan = tbl_regan - 2; export *:2 tbl_regan; }
+# tbl_eaw: (d16,tbl_regan) is tbl_mode=5 & tbl_regan; d16 { local tmp = tbl_regan + d16; export *:2 tmp; }
+tbl_eaw: (extw) is tbl_mode=6 & tbl_regan; extw [ pcmode=0; regtfan=tbl_regan; ] { build extw; export *:2 extw; }
+tbl_eaw: (d16,PC) is PC & tbl_mode=7 & tbl_regan=2; d16 { tmp:4 = inst_start + 2 + d16; export *:2 tmp; }
+tbl_eaw: (extw) is tbl_mode=7 & tbl_regan=3; extw [ pcmode=1; ] { build extw; export *:2 extw; }
+tbl_eaw: (d16)".w" is tbl_mode=7 & tbl_regan=0; d16 { export *:2 d16; }
+tbl_eaw: (d32)".l" is tbl_mode=7 & tbl_regan=1; d32 { export *:2 d32; }
+tbl_eaw: "#"^d16 is tbl_mode=7 & tbl_regan=4; d16 { export *[const]:2 d16; }
+
+tbl_eab: (tbl_regan) is tbl_mode=2 & tbl_regan { export *:1 tbl_regan; }
+# tbl_eab: -(tbl_regan) is tbl_mode=4 & tbl_regan { tbl_regan = tbl_regan - 1; export *:1 tbl_regan; }
+# tbl_eab: (d16,tbl_regan) is tbl_mode=5 & tbl_regan; d16 { local tmp = tbl_regan + d16; export *:1 tmp; }
+tbl_eab: (extw) is tbl_mode=6 & tbl_regan; extw [ pcmode=0; regtfan=tbl_regan; ] { build extw; export *:1 extw; }
+tbl_eab: (d16,PC) is PC & tbl_mode=7 & tbl_regan=2; d16 { tmp:4 = inst_start + 2 + d16; export *:1 tmp; }
+tbl_eab: (extw) is tbl_mode=7 & tbl_regan=3; extw [ pcmode=1; ] { build extw; export *:1 extw; }
+tbl_eab: (d16)".w" is tbl_mode=7 & tbl_regan=0; d16 { export *:1 d16; }
+tbl_eab: (d32)".l" is tbl_mode=7 & tbl_regan=1; d32 { export *:1 d32; }
+tbl_eab: "#"^d8 is tbl_mode=7 & tbl_regan=4; d8 { export *[const]:1 d8; }
+
+tblsign: "u" is tbl_sign=0 { }
+tblsign: "s" is tbl_sign=1 { }
+
+tbldrsign: "u" is tbl_dr_sign=0 { }
+tbldrsign: "s" is tbl_dr_sign=1 { }
+
+define pcodeop tableLookup;
+
+# Rounded Table Lookup and Interpolate
+
+:tbl^tblsign^".b" tbl_eab,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=0 & tblsign & tbl_round=0 & tbl_regxdn) ... & tbl_eab
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eab); }
+
+:tbl^tblsign^".w" tbl_eaw,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=1 & tblsign & tbl_round=0 & tbl_regxdn) ... & tbl_eaw
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eaw); }
+
+:tbl^tblsign^".l" tbl_eal,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=2 & tblsign & tbl_round=0 & tbl_regxdn) ... & tbl_eal
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eal); }
+
+# Unrounded Table Lookup and Interpolate
+
+:tbl^tblsign^"n.b" tbl_eab,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=0 & tblsign & tbl_round=1 & tbl_regxdn) ... & tbl_eab
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eab); }
+
+:tbl^tblsign^"n.w" tbl_eaw,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=1 & tblsign & tbl_round=1 & tbl_regxdn) ... & tbl_eaw
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eaw); }
+
+:tbl^tblsign^"n.l" tbl_eal,tbl_regxdn is (tbl_opbig=0xF8 & tbl_op67=0 & $(TBL_ADDR_MODES) & tbl_size=2 & tblsign & tbl_round=1 & tbl_regxdn) ... & tbl_eal
+ { tbl_regxdn = tableLookup(tbl_regxdn, tbl_eal); }
+
+define pcodeop interpolate;
+
+# Rounded Data Register Interpolate
+
+:tbl^tbldrsign^".b" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=0 & tbldrsign & tbl_dr_round=0 & tbl_dr_reg & regxdn
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
+
+:tbl^tbldrsign^".w" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=1 & tbldrsign & tbl_dr_round=0 & tbl_dr_reg & regxdn
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
+
+:tbl^tbldrsign^".l" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=2 & tbldrsign & tbl_dr_round=0 & tbl_dr_reg & regxdn
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
+
+# Unrounded Data Register Interpolate
+
+:tbl^tbldrsign^"n.b" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=0 & tbldrsign & tbl_dr_round=1 & tbl_dr_reg & regxdn
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
+
+:tbl^tbldrsign^"n.w" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=1 & tbldrsign & tbl_dr_round=1 & tbl_dr_reg & regxdn
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
+
+:tbl^tbldrsign^"n.l" regdn:tbl_dr_reg,regxdn is opbig=0xF8 & op37=0 & mode=0 & regdn ; tbl_dr_size=2 & tbldrsign & tbl_dr_round=1 & tbl_dr_reg & regxdn
+ { regxdn = interpolate(regdn, tbl_dr_reg); }
+
+@endif # CPU32
+
+
# Tables for register lists, for the movem instruction
# Register to mememory, forward direction, via word
r2mfwf: D0w is D0w & mvm0=1 { *movemptr = D0w; movemptr = movemptr + 2; }
diff --git a/Ghidra/Processors/68000/data/languages/CPU32.slaspec b/Ghidra/Processors/68000/data/languages/CPU32.slaspec
new file mode 100644
index 00000000000..75d9af4ba2a
--- /dev/null
+++ b/Ghidra/Processors/68000/data/languages/CPU32.slaspec
@@ -0,0 +1,7 @@
+# Motorola's CPU32 processor
+
+@define CPU32 ""
+@define MC68332 ""
+@define MC68336 ""
+
+@include "68000.sinc"
\ No newline at end of file