From e50f27d6b683c7c781f78e296ec3d66f4f1637a6 Mon Sep 17 00:00:00 2001 From: Sami Saari Date: Sat, 28 Mar 2026 15:31:09 +0000 Subject: [PATCH] #1244 Add CPU32 processor variant with full instruction set support Add Motorola CPU32 processor variant to the 68000 processor module. CPU32 is based on the 68020 with some instructions removed and table lookup/interpolation instructions added. Used in MC68330, MC68340, MC68360 and similar microcontrollers. Changes: - 68000.sinc: @ifdef/@ifndef CPU32 conditionals - Added: TBL instructions, LPSTOP, BGND - Excluded: BFxxx, CALLM, CAS, CAS2, PACK, RTM, UNPK - CPU32.slaspec: new language specification - 68000.ldefs: CPU32 variant definition - certification.manifest: CPU32.slaspec entry - Emulator test classes and pcode_defs.py configuration All 79 CPU32 instructions verified against CPU32 Reference Manual (Rev 1, Dec 1990). Pcode emulator tests pass: 16/16 O0, 16/16 O3. --- .../SleighDevTools/pcodetest/pcode_defs.py | 16 ++ .../Processors/68000/certification.manifest | 1 + .../68000/data/languages/68000.ldefs | 13 ++ .../68000/data/languages/68000.sinc | 141 +++++++++++++++++- .../68000/data/languages/CPU32.slaspec | 6 + .../processors/CPU32_O0_EmulatorTest.java | 40 +++++ .../processors/CPU32_O3_EmulatorTest.java | 40 +++++ 7 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 Ghidra/Processors/68000/data/languages/CPU32.slaspec create mode 100644 Ghidra/Processors/68000/src/test.processors/java/ghidra/test/processors/CPU32_O0_EmulatorTest.java create mode 100644 Ghidra/Processors/68000/src/test.processors/java/ghidra/test/processors/CPU32_O3_EmulatorTest.java diff --git a/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py b/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py index 0e70268d34..44d612a11b 100644 --- a/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py +++ b/Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py @@ -842,3 +842,19 @@ PCodeTest({ 'language_id': 'Xtensa:BE:32:default', 'ccflags': '-L %(toolchain_dir)s/lib/gcc/xtensa-elf/%(gcc_version)s', }) + + +PCodeTest({ + 'name': 'CPU32', + 'build_all': 1, + 'build_exe': 0, + 'has_float': 0, + 'has_double': 0, + 'toolchain': 'm68k/m68k-linux-gnu', + 'exec_prefix': 'm68k-linux-gnu-', + 'gcc_version': '14', + 'ccflags': '-mcpu=cpu32 -nostdlib -static', + 'cclibs': '-lgcc', + 'gcc_libdir': '/usr/lib/gcc-cross/m68k-linux-gnu/14', + 'language_id': '68000:BE:32:CPU32', +}) diff --git a/Ghidra/Processors/68000/certification.manifest b/Ghidra/Processors/68000/certification.manifest index 55d58490e3..caf51979e7 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 5115f2d878..7fe13fc6bf 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 (MC68340) + + + diff --git a/Ghidra/Processors/68000/data/languages/68000.sinc b/Ghidra/Processors/68000/data/languages/68000.sinc index 674c9d0653..963f0829d3 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)" +@endif + # Floating-point condition code bits within FPSR @define N_FP "FPSR[27,1]" @define Z_FP "FPSR[26,1]" @@ -173,9 +177,29 @@ define token extword (16) reg12x = (12,15) reg12xwu = (12,15) reg12xwl = (12,15) -@endif +@endif +@ifdef CPU32 + tbl_dr_size = (6,7) + tbl_dr_round = (10,10) + tbl_dr_sign = (11,11) + tbl_dr_reg = (0,2) +@endif ; +@ifdef CPU32 +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) @@ -307,12 +331,20 @@ 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 ]; @@ -1051,6 +1083,7 @@ with : extGUARD=1 { local source = regdn; mask:4 = 1 << (const8 & 31); ZF = (source & mask) == 0; regdn = source & (~mask); } +@ifndef CPU32 bfOffWd: {f_off:f_wd} is f_off & f_wd { } :bfchg e2l^bfOffWd is opbig=0xea & op67=3 & $(DAT_DIR_CTL_ADDR_MODES); bfOffWd & f_off & f_wd; e2l [ savmod2=savmod1; regtsan=regtfan; ] { logflags(); @@ -1144,6 +1177,7 @@ bfOffWd: {f_off:f_wd} is f_off & f_wd { } getbitfield(tmp, f_off, f_wd); resbitflags(tmp, f_wd-1); } +@endif # CPU32 - no bitfield instructions define pcodeop breakpoint; :bkpt "#"op02 is opbig=0x48 & op67=1 & op5=0 & op34=1 & op02 { breakpoint(); } @@ -1205,7 +1239,8 @@ define pcodeop breakpoint; } @endif # COLDFIRE -# TODO: Determine layout of a module descriptor +@ifndef CPU32 +# TODO: Determine layout of a module descriptor define pcodeop callm; :callm const8,e2l is opbig=6 & op67=3 & $(CTL_ADDR_MODES); const8; e2l [ savmod2=savmod1; regtsan=regtfan; ] { PC = callm(const8, e2l); @@ -1283,6 +1318,7 @@ define pcodeop callm; ZF = 1; NF = 0; } +@endif # CPU32 - no CALLM, CAS, CAS2 :chk.w eaw,reg9dnw is (op=4 & reg9dnw & op68=6 & $(DAT_ALTER_ADDR_MODES))... & eaw { build eaw; @@ -2060,6 +2096,7 @@ macro negResFlags(result) { :ori const8,"CCR" is opbig=0 & op37=7 & op02=4; const8 { packflags(SR); SR=SR|zext(const8); unpackflags(SR); } :ori const16,SR is SR; opbig=0x00 & d8base=0x7c; const16 { packflags(SR); SR=SR|const16; unpackflags(SR); } +@ifndef CPU32 :pack Tyw,Txw,const16 is op=8 & op48=20 & Txw & Tyw & rmbit=0; const16 { local value = (Tyw & 0x0F0F) + const16; Txw = (Txw & 0xFF00) | ((value & 0x0F00) >> 4) | (value & 0x000F); @@ -2070,6 +2107,7 @@ macro negResFlags(result) { local result:2 = ((value & 0x0F00) >> 4) | (value & 0x000F); Txb = result:1; } +@endif # CPU32 - no PACK :pea eaptr is (opbig=0x48 & op67=1 & $(CTL_ADDR_MODES))... & eaptr { value:4 = eaptr; SP = SP-4; *SP = value; } @@ -2227,9 +2265,11 @@ ptestLevel: "#"^mregn is mregn { export *[const]:1 mregn; } :rtd const16 is opbig=0x4e & op37=14 & op02=4; const16 { PC = *SP; SP = SP + 4 + zext(const16); return [PC]; } :rte is d16=0x4e73 { tmp:4 = 0; return [tmp]; } +@ifndef CPU32 define pcodeop rtm; :rtm regdn is opbig=0x06 & op37=24 & regdn { PC = rtm(regdn); return [PC]; } :rtm regan is opbig=0x06 & op37=25 & regan { PC = rtm(regan); return [PC];} +@endif # CPU32 - no RTM :rtr is opbig=0x4e & op37=14 & op02=7 { SR = *SP; SP = SP+2; PC = *SP; SP = SP+4; unpackflags(SR); return [PC]; } @@ -2306,6 +2346,7 @@ define pcodeop stop; :unlk regan is opbig=0x4e & op37=11 & regan { SP = regan; regan = *SP; SP = SP+4; } +@ifndef CPU32 :unpk Tyw,Txw,const16 is op=8 & Txw & op48=24 & Tyw & rmbit=0; const16 { Txw = (Txw & 0xF0F0) | ((((Tyw & 0x00F0) << 4) | (Tyw & 0x000F)) + const16); } @@ -2315,7 +2356,9 @@ define pcodeop stop; source = (((source & 0x00F0) << 4) | (source & 0x000F)) + const16; Txw = (Txw & 0xF0F0) | source; } +@endif # CPU32 - no UNPK +@ifndef CPU32 # Floating Point Instructions # 68040 directly implements Floating Point instructions but requires Coprocessor ID be 001 @@ -2883,6 +2926,7 @@ fsubrnd: "d" is fdst & fopmode=0x6c { tmp:4 = float2float(fdst); fdst = float2f :ftwotox.x fsrc, fdst is op=15 & $(FP_COP) & op68=0 & mode=0 & regan=0; frm=0 & f1515=0 & f1313=0 & fsrc & fdst & fopmode=0x11 { fdst = ftwotox(fsrc); } +@endif # CPU32 - no FPU instructions @ifdef COLDFIRE @@ -3151,4 +3195,97 @@ moveaccreg2: ACC3 is ACC3 & op01=3 { export ACC3; } @endif +@ifdef CPU32 + +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 = 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); } + +define pcodeop low_power_stop; +:lpstop "#"^d16 is opbig=0xf8 & d8base=0x00; opbig=0x01 & d8base=0xC0; d16 { SR = d16; low_power_stop(); } + +define pcodeop background_mode; +:bgnd is opbig=0x4A & d8base=0xFA { background_mode(); } + +@endif # CPU32 } # end with : extGUARD=1 diff --git a/Ghidra/Processors/68000/data/languages/CPU32.slaspec b/Ghidra/Processors/68000/data/languages/CPU32.slaspec new file mode 100644 index 0000000000..dc2c54ab6f --- /dev/null +++ b/Ghidra/Processors/68000/data/languages/CPU32.slaspec @@ -0,0 +1,6 @@ +# Motorola's CPU32 processor + +@define CPU32 "" +@define MC68332 "" + +@include "68000.sinc" diff --git a/Ghidra/Processors/68000/src/test.processors/java/ghidra/test/processors/CPU32_O0_EmulatorTest.java b/Ghidra/Processors/68000/src/test.processors/java/ghidra/test/processors/CPU32_O0_EmulatorTest.java new file mode 100644 index 0000000000..583c7052a9 --- /dev/null +++ b/Ghidra/Processors/68000/src/test.processors/java/ghidra/test/processors/CPU32_O0_EmulatorTest.java @@ -0,0 +1,40 @@ +/* ### + * 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. + */ +package ghidra.test.processors; + +import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; +import junit.framework.Test; + +public class CPU32_O0_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "68000:BE:32:CPU32"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public CPU32_O0_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "CPU32_GCC_O0"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(CPU32_O0_EmulatorTest.class); + } +} diff --git a/Ghidra/Processors/68000/src/test.processors/java/ghidra/test/processors/CPU32_O3_EmulatorTest.java b/Ghidra/Processors/68000/src/test.processors/java/ghidra/test/processors/CPU32_O3_EmulatorTest.java new file mode 100644 index 0000000000..086c4ab070 --- /dev/null +++ b/Ghidra/Processors/68000/src/test.processors/java/ghidra/test/processors/CPU32_O3_EmulatorTest.java @@ -0,0 +1,40 @@ +/* ### + * 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. + */ +package ghidra.test.processors; + +import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; +import junit.framework.Test; + +public class CPU32_O3_EmulatorTest extends ProcessorEmulatorTestAdapter { + + private static final String LANGUAGE_ID = "68000:BE:32:CPU32"; + private static final String COMPILER_SPEC_ID = "default"; + + private static final String[] REG_DUMP_SET = new String[] {}; + + public CPU32_O3_EmulatorTest(String name) throws Exception { + super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET); + } + + @Override + protected String getProcessorDesignator() { + return "CPU32_GCC_O3"; + } + + public static Test suite() { + return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(CPU32_O3_EmulatorTest.class); + } +}