summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/e132xs/e132xsfe.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/e132xs/e132xsfe.cpp')
-rw-r--r--src/devices/cpu/e132xs/e132xsfe.cpp1302
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;
+}