From 51d73bd395810801d85c83dee3a1efe644289ca7 Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Wed, 25 Dec 2019 13:50:39 +0100 Subject: [PATCH 01/14] CP1600-series processor support. --- Ghidra/Processors/CP1600/Module.manifest | 0 Ghidra/Processors/CP1600/build.gradle | 4 + .../CP1600/data/languages/CP1600.cspec | 20 + .../CP1600/data/languages/CP1600.ldefs | 15 + .../CP1600/data/languages/CP1600.opinion | 2 + .../CP1600/data/languages/CP1600.pspec | 5 + .../CP1600/data/languages/CP1600.slaspec | 651 ++++++++++++++++++ 7 files changed, 697 insertions(+) create mode 100644 Ghidra/Processors/CP1600/Module.manifest create mode 100644 Ghidra/Processors/CP1600/build.gradle create mode 100644 Ghidra/Processors/CP1600/data/languages/CP1600.cspec create mode 100644 Ghidra/Processors/CP1600/data/languages/CP1600.ldefs create mode 100644 Ghidra/Processors/CP1600/data/languages/CP1600.opinion create mode 100644 Ghidra/Processors/CP1600/data/languages/CP1600.pspec create mode 100644 Ghidra/Processors/CP1600/data/languages/CP1600.slaspec diff --git a/Ghidra/Processors/CP1600/Module.manifest b/Ghidra/Processors/CP1600/Module.manifest new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Ghidra/Processors/CP1600/build.gradle b/Ghidra/Processors/CP1600/build.gradle new file mode 100644 index 0000000000..1ca31f7030 --- /dev/null +++ b/Ghidra/Processors/CP1600/build.gradle @@ -0,0 +1,4 @@ +apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle" +apply from: "$rootProject.projectDir/gradle/processorProject.gradle" +apply plugin: 'eclipse' +eclipse.project.name = 'Processors CP1600' diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.cspec b/Ghidra/Processors/CP1600/data/languages/CP1600.cspec new file mode 100644 index 0000000000..6d36f9d6ee --- /dev/null +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.cspec @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.ldefs b/Ghidra/Processors/CP1600/data/languages/CP1600.ldefs new file mode 100644 index 0000000000..45a7688cce --- /dev/null +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.ldefs @@ -0,0 +1,15 @@ + + + + + General Instruments CP1600 + + + diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.opinion b/Ghidra/Processors/CP1600/data/languages/CP1600.opinion new file mode 100644 index 0000000000..c974dcfb5f --- /dev/null +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.opinion @@ -0,0 +1,2 @@ + + diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.pspec b/Ghidra/Processors/CP1600/data/languages/CP1600.pspec new file mode 100644 index 0000000000..6be5008d9a --- /dev/null +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.pspec @@ -0,0 +1,5 @@ + + + + + diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec new file mode 100644 index 0000000000..b8a47d9856 --- /dev/null +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -0,0 +1,651 @@ +define endian=big; +define alignment=2; +define space ram type=ram_space wordsize=2 size=2 default; +define space register type=register_space size=2; + +define register offset=0x00 size=2 [ R0 R1 R2 R3 R4 R5 R6 R7 ]; +define register offset=0x10 size=1 [ I D C O Z S ]; # Status bits +define register offset=0x20 size=4 [ contextreg ]; + +define token opcode_word (16) + clear = (10, 15) + reg3_5 = (3, 5) + reg0_2 = (0, 2) + reg0_1 = (0, 1) + operation_size = (2, 2) + + branch_sign = (5, 5) + branch_external = (4, 4) + branch_condition = (0, 3) + external_condition = (0, 3) + + opcode6_9 = (6, 9) + opcode3_9 = (3, 9) + opcode2_9 = (2, 9) + opcode1_9 = (1, 9) + opcode0_9 = (0, 9) +; + +define token jump_token (32) + unused_jump = (26, 31) + reg24_25 = (24, 25) + address_hi = (18, 23) + jump_type = (16, 17) + address_lo = (0, 9) +; + +define token double16 (32) + unused_lo = (17, 31) + value_lo = (16, 23) + unused_hi = (8, 15) + value_hi = (0, 7) +; + +define token immediate16 (16) + imm16 = (0, 15) + addr16 = (0, 15) +; + +define context contextreg + doublebyte = (0, 0) +; + +attach variables [ reg0_1 ] [ R0 R1 R2 R3 ]; +attach variables [ reg0_2 reg3_5 ] [ R0 R1 R2 R3 R4 R5 R6 R7 ]; +attach variables [ reg24_25 ] [ R4 R5 R6 R7 ]; # R7 is not used. + +################################################################ + +jmpdest16: reloc is address_hi & address_lo [ reloc = (address_hi << 10) + address_lo; ] { export *:2 reloc; } +branchdest16: reloc is branch_sign=0 ; imm16 [ reloc = inst_start + 2 + imm16; ] { export *:2 reloc; } +branchdest16: reloc is branch_sign=1 ; imm16 [ reloc = inst_start + 2 - imm16; ] { export *:2 reloc; } +splitimm16: split is value_hi & value_lo [ split = (value_hi << 8) + value_lo; ] { local tmp:2 = split & 0xFFFF; export tmp; } + +################################################################ + +macro resultFlags(value) { + Z = value == 0; + S = value s< 0; +} + +macro addition(first, second) { + local tmpC = carry(first, second); + local tmpO = scarry(first, second); + first = first + second; + C = tmpC; + O = tmpO; + resultFlags(first); +} + +macro readHalfDoubleWord(reg, dest) { + if (reg != R6) goto ; + reg = reg - 1; + + local __tmp__:2 = reg; + local __ptr__:2 = *__tmp__; + dest = (*:2 (__ptr__)) & 0x00FF; + if ((reg != R4) || (reg != R5)) goto ; + reg = reg + 1; + +} + +macro readDoubleWord(reg, dest) { + local __tmpl__:2 = 0; + readHalfDoubleWord(reg, __tmpl__); + local __tmph__:2 = 0; + readHalfDoubleWord(reg, __tmph__); + dest = (__tmph__ << 8) | __tmpl__; +} + +macro comparison(first, second) { + local __val__ = first - second; + O = sborrow(first, second); + C = first < second; + resultFlags(__val__); +} + +macro subtraction(first, second) { + local __val__ = first - second; + O = sborrow(first, second); + C = first < second; + resultFlags(__val__); + first = __val__; +} + +################################################################ + +define pcodeop TerminateCurrentInterrupt; +define pcodeop SoftwareInterrupt; + +################################################################ + +:ADD addr16, reg0_2 is opcode3_9=0x0058 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local ptr:2 = addr16; + addition(reg0_2, *(*:2 ptr)); +} + +:ADCR reg0_2 is opcode3_9=0x0005 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local oldC = zext(C); + addition(reg0_2, oldC); +} + +:ADDR reg3_5, reg0_2 is opcode6_9=0x0003 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + addition(reg0_2, reg3_5); +} + +:AND addr16, reg0_2 is opcode3_9=0x0070 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local ptr:2 = addr16; + reg0_2 = reg0_2 & *(*:2 ptr); + resultFlags(reg0_2); +} + +:ANDR reg3_5, reg0_2 is opcode6_9=0x0006 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 & reg3_5; + resultFlags(reg0_2); +} + +:B branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=0) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + goto branchdest16; +} + +:BC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=1) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (C == 1) goto branchdest16; +} + +:BEQ branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=4) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (Z == 1) goto branchdest16; +} + +:BESC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=15) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (S == C) goto branchdest16; +} + +:BGE branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=13) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (S == O) goto branchdest16; +} + +:BGT branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=14) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if ((Z == 0) || (S == O)) goto branchdest16; +} + +:BLE branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=6) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if ((Z == 1) || (S != O)) goto branchdest16; +} + +:BLT branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=5) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (S != O) goto branchdest16; +} + +:BMI branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=11) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (S == 1) goto branchdest16; +} + +:BNC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=9) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (C == 0) goto branchdest16; +} + +:BNEQ branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=12) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (Z == 0) goto branchdest16; +} + +:BNOV branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=10) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (O == 0) goto branchdest16; +} + +:BOV branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=2) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (O == 1) goto branchdest16; +} + +:BPL branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=3) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (S == 0) goto branchdest16; +} + +:BUSC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=7) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + if (S != C) goto branchdest16; +} + +:BEXT branchdest16, #external_condition is (opcode6_9=0x0008 & branch_external=1 & external_condition) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + goto branchdest16; +} + +:CLRC is opcode0_9=0x0006 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + C = 0; +} + +:CMP addr16, reg0_2 is opcode3_9=0x0068 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local ptr:2 = addr16; + comparison(reg0_2, *(*:2 ptr)); +} + +:CMPR reg3_5, reg0_2 is opcode6_9=0x0005 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + comparison(reg0_2, reg3_5); +} + +:COMR reg0_2 is opcode3_9=0x0003 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = ~reg0_2; + resultFlags(reg0_2); +} + +:DECR reg0_2 is opcode3_9=0x0002 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 - 1; + resultFlags(reg0_2); +} + +:DIS is opcode0_9=0x0003 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + I = 0; +} + +:EIS is opcode0_9=0x0002 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + I = 1; +} + +:GSWD reg0_1 is opcode2_9=0x000C & reg0_1 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local mask:2 = (zext(S) << 7) + (zext(Z) << 6) + (zext(O) << 5) + (zext(C) << 4); + reg0_1 = (mask << 8) + mask; +} + +:HLT is opcode0_9=0x0000 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + goto inst_start; +} + +:INCR reg0_2 is opcode3_9=0x0001 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 + 1; + resultFlags(reg0_2); +} + +:J jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & reg24_25=R7 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + goto jmpdest16; +} + +:JD jmpdest16 is opcode0_9=0x0004 ; jump_type=2 & reg24_25=R7 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + I = 0; + goto jmpdest16; +} + +:JE jmpdest16 is opcode0_9=0x0004 ; jump_type=1 & reg24_25=R7 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + I = 1; + goto jmpdest16; +} + +:JSR reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & reg24_25 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg24_25 = inst_next; + call jmpdest16; +} + +:JSRD reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=2 & reg24_25 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + I = 0; + reg24_25 = inst_next; + call jmpdest16; +} + +:JSRE reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=1 & reg24_25 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + I = 1; + reg24_25 = inst_next; + call jmpdest16; +} + +:MOVR reg3_5, reg0_2 is opcode6_9=0x0002 & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg3_5; + resultFlags(reg0_2); +} + +:MVI addr16, reg0_2 is opcode3_9=0x0050 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local ptr:2 = addr16; + reg0_2 = *(*:2 ptr); +} + +:MVO reg0_2, addr16 is opcode3_9=0x0048 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local ptr:2 = addr16; + *ptr = reg0_2; +} + +:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local ptr:2 = reg3_5; + *ptr = reg0_2; + if ((reg3_5 != R4) && (reg3_5 != R5) && (reg3_5 != R6)) goto inst_next; + reg3_5 = reg3_5 + 1; +} + +:MVOI reg0_2 is opcode3_9=0x004F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmp:2 = inst_start + 2; + *tmp = reg0_2; +} + +:NEGR reg0_2 is opcode3_9=0x0004 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmp = reg0_2 ^ 0xFFFF; + local tmpC = carry(tmp, 1); + local tmpO = scarry(tmp, 1); + reg0_2 = -reg0_2; + C = tmpC; + O = tmpO; + resultFlags(reg0_2); +} + +:NOP is opcode1_9=0x001A [ doublebyte=0; globalset(inst_next, doublebyte); ] { +} + +:NOPP is opcode6_9=0x0008 & branch_external=0 & branch_condition=8 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +} + +:RSWD reg0_2 is opcode3_9=0x0007 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + C = (reg0_2 & 0b00001000) != 0; + O = (reg0_2 & 0b00010000) != 0; + Z = (reg0_2 & 0b00100000) != 0; + S = (reg0_2 & 0b01000000) != 0; +} + +:SDBD is opcode0_9=0x0001 [ doublebyte=1; globalset(inst_next, doublebyte); ] { + D = 1; +} + +:SETC is opcode0_9=0x0007 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + C = 1; +} + +:SIN is opcode1_9=0x001B [ doublebyte=0; globalset(inst_next, doublebyte); ] { + SoftwareInterrupt(); +} + +:SUB addr16, reg0_2 is opcode3_9=0x0060 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local ptr:2 = addr16; + subtraction(reg0_2, *(*:2 ptr)); +} + +:SUBR reg3_5, reg0_2 is opcode6_9=0x0004 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + subtraction(reg0_2, reg3_5); +} + +:TCI is opcode0_9=0x0005 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + TerminateCurrentInterrupt(); +} + +:XOR addr16, reg0_2 is opcode3_9=0x0078 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local ptr:2 = addr16; + reg0_2 = reg0_2 ^ *(*:2 ptr); + resultFlags(reg0_2); +} + +:XORR reg3_5, reg0_2 is opcode6_9=0x0007 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 ^ reg3_5; + resultFlags(reg0_2); +} + +with : operation_size=0 { + +:RLC reg0_2, 1 is opcode3_9=0x000A & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpC = (reg0_2 & 0x8000) != 0; + local tmpS = (reg0_2 & 0x4000) != 0; + reg0_2 = (reg0_2 << 1) + zext(C); + C = tmpC; + S = tmpS; + Z = reg0_2 == 0; +} + +:RRC reg0_2, 1 is opcode3_9=0x000E & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpC = (reg0_2 & 0x0001) != 0; + local tmpS = (reg0_2 & 0x0100) != 0; + reg0_2 = (reg0_2 >> 1) | (zext(C) << 15); + C = tmpC; + S = tmpS; + Z = reg0_2 == 0; +} + +:SAR reg0_2, 1 is opcode3_9=0x000D & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpS = (reg0_2 & 0x0100) != 0; + reg0_2 = reg0_2 s>> 1; + S = tmpS; + Z = reg0_2 == 0; +} + +:SARC reg0_2, 1 is opcode3_9=0x000F & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpC = (reg0_2 & 0x0001) != 0; + local tmpS = (reg0_2 & 0x0100) != 0; + reg0_2 = reg0_2 s>> 1; + C = tmpC; + S = tmpS; + Z = reg0_2 == 0; +} + +:SLL reg0_2, 1 is opcode3_9=0x0009 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpS = (reg0_2 & 0x4000) != 0; + reg0_2 = reg0_2 << 1; + S = tmpS; + Z = reg0_2 == 0; +} + +:SLLC reg0_2, 1 is opcode3_9=0x000B & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpC = (reg0_2 & 0x8000) != 0; + local tmpS = (reg0_2 & 0x4000) != 0; + reg0_2 = reg0_2 << 1; + C = tmpC; + S = tmpS; + Z = reg0_2 == 0; +} + +:SLR reg0_2, 1 is opcode3_9=0x000C & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpS = (reg0_2 & 0x0100) != 0; + reg0_2 = reg0_2 >> 1; + S = tmpS; + Z = reg0_2 == 0; +} + +:SWAP reg0_2, 1 is opcode3_9=0x0008 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpS = (reg0_2 & 0x8000) != 0; + local tmp = (reg0_2 << 8) & 0xFF00; + reg0_2 = tmp | ((reg0_2 >> 8) & 0x00FF); + S = tmpS; +} + +} + +with : operation_size=1 { + +:RLC reg0_2, 2 is opcode3_9=0x000A & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpC = (reg0_2 & 0x8000) != 0; + local tmpO = (reg0_2 & 0x4000) != 0; + local tmpS = (reg0_2 & 0x2000) != 0; + reg0_2 = (reg0_2 << 2) + (zext(C) << 1) + zext(O); + C = tmpC; + O = tmpO; + S = tmpS; + Z = reg0_2 == 0; +} + +:RRC reg0_2, 2 is opcode3_9=0x000E & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpC = (reg0_2 & 0x0001) != 0; + local tmpO = (reg0_2 & 0x0002) != 0; + local tmpS = (reg0_2 & 0x0200) != 0; + reg0_2 = (reg0_2 >> 2) | (zext(C) << 14) | (zext(O) << 15); + C = tmpC; + O = tmpO; + S = tmpS; + Z = reg0_2 == 0; +} + +:SAR reg0_2, 2 is opcode3_9=0x000D & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpS = (reg0_2 & 0x0200) != 0; + reg0_2 = reg0_2 s>> 2; + S = tmpS; + Z = reg0_2 == 0; +} + +:SARC reg0_2, 2 is opcode3_9=0x000F & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpC = (reg0_2 & 0x0001) != 0; + local tmpO = (reg0_2 & 0x0002) != 0; + local tmpS = (reg0_2 & 0x0200) != 0; + reg0_2 = reg0_2 s>> 2; + C = tmpC; + O = tmpO; + S = tmpS; + Z = reg0_2 == 0; +} + +:SLL reg0_2, 2 is opcode3_9=0x0009 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpS = (reg0_2 & 0x2000) != 0; + reg0_2 = reg0_2 << 2; + S = tmpS; + Z = reg0_2 == 0; +} + +:SLLC reg0_2, 2 is opcode3_9=0x000B & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpC = (reg0_2 & 0x8000) != 0; + local tmpO = (reg0_2 & 0x4000) != 0; + local tmpS = (reg0_2 & 0x2000) != 0; + reg0_2 = reg0_2 << 2; + C = tmpC; + O = tmpO; + S = tmpS; + Z = reg0_2 == 0; +} + +:SLR reg0_2, 2 is opcode3_9=0x000C & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpS = (reg0_2 & 0x0200) != 0; + reg0_2 = reg0_2 >> 2; + S = tmpS; + Z = reg0_2 == 0; +} + +:SWAP reg0_2, 2 is opcode3_9=0x0008 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmpS = (reg0_2 & 0x0080) != 0; + reg0_2 = (reg0_2 << 8) | (reg0_2 & 0x00FF); + S = tmpS; +} + +} + +with : doublebyte=0 { + +:ADD@ reg3_5, reg0_2 is opcode6_9=0x000B & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readHalfDoubleWord(reg3_5, val); + addition(reg0_2, val); +} + +:ADDI #imm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + addition(reg0_2, imm16); +} + +:AND@ reg3_5, reg0_2 is opcode6_9=0x000E & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readHalfDoubleWord(reg3_5, val); + reg0_2 = reg0_2 & val; + resultFlags(reg0_2); +} + +:ANDI #imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 & imm16; + resultFlags(reg0_2); +} + +:CMP@ reg3_5, reg0_2 is opcode6_9=0x000D & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmp:2 = 0; + readHalfDoubleWord(reg3_5, tmp); + comparison(reg0_2, tmp); +} + +:CMPI #imm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + comparison(reg0_2, imm16); +} + +:MVI@ reg3_5, reg0_2 is opcode6_9=0x000A & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readHalfDoubleWord(reg3_5, val); + reg0_2 = val; +} + +:MVII #imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = imm16; +} + +:SUB@ reg3_5, reg0_2 is opcode6_9=0x000C & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readHalfDoubleWord(reg3_5, val); + subtraction(reg0_2, val); +} + +:SUBI #imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + subtraction(reg0_2, imm16); +} + +:XOR@ reg3_5, reg0_2 is opcode6_9=0x000F & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readHalfDoubleWord(reg3_5, val); + reg0_2 = reg0_2 ^ val; + resultFlags(reg0_2); +} + +:XORI #imm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 ^ imm16; + resultFlags(reg0_2); +} + +} + +with : doublebyte=1 { + +:ADD@ reg3_5, reg0_2 is opcode6_9=0x000B & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readDoubleWord(reg3_5, val); + addition(reg0_2, val); +} + +:ADDI #splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + addition(reg0_2, splitimm16); +} + +:AND@ reg3_5, reg0_2 is opcode6_9=0x000E & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readDoubleWord(reg3_5, val); + reg0_2 = reg0_2 & val; + resultFlags(reg0_2); +} + +:ANDI #splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 & splitimm16; + resultFlags(reg0_2); +} + +:CMP@ reg3_5, reg0_2 is opcode6_9=0x000D & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local tmp:2 = 0; + readDoubleWord(reg3_5, tmp); + comparison(reg0_2, tmp); +} + +:CMPI #splitimm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + comparison(reg0_2, splitimm16); +} + +:MVI@ reg3_5, reg0_2 is opcode6_9=0x000A & reg0_2 & reg3_5 [ globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readDoubleWord(reg3_5, val); + reg0_2 = val; +} + +:MVII #splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = splitimm16; +} + +:SUB@ reg3_5, reg0_2 is opcode6_9=0x000C & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readDoubleWord(reg3_5, val); + subtraction(reg0_2, val); +} + +:SUBI #splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + subtraction(reg0_2, splitimm16); +} + +:XOR@ reg3_5, reg0_2 is opcode6_9=0x000F & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + local val:2 = 0; + readDoubleWord(reg3_5, val); + reg0_2 = reg0_2 ^ val; + resultFlags(reg0_2); +} + +:XORI #splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 ^ splitimm16; + resultFlags(reg0_2); +} + +} + From 59bf66752048f2ddce559d17046c2ea6f3ef1d7d Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Fri, 27 Dec 2019 15:41:35 +0100 Subject: [PATCH 02/14] Fix review issues. --- .../CP1600/data/languages/CP1600.slaspec | 225 +++++++----------- 1 file changed, 92 insertions(+), 133 deletions(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index b8a47d9856..f4969510e8 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -4,11 +4,11 @@ define space ram type=ram_space wordsize=2 size=2 default; define space register type=register_space size=2; define register offset=0x00 size=2 [ R0 R1 R2 R3 R4 R5 R6 R7 ]; -define register offset=0x10 size=1 [ I D C O Z S ]; # Status bits +define register offset=0x10 size=1 [ I D C O Z S ]; define register offset=0x20 size=4 [ contextreg ]; define token opcode_word (16) - clear = (10, 15) + target3_5 = (3, 5) reg3_5 = (3, 5) reg0_2 = (0, 2) reg0_1 = (0, 1) @@ -27,7 +27,7 @@ define token opcode_word (16) ; define token jump_token (32) - unused_jump = (26, 31) + target24_25 = (24, 25) reg24_25 = (24, 25) address_hi = (18, 23) jump_type = (16, 17) @@ -35,9 +35,7 @@ define token jump_token (32) ; define token double16 (32) - unused_lo = (17, 31) value_lo = (16, 23) - unused_hi = (8, 15) value_hi = (0, 7) ; @@ -52,7 +50,7 @@ define context contextreg attach variables [ reg0_1 ] [ R0 R1 R2 R3 ]; attach variables [ reg0_2 reg3_5 ] [ R0 R1 R2 R3 R4 R5 R6 R7 ]; -attach variables [ reg24_25 ] [ R4 R5 R6 R7 ]; # R7 is not used. +attach variables [ reg24_25 ] [ R4 R5 R6 R7 ]; ################################################################ @@ -61,6 +59,45 @@ branchdest16: reloc is branch_sign=0 ; imm16 [ reloc = inst_start + 2 + imm16 branchdest16: reloc is branch_sign=1 ; imm16 [ reloc = inst_start + 2 - imm16; ] { export *:2 reloc; } splitimm16: split is value_hi & value_lo [ split = (value_hi << 8) + value_lo; ] { local tmp:2 = split & 0xFFFF; export tmp; } +impliedval16: reg3_5 is reg3_5 & (target3_5=0 | target3_5=1 | target3_5=2 | target3_5=3 | target3_5=7) & doublebyte=0 { + local tmp:2 = *:2 reg3_5; + export tmp; +} + +impliedval16: reg3_5 is reg3_5 & (target3_5=4 | target3_5=5) & doublebyte=0 { + local tmp:2 = *:2 reg3_5; + reg3_5 = reg3_5 + 1; + export tmp; +} + +impliedval16: reg3_5 is reg3_5 & target3_5=6 & doublebyte=0 { + reg3_5 = reg3_5 - 1; + local tmp:2 = *:2 reg3_5; + export tmp; +} + +impliedval16: reg3_5 is reg3_5 & (target3_5=4 | target3_5=5) & doublebyte=1 { + local tmp:2 = zext(*:1 reg3_5); + reg3_5 = reg3_5 + 1; + tmp = tmp | (zext(*:1 reg3_5) << 8); + reg3_5 = reg3_5 + 1; + export tmp; +} + +impliedval16: reg3_5 is reg3_5 & target3_5=6 & doublebyte=1 { + reg3_5 = reg3_5 - 1; + local tmp:2 = zext(*:1 reg3_5); + reg3_5 = reg3_5 - 1; + tmp = tmp | (zext(*:1 reg3_5) << 8); + export tmp; +} + +impliedval16: reg3_5 is reg3_5 & (target3_5=0 | target3_5=1 | target3_5=2 | target3_5=3 | target3_5=7) & doublebyte=1 { + local tmp:2 = zext(*:1 reg3_5); + tmp = tmp | (zext(*:1 reg3_5) << 8); + export tmp; +} + ################################################################ macro resultFlags(value) { @@ -77,26 +114,6 @@ macro addition(first, second) { resultFlags(first); } -macro readHalfDoubleWord(reg, dest) { - if (reg != R6) goto ; - reg = reg - 1; - - local __tmp__:2 = reg; - local __ptr__:2 = *__tmp__; - dest = (*:2 (__ptr__)) & 0x00FF; - if ((reg != R4) || (reg != R5)) goto ; - reg = reg + 1; - -} - -macro readDoubleWord(reg, dest) { - local __tmpl__:2 = 0; - readHalfDoubleWord(reg, __tmpl__); - local __tmph__:2 = 0; - readHalfDoubleWord(reg, __tmph__); - dest = (__tmph__ << 8) | __tmpl__; -} - macro comparison(first, second) { local __val__ = first - second; O = sborrow(first, second); @@ -121,7 +138,11 @@ define pcodeop SoftwareInterrupt; :ADD addr16, reg0_2 is opcode3_9=0x0058 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { local ptr:2 = addr16; - addition(reg0_2, *(*:2 ptr)); + addition(reg0_2, *:2 ptr); +} + +:ADD@ impliedval16, reg0_2 is opcode6_9=0x000B & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + addition(reg0_2, impliedval16); } :ADCR reg0_2 is opcode3_9=0x0005 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { @@ -135,7 +156,12 @@ define pcodeop SoftwareInterrupt; :AND addr16, reg0_2 is opcode3_9=0x0070 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { local ptr:2 = addr16; - reg0_2 = reg0_2 & *(*:2 ptr); + reg0_2 = reg0_2 & *:2 ptr; + resultFlags(reg0_2); +} + +:AND@ impliedval16, reg0_2 is opcode6_9=0x000E & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 & impliedval16; resultFlags(reg0_2); } @@ -214,7 +240,11 @@ define pcodeop SoftwareInterrupt; :CMP addr16, reg0_2 is opcode3_9=0x0068 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { local ptr:2 = addr16; - comparison(reg0_2, *(*:2 ptr)); + comparison(reg0_2, *:2 ptr); +} + +:CMP@ impliedval16, reg0_2 is opcode6_9=0x000D & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + comparison(reg0_2, impliedval16); } :CMPR reg3_5, reg0_2 is opcode6_9=0x0005 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { @@ -253,16 +283,16 @@ define pcodeop SoftwareInterrupt; resultFlags(reg0_2); } -:J jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & reg24_25=R7 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:J jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & target24_25=3 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { goto jmpdest16; } -:JD jmpdest16 is opcode0_9=0x0004 ; jump_type=2 & reg24_25=R7 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:JD jmpdest16 is opcode0_9=0x0004 ; jump_type=2 & target24_25=3 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { I = 0; goto jmpdest16; } -:JE jmpdest16 is opcode0_9=0x0004 ; jump_type=1 & reg24_25=R7 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:JE jmpdest16 is opcode0_9=0x0004 ; jump_type=1 & target24_25=3 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { I = 1; goto jmpdest16; } @@ -294,15 +324,20 @@ define pcodeop SoftwareInterrupt; reg0_2 = *(*:2 ptr); } +:MVI@ impliedval16, reg0_2 is opcode6_9=0x000A & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = impliedval16; +} + :MVO reg0_2, addr16 is opcode3_9=0x0048 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { local ptr:2 = addr16; *ptr = reg0_2; } -:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 & target3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { local ptr:2 = reg3_5; *ptr = reg0_2; - if ((reg3_5 != R4) && (reg3_5 != R5) && (reg3_5 != R6)) goto inst_next; + local target:2 = target3_5; + if ((target != 4) && (target != 5) && (target != 6)) goto inst_next; reg3_5 = reg3_5 + 1; } @@ -348,7 +383,11 @@ define pcodeop SoftwareInterrupt; :SUB addr16, reg0_2 is opcode3_9=0x0060 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { local ptr:2 = addr16; - subtraction(reg0_2, *(*:2 ptr)); + subtraction(reg0_2, *:2 ptr); +} + +:SUB@ impliedval16, reg0_2 is opcode6_9=0x000C & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + subtraction(reg0_2, impliedval16); } :SUBR reg3_5, reg0_2 is opcode6_9=0x0004 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { @@ -361,7 +400,12 @@ define pcodeop SoftwareInterrupt; :XOR addr16, reg0_2 is opcode3_9=0x0078 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { local ptr:2 = addr16; - reg0_2 = reg0_2 ^ *(*:2 ptr); + reg0_2 = reg0_2 ^ *:2 ptr; + resultFlags(reg0_2); +} + +:XOR@ impliedval16, reg0_2 is opcode6_9=0x000F & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { + reg0_2 = reg0_2 ^ impliedval16; resultFlags(reg0_2); } @@ -370,8 +414,6 @@ define pcodeop SoftwareInterrupt; resultFlags(reg0_2); } -with : operation_size=0 { - :RLC reg0_2, 1 is opcode3_9=0x000A & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { local tmpC = (reg0_2 & 0x8000) != 0; local tmpS = (reg0_2 & 0x4000) != 0; @@ -436,8 +478,6 @@ with : operation_size=0 { S = tmpS; } -} - with : operation_size=1 { :RLC reg0_2, 2 is opcode3_9=0x000A & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { @@ -513,139 +553,58 @@ with : operation_size=1 { } -with : doublebyte=0 { - -:ADD@ reg3_5, reg0_2 is opcode6_9=0x000B & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readHalfDoubleWord(reg3_5, val); - addition(reg0_2, val); -} - -:ADDI #imm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ADDI imm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { addition(reg0_2, imm16); } -:AND@ reg3_5, reg0_2 is opcode6_9=0x000E & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readHalfDoubleWord(reg3_5, val); - reg0_2 = reg0_2 & val; - resultFlags(reg0_2); -} - -:ANDI #imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ANDI imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { reg0_2 = reg0_2 & imm16; resultFlags(reg0_2); } -:CMP@ reg3_5, reg0_2 is opcode6_9=0x000D & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local tmp:2 = 0; - readHalfDoubleWord(reg3_5, tmp); - comparison(reg0_2, tmp); -} - -:CMPI #imm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:CMPI imm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { comparison(reg0_2, imm16); } -:MVI@ reg3_5, reg0_2 is opcode6_9=0x000A & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readHalfDoubleWord(reg3_5, val); - reg0_2 = val; -} - -:MVII #imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVII imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { reg0_2 = imm16; } -:SUB@ reg3_5, reg0_2 is opcode6_9=0x000C & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readHalfDoubleWord(reg3_5, val); - subtraction(reg0_2, val); -} - -:SUBI #imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SUBI imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { subtraction(reg0_2, imm16); } -:XOR@ reg3_5, reg0_2 is opcode6_9=0x000F & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readHalfDoubleWord(reg3_5, val); - reg0_2 = reg0_2 ^ val; - resultFlags(reg0_2); -} - -:XORI #imm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:XORI imm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { reg0_2 = reg0_2 ^ imm16; resultFlags(reg0_2); } -} - with : doublebyte=1 { -:ADD@ reg3_5, reg0_2 is opcode6_9=0x000B & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readDoubleWord(reg3_5, val); - addition(reg0_2, val); -} - -:ADDI #splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ADDI splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { addition(reg0_2, splitimm16); } -:AND@ reg3_5, reg0_2 is opcode6_9=0x000E & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readDoubleWord(reg3_5, val); - reg0_2 = reg0_2 & val; - resultFlags(reg0_2); -} - -:ANDI #splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ANDI splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { reg0_2 = reg0_2 & splitimm16; resultFlags(reg0_2); } -:CMP@ reg3_5, reg0_2 is opcode6_9=0x000D & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local tmp:2 = 0; - readDoubleWord(reg3_5, tmp); - comparison(reg0_2, tmp); -} - -:CMPI #splitimm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:CMPI splitimm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { comparison(reg0_2, splitimm16); } -:MVI@ reg3_5, reg0_2 is opcode6_9=0x000A & reg0_2 & reg3_5 [ globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readDoubleWord(reg3_5, val); - reg0_2 = val; -} - -:MVII #splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVII splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { reg0_2 = splitimm16; } -:SUB@ reg3_5, reg0_2 is opcode6_9=0x000C & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readDoubleWord(reg3_5, val); - subtraction(reg0_2, val); -} - -:SUBI #splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SUBI splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { subtraction(reg0_2, splitimm16); } -:XOR@ reg3_5, reg0_2 is opcode6_9=0x000F & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { - local val:2 = 0; - readDoubleWord(reg3_5, val); - reg0_2 = reg0_2 ^ val; - resultFlags(reg0_2); -} - -:XORI #splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:XORI splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { reg0_2 = reg0_2 ^ splitimm16; resultFlags(reg0_2); } } - From c72e4bc98bb05cacebfdf2cc318377838891fcfe Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Fri, 27 Dec 2019 18:35:30 +0100 Subject: [PATCH 03/14] Use `noflow` in context entry. --- .../CP1600/data/languages/CP1600.slaspec | 176 +++++++++--------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index f4969510e8..d7560ad176 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -45,7 +45,7 @@ define token immediate16 (16) ; define context contextreg - doublebyte = (0, 0) + doublebyte = (0, 0) noflow ; attach variables [ reg0_1 ] [ R0 R1 R2 R3 ]; @@ -136,204 +136,204 @@ define pcodeop SoftwareInterrupt; ################################################################ -:ADD addr16, reg0_2 is opcode3_9=0x0058 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ADD addr16, reg0_2 is opcode3_9=0x0058 & reg0_2 ; addr16 { local ptr:2 = addr16; addition(reg0_2, *:2 ptr); } -:ADD@ impliedval16, reg0_2 is opcode6_9=0x000B & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ADD@ impliedval16, reg0_2 is opcode6_9=0x000B & reg0_2 & impliedval16 { addition(reg0_2, impliedval16); } -:ADCR reg0_2 is opcode3_9=0x0005 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ADCR reg0_2 is opcode3_9=0x0005 & reg0_2 { local oldC = zext(C); addition(reg0_2, oldC); } -:ADDR reg3_5, reg0_2 is opcode6_9=0x0003 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ADDR reg3_5, reg0_2 is opcode6_9=0x0003 & reg3_5 & reg0_2 { addition(reg0_2, reg3_5); } -:AND addr16, reg0_2 is opcode3_9=0x0070 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:AND addr16, reg0_2 is opcode3_9=0x0070 & reg0_2 ; addr16 { local ptr:2 = addr16; reg0_2 = reg0_2 & *:2 ptr; resultFlags(reg0_2); } -:AND@ impliedval16, reg0_2 is opcode6_9=0x000E & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:AND@ impliedval16, reg0_2 is opcode6_9=0x000E & reg0_2 & impliedval16 { reg0_2 = reg0_2 & impliedval16; resultFlags(reg0_2); } -:ANDR reg3_5, reg0_2 is opcode6_9=0x0006 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ANDR reg3_5, reg0_2 is opcode6_9=0x0006 & reg3_5 & reg0_2 { reg0_2 = reg0_2 & reg3_5; resultFlags(reg0_2); } -:B branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=0) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:B branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=0) ... & branchdest16 { goto branchdest16; } -:BC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=1) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=1) ... & branchdest16 { if (C == 1) goto branchdest16; } -:BEQ branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=4) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BEQ branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=4) ... & branchdest16 { if (Z == 1) goto branchdest16; } -:BESC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=15) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BESC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=15) ... & branchdest16 { if (S == C) goto branchdest16; } -:BGE branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=13) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BGE branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=13) ... & branchdest16 { if (S == O) goto branchdest16; } -:BGT branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=14) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BGT branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=14) ... & branchdest16 { if ((Z == 0) || (S == O)) goto branchdest16; } -:BLE branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=6) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BLE branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=6) ... & branchdest16 { if ((Z == 1) || (S != O)) goto branchdest16; } -:BLT branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=5) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BLT branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=5) ... & branchdest16 { if (S != O) goto branchdest16; } -:BMI branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=11) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BMI branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=11) ... & branchdest16 { if (S == 1) goto branchdest16; } -:BNC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=9) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BNC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=9) ... & branchdest16 { if (C == 0) goto branchdest16; } -:BNEQ branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=12) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BNEQ branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=12) ... & branchdest16 { if (Z == 0) goto branchdest16; } -:BNOV branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=10) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BNOV branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=10) ... & branchdest16 { if (O == 0) goto branchdest16; } -:BOV branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=2) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BOV branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=2) ... & branchdest16 { if (O == 1) goto branchdest16; } -:BPL branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=3) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BPL branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=3) ... & branchdest16 { if (S == 0) goto branchdest16; } -:BUSC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=7) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BUSC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=7) ... & branchdest16 { if (S != C) goto branchdest16; } -:BEXT branchdest16, #external_condition is (opcode6_9=0x0008 & branch_external=1 & external_condition) ... & branchdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:BEXT branchdest16, #external_condition is (opcode6_9=0x0008 & branch_external=1 & external_condition) ... & branchdest16 { goto branchdest16; } -:CLRC is opcode0_9=0x0006 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:CLRC is opcode0_9=0x0006 { C = 0; } -:CMP addr16, reg0_2 is opcode3_9=0x0068 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:CMP addr16, reg0_2 is opcode3_9=0x0068 & reg0_2 ; addr16 { local ptr:2 = addr16; comparison(reg0_2, *:2 ptr); } -:CMP@ impliedval16, reg0_2 is opcode6_9=0x000D & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:CMP@ impliedval16, reg0_2 is opcode6_9=0x000D & reg0_2 & impliedval16 { comparison(reg0_2, impliedval16); } -:CMPR reg3_5, reg0_2 is opcode6_9=0x0005 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:CMPR reg3_5, reg0_2 is opcode6_9=0x0005 & reg3_5 & reg0_2 { comparison(reg0_2, reg3_5); } -:COMR reg0_2 is opcode3_9=0x0003 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:COMR reg0_2 is opcode3_9=0x0003 & reg0_2 { reg0_2 = ~reg0_2; resultFlags(reg0_2); } -:DECR reg0_2 is opcode3_9=0x0002 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:DECR reg0_2 is opcode3_9=0x0002 & reg0_2 { reg0_2 = reg0_2 - 1; resultFlags(reg0_2); } -:DIS is opcode0_9=0x0003 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:DIS is opcode0_9=0x0003 { I = 0; } -:EIS is opcode0_9=0x0002 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:EIS is opcode0_9=0x0002 { I = 1; } -:GSWD reg0_1 is opcode2_9=0x000C & reg0_1 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:GSWD reg0_1 is opcode2_9=0x000C & reg0_1 { local mask:2 = (zext(S) << 7) + (zext(Z) << 6) + (zext(O) << 5) + (zext(C) << 4); reg0_1 = (mask << 8) + mask; } -:HLT is opcode0_9=0x0000 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:HLT is opcode0_9=0x0000 { goto inst_start; } -:INCR reg0_2 is opcode3_9=0x0001 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:INCR reg0_2 is opcode3_9=0x0001 & reg0_2 { reg0_2 = reg0_2 + 1; resultFlags(reg0_2); } -:J jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & target24_25=3 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:J jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & target24_25=3 & jmpdest16 { goto jmpdest16; } -:JD jmpdest16 is opcode0_9=0x0004 ; jump_type=2 & target24_25=3 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:JD jmpdest16 is opcode0_9=0x0004 ; jump_type=2 & target24_25=3 & jmpdest16 { I = 0; goto jmpdest16; } -:JE jmpdest16 is opcode0_9=0x0004 ; jump_type=1 & target24_25=3 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:JE jmpdest16 is opcode0_9=0x0004 ; jump_type=1 & target24_25=3 & jmpdest16 { I = 1; goto jmpdest16; } -:JSR reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & reg24_25 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:JSR reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & reg24_25 & jmpdest16 { reg24_25 = inst_next; call jmpdest16; } -:JSRD reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=2 & reg24_25 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:JSRD reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=2 & reg24_25 & jmpdest16 { I = 0; reg24_25 = inst_next; call jmpdest16; } -:JSRE reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=1 & reg24_25 & jmpdest16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:JSRE reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=1 & reg24_25 & jmpdest16 { I = 1; reg24_25 = inst_next; call jmpdest16; } -:MOVR reg3_5, reg0_2 is opcode6_9=0x0002 & reg0_2 & reg3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MOVR reg3_5, reg0_2 is opcode6_9=0x0002 & reg0_2 & reg3_5 { reg0_2 = reg3_5; resultFlags(reg0_2); } -:MVI addr16, reg0_2 is opcode3_9=0x0050 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVI addr16, reg0_2 is opcode3_9=0x0050 & reg0_2 ; addr16 { local ptr:2 = addr16; reg0_2 = *(*:2 ptr); } -:MVI@ impliedval16, reg0_2 is opcode6_9=0x000A & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVI@ impliedval16, reg0_2 is opcode6_9=0x000A & reg0_2 & impliedval16 { reg0_2 = impliedval16; } -:MVO reg0_2, addr16 is opcode3_9=0x0048 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVO reg0_2, addr16 is opcode3_9=0x0048 & reg0_2 ; addr16 { local ptr:2 = addr16; *ptr = reg0_2; } -:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 & target3_5 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 & target3_5 { local ptr:2 = reg3_5; *ptr = reg0_2; local target:2 = target3_5; @@ -341,12 +341,12 @@ define pcodeop SoftwareInterrupt; reg3_5 = reg3_5 + 1; } -:MVOI reg0_2 is opcode3_9=0x004F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVOI reg0_2 is opcode3_9=0x004F & reg0_2 ; imm16 { local tmp:2 = inst_start + 2; *tmp = reg0_2; } -:NEGR reg0_2 is opcode3_9=0x0004 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:NEGR reg0_2 is opcode3_9=0x0004 & reg0_2 { local tmp = reg0_2 ^ 0xFFFF; local tmpC = carry(tmp, 1); local tmpO = scarry(tmp, 1); @@ -356,13 +356,13 @@ define pcodeop SoftwareInterrupt; resultFlags(reg0_2); } -:NOP is opcode1_9=0x001A [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:NOP is opcode1_9=0x001A { } -:NOPP is opcode6_9=0x0008 & branch_external=0 & branch_condition=8 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:NOPP is opcode6_9=0x0008 & branch_external=0 & branch_condition=8 ; imm16 { } -:RSWD reg0_2 is opcode3_9=0x0007 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:RSWD reg0_2 is opcode3_9=0x0007 & reg0_2 { C = (reg0_2 & 0b00001000) != 0; O = (reg0_2 & 0b00010000) != 0; Z = (reg0_2 & 0b00100000) != 0; @@ -373,48 +373,48 @@ define pcodeop SoftwareInterrupt; D = 1; } -:SETC is opcode0_9=0x0007 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SETC is opcode0_9=0x0007 { C = 1; } -:SIN is opcode1_9=0x001B [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SIN is opcode1_9=0x001B { SoftwareInterrupt(); } -:SUB addr16, reg0_2 is opcode3_9=0x0060 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SUB addr16, reg0_2 is opcode3_9=0x0060 & reg0_2 ; addr16 { local ptr:2 = addr16; subtraction(reg0_2, *:2 ptr); } -:SUB@ impliedval16, reg0_2 is opcode6_9=0x000C & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SUB@ impliedval16, reg0_2 is opcode6_9=0x000C & reg0_2 & impliedval16 { subtraction(reg0_2, impliedval16); } -:SUBR reg3_5, reg0_2 is opcode6_9=0x0004 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SUBR reg3_5, reg0_2 is opcode6_9=0x0004 & reg3_5 & reg0_2 { subtraction(reg0_2, reg3_5); } -:TCI is opcode0_9=0x0005 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:TCI is opcode0_9=0x0005 { TerminateCurrentInterrupt(); } -:XOR addr16, reg0_2 is opcode3_9=0x0078 & reg0_2 ; addr16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:XOR addr16, reg0_2 is opcode3_9=0x0078 & reg0_2 ; addr16 { local ptr:2 = addr16; reg0_2 = reg0_2 ^ *:2 ptr; resultFlags(reg0_2); } -:XOR@ impliedval16, reg0_2 is opcode6_9=0x000F & reg0_2 & impliedval16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:XOR@ impliedval16, reg0_2 is opcode6_9=0x000F & reg0_2 & impliedval16 { reg0_2 = reg0_2 ^ impliedval16; resultFlags(reg0_2); } -:XORR reg3_5, reg0_2 is opcode6_9=0x0007 & reg3_5 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:XORR reg3_5, reg0_2 is opcode6_9=0x0007 & reg3_5 & reg0_2 { reg0_2 = reg0_2 ^ reg3_5; resultFlags(reg0_2); } -:RLC reg0_2, 1 is opcode3_9=0x000A & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:RLC reg0_2, 1 is opcode3_9=0x000A & reg0_2 { local tmpC = (reg0_2 & 0x8000) != 0; local tmpS = (reg0_2 & 0x4000) != 0; reg0_2 = (reg0_2 << 1) + zext(C); @@ -423,7 +423,7 @@ define pcodeop SoftwareInterrupt; Z = reg0_2 == 0; } -:RRC reg0_2, 1 is opcode3_9=0x000E & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:RRC reg0_2, 1 is opcode3_9=0x000E & reg0_2 { local tmpC = (reg0_2 & 0x0001) != 0; local tmpS = (reg0_2 & 0x0100) != 0; reg0_2 = (reg0_2 >> 1) | (zext(C) << 15); @@ -432,14 +432,14 @@ define pcodeop SoftwareInterrupt; Z = reg0_2 == 0; } -:SAR reg0_2, 1 is opcode3_9=0x000D & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SAR reg0_2, 1 is opcode3_9=0x000D & reg0_2 { local tmpS = (reg0_2 & 0x0100) != 0; reg0_2 = reg0_2 s>> 1; S = tmpS; Z = reg0_2 == 0; } -:SARC reg0_2, 1 is opcode3_9=0x000F & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SARC reg0_2, 1 is opcode3_9=0x000F & reg0_2 { local tmpC = (reg0_2 & 0x0001) != 0; local tmpS = (reg0_2 & 0x0100) != 0; reg0_2 = reg0_2 s>> 1; @@ -448,14 +448,14 @@ define pcodeop SoftwareInterrupt; Z = reg0_2 == 0; } -:SLL reg0_2, 1 is opcode3_9=0x0009 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SLL reg0_2, 1 is opcode3_9=0x0009 & reg0_2 { local tmpS = (reg0_2 & 0x4000) != 0; reg0_2 = reg0_2 << 1; S = tmpS; Z = reg0_2 == 0; } -:SLLC reg0_2, 1 is opcode3_9=0x000B & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SLLC reg0_2, 1 is opcode3_9=0x000B & reg0_2 { local tmpC = (reg0_2 & 0x8000) != 0; local tmpS = (reg0_2 & 0x4000) != 0; reg0_2 = reg0_2 << 1; @@ -464,14 +464,14 @@ define pcodeop SoftwareInterrupt; Z = reg0_2 == 0; } -:SLR reg0_2, 1 is opcode3_9=0x000C & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SLR reg0_2, 1 is opcode3_9=0x000C & reg0_2 { local tmpS = (reg0_2 & 0x0100) != 0; reg0_2 = reg0_2 >> 1; S = tmpS; Z = reg0_2 == 0; } -:SWAP reg0_2, 1 is opcode3_9=0x0008 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SWAP reg0_2, 1 is opcode3_9=0x0008 & reg0_2 { local tmpS = (reg0_2 & 0x8000) != 0; local tmp = (reg0_2 << 8) & 0xFF00; reg0_2 = tmp | ((reg0_2 >> 8) & 0x00FF); @@ -480,7 +480,7 @@ define pcodeop SoftwareInterrupt; with : operation_size=1 { -:RLC reg0_2, 2 is opcode3_9=0x000A & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:RLC reg0_2, 2 is opcode3_9=0x000A & reg0_2 { local tmpC = (reg0_2 & 0x8000) != 0; local tmpO = (reg0_2 & 0x4000) != 0; local tmpS = (reg0_2 & 0x2000) != 0; @@ -491,7 +491,7 @@ with : operation_size=1 { Z = reg0_2 == 0; } -:RRC reg0_2, 2 is opcode3_9=0x000E & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:RRC reg0_2, 2 is opcode3_9=0x000E & reg0_2 { local tmpC = (reg0_2 & 0x0001) != 0; local tmpO = (reg0_2 & 0x0002) != 0; local tmpS = (reg0_2 & 0x0200) != 0; @@ -502,14 +502,14 @@ with : operation_size=1 { Z = reg0_2 == 0; } -:SAR reg0_2, 2 is opcode3_9=0x000D & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SAR reg0_2, 2 is opcode3_9=0x000D & reg0_2 { local tmpS = (reg0_2 & 0x0200) != 0; reg0_2 = reg0_2 s>> 2; S = tmpS; Z = reg0_2 == 0; } -:SARC reg0_2, 2 is opcode3_9=0x000F & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SARC reg0_2, 2 is opcode3_9=0x000F & reg0_2 { local tmpC = (reg0_2 & 0x0001) != 0; local tmpO = (reg0_2 & 0x0002) != 0; local tmpS = (reg0_2 & 0x0200) != 0; @@ -520,14 +520,14 @@ with : operation_size=1 { Z = reg0_2 == 0; } -:SLL reg0_2, 2 is opcode3_9=0x0009 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SLL reg0_2, 2 is opcode3_9=0x0009 & reg0_2 { local tmpS = (reg0_2 & 0x2000) != 0; reg0_2 = reg0_2 << 2; S = tmpS; Z = reg0_2 == 0; } -:SLLC reg0_2, 2 is opcode3_9=0x000B & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SLLC reg0_2, 2 is opcode3_9=0x000B & reg0_2 { local tmpC = (reg0_2 & 0x8000) != 0; local tmpO = (reg0_2 & 0x4000) != 0; local tmpS = (reg0_2 & 0x2000) != 0; @@ -538,14 +538,14 @@ with : operation_size=1 { Z = reg0_2 == 0; } -:SLR reg0_2, 2 is opcode3_9=0x000C & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SLR reg0_2, 2 is opcode3_9=0x000C & reg0_2 { local tmpS = (reg0_2 & 0x0200) != 0; reg0_2 = reg0_2 >> 2; S = tmpS; Z = reg0_2 == 0; } -:SWAP reg0_2, 2 is opcode3_9=0x0008 & reg0_2 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SWAP reg0_2, 2 is opcode3_9=0x0008 & reg0_2 { local tmpS = (reg0_2 & 0x0080) != 0; reg0_2 = (reg0_2 << 8) | (reg0_2 & 0x00FF); S = tmpS; @@ -553,56 +553,56 @@ with : operation_size=1 { } -:ADDI imm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ADDI imm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; imm16 { addition(reg0_2, imm16); } -:ANDI imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ANDI imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; imm16 { reg0_2 = reg0_2 & imm16; resultFlags(reg0_2); } -:CMPI imm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:CMPI imm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; imm16 { comparison(reg0_2, imm16); } -:MVII imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVII imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; imm16 { reg0_2 = imm16; } -:SUBI imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SUBI imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; imm16 { subtraction(reg0_2, imm16); } -:XORI imm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; imm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:XORI imm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; imm16 { reg0_2 = reg0_2 ^ imm16; resultFlags(reg0_2); } with : doublebyte=1 { -:ADDI splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ADDI splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; splitimm16 { addition(reg0_2, splitimm16); } -:ANDI splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:ANDI splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; splitimm16 { reg0_2 = reg0_2 & splitimm16; resultFlags(reg0_2); } -:CMPI splitimm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:CMPI splitimm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; splitimm16 { comparison(reg0_2, splitimm16); } -:MVII splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:MVII splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; splitimm16 { reg0_2 = splitimm16; } -:SUBI splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:SUBI splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; splitimm16 { subtraction(reg0_2, splitimm16); } -:XORI splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; splitimm16 [ doublebyte=0; globalset(inst_next, doublebyte); ] { +:XORI splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; splitimm16 { reg0_2 = reg0_2 ^ splitimm16; resultFlags(reg0_2); } From 6184f584755d332aa64a3f09b4f4ac2108cbaeca Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Fri, 27 Dec 2019 19:04:54 +0100 Subject: [PATCH 04/14] Use one single entry for conditional opcodes. --- .../CP1600/data/languages/CP1600.slaspec | 77 +++++-------------- 1 file changed, 19 insertions(+), 58 deletions(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index d7560ad176..5d3faab912 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -98,6 +98,22 @@ impliedval16: reg3_5 is reg3_5 & (target3_5=0 | target3_5=1 | target3_5=2 | targ export tmp; } +cc: "" is branch_external=0 & branch_condition=0 { local tmp:1 = 1; export tmp; } +cc: "C" is branch_external=0 & branch_condition=1 { export C; } +cc: "OV" is branch_external=0 & branch_condition=2 { export O; } +cc: "PL" is branch_external=0 & branch_condition=3 { local tmp = !S; export tmp; } +cc: "EQ" is branch_external=0 & branch_condition=4 { export Z; } +cc: "LT" is branch_external=0 & branch_condition=5 { local tmp = S != O; export tmp; } +cc: "LE" is branch_external=0 & branch_condition=6 { local tmp = (Z == 1) || (S != O); export tmp; } +cc: "USC" is branch_external=0 & branch_condition=7 { local tmp = S != C; export tmp; } +cc: "NC" is branch_external=0 & branch_condition=9 { local tmp = !C; export tmp; } +cc: "NOV" is branch_external=0 & branch_condition=10 { local tmp = !O; export tmp; } +cc: "MI" is branch_external=0 & branch_condition=11 { export S; } +cc: "NEQ" is branch_external=0 & branch_condition=12 { local tmp = !Z; export tmp; } +cc: "GE" is branch_external=0 & branch_condition=13 { local tmp = S == O; export tmp; } +cc: "GT" is branch_external=0 & branch_condition=14 { local tmp = (Z == 0) || (S == O); export tmp; } +cc: "ESC" is branch_external=0 & branch_condition=15 { local tmp = S == C; export tmp; } + ################################################################ macro resultFlags(value) { @@ -170,67 +186,12 @@ define pcodeop SoftwareInterrupt; resultFlags(reg0_2); } -:B branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=0) ... & branchdest16 { +:B^cc branchdest16 is (opcode6_9=0x0008 & cc) ... & branchdest16 { + if (!cc) goto inst_next; goto branchdest16; } -:BC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=1) ... & branchdest16 { - if (C == 1) goto branchdest16; -} - -:BEQ branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=4) ... & branchdest16 { - if (Z == 1) goto branchdest16; -} - -:BESC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=15) ... & branchdest16 { - if (S == C) goto branchdest16; -} - -:BGE branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=13) ... & branchdest16 { - if (S == O) goto branchdest16; -} - -:BGT branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=14) ... & branchdest16 { - if ((Z == 0) || (S == O)) goto branchdest16; -} - -:BLE branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=6) ... & branchdest16 { - if ((Z == 1) || (S != O)) goto branchdest16; -} - -:BLT branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=5) ... & branchdest16 { - if (S != O) goto branchdest16; -} - -:BMI branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=11) ... & branchdest16 { - if (S == 1) goto branchdest16; -} - -:BNC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=9) ... & branchdest16 { - if (C == 0) goto branchdest16; -} - -:BNEQ branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=12) ... & branchdest16 { - if (Z == 0) goto branchdest16; -} - -:BNOV branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=10) ... & branchdest16 { - if (O == 0) goto branchdest16; -} - -:BOV branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=2) ... & branchdest16 { - if (O == 1) goto branchdest16; -} - -:BPL branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=3) ... & branchdest16 { - if (S == 0) goto branchdest16; -} - -:BUSC branchdest16 is (opcode6_9=0x0008 & branch_external=0 & branch_condition=7) ... & branchdest16 { - if (S != C) goto branchdest16; -} - -:BEXT branchdest16, #external_condition is (opcode6_9=0x0008 & branch_external=1 & external_condition) ... & branchdest16 { +:BEXT branchdest16, external_condition is (opcode6_9=0x0008 & branch_external=1 & external_condition) ... & branchdest16 { goto branchdest16; } From 8e9940c497bea22dd6b7964d925a69219d901a9d Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Fri, 27 Dec 2019 19:06:21 +0100 Subject: [PATCH 05/14] Remove D flag, it is a context variable now. --- Ghidra/Processors/CP1600/data/languages/CP1600.slaspec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index 5d3faab912..fa2372ac3b 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -4,7 +4,7 @@ define space ram type=ram_space wordsize=2 size=2 default; define space register type=register_space size=2; define register offset=0x00 size=2 [ R0 R1 R2 R3 R4 R5 R6 R7 ]; -define register offset=0x10 size=1 [ I D C O Z S ]; +define register offset=0x10 size=1 [ I C O Z S ]; define register offset=0x20 size=4 [ contextreg ]; define token opcode_word (16) @@ -331,7 +331,6 @@ define pcodeop SoftwareInterrupt; } :SDBD is opcode0_9=0x0001 [ doublebyte=1; globalset(inst_next, doublebyte); ] { - D = 1; } :SETC is opcode0_9=0x0007 { From 941f9e15c9312ad265cc8615efb7b81a5db8d49e Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Mon, 30 Dec 2019 20:24:52 +0100 Subject: [PATCH 06/14] Reverse jump condition check. --- Ghidra/Processors/CP1600/data/languages/CP1600.slaspec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index fa2372ac3b..aeaa18e3f7 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -187,8 +187,7 @@ define pcodeop SoftwareInterrupt; } :B^cc branchdest16 is (opcode6_9=0x0008 & cc) ... & branchdest16 { - if (!cc) goto inst_next; - goto branchdest16; + if (cc) goto branchdest16; } :BEXT branchdest16, external_condition is (opcode6_9=0x0008 & branch_external=1 & external_condition) ... & branchdest16 { From 9da10a6b7eb3acd8baef5e03d95f242c90b7fa65 Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Thu, 7 May 2020 01:39:47 +0200 Subject: [PATCH 07/14] Fix backwards relative jumps. --- Ghidra/Processors/CP1600/data/languages/CP1600.slaspec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index aeaa18e3f7..f195810d5c 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -41,6 +41,7 @@ define token double16 (32) define token immediate16 (16) imm16 = (0, 15) + simm16 = (0, 15) signed addr16 = (0, 15) ; @@ -56,7 +57,7 @@ attach variables [ reg24_25 ] [ R4 R5 R6 R7 ]; jmpdest16: reloc is address_hi & address_lo [ reloc = (address_hi << 10) + address_lo; ] { export *:2 reloc; } branchdest16: reloc is branch_sign=0 ; imm16 [ reloc = inst_start + 2 + imm16; ] { export *:2 reloc; } -branchdest16: reloc is branch_sign=1 ; imm16 [ reloc = inst_start + 2 - imm16; ] { export *:2 reloc; } +branchdest16: reloc is branch_sign=1 ; simm16 [ reloc = inst_start + 2 + ~simm16; ] { export *:2 reloc; } splitimm16: split is value_hi & value_lo [ split = (value_hi << 8) + value_lo; ] { local tmp:2 = split & 0xFFFF; export tmp; } impliedval16: reg3_5 is reg3_5 & (target3_5=0 | target3_5=1 | target3_5=2 | target3_5=3 | target3_5=7) & doublebyte=0 { From 3baebe2d38df821d2bd20a473c648bacaac0b1ce Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Thu, 7 May 2020 01:44:44 +0200 Subject: [PATCH 08/14] Prepend the appropriate marker to number literals. --- .../CP1600/data/languages/CP1600.slaspec | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index f195810d5c..ac0ea3f624 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -513,56 +513,56 @@ with : operation_size=1 { } -:ADDI imm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; imm16 { +:ADDI "#"imm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; imm16 { addition(reg0_2, imm16); } -:ANDI imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; imm16 { +:ANDI "#"imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; imm16 { reg0_2 = reg0_2 & imm16; resultFlags(reg0_2); } -:CMPI imm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; imm16 { +:CMPI "#"imm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; imm16 { comparison(reg0_2, imm16); } -:MVII imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; imm16 { +:MVII "#"imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; imm16 { reg0_2 = imm16; } -:SUBI imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; imm16 { +:SUBI "#"imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; imm16 { subtraction(reg0_2, imm16); } -:XORI imm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; imm16 { +:XORI "#"imm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; imm16 { reg0_2 = reg0_2 ^ imm16; resultFlags(reg0_2); } with : doublebyte=1 { -:ADDI splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; splitimm16 { +:ADDI "#"splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; splitimm16 { addition(reg0_2, splitimm16); } -:ANDI splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; splitimm16 { +:ANDI "#"splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; splitimm16 { reg0_2 = reg0_2 & splitimm16; resultFlags(reg0_2); } -:CMPI splitimm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; splitimm16 { +:CMPI "#"splitimm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; splitimm16 { comparison(reg0_2, splitimm16); } -:MVII splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; splitimm16 { +:MVII "#"splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; splitimm16 { reg0_2 = splitimm16; } -:SUBI splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; splitimm16 { +:SUBI "#"splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; splitimm16 { subtraction(reg0_2, splitimm16); } -:XORI splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; splitimm16 { +:XORI "#"splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; splitimm16 { reg0_2 = reg0_2 ^ splitimm16; resultFlags(reg0_2); } From ee594872053defec4049054a3b3d5f21f8298d23 Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Thu, 7 May 2020 02:41:16 +0200 Subject: [PATCH 09/14] Add PSHR and PULR synthetic opcodes. --- Ghidra/Processors/CP1600/data/languages/CP1600.slaspec | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index ac0ea3f624..ed447e30da 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -323,6 +323,16 @@ define pcodeop SoftwareInterrupt; :NOPP is opcode6_9=0x0008 & branch_external=0 & branch_condition=8 ; imm16 { } +:PSHR reg0_2 is opcode6_9=0x0009 & reg0_2 & reg3_5=6 { + local ptr:2 = R6; + *ptr = reg0_2; + R6 = R6 + 1; +} + +:PULR reg0_2 is opcode6_9=0x000A & impliedval16 & reg0_2 & reg3_5=6 { + reg0_2 = impliedval16; +} + :RSWD reg0_2 is opcode3_9=0x0007 & reg0_2 { C = (reg0_2 & 0b00001000) != 0; O = (reg0_2 & 0b00010000) != 0; From 07cc606f7cf3eff10caf753e489b10df896514d4 Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Thu, 7 May 2020 03:32:38 +0200 Subject: [PATCH 10/14] Add TSTR synthetic opcode. --- Ghidra/Processors/CP1600/data/languages/CP1600.slaspec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index ed447e30da..6a0ec64694 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -10,6 +10,7 @@ define register offset=0x20 size=4 [ contextreg ]; define token opcode_word (16) target3_5 = (3, 5) reg3_5 = (3, 5) + target0_2 = (0, 2) reg0_2 = (0, 2) reg0_1 = (0, 1) operation_size = (2, 2) @@ -368,6 +369,10 @@ define pcodeop SoftwareInterrupt; TerminateCurrentInterrupt(); } +:TSTR reg0_2 is opcode6_9=0x0002 & reg0_2 & ((target0_2=0 & target3_5=0) | (target0_2=1 & target3_5=1) | (target0_2=2 & target3_5=2) | (target0_2=3 & target3_5=3) | (target0_2=4 & target3_5=4) | (target0_2=5 & target3_5=5) | (target0_2=6 & target3_5=6) | (target0_2=7 & target3_5=7)) { + resultFlags(reg0_2); +} + :XOR addr16, reg0_2 is opcode3_9=0x0078 & reg0_2 ; addr16 { local ptr:2 = addr16; reg0_2 = reg0_2 ^ *:2 ptr; From 551154e32f356a9617d87e815a269aa96c64fdc0 Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Thu, 7 May 2020 23:18:18 +0200 Subject: [PATCH 11/14] Add R7 handling and remaining synthetic opcodes. --- .../CP1600/data/languages/CP1600.slaspec | 120 +++++++++++++++++- 1 file changed, 115 insertions(+), 5 deletions(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index 6a0ec64694..1ccbe2e053 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -157,35 +157,49 @@ define pcodeop SoftwareInterrupt; :ADD addr16, reg0_2 is opcode3_9=0x0058 & reg0_2 ; addr16 { local ptr:2 = addr16; addition(reg0_2, *:2 ptr); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :ADD@ impliedval16, reg0_2 is opcode6_9=0x000B & reg0_2 & impliedval16 { addition(reg0_2, impliedval16); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :ADCR reg0_2 is opcode3_9=0x0005 & reg0_2 { local oldC = zext(C); addition(reg0_2, oldC); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :ADDR reg3_5, reg0_2 is opcode6_9=0x0003 & reg3_5 & reg0_2 { addition(reg0_2, reg3_5); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :AND addr16, reg0_2 is opcode3_9=0x0070 & reg0_2 ; addr16 { local ptr:2 = addr16; reg0_2 = reg0_2 & *:2 ptr; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :AND@ impliedval16, reg0_2 is opcode6_9=0x000E & reg0_2 & impliedval16 { reg0_2 = reg0_2 & impliedval16; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :ANDR reg3_5, reg0_2 is opcode6_9=0x0006 & reg3_5 & reg0_2 { reg0_2 = reg0_2 & reg3_5; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :B^cc branchdest16 is (opcode6_9=0x0008 & cc) ... & branchdest16 { @@ -200,6 +214,13 @@ define pcodeop SoftwareInterrupt; C = 0; } +:CLRR reg0_2 is opcode6_9=0x0007 & reg0_2 & ((target0_2=0 & target3_5=0) | (target0_2=1 & target3_5=1) | (target0_2=2 & target3_5=2) | (target0_2=3 & target3_5=3) | (target0_2=4 & target3_5=4) | (target0_2=5 & target3_5=5) | (target0_2=6 & target3_5=6) | (target0_2=7 & target3_5=7)) { + reg0_2 = 0; + resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; +} + :CMP addr16, reg0_2 is opcode3_9=0x0068 & reg0_2 ; addr16 { local ptr:2 = addr16; comparison(reg0_2, *:2 ptr); @@ -216,11 +237,15 @@ define pcodeop SoftwareInterrupt; :COMR reg0_2 is opcode3_9=0x0003 & reg0_2 { reg0_2 = ~reg0_2; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :DECR reg0_2 is opcode3_9=0x0002 & reg0_2 { reg0_2 = reg0_2 - 1; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :DIS is opcode0_9=0x0003 { @@ -243,6 +268,8 @@ define pcodeop SoftwareInterrupt; :INCR reg0_2 is opcode3_9=0x0001 & reg0_2 { reg0_2 = reg0_2 + 1; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :J jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & target24_25=3 & jmpdest16 { @@ -259,6 +286,11 @@ define pcodeop SoftwareInterrupt; goto jmpdest16; } +:JR reg3_5 is opcode6_9=0x0002 & reg3_5 & target0_2=7 { + R7 = reg3_5; + goto [R7]; +} + :JSR reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & reg24_25 & jmpdest16 { reg24_25 = inst_next; call jmpdest16; @@ -279,15 +311,21 @@ define pcodeop SoftwareInterrupt; :MOVR reg3_5, reg0_2 is opcode6_9=0x0002 & reg0_2 & reg3_5 { reg0_2 = reg3_5; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :MVI addr16, reg0_2 is opcode3_9=0x0050 & reg0_2 ; addr16 { local ptr:2 = addr16; reg0_2 = *(*:2 ptr); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :MVI@ impliedval16, reg0_2 is opcode6_9=0x000A & reg0_2 & impliedval16 { reg0_2 = impliedval16; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :MVO reg0_2, addr16 is opcode3_9=0x0048 & reg0_2 ; addr16 { @@ -295,11 +333,13 @@ define pcodeop SoftwareInterrupt; *ptr = reg0_2; } -:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 & target3_5 { +:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 { local ptr:2 = reg3_5; *ptr = reg0_2; - local target:2 = target3_5; - if ((target != 4) && (target != 5) && (target != 6)) goto inst_next; + if ((®3_5 != &R4) && (®3_5 != &R5) && (®3_5 != &R6) && (®3_5 != &R7)) goto inst_next; + if (®3_5 != &R7) goto ; + goto [R7]; + reg3_5 = reg3_5 + 1; } @@ -316,6 +356,8 @@ define pcodeop SoftwareInterrupt; C = tmpC; O = tmpO; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :NOP is opcode1_9=0x001A { @@ -332,6 +374,8 @@ define pcodeop SoftwareInterrupt; :PULR reg0_2 is opcode6_9=0x000A & impliedval16 & reg0_2 & reg3_5=6 { reg0_2 = impliedval16; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :RSWD reg0_2 is opcode3_9=0x0007 & reg0_2 { @@ -355,14 +399,20 @@ define pcodeop SoftwareInterrupt; :SUB addr16, reg0_2 is opcode3_9=0x0060 & reg0_2 ; addr16 { local ptr:2 = addr16; subtraction(reg0_2, *:2 ptr); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SUB@ impliedval16, reg0_2 is opcode6_9=0x000C & reg0_2 & impliedval16 { subtraction(reg0_2, impliedval16); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SUBR reg3_5, reg0_2 is opcode6_9=0x0004 & reg3_5 & reg0_2 { subtraction(reg0_2, reg3_5); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :TCI is opcode0_9=0x0005 { @@ -377,16 +427,22 @@ define pcodeop SoftwareInterrupt; local ptr:2 = addr16; reg0_2 = reg0_2 ^ *:2 ptr; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :XOR@ impliedval16, reg0_2 is opcode6_9=0x000F & reg0_2 & impliedval16 { reg0_2 = reg0_2 ^ impliedval16; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :XORR reg3_5, reg0_2 is opcode6_9=0x0007 & reg3_5 & reg0_2 { reg0_2 = reg0_2 ^ reg3_5; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :RLC reg0_2, 1 is opcode3_9=0x000A & reg0_2 { @@ -396,6 +452,8 @@ define pcodeop SoftwareInterrupt; C = tmpC; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :RRC reg0_2, 1 is opcode3_9=0x000E & reg0_2 { @@ -405,6 +463,8 @@ define pcodeop SoftwareInterrupt; C = tmpC; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SAR reg0_2, 1 is opcode3_9=0x000D & reg0_2 { @@ -412,6 +472,8 @@ define pcodeop SoftwareInterrupt; reg0_2 = reg0_2 s>> 1; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SARC reg0_2, 1 is opcode3_9=0x000F & reg0_2 { @@ -421,6 +483,8 @@ define pcodeop SoftwareInterrupt; C = tmpC; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SLL reg0_2, 1 is opcode3_9=0x0009 & reg0_2 { @@ -428,6 +492,8 @@ define pcodeop SoftwareInterrupt; reg0_2 = reg0_2 << 1; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SLLC reg0_2, 1 is opcode3_9=0x000B & reg0_2 { @@ -437,6 +503,8 @@ define pcodeop SoftwareInterrupt; C = tmpC; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SLR reg0_2, 1 is opcode3_9=0x000C & reg0_2 { @@ -444,6 +512,8 @@ define pcodeop SoftwareInterrupt; reg0_2 = reg0_2 >> 1; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SWAP reg0_2, 1 is opcode3_9=0x0008 & reg0_2 { @@ -451,6 +521,8 @@ define pcodeop SoftwareInterrupt; local tmp = (reg0_2 << 8) & 0xFF00; reg0_2 = tmp | ((reg0_2 >> 8) & 0x00FF); S = tmpS; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } with : operation_size=1 { @@ -464,6 +536,8 @@ with : operation_size=1 { O = tmpO; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :RRC reg0_2, 2 is opcode3_9=0x000E & reg0_2 { @@ -475,13 +549,17 @@ with : operation_size=1 { O = tmpO; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SAR reg0_2, 2 is opcode3_9=0x000D & reg0_2 { local tmpS = (reg0_2 & 0x0200) != 0; reg0_2 = reg0_2 s>> 2; S = tmpS; - Z = reg0_2 == 0; + Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SARC reg0_2, 2 is opcode3_9=0x000F & reg0_2 { @@ -493,6 +571,8 @@ with : operation_size=1 { O = tmpO; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SLL reg0_2, 2 is opcode3_9=0x0009 & reg0_2 { @@ -500,6 +580,8 @@ with : operation_size=1 { reg0_2 = reg0_2 << 2; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SLLC reg0_2, 2 is opcode3_9=0x000B & reg0_2 { @@ -511,30 +593,40 @@ with : operation_size=1 { O = tmpO; S = tmpS; Z = reg0_2 == 0; -} + if (®0_2 != &R7) goto inst_next; + goto [R7]; +} :SLR reg0_2, 2 is opcode3_9=0x000C & reg0_2 { local tmpS = (reg0_2 & 0x0200) != 0; reg0_2 = reg0_2 >> 2; S = tmpS; Z = reg0_2 == 0; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SWAP reg0_2, 2 is opcode3_9=0x0008 & reg0_2 { local tmpS = (reg0_2 & 0x0080) != 0; reg0_2 = (reg0_2 << 8) | (reg0_2 & 0x00FF); S = tmpS; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } } :ADDI "#"imm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; imm16 { addition(reg0_2, imm16); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :ANDI "#"imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; imm16 { reg0_2 = reg0_2 & imm16; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :CMPI "#"imm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; imm16 { @@ -543,43 +635,61 @@ with : operation_size=1 { :MVII "#"imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; imm16 { reg0_2 = imm16; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SUBI "#"imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; imm16 { subtraction(reg0_2, imm16); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :XORI "#"imm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; imm16 { reg0_2 = reg0_2 ^ imm16; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } with : doublebyte=1 { :ADDI "#"splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; splitimm16 { addition(reg0_2, splitimm16); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :ANDI "#"splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; splitimm16 { reg0_2 = reg0_2 & splitimm16; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :CMPI "#"splitimm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; splitimm16 { comparison(reg0_2, splitimm16); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :MVII "#"splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; splitimm16 { reg0_2 = splitimm16; + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :SUBI "#"splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; splitimm16 { subtraction(reg0_2, splitimm16); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } :XORI "#"splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; splitimm16 { reg0_2 = reg0_2 ^ splitimm16; resultFlags(reg0_2); + if (®0_2 != &R7) goto inst_next; + goto [R7]; } } From 36c16b2cdec50b992333b943e8fa3e879864e73b Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Sat, 9 May 2020 23:08:15 +0200 Subject: [PATCH 12/14] Address review isues. --- .../CP1600/data/languages/CP1600.cspec | 31 +- .../CP1600/data/languages/CP1600.slaspec | 444 ++++++++---------- 2 files changed, 229 insertions(+), 246 deletions(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.cspec b/Ghidra/Processors/CP1600/data/languages/CP1600.cspec index 6d36f9d6ee..611eedda8a 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.cspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.cspec @@ -7,11 +7,34 @@ - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index 1ccbe2e053..94b7495a54 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -42,7 +42,6 @@ define token double16 (32) define token immediate16 (16) imm16 = (0, 15) - simm16 = (0, 15) signed addr16 = (0, 15) ; @@ -56,10 +55,10 @@ attach variables [ reg24_25 ] [ R4 R5 R6 R7 ]; ################################################################ -jmpdest16: reloc is address_hi & address_lo [ reloc = (address_hi << 10) + address_lo; ] { export *:2 reloc; } -branchdest16: reloc is branch_sign=0 ; imm16 [ reloc = inst_start + 2 + imm16; ] { export *:2 reloc; } -branchdest16: reloc is branch_sign=1 ; simm16 [ reloc = inst_start + 2 + ~simm16; ] { export *:2 reloc; } -splitimm16: split is value_hi & value_lo [ split = (value_hi << 8) + value_lo; ] { local tmp:2 = split & 0xFFFF; export tmp; } +jmpdest16: reloc is address_hi & address_lo [ reloc = (address_hi << 10) + address_lo; ] { export *:2 reloc; } +branchdest16: reloc is branch_sign=0 ; imm16 [ reloc = inst_start + 2 + imm16; ] { export *:2 reloc; } +branchdest16: reloc is branch_sign=1 ; imm16 [ reloc = inst_start + 2 + (imm16 ^ 0xFFFF); ] { export *:2 reloc; } +splitimm16: split is value_hi & value_lo [ split = (value_hi << 8) + value_lo; ] { local tmp:2 = split & 0xFFFF; export tmp; } impliedval16: reg3_5 is reg3_5 & (target3_5=0 | target3_5=1 | target3_5=2 | target3_5=3 | target3_5=7) & doublebyte=0 { local tmp:2 = *:2 reg3_5; @@ -100,6 +99,14 @@ impliedval16: reg3_5 is reg3_5 & (target3_5=0 | target3_5=1 | target3_5=2 | targ export tmp; } +checkbranch: is reg0_2=7 { goto [R7]; } +checkbranch: is reg0_2 {} +regval0_2: is reg0_2=7 { + local tmp:2 = inst_next / 2; + export tmp; +} +regval0_2: is reg0_2 { export reg0_2; } + cc: "" is branch_external=0 & branch_condition=0 { local tmp:1 = 1; export tmp; } cc: "C" is branch_external=0 & branch_condition=1 { export C; } cc: "OV" is branch_external=0 & branch_condition=2 { export O; } @@ -123,13 +130,13 @@ macro resultFlags(value) { S = value s< 0; } -macro addition(first, second) { - local tmpC = carry(first, second); - local tmpO = scarry(first, second); - first = first + second; +macro addition(first_w, first_r, second) { + local tmpC = carry(first_r, second); + local tmpO = scarry(first_r, second); + first_w = first_r + second; C = tmpC; O = tmpO; - resultFlags(first); + resultFlags(first_w); } macro comparison(first, second) { @@ -139,12 +146,12 @@ macro comparison(first, second) { resultFlags(__val__); } -macro subtraction(first, second) { - local __val__ = first - second; - O = sborrow(first, second); - C = first < second; +macro subtraction(first_w, first_r, second) { + local __val__ = first_r - second; + O = sborrow(first_r, second); + C = first_r < second; resultFlags(__val__); - first = __val__; + first_w = __val__; } ################################################################ @@ -154,52 +161,45 @@ define pcodeop SoftwareInterrupt; ################################################################ -:ADD addr16, reg0_2 is opcode3_9=0x0058 & reg0_2 ; addr16 { +:ADD addr16, reg0_2 is opcode3_9=0x0058 & reg0_2 & regval0_2 & checkbranch ; addr16 { local ptr:2 = addr16; - addition(reg0_2, *:2 ptr); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + addition(reg0_2, regval0_2, *:2 ptr); + build checkbranch; } -:ADD@ impliedval16, reg0_2 is opcode6_9=0x000B & reg0_2 & impliedval16 { - addition(reg0_2, impliedval16); - if (®0_2 != &R7) goto inst_next; - goto [R7]; +:ADD@ impliedval16, reg0_2 is opcode6_9=0x000B & reg0_2 & regval0_2 & checkbranch & impliedval16 { + addition(reg0_2, regval0_2, impliedval16); + build checkbranch; } -:ADCR reg0_2 is opcode3_9=0x0005 & reg0_2 { +:ADCR reg0_2 is opcode3_9=0x0005 & reg0_2 & regval0_2 & checkbranch { local oldC = zext(C); - addition(reg0_2, oldC); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + addition(reg0_2, regval0_2, oldC); + build checkbranch; } -:ADDR reg3_5, reg0_2 is opcode6_9=0x0003 & reg3_5 & reg0_2 { - addition(reg0_2, reg3_5); - if (®0_2 != &R7) goto inst_next; - goto [R7]; +:ADDR reg3_5, reg0_2 is opcode6_9=0x0003 & reg3_5 & reg0_2 & regval0_2 & checkbranch { + addition(reg0_2, regval0_2, reg3_5); + build checkbranch; } -:AND addr16, reg0_2 is opcode3_9=0x0070 & reg0_2 ; addr16 { +:AND addr16, reg0_2 is opcode3_9=0x0070 & reg0_2 & regval0_2 & checkbranch ; addr16 { local ptr:2 = addr16; - reg0_2 = reg0_2 & *:2 ptr; + reg0_2 = regval0_2 & *:2 ptr; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:AND@ impliedval16, reg0_2 is opcode6_9=0x000E & reg0_2 & impliedval16 { - reg0_2 = reg0_2 & impliedval16; +:AND@ impliedval16, reg0_2 is opcode6_9=0x000E & reg0_2 & regval0_2 & checkbranch & impliedval16 { + reg0_2 = regval0_2 & impliedval16; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:ANDR reg3_5, reg0_2 is opcode6_9=0x0006 & reg3_5 & reg0_2 { - reg0_2 = reg0_2 & reg3_5; +:ANDR reg3_5, reg0_2 is opcode6_9=0x0006 & reg3_5 & reg0_2 & regval0_2 & checkbranch { + reg0_2 = regval0_2 & reg3_5; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } :B^cc branchdest16 is (opcode6_9=0x0008 & cc) ... & branchdest16 { @@ -214,11 +214,10 @@ define pcodeop SoftwareInterrupt; C = 0; } -:CLRR reg0_2 is opcode6_9=0x0007 & reg0_2 & ((target0_2=0 & target3_5=0) | (target0_2=1 & target3_5=1) | (target0_2=2 & target3_5=2) | (target0_2=3 & target3_5=3) | (target0_2=4 & target3_5=4) | (target0_2=5 & target3_5=5) | (target0_2=6 & target3_5=6) | (target0_2=7 & target3_5=7)) { +:CLRR reg0_2 is opcode6_9=0x0007 & reg0_2 & (target0_2=target3_5) & checkbranch { reg0_2 = 0; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } :CMP addr16, reg0_2 is opcode3_9=0x0068 & reg0_2 ; addr16 { @@ -234,18 +233,16 @@ define pcodeop SoftwareInterrupt; comparison(reg0_2, reg3_5); } -:COMR reg0_2 is opcode3_9=0x0003 & reg0_2 { - reg0_2 = ~reg0_2; +:COMR reg0_2 is opcode3_9=0x0003 & reg0_2 & regval0_2 & checkbranch { + reg0_2 = ~regval0_2; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:DECR reg0_2 is opcode3_9=0x0002 & reg0_2 { - reg0_2 = reg0_2 - 1; +:DECR reg0_2 is opcode3_9=0x0002 & reg0_2 & regval0_2 & checkbranch { + reg0_2 = regval0_2 - 1; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } :DIS is opcode0_9=0x0003 { @@ -265,11 +262,10 @@ define pcodeop SoftwareInterrupt; goto inst_start; } -:INCR reg0_2 is opcode3_9=0x0001 & reg0_2 { - reg0_2 = reg0_2 + 1; +:INCR reg0_2 is opcode3_9=0x0001 & reg0_2 & regval0_2 & checkbranch { + reg0_2 = regval0_2 + 1; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } :J jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & target24_25=3 & jmpdest16 { @@ -286,9 +282,10 @@ define pcodeop SoftwareInterrupt; goto jmpdest16; } -:JR reg3_5 is opcode6_9=0x0002 & reg3_5 & target0_2=7 { - R7 = reg3_5; - goto [R7]; +:JR reg3_5 is opcode6_9=0x0002 & reg3_5 & reg0_2 & reg0_2=7 { + reg0_2 = reg3_5; + resultFlags(reg0_2); + return [reg0_2]; } :JSR reg24_25, jmpdest16 is opcode0_9=0x0004 ; jump_type=0 & reg24_25 & jmpdest16 { @@ -308,24 +305,21 @@ define pcodeop SoftwareInterrupt; call jmpdest16; } -:MOVR reg3_5, reg0_2 is opcode6_9=0x0002 & reg0_2 & reg3_5 { +:MOVR reg3_5, reg0_2 is opcode6_9=0x0002 & reg0_2 & reg3_5 & checkbranch { reg0_2 = reg3_5; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:MVI addr16, reg0_2 is opcode3_9=0x0050 & reg0_2 ; addr16 { +:MVI addr16, reg0_2 is opcode3_9=0x0050 & reg0_2 & checkbranch ; addr16 { local ptr:2 = addr16; reg0_2 = *(*:2 ptr); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:MVI@ impliedval16, reg0_2 is opcode6_9=0x000A & reg0_2 & impliedval16 { +:MVI@ impliedval16, reg0_2 is opcode6_9=0x000A & reg0_2 & impliedval16 & checkbranch { reg0_2 = impliedval16; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } :MVO reg0_2, addr16 is opcode3_9=0x0048 & reg0_2 ; addr16 { @@ -333,14 +327,17 @@ define pcodeop SoftwareInterrupt; *ptr = reg0_2; } -:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 { +:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 & (reg3_5=4 | reg3_5=5) & checkbranch { local ptr:2 = reg3_5; *ptr = reg0_2; - if ((®3_5 != &R4) && (®3_5 != &R5) && (®3_5 != &R6) && (®3_5 != &R7)) goto inst_next; - if (®3_5 != &R7) goto ; - goto [R7]; - reg3_5 = reg3_5 + 1; + build checkbranch; +} + +:MVO@ reg0_2, reg3_5 is opcode6_9=0x0009 & reg0_2 & reg3_5 & checkbranch { + local ptr:2 = reg3_5; + *ptr = reg0_2; + build checkbranch; } :MVOI reg0_2 is opcode3_9=0x004F & reg0_2 ; imm16 { @@ -348,16 +345,15 @@ define pcodeop SoftwareInterrupt; *tmp = reg0_2; } -:NEGR reg0_2 is opcode3_9=0x0004 & reg0_2 { - local tmp = reg0_2 ^ 0xFFFF; +:NEGR reg0_2 is opcode3_9=0x0004 & reg0_2 & regval0_2 & checkbranch { + local tmp = regval0_2 ^ 0xFFFF; local tmpC = carry(tmp, 1); local tmpO = scarry(tmp, 1); - reg0_2 = -reg0_2; + reg0_2 = -regval0_2; C = tmpC; O = tmpO; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } :NOP is opcode1_9=0x001A { @@ -366,16 +362,14 @@ define pcodeop SoftwareInterrupt; :NOPP is opcode6_9=0x0008 & branch_external=0 & branch_condition=8 ; imm16 { } -:PSHR reg0_2 is opcode6_9=0x0009 & reg0_2 & reg3_5=6 { - local ptr:2 = R6; +:PSHR reg0_2 is opcode6_9=0x0009 & reg0_2 & reg3_5 & reg3_5=6 { + local ptr:2 = reg3_5; *ptr = reg0_2; - R6 = R6 + 1; + reg3_5 = reg3_5 + 1; } :PULR reg0_2 is opcode6_9=0x000A & impliedval16 & reg0_2 & reg3_5=6 { reg0_2 = impliedval16; - if (®0_2 != &R7) goto inst_next; - goto [R7]; } :RSWD reg0_2 is opcode3_9=0x0007 & reg0_2 { @@ -396,300 +390,266 @@ define pcodeop SoftwareInterrupt; SoftwareInterrupt(); } -:SUB addr16, reg0_2 is opcode3_9=0x0060 & reg0_2 ; addr16 { +:SUB addr16, reg0_2 is opcode3_9=0x0060 & reg0_2 & regval0_2 & checkbranch ; addr16 { local ptr:2 = addr16; - subtraction(reg0_2, *:2 ptr); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + subtraction(reg0_2, regval0_2, *:2 ptr); + build checkbranch; } -:SUB@ impliedval16, reg0_2 is opcode6_9=0x000C & reg0_2 & impliedval16 { - subtraction(reg0_2, impliedval16); - if (®0_2 != &R7) goto inst_next; - goto [R7]; +:SUB@ impliedval16, reg0_2 is opcode6_9=0x000C & reg0_2 & regval0_2 & checkbranch & impliedval16 { + subtraction(reg0_2, regval0_2, impliedval16); + build checkbranch; } -:SUBR reg3_5, reg0_2 is opcode6_9=0x0004 & reg3_5 & reg0_2 { - subtraction(reg0_2, reg3_5); - if (®0_2 != &R7) goto inst_next; - goto [R7]; +:SUBR reg3_5, reg0_2 is opcode6_9=0x0004 & reg3_5 & reg0_2 & regval0_2 & checkbranch { + subtraction(reg0_2, regval0_2, reg3_5); + build checkbranch; } :TCI is opcode0_9=0x0005 { TerminateCurrentInterrupt(); } -:TSTR reg0_2 is opcode6_9=0x0002 & reg0_2 & ((target0_2=0 & target3_5=0) | (target0_2=1 & target3_5=1) | (target0_2=2 & target3_5=2) | (target0_2=3 & target3_5=3) | (target0_2=4 & target3_5=4) | (target0_2=5 & target3_5=5) | (target0_2=6 & target3_5=6) | (target0_2=7 & target3_5=7)) { +:TSTR reg0_2 is opcode6_9=0x0002 & reg0_2 & (target0_2=target3_5) { resultFlags(reg0_2); } -:XOR addr16, reg0_2 is opcode3_9=0x0078 & reg0_2 ; addr16 { +:XOR addr16, reg0_2 is opcode3_9=0x0078 & reg0_2 & regval0_2 & checkbranch ; addr16 { local ptr:2 = addr16; - reg0_2 = reg0_2 ^ *:2 ptr; + reg0_2 = regval0_2 ^ *:2 ptr; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:XOR@ impliedval16, reg0_2 is opcode6_9=0x000F & reg0_2 & impliedval16 { - reg0_2 = reg0_2 ^ impliedval16; +:XOR@ impliedval16, reg0_2 is opcode6_9=0x000F & reg0_2 & regval0_2 & checkbranch & impliedval16 { + reg0_2 = regval0_2 ^ impliedval16; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:XORR reg3_5, reg0_2 is opcode6_9=0x0007 & reg3_5 & reg0_2 { - reg0_2 = reg0_2 ^ reg3_5; +:XORR reg3_5, reg0_2 is opcode6_9=0x0007 & reg3_5 & reg0_2 & regval0_2 & checkbranch { + reg0_2 = regval0_2 ^ reg3_5; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:RLC reg0_2, 1 is opcode3_9=0x000A & reg0_2 { - local tmpC = (reg0_2 & 0x8000) != 0; - local tmpS = (reg0_2 & 0x4000) != 0; - reg0_2 = (reg0_2 << 1) + zext(C); +:RLC reg0_2, 1 is opcode3_9=0x000A & reg0_2 & regval0_2 & checkbranch { + local tmpC = (regval0_2 & 0x8000) != 0; + local tmpS = (regval0_2 & 0x4000) != 0; + reg0_2 = (regval0_2 << 1) + zext(C); C = tmpC; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:RRC reg0_2, 1 is opcode3_9=0x000E & reg0_2 { - local tmpC = (reg0_2 & 0x0001) != 0; - local tmpS = (reg0_2 & 0x0100) != 0; - reg0_2 = (reg0_2 >> 1) | (zext(C) << 15); +:RRC reg0_2, 1 is opcode3_9=0x000E & reg0_2 & regval0_2 & checkbranch { + local tmpC = (regval0_2 & 0x0001) != 0; + local tmpS = (regval0_2 & 0x0100) != 0; + reg0_2 = (regval0_2 >> 1) | (zext(C) << 15); C = tmpC; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SAR reg0_2, 1 is opcode3_9=0x000D & reg0_2 { - local tmpS = (reg0_2 & 0x0100) != 0; - reg0_2 = reg0_2 s>> 1; +:SAR reg0_2, 1 is opcode3_9=0x000D & reg0_2 & regval0_2 & checkbranch { + local tmpS = (regval0_2 & 0x0100) != 0; + reg0_2 = regval0_2 s>> 1; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SARC reg0_2, 1 is opcode3_9=0x000F & reg0_2 { - local tmpC = (reg0_2 & 0x0001) != 0; - local tmpS = (reg0_2 & 0x0100) != 0; - reg0_2 = reg0_2 s>> 1; +:SARC reg0_2, 1 is opcode3_9=0x000F & reg0_2 & regval0_2 & checkbranch { + local tmpC = (regval0_2 & 0x0001) != 0; + local tmpS = (regval0_2 & 0x0100) != 0; + reg0_2 = regval0_2 s>> 1; C = tmpC; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SLL reg0_2, 1 is opcode3_9=0x0009 & reg0_2 { - local tmpS = (reg0_2 & 0x4000) != 0; - reg0_2 = reg0_2 << 1; +:SLL reg0_2, 1 is opcode3_9=0x0009 & reg0_2 & regval0_2 & checkbranch { + local tmpS = (regval0_2 & 0x4000) != 0; + reg0_2 = regval0_2 << 1; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SLLC reg0_2, 1 is opcode3_9=0x000B & reg0_2 { - local tmpC = (reg0_2 & 0x8000) != 0; - local tmpS = (reg0_2 & 0x4000) != 0; - reg0_2 = reg0_2 << 1; +:SLLC reg0_2, 1 is opcode3_9=0x000B & reg0_2 & regval0_2 & checkbranch { + local tmpC = (regval0_2 & 0x8000) != 0; + local tmpS = (regval0_2 & 0x4000) != 0; + reg0_2 = regval0_2 << 1; C = tmpC; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SLR reg0_2, 1 is opcode3_9=0x000C & reg0_2 { - local tmpS = (reg0_2 & 0x0100) != 0; - reg0_2 = reg0_2 >> 1; +:SLR reg0_2, 1 is opcode3_9=0x000C & reg0_2 & regval0_2 & checkbranch { + local tmpS = (regval0_2 & 0x0100) != 0; + reg0_2 = regval0_2 >> 1; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SWAP reg0_2, 1 is opcode3_9=0x0008 & reg0_2 { - local tmpS = (reg0_2 & 0x8000) != 0; - local tmp = (reg0_2 << 8) & 0xFF00; - reg0_2 = tmp | ((reg0_2 >> 8) & 0x00FF); +:SWAP reg0_2, 1 is opcode3_9=0x0008 & reg0_2 & regval0_2 & checkbranch { + local tmpS = (regval0_2 & 0x8000) != 0; + local tmp = (regval0_2 << 8) & 0xFF00; + reg0_2 = tmp | ((regval0_2 >> 8) & 0x00FF); S = tmpS; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } with : operation_size=1 { -:RLC reg0_2, 2 is opcode3_9=0x000A & reg0_2 { - local tmpC = (reg0_2 & 0x8000) != 0; - local tmpO = (reg0_2 & 0x4000) != 0; - local tmpS = (reg0_2 & 0x2000) != 0; - reg0_2 = (reg0_2 << 2) + (zext(C) << 1) + zext(O); +:RLC reg0_2, 2 is opcode3_9=0x000A & reg0_2 & regval0_2 & checkbranch { + local tmpC = (regval0_2 & 0x8000) != 0; + local tmpO = (regval0_2 & 0x4000) != 0; + local tmpS = (regval0_2 & 0x2000) != 0; + reg0_2 = (regval0_2 << 2) + (zext(C) << 1) + zext(O); C = tmpC; O = tmpO; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:RRC reg0_2, 2 is opcode3_9=0x000E & reg0_2 { - local tmpC = (reg0_2 & 0x0001) != 0; - local tmpO = (reg0_2 & 0x0002) != 0; - local tmpS = (reg0_2 & 0x0200) != 0; - reg0_2 = (reg0_2 >> 2) | (zext(C) << 14) | (zext(O) << 15); +:RRC reg0_2, 2 is opcode3_9=0x000E & reg0_2 & regval0_2 & checkbranch { + local tmpC = (regval0_2 & 0x0001) != 0; + local tmpO = (regval0_2 & 0x0002) != 0; + local tmpS = (regval0_2 & 0x0200) != 0; + reg0_2 = (regval0_2 >> 2) | (zext(C) << 14) | (zext(O) << 15); C = tmpC; O = tmpO; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SAR reg0_2, 2 is opcode3_9=0x000D & reg0_2 { - local tmpS = (reg0_2 & 0x0200) != 0; - reg0_2 = reg0_2 s>> 2; +:SAR reg0_2, 2 is opcode3_9=0x000D & reg0_2 & regval0_2 & checkbranch { + local tmpS = (regval0_2 & 0x0200) != 0; + reg0_2 = regval0_2 s>> 2; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SARC reg0_2, 2 is opcode3_9=0x000F & reg0_2 { - local tmpC = (reg0_2 & 0x0001) != 0; - local tmpO = (reg0_2 & 0x0002) != 0; - local tmpS = (reg0_2 & 0x0200) != 0; - reg0_2 = reg0_2 s>> 2; +:SARC reg0_2, 2 is opcode3_9=0x000F & reg0_2 & regval0_2 & checkbranch { + local tmpC = (regval0_2 & 0x0001) != 0; + local tmpO = (regval0_2 & 0x0002) != 0; + local tmpS = (regval0_2 & 0x0200) != 0; + reg0_2 = regval0_2 s>> 2; C = tmpC; O = tmpO; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SLL reg0_2, 2 is opcode3_9=0x0009 & reg0_2 { - local tmpS = (reg0_2 & 0x2000) != 0; - reg0_2 = reg0_2 << 2; +:SLL reg0_2, 2 is opcode3_9=0x0009 & reg0_2 & regval0_2 & checkbranch { + local tmpS = (regval0_2 & 0x2000) != 0; + reg0_2 = regval0_2 << 2; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SLLC reg0_2, 2 is opcode3_9=0x000B & reg0_2 { - local tmpC = (reg0_2 & 0x8000) != 0; - local tmpO = (reg0_2 & 0x4000) != 0; - local tmpS = (reg0_2 & 0x2000) != 0; - reg0_2 = reg0_2 << 2; +:SLLC reg0_2, 2 is opcode3_9=0x000B & reg0_2 & regval0_2 & checkbranch { + local tmpC = (regval0_2 & 0x8000) != 0; + local tmpO = (regval0_2 & 0x4000) != 0; + local tmpS = (regval0_2 & 0x2000) != 0; + reg0_2 = regval0_2 << 2; C = tmpC; O = tmpO; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SLR reg0_2, 2 is opcode3_9=0x000C & reg0_2 { - local tmpS = (reg0_2 & 0x0200) != 0; - reg0_2 = reg0_2 >> 2; +:SLR reg0_2, 2 is opcode3_9=0x000C & reg0_2 & regval0_2 & checkbranch { + local tmpS = (regval0_2 & 0x0200) != 0; + reg0_2 = regval0_2 >> 2; S = tmpS; Z = reg0_2 == 0; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SWAP reg0_2, 2 is opcode3_9=0x0008 & reg0_2 { - local tmpS = (reg0_2 & 0x0080) != 0; - reg0_2 = (reg0_2 << 8) | (reg0_2 & 0x00FF); +:SWAP reg0_2, 2 is opcode3_9=0x0008 & reg0_2 & regval0_2 & checkbranch { + local tmpS = (regval0_2 & 0x0080) != 0; + reg0_2 = (regval0_2 << 8) | (regval0_2 & 0x00FF); S = tmpS; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } } -:ADDI "#"imm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; imm16 { - addition(reg0_2, imm16); - if (®0_2 != &R7) goto inst_next; - goto [R7]; +:ADDI "#"imm16, reg0_2 is opcode3_9=0x005F & reg0_2 & regval0_2 & checkbranch ; imm16 { + addition(reg0_2, regval0_2, imm16); + build checkbranch; } -:ANDI "#"imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; imm16 { +:ANDI "#"imm16, reg0_2 is opcode3_9=0x0077 & reg0_2 & regval0_2 & checkbranch ; imm16 { reg0_2 = reg0_2 & imm16; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } :CMPI "#"imm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; imm16 { comparison(reg0_2, imm16); } -:MVII "#"imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; imm16 { +:MVII "#"imm16, reg0_2 is opcode3_9=0x0057 & reg0_2 & checkbranch ; imm16 { reg0_2 = imm16; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SUBI "#"imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; imm16 { - subtraction(reg0_2, imm16); - if (®0_2 != &R7) goto inst_next; - goto [R7]; +:SUBI "#"imm16, reg0_2 is opcode3_9=0x0067 & reg0_2 & regval0_2 & checkbranch ; imm16 { + subtraction(reg0_2, regval0_2, imm16); + build checkbranch; } -:XORI "#"imm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; imm16 { - reg0_2 = reg0_2 ^ imm16; +:XORI "#"imm16, reg0_2 is opcode3_9=0x007F & reg0_2 & regval0_2 & checkbranch ; imm16 { + reg0_2 = regval0_2 ^ imm16; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } with : doublebyte=1 { -:ADDI "#"splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 ; splitimm16 { - addition(reg0_2, splitimm16); - if (®0_2 != &R7) goto inst_next; - goto [R7]; +:ADDI "#"splitimm16, reg0_2 is opcode3_9=0x005F & reg0_2 & regval0_2 & checkbranch ; splitimm16 { + addition(reg0_2, regval0_2, splitimm16); + build checkbranch; } -:ANDI "#"splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 ; splitimm16 { - reg0_2 = reg0_2 & splitimm16; +:ANDI "#"splitimm16, reg0_2 is opcode3_9=0x0077 & reg0_2 & regval0_2 & checkbranch ; splitimm16 { + reg0_2 = regval0_2 & splitimm16; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } :CMPI "#"splitimm16, reg0_2 is opcode3_9=0x006F & reg0_2 ; splitimm16 { comparison(reg0_2, splitimm16); - if (®0_2 != &R7) goto inst_next; - goto [R7]; } -:MVII "#"splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 ; splitimm16 { +:MVII "#"splitimm16, reg0_2 is opcode3_9=0x0057 & reg0_2 & checkbranch ; splitimm16 { reg0_2 = splitimm16; - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } -:SUBI "#"splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 ; splitimm16 { - subtraction(reg0_2, splitimm16); - if (®0_2 != &R7) goto inst_next; - goto [R7]; +:SUBI "#"splitimm16, reg0_2 is opcode3_9=0x0067 & reg0_2 & regval0_2 & checkbranch ; splitimm16 { + subtraction(reg0_2, regval0_2, splitimm16); + build checkbranch; } -:XORI "#"splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 ; splitimm16 { - reg0_2 = reg0_2 ^ splitimm16; +:XORI "#"splitimm16, reg0_2 is opcode3_9=0x007F & reg0_2 & regval0_2 & checkbranch ; splitimm16 { + reg0_2 = regval0_2 ^ splitimm16; resultFlags(reg0_2); - if (®0_2 != &R7) goto inst_next; - goto [R7]; + build checkbranch; } } From 165334c9c9a46508e3e8f1cde3d0c63983e2f043 Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Wed, 13 May 2020 22:25:31 +0200 Subject: [PATCH 13/14] Use just one memory access for SDBD reads/writes. --- .../CP1600/data/languages/CP1600.slaspec | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec index 94b7495a54..5003b321f6 100644 --- a/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec +++ b/Ghidra/Processors/CP1600/data/languages/CP1600.slaspec @@ -78,25 +78,27 @@ impliedval16: reg3_5 is reg3_5 & target3_5=6 & doublebyte=0 { } impliedval16: reg3_5 is reg3_5 & (target3_5=4 | target3_5=5) & doublebyte=1 { - local tmp:2 = zext(*:1 reg3_5); - reg3_5 = reg3_5 + 1; - tmp = tmp | (zext(*:1 reg3_5) << 8); - reg3_5 = reg3_5 + 1; + local val:4 = *:4 reg3_5; + local low:1 = val(2); + local high:1 = val(0); + local tmp:2 = (zext(high) << 8) | zext(low); + reg3_5 = reg3_5 + 2; export tmp; } impliedval16: reg3_5 is reg3_5 & target3_5=6 & doublebyte=1 { - reg3_5 = reg3_5 - 1; - local tmp:2 = zext(*:1 reg3_5); - reg3_5 = reg3_5 - 1; - tmp = tmp | (zext(*:1 reg3_5) << 8); + reg3_5 = reg3_5 - 2; + local val:4 = *:4 reg3_5; + local low:1 = val(2); + local high:1 = val(0); + local tmp:2 = (zext(high) << 8) | zext(low); export tmp; } impliedval16: reg3_5 is reg3_5 & (target3_5=0 | target3_5=1 | target3_5=2 | target3_5=3 | target3_5=7) & doublebyte=1 { - local tmp:2 = zext(*:1 reg3_5); - tmp = tmp | (zext(*:1 reg3_5) << 8); - export tmp; + local val:2 = *:1 reg3_5; + val = (zext(val) << 8) | zext(val); + export val; } checkbranch: is reg0_2=7 { goto [R7]; } From 60cd19701d65a57d1aa64abb83b865016ee4544f Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Tue, 14 Jul 2020 15:54:34 -0400 Subject: [PATCH 14/14] GT-3426: Added certification --- Ghidra/Processors/CP1600/certification.manifest | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Ghidra/Processors/CP1600/certification.manifest diff --git a/Ghidra/Processors/CP1600/certification.manifest b/Ghidra/Processors/CP1600/certification.manifest new file mode 100644 index 0000000000..a1b17c8f45 --- /dev/null +++ b/Ghidra/Processors/CP1600/certification.manifest @@ -0,0 +1,8 @@ +##VERSION: 2.0 +Module.manifest||GHIDRA||||END| +build.gradle||GHIDRA||||END| +data/languages/CP1600.cspec||GHIDRA||||END| +data/languages/CP1600.ldefs||GHIDRA||||END| +data/languages/CP1600.opinion||GHIDRA||||END| +data/languages/CP1600.pspec||GHIDRA||||END| +data/languages/CP1600.slaspec||GHIDRA||||END|