e132xs: simplify stxx1. nw

This commit is contained in:
mooglyguy 2017-12-02 16:43:46 +01:00
parent f3dcc7e6b6
commit 280fb70b58
4 changed files with 220 additions and 254 deletions

View File

@ -513,8 +513,7 @@ private:
void generate_dbr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_frame(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_call_global(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_call_local(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
template <hyperstone_device::reg_bank SRC_GLOBAL> void generate_call(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_trap_op(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
void generate_extend(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);

View File

@ -937,8 +937,8 @@ bool hyperstone_device::generate_opcode(drcuml_block *block, compiler_state *com
case 0xeb: generate_db<COND_NZ, IS_CLEAR>(block, compiler, desc); break;
case 0xec: generate_dbr(block, compiler, desc); break;
case 0xed: generate_frame(block, compiler, desc); break;
case 0xee: generate_call_global(block, compiler, desc); break;
case 0xef: generate_call_local(block, compiler, desc); break;
case 0xee: generate_call<GLOBAL>(block, compiler, desc); break;
case 0xef: generate_call<LOCAL>(block, compiler, desc); break;
case 0xf0: generate_b<COND_V, IS_SET>(block, compiler, desc); break;
case 0xf1: generate_b<COND_V, IS_CLEAR>(block, compiler, desc); break;
case 0xf2: generate_b<COND_Z, IS_SET>(block, compiler, desc); break;

View File

@ -1189,6 +1189,38 @@ void hyperstone_device::generate_ldxx2(drcuml_block *block, compiler_state *comp
template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL>
void hyperstone_device::generate_stxx1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
{
/*
const uint16_t op = desc->opptr.w[0];
uint16_t next_1 = READ_OP(desc->pc + 2);
const uint16_t sub_type = (next_1 & 0x3000) >> 12;
uint32_t extra_s;
if (next_1 & 0x8000)
{
const uint16_t next_2 = READ_OP(desc->pc + 4);
extra_s = next_2;
extra_s |= ((next_1 & 0xfff) << 16);
if (next_1 & 0x4000)
extra_s |= 0xf0000000;
UML_MOV(block, mem(&m_instruction_length), (3<<19));
UML_ADD(block, DRC_PC, DRC_PC, 4);
}
else
{
extra_s = next_1 & 0xfff;
if (next_1 & 0x4000)
extra_s |= 0xfffff000;
UML_MOV(block, mem(&m_instruction_length), (2<<19));
UML_ADD(block, DRC_PC, DRC_PC, 2);
}
generate_check_delay_pc(block);
*/
}
@ -1334,13 +1366,85 @@ void hyperstone_device::generate_frame(drcuml_block *block, compiler_state *comp
UML_LABEL(block, done);
}
void hyperstone_device::generate_call_global(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
template <hyperstone_device::reg_bank SRC_GLOBAL>
void hyperstone_device::generate_call(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
{
uint16_t op = desc->opptr.w[0];
uint16_t imm_1 = READ_OP(desc->pc + 2);
int32_t extra_s = 0;
if (imm_1 & 0x8000)
{
uint16_t imm_2 = READ_OP(desc->pc + 4);
extra_s = imm_2;
extra_s |= ((imm_1 & 0x3fff) << 16);
if (imm_1 & 0x4000)
extra_s |= 0xc0000000;
UML_MOV(block, mem(&m_instruction_length), (3<<19));
UML_ADD(block, DRC_PC, DRC_PC, 4);
}
else
{
extra_s = imm_1 & 0x3fff;
if (imm_1 & 0x4000)
extra_s |= 0xffffc000;
UML_MOV(block, mem(&m_instruction_length), (2<<19));
UML_ADD(block, DRC_PC, DRC_PC, 2);
}
UML_MOV(block, I1, extra_s);
generate_check_delay_pc(block);
const uint32_t src_code = op & 0xf;
uint32_t dst_code = (op & 0xf0) >> 4;
if (!dst_code)
dst_code = 16;
UML_ROLAND(block, I3, DRC_SR, 7, 0x7f);
if (SRC_GLOBAL)
{
if (src_code == SR_REGISTER)
UML_MOV(block, I2, 0);
else
UML_LOAD(block, I2, (void *)m_global_regs, src_code, SIZE_DWORD, SCALE_x4);
}
else
{
UML_ADD(block, I4, I3, src_code);
UML_AND(block, I5, I4, 0x3f);
UML_LOAD(block, I2, (void *)m_local_regs, I5, SIZE_DWORD, SCALE_x4);
}
UML_AND(block, I4, DRC_PC, ~1);
UML_ROLINS(block, I4, DRC_SR, 32-S_SHIFT, 1);
UML_ADD(block, I1, I3, dst_code);
UML_AND(block, I6, I1, 0x3f);
UML_STORE(block, (void *)m_local_regs, I6, I4, SIZE_DWORD, SCALE_x4);
UML_ADD(block, I4, I6, 1);
UML_AND(block, I5, I4, 0x3f);
UML_STORE(block, (void *)m_local_regs, I5, DRC_SR, SIZE_DWORD, SCALE_x4);
UML_ROLINS(block, DRC_SR, I1, 25, 0xfe000000);
UML_ROLINS(block, DRC_SR, 6, 21, 0x01e00000);
UML_AND(block, DRC_SR, DRC_SR, ~M_MASK);
UML_ADD(block, DRC_PC, I2, extra_s & ~1);
UML_MOV(block, mem(&m_intblock), 2);
//TODO: add interrupt locks, errors, ....
}
void hyperstone_device::generate_call_local(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
{
}
void hyperstone_device::generate_trap_op(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)

View File

@ -1584,167 +1584,84 @@ void hyperstone_device::hyperstone_ldxx1()
const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
const uint32_t dreg = ((DST_GLOBAL && dst_code == SR_REGISTER) ? 0 : (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]);
if (DST_GLOBAL && dst_code == SR_REGISTER)
switch (sub_type)
{
switch (sub_type)
{
case 0: // LDBS.A
if (SRC_GLOBAL)
set_global_register(src_code, (int32_t)(int8_t)READ_B(extra_s));
else
m_local_regs[src_code] = (int32_t)(int8_t)READ_B(extra_s);
break;
case 0: // LDBS.D
if (SRC_GLOBAL)
set_global_register(src_code, (int32_t)(int8_t)READ_B(dreg + extra_s));
else
m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg + extra_s);
break;
case 1: // LDBU.A
if (SRC_GLOBAL)
m_global_regs[src_code] = READ_B(extra_s);
else
m_local_regs[src_code] = READ_B(extra_s);
break;
case 1: // LDBU.D
if (SRC_GLOBAL)
set_global_register(src_code, READ_B(dreg + extra_s));
else
m_local_regs[src_code] = READ_B(dreg + extra_s);
break;
case 2:
if (SRC_GLOBAL)
{
if (extra_s & 1) // LDHS.A
set_global_register(src_code, (int32_t)(int16_t)READ_HW(extra_s));
else // LDHU.A
set_global_register(src_code, READ_HW(extra_s));
}
case 2:
if (SRC_GLOBAL)
{
if (extra_s & 1)
set_global_register(src_code, (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1)));
else
{
if (extra_s & 1) // LDHS.A
m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(extra_s);
else // LDHU.A
m_local_regs[src_code] = READ_HW(extra_s);
}
break;
case 3:
switch (extra_s & 3)
{
case 0: // LDW.A
if (SRC_GLOBAL)
set_global_register(src_code, READ_W(extra_s));
else
m_local_regs[src_code] = READ_W(extra_s);
break;
case 1: // LDD.A
if (SRC_GLOBAL)
{
set_global_register(src_code, READ_W(extra_s));
set_global_register(srcf_code, READ_W(extra_s + 4));
}
else
{
m_local_regs[src_code] = READ_W(extra_s);
m_local_regs[srcf_code] = READ_W(extra_s + 4);
}
m_icount -= m_clock_cycles_1; // extra cycle
break;
case 2: // LDW.IOA
if (SRC_GLOBAL)
set_global_register(src_code, IO_READ_W(extra_s));
else
m_local_regs[src_code] = IO_READ_W(extra_s);
break;
case 3: // LDD.IOA
if (SRC_GLOBAL)
{
set_global_register(src_code, IO_READ_W(extra_s));
set_global_register(srcf_code, IO_READ_W(extra_s + 4));
}
else
{
m_local_regs[src_code] = IO_READ_W(extra_s);
m_local_regs[srcf_code] = IO_READ_W(extra_s + 4);
}
m_icount -= m_clock_cycles_1; // extra cycle
break;
}
break;
}
}
else
{
const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code];
switch (sub_type)
{
case 0: // LDBS.D
if (SRC_GLOBAL)
set_global_register(src_code, (int32_t)(int8_t)READ_B(dreg + extra_s));
set_global_register(src_code, READ_HW(dreg + (extra_s & ~1)));
}
else
{
if (extra_s & 1)
m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1));
else
m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg + extra_s);
break;
m_local_regs[src_code] = READ_HW(dreg + (extra_s & ~1));
}
break;
case 1: // LDBU.D
if (SRC_GLOBAL)
set_global_register(src_code, READ_B(dreg + extra_s));
else
m_local_regs[src_code] = READ_B(dreg + extra_s);
break;
case 2:
if (SRC_GLOBAL)
{
if (extra_s & 1)
set_global_register(src_code, (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1)));
case 3:
switch (extra_s & 3)
{
case 0: // LDW.D
if (SRC_GLOBAL)
set_global_register(src_code, READ_W(dreg + extra_s));
else
set_global_register(src_code, READ_HW(dreg + (extra_s & ~1)));
}
else
{
if (extra_s & 1)
m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1));
m_local_regs[src_code] = READ_W(dreg + extra_s);
break;
case 1: // LDD.D
if (SRC_GLOBAL)
{
set_global_register(src_code, READ_W(dreg + (extra_s & ~1)));
set_global_register(srcf_code, READ_W(dreg + (extra_s & ~1) + 4));
}
else
m_local_regs[src_code] = READ_HW(dreg + (extra_s & ~1));
}
break;
case 3:
switch (extra_s & 3)
{
case 0: // LDW.D
if (SRC_GLOBAL)
set_global_register(src_code, READ_W(dreg + extra_s));
else
m_local_regs[src_code] = READ_W(dreg + extra_s);
break;
case 1: // LDD.D
if (SRC_GLOBAL)
{
set_global_register(src_code, READ_W(dreg + (extra_s & ~1)));
set_global_register(srcf_code, READ_W(dreg + (extra_s & ~1) + 4));
}
else
{
m_local_regs[src_code] = READ_W(dreg + (extra_s & ~1));
m_local_regs[srcf_code] = READ_W(dreg + (extra_s & ~1) + 4);
}
m_icount -= m_clock_cycles_1; // extra cycle
break;
case 2: // LDW.IOD
if (SRC_GLOBAL)
set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3)));
else
m_local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3));
break;
case 3: // LDD.IOD
if (SRC_GLOBAL)
{
set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3)));
set_global_register(srcf_code, IO_READ_W(dreg + (extra_s & ~3) + 4));
}
else
{
m_local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3));
m_local_regs[srcf_code] = IO_READ_W(dreg + (extra_s & ~3) + 4);
}
m_icount -= m_clock_cycles_1; // extra cycle
break;
}
break;
}
{
m_local_regs[src_code] = READ_W(dreg + (extra_s & ~1));
m_local_regs[srcf_code] = READ_W(dreg + (extra_s & ~1) + 4);
}
m_icount -= m_clock_cycles_1; // extra cycle
break;
case 2: // LDW.IOD
if (SRC_GLOBAL)
set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3)));
else
m_local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3));
break;
case 3: // LDD.IOD
if (SRC_GLOBAL)
{
set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3)));
set_global_register(srcf_code, IO_READ_W(dreg + (extra_s & ~3) + 4));
}
else
{
m_local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3));
m_local_regs[srcf_code] = IO_READ_W(dreg + (extra_s & ~3) + 4);
}
m_icount -= m_clock_cycles_1; // extra cycle
break;
}
break;
}
m_icount -= m_clock_cycles_1;
@ -1930,110 +1847,56 @@ void hyperstone_device::hyperstone_stxx1()
const uint32_t fp = GET_FP;
const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f);
const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code];
const uint32_t dreg = ((DST_GLOBAL && dst_code == SR_REGISTER) ? 0 : (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]);
const uint32_t sreg = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]);
if (DST_GLOBAL && dst_code == SR_REGISTER)
switch (sub_type)
{
switch (sub_type)
{
case 0: // STBS.A
// TODO: missing trap on range error
WRITE_B(extra_s, (uint8_t)sreg);
break;
case 0: // STBS.D
// TODO: missing trap on range error
WRITE_B(dreg + extra_s, (uint8_t)sreg);
break;
case 1: // STBU.A
WRITE_B(extra_s, (uint8_t)sreg);
break;
case 1: // STBU.D
WRITE_B(dreg + extra_s, (uint8_t)sreg);
break;
case 2: // STHS.A, STHU.A
WRITE_HW(extra_s, (uint16_t)sreg);
// TODO: missing trap on range error with STHS.A
break;
case 2: // STHS.D, STHU.D
WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg);
// TODO: missing trap on range error with STHS.D
break;
case 3:
switch (extra_s & 3)
case 3:
switch (extra_s & 3)
{
case 0: // STW.D
WRITE_W(dreg + (extra_s & ~1), sreg);
break;
case 1: // STD.D
{
case 0: // STW.A
WRITE_W(extra_s & ~1, sreg);
break;
case 1: // STD.A
{
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
extra_s &= ~1;
WRITE_W(extra_s, sreg);
WRITE_W(extra_s + 4, sregf);
m_icount -= m_clock_cycles_1; // extra cycle
break;
}
case 2: // STW.IOA
IO_WRITE_W(extra_s & ~3, sreg);
break;
case 3: // STD.IOA
{
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
extra_s &= ~3;
IO_WRITE_W(extra_s, sreg);
IO_WRITE_W(extra_s + 4, sregf);
m_icount -= m_clock_cycles_1; // extra cycle
break;
}
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
extra_s &= ~1;
WRITE_W(dreg + extra_s, sreg);
WRITE_W(dreg + extra_s + 4, sregf);
m_icount -= m_clock_cycles_1; // extra cycle
break;
}
break;
}
}
else
{
switch (sub_type)
{
case 0: // STBS.D
// TODO: missing trap on range error
WRITE_B(dreg + extra_s, (uint8_t)sreg);
break;
case 1: // STBU.D
WRITE_B(dreg + extra_s, (uint8_t)sreg);
break;
case 2: // STHS.D, STHU.D
WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg);
// TODO: missing trap on range error with STHS.D
break;
case 3:
switch (extra_s & 3)
case 2: // STW.IOD
IO_WRITE_W(dreg + (extra_s & ~3), sreg);
break;
case 3: // STD.IOD
{
case 0: // STW.D
WRITE_W(dreg + (extra_s & ~1), sreg);
break;
case 1: // STD.D
{
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
extra_s &= ~1;
WRITE_W(dreg + extra_s, sreg);
WRITE_W(dreg + extra_s + 4, sregf);
m_icount -= m_clock_cycles_1; // extra cycle
break;
}
case 2: // STW.IOD
IO_WRITE_W(dreg + (extra_s & ~3), sreg);
break;
case 3: // STD.IOD
{
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
extra_s &= ~3;
IO_WRITE_W(dreg + extra_s, sreg);
IO_WRITE_W(dreg + extra_s + 4, sregf);
m_icount -= m_clock_cycles_1; // extra cycle
break;
}
const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f);
const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]);
extra_s &= ~3;
IO_WRITE_W(dreg + extra_s, sreg);
IO_WRITE_W(dreg + extra_s + 4, sregf);
m_icount -= m_clock_cycles_1; // extra cycle
break;
}
break;
}
}
break;
}
m_icount -= m_clock_cycles_1;