diff options
Diffstat (limited to 'src/devices/cpu/e132xs/e132xsfe.cpp')
-rw-r--r-- | src/devices/cpu/e132xs/e132xsfe.cpp | 1302 |
1 files changed, 1302 insertions, 0 deletions
diff --git a/src/devices/cpu/e132xs/e132xsfe.cpp b/src/devices/cpu/e132xs/e132xsfe.cpp new file mode 100644 index 00000000000..be54f9342d3 --- /dev/null +++ b/src/devices/cpu/e132xs/e132xsfe.cpp @@ -0,0 +1,1302 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/*************************************************************************** + + e132xsfe.cpp + + Front end for Hyperstone recompiler + +***************************************************************************/ + +#include "emu.h" +#include "e132xsfe.h" +#include "32xsdefs.h" + +#define FE_FP ((m_cpu->m_global_regs[1] & 0xfe000000) >> 25) +#define FE_FL (m_cpu->m_fl_lut[((m_cpu->m_global_regs[1] >> 21) & 0xf)]) +#define DST_CODE ((op & 0xf0) >> 4) +#define SRC_CODE (op & 0x0f) +#define SR_CODE (1 << 1) + +/*************************************************************************** + INSTRUCTION PARSERS +***************************************************************************/ + +e132xs_frontend::e132xs_frontend(hyperstone_device *e132xs, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) + : drc_frontend(*e132xs, window_start, window_end, max_sequence) + , m_cpu(e132xs) +{ +} + +inline uint32_t e132xs_frontend::imm_length(opcode_desc &desc, uint16_t op) +{ + uint8_t nybble = op & 0x0f; + switch (nybble) + { + case 0: + default: + return 2; + case 1: + return 6; + case 2: + case 3: + return 4; + } +} + +inline uint16_t e132xs_frontend::read_word(opcode_desc &desc) +{ + return m_cpu->m_direct->read_word(desc.physpc, m_cpu->m_opcodexor); +} + +inline uint16_t e132xs_frontend::read_imm1(opcode_desc &desc) +{ + return m_cpu->m_direct->read_word(desc.physpc + 2, m_cpu->m_opcodexor); +} + +inline uint16_t e132xs_frontend::read_imm2(opcode_desc &desc) +{ + return m_cpu->m_direct->read_word(desc.physpc + 4, m_cpu->m_opcodexor); +} + +inline uint32_t e132xs_frontend::read_ldstxx_imm(opcode_desc &desc) +{ + const uint16_t imm1 = read_imm1(desc); + uint32_t extra_s; + if (imm1 & 0x8000) + { + extra_s = read_imm2(desc); + extra_s |= ((imm1 & 0xfff) << 16); + + if (imm1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + extra_s = imm1 & 0xfff; + + if (imm1 & 0x4000) + extra_s |= 0xfffff000; + } + return extra_s; +} + +inline uint32_t e132xs_frontend::read_limm(opcode_desc &desc, uint16_t op) +{ + static const int32_t immediate_values[16] = + { + 16, 0, 0, 0, 32, 64, 128, int32_t(0x80000000), + -8, -7, -6, -5, -4, -3, -2, -1 + }; + + uint8_t nybble = op & 0xf; + switch (nybble) + { + case 0: + return 16; + case 1: + return (read_imm1(desc) << 16) | read_imm2(desc); + case 2: + return read_imm1(desc); + case 3: + return 0xffff0000 | read_imm1(desc); + default: + return immediate_values[nybble]; + } +} + +inline int32_t e132xs_frontend::decode_pcrel(opcode_desc &desc, uint16_t op) +{ + if (op & 0x80) + { + uint16_t next = read_imm1(desc); + + desc.length = 4; + + int32_t offset = (op & 0x7f) << 16; + offset |= (next & 0xfffe); + + if (next & 1) + offset |= 0xff800000; + + return offset; + } + else + { + int32_t offset = op & 0x7e; + if (op & 1) + offset |= 0xffffff80; + return offset; + } +} + +inline int32_t e132xs_frontend::decode_call(opcode_desc &desc) +{ + const uint16_t imm_1 = read_imm1(desc); + int32_t extra_s = 0; + if (imm_1 & 0x8000) + { + desc.length = 6; + extra_s = read_imm2(desc); + extra_s |= ((imm_1 & 0x3fff) << 16); + + if (imm_1 & 0x4000) + extra_s |= 0xc0000000; + } + else + { + desc.length = 4; + extra_s = imm_1 & 0x3fff; + if (imm_1 & 0x4000) + extra_s |= 0xffffc000; + } + return extra_s; +} + + +/*------------------------------------------------- + describe - build a description of a single + instruction +-------------------------------------------------*/ + +bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) +{ + uint16_t op = desc.opptr.w[0] = read_word(desc); + + /* most instructions are 2 bytes and a single cycle */ + desc.length = 2; + desc.cycles = m_cpu->m_clock_cycles_1; + + const uint32_t fp = FE_FP; + const uint32_t gdst_code = DST_CODE; + const uint32_t gdstf_code = gdst_code + 1; + const uint32_t gsrc_code = SRC_CODE; + const uint32_t gsrcf_code = gsrc_code + 1; + const uint32_t ldst_code = (gdst_code + fp) & 0x1f; + const uint32_t ldstf_code = (gdstf_code + fp) & 0x1f; + const uint32_t lsrc_code = (gsrc_code + fp) & 0x1f; + const uint32_t lsrcf_code = (gsrcf_code + fp) & 0x1f; + const uint32_t ldst_group = 1 + (((DST_CODE + fp) & 0x20) >> 5); + const uint32_t ldstf_group = 1 + (((DST_CODE + fp + 1) & 0x20) >> 5); + const uint32_t lsrc_group = 1 + (((SRC_CODE + fp) & 0x20) >> 5); + const uint32_t lsrcf_group = 1 + ((SRC_CODE + fp + 1) >> 5); + + switch (op >> 8) + { + case 0x00: // chk global,global + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gsrc_code; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x01: // chk global,local + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x02: // chk local,global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x03: // chk local,local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x04: // movd global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gsrcf_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + if (gdst_code == 0) + { + desc.regout[1] = 0xffffffff; + desc.regout[2] = 0xffffffff; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + } + else + { + desc.cycles = m_cpu->m_clock_cycles_2; + } + desc.regout[0] |= SR_CODE; + break; + case 0x05: // movd global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[lsrcf_group] |= 1 << lsrcf_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + if (gdst_code == 0) + { + desc.regout[1] = 0xffffffff; + desc.regout[2] = 0xffffffff; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + } + else + { + desc.cycles = m_cpu->m_clock_cycles_2; + } + desc.regout[0] |= SR_CODE; + break; + case 0x06: // movd local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gsrcf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_2; + break; + case 0x07: // movd local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[lsrcf_group] |= 1 << lsrcf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_2; + break; + case 0x08: // divu global,global + case 0x0c: // divs global,global + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gdstf_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 36 << m_cpu->m_clck_scale; + break; + case 0x09: // divu global,local + case 0x0d: // divs global,local + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gdstf_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 36 << m_cpu->m_clck_scale; + break; + case 0x0a: // divu local,global + case 0x0e: // divs local,global + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[ldstf_group] |= 1 << ldstf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 36 << m_cpu->m_clck_scale; + break; + case 0x0b: // divu local,local + case 0x0f: // divs local,local + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[ldstf_group] |= 1 << ldstf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 36 << m_cpu->m_clck_scale; + break; + case 0x10: // xm global,global + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x11: // xm global,local + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x12: // xm local,global + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x13: // xm local,local + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x14: // mask global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x15: // mask global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x16: // mask local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x17: // mask local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x18: // sum global,global + case 0x1c: // sums global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + if (op & 0x4 && gsrc_code != SR_REGISTER) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x19: // sum global,local + case 0x1d: // sums global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + if (op & 0x4) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x1a: // sum local,global + case 0x1e: // sums local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + if (op & 0x4 && gsrc_code != SR_REGISTER) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x1b: // sum local,local + case 0x1f: // sums local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + if (op & 0x4) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x20: // cmp global,global + case 0x30: // cmpb global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x21: // cmp global,local + case 0x31: // cmpb global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x22: // cmp local,global + case 0x32: // cmpb local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x23: // cmp local,local + case 0x33: // cmpb local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x24: // mov global,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << (gsrc_code + 16); + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x25: // mov global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x26: // mov local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << (gsrc_code + 16); + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x27: // mov local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x28: // add global,global + case 0x2c: // adds global,global + case 0x48: // sub global,global + case 0x4c: // subs global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs + break; + case 0x29: // add global,local + case 0x2d: // adds global,local + case 0x49: // sub global,local + case 0x4d: // subs global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs + break; + case 0x2a: // add local,global + case 0x2e: // adds local,global + case 0x4a: // sub local,global + case 0x4e: // subs local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs + break; + case 0x2b: // add local,local + case 0x2f: // adds local,local + case 0x4b: // sub local,local + case 0x4f: // subs local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs + break; + case 0x34: // andn global,global + case 0x38: // or global,global + case 0x3c: // xor global,global + case 0x54: // and global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x35: // andn global,local + case 0x39: // or global,local + case 0x3d: // xor global,local + case 0x55: // and global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x36: // andn local,global + case 0x3a: // or local,global + case 0x3e: // xor local,global + case 0x56: // and local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x37: // andn local,local + case 0x3b: // or local,local + case 0x3f: // xor local,local + case 0x57: // and local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x40: // subc global,global + case 0x50: // addc global,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x41: // subc global,local + case 0x51: // addc global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x42: // subc local,global + case 0x52: // addc local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x43: // subc local,local + case 0x53: // addc local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x44: // not global,global + case 0x58: // neg global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x45: // not global,local + case 0x59: // neg global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x46: // not local,global + case 0x5a: // neg local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x47: // not local,local + case 0x5b: // neg local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x5c: // negs global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x5d: // negs global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x5e: // negs local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x5f: // negs local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x60: // cmpi global,simm + case 0x70: // cmpbi global,simm + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x61: // cmpi global,limm + case 0x71: // cmpbi global,limm + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + break; + case 0x62: // cmpi local,simm + case 0x72: // cmpbi local,simm + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x63: // cmpi local,limm + case 0x73: // cmpbi local,limm + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + break; + case 0x64: // movi global,simm + desc.regin[0] |= SR_CODE; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << (gdst_code + 16); + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = op & 0xf; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x65: // movi global,limm + desc.regin[0] |= SR_CODE; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << (gdst_code + 16); + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = read_limm(desc, op); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x66: // movi local,simm + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x67: // movi local,limm + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + break; + case 0x68: // addi global,simm + case 0x6c: // addsi global,simm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x69: // addi global,limm + case 0x6d: // addsi global,limm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x6a: // addi local,simm + case 0x6e: // addsi local,simm + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + break; + case 0x6b: // addi local,limm + case 0x6f: // addsi local,limm + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + break; + case 0x74: // andni global,simm + case 0x78: // ori global,simm + case 0x7c: // xori global,simm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x75: // andni global,limm + case 0x79: // ori global,limm + case 0x7d: // xori global,limm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x76: // andni local,simm + case 0x7a: // ori local,simm + case 0x7e: // xori local,simm + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x77: // andni local,limm + case 0x7b: // ori local,limm + case 0x7f: // xori local,limm + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + break; + case 0x80: case 0x81: // shrdi + case 0x84: case 0x85: // sardi + case 0x88: case 0x89: // shldi + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_2; + break; + case 0x82: // shrd + case 0x86: // sard + case 0x8a: // shld + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_2; + break; + case 0x83: // shr + case 0x87: // sar + case 0x8b: // shl + case 0x8f: // rol + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x8c: case 0x8d: // reserved + return false; + case 0x8e: // testlz + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + break; + case 0x90: // ldxx1 global,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + } + case 0x91: // ldxx1 global,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + } + case 0x92: // ldxx1 local,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + break; + } + case 0x93: // ldxx1 local,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + break; + } + case 0x94: // ldxx2 global,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + } + case 0x95: // ldxx2 global,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + } + case 0x96: // ldxx2 local,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + break; + } + case 0x97: // ldxx2 local,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + break; + } + case 0x98: // stxx1 global,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x99: // stxx1 global,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9a: // stxx1 local,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9b: // stxx1 local,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9c: // stxx2 global,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; + desc.regout[0] |= 1 << gdst_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9d: // stxx2 global,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; + desc.regout[0] |= 1 << gdst_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9e: // stxx2 local,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9f: // stxx2 local,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0xa0: // shri global (lo n) + case 0xa1: // shri global (hi n) + case 0xa4: // sari global (lo n) + case 0xa5: // sari global (hi n) + case 0xa8: // shli global (lo n) + case 0xa9: // shli global (hi n) + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0xa2: // shri local (lo n) + case 0xa3: // shri local (hi n) + case 0xa6: // sari local (lo n) + case 0xa7: // sari local (hi n) + case 0xaa: // shli local (lo n) + case 0xab: // shli local (hi n) + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0xac: case 0xad: case 0xae: case 0xaf: // reserved + return false; + case 0xb0: // mulu global,global + case 0xb4: // muls global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_4; + break; + case 0xb1: // mulu global,local + case 0xb5: // muls global,local + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_4; + break; + case 0xb2: // mulu local,global + case 0xb6: // muls local,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_4; + break; + case 0xb3: // mulu local,local + case 0xb7: // muls local,local + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_4; + break; + case 0xb8: // set global (lo n) + case 0xb9: // set global (hi n) + desc.regin[0] |= SR_CODE; + desc.regout[0] |= 1 << gdst_code; + break; + case 0xba: // set local (lo n) + case 0xbb: // set local (hi n) + desc.regout[ldst_group] |= 1 << ldst_code; + break; + case 0xbc: // mul global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 3 << m_cpu->m_clck_scale; + break; + case 0xbd: // muls global,local + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 3 << m_cpu->m_clck_scale; + break; + case 0xbe: // muls local,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 3 << m_cpu->m_clck_scale; + break; + case 0xbf: // mulu local,local + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 3 << m_cpu->m_clck_scale; + break; + case 0xc0: case 0xc1: case 0xc2: case 0xc3: // software + case 0xc4: case 0xc5: case 0xc6: case 0xc7: // software + case 0xc8: case 0xc9: case 0xca: case 0xcb: // software + case 0xcc: case 0xcd: // software + { + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[lsrcf_group] |= 1 << lsrcf_code; + + const uint32_t reg = FE_FP + FE_FL; + desc.regout[1 + (((reg + 0) & 0x20) >> 5)] |= 1 << ((reg + 0) & 0x1f); + desc.regout[1 + (((reg + 1) & 0x20) >> 5)] |= 1 << ((reg + 1) & 0x1f); + desc.regout[1 + (((reg + 2) & 0x20) >> 5)] |= 1 << ((reg + 2) & 0x1f); + desc.regout[1 + (((reg + 3) & 0x20) >> 5)] |= 1 << ((reg + 3) & 0x1f); + desc.regout[1 + (((reg + 4) & 0x20) >> 5)] |= 1 << ((reg + 4) & 0x1f); + + desc.regout[0] |= SR_CODE; + + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + break; + } + case 0xce: // extend - 4 bytes + desc.regin[0] |= SR_CODE; + desc.regin[0] |= (3 << 14); // global regs 14, 15 + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= (3 << 14); // global regs 14, 15 + break; + case 0xcf: // do + return false; + case 0xd0: // ldwr global + case 0xd4: // ldwp global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= 1 << gsrc_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_READS_MEMORY; + break; + case 0xd1: // ldwr local + case 0xd5: // ldwp local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_READS_MEMORY; + break; + case 0xd2: // lddr global + case 0xd6: // lddp global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gsrcf_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_READS_MEMORY; + break; + case 0xd3: // lddr local + case 0xd7: // lddp local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + desc.regout[lsrcf_group] |= 1 << lsrcf_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_READS_MEMORY; + break; + case 0xd8: // stwr global + case 0xdc: // stwp global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + case 0xd9: // stwr local + case 0xdd: // stwp local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + case 0xda: // stdr global + case 0xde: // stdp global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gsrcf_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + case 0xdb: // stdr local + case 0xdf: // stdp local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[lsrcf_group] |= 1 << lsrcf_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + case 0xe0: case 0xe1: case 0xe2: case 0xe3: // dbv, dbnv, dbe, dbne - could be 4 bytes (pcrel) + case 0xe4: case 0xe5: case 0xe6: case 0xe7: // dbc, dbnc, dbse, dbht - could be 4 bytes (pcrel) + case 0xe8: case 0xe9: case 0xea: case 0xeb: // dbn, dbnn, dblt, dbgt - could be 4 bytes (pcrel) + desc.regin[0] |= SR_CODE; + desc.targetpc = desc.pc + decode_pcrel(desc, op); + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; + desc.delayslots = 1; + break; + case 0xec: // dbr - could be 4 bytes (pcrel) + desc.targetpc = desc.pc + decode_pcrel(desc, op); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.delayslots = 1; + break; + case 0xed: // frame + desc.regin[0] |= SR_CODE; + desc.regin[1] = 0xffffffff; + desc.regin[2] = 0xffffffff; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_END_SEQUENCE; + break; + case 0xee: // call global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.targetpc = desc.pc + decode_call(desc); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + break; + case 0xef: // call local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.targetpc = desc.pc + decode_call(desc); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + break; + case 0xf0: case 0xf1: case 0xf2: case 0xf3: // bv, bnv, be, bne + case 0xf4: case 0xf5: case 0xf6: case 0xf7: // bc, bnc, bse, bht + case 0xf8: case 0xf9: case 0xfa: case 0xfb: // bn, bnn, blt, bgt + desc.regin[0] |= SR_CODE; + desc.targetpc = desc.pc + decode_pcrel(desc, op); + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; + break; + case 0xfc: // br + desc.targetpc = desc.pc + decode_pcrel(desc, op); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + break; + case 0xfd: case 0xfe: case 0xff: // trap + desc.regin[0] |= SR_CODE; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + break; + } + return true; +} |