arcompact - start to add the hardware loop support (nw)

This commit is contained in:
mamehaze 2014-12-26 23:42:10 +00:00
parent 6216b82a84
commit 3b35928395
6 changed files with 80 additions and 77 deletions

View File

@ -63,6 +63,8 @@ void arcompact_device::device_start()
state_add( 0, "PC", m_debugger_temp).callimport().callexport().formatstr("%08X");
state_add( 0x10, "STATUS32", m_debugger_temp).callimport().callexport().formatstr("%08X");
state_add( 0x11, "LP_START", m_debugger_temp).callimport().callexport().formatstr("%08X");
state_add( 0x12, "LP_END", m_debugger_temp).callimport().callexport().formatstr("%08X");
state_add(STATE_GENPC, "GENPC", m_debugger_temp).callexport().noshow();
@ -88,6 +90,12 @@ void arcompact_device::state_export(const device_state_entry &entry)
case 0x10:
m_debugger_temp = m_status32;
break;
case 0x11:
m_debugger_temp = m_LP_START;
break;
case 0x12:
m_debugger_temp = m_LP_END;
break;
case STATE_GENPC:
m_debugger_temp = m_pc;
@ -116,6 +124,12 @@ void arcompact_device::state_import(const device_state_entry &entry)
case 0x10:
m_status32 = m_debugger_temp;
break;
case 0x11:
m_LP_START = m_debugger_temp;
break;
case 0x12:
m_LP_END = m_debugger_temp;
break;
default:
if ((index >= 0x100) && (index < 0x140))
@ -137,6 +151,9 @@ void arcompact_device::device_reset()
m_regs[i] = 0;
m_status32 = 0;
m_LP_START = 0;
m_LP_END = 0;
}
/*****************************************************************************/

View File

@ -186,7 +186,7 @@ protected:
ARCOMPACT_RETTYPE arcompact_handle04_2b(OPS_32);
ARCOMPACT_RETTYPE arcompact_handle04_2f_00(OPS_32);
ARCOMPACT_RETTYPE arcompact_handle04_2f_01(OPS_32);
ARCOMPACT_RETTYPE arcompact_handle04_2f_02(OPS_32);
// ARCOMPACT_RETTYPE arcompact_handle04_2f_02(OPS_32);
ARCOMPACT_RETTYPE arcompact_handle04_2f_03(OPS_32);
ARCOMPACT_RETTYPE arcompact_handle04_2f_04(OPS_32);
ARCOMPACT_RETTYPE arcompact_handle04_2f_05(OPS_32);
@ -778,6 +778,7 @@ protected:
ARCOMPACT_HANDLER04_TYPE_PM(04_16);
ARCOMPACT_HANDLER04_TYPE_PM(04_20);
ARCOMPACT_HANDLER04_TYPE_PM(04_2f_02);
ARCOMPACT_HANDLER04_TYPE_PM(04_2f_07);
ARCOMPACT_HANDLER04_TYPE_PM(04_2f_08);
@ -815,6 +816,10 @@ private:
// f e d c| b a 9 8| 7 6 5 4| 3 2 1 0
// - - - L| Z N C V| U DE AE A2|A1 E2 E1 H
UINT32 m_status32;
UINT32 m_LP_START;
UINT32 m_LP_END;
};
#define V_OVERFLOW_FLAG (0x00000100)
@ -845,6 +850,7 @@ private:
// Condition 0x0c (LE)
#define CONDITION_LE ((STATUS32_CHECK_Z) || (STATUS32_CHECK_N && !STATUS32_CHECK_V) || (!STATUS32_CHECK_N && STATUS32_CHECK_V)) // Z or (N and /V) or (/N and V)
#define CONDITION_EQ (STATUS32_CHECK_Z)
#define CONDITION_CS (STATUS32_CHECK_C)
extern const device_type ARCA5;

View File

@ -19,3 +19,4 @@ extern const char *opcodes_04[0x40];
#define REG_SP (0x1c) // r28
#define REG_ILINK1 (0x1d) // r29
#define REG_ILINK2 (0x1e) // r30
#define REG_LP_COUNT (0x3c) // r60

View File

@ -36,6 +36,17 @@ void arcompact_device::execute_run()
m_pc = get_insruction(op);
}
// hardware loops
if (m_pc == m_LP_END)
{
if (m_regs[REG_LP_COUNT] != 1)
{
m_pc = m_LP_START;
}
m_regs[REG_LP_COUNT]--;
}
m_icount--;
}
@ -138,7 +149,7 @@ int arcompact_device::check_condition(UINT8 condition)
case 0x02: return !CONDITION_EQ; // NE
case 0x03: fatalerror("unhandled condition check %s", conditions[condition]); return -1;
case 0x04: fatalerror("unhandled condition check %s", conditions[condition]); return -1;
case 0x05: fatalerror("unhandled condition check %s", conditions[condition]); return -1;
case 0x05: return CONDITION_CS; // CS (Carry Set / Lower than)
case 0x06: fatalerror("unhandled condition check %s", conditions[condition]); return -1;
case 0x07: fatalerror("unhandled condition check %s", conditions[condition]); return -1;
case 0x08: fatalerror("unhandled condition check %s", conditions[condition]); return -1;
@ -2054,23 +2065,46 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_23(OPS_32)
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_28(OPS_32) // LPcc (loop setup)
{
int size = 4;
// COMMON32_GET_breg; // breg is reserved
COMMON32_GET_p;
if (p == 0x00)
{
arcompact_fatal("<illegal LPcc, p = 0x00)");
}
else if (p == 0x01)
{
arcompact_fatal("<illegal LPcc, p = 0x01)");
}
else if (p == 0x02) // Loop unconditional
{
{ // 0010 0RRR 1010 1000 0RRR ssss ssSS SSSS
COMMON32_GET_s12
if (S & 0x800) S = -0x800 + (S&0x7ff);
arcompact_fatal("Lp unconditional not supported %d", S);
}
else if (p == 0x03) // Loop conditional
{ // 0010 0RRR 1110 1000 0RRR uuuu uu1Q QQQQ
COMMON32_GET_u6
COMMON32_GET_CONDITION
//arcompact_fatal("Lp conditional %s not supported %d", conditions[condition], u);
// if the loop condition fails then just jump to after the end of the loop, don't set any registers
if (!check_condition(condition))
{
UINT32 realoffset = PC_ALIGNED32 + (u * 2);
return realoffset;
}
else
{
// otherwise set up the loop positions
m_LP_START = m_pc + (size >> 0);
m_LP_END = PC_ALIGNED32 + (u * 2);
return m_pc + (size>>0);
}
}
arcompact_log("unimplemented LPcc %08x", op);
return m_pc + (size>>0);
}
@ -2211,83 +2245,16 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_helper(OPS_32, const c
}
#define SETUP_HANDLE04_2f_0x_P00 \
int size = 4; \
UINT32 limm = 0; \
\
COMMON32_GET_breg; \
COMMON32_GET_F; \
COMMON32_GET_creg; \
\
UINT32 c; \
\
if (creg == LIMM_REG) \
{ \
GET_LIMM_32; \
size = 8; \
c = limm; \
} \
else \
{ \
c = m_regs[creg]; \
} \
/* todo: is the limm, limm syntax valid? (it's pointless.) */ \
/* todo: if breg = LIMM then there is no result (but since that register can never be read, I guess it doesn't matter if we store it there anyway?) */ \
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_00(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "ASL"); } // ASL
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_01(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "ASR"); } // ASR
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_02(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "LSR"); } // LSR
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_03(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "ROR"); } // ROR
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_04(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "RCC"); } // RCC
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_05(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "SEXB"); } // SEXB
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_06(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "SEXW"); } // SEXW
// EXTW b <- c or EXTW b <- limm or EXTW limm <- c (no result) or EXTW limm, limm (invalid?)
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_08_p00(OPS_32) // note 'b' destination for 04_2f_08_xx group
{
SETUP_HANDLE04_2f_0x_P00;
m_regs[breg] = c & 0x0000ffff;
if (F)
{
arcompact_fatal("arcompact_handle04_2f_08_p00 (EXTW) (F set)\n"); // not yet supported
}
return m_pc + (size >> 0);
}
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_08_p01(OPS_32)
{
int size = 4;
arcompact_fatal("arcompact_handle04_2f_08_p01 (EXTW)\n");
return m_pc + (size >> 0);
}
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_08_p10(OPS_32)
{
int size = 4;
arcompact_fatal("illegal 04_2f_08_p10 (EXTW)\n"); // illegal mode because 'S' bits have already been used for opcode select
return m_pc + (size >> 0);
}
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_08_p11_m0(OPS_32)
{
int size = 4;
arcompact_fatal("arcompact_handle04_2f_08_p11_m0 (EXTW)\n"); // illegal mode because 'Q' bits have already been used for opcode select
return m_pc + (size >> 0);
}
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_08_p11_m1(OPS_32)
{
int size = 4;
arcompact_fatal("arcompact_handle04_2f_08_p11_m1 (EXTW)\n"); // illegal mode because 'Q' bits have already been used for opcode select
return m_pc + (size >> 0);
}
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_09(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "ABS"); } // ABS
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_0a(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "NOT"); } // NOT
ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_0b(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "RCL"); } // RLC

View File

@ -9,6 +9,16 @@ def EmitGroup04_Handle_NZ_Flags(f, funcname, opname):
print >>f, " if (result == 0x00000000) { STATUS32_SET_Z; }"
print >>f, " else { STATUS32_CLEAR_Z; }"
def EmitGroup04_Handle_NZC_LSR1_Flags(f, funcname, opname):
print >>f, " if (result & 0x80000000) { STATUS32_SET_N; }"
print >>f, " else { STATUS32_CLEAR_N; }"
print >>f, " if (result == 0x00000000) { STATUS32_SET_Z; }"
print >>f, " else { STATUS32_CLEAR_Z; }"
print >>f, " if (c == 0x00000001) { STATUS32_SET_C; }"
print >>f, " else { STATUS32_CLEAR_C; }"
def EmitGroup04_no_Flags(f, funcname, opname):
print >>f, " // no flag changes"
@ -289,7 +299,9 @@ EmitGroup04(f, "05_00", "ASL", "UINT32 result = b << (c&0x1f);", "m_regs[areg] =
EmitGroup04(f, "05_01", "LSR", "UINT32 result = b >> (c&0x1f);", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags )
# the 04_2f subgroup uses the same encoding, but the areg is already used as sub-opcode select, so any modes relying on areg bits for other reasons (sign, condition) (modes 10, 11m0, 11m1) are illegal. the destination is also breg not areg
EmitGroup04(f, "04_2f_07", "EXTB", "UINT32 result = c & 0x000000ff;", "m_regs[breg] = result;","", 2,1, -1, EmitGroup04_unsupported_Flags ) # no alt handler (invalid path)
EmitGroup04(f, "04_2f_02", "LSR1", "UINT32 result = c >> 1;", "m_regs[breg] = result;","", 2,1, -1, EmitGroup04_Handle_NZC_LSR1_Flags ) # no alt handler (invalid path)
EmitGroup04(f, "04_2f_07", "EXTB", "UINT32 result = c & 0x000000ff;", "m_regs[breg] = result;","", 2,1, -1, EmitGroup04_unsupported_Flags ) # ^
EmitGroup04(f, "04_2f_08", "EXTW", "UINT32 result = c & 0x0000ffff;", "m_regs[breg] = result;","", 2,1, -1, EmitGroup04_unsupported_Flags ) # ^
# xxx_S b, b, u5 format opcodes

View File

@ -887,7 +887,7 @@ int arcompact_handle04_28_dasm(DASM_OPS_32) // LPcc (loop setup)
{ // 0010 0RRR 1110 1000 0RRR uuuu uu1Q QQQQ
COMMON32_GET_u6
COMMON32_GET_CONDITION
output += sprintf(output, "LP<%s> (start %08x, end %08x)", conditions[condition], pc + 4, pc + u*2);
output += sprintf(output, "LP<%s> (start %08x, end %08x)", conditions[condition], pc + 4, PC_ALIGNED32 + u*2);
int unused = (op & 0x00000020)>>5;
if (unused==0) output += sprintf(output, "(unused bit not set)");