summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/sh/sh4.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/sh/sh4.cpp')
-rw-r--r--src/devices/cpu/sh/sh4.cpp5054
1 files changed, 2110 insertions, 2944 deletions
diff --git a/src/devices/cpu/sh/sh4.cpp b/src/devices/cpu/sh/sh4.cpp
index cc7c333d9cc..a2e90e1fd5a 100644
--- a/src/devices/cpu/sh/sh4.cpp
+++ b/src/devices/cpu/sh/sh4.cpp
@@ -34,25 +34,6 @@
#include "debugger.h"
-#if SH4_USE_FASTRAM_OPTIMIZATION
-void sh34_base_device::add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base)
-{
- if (m_fastram_select < ARRAY_LENGTH(m_fastram))
- {
- m_fastram[m_fastram_select].start = start;
- m_fastram[m_fastram_select].end = end;
- m_fastram[m_fastram_select].readonly = readonly;
- m_fastram[m_fastram_select].base = base;
- m_fastram_select++;
- }
-}
-#else
-void sh34_base_device::add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base)
-{
-}
-#endif
-
-
CPU_DISASSEMBLE( sh4 );
CPU_DISASSEMBLE( sh4be );
@@ -92,7 +73,7 @@ ADDRESS_MAP_END
sh34_base_device::sh34_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness, address_map_constructor internal)
- : cpu_device(mconfig, type, tag, owner, clock)
+ : sh_common_execution(mconfig, type, tag, owner, clock, endianness, internal)
, m_program_config("program", endianness, 64, 32, 0, internal)
, m_io_config("io", endianness, 64, 8)
, c_md2(0)
@@ -106,17 +87,8 @@ sh34_base_device::sh34_base_device(const machine_config &mconfig, device_type ty
, c_md8(0)
, c_clock(0)
, m_mmuhack(1)
-#if SH4_USE_FASTRAM_OPTIMIZATION
, m_bigendian(endianness == ENDIANNESS_BIG)
- , m_byte_xor(m_bigendian ? BYTE8_XOR_BE(0) : BYTE8_XOR_LE(0))
- , m_word_xor(m_bigendian ? WORD2_XOR_BE(0) : WORD2_XOR_LE(0))
- , m_dword_xor(m_bigendian ? DWORD_XOR_BE(0) : DWORD_XOR_LE(0))
- , m_fastram_select(0)
-#endif
{
-#if SH4_USE_FASTRAM_OPTIMIZATION
- memset(m_fastram, 0, sizeof(m_fastram));
-#endif
}
device_memory_interface::space_config_vector sh34_base_device::memory_space_config() const
@@ -132,6 +104,7 @@ sh3_base_device::sh3_base_device(const machine_config &mconfig, device_type type
: sh34_base_device(mconfig, type, tag, owner, clock, endianness, ADDRESS_MAP_NAME(sh3_internal_map))
{
m_cpu_type = CPU_TYPE_SH3;
+ m_am = SH34_AM;
}
@@ -139,30 +112,35 @@ sh4_base_device::sh4_base_device(const machine_config &mconfig, device_type type
: sh34_base_device(mconfig, type, tag, owner, clock, endianness, ADDRESS_MAP_NAME(sh4_internal_map))
{
m_cpu_type = CPU_TYPE_SH4;
+ m_am = SH34_AM;
}
sh3_device::sh3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: sh3_base_device(mconfig, SH3LE, tag, owner, clock, ENDIANNESS_LITTLE)
{
+ m_xor = 1;
}
sh3be_device::sh3be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: sh3_base_device(mconfig, SH3BE, tag, owner, clock, ENDIANNESS_BIG)
{
+ m_xor = 2;
}
sh4_device::sh4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: sh4_base_device(mconfig, SH4LE, tag, owner, clock, ENDIANNESS_LITTLE)
{
+ m_xor = 1;
}
sh4be_device::sh4be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: sh4_base_device(mconfig, SH4BE, tag, owner, clock, ENDIANNESS_BIG)
{
+ m_xor = 2;
}
@@ -207,20 +185,20 @@ void sh4_base_device::LDTLB(const uint16_t opcode)
logerror("using LDTLB to replace UTLB entry %02x\n", replace);
// these come from PTEH
- m_utlb[replace].VPN = (m_m[PTEH] & 0xfffffc00) >> 10;
-// m_utlb[replace].D = (m_m[PTEH] & 0x00000200) >> 9; // from PTEL
-// m_utlb[replace].V = (m_m[PTEH] & 0x00000100) >> 8; // from PTEL
+ m_utlb[replace].VPN = (m_m[PTEH] & 0xfffffc00) >> 10;
+ // m_utlb[replace].D = (m_m[PTEH] & 0x00000200) >> 9; // from PTEL
+ // m_utlb[replace].V = (m_m[PTEH] & 0x00000100) >> 8; // from PTEL
m_utlb[replace].ASID = (m_m[PTEH] & 0x000000ff) >> 0;
// these come from PTEL
m_utlb[replace].PPN = (m_m[PTEL] & 0x1ffffc00) >> 10;
- m_utlb[replace].V = (m_m[PTEL] & 0x00000100) >> 8;
+ m_utlb[replace].V = (m_m[PTEL] & 0x00000100) >> 8;
m_utlb[replace].PSZ = (m_m[PTEL] & 0x00000080) >> 6;
- m_utlb[replace].PSZ |=(m_m[PTEL] & 0x00000010) >> 4;
- m_utlb[replace].PPR= (m_m[PTEL] & 0x00000060) >> 5;
- m_utlb[replace].C = (m_m[PTEL] & 0x00000008) >> 3;
- m_utlb[replace].D = (m_m[PTEL] & 0x00000004) >> 2;
- m_utlb[replace].SH = (m_m[PTEL] & 0x00000002) >> 1;
- m_utlb[replace].WT = (m_m[PTEL] & 0x00000001) >> 0;
+ m_utlb[replace].PSZ |= (m_m[PTEL] & 0x00000010) >> 4;
+ m_utlb[replace].PPR = (m_m[PTEL] & 0x00000060) >> 5;
+ m_utlb[replace].C = (m_m[PTEL] & 0x00000008) >> 3;
+ m_utlb[replace].D = (m_m[PTEL] & 0x00000004) >> 2;
+ m_utlb[replace].SH = (m_m[PTEL] & 0x00000002) >> 1;
+ m_utlb[replace].WT = (m_m[PTEL] & 0x00000001) >> 0;
// these come from PTEA
m_utlb[replace].TC = (m_m[PTEA] & 0x00000008) >> 3;
m_utlb[replace].SA = (m_m[PTEA] & 0x00000007) >> 0;
@@ -229,22 +207,22 @@ void sh4_base_device::LDTLB(const uint16_t opcode)
#if 0
int sign_of(int n)
{
- return(m_fr[n]>>31);
+ return(m_fr[n] >> 31);
}
-void zero(int n,int sign)
+void zero(int n, int sign)
{
-if (sign == 0)
- m_fr[n] = 0x00000000;
-else
- m_fr[n] = 0x80000000;
-if ((m_fpscr & PR) == 1)
- m_fr[n+1] = 0x00000000;
+ if (sign == 0)
+ m_fr[n] = 0x00000000;
+ else
+ m_fr[n] = 0x80000000;
+ if ((m_fpscr & PR) == 1)
+ m_fr[n + 1] = 0x00000000;
}
int data_type_of(int n)
{
-uint32_t abs;
+ uint32_t abs;
abs = m_fr[n] & 0x7fffffff;
if ((m_fpscr & PR) == 0) { /* Single-precision */
@@ -253,13 +231,16 @@ uint32_t abs;
if (sign_of(n) == 0) {
zero(n, 0);
return(SH4_FPU_PZERO);
- } else {
+ }
+ else {
zero(n, 1);
return(SH4_FPU_NZERO);
}
- } else
+ }
+ else
return(SH4_FPU_DENORM);
- } else
+ }
+ else
if (abs < 0x7f800000)
return(SH4_FPU_NORM);
else
@@ -268,33 +249,39 @@ uint32_t abs;
return(SH4_FPU_PINF);
else
return(SH4_FPU_NINF);
- } else
+ }
+ else
if (abs < 0x7fc00000)
return(SH4_FPU_qNaN);
else
return(SH4_FPU_sNaN);
- } else { /* Double-precision */
+ }
+ else { /* Double-precision */
if (abs < 0x00100000) {
- if (((m_fpscr & DN) == 1) || ((abs == 0x00000000) && (m_fr[n+1] == 0x00000000))) {
- if(sign_of(n) == 0) {
+ if (((m_fpscr & DN) == 1) || ((abs == 0x00000000) && (m_fr[n + 1] == 0x00000000))) {
+ if (sign_of(n) == 0) {
zero(n, 0);
return(SH4_FPU_PZERO);
- } else {
+ }
+ else {
zero(n, 1);
return(SH4_FPU_NZERO);
}
- } else
+ }
+ else
return(SH4_FPU_DENORM);
- } else
+ }
+ else
if (abs < 0x7ff00000)
return(SH4_FPU_NORM);
else
- if ((abs == 0x7ff00000) && (m_fr[n+1] == 0x00000000)) {
+ if ((abs == 0x7ff00000) && (m_fr[n + 1] == 0x00000000)) {
if (sign_of(n) == 0)
return(SH4_FPU_PINF);
else
return(SH4_FPU_NINF);
- } else
+ }
+ else
if (abs < 0x7ff80000)
return(SH4_FPU_qNaN);
else
@@ -311,35 +298,20 @@ inline uint8_t sh34_base_device::RB(offs_t A)
if (A >= 0x80000000) // P1/P2/P3 region
{
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
- {
- if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
- {
- continue;
- }
- uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- return fastbase[_A ^ m_byte_xor];
- }
- return m_program->read_byte(_A);
-#else
- return m_program->read_byte(A & AM);
-#endif
+ return m_program->read_byte(A & SH34_AM);
}
else // P0 region
{
if (!m_sh4_mmu_enabled)
{
- return m_program->read_byte(A & AM);
+ return m_program->read_byte(A & SH34_AM);
}
else
{
- A = get_remap(A & AM);
+ A = get_remap(A & SH34_AM);
return m_program->read_byte(A);
}
}
-
}
inline uint16_t sh34_base_device::RW(offs_t A)
@@ -349,35 +321,20 @@ inline uint16_t sh34_base_device::RW(offs_t A)
if (A >= 0x80000000) // P1/P2/P3 region
{
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
- {
- if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
- {
- continue;
- }
- uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- return ((uint16_t*)fastbase)[(_A ^ m_word_xor) >> 1];
- }
- return m_program->read_word(_A);
-#else
- return m_program->read_word(A & AM);
-#endif
+ return m_program->read_word(A & SH34_AM);
}
else
{
if (!m_sh4_mmu_enabled)
{
- return m_program->read_word(A & AM);
+ return m_program->read_word(A & SH34_AM);
}
else
{
- A = get_remap(A & AM);
+ A = get_remap(A & SH34_AM);
return m_program->read_word(A);
}
}
-
}
inline uint32_t sh34_base_device::RL(offs_t A)
@@ -387,820 +344,135 @@ inline uint32_t sh34_base_device::RL(offs_t A)
if (A >= 0x80000000) // P1/P2/P3 region
{
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
- {
- if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
- {
- continue;
- }
- uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- return ((uint32_t*)fastbase)[(_A^m_dword_xor) >> 2];
- }
- return m_program->read_dword(_A);
-#else
- return m_program->read_dword(A & AM);
-#endif
+ return m_program->read_dword(A & SH34_AM);
}
else
{
if (!m_sh4_mmu_enabled)
{
- return m_program->read_dword(A & AM);
+ return m_program->read_dword(A & SH34_AM);
}
else
{
- A = get_remap(A & AM);
+ A = get_remap(A & SH34_AM);
return m_program->read_dword(A);
}
}
-
}
inline void sh34_base_device::WB(offs_t A, uint8_t V)
{
if (A >= 0xe0000000)
{
- m_program->write_byte(A,V);
+ m_program->write_byte(A, V);
return;
}
if (A >= 0x80000000) // P1/P2/P3 region
{
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
- {
- if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
- {
- continue;
- }
- uint8_t *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- fastbase[_A ^ m_byte_xor] = V;
- return;
- }
- m_program->write_byte(_A, V);
-#else
- m_program->write_byte(A & AM, V);
-#endif
+ m_program->write_byte(A & SH34_AM, V);
}
else
{
if (!m_sh4_mmu_enabled)
{
- m_program->write_byte(A & AM, V);
+ m_program->write_byte(A & SH34_AM, V);
}
else
{
- A = get_remap(A & AM);
+ A = get_remap(A & SH34_AM);
m_program->write_byte(A, V);
}
}
-
}
inline void sh34_base_device::WW(offs_t A, uint16_t V)
{
if (A >= 0xe0000000)
{
- m_program->write_word(A,V);
+ m_program->write_word(A, V);
return;
}
if (A >= 0x80000000) // P1/P2/P3 region
{
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
- {
- if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
- {
- continue;
- }
- void *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- ((uint16_t*)fastbase)[(_A ^ m_word_xor) >> 1] = V;
- return;
- }
- m_program->write_word(_A, V);
-#else
- m_program->write_word(A & AM, V);
-#endif
+ m_program->write_word(A & SH34_AM, V);
}
else
{
if (!m_sh4_mmu_enabled)
{
- m_program->write_word(A & AM, V);
+ m_program->write_word(A & SH34_AM, V);
}
else
{
- A = get_remap(A & AM);
+ A = get_remap(A & SH34_AM);
m_program->write_word(A, V);
}
}
-
}
inline void sh34_base_device::WL(offs_t A, uint32_t V)
{
if (A >= 0xe0000000)
{
- m_program->write_dword(A,V);
+ m_program->write_dword(A, V);
return;
}
if (A >= 0x80000000) // P1/P2/P3 region
{
-#if SH4_USE_FASTRAM_OPTIMIZATION
- const offs_t _A = A & AM;
- for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
- {
- if (m_fastram[ramnum].readonly == true || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end)
- {
- continue;
- }
- void *fastbase = (uint8_t*)m_fastram[ramnum].base - m_fastram[ramnum].start;
- ((uint32_t*)fastbase)[(_A ^ m_dword_xor) >> 2] = V;
- return;
- }
- m_program->write_dword(_A, V);
-#else
- m_program->write_dword(A & AM, V);
-#endif
+ m_program->write_dword(A & SH34_AM, V);
}
else
{
if (!m_sh4_mmu_enabled)
{
- m_program->write_dword(A & AM, V);
+ m_program->write_dword(A & SH34_AM, V);
}
else
{
- A = get_remap(A & AM);
+ A = get_remap(A & SH34_AM);
m_program->write_dword(A, V);
}
}
-
-}
-
-/* code cycles t-bit
- * 0011 nnnn mmmm 1100 1 -
- * ADD Rm,Rn
- */
-inline void sh34_base_device::ADD(const uint16_t opcode)
-{
- m_r[Rn] += m_r[Rm];
-}
-
-/* code cycles t-bit
- * 0111 nnnn iiii iiii 1 -
- * ADD #imm,Rn
- */
-inline void sh34_base_device::ADDI(const uint16_t opcode)
-{
- m_r[Rn] += (int32_t)(int16_t)(int8_t)(opcode&0xff);
-}
-
-/* code cycles t-bit
- * 0011 nnnn mmmm 1110 1 carry
- * ADDC Rm,Rn
- */
-inline void sh34_base_device::ADDC(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
- uint32_t tmp0, tmp1;
-
- tmp1 = m_r[n] + m_r[m];
- tmp0 = m_r[n];
- m_r[n] = tmp1 + (m_sr & T);
- if (tmp0 > tmp1)
- m_sr |= T;
- else
- m_sr &= ~T;
- if (tmp1 > m_r[n])
- m_sr |= T;
-}
-
-/* code cycles t-bit
- * 0011 nnnn mmmm 1111 1 overflow
- * ADDV Rm,Rn
- */
-inline void sh34_base_device::ADDV(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
- int32_t dest, src, ans;
-
- if ((int32_t) m_r[n] >= 0)
- dest = 0;
- else
- dest = 1;
- if ((int32_t) m_r[m] >= 0)
- src = 0;
- else
- src = 1;
- src += dest;
- m_r[n] += m_r[m];
- if ((int32_t) m_r[n] >= 0)
- ans = 0;
- else
- ans = 1;
- ans += dest;
- if (src == 0 || src == 2)
- {
- if (ans == 1)
- m_sr |= T;
- else
- m_sr &= ~T;
- }
- else
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0010 nnnn mmmm 1001 1 -
- * AND Rm,Rn
- */
-inline void sh34_base_device::AND(const uint16_t opcode)
-{
- m_r[Rn] &= m_r[Rm];
-}
-
-
-/* code cycles t-bit
- * 1100 1001 iiii iiii 1 -
- * AND #imm,R0
- */
-inline void sh34_base_device::ANDI(const uint16_t opcode)
-{
- m_r[0] &= (opcode&0xff);
-}
-
-/* code cycles t-bit
- * 1100 1101 iiii iiii 1 -
- * AND.B #imm,@(R0,GBR)
- */
-inline void sh34_base_device::ANDM(const uint16_t opcode)
-{
- uint32_t temp;
-
- m_ea = m_gbr + m_r[0];
- temp = (opcode&0xff) & RB( m_ea );
- WB(m_ea, temp );
- m_sh4_icount -= 2;
-}
-
-/* code cycles t-bit
- * 1000 1011 dddd dddd 3/1 -
- * BF disp8
- */
-inline void sh34_base_device::BF(const uint16_t opcode)
-{
- if ((m_sr & T) == 0)
- {
- int32_t disp = ((int32_t)(opcode&0xff) << 24) >> 24;
- m_pc = m_ea = m_pc + disp * 2 + 2;
- m_sh4_icount -= 2;
- }
-}
-
-/* code cycles t-bit
- * 1000 1111 dddd dddd 3/1 -
- * BFS disp8
- */
-inline void sh34_base_device::BFS(const uint16_t opcode)
-{
- if ((m_sr & T) == 0)
- {
- int32_t disp = ((int32_t)(opcode&0xff) << 24) >> 24;
- m_delay = m_ea = m_pc + disp * 2 + 2;
- m_sh4_icount--;
- }
-}
-
-/* code cycles t-bit
- * 1010 dddd dddd dddd 2 -
- * BRA disp12
- */
-inline void sh34_base_device::BRA(const uint16_t opcode)
-{
- int32_t disp = ((int32_t)(opcode&0xfff) << 20) >> 20;
-
-#if BUSY_LOOP_HACKS
- if (disp == -2)
- {
- uint32_t next_opcode = RW(m_pc & AM);
- /* BRA $
- * NOP
- */
- if (next_opcode == 0x0009)
- m_sh4_icount %= 3; /* cycles for BRA $ and NOP taken (3) */
- }
-#endif
- m_delay = m_ea = m_pc + disp * 2 + 2;
- m_sh4_icount--;
-}
-
-/* code cycles t-bit
- * 0000 mmmm 0010 0011 2 -
- * BRAF Rm
- */
-inline void sh34_base_device::BRAF(const uint16_t opcode)
-{
- m_delay = m_pc + m_r[Rn] + 2;
- m_sh4_icount--;
-}
-
-/* code cycles t-bit
- * 1011 dddd dddd dddd 2 -
- * BSR disp12
- */
-inline void sh34_base_device::BSR(const uint16_t opcode)
-{
- int32_t disp = ((int32_t)(opcode&0xfff) << 20) >> 20;
-
- m_pr = m_pc + 2;
- m_delay = m_ea = m_pc + disp * 2 + 2;
- m_sh4_icount--;
-}
-
-/* code cycles t-bit
- * 0000 mmmm 0000 0011 2 -
- * BSRF Rm
- */
-inline void sh34_base_device::BSRF(const uint16_t opcode)
-{
- m_pr = m_pc + 2;
- m_delay = m_pc + m_r[Rn] + 2;
- m_sh4_icount--;
-}
-
-/* code cycles t-bit
- * 1000 1001 dddd dddd 3/1 -
- * BT disp8
- */
-inline void sh34_base_device::BT(const uint16_t opcode)
-{
- if ((m_sr & T) != 0)
- {
- int32_t disp = ((int32_t)(opcode&0xff) << 24) >> 24;
- m_pc = m_ea = m_pc + disp * 2 + 2;
- m_sh4_icount -= 2;
- }
-}
-
-/* code cycles t-bit
- * 1000 1101 dddd dddd 2/1 -
- * BTS disp8
- */
-inline void sh34_base_device::BTS(const uint16_t opcode)
-{
- if ((m_sr & T) != 0)
- {
- int32_t disp = ((int32_t)(opcode&0xff) << 24) >> 24;
- m_delay = m_ea = m_pc + disp * 2 + 2;
- m_sh4_icount--;
- }
-}
-
-/* code cycles t-bit
- * 0000 0000 0010 1000 1 -
- * CLRMAC
- */
-inline void sh34_base_device::CLRMAC(const uint16_t opcode)
-{
- m_mach = 0;
- m_macl = 0;
-}
-
-/* code cycles t-bit
- * 0000 0000 0000 1000 1 -
- * CLRT
- */
-inline void sh34_base_device::CLRT(const uint16_t opcode)
-{
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0011 nnnn mmmm 0000 1 comparison result
- * CMP_EQ Rm,Rn
- */
-inline void sh34_base_device::CMPEQ(const uint16_t opcode)
-{
- if (m_r[Rn] == m_r[Rm])
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0011 nnnn mmmm 0011 1 comparison result
- * CMP_GE Rm,Rn
- */
-inline void sh34_base_device::CMPGE(const uint16_t opcode)
-{
- if ((int32_t) m_r[Rn] >= (int32_t) m_r[Rm])
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0011 nnnn mmmm 0111 1 comparison result
- * CMP_GT Rm,Rn
- */
-inline void sh34_base_device::CMPGT(const uint16_t opcode)
-{
- if ((int32_t) m_r[Rn] > (int32_t) m_r[Rm])
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0011 nnnn mmmm 0110 1 comparison result
- * CMP_HI Rm,Rn
- */
-inline void sh34_base_device::CMPHI(const uint16_t opcode)
-{
- if ((uint32_t) m_r[Rn] > (uint32_t) m_r[Rm])
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0011 nnnn mmmm 0010 1 comparison result
- * CMP_HS Rm,Rn
- */
-inline void sh34_base_device::CMPHS(const uint16_t opcode)
-{
- if ((uint32_t) m_r[Rn] >= (uint32_t) m_r[Rm])
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-
-/* code cycles t-bit
- * 0100 nnnn 0001 0101 1 comparison result
- * CMP_PL Rn
- */
-inline void sh34_base_device::CMPPL(const uint16_t opcode)
-{
- if ((int32_t) m_r[Rn] > 0)
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0100 nnnn 0001 0001 1 comparison result
- * CMP_PZ Rn
- */
-inline void sh34_base_device::CMPPZ(const uint16_t opcode)
-{
- if ((int32_t) m_r[Rn] >= 0)
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0010 nnnn mmmm 1100 1 comparison result
- * CMP_STR Rm,Rn
- */
-inline void sh34_base_device::CMPSTR(const uint16_t opcode)
-{
- uint32_t temp;
- int32_t HH, HL, LH, LL;
- temp = m_r[Rn] ^ m_r[Rm];
- HH = (temp >> 24) & 0xff;
- HL = (temp >> 16) & 0xff;
- LH = (temp >> 8) & 0xff;
- LL = temp & 0xff;
- if (HH && HL && LH && LL)
- m_sr &= ~T;
- else
- m_sr |= T;
- }
-
-
-/* code cycles t-bit
- * 1000 1000 iiii iiii 1 comparison result
- * CMP/EQ #imm,R0
- */
-inline void sh34_base_device::CMPIM(const uint16_t opcode)
-{
- uint32_t imm = (uint32_t)(int32_t)(int16_t)(int8_t)(opcode&0xff);
-
- if (m_r[0] == imm)
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0010 nnnn mmmm 0111 1 calculation result
- * DIV0S Rm,Rn
- */
-inline void sh34_base_device::DIV0S(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- if ((m_r[n] & 0x80000000) == 0)
- m_sr &= ~Q;
- else
- m_sr |= Q;
- if ((m_r[m] & 0x80000000) == 0)
- m_sr &= ~M;
- else
- m_sr |= M;
- if ((m_r[m] ^ m_r[n]) & 0x80000000)
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* code cycles t-bit
- * 0000 0000 0001 1001 1 0
- * DIV0U
- */
-inline void sh34_base_device::DIV0U(const uint16_t opcode)
-{
- m_sr &= ~(M | Q | T);
-}
-
-/* code cycles t-bit
- * 0011 nnnn mmmm 0100 1 calculation result
- * DIV1 Rm,Rn
- */
-inline void sh34_base_device::DIV1(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- uint32_t tmp0;
- uint32_t old_q;
-
- old_q = m_sr & Q;
- if (0x80000000 & m_r[n])
- m_sr |= Q;
- else
- m_sr &= ~Q;
-
- m_r[n] = (m_r[n] << 1) | (m_sr & T);
-
- if (!old_q)
- {
- if (!(m_sr & M))
- {
- tmp0 = m_r[n];
- m_r[n] -= m_r[m];
- if(!(m_sr & Q))
- if(m_r[n] > tmp0)
- m_sr |= Q;
- else
- m_sr &= ~Q;
- else
- if(m_r[n] > tmp0)
- m_sr &= ~Q;
- else
- m_sr |= Q;
- }
- else
- {
- tmp0 = m_r[n];
- m_r[n] += m_r[m];
- if(!(m_sr & Q))
- {
- if(m_r[n] < tmp0)
- m_sr &= ~Q;
- else
- m_sr |= Q;
- }
- else
- {
- if(m_r[n] < tmp0)
- m_sr |= Q;
- else
- m_sr &= ~Q;
- }
- }
- }
- else
- {
- if (!(m_sr & M))
- {
- tmp0 = m_r[n];
- m_r[n] += m_r[m];
- if(!(m_sr & Q))
- if(m_r[n] < tmp0)
- m_sr |= Q;
- else
- m_sr &= ~Q;
- else
- if(m_r[n] < tmp0)
- m_sr &= ~Q;
- else
- m_sr |= Q;
- }
- else
- {
- tmp0 = m_r[n];
- m_r[n] -= m_r[m];
- if(!(m_sr & Q))
- if(m_r[n] > tmp0)
- m_sr &= ~Q;
- else
- m_sr |= Q;
- else
- if(m_r[n] > tmp0)
- m_sr |= Q;
- else
- m_sr &= ~Q;
- }
- }
-
- tmp0 = (m_sr & (Q | M));
- if((!tmp0) || (tmp0 == 0x300)) /* if Q == M set T else clear T */
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* DMULS.L Rm,Rn */
-inline void sh34_base_device::DMULS(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2;
- uint32_t temp0, temp1, temp2, temp3;
- int32_t tempm, tempn, fnLmL;
-
- tempn = (int32_t) m_r[n];
- tempm = (int32_t) m_r[m];
- if (tempn < 0)
- tempn = 0 - tempn;
- if (tempm < 0)
- tempm = 0 - tempm;
- if ((int32_t) (m_r[n] ^ m_r[m]) < 0)
- fnLmL = -1;
- else
- fnLmL = 0;
- temp1 = (uint32_t) tempn;
- temp2 = (uint32_t) tempm;
- RnL = temp1 & 0x0000ffff;
- RnH = (temp1 >> 16) & 0x0000ffff;
- RmL = temp2 & 0x0000ffff;
- RmH = (temp2 >> 16) & 0x0000ffff;
- temp0 = RmL * RnL;
- temp1 = RmH * RnL;
- temp2 = RmL * RnH;
- temp3 = RmH * RnH;
- Res2 = 0;
- Res1 = temp1 + temp2;
- if (Res1 < temp1)
- Res2 += 0x00010000;
- temp1 = (Res1 << 16) & 0xffff0000;
- Res0 = temp0 + temp1;
- if (Res0 < temp0)
- Res2++;
- Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
- if (fnLmL < 0)
- {
- Res2 = ~Res2;
- if (Res0 == 0)
- Res2++;
- else
- Res0 = (~Res0) + 1;
- }
- m_mach = Res2;
- m_macl = Res0;
- m_sh4_icount--;
-}
-
-/* DMULU.L Rm,Rn */
-inline void sh34_base_device::DMULU(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2;
- uint32_t temp0, temp1, temp2, temp3;
-
- RnL = m_r[n] & 0x0000ffff;
- RnH = (m_r[n] >> 16) & 0x0000ffff;
- RmL = m_r[m] & 0x0000ffff;
- RmH = (m_r[m] >> 16) & 0x0000ffff;
- temp0 = RmL * RnL;
- temp1 = RmH * RnL;
- temp2 = RmL * RnH;
- temp3 = RmH * RnH;
- Res2 = 0;
- Res1 = temp1 + temp2;
- if (Res1 < temp1)
- Res2 += 0x00010000;
- temp1 = (Res1 << 16) & 0xffff0000;
- Res0 = temp0 + temp1;
- if (Res0 < temp0)
- Res2++;
- Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
- m_mach = Res2;
- m_macl = Res0;
- m_sh4_icount--;
-}
-
-/* DT Rn */
-inline void sh34_base_device::DT(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_r[n]--;
- if (m_r[n] == 0)
- m_sr |= T;
- else
- m_sr &= ~T;
-#if BUSY_LOOP_HACKS
- {
- uint32_t next_opcode = RW(m_pc & AM);
- /* DT Rn
- * BF $-2
- */
- if (next_opcode == 0x8bfd)
- {
- while (m_r[n] > 1 && m_sh4_icount > 4)
- {
- m_r[n]--;
- m_sh4_icount -= 4; /* cycles for DT (1) and BF taken (3) */
- }
- }
- }
-#endif
-}
-
-/* EXTS.B Rm,Rn */
-inline void sh34_base_device::EXTSB(const uint16_t opcode)
-{
- m_r[Rn] = ((int32_t)m_r[Rm] << 24) >> 24;
}
-/* EXTS.W Rm,Rn */
-inline void sh34_base_device::EXTSW(const uint16_t opcode)
+inline void sh34_base_device::ILLEGAL()
{
- m_r[Rn] = ((int32_t)m_r[Rm] << 16) >> 16;
+ NOP();
}
-/* EXTU.B Rm,Rn */
-inline void sh34_base_device::EXTUB(const uint16_t opcode)
-{
- m_r[Rn] = m_r[Rm] & 0x000000ff;
-}
-
-/* EXTU.W Rm,Rn */
-inline void sh34_base_device::EXTUW(const uint16_t opcode)
+/* MOVCA.L R0,@Rn */
+inline void sh34_base_device::MOVCAL(const uint16_t opcode)
{
- m_r[Rn] = m_r[Rm] & 0x0000ffff;
+ m_sh2_state->ea = m_sh2_state->r[Rn];
+ WL(m_sh2_state->ea, m_sh2_state->r[0]);
}
-/* JMP @Rm */
-inline void sh34_base_device::JMP(const uint16_t opcode)
+inline void sh34_base_device::CLRS(const uint16_t opcode)
{
- m_delay = m_ea = m_r[Rn];
+ m_sh2_state->sr &= ~SH_S;
}
-/* JSR @Rm */
-inline void sh34_base_device::JSR(const uint16_t opcode)
+inline void sh34_base_device::SETS(const uint16_t opcode)
{
- m_pr = m_pc + 2;
- m_delay = m_ea = m_r[Rn];
- m_sh4_icount--;
+ m_sh2_state->sr |= SH_S;
}
-
/* LDC Rm,SR */
inline void sh34_base_device::LDCSR(const uint16_t opcode)
{
- uint32_t reg;
-
- reg = m_r[Rn];
+ // copy current registers to banked version of current register set
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
- sh4_syncronize_register_bank((m_sr & sRB) >> 29);
- if ((m_r[Rn] & sRB) != (m_sr & sRB))
- sh4_change_register_bank(m_r[Rn] & sRB ? 1 : 0);
- m_sr = reg & FLAGS;
- sh4_exception_recompute();
-}
+ sh4_syncronize_register_bank((m_sh2_state->sr & sRB) >> 29);
-/* LDC Rm,GBR */
-inline void sh34_base_device::LDCGBR(const uint16_t opcode)
-{
- m_gbr = m_r[Rn];
-}
-
-/* LDC Rm,VBR */
-inline void sh34_base_device::LDCVBR(const uint16_t opcode)
-{
- m_vbr = m_r[Rn];
+ // if the register bank in the new differs from the one already in SR
+ if ((m_sh2_state->r[Rn] & sRB) != (m_sh2_state->sr & sRB))
+ sh4_change_register_bank(m_sh2_state->r[Rn] & sRB ? 1 : 0);
+
+ m_sh2_state->sr = m_sh2_state->r[Rn] & SH34_FLAGS;
+ sh4_exception_recompute();
}
/* LDC.L @Rm+,SR */
@@ -1208,924 +480,37 @@ inline void sh34_base_device::LDCMSR(const uint16_t opcode)
{
uint32_t old;
- old = m_sr;
- m_ea = m_r[Rn];
- m_sr = RL(m_ea ) & FLAGS;
+ old = m_sh2_state->sr;
+ m_sh2_state->ea = m_sh2_state->r[Rn];
+ m_sh2_state->sr = RL(m_sh2_state->ea) & SH34_FLAGS;
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
sh4_syncronize_register_bank((old & sRB) >> 29);
- if ((old & sRB) != (m_sr & sRB))
- sh4_change_register_bank(m_sr & sRB ? 1 : 0);
- m_r[Rn] += 4;
- m_sh4_icount -= 2;
+ if ((old & sRB) != (m_sh2_state->sr & sRB))
+ sh4_change_register_bank(m_sh2_state->sr & sRB ? 1 : 0);
+ m_sh2_state->r[Rn] += 4;
+ m_sh2_state->icount -= 2;
sh4_exception_recompute();
}
-/* LDC.L @Rm+,GBR */
-inline void sh34_base_device::LDCMGBR(const uint16_t opcode)
-{
- m_ea = m_r[Rn];
- m_gbr = RL(m_ea );
- m_r[Rn] += 4;
- m_sh4_icount -= 2;
-}
-
-/* LDC.L @Rm+,VBR */
-inline void sh34_base_device::LDCMVBR(const uint16_t opcode)
-{
- m_ea = m_r[Rn];
- m_vbr = RL(m_ea );
- m_r[Rn] += 4;
- m_sh4_icount -= 2;
-}
-
-/* LDS Rm,MACH */
-inline void sh34_base_device::LDSMACH(const uint16_t opcode)
-{
- m_mach = m_r[Rn];
-}
-
-/* LDS Rm,MACL */
-inline void sh34_base_device::LDSMACL(const uint16_t opcode)
-{
- m_macl = m_r[Rn];
-}
-
-/* LDS Rm,PR */
-inline void sh34_base_device::LDSPR(const uint16_t opcode)
-{
- m_pr = m_r[Rn];
-}
-
-/* LDS.L @Rm+,MACH */
-inline void sh34_base_device::LDSMMACH(const uint16_t opcode)
-{
- m_ea = m_r[Rn];
- m_mach = RL(m_ea );
- m_r[Rn] += 4;
-}
-
-/* LDS.L @Rm+,MACL */
-inline void sh34_base_device::LDSMMACL(const uint16_t opcode)
-{
- m_ea = m_r[Rn];
- m_macl = RL(m_ea );
- m_r[Rn] += 4;
-}
-
-/* LDS.L @Rm+,PR */
-inline void sh34_base_device::LDSMPR(const uint16_t opcode)
-{
- m_ea = m_r[Rn];
- m_pr = RL(m_ea );
- m_r[Rn] += 4;
-}
-
-/* MAC.L @Rm+,@Rn+ */
-inline void sh34_base_device::MAC_L(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- uint32_t RnL, RnH, RmL, RmH, Res0, Res1, Res2;
- uint32_t temp0, temp1, temp2, temp3;
- int32_t tempm, tempn, fnLmL;
-
- tempn = (int32_t) RL(m_r[n] );
- m_r[n] += 4;
- tempm = (int32_t) RL(m_r[m] );
- m_r[m] += 4;
- if ((int32_t) (tempn ^ tempm) < 0)
- fnLmL = -1;
- else
- fnLmL = 0;
- if (tempn < 0)
- tempn = 0 - tempn;
- if (tempm < 0)
- tempm = 0 - tempm;
- temp1 = (uint32_t) tempn;
- temp2 = (uint32_t) tempm;
- RnL = temp1 & 0x0000ffff;
- RnH = (temp1 >> 16) & 0x0000ffff;
- RmL = temp2 & 0x0000ffff;
- RmH = (temp2 >> 16) & 0x0000ffff;
- temp0 = RmL * RnL;
- temp1 = RmH * RnL;
- temp2 = RmL * RnH;
- temp3 = RmH * RnH;
- Res2 = 0;
- Res1 = temp1 + temp2;
- if (Res1 < temp1)
- Res2 += 0x00010000;
- temp1 = (Res1 << 16) & 0xffff0000;
- Res0 = temp0 + temp1;
- if (Res0 < temp0)
- Res2++;
- Res2 = Res2 + ((Res1 >> 16) & 0x0000ffff) + temp3;
- if (fnLmL < 0)
- {
- Res2 = ~Res2;
- if (Res0 == 0)
- Res2++;
- else
- Res0 = (~Res0) + 1;
- }
- if (m_sr & S)
- {
- Res0 = m_macl + Res0;
- if (m_macl > Res0)
- Res2++;
- Res2 += (m_mach & 0x0000ffff);
- if (((int32_t) Res2 < 0) && (Res2 < 0xffff8000))
- {
- Res2 = 0x00008000;
- Res0 = 0x00000000;
- }
- else if (((int32_t) Res2 > 0) && (Res2 > 0x00007fff))
- {
- Res2 = 0x00007fff;
- Res0 = 0xffffffff;
- }
- m_mach = Res2;
- m_macl = Res0;
- }
- else
- {
- Res0 = m_macl + Res0;
- if (m_macl > Res0)
- Res2++;
- Res2 += m_mach;
- m_mach = Res2;
- m_macl = Res0;
- }
- m_sh4_icount -= 2;
-}
-
-/* MAC.W @Rm+,@Rn+ */
-inline void sh34_base_device::MAC_W(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- int32_t tempm, tempn, dest, src, ans;
- uint32_t templ;
-
- tempn = (int32_t) RW(m_r[n] );
- m_r[n] += 2;
- tempm = (int32_t) RW(m_r[m] );
- m_r[m] += 2;
- templ = m_macl;
- tempm = ((int32_t) (short) tempn * (int32_t) (short) tempm);
- if ((int32_t) m_macl >= 0)
- dest = 0;
- else
- dest = 1;
- if ((int32_t) tempm >= 0)
- {
- src = 0;
- tempn = 0;
- }
- else
- {
- src = 1;
- tempn = 0xffffffff;
- }
- src += dest;
- m_macl += tempm;
- if ((int32_t) m_macl >= 0)
- ans = 0;
- else
- ans = 1;
- ans += dest;
- if (m_sr & S)
- {
- if (ans == 1)
- {
- if (src == 0)
- m_macl = 0x7fffffff;
- if (src == 2)
- m_macl = 0x80000000;
- }
- }
- else
- {
- m_mach += tempn;
- if (templ > m_macl)
- m_mach += 1;
- }
- m_sh4_icount -= 2;
-}
-
-/* MOV Rm,Rn */
-inline void sh34_base_device::MOV(const uint16_t opcode)
-{
- m_r[Rn] = m_r[Rm];
-}
-
-/* MOV.B Rm,@Rn */
-inline void sh34_base_device::MOVBS(const uint16_t opcode)
-{
- m_ea = m_r[Rn];
- WB(m_ea, m_r[Rm] & 0x000000ff);
-}
-
-/* MOV.W Rm,@Rn */
-inline void sh34_base_device::MOVWS(const uint16_t opcode)
-{
- m_ea = m_r[Rn];
- WW(m_ea, m_r[Rm] & 0x0000ffff);
-}
-
-/* MOV.L Rm,@Rn */
-inline void sh34_base_device::MOVLS(const uint16_t opcode)
-{
- m_ea = m_r[Rn];
- WL(m_ea, m_r[Rm] );
-}
-
-/* MOV.B @Rm,Rn */
-inline void sh34_base_device::MOVBL(const uint16_t opcode)
-{
- m_ea = m_r[Rm];
- m_r[Rn] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_ea );
-}
-
-/* MOV.W @Rm,Rn */
-inline void sh34_base_device::MOVWL(const uint16_t opcode)
-{
- m_ea = m_r[Rm];
- m_r[Rn] = (uint32_t)(int32_t)(int16_t) RW(m_ea );
-}
-
-/* MOV.L @Rm,Rn */
-inline void sh34_base_device::MOVLL(const uint16_t opcode)
-{
- m_ea = m_r[Rm];
- m_r[Rn] = RL(m_ea );
-}
-
-/* MOV.B Rm,@-Rn */
-inline void sh34_base_device::MOVBM(const uint16_t opcode)
-{
- uint32_t data = m_r[Rm] & 0x000000ff;
-
- m_r[Rn] -= 1;
- WB(m_r[Rn], data );
-}
-
-/* MOV.W Rm,@-Rn */
-inline void sh34_base_device::MOVWM(const uint16_t opcode)
-{
- uint32_t data = m_r[Rm] & 0x0000ffff;
-
- m_r[Rn] -= 2;
- WW(m_r[Rn], data );
-}
-
-/* MOV.L Rm,@-Rn */
-inline void sh34_base_device::MOVLM(const uint16_t opcode)
-{
- uint32_t data = m_r[Rm];
-
- m_r[Rn] -= 4;
- WL(m_r[Rn], data );
-}
-
-/* MOV.B @Rm+,Rn */
-inline void sh34_base_device::MOVBP(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- m_r[n] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_r[m] );
- if (n != m)
- m_r[m] += 1;
-}
-
-/* MOV.W @Rm+,Rn */
-inline void sh34_base_device::MOVWP(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- m_r[n] = (uint32_t)(int32_t)(int16_t) RW(m_r[m] );
- if (n != m)
- m_r[m] += 2;
-}
-
-/* MOV.L @Rm+,Rn */
-inline void sh34_base_device::MOVLP(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- m_r[n] = RL(m_r[m] );
- if (n != m)
- m_r[m] += 4;
-}
-
-/* MOV.B Rm,@(R0,Rn) */
-inline void sh34_base_device::MOVBS0(const uint16_t opcode)
-{
- m_ea = m_r[Rn] + m_r[0];
- WB(m_ea, m_r[Rm] & 0x000000ff );
-}
-
-/* MOV.W Rm,@(R0,Rn) */
-inline void sh34_base_device::MOVWS0(const uint16_t opcode)
-{
- m_ea = m_r[Rn] + m_r[0];
- WW(m_ea, m_r[Rm] & 0x0000ffff );
-}
-
-/* MOV.L Rm,@(R0,Rn) */
-inline void sh34_base_device::MOVLS0(const uint16_t opcode)
-{
- m_ea = m_r[Rn] + m_r[0];
- WL(m_ea, m_r[Rm] );
-}
-
-/* MOV.B @(R0,Rm),Rn */
-inline void sh34_base_device::MOVBL0(const uint16_t opcode)
-{
- m_ea = m_r[Rm] + m_r[0];
- m_r[Rn] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_ea );
-}
-
-/* MOV.W @(R0,Rm),Rn */
-inline void sh34_base_device::MOVWL0(const uint16_t opcode)
-{
- m_ea = m_r[Rm] + m_r[0];
- m_r[Rn] = (uint32_t)(int32_t)(int16_t) RW(m_ea );
-}
-
-/* MOV.L @(R0,Rm),Rn */
-inline void sh34_base_device::MOVLL0(const uint16_t opcode)
-{
- m_ea = m_r[Rm] + m_r[0];
- m_r[Rn] = RL(m_ea );
-}
-
-/* MOV #imm,Rn */
-inline void sh34_base_device::MOVI(const uint16_t opcode)
-{
- m_r[Rn] = (uint32_t)(int32_t)(int16_t)(int8_t)(opcode&0xff);
-}
-
-/* MOV.W @(disp8,PC),Rn */
-inline void sh34_base_device::MOVWI(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0xff;
- m_ea = m_pc + disp * 2 + 2;
- m_r[Rn] = (uint32_t)(int32_t)(int16_t) RW(m_ea );
-}
-
-/* MOV.L @(disp8,PC),Rn */
-inline void sh34_base_device::MOVLI(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0xff;
- m_ea = ((m_pc + 2) & ~3) + disp * 4;
- m_r[Rn] = RL(m_ea );
-}
-
-/* MOV.B @(disp8,GBR),R0 */
-inline void sh34_base_device::MOVBLG(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0xff;
- m_ea = m_gbr + disp;
- m_r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_ea );
-}
-
-/* MOV.W @(disp8,GBR),R0 */
-inline void sh34_base_device::MOVWLG(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0xff;
- m_ea = m_gbr + disp * 2;
- m_r[0] = (int32_t)(int16_t) RW(m_ea );
-}
-
-/* MOV.L @(disp8,GBR),R0 */
-inline void sh34_base_device::MOVLLG(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0xff;
- m_ea = m_gbr + disp * 4;
- m_r[0] = RL(m_ea );
-}
-
-/* MOV.B R0,@(disp8,GBR) */
-inline void sh34_base_device::MOVBSG(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0xff;
- m_ea = m_gbr + disp;
- WB(m_ea, m_r[0] & 0x000000ff );
-}
-
-/* MOV.W R0,@(disp8,GBR) */
-inline void sh34_base_device::MOVWSG(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0xff;
- m_ea = m_gbr + disp * 2;
- WW(m_ea, m_r[0] & 0x0000ffff );
-}
-
-/* MOV.L R0,@(disp8,GBR) */
-inline void sh34_base_device::MOVLSG(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0xff;
- m_ea = m_gbr + disp * 4;
- WL(m_ea, m_r[0] );
-}
-
-/* MOV.B R0,@(disp4,Rm) */
-inline void sh34_base_device::MOVBS4(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0x0f;
- m_ea = m_r[Rm] + disp;
- WB(m_ea, m_r[0] & 0x000000ff );
-}
-
-/* MOV.W R0,@(disp4,Rm) */
-inline void sh34_base_device::MOVWS4(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0x0f;
- m_ea = m_r[Rm] + disp * 2;
- WW(m_ea, m_r[0] & 0x0000ffff );
-}
-
-/* MOV.L Rm,@(disp4,Rn) */
-inline void sh34_base_device::MOVLS4(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0x0f;
- m_ea = m_r[Rn] + disp * 4;
- WL(m_ea, m_r[Rm] );
-}
-
-/* MOV.B @(disp4,Rm),R0 */
-inline void sh34_base_device::MOVBL4(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0x0f;
- m_ea = m_r[Rm] + disp;
- m_r[0] = (uint32_t)(int32_t)(int16_t)(int8_t) RB( m_ea );
-}
-
-/* MOV.W @(disp4,Rm),R0 */
-inline void sh34_base_device::MOVWL4(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0x0f;
- m_ea = m_r[Rm] + disp * 2;
- m_r[0] = (uint32_t)(int32_t)(int16_t) RW(m_ea );
-}
-
-/* MOV.L @(disp4,Rm),Rn */
-inline void sh34_base_device::MOVLL4(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0x0f;
- m_ea = m_r[Rm] + disp * 4;
- m_r[Rn] = RL(m_ea );
-}
-
-/* MOVA @(disp8,PC),R0 */
-inline void sh34_base_device::MOVA(const uint16_t opcode)
-{
- uint32_t disp = opcode & 0xff;
- m_ea = ((m_pc + 2) & ~3) + disp * 4;
- m_r[0] = m_ea;
-}
-
-/* MOVT Rn */
-void sh34_base_device::MOVT(const uint16_t opcode)
-{
- m_r[Rn] = m_sr & T;
-}
-
-/* MUL.L Rm,Rn */
-inline void sh34_base_device::MULL(const uint16_t opcode)
-{
- m_macl = m_r[Rn] * m_r[Rm];
- m_sh4_icount--;
-}
-
-/* MULS Rm,Rn */
-inline void sh34_base_device::MULS(const uint16_t opcode)
-{
- m_macl = (int16_t) m_r[Rn] * (int16_t) m_r[Rm];
-}
-
-/* MULU Rm,Rn */
-inline void sh34_base_device::MULU(const uint16_t opcode)
-{
- m_macl = (uint16_t) m_r[Rn] * (uint16_t) m_r[Rm];
-}
-
-/* NEG Rm,Rn */
-inline void sh34_base_device::NEG(const uint16_t opcode)
-{
- m_r[Rn] = 0 - m_r[Rm];
-}
-
-/* NEGC Rm,Rn */
-inline void sh34_base_device::NEGC(const uint16_t opcode)
-{
- uint32_t temp;
-
- temp = m_r[Rm];
- m_r[Rn] = -temp - (m_sr & T);
- if (temp || (m_sr & T))
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* NOP */
-inline void sh34_base_device::NOP(const uint16_t opcode)
-{
-}
-
-/* NOT Rm,Rn */
-inline void sh34_base_device::NOT(const uint16_t opcode)
-{
- m_r[Rn] = ~m_r[Rm];
-}
-
-/* OR Rm,Rn */
-inline void sh34_base_device::OR(const uint16_t opcode)
-{
- m_r[Rn] |= m_r[Rm];
-}
-
-/* OR #imm,R0 */
-inline void sh34_base_device::ORI(const uint16_t opcode)
-{
- m_r[0] |= (opcode&0xff);
- m_sh4_icount -= 2;
-}
-
-/* OR.B #imm,@(R0,GBR) */
-inline void sh34_base_device::ORM(const uint16_t opcode)
-{
- uint32_t temp;
-
- m_ea = m_gbr + m_r[0];
- temp = RB( m_ea );
- temp |= (opcode&0xff);
- WB(m_ea, temp );
-}
-
-/* ROTCL Rn */
-inline void sh34_base_device::ROTCL(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- uint32_t temp;
-
- temp = (m_r[n] >> 31) & T;
- m_r[n] = (m_r[n] << 1) | (m_sr & T);
- m_sr = (m_sr & ~T) | temp;
-}
-
-/* ROTCR Rn */
-inline void sh34_base_device::ROTCR(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- uint32_t temp;
- temp = (m_sr & T) << 31;
- if (m_r[n] & T)
- m_sr |= T;
- else
- m_sr &= ~T;
- m_r[n] = (m_r[n] >> 1) | temp;
-}
-
-/* ROTL Rn */
-inline void sh34_base_device::ROTL(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_sr = (m_sr & ~T) | ((m_r[n] >> 31) & T);
- m_r[n] = (m_r[n] << 1) | (m_r[n] >> 31);
-}
-
-/* ROTR Rn */
-inline void sh34_base_device::ROTR(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_sr = (m_sr & ~T) | (m_r[n] & T);
- m_r[n] = (m_r[n] >> 1) | (m_r[n] << 31);
-}
-
/* RTE */
-inline void sh34_base_device::RTE(const uint16_t opcode)
+inline void sh34_base_device::RTE()
{
- m_delay = m_ea = m_spc;
+ m_sh2_state->m_delay = m_sh2_state->ea = m_spc;
+
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
- sh4_syncronize_register_bank((m_sr & sRB) >> 29);
- if ((m_ssr & sRB) != (m_sr & sRB))
+ sh4_syncronize_register_bank((m_sh2_state->sr & sRB) >> 29);
+ if ((m_ssr & sRB) != (m_sh2_state->sr & sRB))
sh4_change_register_bank(m_ssr & sRB ? 1 : 0);
- m_sr = m_ssr;
- m_sh4_icount--;
- sh4_exception_recompute();
-}
-
-/* RTS */
-inline void sh34_base_device::RTS(const uint16_t opcode)
-{
- m_delay = m_ea = m_pr;
- m_sh4_icount--;
-}
-
-/* SETT */
-inline void sh34_base_device::SETT(const uint16_t opcode)
-{
- m_sr |= T;
-}
-
-/* SHAL Rn (same as SHLL) */
-inline void sh34_base_device::SHAL(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_sr = (m_sr & ~T) | ((m_r[n] >> 31) & T);
- m_r[n] <<= 1;
-}
-
-/* SHAR Rn */
-inline void sh34_base_device::SHAR(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_sr = (m_sr & ~T) | (m_r[n] & T);
- m_r[n] = (uint32_t)((int32_t)m_r[n] >> 1);
-}
-
-/* SHLL Rn (same as SHAL) */
-inline void sh34_base_device::SHLL(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_sr = (m_sr & ~T) | ((m_r[n] >> 31) & T);
- m_r[n] <<= 1;
-}
-
-/* SHLL2 Rn */
-inline void sh34_base_device::SHLL2(const uint16_t opcode)
-{
- m_r[Rn] <<= 2;
-}
-
-/* SHLL8 Rn */
-inline void sh34_base_device::SHLL8(const uint16_t opcode)
-{
- m_r[Rn] <<= 8;
-}
-
-/* SHLL16 Rn */
-inline void sh34_base_device::SHLL16(const uint16_t opcode)
-{
- m_r[Rn] <<= 16;
-}
-
-/* SHLR Rn */
-inline void sh34_base_device::SHLR(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_sr = (m_sr & ~T) | (m_r[n] & T);
- m_r[n] >>= 1;
-}
-
-/* SHLR2 Rn */
-inline void sh34_base_device::SHLR2(const uint16_t opcode)
-{
- m_r[Rn] >>= 2;
-}
-
-/* SHLR8 Rn */
-inline void sh34_base_device::SHLR8(const uint16_t opcode)
-{
- m_r[Rn] >>= 8;
-}
-
-/* SHLR16 Rn */
-inline void sh34_base_device::SHLR16(const uint16_t opcode)
-{
- m_r[Rn] >>= 16;
-}
-
-/* SLEEP */
-inline void sh34_base_device::SLEEP(const uint16_t opcode)
-{
- /* 0 = normal mode */
- /* 1 = enters into power-down mode */
- /* 2 = go out the power-down mode after an exception */
- if(m_sleep_mode != 2)
- m_pc -= 2;
- m_sh4_icount -= 2;
- /* Wait_for_exception; */
- if(m_sleep_mode == 0)
- m_sleep_mode = 1;
- else if(m_sleep_mode == 2)
- m_sleep_mode = 0;
-}
-
-/* STC SR,Rn */
-inline void sh34_base_device::STCSR(const uint16_t opcode)
-{
- m_r[Rn] = m_sr;
-}
-
-/* STC GBR,Rn */
-inline void sh34_base_device::STCGBR(const uint16_t opcode)
-{
- m_r[Rn] = m_gbr;
-}
-
-/* STC VBR,Rn */
-inline void sh34_base_device::STCVBR(const uint16_t opcode)
-{
- m_r[Rn] = m_vbr;
-}
-
-/* STC.L SR,@-Rn */
-inline void sh34_base_device::STCMSR(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_sr );
- m_sh4_icount--;
-}
-
-/* STC.L GBR,@-Rn */
-inline void sh34_base_device::STCMGBR(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_gbr );
- m_sh4_icount--;
-}
-
-/* STC.L VBR,@-Rn */
-inline void sh34_base_device::STCMVBR(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_vbr );
- m_sh4_icount--;
-}
-
-/* STS MACH,Rn */
-inline void sh34_base_device::STSMACH(const uint16_t opcode)
-{
- m_r[Rn] = m_mach;
-}
-
-/* STS MACL,Rn */
-inline void sh34_base_device::STSMACL(const uint16_t opcode)
-{
- m_r[Rn] = m_macl;
-}
-
-/* STS PR,Rn */
-inline void sh34_base_device::STSPR(const uint16_t opcode)
-{
- m_r[Rn] = m_pr;
-}
-
-/* STS.L MACH,@-Rn */
-inline void sh34_base_device::STSMMACH(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_mach );
-}
-
-/* STS.L MACL,@-Rn */
-inline void sh34_base_device::STSMMACL(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_macl );
-}
-
-/* STS.L PR,@-Rn */
-inline void sh34_base_device::STSMPR(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_pr );
-}
-
-/* SUB Rm,Rn */
-inline void sh34_base_device::SUB(const uint16_t opcode)
-{
- m_r[Rn] -= m_r[Rm];
-}
-
-/* SUBC Rm,Rn */
-inline void sh34_base_device::SUBC(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- uint32_t tmp0, tmp1;
-
- tmp1 = m_r[n] - m_r[m];
- tmp0 = m_r[n];
- m_r[n] = tmp1 - (m_sr & T);
- if (tmp0 < tmp1)
- m_sr |= T;
- else
- m_sr &= ~T;
- if (tmp1 < m_r[n])
- m_sr |= T;
-}
-
-/* SUBV Rm,Rn */
-inline void sh34_base_device::SUBV(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- int32_t dest, src, ans;
-
- if ((int32_t) m_r[n] >= 0)
- dest = 0;
- else
- dest = 1;
- if ((int32_t) m_r[m] >= 0)
- src = 0;
- else
- src = 1;
- src += dest;
- m_r[n] -= m_r[m];
- if ((int32_t) m_r[n] >= 0)
- ans = 0;
- else
- ans = 1;
- ans += dest;
- if (src == 1)
- {
- if (ans == 1)
- m_sr |= T;
- else
- m_sr &= ~T;
- }
- else
- m_sr &= ~T;
-}
-
-/* SWAP.B Rm,Rn */
-inline void sh34_base_device::SWAPB(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- uint32_t temp0, temp1;
-
- temp0 = m_r[m] & 0xffff0000;
- temp1 = (m_r[m] & 0x000000ff) << 8;
- m_r[n] = (m_r[m] >> 8) & 0x000000ff;
- m_r[n] = m_r[n] | temp1 | temp0;
-}
-
-/* SWAP.W Rm,Rn */
-inline void sh34_base_device::SWAPW(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- uint32_t temp;
- temp = (m_r[m] >> 16) & 0x0000ffff;
- m_r[n] = (m_r[m] << 16) | temp;
-}
-
-/* TAS.B @Rn */
-inline void sh34_base_device::TAS(const uint16_t opcode)
-{
- uint32_t n = Rn;
-
- uint32_t temp;
- m_ea = m_r[n];
- /* Bus Lock enable */
- temp = RB( m_ea );
- if (temp == 0)
- m_sr |= T;
- else
- m_sr &= ~T;
- temp |= 0x80;
- /* Bus Lock disable */
- WB(m_ea, temp );
- m_sh4_icount -= 3;
+ m_sh2_state->sr = m_ssr;
+ m_sh2_state->icount--;
+ sh4_exception_recompute();
}
/* TRAPA #imm */
-inline void sh34_base_device::TRAPA(const uint16_t opcode)
+inline void sh34_base_device::TRAPA(uint32_t i)
{
- uint32_t imm = opcode & 0xff;
+ uint32_t imm = i & 0xff;
if (m_cpu_type == CPU_TYPE_SH4)
{
@@ -2136,18 +521,18 @@ inline void sh34_base_device::TRAPA(const uint16_t opcode)
m_sh3internal_upper[SH3_TRA_ADDR] = imm << 2;
}
+ m_ssr = m_sh2_state->sr;
+ m_spc = m_sh2_state->pc;
- m_ssr = m_sr;
- m_spc = m_pc;
- m_sgr = m_r[15];
+ m_sgr = m_sh2_state->r[15];
- m_sr |= MD;
+ m_sh2_state->sr |= MD;
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
- sh4_syncronize_register_bank((m_sr & sRB) >> 29);
- if (!(m_sr & sRB))
+ sh4_syncronize_register_bank((m_sh2_state->sr & sRB) >> 29);
+ if (!(m_sh2_state->sr & sRB))
sh4_change_register_bank(1);
- m_sr |= sRB;
- m_sr |= BL;
+ m_sh2_state->sr |= sRB;
+ m_sh2_state->sr |= BL;
sh4_exception_recompute();
if (m_cpu_type == CPU_TYPE_SH4)
@@ -2159,116 +544,9 @@ inline void sh34_base_device::TRAPA(const uint16_t opcode)
m_sh3internal_upper[SH3_EXPEVT_ADDR] = 0x00000160;
}
- m_pc = m_vbr + 0x00000100;
+ m_sh2_state->pc = m_sh2_state->vbr + 0x00000100;
- m_sh4_icount -= 7;
-}
-
-/* TST Rm,Rn */
-inline void sh34_base_device::TST(const uint16_t opcode)
-{
- if ((m_r[Rn] & m_r[Rm]) == 0)
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* TST #imm,R0 */
-inline void sh34_base_device::TSTI(const uint16_t opcode)
-{
- uint32_t imm = opcode & 0xff;
-
- if ((imm & m_r[0]) == 0)
- m_sr |= T;
- else
- m_sr &= ~T;
-}
-
-/* TST.B #imm,@(R0,GBR) */
-inline void sh34_base_device::TSTM(const uint16_t opcode)
-{
- uint32_t imm = opcode & 0xff;
-
- m_ea = m_gbr + m_r[0];
- if ((imm & RB( m_ea )) == 0)
- m_sr |= T;
- else
- m_sr &= ~T;
- m_sh4_icount -= 2;
-}
-
-/* XOR Rm,Rn */
-inline void sh34_base_device::XOR(const uint16_t opcode)
-{
- m_r[Rn] ^= m_r[Rm];
-}
-
-/* XOR #imm,R0 */
-inline void sh34_base_device::XORI(const uint16_t opcode)
-{
- uint32_t imm = opcode & 0xff;
- m_r[0] ^= imm;
-}
-
-/* XOR.B #imm,@(R0,GBR) */
-inline void sh34_base_device::XORM(const uint16_t opcode)
-{
- uint32_t imm = opcode & 0xff;
- uint32_t temp;
-
- m_ea = m_gbr + m_r[0];
- temp = RB( m_ea );
- temp ^= imm;
- WB(m_ea, temp );
- m_sh4_icount -= 2;
-}
-
-/* XTRCT Rm,Rn */
-inline void sh34_base_device::XTRCT(const uint16_t opcode)
-{
- uint32_t m = Rm; uint32_t n = Rn;
-
- uint32_t temp;
-
- temp = (m_r[m] << 16) & 0xffff0000;
- m_r[n] = (m_r[n] >> 16) & 0x0000ffff;
- m_r[n] |= temp;
-}
-
-/* STC SSR,Rn */
-inline void sh34_base_device::STCSSR(const uint16_t opcode)
-{
- m_r[Rn] = m_ssr;
-}
-
-/* STC SPC,Rn */
-inline void sh34_base_device::STCSPC(const uint16_t opcode)
-{
- m_r[Rn] = m_spc;
-}
-
-/* STC SGR,Rn */
-inline void sh34_base_device::STCSGR(const uint16_t opcode)
-{
- m_r[Rn] = m_sgr;
-}
-
-/* STS FPUL,Rn */
-inline void sh34_base_device::STSFPUL(const uint16_t opcode)
-{
- m_r[Rn] = m_fpul;
-}
-
-/* STS FPSCR,Rn */
-inline void sh34_base_device::STSFPSCR(const uint16_t opcode)
-{
- m_r[Rn] = m_fpscr & 0x003FFFFF;
-}
-
-/* STC DBR,Rn */
-inline void sh34_base_device::STCDBR(const uint16_t opcode)
-{
- m_r[Rn] = m_dbr;
+ m_sh2_state->icount -= 7;
}
/* STCRBANK Rm_BANK,Rn */
@@ -2276,7 +554,7 @@ inline void sh34_base_device::STCRBANK(const uint16_t opcode)
{
uint32_t m = Rm;
- m_r[Rn] = m_rbnk[m_sr&sRB ? 0 : 1][m & 7];
+ m_sh2_state->r[Rn] = m_rbnk[m_sh2_state->sr&sRB ? 0 : 1][m & 7];
}
/* STCMRBANK Rm_BANK,@-Rn */
@@ -2284,27 +562,10 @@ inline void sh34_base_device::STCMRBANK(const uint16_t opcode)
{
uint32_t m = Rm; uint32_t n = Rn;
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_rbnk[m_sr&sRB ? 0 : 1][m & 7]);
- m_sh4_icount--;
-}
-
-/* MOVCA.L R0,@Rn */
-inline void sh34_base_device::MOVCAL(const uint16_t opcode)
-{
- m_ea = m_r[Rn];
- WL(m_ea, m_r[0] );
-}
-
-inline void sh34_base_device::CLRS(const uint16_t opcode)
-{
- m_sr &= ~S;
-}
-
-inline void sh34_base_device::SETS(const uint16_t opcode)
-{
- m_sr |= S;
+ m_sh2_state->r[n] -= 4;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_rbnk[m_sh2_state->sr&sRB ? 0 : 1][m & 7]);
+ m_sh2_state->icount--;
}
/* STS.L SGR,@-Rn */
@@ -2312,9 +573,9 @@ inline void sh34_base_device::STCMSGR(const uint16_t opcode)
{
uint32_t n = Rn;
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_sgr );
+ m_sh2_state->r[n] -= 4;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_sgr);
}
/* STS.L FPUL,@-Rn */
@@ -2322,9 +583,9 @@ inline void sh34_base_device::STSMFPUL(const uint16_t opcode)
{
uint32_t n = Rn;
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_fpul );
+ m_sh2_state->r[n] -= 4;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_fpul);
}
/* STS.L FPSCR,@-Rn */
@@ -2332,9 +593,9 @@ inline void sh34_base_device::STSMFPSCR(const uint16_t opcode)
{
uint32_t n = Rn;
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_fpscr & 0x003FFFFF);
+ m_sh2_state->r[n] -= 4;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_fpscr & 0x003FFFFF);
}
/* STC.L DBR,@-Rn */
@@ -2342,9 +603,9 @@ inline void sh34_base_device::STCMDBR(const uint16_t opcode)
{
uint32_t n = Rn;
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_dbr );
+ m_sh2_state->r[n] -= 4;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_dbr);
}
/* STC.L SSR,@-Rn */
@@ -2352,9 +613,9 @@ inline void sh34_base_device::STCMSSR(const uint16_t opcode)
{
uint32_t n = Rn;
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_ssr );
+ m_sh2_state->r[n] -= 4;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_ssr);
}
/* STC.L SPC,@-Rn */
@@ -2362,17 +623,17 @@ inline void sh34_base_device::STCMSPC(const uint16_t opcode)
{
uint32_t n = Rn;
- m_r[n] -= 4;
- m_ea = m_r[n];
- WL(m_ea, m_spc );
+ m_sh2_state->r[n] -= 4;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_spc);
}
/* LDS.L @Rm+,FPUL */
inline void sh34_base_device::LDSMFPUL(const uint16_t opcode)
{
- m_ea = m_r[Rn];
- m_fpul = RL(m_ea );
- m_r[Rn] += 4;
+ m_sh2_state->ea = m_sh2_state->r[Rn];
+ m_fpul = RL(m_sh2_state->ea);
+ m_sh2_state->r[Rn] += 4;
}
/* LDS.L @Rm+,FPSCR */
@@ -2381,10 +642,10 @@ inline void sh34_base_device::LDSMFPSCR(const uint16_t opcode)
uint32_t s;
s = m_fpscr;
- m_ea = m_r[Rn];
- m_fpscr = RL(m_ea );
+ m_sh2_state->ea = m_sh2_state->r[Rn];
+ m_fpscr = RL(m_sh2_state->ea);
m_fpscr &= 0x003FFFFF;
- m_r[Rn] += 4;
+ m_sh2_state->r[Rn] += 4;
if ((s & FR) != (m_fpscr & FR))
sh4_swap_fp_registers();
#ifdef LSB_FIRST
@@ -2398,9 +659,9 @@ inline void sh34_base_device::LDSMFPSCR(const uint16_t opcode)
/* LDC.L @Rm+,DBR */
inline void sh34_base_device::LDCMDBR(const uint16_t opcode)
{
- m_ea = m_r[Rn];
- m_dbr = RL(m_ea );
- m_r[Rn] += 4;
+ m_sh2_state->ea = m_sh2_state->r[Rn];
+ m_dbr = RL(m_sh2_state->ea);
+ m_sh2_state->r[Rn] += 4;
}
/* LDC.L @Rn+,Rm_BANK */
@@ -2408,31 +669,31 @@ inline void sh34_base_device::LDCMRBANK(const uint16_t opcode)
{
uint32_t m = Rm; uint32_t n = Rn;
- m_ea = m_r[n];
- m_rbnk[m_sr&sRB ? 0 : 1][m & 7] = RL(m_ea );
- m_r[n] += 4;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ m_rbnk[m_sh2_state->sr&sRB ? 0 : 1][m & 7] = RL(m_sh2_state->ea);
+ m_sh2_state->r[n] += 4;
}
/* LDC.L @Rm+,SSR */
inline void sh34_base_device::LDCMSSR(const uint16_t opcode)
{
- m_ea = m_r[Rn];
- m_ssr = RL(m_ea );
- m_r[Rn] += 4;
+ m_sh2_state->ea = m_sh2_state->r[Rn];
+ m_ssr = RL(m_sh2_state->ea);
+ m_sh2_state->r[Rn] += 4;
}
/* LDC.L @Rm+,SPC */
inline void sh34_base_device::LDCMSPC(const uint16_t opcode)
{
- m_ea = m_r[Rn];
- m_spc = RL(m_ea );
- m_r[Rn] += 4;
+ m_sh2_state->ea = m_sh2_state->r[Rn];
+ m_spc = RL(m_sh2_state->ea);
+ m_sh2_state->r[Rn] += 4;
}
/* LDS Rm,FPUL */
inline void sh34_base_device::LDSFPUL(const uint16_t opcode)
{
- m_fpul = m_r[Rn];
+ m_fpul = m_sh2_state->r[Rn];
}
/* LDS Rm,FPSCR */
@@ -2441,7 +702,7 @@ inline void sh34_base_device::LDSFPSCR(const uint16_t opcode)
uint32_t s;
s = m_fpscr;
- m_fpscr = m_r[Rn] & 0x003FFFFF;
+ m_fpscr = m_sh2_state->r[Rn] & 0x003FFFFF;
if ((s & FR) != (m_fpscr & FR))
sh4_swap_fp_registers();
#ifdef LSB_FIRST
@@ -2455,7 +716,44 @@ inline void sh34_base_device::LDSFPSCR(const uint16_t opcode)
/* LDC Rm,DBR */
inline void sh34_base_device::LDCDBR(const uint16_t opcode)
{
- m_dbr = m_r[Rn];
+ m_dbr = m_sh2_state->r[Rn];
+}
+
+
+/* STC SSR,Rn */
+inline void sh34_base_device::STCSSR(const uint16_t opcode)
+{
+ m_sh2_state->r[Rn] = m_ssr;
+}
+
+/* STC SPC,Rn */
+inline void sh34_base_device::STCSPC(const uint16_t opcode)
+{
+ m_sh2_state->r[Rn] = m_spc;
+}
+
+/* STC SGR,Rn */
+inline void sh34_base_device::STCSGR(const uint16_t opcode)
+{
+ m_sh2_state->r[Rn] = m_sgr;
+}
+
+/* STS FPUL,Rn */
+inline void sh34_base_device::STSFPUL(const uint16_t opcode)
+{
+ m_sh2_state->r[Rn] = m_fpul;
+}
+
+/* STS FPSCR,Rn */
+inline void sh34_base_device::STSFPSCR(const uint16_t opcode)
+{
+ m_sh2_state->r[Rn] = m_fpscr & 0x003FFFFF;
+}
+
+/* STC DBR,Rn */
+inline void sh34_base_device::STCDBR(const uint16_t opcode)
+{
+ m_sh2_state->r[Rn] = m_dbr;
}
/* SHAD Rm,Rn */
@@ -2463,15 +761,16 @@ inline void sh34_base_device::SHAD(const uint16_t opcode)
{
uint32_t m = Rm; uint32_t n = Rn;
- if ((m_r[m] & 0x80000000) == 0)
- m_r[n] = m_r[n] << (m_r[m] & 0x1F);
- else if ((m_r[m] & 0x1F) == 0) {
- if ((m_r[n] & 0x80000000) == 0)
- m_r[n] = 0;
+ if ((m_sh2_state->r[m] & 0x80000000) == 0)
+ m_sh2_state->r[n] = m_sh2_state->r[n] << (m_sh2_state->r[m] & 0x1F);
+ else if ((m_sh2_state->r[m] & 0x1F) == 0) {
+ if ((m_sh2_state->r[n] & 0x80000000) == 0)
+ m_sh2_state->r[n] = 0;
else
- m_r[n] = 0xFFFFFFFF;
- } else
- m_r[n]=(int32_t)m_r[n] >> ((~m_r[m] & 0x1F)+1);
+ m_sh2_state->r[n] = 0xFFFFFFFF;
+ }
+ else
+ m_sh2_state->r[n] = (int32_t)m_sh2_state->r[n] >> ((~m_sh2_state->r[m] & 0x1F) + 1);
}
/* SHLD Rm,Rn */
@@ -2479,12 +778,12 @@ inline void sh34_base_device::SHLD(const uint16_t opcode)
{
uint32_t m = Rm; uint32_t n = Rn;
- if ((m_r[m] & 0x80000000) == 0)
- m_r[n] = m_r[n] << (m_r[m] & 0x1F);
- else if ((m_r[m] & 0x1F) == 0)
- m_r[n] = 0;
+ if ((m_sh2_state->r[m] & 0x80000000) == 0)
+ m_sh2_state->r[n] = m_sh2_state->r[n] << (m_sh2_state->r[m] & 0x1F);
+ else if ((m_sh2_state->r[m] & 0x1F) == 0)
+ m_sh2_state->r[n] = 0;
else
- m_r[n] = m_r[n] >> ((~m_r[m] & 0x1F)+1);
+ m_sh2_state->r[n] = m_sh2_state->r[n] >> ((~m_sh2_state->r[m] & 0x1F) + 1);
}
/* LDCRBANK Rn,Rm_BANK */
@@ -2492,28 +791,28 @@ inline void sh34_base_device::LDCRBANK(const uint16_t opcode)
{
uint32_t m = Rm;
- m_rbnk[m_sr&sRB ? 0 : 1][m & 7] = m_r[Rn];
+ m_rbnk[m_sh2_state->sr&sRB ? 0 : 1][m & 7] = m_sh2_state->r[Rn];
}
/* LDC Rm,SSR */
inline void sh34_base_device::LDCSSR(const uint16_t opcode)
{
- m_ssr = m_r[Rn];
+ m_ssr = m_sh2_state->r[Rn];
}
/* LDC Rm,SPC */
inline void sh34_base_device::LDCSPC(const uint16_t opcode)
{
- m_spc = m_r[Rn];
+ m_spc = m_sh2_state->r[Rn];
}
/* PREF @Rn */
inline void sh34_base_device::PREFM(const uint16_t opcode)
{
int a;
- uint32_t addr,dest,sq;
+ uint32_t addr, dest, sq;
- addr = m_r[Rn]; // address
+ addr = m_sh2_state->r[Rn]; // address
if ((addr >= 0xE0000000) && (addr <= 0xE3FFFFFF))
{
if (m_sh4_mmu_enabled)
@@ -2582,28 +881,30 @@ inline void sh34_base_device::FMOVMRIFR(const uint16_t opcode)
#ifdef LSB_FIRST
n ^= m_fpu_pr;
#endif
- m_ea = m_r[m];
- m_xf[n] = RL(m_ea );
- m_r[m] += 4;
- m_xf[n^1] = RL(m_ea+4 );
- m_r[m] += 4;
- } else {
+ m_sh2_state->ea = m_sh2_state->r[m];
+ m_xf[n] = RL(m_sh2_state->ea);
+ m_sh2_state->r[m] += 4;
+ m_xf[n ^ 1] = RL(m_sh2_state->ea + 4);
+ m_sh2_state->r[m] += 4;
+ }
+ else {
#ifdef LSB_FIRST
n ^= m_fpu_pr;
#endif
- m_ea = m_r[m];
- m_fr[n] = RL(m_ea );
- m_r[m] += 4;
- m_fr[n^1] = RL(m_ea+4 );
- m_r[m] += 4;
+ m_sh2_state->ea = m_sh2_state->r[m];
+ m_fr[n] = RL(m_sh2_state->ea);
+ m_sh2_state->r[m] += 4;
+ m_fr[n ^ 1] = RL(m_sh2_state->ea + 4);
+ m_sh2_state->r[m] += 4;
}
- } else { /* SZ = 0 */
- m_ea = m_r[m];
+ }
+ else { /* SZ = 0 */
+ m_sh2_state->ea = m_sh2_state->r[m];
#ifdef LSB_FIRST
n ^= m_fpu_pr;
#endif
- m_fr[n] = RL(m_ea );
- m_r[m] += 4;
+ m_fr[n] = RL(m_sh2_state->ea);
+ m_sh2_state->r[m] += 4;
}
}
@@ -2621,23 +922,25 @@ inline void sh34_base_device::FMOVFRMR(const uint16_t opcode)
#ifdef LSB_FIRST
m ^= m_fpu_pr;
#endif
- m_ea = m_r[n];
- WL(m_ea,m_xf[m] );
- WL(m_ea+4,m_xf[m^1] );
- } else {
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_xf[m]);
+ WL(m_sh2_state->ea + 4, m_xf[m ^ 1]);
+ }
+ else {
#ifdef LSB_FIRST
m ^= m_fpu_pr;
#endif
- m_ea = m_r[n];
- WL(m_ea,m_fr[m] );
- WL(m_ea+4,m_fr[m^1] );
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_fr[m]);
+ WL(m_sh2_state->ea + 4, m_fr[m ^ 1]);
}
- } else { /* SZ = 0 */
- m_ea = m_r[n];
+ }
+ else { /* SZ = 0 */
+ m_sh2_state->ea = m_sh2_state->r[n];
#ifdef LSB_FIRST
m ^= m_fpu_pr;
#endif
- WL(m_ea,m_fr[m] );
+ WL(m_sh2_state->ea, m_fr[m]);
}
}
@@ -2655,26 +958,28 @@ inline void sh34_base_device::FMOVFRMDR(const uint16_t opcode)
#ifdef LSB_FIRST
m ^= m_fpu_pr;
#endif
- m_r[n] -= 8;
- m_ea = m_r[n];
- WL(m_ea,m_xf[m] );
- WL(m_ea+4,m_xf[m^1] );
- } else {
+ m_sh2_state->r[n] -= 8;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_xf[m]);
+ WL(m_sh2_state->ea + 4, m_xf[m ^ 1]);
+ }
+ else {
#ifdef LSB_FIRST
m ^= m_fpu_pr;
#endif
- m_r[n] -= 8;
- m_ea = m_r[n];
- WL(m_ea,m_fr[m] );
- WL(m_ea+4,m_fr[m^1] );
+ m_sh2_state->r[n] -= 8;
+ m_sh2_state->ea = m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_fr[m]);
+ WL(m_sh2_state->ea + 4, m_fr[m ^ 1]);
}
- } else { /* SZ = 0 */
- m_r[n] -= 4;
- m_ea = m_r[n];
+ }
+ else { /* SZ = 0 */
+ m_sh2_state->r[n] -= 4;
+ m_sh2_state->ea = m_sh2_state->r[n];
#ifdef LSB_FIRST
m ^= m_fpu_pr;
#endif
- WL(m_ea,m_fr[m] );
+ WL(m_sh2_state->ea, m_fr[m]);
}
}
@@ -2692,23 +997,25 @@ inline void sh34_base_device::FMOVFRS0(const uint16_t opcode)
#ifdef LSB_FIRST
m ^= m_fpu_pr;
#endif
- m_ea = m_r[0] + m_r[n];
- WL(m_ea,m_xf[m] );
- WL(m_ea+4,m_xf[m^1] );
- } else {
+ m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_xf[m]);
+ WL(m_sh2_state->ea + 4, m_xf[m ^ 1]);
+ }
+ else {
#ifdef LSB_FIRST
m ^= m_fpu_pr;
#endif
- m_ea = m_r[0] + m_r[n];
- WL(m_ea,m_fr[m] );
- WL(m_ea+4,m_fr[m^1] );
+ m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[n];
+ WL(m_sh2_state->ea, m_fr[m]);
+ WL(m_sh2_state->ea + 4, m_fr[m ^ 1]);
}
- } else { /* SZ = 0 */
- m_ea = m_r[0] + m_r[n];
+ }
+ else { /* SZ = 0 */
+ m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[n];
#ifdef LSB_FIRST
m ^= m_fpu_pr;
#endif
- WL(m_ea,m_fr[m] );
+ WL(m_sh2_state->ea, m_fr[m]);
}
}
@@ -2726,23 +1033,25 @@ inline void sh34_base_device::FMOVS0FR(const uint16_t opcode)
#ifdef LSB_FIRST
n ^= m_fpu_pr;
#endif
- m_ea = m_r[0] + m_r[m];
- m_xf[n] = RL(m_ea );
- m_xf[n^1] = RL(m_ea+4 );
- } else {
+ m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[m];
+ m_xf[n] = RL(m_sh2_state->ea);
+ m_xf[n ^ 1] = RL(m_sh2_state->ea + 4);
+ }
+ else {
#ifdef LSB_FIRST
n ^= m_fpu_pr;
#endif
- m_ea = m_r[0] + m_r[m];
- m_fr[n] = RL(m_ea );
- m_fr[n^1] = RL(m_ea+4 );
+ m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[m];
+ m_fr[n] = RL(m_sh2_state->ea);
+ m_fr[n ^ 1] = RL(m_sh2_state->ea + 4);
}
- } else { /* SZ = 0 */
- m_ea = m_r[0] + m_r[m];
+ }
+ else { /* SZ = 0 */
+ m_sh2_state->ea = m_sh2_state->r[0] + m_sh2_state->r[m];
#ifdef LSB_FIRST
n ^= m_fpu_pr;
#endif
- m_fr[n] = RL(m_ea );
+ m_fr[n] = RL(m_sh2_state->ea);
}
}
@@ -2761,23 +1070,25 @@ inline void sh34_base_device::FMOVMRFR(const uint16_t opcode)
#ifdef LSB_FIRST
n ^= m_fpu_pr;
#endif
- m_ea = m_r[m];
- m_xf[n] = RL(m_ea );
- m_xf[n^1] = RL(m_ea+4 );
- } else {
+ m_sh2_state->ea = m_sh2_state->r[m];
+ m_xf[n] = RL(m_sh2_state->ea);
+ m_xf[n ^ 1] = RL(m_sh2_state->ea + 4);
+ }
+ else {
#ifdef LSB_FIRST
n ^= m_fpu_pr;
#endif
- m_ea = m_r[m];
- m_fr[n] = RL(m_ea );
- m_fr[n^1] = RL(m_ea+4 );
+ m_sh2_state->ea = m_sh2_state->r[m];
+ m_fr[n] = RL(m_sh2_state->ea);
+ m_fr[n ^ 1] = RL(m_sh2_state->ea + 4);
}
- } else { /* SZ = 0 */
- m_ea = m_r[m];
+ }
+ else { /* SZ = 0 */
+ m_sh2_state->ea = m_sh2_state->r[m];
#ifdef LSB_FIRST
n ^= m_fpu_pr;
#endif
- m_fr[n] = RL(m_ea );
+ m_fr[n] = RL(m_sh2_state->ea);
}
}
@@ -2790,7 +1101,7 @@ inline void sh34_base_device::FMOVFR(const uint16_t opcode)
{
uint32_t m = Rm; uint32_t n = Rn;
- if (m_fpu_sz == 0) { /* SZ = 0 */
+ if (m_fpu_sz == 0) { /* SZ = 0 */
#ifdef LSB_FIRST
n ^= m_fpu_pr;
m ^= m_fpu_pr;
@@ -2802,15 +1113,18 @@ inline void sh34_base_device::FMOVFR(const uint16_t opcode)
if (n & 1) {
m_xf[n & 14] = m_xf[m & 14];
m_xf[n | 1] = m_xf[m | 1];
- } else {
+ }
+ else {
m_fr[n] = m_xf[m & 14];
m_fr[n | 1] = m_xf[m | 1];
}
- } else {
+ }
+ else {
if (n & 1) {
m_xf[n & 14] = m_fr[m];
m_xf[n | 1] = m_fr[m | 1]; // (a&14)+1 -> a|1
- } else {
+ }
+ else {
m_fr[n] = m_fr[m];
m_fr[n | 1] = m_fr[m | 1];
}
@@ -2839,7 +1153,7 @@ inline void sh34_base_device::FLDI0(const uint16_t opcode)
}
/* FLDS FRm,FPUL 1111mmmm00011101 */
-inline void sh34_base_device:: FLDS(const uint16_t opcode)
+inline void sh34_base_device::FLDS(const uint16_t opcode)
{
#ifdef LSB_FIRST
m_fpul = m_fr[Rn ^ m_fpu_pr];
@@ -2849,7 +1163,7 @@ inline void sh34_base_device:: FLDS(const uint16_t opcode)
}
/* FSTS FPUL,FRn 1111nnnn00001101 */
-inline void sh34_base_device:: FSTS(const uint16_t opcode)
+inline void sh34_base_device::FSTS(const uint16_t opcode)
{
#ifdef LSB_FIRST
m_fr[Rn ^ m_fpu_pr] = m_fpul;
@@ -2879,13 +1193,14 @@ inline void sh34_base_device::FTRC(const uint16_t opcode)
uint32_t n = Rn;
if (m_fpu_pr) { /* PR = 1 */
- if(n & 1)
- fatalerror("SH-4: FTRC opcode used with n %d",n);
+ if (n & 1)
+ fatalerror("SH-4: FTRC opcode used with n %d", n);
n = n & 14;
*((int32_t *)&m_fpul) = (int32_t)FP_RFD(n);
- } else { /* PR = 0 */
- /* read m_fr[n] as float -> truncate -> fpul(32) */
+ }
+ else { /* PR = 0 */
+ /* read m_fr[n] as float -> truncate -> fpul(32) */
*((int32_t *)&m_fpul) = (int32_t)FP_RFS(n);
}
}
@@ -2897,12 +1212,13 @@ inline void sh34_base_device::FLOAT(const uint16_t opcode)
uint32_t n = Rn;
if (m_fpu_pr) { /* PR = 1 */
- if(n & 1)
- fatalerror("SH-4: FLOAT opcode used with n %d",n);
+ if (n & 1)
+ fatalerror("SH-4: FLOAT opcode used with n %d", n);
n = n & 14;
FP_RFD(n) = (double)*((int32_t *)&m_fpul);
- } else { /* PR = 0 */
+ }
+ else { /* PR = 0 */
FP_RFS(n) = (float)*((int32_t *)&m_fpul);
}
}
@@ -2915,7 +1231,8 @@ inline void sh34_base_device::FNEG(const uint16_t opcode)
if (m_fpu_pr) { /* PR = 1 */
FP_RFD(n) = -FP_RFD(n);
- } else { /* PR = 0 */
+ }
+ else { /* PR = 0 */
FP_RFS(n) = -FP_RFS(n);
}
}
@@ -2934,7 +1251,8 @@ inline void sh34_base_device::FABS(const uint16_t opcode)
n = n & 14;
m_fr[n] = m_fr[n] & 0x7fffffff;
#endif
- } else { /* PR = 0 */
+ }
+ else { /* PR = 0 */
m_fr[n] = m_fr[n] & 0x7fffffff;
}
}
@@ -2949,14 +1267,15 @@ inline void sh34_base_device::FCMP_EQ(const uint16_t opcode)
n = n & 14;
m = m & 14;
if (FP_RFD(n) == FP_RFD(m))
- m_sr |= T;
+ m_sh2_state->sr |= SH_T;
else
- m_sr &= ~T;
- } else { /* PR = 0 */
+ m_sh2_state->sr &= ~SH_T;
+ }
+ else { /* PR = 0 */
if (FP_RFS(n) == FP_RFS(m))
- m_sr |= T;
+ m_sh2_state->sr |= SH_T;
else
- m_sr &= ~T;
+ m_sh2_state->sr &= ~SH_T;
}
}
@@ -2970,14 +1289,15 @@ inline void sh34_base_device::FCMP_GT(const uint16_t opcode)
n = n & 14;
m = m & 14;
if (FP_RFD(n) > FP_RFD(m))
- m_sr |= T;
+ m_sh2_state->sr |= SH_T;
else
- m_sr &= ~T;
- } else { /* PR = 0 */
+ m_sh2_state->sr &= ~SH_T;
+ }
+ else { /* PR = 0 */
if (FP_RFS(n) > FP_RFS(m))
- m_sr |= T;
+ m_sh2_state->sr |= SH_T;
else
- m_sr &= ~T;
+ m_sh2_state->sr &= ~SH_T;
}
}
@@ -2989,7 +1309,7 @@ inline void sh34_base_device::FCNVDS(const uint16_t opcode)
if (m_fpu_pr) { /* PR = 1 */
n = n & 14;
if (m_fpscr & RM)
- m_fr[n | NATIVE_ENDIAN_VALUE_LE_BE(0,1)] &= 0xe0000000; /* round toward zero*/
+ m_fr[n | NATIVE_ENDIAN_VALUE_LE_BE(0, 1)] &= 0xe0000000; /* round toward zero*/
*((float *)&m_fpul) = (float)FP_RFD(n);
}
}
@@ -3015,7 +1335,8 @@ inline void sh34_base_device::FADD(const uint16_t opcode)
n = n & 14;
m = m & 14;
FP_RFD(n) = FP_RFD(n) + FP_RFD(m);
- } else { /* PR = 0 */
+ }
+ else { /* PR = 0 */
FP_RFS(n) = FP_RFS(n) + FP_RFS(m);
}
}
@@ -3030,7 +1351,8 @@ inline void sh34_base_device::FSUB(const uint16_t opcode)
n = n & 14;
m = m & 14;
FP_RFD(n) = FP_RFD(n) - FP_RFD(m);
- } else { /* PR = 0 */
+ }
+ else { /* PR = 0 */
FP_RFS(n) = FP_RFS(n) - FP_RFS(m);
}
}
@@ -3046,7 +1368,8 @@ inline void sh34_base_device::FMUL(const uint16_t opcode)
n = n & 14;
m = m & 14;
FP_RFD(n) = FP_RFD(n) * FP_RFD(m);
- } else { /* PR = 0 */
+ }
+ else { /* PR = 0 */
FP_RFS(n) = FP_RFS(n) * FP_RFS(m);
}
}
@@ -3063,7 +1386,8 @@ inline void sh34_base_device::FDIV(const uint16_t opcode)
if (FP_RFD(m) == 0)
return;
FP_RFD(n) = FP_RFD(n) / FP_RFD(m);
- } else { /* PR = 0 */
+ }
+ else { /* PR = 0 */
if (FP_RFS(m) == 0)
return;
FP_RFS(n) = FP_RFS(n) / FP_RFS(m);
@@ -3091,7 +1415,8 @@ inline void sh34_base_device::FSQRT(const uint16_t opcode)
if (FP_RFD(n) < 0)
return;
FP_RFD(n) = sqrtf(FP_RFD(n));
- } else { /* PR = 0 */
+ }
+ else { /* PR = 0 */
if (FP_RFS(n) < 0)
return;
FP_RFS(n) = sqrtf(FP_RFS(n));
@@ -3115,9 +1440,9 @@ void sh34_base_device::FSSCA(const uint16_t opcode)
float angle;
- angle = (((float)(m_fpul & 0xFFFF)) / 65536.0f) * 2.0f * (float) M_PI;
+ angle = (((float)(m_fpul & 0xFFFF)) / 65536.0f) * 2.0f * (float)M_PI;
FP_RFS(n) = sinf(angle);
- FP_RFS(n+1) = cosf(angle);
+ FP_RFS(n + 1) = cosf(angle);
}
/* FIPR FVm,FVn PR=0 1111nnmm11101101 */
@@ -3125,15 +1450,15 @@ inline void sh34_base_device::FIPR(const uint16_t opcode)
{
uint32_t n = Rn;
-uint32_t m;
-float ml[4];
-int a;
+ uint32_t m;
+ float ml[4];
+ int a;
m = (n & 3) << 2;
n = n & 12;
for (a = 0;a < 4;a++)
- ml[a] = FP_RFS(n+a) * FP_RFS(m+a);
- FP_RFS(n+3) = ml[0] + ml[1] + ml[2] + ml[3];
+ ml[a] = FP_RFS(n + a) * FP_RFS(m + a);
+ FP_RFS(n + 3) = ml[0] + ml[1] + ml[2] + ml[3];
}
/* FTRV XMTRX,FVn PR=0 1111nn0111111101 */
@@ -3141,13 +1466,13 @@ void sh34_base_device::FTRV(const uint16_t opcode)
{
uint32_t n = Rn;
-int i,j;
-float sum[4];
+ int i, j;
+ float sum[4];
n = n & 12;
for (i = 0;i < 4;i++) {
sum[i] = 0;
- for (j=0;j < 4;j++)
+ for (j = 0;j < 4;j++)
sum[i] += FP_XFS((j << 2) + i)*FP_RFS(n + j);
}
for (i = 0;i < 4;i++)
@@ -3157,25 +1482,27 @@ float sum[4];
inline void sh34_base_device::op1111_0xf13(const uint16_t opcode)
{
if (opcode & 0x100) {
- if (opcode & 0x200) {
- switch (opcode & 0xC00)
- {
- case 0x000:
- FSCHG();
- break;
- case 0x800:
- FRCHG();
- break;
- default:
- machine().debug_break();
- break;
- }
- } else {
- FTRV(opcode);
+ if (opcode & 0x200) {
+ switch (opcode & 0xC00)
+ {
+ case 0x000:
+ FSCHG();
+ break;
+ case 0x800:
+ FRCHG();
+ break;
+ default:
+ machine().debug_break();
+ break;
}
- } else {
- FSSCA(opcode);
}
+ else {
+ FTRV(opcode);
+ }
+ }
+ else {
+ FSSCA(opcode);
+ }
}
void sh34_base_device::dbreak(const uint16_t opcode)
@@ -3186,24 +1513,24 @@ void sh34_base_device::dbreak(const uint16_t opcode)
inline void sh34_base_device::op1111_0x13(uint16_t opcode)
{
- switch((opcode >> 4) & 0x0f)
+ switch ((opcode >> 4) & 0x0f)
{
- case 0x00: FSTS(opcode); break;
- case 0x01: FLDS(opcode); break;
- case 0x02: FLOAT(opcode); break;
- case 0x03: FTRC(opcode); break;
- case 0x04: FNEG(opcode); break;
- case 0x05: FABS(opcode); break;
- case 0x06: FSQRT(opcode); break;
- case 0x07: FSRRA(opcode); break;
- case 0x08: FLDI0(opcode); break;
- case 0x09: FLDI1(opcode); break;
- case 0x0a: FCNVSD(opcode); break;
- case 0x0b: FCNVDS(opcode); break;
- case 0x0c: dbreak(opcode); break;
- case 0x0d: dbreak(opcode); break;
- case 0x0e: FIPR(opcode); break;
- case 0x0f: op1111_0xf13(opcode); break;
+ case 0x00: FSTS(opcode); break;
+ case 0x01: FLDS(opcode); break;
+ case 0x02: FLOAT(opcode); break;
+ case 0x03: FTRC(opcode); break;
+ case 0x04: FNEG(opcode); break;
+ case 0x05: FABS(opcode); break;
+ case 0x06: FSQRT(opcode); break;
+ case 0x07: FSRRA(opcode); break;
+ case 0x08: FLDI0(opcode); break;
+ case 0x09: FLDI1(opcode); break;
+ case 0x0a: FCNVSD(opcode); break;
+ case 0x0b: FCNVDS(opcode); break;
+ case 0x0c: dbreak(opcode); break;
+ case 0x0d: dbreak(opcode); break;
+ case 0x0e: FIPR(opcode); break;
+ case 0x0f: op1111_0xf13(opcode); break;
}
}
@@ -3215,20 +1542,20 @@ inline void sh34_base_device::op1111_0x13(uint16_t opcode)
void sh34_base_device::device_reset()
{
m_spc = 0;
- m_pr = 0;
- m_sr = 0;
+ m_sh2_state->pr = 0;
+ m_sh2_state->sr = 0;
m_ssr = 0;
- m_gbr = 0;
- m_vbr = 0;
- m_mach = 0;
- m_macl = 0;
- memset(m_r, 0, sizeof(m_r));
+ m_sh2_state->gbr = 0;
+ m_sh2_state->vbr = 0;
+ m_sh2_state->mach = 0;
+ m_sh2_state->macl = 0;
+ memset(m_sh2_state->r, 0, sizeof(m_sh2_state->r));
memset(m_rbnk, 0, sizeof(m_rbnk));
m_sgr = 0;
memset(m_fr, 0, sizeof(m_fr));
memset(m_xf, 0, sizeof(m_xf));
- m_ea = 0;
- m_delay = 0;
+ m_sh2_state->ea = 0;
+ m_sh2_state->m_delay = 0;
m_cpu_off = 0;
m_pending_irq = 0;
m_test_irq = 0;
@@ -3290,10 +1617,10 @@ void sh34_base_device::device_reset()
m_rtc_timer->adjust(attotime::from_hz(128));
- m_pc = 0xa0000000;
- m_ppc = m_pc & AM;
- m_r[15] = RL(4);
- m_sr = 0x700000f0;
+ m_sh2_state->pc = 0xa0000000;
+ m_ppc = m_sh2_state->pc & SH34_AM;
+ m_sh2_state->r[15] = RL(4);
+ m_sh2_state->sr = 0x700000f0;
m_fpscr = 0x00040001;
m_fpu_sz = (m_fpscr & SZ) ? 1 : 0;
m_fpu_pr = (m_fpscr & PR) ? 1 : 0;
@@ -3302,7 +1629,7 @@ void sh34_base_device::device_reset()
m_internal_irq_level = -1;
m_irln = 15;
- m_sleep_mode = 0;
+ m_sh2_state->sleep_mode = 0;
m_sh4_mmu_enabled = 0;
}
@@ -3338,846 +1665,344 @@ void sh4_base_device::device_reset()
inline void sh34_base_device::execute_one_0000(const uint16_t opcode)
{
- switch(opcode & 0xff)
+ switch (opcode & 0xff)
{
- // 0x00
- case 0x00: NOP(opcode); break;
- case 0x10: NOP(opcode); break;
- case 0x20: NOP(opcode); break;
- case 0x30: NOP(opcode); break;
- case 0x40: NOP(opcode); break;
- case 0x50: NOP(opcode); break;
- case 0x60: NOP(opcode); break;
- case 0x70: NOP(opcode); break;
- case 0x80: NOP(opcode); break;
- case 0x90: NOP(opcode); break;
- case 0xa0: NOP(opcode); break;
- case 0xb0: NOP(opcode); break;
- case 0xc0: NOP(opcode); break;
- case 0xd0: NOP(opcode); break;
- case 0xe0: NOP(opcode); break;
- case 0xf0: NOP(opcode); break;
- // 0x10
- case 0x01: NOP(opcode); break;
- case 0x11: NOP(opcode); break;
- case 0x21: NOP(opcode); break;
- case 0x31: NOP(opcode); break;
- case 0x41: NOP(opcode); break;
- case 0x51: NOP(opcode); break;
- case 0x61: NOP(opcode); break;
- case 0x71: NOP(opcode); break;
- case 0x81: NOP(opcode); break;
- case 0x91: NOP(opcode); break;
- case 0xa1: NOP(opcode); break;
- case 0xb1: NOP(opcode); break;
- case 0xc1: NOP(opcode); break;
- case 0xd1: NOP(opcode); break;
- case 0xe1: NOP(opcode); break;
- case 0xf1: NOP(opcode); break;
- // 0x20
- case 0x02: STCSR(opcode); break;
- case 0x12: STCGBR(opcode); break;
- case 0x22: STCVBR(opcode); break;
- case 0x32: STCSSR(opcode); break;
- case 0x42: STCSPC(opcode); break;
- case 0x52: NOP(opcode); break;
- case 0x62: NOP(opcode); break;
- case 0x72: NOP(opcode); break;
- case 0x82: STCRBANK(opcode); break;
- case 0x92: STCRBANK(opcode); break;
- case 0xa2: STCRBANK(opcode); break;
- case 0xb2: STCRBANK(opcode); break;
- case 0xc2: STCRBANK(opcode); break;
- case 0xd2: STCRBANK(opcode); break;
- case 0xe2: STCRBANK(opcode); break;
- case 0xf2: STCRBANK(opcode); break;
- // 0x30
- case 0x03: BSRF(opcode); break;
- case 0x13: NOP(opcode); break;
- case 0x23: BRAF(opcode); break;
- case 0x33: NOP(opcode); break;
- case 0x43: NOP(opcode); break;
- case 0x53: NOP(opcode); break;
- case 0x63: NOP(opcode); break;
- case 0x73: NOP(opcode); break;
- case 0x83: PREFM(opcode); break;
- case 0x93: TODO(opcode); break;
- case 0xa3: TODO(opcode); break;
- case 0xb3: TODO(opcode); break;
- case 0xc3: MOVCAL(opcode); break;
- case 0xd3: NOP(opcode); break;
- case 0xe3: NOP(opcode); break;
- case 0xf3: NOP(opcode); break;
- // 0x40
- case 0x04: MOVBS0(opcode); break;
- case 0x14: MOVBS0(opcode); break;
- case 0x24: MOVBS0(opcode); break;
- case 0x34: MOVBS0(opcode); break;
- case 0x44: MOVBS0(opcode); break;
- case 0x54: MOVBS0(opcode); break;
- case 0x64: MOVBS0(opcode); break;
- case 0x74: MOVBS0(opcode); break;
- case 0x84: MOVBS0(opcode); break;
- case 0x94: MOVBS0(opcode); break;
- case 0xa4: MOVBS0(opcode); break;
- case 0xb4: MOVBS0(opcode); break;
- case 0xc4: MOVBS0(opcode); break;
- case 0xd4: MOVBS0(opcode); break;
- case 0xe4: MOVBS0(opcode); break;
- case 0xf4: MOVBS0(opcode); break;
- // 0x50
- case 0x05: MOVWS0(opcode); break;
- case 0x15: MOVWS0(opcode); break;
- case 0x25: MOVWS0(opcode); break;
- case 0x35: MOVWS0(opcode); break;
- case 0x45: MOVWS0(opcode); break;
- case 0x55: MOVWS0(opcode); break;
- case 0x65: MOVWS0(opcode); break;
- case 0x75: MOVWS0(opcode); break;
- case 0x85: MOVWS0(opcode); break;
- case 0x95: MOVWS0(opcode); break;
- case 0xa5: MOVWS0(opcode); break;
- case 0xb5: MOVWS0(opcode); break;
- case 0xc5: MOVWS0(opcode); break;
- case 0xd5: MOVWS0(opcode); break;
- case 0xe5: MOVWS0(opcode); break;
- case 0xf5: MOVWS0(opcode); break;
- // 0x60
- case 0x06: MOVLS0(opcode); break;
- case 0x16: MOVLS0(opcode); break;
- case 0x26: MOVLS0(opcode); break;
- case 0x36: MOVLS0(opcode); break;
- case 0x46: MOVLS0(opcode); break;
- case 0x56: MOVLS0(opcode); break;
- case 0x66: MOVLS0(opcode); break;
- case 0x76: MOVLS0(opcode); break;
- case 0x86: MOVLS0(opcode); break;
- case 0x96: MOVLS0(opcode); break;
- case 0xa6: MOVLS0(opcode); break;
- case 0xb6: MOVLS0(opcode); break;
- case 0xc6: MOVLS0(opcode); break;
- case 0xd6: MOVLS0(opcode); break;
- case 0xe6: MOVLS0(opcode); break;
- case 0xf6: MOVLS0(opcode); break;
- // 0x70
- case 0x07: MULL(opcode); break;
- case 0x17: MULL(opcode); break;
- case 0x27: MULL(opcode); break;
- case 0x37: MULL(opcode); break;
- case 0x47: MULL(opcode); break;
- case 0x57: MULL(opcode); break;
- case 0x67: MULL(opcode); break;
- case 0x77: MULL(opcode); break;
- case 0x87: MULL(opcode); break;
- case 0x97: MULL(opcode); break;
- case 0xa7: MULL(opcode); break;
- case 0xb7: MULL(opcode); break;
- case 0xc7: MULL(opcode); break;
- case 0xd7: MULL(opcode); break;
- case 0xe7: MULL(opcode); break;
- case 0xf7: MULL(opcode); break;
- // 0x80
- case 0x08: CLRT(opcode); break;
- case 0x18: SETT(opcode); break;
- case 0x28: CLRMAC(opcode); break;
- case 0x38: LDTLB(opcode); break;
- case 0x48: CLRS(opcode); break;
- case 0x58: SETS(opcode); break;
- case 0x68: NOP(opcode); break;
- case 0x78: NOP(opcode); break;
- case 0x88: CLRT(opcode); break;
- case 0x98: SETT(opcode); break;
- case 0xa8: CLRMAC(opcode); break;
- case 0xb8: LDTLB(opcode); break;
- case 0xc8: CLRS(opcode); break;
- case 0xd8: SETS(opcode); break;
- case 0xe8: NOP(opcode); break;
- case 0xf8: NOP(opcode); break;
- // 0x90
- case 0x09: NOP(opcode); break;
- case 0x19: DIV0U(opcode); break;
- case 0x29: MOVT(opcode); break;
- case 0x39: NOP(opcode); break;
- case 0x49: NOP(opcode); break;
- case 0x59: DIV0U(opcode); break;
- case 0x69: MOVT(opcode); break;
- case 0x79: NOP(opcode); break;
- case 0x89: NOP(opcode); break;
- case 0x99: DIV0U(opcode); break;
- case 0xa9: MOVT(opcode); break;
- case 0xb9: NOP(opcode); break;
- case 0xc9: NOP(opcode); break;
- case 0xd9: DIV0U(opcode); break;
- case 0xe9: MOVT(opcode); break;
- case 0xf9: NOP(opcode); break;
- // 0xa0
- case 0x0a: STSMACH(opcode); break;
- case 0x1a: STSMACL(opcode); break;
- case 0x2a: STSPR(opcode); break;
- case 0x3a: STCSGR(opcode); break;
- case 0x4a: NOP(opcode); break;
- case 0x5a: STSFPUL(opcode); break;
- case 0x6a: STSFPSCR(opcode); break;
- case 0x7a: STCDBR(opcode); break;
- case 0x8a: STSMACH(opcode); break;
- case 0x9a: STSMACL(opcode); break;
- case 0xaa: STSPR(opcode); break;
- case 0xba: STCSGR(opcode); break;
- case 0xca: NOP(opcode); break;
- case 0xda: STSFPUL(opcode); break;
- case 0xea: STSFPSCR(opcode); break;
- case 0xfa: STCDBR(opcode); break;
- // 0xb0
- case 0x0b: RTS(opcode); break;
- case 0x1b: SLEEP(opcode); break;
- case 0x2b: RTE(opcode); break;
- case 0x3b: NOP(opcode); break;
- case 0x4b: RTS(opcode); break;
- case 0x5b: SLEEP(opcode); break;
- case 0x6b: RTE(opcode); break;
- case 0x7b: NOP(opcode); break;
- case 0x8b: RTS(opcode); break;
- case 0x9b: SLEEP(opcode); break;
- case 0xab: RTE(opcode); break;
- case 0xbb: NOP(opcode); break;
- case 0xcb: RTS(opcode); break;
- case 0xdb: SLEEP(opcode); break;
- case 0xeb: RTE(opcode); break;
- case 0xfb: NOP(opcode); break;
- // 0xc0
- case 0x0c: MOVBL0(opcode); break;
- case 0x1c: MOVBL0(opcode); break;
- case 0x2c: MOVBL0(opcode); break;
- case 0x3c: MOVBL0(opcode); break;
- case 0x4c: MOVBL0(opcode); break;
- case 0x5c: MOVBL0(opcode); break;
- case 0x6c: MOVBL0(opcode); break;
- case 0x7c: MOVBL0(opcode); break;
- case 0x8c: MOVBL0(opcode); break;
- case 0x9c: MOVBL0(opcode); break;
- case 0xac: MOVBL0(opcode); break;
- case 0xbc: MOVBL0(opcode); break;
- case 0xcc: MOVBL0(opcode); break;
- case 0xdc: MOVBL0(opcode); break;
- case 0xec: MOVBL0(opcode); break;
- case 0xfc: MOVBL0(opcode); break;
- // 0xd0
- case 0x0d: MOVWL0(opcode); break;
- case 0x1d: MOVWL0(opcode); break;
- case 0x2d: MOVWL0(opcode); break;
- case 0x3d: MOVWL0(opcode); break;
- case 0x4d: MOVWL0(opcode); break;
- case 0x5d: MOVWL0(opcode); break;
- case 0x6d: MOVWL0(opcode); break;
- case 0x7d: MOVWL0(opcode); break;
- case 0x8d: MOVWL0(opcode); break;
- case 0x9d: MOVWL0(opcode); break;
- case 0xad: MOVWL0(opcode); break;
- case 0xbd: MOVWL0(opcode); break;
- case 0xcd: MOVWL0(opcode); break;
- case 0xdd: MOVWL0(opcode); break;
- case 0xed: MOVWL0(opcode); break;
- case 0xfd: MOVWL0(opcode); break;
- // 0xe0
- case 0x0e: MOVLL0(opcode); break;
- case 0x1e: MOVLL0(opcode); break;
- case 0x2e: MOVLL0(opcode); break;
- case 0x3e: MOVLL0(opcode); break;
- case 0x4e: MOVLL0(opcode); break;
- case 0x5e: MOVLL0(opcode); break;
- case 0x6e: MOVLL0(opcode); break;
- case 0x7e: MOVLL0(opcode); break;
- case 0x8e: MOVLL0(opcode); break;
- case 0x9e: MOVLL0(opcode); break;
- case 0xae: MOVLL0(opcode); break;
- case 0xbe: MOVLL0(opcode); break;
- case 0xce: MOVLL0(opcode); break;
- case 0xde: MOVLL0(opcode); break;
- case 0xee: MOVLL0(opcode); break;
- case 0xfe: MOVLL0(opcode); break;
- // 0xf0
- case 0x0f: MAC_L(opcode); break;
- case 0x1f: MAC_L(opcode); break;
- case 0x2f: MAC_L(opcode); break;
- case 0x3f: MAC_L(opcode); break;
- case 0x4f: MAC_L(opcode); break;
- case 0x5f: MAC_L(opcode); break;
- case 0x6f: MAC_L(opcode); break;
- case 0x7f: MAC_L(opcode); break;
- case 0x8f: MAC_L(opcode); break;
- case 0x9f: MAC_L(opcode); break;
- case 0xaf: MAC_L(opcode); break;
- case 0xbf: MAC_L(opcode); break;
- case 0xcf: MAC_L(opcode); break;
- case 0xdf: MAC_L(opcode); break;
- case 0xef: MAC_L(opcode); break;
- case 0xff: MAC_L(opcode); break;
+ default:
+ // fall through to SH2 handlers
+ sh_common_execution::execute_one_0000(opcode); break;
+
+ case 0x52:
+ case 0x62:
+ case 0x43:
+ case 0x63:
+ case 0xe3:
+ case 0x68:
+ case 0xe8:
+ case 0x4a:
+ case 0xca:
+ ILLEGAL(); break; // illegal on sh4
+
+ case 0x93:
+ case 0xa3:
+ case 0xb3:
+ TODO(opcode); break;
+
+ case 0x82:
+ case 0x92:
+ case 0xa2:
+ case 0xb2:
+ case 0xc2:
+ case 0xd2:
+ case 0xe2:
+ case 0xf2:
+ STCRBANK(opcode); break; // sh4 only
+
+ case 0x32: STCSSR(opcode); break; // sh4 only
+ case 0x42: STCSPC(opcode); break; // sh4 only
+ case 0x83: PREFM(opcode); break; // sh4 only
+ case 0xc3: MOVCAL(opcode); break; // sh4 only
+
+ case 0x38:
+ case 0xb8:
+ LDTLB(opcode); break; // sh4 only
+
+ case 0x48:
+ case 0xc8:
+ CLRS(opcode); break; // sh4 only
+
+ case 0x58:
+ case 0xd8:
+ SETS(opcode); break; // sh4 only
+
+ case 0x3a:
+ case 0xba:
+ STCSGR(opcode); break; // sh4 only
+
+ case 0x5a:
+ case 0xda:
+ STSFPUL(opcode); break; // sh4 only
+
+ case 0x6a:
+ case 0xea:
+ STSFPSCR(opcode); break; // sh4 only
+
+ case 0x7a:
+ case 0xfa:
+ STCDBR(opcode); break; // sh4 only
}
}
inline void sh34_base_device::execute_one_4000(const uint16_t opcode)
{
- switch(opcode & 0xff)
+ switch (opcode & 0xff)
{
- // 0x00
- case 0x00: SHLL(opcode); break;
- case 0x10: DT(opcode); break;
- case 0x20: SHAL(opcode); break;
- case 0x30: NOP(opcode); break;
- case 0x40: SHLL(opcode); break;
- case 0x50: DT(opcode); break;
- case 0x60: SHAL(opcode); break;
- case 0x70: NOP(opcode); break;
- case 0x80: SHLL(opcode); break;
- case 0x90: DT(opcode); break;
- case 0xa0: SHAL(opcode); break;
- case 0xb0: NOP(opcode); break;
- case 0xc0: SHLL(opcode); break;
- case 0xd0: DT(opcode); break;
- case 0xe0: SHAL(opcode); break;
- case 0xf0: NOP(opcode); break;
- // 0x10
- case 0x01: SHLR(opcode); break;
- case 0x11: CMPPZ(opcode); break;
- case 0x21: SHAR(opcode); break;
- case 0x31: NOP(opcode); break;
- case 0x41: SHLR(opcode); break;
- case 0x51: CMPPZ(opcode); break;
- case 0x61: SHAR(opcode); break;
- case 0x71: NOP(opcode); break;
- case 0x81: SHLR(opcode); break;
- case 0x91: CMPPZ(opcode); break;
- case 0xa1: SHAR(opcode); break;
- case 0xb1: NOP(opcode); break;
- case 0xc1: SHLR(opcode); break;
- case 0xd1: CMPPZ(opcode); break;
- case 0xe1: SHAR(opcode); break;
- case 0xf1: NOP(opcode); break;
- // 0x20
- case 0x02: STSMMACH(opcode); break;
- case 0x12: STSMMACL(opcode); break;
- case 0x22: STSMPR(opcode); break;
- case 0x32: STCMSGR(opcode); break;
- case 0x42: NOP(opcode); break;
- case 0x52: STSMFPUL(opcode); break;
- case 0x62: STSMFPSCR(opcode); break;
- case 0x72: NOP(opcode); break;
- case 0x82: NOP(opcode); break;
- case 0x92: NOP(opcode); break;
- case 0xa2: NOP(opcode); break;
- case 0xb2: NOP(opcode); break;
- case 0xc2: NOP(opcode); break;
- case 0xd2: NOP(opcode); break;
- case 0xe2: NOP(opcode); break;
- case 0xf2: STCMDBR(opcode); break;
- // 0x30
- case 0x03: STCMSR(opcode); break;
- case 0x13: STCMGBR(opcode); break;
- case 0x23: STCMVBR(opcode); break;
- case 0x33: STCMSSR(opcode); break;
- case 0x43: STCMSPC(opcode); break;
- case 0x53: NOP(opcode); break;
- case 0x63: NOP(opcode); break;
- case 0x73: NOP(opcode); break;
- case 0x83: STCMRBANK(opcode); break;
- case 0x93: STCMRBANK(opcode); break;
- case 0xa3: STCMRBANK(opcode); break;
- case 0xb3: STCMRBANK(opcode); break;
- case 0xc3: STCMRBANK(opcode); break;
- case 0xd3: STCMRBANK(opcode); break;
- case 0xe3: STCMRBANK(opcode); break;
- case 0xf3: STCMRBANK(opcode); break;
- // 0x40
- case 0x04: ROTL(opcode); break;
- case 0x14: NOP(opcode); break;
- case 0x24: ROTCL(opcode); break;
- case 0x34: NOP(opcode); break;
- case 0x44: ROTL(opcode); break;
- case 0x54: NOP(opcode); break;
- case 0x64: ROTCL(opcode); break;
- case 0x74: NOP(opcode); break;
- case 0x84: ROTL(opcode); break;
- case 0x94: NOP(opcode); break;
- case 0xa4: ROTCL(opcode); break;
- case 0xb4: NOP(opcode); break;
- case 0xc4: ROTL(opcode); break;
- case 0xd4: NOP(opcode); break;
- case 0xe4: ROTCL(opcode); break;
- case 0xf4: NOP(opcode); break;
- // 0x50
- case 0x05: ROTR(opcode); break;
- case 0x15: CMPPL(opcode); break;
- case 0x25: ROTCR(opcode); break;
- case 0x35: NOP(opcode); break;
- case 0x45: ROTR(opcode); break;
- case 0x55: CMPPL(opcode); break;
- case 0x65: ROTCR(opcode); break;
- case 0x75: NOP(opcode); break;
- case 0x85: ROTR(opcode); break;
- case 0x95: CMPPL(opcode); break;
- case 0xa5: ROTCR(opcode); break;
- case 0xb5: NOP(opcode); break;
- case 0xc5: ROTR(opcode); break;
- case 0xd5: CMPPL(opcode); break;
- case 0xe5: ROTCR(opcode); break;
- case 0xf5: NOP(opcode); break;
- // 0x60
- case 0x06: LDSMMACH(opcode); break;
- case 0x16: LDSMMACL(opcode); break;
- case 0x26: LDSMPR(opcode); break;
- case 0x36: NOP(opcode); break;
- case 0x46: NOP(opcode); break;
- case 0x56: LDSMFPUL(opcode); break;
- case 0x66: LDSMFPSCR(opcode); break;
- case 0x76: NOP(opcode); break;
- case 0x86: NOP(opcode); break;
- case 0x96: NOP(opcode); break;
- case 0xa6: NOP(opcode); break;
- case 0xb6: NOP(opcode); break;
- case 0xc6: NOP(opcode); break;
- case 0xd6: NOP(opcode); break;
- case 0xe6: NOP(opcode); break;
- case 0xf6: LDCMDBR(opcode); break;
- // 0x70
- case 0x07: LDCMSR(opcode); break;
- case 0x17: LDCMGBR(opcode); break;
- case 0x27: LDCMVBR(opcode); break;
- case 0x37: LDCMSSR(opcode); break;
- case 0x47: LDCMSPC(opcode); break;
- case 0x57: NOP(opcode); break;
- case 0x67: NOP(opcode); break;
- case 0x77: NOP(opcode); break;
- case 0x87: LDCMRBANK(opcode); break;
- case 0x97: LDCMRBANK(opcode); break;
- case 0xa7: LDCMRBANK(opcode); break;
- case 0xb7: LDCMRBANK(opcode); break;
- case 0xc7: LDCMRBANK(opcode); break;
- case 0xd7: LDCMRBANK(opcode); break;
- case 0xe7: LDCMRBANK(opcode); break;
- case 0xf7: LDCMRBANK(opcode); break;
- // 0x80
- case 0x08: SHLL2(opcode); break;
- case 0x18: SHLL8(opcode); break;
- case 0x28: SHLL16(opcode); break;
- case 0x38: NOP(opcode); break;
- case 0x48: SHLL2(opcode); break;
- case 0x58: SHLL8(opcode); break;
- case 0x68: SHLL16(opcode); break;
- case 0x78: NOP(opcode); break;
- case 0x88: SHLL2(opcode); break;
- case 0x98: SHLL8(opcode); break;
- case 0xa8: SHLL16(opcode); break;
- case 0xb8: NOP(opcode); break;
- case 0xc8: SHLL2(opcode); break;
- case 0xd8: SHLL8(opcode); break;
- case 0xe8: SHLL16(opcode); break;
- case 0xf8: NOP(opcode); break;
- // 0x90
- case 0x09: SHLR2(opcode); break;
- case 0x19: SHLR8(opcode); break;
- case 0x29: SHLR16(opcode); break;
- case 0x39: NOP(opcode); break;
- case 0x49: SHLR2(opcode); break;
- case 0x59: SHLR8(opcode); break;
- case 0x69: SHLR16(opcode); break;
- case 0x79: NOP(opcode); break;
- case 0x89: SHLR2(opcode); break;
- case 0x99: SHLR8(opcode); break;
- case 0xa9: SHLR16(opcode); break;
- case 0xb9: NOP(opcode); break;
- case 0xc9: SHLR2(opcode); break;
- case 0xd9: SHLR8(opcode); break;
- case 0xe9: SHLR16(opcode); break;
- case 0xf9: NOP(opcode); break;
- // 0xa0
- case 0x0a: LDSMACH(opcode); break;
- case 0x1a: LDSMACL(opcode); break;
- case 0x2a: LDSPR(opcode); break;
- case 0x3a: NOP(opcode); break;
- case 0x4a: NOP(opcode); break;
- case 0x5a: LDSFPUL(opcode); break;
- case 0x6a: LDSFPSCR(opcode); break;
- case 0x7a: NOP(opcode); break;
- case 0x8a: NOP(opcode); break;
- case 0x9a: NOP(opcode); break;
- case 0xaa: NOP(opcode); break;
- case 0xba: NOP(opcode); break;
- case 0xca: NOP(opcode); break;
- case 0xda: NOP(opcode); break;
- case 0xea: NOP(opcode); break;
- case 0xfa: LDCDBR(opcode); break;
- // 0xb0
- case 0x0b: JSR(opcode); break;
- case 0x1b: TAS(opcode); break;
- case 0x2b: JMP(opcode); break;
- case 0x3b: NOP(opcode); break;
- case 0x4b: JSR(opcode); break;
- case 0x5b: TAS(opcode); break;
- case 0x6b: JMP(opcode); break;
- case 0x7b: NOP(opcode); break;
- case 0x8b: JSR(opcode); break;
- case 0x9b: TAS(opcode); break;
- case 0xab: JMP(opcode); break;
- case 0xbb: NOP(opcode); break;
- case 0xcb: JSR(opcode); break;
- case 0xdb: TAS(opcode); break;
- case 0xeb: JMP(opcode); break;
- case 0xfb: NOP(opcode); break;
- // 0xc0
- case 0x0c: SHAD(opcode); break;
- case 0x1c: SHAD(opcode); break;
- case 0x2c: SHAD(opcode); break;
- case 0x3c: SHAD(opcode); break;
- case 0x4c: SHAD(opcode); break;
- case 0x5c: SHAD(opcode); break;
- case 0x6c: SHAD(opcode); break;
- case 0x7c: SHAD(opcode); break;
- case 0x8c: SHAD(opcode); break;
- case 0x9c: SHAD(opcode); break;
- case 0xac: SHAD(opcode); break;
- case 0xbc: SHAD(opcode); break;
- case 0xcc: SHAD(opcode); break;
- case 0xdc: SHAD(opcode); break;
- case 0xec: SHAD(opcode); break;
- case 0xfc: SHAD(opcode); break;
- // 0xd0
- case 0x0d: SHLD(opcode); break;
- case 0x1d: SHLD(opcode); break;
- case 0x2d: SHLD(opcode); break;
- case 0x3d: SHLD(opcode); break;
- case 0x4d: SHLD(opcode); break;
- case 0x5d: SHLD(opcode); break;
- case 0x6d: SHLD(opcode); break;
- case 0x7d: SHLD(opcode); break;
- case 0x8d: SHLD(opcode); break;
- case 0x9d: SHLD(opcode); break;
- case 0xad: SHLD(opcode); break;
- case 0xbd: SHLD(opcode); break;
- case 0xcd: SHLD(opcode); break;
- case 0xdd: SHLD(opcode); break;
- case 0xed: SHLD(opcode); break;
- case 0xfd: SHLD(opcode); break;
- // 0xe0
- case 0x0e: LDCSR(opcode); break;
- case 0x1e: LDCGBR(opcode); break;
- case 0x2e: LDCVBR(opcode); break;
- case 0x3e: LDCSSR(opcode); break;
- case 0x4e: LDCSPC(opcode); break;
- case 0x5e: NOP(opcode); break;
- case 0x6e: NOP(opcode); break;
- case 0x7e: NOP(opcode); break;
- case 0x8e: LDCRBANK(opcode); break;
- case 0x9e: LDCRBANK(opcode); break;
- case 0xae: LDCRBANK(opcode); break;
- case 0xbe: LDCRBANK(opcode); break;
- case 0xce: LDCRBANK(opcode); break;
- case 0xde: LDCRBANK(opcode); break;
- case 0xee: LDCRBANK(opcode); break;
- case 0xfe: LDCRBANK(opcode); break;
- // 0xf0
- case 0x0f: MAC_W(opcode); break;
- case 0x1f: MAC_W(opcode); break;
- case 0x2f: MAC_W(opcode); break;
- case 0x3f: MAC_W(opcode); break;
- case 0x4f: MAC_W(opcode); break;
- case 0x5f: MAC_W(opcode); break;
- case 0x6f: MAC_W(opcode); break;
- case 0x7f: MAC_W(opcode); break;
- case 0x8f: MAC_W(opcode); break;
- case 0x9f: MAC_W(opcode); break;
- case 0xaf: MAC_W(opcode); break;
- case 0xbf: MAC_W(opcode); break;
- case 0xcf: MAC_W(opcode); break;
- case 0xdf: MAC_W(opcode); break;
- case 0xef: MAC_W(opcode); break;
- case 0xff: MAC_W(opcode); break;
- }
-}
-
-inline void sh34_base_device::execute_one(const uint16_t opcode)
-{
- switch(opcode & 0xf000)
+ default: // LDCMSR (0x0e) has sh2/4 flag difference
+ // fall through to SH2 handlers
+ sh_common_execution::execute_one_4000(opcode); break;
+
+ case 0x42:
+ case 0x46:
+ case 0x4a:
+ case 0x53:
+ case 0x57:
+ case 0x5e:
+ case 0x63:
+ case 0x67:
+ case 0x6e:
+ case 0x82:
+ case 0x86:
+ case 0x8a:
+ case 0x92:
+ case 0x96:
+ case 0x9a:
+ case 0xa2:
+ case 0xa6:
+ case 0xaa:
+ case 0xc2:
+ case 0xc6:
+ case 0xca:
+ case 0xd2:
+ case 0xd6:
+ case 0xda:
+ case 0xe2:
+ case 0xe6:
+ case 0xea:
+ ILLEGAL(); break; // defined as illegal on SH4
+
+ case 0x0c:
+ case 0x1c:
+ case 0x2c:
+ case 0x3c:
+ case 0x4c:
+ case 0x5c:
+ case 0x6c:
+ case 0x7c:
+ case 0x8c:
+ case 0x9c:
+ case 0xac:
+ case 0xbc:
+ case 0xcc:
+ case 0xdc:
+ case 0xec:
+ case 0xfc:
+ SHAD(opcode); break; // sh3/4 only
+
+ case 0x0d:
+ case 0x1d:
+ case 0x2d:
+ case 0x3d:
+ case 0x4d:
+ case 0x5d:
+ case 0x6d:
+ case 0x7d:
+ case 0x8d:
+ case 0x9d:
+ case 0xad:
+ case 0xbd:
+ case 0xcd:
+ case 0xdd:
+ case 0xed:
+ case 0xfd:
+ SHLD(opcode); break; // sh3/4 only
+
+ case 0x8e:
+ case 0x9e:
+ case 0xae:
+ case 0xbe:
+ case 0xce:
+ case 0xde:
+ case 0xee:
+ case 0xfe:
+ LDCRBANK(opcode); break; // sh3/4 only
+
+ case 0x83:
+ case 0x93:
+ case 0xa3:
+ case 0xb3:
+ case 0xc3:
+ case 0xd3:
+ case 0xe3:
+ case 0xf3:
+ STCMRBANK(opcode); break; // sh3/4 only
+
+ case 0x87:
+ case 0x97:
+ case 0xa7:
+ case 0xb7:
+ case 0xc7:
+ case 0xd7:
+ case 0xe7:
+ case 0xf7:
+ LDCMRBANK(opcode); break; // sh3/4 only
+
+ case 0x32: STCMSGR(opcode); break; // sh4 only
+ case 0x33: STCMSSR(opcode); break; // sh4 only
+ case 0x37: LDCMSSR(opcode); break; // sh4 only
+ case 0x3e: LDCSSR(opcode); break; // sh4 only
+ case 0x43: STCMSPC(opcode); break; // sh4 only
+ case 0x47: LDCMSPC(opcode); break; // sh4 only
+ case 0x4e: LDCSPC(opcode); break; // sh4 only
+ case 0x52: STSMFPUL(opcode); break; // sh4 only
+ case 0x56: LDSMFPUL(opcode); break; // sh4 only
+ case 0x5a: LDSFPUL(opcode); break; // sh4 only
+ case 0x62: STSMFPSCR(opcode); break; // sh4 only
+ case 0x66: LDSMFPSCR(opcode); break; // sh4 only
+ case 0x6a: LDSFPSCR(opcode); break; // sh4 only
+ case 0xf2: STCMDBR(opcode); break; // sh4 only
+ case 0xf6: LDCMDBR(opcode); break; // sh4 only
+ case 0xfa: LDCDBR(opcode); break; // sh4 only
+
+ }
+}
+
+inline void sh34_base_device::execute_one_f000(const uint16_t opcode)
+{
+ // the SH3 doesn't have these?
+
+ switch (opcode & 0x0f)
{
- case 0x0000:
- execute_one_0000(opcode);
- break;
-
- case 0x1000:
- MOVLS4(opcode);
- break;
-
- case 0x2000:
- switch(opcode & 0x0f)
- {
- case 0x00: MOVBS(opcode); break;
- case 0x01: MOVWS(opcode); break;
- case 0x02: MOVLS(opcode); break;
- case 0x03: NOP(opcode); break;
- case 0x04: MOVBM(opcode); break;
- case 0x05: MOVWM(opcode); break;
- case 0x06: MOVLM(opcode); break;
- case 0x07: DIV0S(opcode); break;
- case 0x08: TST(opcode); break;
- case 0x09: AND(opcode); break;
- case 0x0a: XOR(opcode); break;
- case 0x0b: OR(opcode); break;
- case 0x0c: CMPSTR(opcode); break;
- case 0x0d: XTRCT(opcode); break;
- case 0x0e: MULU(opcode); break;
- case 0x0f: MULS(opcode); break;
- }
- break;
-
- case 0x3000:
- switch(opcode & 0x0f)
- {
- case 0x00: CMPEQ(opcode); break;
- case 0x01: NOP(opcode); break;
- case 0x02: CMPHS(opcode); break;
- case 0x03: CMPGE(opcode); break;
- case 0x04: DIV1(opcode); break;
- case 0x05: DMULU(opcode); break;
- case 0x06: CMPHI(opcode); break;
- case 0x07: CMPGT(opcode); break;
- case 0x08: SUB(opcode); break;
- case 0x09: NOP(opcode); break;
- case 0x0a: SUBC(opcode); break;
- case 0x0b: SUBV(opcode); break;
- case 0x0c: ADD(opcode); break;
- case 0x0d: DMULS(opcode); break;
- case 0x0e: ADDC(opcode); break;
- case 0x0f: ADDV(opcode); break;
- }
- break;
-
- case 0x4000:
- execute_one_4000(opcode);
- break;
-
- case 0x5000:
- MOVLL4(opcode);
- break;
-
- case 0x6000:
- switch(opcode & 0x0f)
- {
- case 0x00: MOVBL(opcode); break;
- case 0x01: MOVWL(opcode); break;
- case 0x02: MOVLL(opcode); break;
- case 0x03: MOV(opcode); break;
- case 0x04: MOVBP(opcode); break;
- case 0x05: MOVWP(opcode); break;
- case 0x06: MOVLP(opcode); break;
- case 0x07: NOT(opcode); break;
- case 0x08: SWAPB(opcode); break;
- case 0x09: SWAPW(opcode); break;
- case 0x0a: NEGC(opcode); break;
- case 0x0b: NEG(opcode); break;
- case 0x0c: EXTUB(opcode); break;
- case 0x0d: EXTUW(opcode); break;
- case 0x0e: EXTSB(opcode); break;
- case 0x0f: EXTSW(opcode); break;
- }
- break;
-
- case 0x7000:
- ADDI(opcode);
- break;
-
- case 0x8000:
- switch((opcode >> 8) & 0x0f)
- {
- case 0x00: MOVBS4(opcode); break;
- case 0x01: MOVWS4(opcode); break;
- case 0x02: NOP(opcode); break;
- case 0x03: NOP(opcode); break;
- case 0x04: MOVBL4(opcode); break;
- case 0x05: MOVWL4(opcode); break;
- case 0x06: NOP(opcode); break;
- case 0x07: NOP(opcode); break;
- case 0x08: CMPIM(opcode); break;
- case 0x09: BT(opcode); break;
- case 0x0a: NOP(opcode); break;
- case 0x0b: BF(opcode); break;
- case 0x0c: NOP(opcode); break;
- case 0x0d: BTS(opcode); break;
- case 0x0e: NOP(opcode); break;
- case 0x0f: BFS(opcode); break;
- }
- break;
-
- case 0x9000:
- MOVWI(opcode);
- break;
-
- case 0xa000:
- BRA(opcode);
- break;
-
- case 0xb000:
- BSR(opcode);
- break;
-
- case 0xc000:
- switch((opcode >> 8) & 0x0f)
- {
- case 0x00: MOVBSG(opcode); break;
- case 0x01: MOVWSG(opcode); break;
- case 0x02: MOVLSG(opcode); break;
- case 0x03: TRAPA(opcode); break;
- case 0x04: MOVBLG(opcode); break;
- case 0x05: MOVWLG(opcode); break;
- case 0x06: MOVLLG(opcode); break;
- case 0x07: MOVA(opcode); break;
- case 0x08: TSTI(opcode); break;
- case 0x09: ANDI(opcode); break;
- case 0x0a: XORI(opcode); break;
- case 0x0b: ORI(opcode); break;
- case 0x0c: TSTM(opcode); break;
- case 0x0d: ANDM(opcode); break;
- case 0x0e: XORM(opcode); break;
- case 0x0f: ORM(opcode); break;
- }
- break;
-
- case 0xd000:
- MOVLI(opcode);
- break;
-
- case 0xe000:
- MOVI(opcode);
- break;
-
- case 0xf000:
- switch(opcode & 0x0f)
- {
- case 0x00: FADD(opcode); break;
- case 0x01: FSUB(opcode); break;
- case 0x02: FMUL(opcode); break;
- case 0x03: FDIV(opcode); break;
- case 0x04: FCMP_EQ(opcode); break;
- case 0x05: FCMP_GT(opcode); break;
- case 0x06: FMOVS0FR(opcode); break;
- case 0x07: FMOVFRS0(opcode); break;
- case 0x08: FMOVMRFR(opcode); break;
- case 0x09: FMOVMRIFR(opcode); break;
- case 0x0a: FMOVFRMR(opcode); break;
- case 0x0b: FMOVFRMDR(opcode); break;
- case 0x0c: FMOVFR(opcode); break;
- case 0x0d: op1111_0x13(opcode); break;
- case 0x0e: FMAC(opcode); break;
- case 0x0f: dbreak(opcode); break;
- }
- break;
+ case 0x00: FADD(opcode); break;
+ case 0x01: FSUB(opcode); break;
+ case 0x02: FMUL(opcode); break;
+ case 0x03: FDIV(opcode); break;
+ case 0x04: FCMP_EQ(opcode); break;
+ case 0x05: FCMP_GT(opcode); break;
+ case 0x06: FMOVS0FR(opcode); break;
+ case 0x07: FMOVFRS0(opcode); break;
+ case 0x08: FMOVMRFR(opcode); break;
+ case 0x09: FMOVMRIFR(opcode); break;
+ case 0x0a: FMOVFRMR(opcode); break;
+ case 0x0b: FMOVFRMDR(opcode); break;
+ case 0x0c: FMOVFR(opcode); break;
+ case 0x0d: op1111_0x13(opcode); break;
+ case 0x0e: FMAC(opcode); break;
+ case 0x0f: dbreak(opcode); break;
}
}
-
/* Execute cycles - returns number of cycles actually run */
void sh34_base_device::execute_run()
{
+ if ( m_isdrc )
+ {
+ execute_run_drc();
+ return;
+ }
+
if (m_cpu_off)
{
- m_sh4_icount = 0;
+ m_sh2_state->icount = 0;
return;
}
do
{
- m_ppc = m_pc & AM;
- debugger_instruction_hook(this, m_pc & AM);
+ m_ppc = m_sh2_state->pc & SH34_AM;
+ debugger_instruction_hook(this, m_sh2_state->pc & SH34_AM);
uint16_t opcode;
- if (!m_sh4_mmu_enabled) opcode = m_direct->read_word(m_pc & AM, WORD2_XOR_LE(0));
- else opcode = RW(m_pc); // should probably use a different function as this needs to go through the ITLB
+ if (!m_sh4_mmu_enabled) opcode = m_direct->read_word(m_sh2_state->pc & SH34_AM, WORD2_XOR_LE(0));
+ else opcode = RW(m_sh2_state->pc); // should probably use a different function as this needs to go through the ITLB
- if (m_delay)
+ if (m_sh2_state->m_delay)
{
- m_pc = m_delay;
- m_delay = 0;
+ m_sh2_state->pc = m_sh2_state->m_delay;
+ m_sh2_state->m_delay = 0;
}
else
- m_pc += 2;
+ m_sh2_state->pc += 2;
execute_one(opcode);
- if (m_test_irq && !m_delay)
+ if (m_test_irq && !m_sh2_state->m_delay)
{
sh4_check_pending_irq("mame_sh4_execute");
}
- m_sh4_icount--;
- } while( m_sh4_icount > 0 );
+ m_sh2_state->icount--;
+ } while (m_sh2_state->icount > 0);
}
void sh3be_device::execute_run()
{
+ if ( m_isdrc )
+ {
+ execute_run_drc();
+ return;
+ }
+
if (m_cpu_off)
{
- m_sh4_icount = 0;
+ m_sh2_state->icount = 0;
return;
}
do
{
- m_ppc = m_pc & AM;
- debugger_instruction_hook(this, m_pc & AM);
+ m_ppc = m_sh2_state->pc & SH34_AM;
+ debugger_instruction_hook(this, m_sh2_state->pc & SH34_AM);
- const uint16_t opcode = m_direct->read_word(m_pc & AM, WORD_XOR_LE(6));
+ const uint16_t opcode = m_direct->read_word(m_sh2_state->pc & SH34_AM, WORD_XOR_LE(6));
- if (m_delay)
+ if (m_sh2_state->m_delay)
{
- m_pc = m_delay;
- m_delay = 0;
+ m_sh2_state->pc = m_sh2_state->m_delay;
+ m_sh2_state->m_delay = 0;
}
else
- m_pc += 2;
+ m_sh2_state->pc += 2;
execute_one(opcode);
- if (m_test_irq && !m_delay)
+ if (m_test_irq && !m_sh2_state->m_delay)
{
sh4_check_pending_irq("mame_sh4_execute");
}
- m_sh4_icount--;
- } while( m_sh4_icount > 0 );
+ m_sh2_state->icount--;
+ } while (m_sh2_state->icount > 0);
}
void sh4be_device::execute_run()
{
+ if ( m_isdrc )
+ {
+ execute_run_drc();
+ return;
+ }
+
if (m_cpu_off)
{
- m_sh4_icount = 0;
+ m_sh2_state->icount = 0;
return;
}
do
{
- m_ppc = m_pc & AM;
- debugger_instruction_hook(this, m_pc & AM);
+ m_ppc = m_sh2_state->pc & SH34_AM;
+ debugger_instruction_hook(this, m_sh2_state->pc & SH34_AM);
- const uint16_t opcode = m_direct->read_word(m_pc & AM, WORD_XOR_LE(6));
+ const uint16_t opcode = m_direct->read_word(m_sh2_state->pc & SH34_AM, WORD_XOR_LE(6));
- if (m_delay)
+ if (m_sh2_state->m_delay)
{
- m_pc = m_delay;
- m_delay = 0;
+ m_sh2_state->pc = m_sh2_state->m_delay;
+ m_sh2_state->m_delay = 0;
}
else
- m_pc += 2;
+ m_sh2_state->pc += 2;
execute_one(opcode);
- if (m_test_irq && !m_delay)
+ if (m_test_irq && !m_sh2_state->m_delay)
{
sh4_check_pending_irq("mame_sh4_execute");
}
- m_sh4_icount--;
- } while( m_sh4_icount > 0 );
+ m_sh2_state->icount--;
+ } while (m_sh2_state->icount > 0);
}
void sh4_base_device::device_start()
@@ -4185,7 +2010,7 @@ void sh4_base_device::device_start()
sh34_base_device::device_start();
int i;
- for (i=0;i<64;i++)
+ for (i = 0;i < 64;i++)
{
m_utlb[i].ASID = 0;
m_utlb[i].VPN = 0;
@@ -4201,7 +2026,7 @@ void sh4_base_device::device_start()
m_utlb[i].TC = 0;
}
- for (i=0;i<64;i++)
+ for (i = 0;i < 64;i++)
{
save_item(NAME(m_utlb[i].ASID), i);
save_item(NAME(m_utlb[i].VPN), i);
@@ -4216,20 +2041,23 @@ void sh4_base_device::device_start()
save_item(NAME(m_utlb[i].SA), i);
save_item(NAME(m_utlb[i].TC), i);
}
-
}
void sh34_base_device::device_start()
{
- for (int i=0; i<3; i++)
+ m_isdrc = allow_drc();
+
+ sh_common_execution::device_start();
+
+ for (int i = 0; i < 3; i++)
{
m_timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sh34_base_device::sh4_timer_callback), this));
m_timer[i]->adjust(attotime::never, i);
}
- for (int i=0; i<4; i++)
+ for (int i = 0; i < 4; i++)
{
m_dma_timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sh34_base_device::sh4_dmac_callback), this));
m_dma_timer[i]->adjust(attotime::never, i);
@@ -4252,14 +2080,7 @@ void sh34_base_device::device_start()
m_irln = 15;
m_test_irq = 0;
- save_item(NAME(m_pc));
- save_item(NAME(m_r));
- save_item(NAME(m_sr));
- save_item(NAME(m_pr));
- save_item(NAME(m_gbr));
- save_item(NAME(m_vbr));
- save_item(NAME(m_mach));
- save_item(NAME(m_macl));
+
save_item(NAME(m_spc));
save_item(NAME(m_ssr));
save_item(NAME(m_sgr));
@@ -4267,8 +2088,7 @@ void sh34_base_device::device_start()
save_item(NAME(m_rbnk));
save_item(NAME(m_fr));
save_item(NAME(m_xf));
- save_item(NAME(m_ea));
- save_item(NAME(m_delay));
+
save_item(NAME(m_cpu_off));
save_item(NAME(m_pending_irq));
save_item(NAME(m_test_irq));
@@ -4306,7 +2126,7 @@ void sh34_base_device::device_start()
save_item(NAME(m_SH4_DMATCR3));
save_item(NAME(m_SH4_DMAOR));
save_item(NAME(m_nmi_line_state));
- save_item(NAME(m_sleep_mode));
+
save_item(NAME(m_frt_input));
save_item(NAME(m_irln));
save_item(NAME(m_internal_irq_level));
@@ -4320,11 +2140,12 @@ void sh34_base_device::device_start()
save_item(NAME(m_dma_source_increment));
save_item(NAME(m_dma_destination_increment));
save_item(NAME(m_dma_mode));
- save_item(NAME(m_sh4_icount));
+
+
save_item(NAME(m_fpu_sz));
save_item(NAME(m_fpu_pr));
save_item(NAME(m_ioport16_pullup));
- save_item(NAME( m_ioport16_direction));
+ save_item(NAME(m_ioport16_direction));
save_item(NAME(m_ioport4_pullup));
save_item(NAME(m_ioport4_direction));
save_item(NAME(m_sh4_mmu_enabled));
@@ -4333,92 +2154,70 @@ void sh34_base_device::device_start()
// Debugger state
- state_add(SH4_PC, "PC", m_pc).formatstr("%08X").callimport();
- state_add(SH4_SR, "SR", m_sr).formatstr("%08X").callimport();
- state_add(SH4_PR, "PR", m_pr).formatstr("%08X");
- state_add(SH4_GBR, "GBR", m_gbr).formatstr("%08X");
- state_add(SH4_VBR, "VBR", m_vbr).formatstr("%08X");
- state_add(SH4_DBR, "DBR", m_dbr).formatstr("%08X");
- state_add(SH4_MACH, "MACH", m_mach).formatstr("%08X");
- state_add(SH4_MACL, "MACL", m_macl).formatstr("%08X");
- state_add(SH4_R0, "R0", m_r[ 0]).formatstr("%08X");
- state_add(SH4_R1, "R1", m_r[ 1]).formatstr("%08X");
- state_add(SH4_R2, "R2", m_r[ 2]).formatstr("%08X");
- state_add(SH4_R3, "R3", m_r[ 3]).formatstr("%08X");
- state_add(SH4_R4, "R4", m_r[ 4]).formatstr("%08X");
- state_add(SH4_R5, "R5", m_r[ 5]).formatstr("%08X");
- state_add(SH4_R6, "R6", m_r[ 6]).formatstr("%08X");
- state_add(SH4_R7, "R7", m_r[ 7]).formatstr("%08X");
- state_add(SH4_R8, "R8", m_r[ 8]).formatstr("%08X");
- state_add(SH4_R9, "R9", m_r[ 9]).formatstr("%08X");
- state_add(SH4_R10, "R10", m_r[10]).formatstr("%08X");
- state_add(SH4_R11, "R11", m_r[11]).formatstr("%08X");
- state_add(SH4_R12, "R12", m_r[12]).formatstr("%08X");
- state_add(SH4_R13, "R13", m_r[13]).formatstr("%08X");
- state_add(SH4_R14, "R14", m_r[14]).formatstr("%08X");
- state_add(SH4_R15, "R15", m_r[15]).formatstr("%08X");
- state_add(SH4_EA, "EA", m_ea).formatstr("%08X");
- state_add(SH4_R0_BK0, "R0 BK 0", m_rbnk[0][0]).formatstr("%08X");
- state_add(SH4_R1_BK0, "R1 BK 0", m_rbnk[0][1]).formatstr("%08X");
- state_add(SH4_R2_BK0, "R2 BK 0", m_rbnk[0][2]).formatstr("%08X");
- state_add(SH4_R3_BK0, "R3 BK 0", m_rbnk[0][3]).formatstr("%08X");
- state_add(SH4_R4_BK0, "R4 BK 0", m_rbnk[0][4]).formatstr("%08X");
- state_add(SH4_R5_BK0, "R5 BK 0", m_rbnk[0][5]).formatstr("%08X");
- state_add(SH4_R6_BK0, "R6 BK 0", m_rbnk[0][6]).formatstr("%08X");
- state_add(SH4_R7_BK0, "R7 BK 0", m_rbnk[0][7]).formatstr("%08X");
- state_add(SH4_R0_BK1, "R0 BK 1", m_rbnk[1][0]).formatstr("%08X");
- state_add(SH4_R1_BK1, "R1 BK 1", m_rbnk[1][1]).formatstr("%08X");
- state_add(SH4_R2_BK1, "R2 BK 1", m_rbnk[1][2]).formatstr("%08X");
- state_add(SH4_R3_BK1, "R3 BK 1", m_rbnk[1][3]).formatstr("%08X");
- state_add(SH4_R4_BK1, "R4 BK 1", m_rbnk[1][4]).formatstr("%08X");
- state_add(SH4_R5_BK1, "R5 BK 1", m_rbnk[1][5]).formatstr("%08X");
- state_add(SH4_R6_BK1, "R6 BK 1", m_rbnk[1][6]).formatstr("%08X");
- state_add(SH4_R7_BK1, "R7 BK 1", m_rbnk[1][7]).formatstr("%08X");
- state_add(SH4_SPC, "SPC", m_spc).formatstr("%08X");
- state_add(SH4_SSR, "SSR", m_ssr).formatstr("%08X");
- state_add(SH4_SGR, "SGR", m_sgr).formatstr("%08X");
- state_add(SH4_FPSCR, "FPSCR", m_fpscr).formatstr("%08X");
- state_add(SH4_FPUL, "FPUL", m_fpul).formatstr("%08X");
-
- state_add(SH4_FR0, "FR0", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR1, "FR1", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR2, "FR2", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR3, "FR3", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR4, "FR4", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR5, "FR5", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR6, "FR6", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR7, "FR7", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR8, "FR8", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR9, "FR9", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR10, "FR10", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR11, "FR11", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR12, "FR12", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR13, "FR13", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR14, "FR14", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_FR15, "FR15", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF0, "XF0", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF1, "XF1", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF2, "XF2", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF3, "XF3", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF4, "XF4", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF5, "XF5", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF6, "XF6", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF7, "XF7", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF8, "XF8", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF9, "XF9", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF10, "XF10", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF11, "XF11", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF12, "XF12", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF13, "XF13", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF14, "XF14", m_debugger_temp).callimport().formatstr("%25s");
- state_add(SH4_XF15, "XF15", m_debugger_temp).callimport().formatstr("%25s");
+
+ state_add(SH4_DBR, "DBR", m_dbr).formatstr("%08X");
+
+ state_add(SH4_R0_BK0, "R0 BK 0", m_rbnk[0][0]).formatstr("%08X");
+ state_add(SH4_R1_BK0, "R1 BK 0", m_rbnk[0][1]).formatstr("%08X");
+ state_add(SH4_R2_BK0, "R2 BK 0", m_rbnk[0][2]).formatstr("%08X");
+ state_add(SH4_R3_BK0, "R3 BK 0", m_rbnk[0][3]).formatstr("%08X");
+ state_add(SH4_R4_BK0, "R4 BK 0", m_rbnk[0][4]).formatstr("%08X");
+ state_add(SH4_R5_BK0, "R5 BK 0", m_rbnk[0][5]).formatstr("%08X");
+ state_add(SH4_R6_BK0, "R6 BK 0", m_rbnk[0][6]).formatstr("%08X");
+ state_add(SH4_R7_BK0, "R7 BK 0", m_rbnk[0][7]).formatstr("%08X");
+ state_add(SH4_R0_BK1, "R0 BK 1", m_rbnk[1][0]).formatstr("%08X");
+ state_add(SH4_R1_BK1, "R1 BK 1", m_rbnk[1][1]).formatstr("%08X");
+ state_add(SH4_R2_BK1, "R2 BK 1", m_rbnk[1][2]).formatstr("%08X");
+ state_add(SH4_R3_BK1, "R3 BK 1", m_rbnk[1][3]).formatstr("%08X");
+ state_add(SH4_R4_BK1, "R4 BK 1", m_rbnk[1][4]).formatstr("%08X");
+ state_add(SH4_R5_BK1, "R5 BK 1", m_rbnk[1][5]).formatstr("%08X");
+ state_add(SH4_R6_BK1, "R6 BK 1", m_rbnk[1][6]).formatstr("%08X");
+ state_add(SH4_R7_BK1, "R7 BK 1", m_rbnk[1][7]).formatstr("%08X");
+ state_add(SH4_SPC, "SPC", m_spc).formatstr("%08X");
+ state_add(SH4_SSR, "SSR", m_ssr).formatstr("%08X");
+ state_add(SH4_SGR, "SGR", m_sgr).formatstr("%08X");
+ state_add(SH4_FPSCR, "FPSCR", m_fpscr).formatstr("%08X");
+ state_add(SH4_FPUL, "FPUL", m_fpul).formatstr("%08X");
+
+ state_add(SH4_FR0, "FR0", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR1, "FR1", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR2, "FR2", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR3, "FR3", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR4, "FR4", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR5, "FR5", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR6, "FR6", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR7, "FR7", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR8, "FR8", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR9, "FR9", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR10, "FR10", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR11, "FR11", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR12, "FR12", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR13, "FR13", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR14, "FR14", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_FR15, "FR15", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF0, "XF0", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF1, "XF1", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF2, "XF2", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF3, "XF3", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF4, "XF4", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF5, "XF5", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF6, "XF6", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF7, "XF7", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF8, "XF8", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF9, "XF9", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF10, "XF10", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF11, "XF11", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF12, "XF12", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF13, "XF13", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF14, "XF14", m_debugger_temp).callimport().formatstr("%25s");
+ state_add(SH4_XF15, "XF15", m_debugger_temp).callimport().formatstr("%25s");
state_add(STATE_GENPC, "GENPC", m_debugger_temp).callimport().callexport().noshow();
- state_add(STATE_GENPCBASE, "CURPC", m_ppc).noshow();
- state_add(STATE_GENSP, "GENSP", m_r[15]).noshow();
- state_add(STATE_GENFLAGS, "GENFLAGS", m_sr).formatstr("%20s").noshow();
+ //state_add(STATE_GENPCBASE, "CURPC", m_ppc).noshow();
+ state_add( STATE_GENPCBASE, "CURPC", m_sh2_state->pc ).callimport().noshow();
- m_icountptr = &m_sh4_icount;
+
+ drc_start();
}
void sh34_base_device::state_import(const device_state_entry &entry)
@@ -4432,12 +2231,12 @@ void sh34_base_device::state_import(const device_state_entry &entry)
switch (entry.index())
{
case STATE_GENPC:
- m_pc = m_debugger_temp;
+ m_sh2_state->pc = m_debugger_temp;
case SH4_PC:
- m_delay = 0;
+ m_sh2_state->m_delay = 0;
break;
- case SH4_SR:
+ case SH_SR:
sh4_exception_recompute();
sh4_check_pending_irq("sh4_set_info");
break;
@@ -4577,7 +2376,7 @@ void sh34_base_device::state_export(const device_state_entry &entry)
switch (entry.index())
{
case STATE_GENPC:
- m_debugger_temp = (m_pc & AM);
+ m_debugger_temp = (m_sh2_state->pc & SH34_AM);
break;
}
}
@@ -4594,15 +2393,15 @@ void sh34_base_device::state_string_export(const device_state_entry &entry, std:
{
case STATE_GENFLAGS:
str = string_format("%s%s%s%s%c%c%d%c%c",
- m_sr & MD ? "MD ":" ",
- m_sr & sRB ? "RB ":" ",
- m_sr & BL ? "BL ":" ",
- m_sr & FD ? "FD ":" ",
- m_sr & M ? 'M':'.',
- m_sr & Q ? 'Q':'.',
- (m_sr & I) >> 4,
- m_sr & S ? 'S':'.',
- m_sr & T ? 'T':'.');
+ m_sh2_state->sr & MD ? "MD ":" ",
+ m_sh2_state->sr & sRB ? "RB ":" ",
+ m_sh2_state->sr & BL ? "BL ":" ",
+ m_sh2_state->sr & FD ? "FD ":" ",
+ m_sh2_state->sr & SH_M ? 'M':'.',
+ m_sh2_state->sr & SH_Q ? 'Q':'.',
+ (m_sh2_state->sr & SH_I) >> 4,
+ m_sh2_state->sr & SH_S ? 'S':'.',
+ m_sh2_state->sr & SH_T ? 'T':'.');
break;
case SH4_FR0:
@@ -4736,8 +2535,1375 @@ void sh34_base_device::state_string_export(const device_state_entry &entry, std:
}
}
-
+/*
void sh34_base_device::sh4_set_ftcsr_callback(sh4_ftcsr_callback callback)
{
m_ftcsr_read_callback = callback;
}
+*/
+
+using namespace uml;
+
+const opcode_desc* sh4be_device::get_desclist(offs_t pc)
+{
+ return m_drcfe->describe_code(pc);
+}
+
+void sh4be_device::init_drc_frontend()
+{
+ m_drcfe = std::make_unique<sh4be_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
+}
+
+
+const opcode_desc* sh4_device::get_desclist(offs_t pc)
+{
+ return m_drcfe->describe_code(pc);
+}
+
+void sh4_device::init_drc_frontend()
+{
+ m_drcfe = std::make_unique<sh4_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
+}
+
+const opcode_desc* sh3be_device::get_desclist(offs_t pc)
+{
+ return m_drcfe->describe_code(pc);
+}
+
+void sh3be_device::init_drc_frontend()
+{
+ m_drcfe = std::make_unique<sh4be_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
+}
+
+const opcode_desc* sh3_device::get_desclist(offs_t pc)
+{
+ return m_drcfe->describe_code(pc);
+}
+
+void sh3_device::init_drc_frontend()
+{
+ m_drcfe = std::make_unique<sh4_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
+}
+
+/*-------------------------------------------------
+ generate_update_cycles - generate code to
+ subtract cycles from the icount and generate
+ an exception if out
+-------------------------------------------------*/
+
+void sh34_base_device::func_CHECKIRQ() { if (m_test_irq) sh4_check_pending_irq("mame_sh4_execute"); }
+static void cfunc_CHECKIRQ(void *param) { ((sh34_base_device *)param)->func_CHECKIRQ(); };
+
+void sh34_base_device::generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception)
+{
+ /* TODO: this is likely wrong? - I've not seen it called when compiler->checkints is true */
+
+ /* check full interrupts if pending */
+ if (compiler->checkints)
+ {
+ compiler->checkints = false;
+
+ /* param is pc + 2 (the opcode after the current one)
+ as we're calling from opcode handlers here that will point to the current opcode instead
+ but I believe the exception functoin requires it to point to the next one so update the
+ local copy of the PC variable here for that? */
+ UML_MOV(block, mem(&m_sh2_state->pc), param);
+
+ // save_fast_iregs(block);
+ UML_CALLC(block, cfunc_CHECKIRQ, this);
+ load_fast_iregs(block);
+
+ /* generate a hash jump via the current mode and PC
+ pc should be pointing to either the exception address
+ or have been left on the next PC set above? */
+ UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // hashjmp <mode>,<pc>,nocode
+ }
+
+ /* account for cycles */
+ if (compiler->cycles > 0)
+ {
+ UML_SUB(block, mem(&m_sh2_state->icount), mem(&m_sh2_state->icount), MAPVAR_CYCLES); // sub icount,icount,cycles
+ UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0
+ if (allow_exception)
+ UML_EXHc(block, COND_S, *m_out_of_cycles, param);
+ // exh out_of_cycles,nextpc
+ }
+ compiler->cycles = 0;
+}
+
+/*-------------------------------------------------
+ static_generate_entry_point - generate a
+ static entry point
+-------------------------------------------------*/
+
+
+void sh34_base_device::static_generate_entry_point()
+{
+
+ drcuml_state *drcuml = m_drcuml.get();
+ //code_label skip = 1;
+ drcuml_block *block;
+
+ /* begin generating */
+ block = drcuml->begin_block(200);
+
+ /* forward references */
+ alloc_handle(drcuml, &m_nocode, "nocode");
+ alloc_handle(drcuml, &m_write32, "write32"); // necessary?
+ alloc_handle(drcuml, &m_entry, "entry");
+ UML_HANDLE(block, *m_entry); // handle entry
+
+ UML_CALLC(block, cfunc_CHECKIRQ, this);
+ load_fast_iregs(block);
+
+ /* generate a hash jump via the current mode and PC */
+ UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // hashjmp <mode>,<pc>,nocode
+
+ block->end();
+
+}
+
+
+/*------------------------------------------------------------------
+ static_generate_memory_accessor
+------------------------------------------------------------------*/
+
+void sh34_base_device::static_generate_memory_accessor(int size, int iswrite, const char *name, code_handle **handleptr)
+{
+ /* on entry, address is in I0; data for writes is in I1 */
+ /* on exit, read result is in I0 */
+ /* routine trashes I0 */
+ drcuml_state *drcuml = m_drcuml.get();
+ drcuml_block *block;
+ int label = 1;
+
+ /* begin generating */
+ block = drcuml->begin_block(1024);
+
+ /* add a global entry for this */
+ alloc_handle(drcuml, handleptr, name);
+ UML_HANDLE(block, **handleptr); // handle *handleptr
+
+#if 0
+ if (A >= 0xe0000000)
+ {
+ m_program->write_word(A, V);
+ return;
+ }
+
+ if (A >= 0x80000000) // P1/P2/P3 region
+ {
+ m_program->write_word(A & SH34_AM, V);
+ }
+ else
+ {
+ // MMU handling
+ m_program->write_word(A & SH34_AM, V);
+ }
+#endif
+
+ UML_CMP(block, I0, 0xe0000000);
+ UML_JMPc(block, COND_AE, label);
+
+ UML_AND(block, I0, I0, SH34_AM); // and r0, r0, #AM (0x1fffffff)
+
+ UML_LABEL(block, label++); // label:
+
+ for (auto & elem : m_fastram)
+ {
+ if (elem.base != nullptr && (!iswrite || !elem.readonly))
+ {
+ void *fastbase = (uint8_t *)elem.base - elem.start;
+ uint32_t skip = label++;
+ if (elem.end != 0xffffffff)
+ {
+ UML_CMP(block, I0, elem.end); // cmp i0,end
+ UML_JMPc(block, COND_A, skip); // ja skip
+ }
+ if (elem.start != 0x00000000)
+ {
+ UML_CMP(block, I0, elem.start);// cmp i0,fastram_start
+ UML_JMPc(block, COND_B, skip); // jb skip
+ }
+
+ if (!iswrite)
+ {
+ if (size == 1)
+ {
+ UML_XOR(block, I0, I0, m_bigendian ? BYTE8_XOR_BE(0) : BYTE8_XOR_LE(0));
+ UML_LOAD(block, I0, fastbase, I0, SIZE_BYTE, SCALE_x1); // load i0,fastbase,i0,byte
+ }
+ else if (size == 2)
+ {
+ UML_XOR(block, I0, I0, m_bigendian ? WORD2_XOR_BE(0) : WORD2_XOR_LE(0));
+ UML_LOAD(block, I0, fastbase, I0, SIZE_WORD, SCALE_x1); // load i0,fastbase,i0,word_x1
+ }
+ else if (size == 4)
+ {
+
+ UML_XOR(block, I0, I0, m_bigendian ? DWORD_XOR_BE(0) : DWORD_XOR_LE(0));
+ UML_LOAD(block, I0, fastbase, I0, SIZE_DWORD, SCALE_x1); // load i0,fastbase,i0,dword_x1
+ }
+ UML_RET(block); // ret
+ }
+ else
+ {
+ if (size == 1)
+ {
+ UML_XOR(block, I0, I0, m_bigendian ? BYTE8_XOR_BE(0) : BYTE8_XOR_LE(0));
+ UML_STORE(block, fastbase, I0, I1, SIZE_BYTE, SCALE_x1);// store fastbase,i0,i1,byte
+ }
+ else if (size == 2)
+ {
+ UML_XOR(block, I0, I0, m_bigendian ? WORD2_XOR_BE(0) : WORD2_XOR_LE(0));
+ UML_STORE(block, fastbase, I0, I1, SIZE_WORD, SCALE_x1);// store fastbase,i0,i1,word_x1
+ }
+ else if (size == 4)
+ {
+ UML_XOR(block, I0, I0, m_bigendian ? DWORD_XOR_BE(0) : DWORD_XOR_LE(0));
+ UML_STORE(block, fastbase, I0, I1, SIZE_DWORD, SCALE_x1); // store fastbase,i0,i1,dword_x1
+ }
+ UML_RET(block); // ret
+ }
+
+ UML_LABEL(block, skip); // skip:
+ }
+ }
+
+ if (iswrite)
+ {
+ switch (size)
+ {
+ case 1:
+ UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM); // write r0, r1, program_byte
+ break;
+
+ case 2:
+ UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); // write r0, r1, program_word
+ break;
+
+ case 4:
+ UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); // write r0, r1, program_dword
+ break;
+ }
+ }
+ else
+ {
+ switch (size)
+ {
+ case 1:
+ UML_READ(block, I0, I0, SIZE_BYTE, SPACE_PROGRAM); // read r0, program_byte
+ break;
+
+ case 2:
+ UML_READ(block, I0, I0, SIZE_WORD, SPACE_PROGRAM); // read r0, program_word
+ break;
+
+ case 4:
+ UML_READ(block, I0, I0, SIZE_DWORD, SPACE_PROGRAM); // read r0, program_dword
+ break;
+ }
+ }
+
+ UML_RET(block); // ret
+
+ block->end();
+}
+
+bool sh34_base_device::generate_group_0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ switch (opcode & 0xff)
+ {
+ default:
+ // fall through to SH2 handlers
+ return sh_common_execution::generate_group_0(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+
+ case 0x52:
+ case 0x62:
+ case 0x43:
+ case 0x63:
+ case 0xe3:
+ case 0x68:
+ case 0xe8:
+ case 0x4a:
+ case 0xca:
+ return true; // ILLEGAL(); break; // illegal on sh4
+
+ case 0x93:
+ case 0xa3:
+ case 0xb3:
+ return true; // TODO(opcode); break;
+
+ case 0x82:
+ case 0x92:
+ case 0xa2:
+ case 0xb2:
+ case 0xc2:
+ case 0xd2:
+ case 0xe2:
+ case 0xf2:
+ return generate_group_0_STCRBANK(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+
+ case 0x32: return generate_group_0_STCSSR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+ case 0x42: return generate_group_0_STCSPC(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+ case 0x83: return generate_group_0_PREFM(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+ case 0xc3: return generate_group_0_MOVCAL(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+
+ case 0x38:
+ case 0xb8:
+ return generate_group_0_LDTLB(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+
+ case 0x48:
+ case 0xc8:
+ return generate_group_0_CLRS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+
+ case 0x58:
+ case 0xd8:
+ return generate_group_0_SETS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+
+ case 0x3a:
+ case 0xba:
+ return generate_group_0_STCSGR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+
+ case 0x5a:
+ case 0xda:
+ return generate_group_0_STSFPUL(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+
+ case 0x6a:
+ case 0xea:
+ return generate_group_0_STSFPSCR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+
+ case 0x7a:
+ case 0xfa:
+ return generate_group_0_STCDBR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+ }
+
+ return false;
+}
+
+void sh34_base_device::func_STCRBANK() { STCRBANK(m_sh2_state->arg0); }
+static void cfunc_STCRBANK(void *param) { ((sh34_base_device *)param)->func_STCRBANK(); };
+
+bool sh34_base_device::generate_group_0_STCRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCRBANK, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STCSSR() { STCSSR(m_sh2_state->arg0); }
+static void cfunc_STCSSR(void *param) { ((sh34_base_device *)param)->func_STCSSR(); };
+
+bool sh34_base_device::generate_group_0_STCSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCSSR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STCSPC() { STCSPC(m_sh2_state->arg0); }
+static void cfunc_STCSPC(void *param) { ((sh34_base_device *)param)->func_STCSPC(); };
+
+bool sh34_base_device::generate_group_0_STCSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCSPC, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_PREFM() { PREFM(m_sh2_state->arg0); }
+static void cfunc_PREFM(void *param) { ((sh34_base_device *)param)->func_PREFM(); };
+
+bool sh34_base_device::generate_group_0_PREFM(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_PREFM, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_MOVCAL() { MOVCAL(m_sh2_state->arg0); }
+static void cfunc_MOVCAL(void *param) { ((sh34_base_device *)param)->func_MOVCAL(); };
+
+bool sh34_base_device::generate_group_0_MOVCAL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_MOVCAL, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDTLB() { LDTLB(m_sh2_state->arg0); }
+static void cfunc_LDTLB(void *param) { ((sh34_base_device *)param)->func_LDTLB(); };
+
+bool sh34_base_device::generate_group_0_LDTLB(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDTLB, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_CLRS() { CLRS(m_sh2_state->arg0); }
+static void cfunc_CLRS(void *param) { ((sh34_base_device *)param)->func_CLRS(); };
+
+bool sh34_base_device::generate_group_0_CLRS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_CLRS, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_SETS() { SETS(m_sh2_state->arg0); }
+static void cfunc_SETS(void *param) { ((sh34_base_device *)param)->func_SETS(); };
+
+bool sh34_base_device::generate_group_0_SETS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_SETS, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STCSGR() { STCSGR(m_sh2_state->arg0); }
+static void cfunc_STCSGR(void *param) { ((sh34_base_device *)param)->func_STCSGR(); };
+
+bool sh34_base_device::generate_group_0_STCSGR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCSGR, this);
+ load_fast_iregs(block);
+ return true;
+
+}
+
+void sh34_base_device::func_STSFPUL() { STSFPUL(m_sh2_state->arg0); }
+static void cfunc_STSFPUL(void *param) { ((sh34_base_device *)param)->func_STSFPUL(); };
+
+bool sh34_base_device::generate_group_0_STSFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STSFPUL, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STSFPSCR() { STSFPSCR(m_sh2_state->arg0); }
+static void cfunc_STSFPSCR(void *param) { ((sh34_base_device *)param)->func_STSFPSCR(); };
+
+bool sh34_base_device::generate_group_0_STSFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STSFPSCR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STCDBR() { STCDBR(m_sh2_state->arg0); }
+static void cfunc_STCDBR(void *param) { ((sh34_base_device *)param)->func_STCDBR(); };
+
+bool sh34_base_device::generate_group_0_STCDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCDBR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_RTE() { RTE(); }
+static void cfunc_RTE(void *param) { ((sh34_base_device *)param)->func_RTE(); };
+
+bool sh34_base_device::generate_group_0_RTE(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ generate_delay_slot(block, compiler, desc, 0xffffffff);
+ save_fast_iregs(block);
+ UML_CALLC(block, cfunc_RTE, this);
+ load_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->pc), mem(&m_sh2_state->m_delay));
+ generate_update_cycles(block, compiler, mem(&m_sh2_state->ea), true); // <subtract cycles>
+ UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // and jump to the "resume PC"
+ return true;
+}
+
+void sh34_base_device::func_TRAPA() { TRAPA(m_sh2_state->arg0 & 0xff); }
+static void cfunc_TRAPA(void *param) { ((sh34_base_device *)param)->func_TRAPA(); };
+
+bool sh34_base_device::generate_group_12_TRAPA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->pc), desc->pc + 2); // copy the PC because we need to use it
+ UML_CALLC(block, cfunc_TRAPA, this);
+ load_fast_iregs(block);
+ UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode);
+ return true;
+}
+
+void sh34_base_device::func_LDCSR() { LDCSR(m_sh2_state->arg0); }
+static void cfunc_LDCSR(void *param) { ((sh34_base_device *)param)->func_LDCSR(); };
+
+bool sh34_base_device::generate_group_4_LDCSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCSR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDCMSR() { LDCMSR(m_sh2_state->arg0); }
+static void cfunc_LDCMSR(void *param) { ((sh34_base_device *)param)->func_LDCMSR(); };
+
+bool sh34_base_device::generate_group_4_LDCMSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCMSR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_SHAD() { SHAD(m_sh2_state->arg0); }
+static void cfunc_SHAD(void *param) { ((sh34_base_device *)param)->func_SHAD(); };
+
+bool sh34_base_device::generate_group_4_SHAD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_SHAD, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_SHLD() { SHLD(m_sh2_state->arg0); }
+static void cfunc_SHLD(void *param) { ((sh34_base_device *)param)->func_SHLD(); };
+
+bool sh34_base_device::generate_group_4_SHLD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_SHLD, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+bool sh34_base_device::generate_group_4(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ switch (opcode & 0xff)
+ {
+ default: // LDCMSR (0x0e) has sh2/4 flag difference
+ // fall through to SH2 handlers
+ return sh_common_execution::generate_group_4(block, compiler, desc, opcode, in_delay_slot, ovrpc); break;
+
+ case 0x42:
+ case 0x46:
+ case 0x4a:
+ case 0x53:
+ case 0x57:
+ case 0x5e:
+ case 0x63:
+ case 0x67:
+ case 0x6e:
+ case 0x82:
+ case 0x86:
+ case 0x8a:
+ case 0x92:
+ case 0x96:
+ case 0x9a:
+ case 0xa2:
+ case 0xa6:
+ case 0xaa:
+ case 0xc2:
+ case 0xc6:
+ case 0xca:
+ case 0xd2:
+ case 0xd6:
+ case 0xda:
+ case 0xe2:
+ case 0xe6:
+ case 0xea:
+ return true; // ILLEGAL(); break; // defined as illegal on SH4
+
+ case 0x0c:
+ case 0x1c:
+ case 0x2c:
+ case 0x3c:
+ case 0x4c:
+ case 0x5c:
+ case 0x6c:
+ case 0x7c:
+ case 0x8c:
+ case 0x9c:
+ case 0xac:
+ case 0xbc:
+ case 0xcc:
+ case 0xdc:
+ case 0xec:
+ case 0xfc:
+ return generate_group_4_SHAD(block, compiler, desc, opcode, in_delay_slot, ovrpc); break;
+
+ case 0x0d:
+ case 0x1d:
+ case 0x2d:
+ case 0x3d:
+ case 0x4d:
+ case 0x5d:
+ case 0x6d:
+ case 0x7d:
+ case 0x8d:
+ case 0x9d:
+ case 0xad:
+ case 0xbd:
+ case 0xcd:
+ case 0xdd:
+ case 0xed:
+ case 0xfd:
+ return generate_group_4_SHLD(block, compiler, desc, opcode, in_delay_slot, ovrpc); break;
+
+ case 0x8e:
+ case 0x9e:
+ case 0xae:
+ case 0xbe:
+ case 0xce:
+ case 0xde:
+ case 0xee:
+ case 0xfe:
+ return generate_group_4_LDCRBANK(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh3/4 only
+
+ case 0x83:
+ case 0x93:
+ case 0xa3:
+ case 0xb3:
+ case 0xc3:
+ case 0xd3:
+ case 0xe3:
+ case 0xf3:
+ return generate_group_4_STCMRBANK(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh3/4 only
+
+ case 0x87:
+ case 0x97:
+ case 0xa7:
+ case 0xb7:
+ case 0xc7:
+ case 0xd7:
+ case 0xe7:
+ case 0xf7:
+ return generate_group_4_LDCMRBANK(block, compiler, desc, opcode, in_delay_slot, ovrpc); // sh4 only
+
+ case 0x32: return generate_group_4_STCMSGR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x33: return generate_group_4_STCMSSR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x37: return generate_group_4_LDCMSSR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x3e: return generate_group_4_LDCSSR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x43: return generate_group_4_STCMSPC(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x47: return generate_group_4_LDCMSPC(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x4e: return generate_group_4_LDCSPC(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x52: return generate_group_4_STSMFPUL(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x56: return generate_group_4_LDSMFPUL(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x5a: return generate_group_4_LDSFPUL(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x62: return generate_group_4_STSMFPSCR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x66: return generate_group_4_LDSMFPSCR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x6a: return generate_group_4_LDSFPSCR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0xf2: return generate_group_4_STCMDBR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0xf6: return generate_group_4_LDCMDBR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0xfa: return generate_group_4_LDCDBR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ }
+ return false;
+}
+
+
+void sh34_base_device::func_LDCRBANK() { LDCRBANK(m_sh2_state->arg0); }
+static void cfunc_LDCRBANK(void *param) { ((sh34_base_device *)param)->func_LDCRBANK(); };
+
+bool sh34_base_device::generate_group_4_LDCRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCRBANK, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STCMRBANK() { STCMRBANK(m_sh2_state->arg0); }
+static void cfunc_STCMRBANK(void *param) { ((sh34_base_device *)param)->func_STCMRBANK(); };
+
+bool sh34_base_device::generate_group_4_STCMRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCMRBANK, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDCMRBANK() { LDCMRBANK(m_sh2_state->arg0); }
+static void cfunc_LDCMRBANK(void *param) { ((sh34_base_device *)param)->func_LDCMRBANK(); };
+
+bool sh34_base_device::generate_group_4_LDCMRBANK(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCMRBANK, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STCMSGR() { STCMSGR(m_sh2_state->arg0); }
+static void cfunc_STCMSGR(void *param) { ((sh34_base_device *)param)->func_STCMSGR(); };
+
+bool sh34_base_device::generate_group_4_STCMSGR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCMSGR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STCMSSR() { STCMSSR(m_sh2_state->arg0); }
+static void cfunc_STCMSSR(void *param) { ((sh34_base_device *)param)->func_STCMSSR(); };
+
+bool sh34_base_device::generate_group_4_STCMSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCMSSR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDCMSSR() { LDCMSSR(m_sh2_state->arg0); }
+static void cfunc_LDCMSSR(void *param) { ((sh34_base_device *)param)->func_LDCMSSR(); };
+
+bool sh34_base_device::generate_group_4_LDCMSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCMSSR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDCSSR() { LDCSSR(m_sh2_state->arg0); }
+static void cfunc_LDCSSR(void *param) { ((sh34_base_device *)param)->func_LDCSSR(); };
+
+bool sh34_base_device::generate_group_4_LDCSSR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCSSR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STCMSPC() { STCMSPC(m_sh2_state->arg0); }
+static void cfunc_STCMSPC(void *param) { ((sh34_base_device *)param)->func_STCMSPC(); };
+
+bool sh34_base_device::generate_group_4_STCMSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCMSPC, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDCMSPC() { LDCMSPC(m_sh2_state->arg0); }
+static void cfunc_LDCMSPC(void *param) { ((sh34_base_device *)param)->func_LDCMSPC(); };
+
+bool sh34_base_device::generate_group_4_LDCMSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCMSPC, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDCSPC() { LDCSPC(m_sh2_state->arg0); }
+static void cfunc_LDCSPC(void *param) { ((sh34_base_device *)param)->func_LDCSPC(); };
+
+bool sh34_base_device::generate_group_4_LDCSPC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCSPC, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STSMFPUL() { STSMFPUL(m_sh2_state->arg0); }
+static void cfunc_STSMFPUL(void *param) { ((sh34_base_device *)param)->func_STSMFPUL(); };
+
+bool sh34_base_device::generate_group_4_STSMFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STSMFPUL, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDSMFPUL() { LDSMFPUL(m_sh2_state->arg0); }
+static void cfunc_LDSMFPUL(void *param) { ((sh34_base_device *)param)->func_LDSMFPUL(); };
+
+bool sh34_base_device::generate_group_4_LDSMFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDSMFPUL, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDSFPUL() { LDSFPUL(m_sh2_state->arg0); }
+static void cfunc_LDSFPUL(void *param) { ((sh34_base_device *)param)->func_LDSFPUL(); };
+
+bool sh34_base_device::generate_group_4_LDSFPUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDSFPUL, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STSMFPSCR() { STSMFPSCR(m_sh2_state->arg0); }
+static void cfunc_STSMFPSCR(void *param) { ((sh34_base_device *)param)->func_STSMFPSCR(); };
+
+bool sh34_base_device::generate_group_4_STSMFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STSMFPSCR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDSMFPSCR() { LDSMFPSCR(m_sh2_state->arg0); }
+static void cfunc_LDSMFPSCR(void *param) { ((sh34_base_device *)param)->func_LDSMFPSCR(); };
+
+
+bool sh34_base_device::generate_group_4_LDSMFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDSMFPSCR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+
+void sh34_base_device::func_LDSFPSCR() { LDSFPSCR(m_sh2_state->arg0); }
+static void cfunc_LDSFPSCR(void *param) { ((sh34_base_device *)param)->func_LDSFPSCR(); };
+
+bool sh34_base_device::generate_group_4_LDSFPSCR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDSFPSCR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_STCMDBR() { STCMDBR(m_sh2_state->arg0); }
+static void cfunc_STCMDBR(void *param) { ((sh34_base_device *)param)->func_STCMDBR(); };
+
+bool sh34_base_device::generate_group_4_STCMDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_STCMDBR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDCMDBR() { LDCMDBR(m_sh2_state->arg0); }
+static void cfunc_LDCMDBR(void *param) { ((sh34_base_device *)param)->func_LDCMDBR(); };
+
+bool sh34_base_device::generate_group_4_LDCMDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCMDBR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_LDCDBR() { LDCDBR(m_sh2_state->arg0); }
+static void cfunc_LDCDBR(void *param) { ((sh34_base_device *)param)->func_LDCDBR(); };
+
+bool sh34_base_device::generate_group_4_LDCDBR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_LDCDBR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+bool sh34_base_device::generate_group_15(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ switch (opcode & 0x0f)
+ {
+ case 0x00: return generate_group_15_FADD(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x01: return generate_group_15_FSUB(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x02: return generate_group_15_FMUL(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x03: return generate_group_15_FDIV(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x04: return generate_group_15_FCMP_EQ(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x05: return generate_group_15_FCMP_GT(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x06: return generate_group_15_FMOVS0FR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x07: return generate_group_15_FMOVFRS0(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x08: return generate_group_15_FMOVMRFR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x09: return generate_group_15_FMOVMRIFR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x0a: return generate_group_15_FMOVFRMR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x0b: return generate_group_15_FMOVFRMDR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x0c: return generate_group_15_FMOVFR(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x0d: return generate_group_15_op1111_0x13(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x0e: return generate_group_15_FMAC(block, compiler, desc, opcode, in_delay_slot, ovrpc);
+ case 0x0f:
+ return true;
+ //if (opcode == 0xffff) return true; // atomiswave uses ffff as NOP?
+ //return false; // dbreak(opcode); break;
+ }
+ return false;
+}
+
+void sh34_base_device::func_FADD() { FADD(m_sh2_state->arg0); }
+static void cfunc_FADD(void *param) { ((sh34_base_device *)param)->func_FADD(); };
+
+bool sh34_base_device::generate_group_15_FADD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FADD, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FSUB() { FSUB(m_sh2_state->arg0); }
+static void cfunc_FSUB(void *param) { ((sh34_base_device *)param)->func_FSUB(); };
+
+bool sh34_base_device::generate_group_15_FSUB(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FSUB, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FMUL() { FMUL(m_sh2_state->arg0); }
+static void cfunc_FMUL(void *param) { ((sh34_base_device *)param)->func_FMUL(); };
+
+bool sh34_base_device::generate_group_15_FMUL(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FMUL, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FDIV() { FDIV(m_sh2_state->arg0); }
+static void cfunc_FDIV(void *param) { ((sh34_base_device *)param)->func_FDIV(); };
+
+bool sh34_base_device::generate_group_15_FDIV(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FDIV, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FCMP_EQ() { FCMP_EQ(m_sh2_state->arg0); }
+static void cfunc_FCMP_EQ(void *param) { ((sh34_base_device *)param)->func_FCMP_EQ(); };
+
+bool sh34_base_device::generate_group_15_FCMP_EQ(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FCMP_EQ, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FCMP_GT() { FCMP_GT(m_sh2_state->arg0); }
+static void cfunc_FCMP_GT(void *param) { ((sh34_base_device *)param)->func_FCMP_GT(); };
+
+bool sh34_base_device::generate_group_15_FCMP_GT(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FCMP_GT, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FMOVS0FR() { FMOVS0FR(m_sh2_state->arg0); }
+static void cfunc_FMOVS0FR(void *param) { ((sh34_base_device *)param)->func_FMOVS0FR(); };
+
+bool sh34_base_device::generate_group_15_FMOVS0FR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FMOVS0FR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FMOVFRS0() { FMOVFRS0(m_sh2_state->arg0); }
+static void cfunc_FMOVFRS0(void *param) { ((sh34_base_device *)param)->func_FMOVFRS0(); };
+
+bool sh34_base_device::generate_group_15_FMOVFRS0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FMOVFRS0, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FMOVMRFR() { FMOVMRFR(m_sh2_state->arg0); }
+static void cfunc_FMOVMRFR(void *param) { ((sh34_base_device *)param)->func_FMOVMRFR(); };
+
+bool sh34_base_device::generate_group_15_FMOVMRFR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FMOVMRFR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FMOVMRIFR() { FMOVMRIFR(m_sh2_state->arg0); }
+static void cfunc_FMOVMRIFR(void *param) { ((sh34_base_device *)param)->func_FMOVMRIFR(); };
+
+bool sh34_base_device::generate_group_15_FMOVMRIFR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FMOVMRIFR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FMOVFRMR() { FMOVFRMR(m_sh2_state->arg0); }
+static void cfunc_FMOVFRMR(void *param) { ((sh34_base_device *)param)->func_FMOVFRMR(); };
+
+bool sh34_base_device::generate_group_15_FMOVFRMR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FMOVFRMR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FMOVFRMDR() { FMOVFRMDR(m_sh2_state->arg0); }
+static void cfunc_FMOVFRMDR(void *param) { ((sh34_base_device *)param)->func_FMOVFRMDR(); };
+
+bool sh34_base_device::generate_group_15_FMOVFRMDR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FMOVFRMDR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FMOVFR() { FMOVFR(m_sh2_state->arg0); }
+static void cfunc_FMOVFR(void *param) { ((sh34_base_device *)param)->func_FMOVFR(); };
+
+bool sh34_base_device::generate_group_15_FMOVFR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FMOVFR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FMAC() { FMAC(m_sh2_state->arg0); }
+static void cfunc_FMAC(void *param) { ((sh34_base_device *)param)->func_FMAC(); };
+
+bool sh34_base_device::generate_group_15_FMAC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FMAC, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+bool sh34_base_device::generate_group_15_op1111_0x13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ switch ((opcode >> 4) & 0x0f)
+ {
+ case 0x00: return generate_group_15_op1111_0x13_FSTS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSTS(opcode); break;
+ case 0x01: return generate_group_15_op1111_0x13_FLDS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FLDS(opcode); break;
+ case 0x02: return generate_group_15_op1111_0x13_FLOAT(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FLOAT(opcode); break;
+ case 0x03: return generate_group_15_op1111_0x13_FTRC(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FTRC(opcode); break;
+ case 0x04: return generate_group_15_op1111_0x13_FNEG(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FNEG(opcode); break;
+ case 0x05: return generate_group_15_op1111_0x13_FABS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FABS(opcode); break;
+ case 0x06: return generate_group_15_op1111_0x13_FSQRT(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSQRT(opcode); break;
+ case 0x07: return generate_group_15_op1111_0x13_FSRRA(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSRRA(opcode); break;
+ case 0x08: return generate_group_15_op1111_0x13_FLDI0(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FLDI0(opcode); break;
+ case 0x09: return generate_group_15_op1111_0x13_FLDI1(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FLDI1(opcode); break;
+ case 0x0a: return generate_group_15_op1111_0x13_FCNVSD(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FCNVSD(opcode); break;
+ case 0x0b: return generate_group_15_op1111_0x13_FCNVDS(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FCNVDS(opcode); break;
+ case 0x0c: return false; // dbreak(opcode); break;
+ case 0x0d: return false; //dbreak(opcode); break;
+ case 0x0e: return generate_group_15_op1111_0x13_FIPR(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FIPR(opcode); break;
+ case 0x0f: return generate_group_15_op1111_0x13_op1111_0xf13(block, compiler, desc, opcode, in_delay_slot, ovrpc); // op1111_0xf13(opcode); break;
+ }
+ return false;
+}
+
+void sh34_base_device::func_FSTS() { FSTS(m_sh2_state->arg0); }
+static void cfunc_FSTS(void *param) { ((sh34_base_device *)param)->func_FSTS(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FSTS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FSTS, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FLDS() { FLDS(m_sh2_state->arg0); }
+static void cfunc_FLDS(void *param) { ((sh34_base_device *)param)->func_FLDS(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FLDS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FLDS, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FLOAT() { FLOAT(m_sh2_state->arg0); }
+static void cfunc_FLOAT(void *param) { ((sh34_base_device *)param)->func_FLOAT(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FLOAT(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FLOAT, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FTRC() { FTRC(m_sh2_state->arg0); }
+static void cfunc_FTRC(void *param) { ((sh34_base_device *)param)->func_FTRC(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FTRC(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FTRC, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FNEG() { FNEG(m_sh2_state->arg0); }
+static void cfunc_FNEG(void *param) { ((sh34_base_device *)param)->func_FNEG(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FNEG(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FNEG, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FABS() { FABS(m_sh2_state->arg0); }
+static void cfunc_FABS(void *param) { ((sh34_base_device *)param)->func_FABS(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FABS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FABS, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FSQRT() { FSQRT(m_sh2_state->arg0); }
+static void cfunc_FSQRT(void *param) { ((sh34_base_device *)param)->func_FSQRT(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FSQRT(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FSQRT, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FSRRA() { FSRRA(m_sh2_state->arg0); }
+static void cfunc_FSRRA(void *param) { ((sh34_base_device *)param)->func_FSRRA(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FSRRA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FSRRA, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FLDI0() { FLDI0(m_sh2_state->arg0); }
+static void cfunc_FLDI0(void *param) { ((sh34_base_device *)param)->func_FLDI0(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FLDI0(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FLDI0, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FLDI1() { FLDI1(m_sh2_state->arg0); }
+static void cfunc_FLDI1(void *param) { ((sh34_base_device *)param)->func_FLDI1(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FLDI1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FLDI1, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FCNVSD() { FCNVSD(m_sh2_state->arg0); }
+static void cfunc_FCNVSD(void *param) { ((sh34_base_device *)param)->func_FCNVSD(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FCNVSD(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FCNVSD, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FCNVDS() { FCNVDS(m_sh2_state->arg0); }
+static void cfunc_FCNVDS(void *param) { ((sh34_base_device *)param)->func_FCNVDS(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FCNVDS(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FCNVDS, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FIPR() { FIPR(m_sh2_state->arg0); }
+static void cfunc_FIPR(void *param) { ((sh34_base_device *)param)->func_FIPR(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_FIPR(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FIPR, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ if (opcode & 0x100) {
+ if (opcode & 0x200) {
+ switch (opcode & 0xC00)
+ {
+ case 0x000:
+ return generate_group_15_op1111_0x13_op1111_0xf13_FSCHG(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSCHG();
+ break;
+ case 0x800:
+ return generate_group_15_op1111_0x13_op1111_0xf13_FRCHG(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FRCHG();
+ break;
+ default:
+ return false; //machine().debug_break();
+ break;
+ }
+ }
+ else {
+ return generate_group_15_op1111_0x13_op1111_0xf13_FTRV(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FTRV(opcode);
+ }
+ }
+ else {
+ return generate_group_15_op1111_0x13_op1111_0xf13_FSSCA(block, compiler, desc, opcode, in_delay_slot, ovrpc); // FSSCA(opcode);
+ }
+ return false;
+}
+
+void sh34_base_device::func_FSCHG() { FSCHG(); }
+static void cfunc_FSCHG(void *param) { ((sh34_base_device *)param)->func_FSCHG(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FSCHG(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ //UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FSCHG, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FRCHG() { FRCHG(); }
+static void cfunc_FRCHG(void *param) { ((sh34_base_device *)param)->func_FRCHG(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FRCHG(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ //UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FRCHG, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FTRV() { FTRV(m_sh2_state->arg0); }
+static void cfunc_FTRV(void *param) { ((sh34_base_device *)param)->func_FTRV(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FTRV(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FTRV, this);
+ load_fast_iregs(block);
+ return true;
+}
+
+void sh34_base_device::func_FSSCA() { FSSCA(m_sh2_state->arg0); }
+static void cfunc_FSSCA(void *param) { ((sh34_base_device *)param)->func_FSSCA(); };
+
+bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FSSCA(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
+{
+ save_fast_iregs(block);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_CALLC(block, cfunc_FSSCA, this);
+ load_fast_iregs(block);
+ return true;
+}
+